DPC++ Runtime
Runtime libraries for oneAPI DPC++
global_handler.cpp
Go to the documentation of this file.
1 //==--------- global_handler.cpp --- Global objects handler ----------------==//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include <CL/sycl/detail/pi.hpp>
12 #include <detail/config.hpp>
14 #include <detail/platform_impl.hpp>
15 #include <detail/plugin.hpp>
18 #include <detail/thread_pool.hpp>
19 #include <detail/xpti_registry.hpp>
20 
21 #ifdef _WIN32
22 #include <windows.h>
23 #endif
24 
25 #include <vector>
26 
28 namespace sycl {
29 namespace detail {
30 using LockGuard = std::lock_guard<SpinLock>;
31 
32 GlobalHandler::GlobalHandler() = default;
33 GlobalHandler::~GlobalHandler() = default;
34 
35 GlobalHandler &GlobalHandler::instance() {
36  static GlobalHandler *SyclGlobalObjectsHandler = new GlobalHandler();
37  return *SyclGlobalObjectsHandler;
38 }
39 
40 template <typename T, typename... Types>
41 T &GlobalHandler::getOrCreate(InstWithLock<T> &IWL, Types... Args) {
42  const LockGuard Lock{IWL.Lock};
43 
44  if (!IWL.Inst)
45  IWL.Inst = std::make_unique<T>(Args...);
46 
47  return *IWL.Inst;
48 }
49 
50 Scheduler &GlobalHandler::getScheduler() { return getOrCreate(MScheduler); }
51 
52 ProgramManager &GlobalHandler::getProgramManager() {
53  return getOrCreate(MProgramManager);
54 }
55 
56 std::unordered_map<PlatformImplPtr, ContextImplPtr> &
57 GlobalHandler::getPlatformToDefaultContextCache() {
58  return getOrCreate(MPlatformToDefaultContextCache);
59 }
60 
61 std::mutex &GlobalHandler::getPlatformToDefaultContextCacheMutex() {
62  return getOrCreate(MPlatformToDefaultContextCacheMutex);
63 }
64 
65 Sync &GlobalHandler::getSync() { return getOrCreate(MSync); }
66 
67 std::vector<PlatformImplPtr> &GlobalHandler::getPlatformCache() {
68  return getOrCreate(MPlatformCache);
69 }
70 
71 std::mutex &GlobalHandler::getPlatformMapMutex() {
72  return getOrCreate(MPlatformMapMutex);
73 }
74 
75 std::mutex &GlobalHandler::getFilterMutex() {
76  return getOrCreate(MFilterMutex);
77 }
78 std::vector<plugin> &GlobalHandler::getPlugins() {
79  return getOrCreate(MPlugins);
80 }
82 GlobalHandler::getDeviceFilterList(const std::string &InitValue) {
83  return getOrCreate(MDeviceFilterList, InitValue);
84 }
85 
86 XPTIRegistry &GlobalHandler::getXPTIRegistry() {
87  return getOrCreate(MXPTIRegistry);
88 }
89 
90 std::mutex &GlobalHandler::getHandlerExtendedMembersMutex() {
91  return getOrCreate(MHandlerExtendedMembersMutex);
92 }
93 
94 ThreadPool &GlobalHandler::getHostTaskThreadPool() {
96  ThreadPool &TP = getOrCreate(MHostTaskThreadPool, Size);
97 
98  return TP;
99 }
100 
102  // Release shared-pointers to SYCL objects.
103 #ifndef _WIN32
104  GlobalHandler::instance().MPlatformToDefaultContextCache.Inst.reset(nullptr);
105 #else
106  // Windows does not maintain dependencies between dynamically loaded libraries
107  // and can unload SYCL runtime dependencies before sycl.dll's DllMain has
108  // finished. To avoid calls to nowhere, intentionally leak platform to device
109  // cache. This will prevent destructors from being called, thus no PI cleanup
110  // routines will be called in the end.
111  GlobalHandler::instance().MPlatformToDefaultContextCache.Inst.release();
112 #endif
113 }
114 
117 };
118 
119 void GlobalHandler::registerDefaultContextReleaseHandler() {
121 }
122 
123 void shutdown() {
124  // Ensure neither host task is working so that no default context is accessed
125  // upon its release
126  if (GlobalHandler::instance().MHostTaskThreadPool.Inst)
127  GlobalHandler::instance().MHostTaskThreadPool.Inst->finishAndWait();
128 
129  // If default contexts are requested after the first default contexts have
130  // been released there may be a new default context. These must be released
131  // prior to closing the plugins.
132  // Note: Releasing a default context here may cause failures in plugins with
133  // global state as the global state may have been released.
135 
136  // First, release resources, that may access plugins.
137  GlobalHandler::instance().MPlatformCache.Inst.reset(nullptr);
138  GlobalHandler::instance().MScheduler.Inst.reset(nullptr);
139  GlobalHandler::instance().MProgramManager.Inst.reset(nullptr);
140 
141  // Call to GlobalHandler::instance().getPlugins() initializes plugins. If
142  // user application has loaded SYCL runtime, and never called any APIs,
143  // there's no need to load and unload plugins.
144  if (GlobalHandler::instance().MPlugins.Inst) {
145  for (plugin &Plugin : GlobalHandler::instance().getPlugins()) {
146  // PluginParameter is reserved for future use that can control
147  // some parameters in the plugin tear-down process.
148  // Currently, it is not used.
149  void *PluginParameter = nullptr;
150  Plugin.call<PiApiKind::piTearDown>(PluginParameter);
151  Plugin.unload();
152  }
153  GlobalHandler::instance().MPlugins.Inst.reset(nullptr);
154  }
155 
156  // Release the rest of global resources.
157  delete &GlobalHandler::instance();
158 }
159 
160 #ifdef _WIN32
161 extern "C" __SYCL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL,
162  DWORD fdwReason,
163  LPVOID lpReserved) {
164  // Perform actions based on the reason for calling.
165  switch (fdwReason) {
166  case DLL_PROCESS_DETACH:
167  if (!lpReserved)
168  shutdown();
169  break;
170  case DLL_PROCESS_ATTACH:
171  case DLL_THREAD_ATTACH:
172  case DLL_THREAD_DETACH:
173  break;
174  }
175  return TRUE; // Successful DLL_PROCESS_ATTACH.
176 }
177 #else
178 // Setting low priority on destructor ensures it runs after all other global
179 // destructors. Priorities 0-100 are reserved by the compiler. The priority
180 // value 110 allows SYCL users to run their destructors after runtime library
181 // deinitialization.
182 __attribute__((destructor(110))) static void syclUnload() { shutdown(); }
183 #endif
184 } // namespace detail
185 } // namespace sycl
186 } // __SYCL_INLINE_NAMESPACE(cl)
cl::sycl::detail::Scheduler
DPC++ graph scheduler class.
Definition: scheduler.hpp:358
cl::sycl::detail::Sync
Groups and provides access to all the locks used the SYCL runtime.
Definition: util.hpp:24
cl::sycl::detail::__attribute__
__attribute__((destructor(110))) static void syclUnload()
Definition: global_handler.cpp:182
device_filter.hpp
config.hpp
xpti_registry.hpp
piTearDown
pi_result piTearDown(void *PluginParameter)
API to notify that the plugin should clean up its resources.
Definition: pi_esimd_emulator.cpp:1974
cl::sycl::detail::LockGuard
std::lock_guard< SpinLock > LockGuard
Definition: global_handler.cpp:30
sycl
Definition: invoke_simd.hpp:68
plugin.hpp
pi.hpp
scheduler.hpp
cl::sycl::detail::shutdown
void shutdown()
Definition: global_handler.cpp:123
cl::sycl::detail::GlobalHandler
Wrapper class for global data structures with non-trivial destructors.
Definition: global_handler.hpp:45
platform_impl.hpp
cl::sycl::detail::releaseDefaultContexts
void releaseDefaultContexts()
Definition: global_handler.cpp:101
cl::sycl::detail::device_filter_list
Definition: device_filter.hpp:37
cl::sycl::detail::DefaultContextReleaseHandler
Definition: global_handler.cpp:115
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::detail::XPTIRegistry
Definition: xpti_registry.hpp:47
global_handler.hpp
spinlock.hpp
cl::sycl::detail::ThreadPool
Definition: thread_pool.hpp:25
cl::sycl::detail::plugin
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:90
program_manager.hpp
cl::sycl::detail::ProgramManager
Definition: program_manager.hpp:71
cl::sycl::handler
Command group handler class.
Definition: handler.hpp:361
std::get
constexpr tuple_element< I, tuple< Types... > >::type & get(cl::sycl::detail::tuple< Types... > &Arg) noexcept
Definition: tuple.hpp:199
cl::sycl::detail::DefaultContextReleaseHandler::~DefaultContextReleaseHandler
~DefaultContextReleaseHandler()
Definition: global_handler.cpp:116
thread_pool.hpp
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12