Skip to content

Commit 4c24517

Browse files
committed
Address review comments
* Specialize SYCLConfig template class for SYCL_BE and SYCL_PI_TRACE. * Reuse SYCLConfig instead of introducing new Config class in PI. * Use recently introduced backend enum instead of pi::Backend enum. * Print label instead of number during PI_TRACE. * Introduce helper that returns label depending on level of tracing * Force SYCL RT to use specified backend when SYCL_BE is set. If SYCL_BE is not specified then SYCL RT is not forced to use specific backend. But make opencl backend preferred. * Update docs with info about SYCL_BE and SYCL_PI_TRACE Signed-off-by: Artur Gainullin <[email protected]>
1 parent 71e7fac commit 4c24517

File tree

11 files changed

+122
-108
lines changed

11 files changed

+122
-108
lines changed

sycl/doc/EnvironmentVariables.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ subject to change. Do not rely on these variables in production code.
1111

1212
| Environment variable | Values | Description |
1313
| -------------------- | ------ | ----------- |
14-
| SYCL_PI_TRACE | Any(\*) | Force tracing of PI calls to stderr. |
15-
| SYCL_BE | PI_OPENCL, PI_CUDA, PI_OTHER | When SYCL RT is built with PI, this controls which plugin is used by the default device selector. Default value is PI_OPENCL. |
14+
| SYCL_PI_TRACE | Described [below](#sycl_pi_trace-options) | Enable specified level of tracing for PI. |
15+
| SYCL_BE | PI_OPENCL, PI_CUDA | When SYCL RT is built with PI, force SYCL to consider only devices of the specified backend during the device selection. |
1616
| SYCL_DEVICE_TYPE | One of: CPU, GPU, ACC, HOST | Force SYCL to use the specified device type. If unset, default selection rules are applied. If set to any unlisted value, this control has no effect. If the requested device type is not found, a `cl::sycl::runtime_error` exception is thrown. If a non-default device selector is used, a device must satisfy both the selector and this control to be chosen. This control only has effect on devices created with a selector. |
1717
| SYCL_PROGRAM_COMPILE_OPTIONS | String of valid OpenCL compile options | Override compile options for all programs. |
1818
| SYCL_PROGRAM_LINK_OPTIONS | String of valid OpenCL link options | Override link options for all programs. |
@@ -39,3 +39,12 @@ SYCL_PRINT_EXECUTION_GRAPH can accept one or more comma separated values from th
3939
| after_addHostAcc | print graph after addHostAccessor method |
4040
| always | print graph before and after each of the above methods |
4141

42+
### SYCL_PI_TRACE Options
43+
44+
SYCL_PI_TRACE can accept one of the values from the table below
45+
46+
| Option | Description |
47+
| ------ | ----------- |
48+
| 1 | Enable basic tracing |
49+
| 2 | Enable tracing of the PI calls |
50+
| -1 | Enable all levelis of tracing |

sycl/include/CL/sycl/detail/pi.hpp

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#pragma once
1515

16+
#include <CL/sycl/backend_types.hpp>
1617
#include <CL/sycl/detail/common.hpp>
1718
#include <CL/sycl/detail/export.hpp>
1819
#include <CL/sycl/detail/os_util.hpp>
@@ -124,13 +125,6 @@ void *loadOsLibrary(const std::string &Library);
124125
// library, implementation is OS dependent.
125126
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName);
126127

127-
// For selection of SYCL RT back-end, now manually through the "SYCL_BE"
128-
// environment variable.
129-
enum Backend { SYCL_BE_PI_OPENCL, SYCL_BE_PI_CUDA, SYCL_BE_PI_OTHER };
130-
131-
// Get the preferred BE (selected with SYCL_BE).
132-
Backend getPreferredBE();
133-
134128
// Get a string representing a _pi_platform_info enum
135129
std::string platformInfoToString(pi_platform_info info);
136130

