| //===--- Level Zero Target RTL Implementation -----------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // Level Zero RTL Options support. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "omptarget.h" | |
| #include "L0Options.h" | |
| namespace llvm::omp::target::plugin { | |
| /// Read environment variables. | |
| void L0OptionsTy::processEnvironmentVars() { | |
| // Compilation options for IGC. | |
| UserCompilationOptions += | |
| std::string(" ") + | |
| StringEnvar("LIBOMPTARGET_LEVEL_ZERO_COMPILATION_OPTIONS", "").get(); | |
| Flags.UseCopyOffloadHint = | |
| BoolEnvar("LIBOFFLOAD_LEVEL_ZERO_USE_COPY_OFFLOAD_HINT", true); | |
| // Always print the full module build/link log, not only on failure. | |
| Flags.ShowBuildLog = BoolEnvar("LIBOFFLOAD_LEVEL_ZERO_SHOW_BUILD_LOG", false); | |
| // Memory pool syntax: | |
| // LIBOMPTARGET_LEVEL_ZERO_MEMORY_POOL=<Option> | |
| // <Option> := 0 | <PoolInfoList> | |
| // <PoolInfoList> := <PoolInfo>[,<PoolInfoList>] | |
| // <PoolInfo> := <MemType>[,<AllocMax>[,<Capacity>[,<PoolSize>]]] | |
| // <MemType> := all | device | host | shared | |
| // <AllocMax> := non-negative integer or empty, max allocation size in | |
| // MB (default: 1). | |
| // <Capacity> := positive integer or empty, number of allocations from | |
| // a single block (default: 4). | |
| // <PoolSize> := positive integer or empty, max pool size in MB | |
| // (default: 256). | |
| const StringEnvar MemoryPoolVar("LIBOMPTARGET_LEVEL_ZERO_MEMORY_POOL", ""); | |
| if (MemoryPoolVar.isPresent()) { | |
| if (MemoryPoolVar.get() == "0") { | |
| Flags.UseMemoryPool = 0; | |
| MemPoolConfig.fill({false, 0, 0, 0}); | |
| } else { | |
| std::istringstream Str(MemoryPoolVar.get()); | |
| int32_t MemType = -1; | |
| int32_t Offset = 0; | |
| int32_t Valid = 1; | |
| constexpr std::array<int32_t, 3> DefaultValue{1, 4, 256}; | |
| constexpr int32_t AllMemType = | |
| std::numeric_limits<decltype(AllMemType)>::max(); | |
| std::array<int32_t, 3> AllInfo{1, 4, 256}; | |
| std::array<std::array<int32_t, 3>, 3> PoolInfo; | |
| PoolInfo.fill({-1, 0, 0}); | |
| for (std::string Token; std::getline(Str, Token, ',') && Valid > 0;) { | |
| if (Token == "device") { | |
| MemType = TARGET_ALLOC_DEVICE; | |
| PoolInfo[TARGET_ALLOC_DEVICE] = DefaultValue; | |
| Offset = 0; | |
| } else if (Token == "host") { | |
| MemType = TARGET_ALLOC_HOST; | |
| PoolInfo[TARGET_ALLOC_HOST] = DefaultValue; | |
| Offset = 0; | |
| } else if (Token == "shared") { | |
| MemType = TARGET_ALLOC_SHARED; | |
| PoolInfo[TARGET_ALLOC_SHARED] = DefaultValue; | |
| Offset = 0; | |
| } else if (Token == "all") { | |
| MemType = AllMemType; | |
| Offset = 0; | |
| Valid = 2; | |
| } else if (Offset < 3 && MemType >= 0) { | |
| int32_t Num = std::atoi(Token.c_str()); | |
| bool ValidNum = (Num >= 0 && Offset == 0) || (Num > 0 && Offset > 0); | |
| if (ValidNum && MemType == AllMemType) | |
| AllInfo[Offset++] = Num; | |
| else if (ValidNum) | |
| PoolInfo[MemType][Offset++] = Num; | |
| else if (Token.size() == 0) | |
| Offset++; | |
| else | |
| Valid = 0; | |
| } else { | |
| Valid = 0; | |
| } | |
| } | |
| if (Valid > 0) { | |
| if (Valid == 2) { | |
| // "all" is specified -- ignore other inputs. | |
| if (AllInfo[0] > 0) { | |
| MemPoolConfig[TARGET_ALLOC_DEVICE] = {true, AllInfo[0], AllInfo[1], | |
| AllInfo[2]}; | |
| MemPoolConfig[TARGET_ALLOC_HOST] = {true, AllInfo[0], AllInfo[1], | |
| AllInfo[2]}; | |
| MemPoolConfig[TARGET_ALLOC_SHARED] = {true, AllInfo[0], AllInfo[1], | |
| AllInfo[2]}; | |
| } else { | |
| MemPoolConfig.fill({false, 0, 0, 0}); | |
| } | |
| } else { | |
| for (size_t Pool = 0; Pool < PoolInfo.size(); ++Pool) { | |
| switch (PoolInfo[Pool][0]) { | |
| case -1: | |
| // No value was specified, keep the default. | |
| break; | |
| case 0: | |
| // Pool was disabled. | |
| MemPoolConfig[Pool] = {false, 0, 0, 0}; | |
| break; | |
| default: | |
| // Use the user specified values. | |
| MemPoolConfig[Pool] = {true, PoolInfo[Pool][0], PoolInfo[Pool][1], | |
| PoolInfo[Pool][2]}; | |
| break; | |
| } | |
| } | |
| } | |
| } else { | |
| ODBG_OS(OLDT_Init, [&](llvm::raw_ostream &O) { | |
| O << "Ignoring incorrect memory pool configuration " | |
| "LIBOMPTARGET_LEVEL_ZERO_MEMORY_POOL=" | |
| << MemoryPoolVar.get() << "\n"; | |
| O << "LIBOMPTARGET_LEVEL_ZERO_MEMORY_POOL=<Option>\n"; | |
| O << " <Option> := 0 | <PoolInfoList>\n"; | |
| O << " <PoolInfoList> := <PoolInfo>[,<PoolInfoList>]\n"; | |
| O << " <PoolInfo> := " | |
| "<MemType>[,<AllocMax>[,<Capacity>[,<PoolSize>]]]\n"; | |
| O << " <MemType> := all | device | host | shared\n"; | |
| O << " <AllocMax> := non-negative integer or empty, " | |
| "max allocation size in MB (default: 1)\n"; | |
| O << " <Capacity> := positive integer or empty, " | |
| "number of allocations from a single block (default: 4)\n"; | |
| O << " <PoolSize> := positive integer or empty, " | |
| "max pool size in MB (default: 256)\n"; | |
| }); | |
| } | |
| } | |
| } | |
| if (StringEnvar("INTEL_ENABLE_OFFLOAD_ANNOTATIONS").isPresent()) { | |
| // To match SYCL RT behavior, we just need to check whether | |
| // INTEL_ENABLE_OFFLOAD_ANNOTATIONS is set. The actual value | |
| // does not matter. | |
| CommonSpecConstants.addConstant<char>(0xFF747469, 1); | |
| } | |
| // LIBOMPTARGET_LEVEL_ZERO_COMMAND_MODE=<Fmt>. | |
| // <Fmt> := inorder | sync | |
| // inorder: use level zero command queue in-order mode. This is the default. | |
| // sync: perform synchronization after each command. | |
| const StringEnvar CommandModeVar("LIBOMPTARGET_LEVEL_ZERO_COMMAND_MODE"); | |
| if (CommandModeVar.isPresent()) { | |
| if (match(CommandModeVar, "sync")) | |
| CommandMode = CommandModeTy::Sync; | |
| else if (match(CommandModeVar, "inorder")) | |
| CommandMode = CommandModeTy::InOrder; | |
| else | |
| MESSAGE("Warning: Ignoring invalid value for " | |
| "LIBOMPTARGET_LEVEL_ZERO_COMMAND_MODE=%s\n", | |
| CommandModeVar.get().c_str()); | |
| } | |
| } | |
| } // namespace llvm::omp::target::plugin |