From db8d6826027d61915c898163760b6b0baf982442 Mon Sep 17 00:00:00 2001 From: Kieran Holland Date: Mon, 8 Jun 2020 11:53:41 -0700 Subject: [PATCH] [SYCL] Eliminated redundancy in pi initialization. Passed the implementation of pi initialization into a "call_once" function, so that plugin initiliazation only needs to be executed once. After the first time, the already initiliazed plugin will be returned. Also, updated pi::initialize to return const reference to the global vector of plugins, rather than a temporary copy of it. --- sycl/include/CL/sycl/detail/pi.hpp | 2 +- sycl/source/detail/pi.cpp | 27 +++++++++++++++++++++------ sycl/source/detail/platform_impl.cpp | 2 +- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/sycl/include/CL/sycl/detail/pi.hpp b/sycl/include/CL/sycl/detail/pi.hpp index e929ffabca5e..aecaf438847b 100644 --- a/sycl/include/CL/sycl/detail/pi.hpp +++ b/sycl/include/CL/sycl/detail/pi.hpp @@ -137,7 +137,7 @@ template To cast(From value); extern std::shared_ptr GlobalPlugin; // Performs PI one-time initialization. -vector_class initialize(); +const vector_class &initialize(); // Utility Functions to get Function Name for a PI Api. template struct PiFuncInfo {}; diff --git a/sycl/source/detail/pi.cpp b/sycl/source/detail/pi.cpp index 699315af4e02..7190a927b504 100644 --- a/sycl/source/detail/pi.cpp +++ b/sycl/source/detail/pi.cpp @@ -52,6 +52,8 @@ constexpr const char *GVerStr = "sycl 1.0"; namespace pi { +static void initializePlugins(vector_class *Plugins); + bool XPTIInitDone = false; // Implementation of the SYCL PI API call tracing methods that use XPTI @@ -254,8 +256,23 @@ bool trace(TraceLevel Level) { } // Initializes all available Plugins. -vector_class initialize() { - vector_class Plugins; +const vector_class &initialize() { + static std::once_flag PluginsInitDone; + static vector_class *Plugins = nullptr; + + std::call_once(PluginsInitDone, []() { + // The memory for "Plugins" is intentionally leaked because the application + // may call into the SYCL runtime from a global destructor, and such a call + // could eventually call down to initialize(). Therefore, there is no safe + // time when "Plugins" could be deleted. + Plugins = new vector_class; + initializePlugins(Plugins); + }); + + return *Plugins; +} + +static void initializePlugins(vector_class *Plugins) { vector_class> PluginNames; findPlugins(PluginNames); @@ -303,7 +320,7 @@ vector_class initialize() { // Use the CUDA plugin as the GlobalPlugin GlobalPlugin = std::make_shared(PluginInformation, backend::cuda); } - Plugins.emplace_back(plugin(PluginInformation, PluginNames[I].second)); + Plugins->emplace_back(plugin(PluginInformation, PluginNames[I].second)); if (trace(TraceLevel::PI_TRACE_BASIC)) std::cerr << "SYCL_PI_TRACE[basic]: " << "Plugin found and successfully loaded: " @@ -312,7 +329,7 @@ vector_class initialize() { #ifdef XPTI_ENABLE_INSTRUMENTATION if (!(xptiTraceEnabled() && !XPTIInitDone)) - return Plugins; + return; // Not sure this is the best place to initialize the framework; SYCL runtime // team needs to advise on the right place, until then we piggy-back on the // initialization of the PI layer. @@ -353,8 +370,6 @@ vector_class initialize() { xptiMakeEvent("PI Layer", &PIPayload, xpti::trace_algorithm_event, xpti_at::active, &PiInstanceNo); #endif - - return Plugins; } // Report error and no return (keeps compiler from printing warnings). diff --git a/sycl/source/detail/platform_impl.cpp b/sycl/source/detail/platform_impl.cpp index 6d1096066465..daabe5722f75 100644 --- a/sycl/source/detail/platform_impl.cpp +++ b/sycl/source/detail/platform_impl.cpp @@ -49,7 +49,7 @@ static bool IsBannedPlatform(platform Platform) { vector_class platform_impl::get_platforms() { vector_class Platforms; - vector_class Plugins = RT::initialize(); + const vector_class &Plugins = RT::initialize(); info::device_type ForcedType = detail::get_forced_type(); for (unsigned int i = 0; i < Plugins.size(); i++) {