sycl/source/detail/config.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ void readConfig() {
103103
void dumpConfig() {
104104
#define CONFIG(Name, MaxSize, CompileTimeDef) \
105105
{ \
106-
const char *Val = SYCLConfig<Name>::get(); \
106+
const char *Val = SYCLConfigBase<Name>::getRawValue(); \
107107
std::cerr << SYCLConfigBase<Name>::MConfigName << " : " \
108108
<< (Val ? Val : "unset") << std::endl; \
109109
}

sycl/source/detail/config.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,5 @@
1313
CONFIG(SYCL_PRINT_EXECUTION_GRAPH, 32, __SYCL_PRINT_EXECUTION_GRAPH)
1414
CONFIG(SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP, 1, __SYCL_DISABLE_EXECUTION_GRAPH_CLEANUP)
1515
CONFIG(SYCL_DEVICE_ALLOWLIST, 1024, __SYCL_DEVICE_ALLOWLIST)
16+
CONFIG(SYCL_BE, 16, __SYCL_BE)
17+
CONFIG(SYCL_PI_TRACE, 4, __SYCL_PI_TRACE)

sycl/source/detail/config.hpp

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@
88

99
#pragma once
1010

11+
#include <CL/sycl/backend_types.hpp>
1112
#include <CL/sycl/detail/defines.hpp>
13+
#include <CL/sycl/detail/pi.hpp>
1214

1315
#include <cstdlib>
16+
#include <map>
1417

1518
__SYCL_INLINE_NAMESPACE(cl) {
1619
namespace sycl {
@@ -48,6 +51,9 @@ constexpr const char *getStrOrNullptr(const char *Str) {
4851
return (Str[0] == '_' && Str[1] == '_') ? nullptr : Str;
4952
}
5053

54+
// Intializes configs from the configuration file
55+
void readConfig();
56+
5157
template <ConfigID Config> class SYCLConfigBase;
5258

5359
#define CONFIG(Name, MaxSize, CompileTimeDef) \
@@ -65,38 +71,82 @@ template <ConfigID Config> class SYCLConfigBase;
6571
* beginning of the string, if it starts with double underscore(__) the \
6672
* value is not set.*/ \
6773
static const char *const MCompileTimeDef; \
74+
\
75+
static const char *getRawValue() { \
76+
if (ConfigFromEnvEnabled) \
77+
if (const char *ValStr = getenv(MConfigName)) \
78+
return ValStr; \
79+
\
80+
if (ConfigFromFileEnabled) { \
81+
readConfig(); \
82+
if (MValueFromFile) \
83+
return MValueFromFile; \
84+
} \
85+
\
86+
if (ConfigFromCompileDefEnabled && MCompileTimeDef) \
87+
return MCompileTimeDef; \
88+
\
89+
return nullptr; \
90+
} \
6891
};
6992
#include "config.def"
7093
#undef CONFIG
7194

72-
// Intializes configs from the configuration file
73-
void readConfig();
74-
7595
template <ConfigID Config> class SYCLConfig {
7696
using BaseT = SYCLConfigBase<Config>;
7797

7898
public:
7999
static const char *get() {
80-
const char *ValStr = getRawValue();
100+
const char *ValStr = BaseT::getRawValue();
81101
return ValStr;
82102
}
103+
};
83104

84-
private:
85-
static const char *getRawValue() {
86-
if (ConfigFromEnvEnabled)
87-
if (const char *ValStr = getenv(BaseT::MConfigName))
88-
return ValStr;
105+
template <> class SYCLConfig<SYCL_BE> {
106+
using BaseT = SYCLConfigBase<SYCL_BE>;
89107

90-
if (ConfigFromFileEnabled) {
91-
readConfig();
92-
if (BaseT::MValueFromFile)
93-
return BaseT::MValueFromFile;
108+
public:
109+
static backend get() {
110+
static bool Initialized = false;
111+
static backend Backend = backend::opencl;
112+
113+
// Configuration parameters are processed only once, like reading a string
114+
// from environment and converting it into a typed object.
115+
if (Initialized)
116+
return Backend;
117+
118+
const char *ValStr = BaseT::getRawValue();
119+
const std::map<std::string, backend> SyclBeMap{
120+
{"PI_OPENCL", backend::opencl}, {"PI_CUDA", backend::cuda}};
121+
if (ValStr) {
122+
auto It = SyclBeMap.find(ValStr);
123+
if (It == SyclBeMap.end())
124+
pi::die("Invalid backend. "
125+
"Valid values are PI_OPENCL/PI_CUDA");
126+
Backend = It->second;
94127
}
128+
Initialized = true;
129+
return Backend;
130+
}
131+
};
95132

96-
if (ConfigFromCompileDefEnabled && BaseT::MCompileTimeDef)
97-
return BaseT::MCompileTimeDef;
133+
template <> class SYCLConfig<SYCL_PI_TRACE> {
134+
using BaseT = SYCLConfigBase<SYCL_PI_TRACE>;
98135

99-
return nullptr;
136+
public:
137+
static int get() {
138+
static bool Initialized = false;
139+
static int Level = 0; // No tracing by default
140+
141+
// Configuration parameters are processed only once, like reading a string
142+
// from environment and converting it into a typed object.
143+
if (Initialized)
144+
return Level;
145+
146+
const char *ValStr = BaseT::getRawValue();
147+
Level = (ValStr ? std::atoi(ValStr) : 0);
148+
Initialized = true;
149+
return Level;
100150
}
101151
};
102152

sycl/source/detail/pi.cpp

Lines changed: 17 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <CL/sycl/context.hpp>
1616
#include <CL/sycl/detail/common.hpp>
1717
#include <CL/sycl/detail/pi.hpp>
18+
#include <detail/config.hpp>
1819
#include <detail/plugin.hpp>
1920

2021
#include <bitset>
@@ -141,80 +142,21 @@ std::string memFlagsToString(pi_mem_flags Flags) {
141142
return Sstream.str();
142143
}
143144

144-
// A singleton class to aid that PI configuration parameters
145-
// are processed only once, like reading a string from environment
146-
// and converting it into a typed object.
147-
//
148-
template <typename T, const char *E> class Config {
149-
static Config *m_Instance;
150-
T m_Data;
151-
Config();
152-
153-
public:
154-
static T get() {
155-
if (!m_Instance) {
156-
m_Instance = new Config();
157-
}
158-
return m_Instance->m_Data;
159-
}
160-
};
161-
162-
template <typename T, const char *E>
163-
Config<T, E> *Config<T, E>::m_Instance = nullptr;
164-
165-
// Lists valid configuration environment variables.
166-
static constexpr char SYCL_BE[] = "SYCL_BE";
167-
static constexpr char SYCL_INTEROP_BE[] = "SYCL_INTEROP_BE";
168-
static constexpr char SYCL_PI_TRACE[] = "SYCL_PI_TRACE";
169-
170-
// SYCL_PI_TRACE gives the mask of enabled tracing components (0 default)
171-
template <> Config<int, SYCL_PI_TRACE>::Config() {
172-
const char *Env = std::getenv(SYCL_PI_TRACE);
173-
m_Data = (Env ? std::atoi(Env) : 0);
174-
}
175-
176-
static Backend getBE(const char *EnvVar) {
177-
const char *BE = std::getenv(EnvVar);
178-
const std::map<std::string, Backend> SyclBeMap{
179-
{"PI_OTHER", SYCL_BE_PI_OTHER},
180-
{"PI_CUDA", SYCL_BE_PI_CUDA},
181-
{"PI_OPENCL", SYCL_BE_PI_OPENCL}};
182-
if (BE) {
183-
auto It = SyclBeMap.find(BE);
184-
if (It == SyclBeMap.end())
185-
pi::die("Invalid backend. "
186-
"Valid values are PI_OPENCL/PI_CUDA");
187-
return It->second;
188-
}
189-
// Default backend
190-
return SYCL_BE_PI_OPENCL;
191-
}
192-
193-
template <> Config<Backend, SYCL_BE>::Config() { m_Data = getBE(SYCL_BE); }
194-
195-
// SYCL_INTEROP_BE is a way to specify the interoperability plugin.
196-
template <> Config<Backend, SYCL_INTEROP_BE>::Config() {
197-
m_Data = getBE(SYCL_INTEROP_BE);
198-
}
199-
200-
// Helper interface to not expose "pi::Config" outside of pi.cpp
201-
Backend getPreferredBE() { return Config<Backend, SYCL_BE>::get(); }
202-
203145
// GlobalPlugin is a global Plugin used with Interoperability constructors that
204146
// use OpenCL objects to construct SYCL class objects.
205147
std::shared_ptr<plugin> GlobalPlugin;
206148

207149
// Find the plugin at the appropriate location and return the location.
208-
bool findPlugins(vector_class<std::pair<std::string, Backend>> &PluginNames) {
150+
bool findPlugins(vector_class<std::pair<std::string, backend>> &PluginNames) {
209151
// TODO: Based on final design discussions, change the location where the
210152
// plugin must be searched; how to identify the plugins etc. Currently the
211153
// search is done for libpi_opencl.so/pi_opencl.dll file in LD_LIBRARY_PATH
212154
// env only.
213155
//
214-
PluginNames.push_back(std::make_pair<std::string, Backend>(
215-
OPENCL_PLUGIN_NAME, SYCL_BE_PI_OPENCL));
156+
PluginNames.push_back(std::make_pair<std::string, backend>(OPENCL_PLUGIN_NAME,
157+
backend::opencl));
216158
PluginNames.push_back(
217-
std::make_pair<std::string, Backend>(CUDA_PLUGIN_NAME, SYCL_BE_PI_CUDA));
159+
std::make_pair<std::string, backend>(CUDA_PLUGIN_NAME, backend::cuda));
218160
return true;
219161
}
220162

@@ -249,12 +191,12 @@ bool bindPlugin(void *Library, PiPlugin *PluginInformation) {
249191
}
250192

251193
bool trace(TraceLevel Level) {
252-
auto TraceLevelMask = Config<int, SYCL_PI_TRACE>::get();
194+
auto TraceLevelMask = SYCLConfig<SYCL_PI_TRACE>::get();
253195
return (TraceLevelMask & Level) == Level;
254196
}
255197

256198
const char *traceLabel() {
257-
auto TraceLevelMask = Config<int, SYCL_PI_TRACE>::get();
199+
int TraceLevelMask = SYCLConfig<SYCL_PI_TRACE>::get();
258200
switch (TraceLevelMask) {
259201
case PI_TRACE_BASIC:
260202
return "SYCL_PI_TRACE[PI_TRACE_BASIC]: ";
@@ -271,7 +213,7 @@ const char *traceLabel() {
271213
// Initializes all available Plugins.
272214
vector_class<plugin> initialize() {
273215
vector_class<plugin> Plugins;
274-
vector_class<std::pair<std::string, Backend>> PluginNames;
216+
vector_class<std::pair<std::string, backend>> PluginNames;
275217
findPlugins(PluginNames);
276218

277219
if (PluginNames.empty() && trace(PI_TRACE_ALL))
@@ -297,12 +239,16 @@ vector_class<plugin> initialize() {
297239
}
298240
continue;
299241
}
300-
// Set the Global Plugin based on SYCL_INTEROP_BE.
301-
// Rework this when it will be explicit in the code which BE is used in the
302-
// interoperability methods.
303-
if (Config<Backend, SYCL_INTEROP_BE>::get() == PluginNames[I].second) {
242+
if (SYCLConfig<SYCL_BE>::get() == backend::opencl &&
243+
PluginNames[I].first.find("opencl") != std::string::npos) {
244+
// Use the OpenCL plugin as the GlobalPlugin
304245
GlobalPlugin =
305-
std::make_shared<plugin>(PluginInformation, PluginNames[I].second);
246+
std::make_shared<plugin>(PluginInformation, backend::opencl);
247+
}
248+
if (SYCLConfig<SYCL_BE>::get() == backend::cuda &&
249+
PluginNames[I].first.find("cuda") != std::string::npos) {
250+
// Use the CUDA plugin as the GlobalPlugin
251+
GlobalPlugin = std::make_shared<plugin>(PluginInformation, backend::cuda);
306252
}
307253
Plugins.emplace_back(plugin(PluginInformation, PluginNames[I].second));
308254
if (trace(TraceLevel::PI_TRACE_BASIC))

sycl/source/detail/plugin.hpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#pragma once
10+
#include <CL/sycl/backend_types.hpp>
1011
#include <CL/sycl/detail/common.hpp>
1112
#include <CL/sycl/detail/pi.hpp>
1213
#include <CL/sycl/stl.hpp>
@@ -23,7 +24,7 @@ class plugin {
2324
public:
2425
plugin() = delete;
2526

26-
plugin(RT::PiPlugin Plugin, RT::Backend UseBackend)
27+
plugin(RT::PiPlugin Plugin, backend UseBackend)
2728
: MPlugin(Plugin), MBackend(UseBackend) {}
2829

2930
~plugin() = default;
@@ -73,11 +74,11 @@ class plugin {
7374
checkPiResult(Err);
7475
}
7576

76-
RT::Backend getBackend(void) const { return MBackend; }
77+
backend getBackend(void) const { return MBackend; }
7778

7879
private:
7980
RT::PiPlugin MPlugin;
80-
const RT::Backend MBackend;
81+
const backend MBackend;
8182
}; // class plugin
8283
} // namespace detail
8384
} // namespace sycl

sycl/source/detail/program_manager/program_manager.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include <CL/sycl/backend_types.hpp>
910
#include <CL/sycl/context.hpp>
1011
#include <CL/sycl/detail/common.hpp>
1112
#include <CL/sycl/detail/os_util.hpp>
@@ -270,8 +271,8 @@ static bool isDeviceBinaryTypeSupported(const context &C,
270271
}
271272

272273
// OpenCL 2.1 and greater require clCreateProgramWithIL
273-
pi::Backend CBackend = (detail::getSyclObjImpl(C)->getPlugin()).getBackend();
274-
if ((CBackend == pi::SYCL_BE_PI_OPENCL) &&
274+
backend CBackend = (detail::getSyclObjImpl(C)->getPlugin()).getBackend();
275+
if ((CBackend == backend::opencl) &&
275276
C.get_platform().get_info<info::platform::version>() >= "2.1")
276277
return true;
277278

sycl/source/detail/scheduler/commands.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "CL/sycl/access/access.hpp"
1212
#include <CL/cl.h>
13+
#include <CL/sycl/backend_types.hpp>
1314
#include <CL/sycl/detail/kernel_desc.hpp>
1415
#include <CL/sycl/detail/memory_manager.hpp>
1516
#include <CL/sycl/detail/stream_impl.hpp>
@@ -1672,7 +1673,7 @@ cl_int ExecCGCommand::enqueueImp() {
16721673
Requirement *Req = (Requirement *)(Arg.MPtr);
16731674
AllocaCommandBase *AllocaCmd = getAllocaForReq(Req);
16741675
RT::PiMem MemArg = (RT::PiMem)AllocaCmd->getMemAllocation();
1675-
if (Plugin.getBackend() == (pi::Backend::SYCL_BE_PI_OPENCL)) {
1676+
if (Plugin.getBackend() == backend::opencl) {
16761677
Plugin.call<PiApiKind::piKernelSetArg>(Kernel, Arg.MIndex,
16771678
sizeof(RT::PiMem), &MemArg);
16781679
} else {

0 commit comments

Comments
 (0)