DPC++ Runtime
Runtime libraries for oneAPI Data Parallel C++
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>
13 #include <detail/platform_impl.hpp>
14 #include <detail/plugin.hpp>
17 #include <detail/xpti_registry.hpp>
18 
19 #ifdef _WIN32
20 #include <windows.h>
21 #endif
22 
23 #include <vector>
24 
26 namespace sycl {
27 namespace detail {
28 using LockGuard = std::lock_guard<SpinLock>;
29 
30 GlobalHandler::GlobalHandler() = default;
31 GlobalHandler::~GlobalHandler() = default;
32 
33 GlobalHandler &GlobalHandler::instance() {
34  static GlobalHandler *SyclGlobalObjectsHandler = new GlobalHandler();
35  return *SyclGlobalObjectsHandler;
36 }
37 
38 template <typename T, typename... Types>
39 T &GlobalHandler::getOrCreate(InstWithLock<T> &IWL, Types... Args) {
40  const LockGuard Lock{IWL.Lock};
41 
42  if (!IWL.Inst)
43  IWL.Inst = std::make_unique<T>(Args...);
44 
45  return *IWL.Inst;
46 }
47 
48 Scheduler &GlobalHandler::getScheduler() { return getOrCreate(MScheduler); }
49 
50 ProgramManager &GlobalHandler::getProgramManager() {
51  return getOrCreate(MProgramManager);
52 }
53 
54 std::unordered_map<PlatformImplPtr, ContextImplPtr> &
55 GlobalHandler::getPlatformToDefaultContextCache() {
56  return getOrCreate(MPlatformToDefaultContextCache);
57 }
58 
59 std::mutex &GlobalHandler::getPlatformToDefaultContextCacheMutex() {
60  return getOrCreate(MPlatformToDefaultContextCacheMutex);
61 }
62 
63 Sync &GlobalHandler::getSync() { return getOrCreate(MSync); }
64 
65 std::vector<PlatformImplPtr> &GlobalHandler::getPlatformCache() {
66  return getOrCreate(MPlatformCache);
67 }
68 
69 std::mutex &GlobalHandler::getPlatformMapMutex() {
70  return getOrCreate(MPlatformMapMutex);
71 }
72 
73 std::mutex &GlobalHandler::getFilterMutex() {
74  return getOrCreate(MFilterMutex);
75 }
76 std::vector<plugin> &GlobalHandler::getPlugins() {
77  return getOrCreate(MPlugins);
78 }
80 GlobalHandler::getDeviceFilterList(const std::string &InitValue) {
81  return getOrCreate(MDeviceFilterList, InitValue);
82 }
83 
84 XPTIRegistry &GlobalHandler::getXPTIRegistry() {
85  return getOrCreate(MXPTIRegistry);
86 }
87 
88 std::mutex &GlobalHandler::getHandlerExtendedMembersMutex() {
89  return getOrCreate(MHandlerExtendedMembersMutex);
90 }
91 
93  // Release shared-pointers to SYCL objects.
94 #ifndef _WIN32
95  GlobalHandler::instance().MPlatformToDefaultContextCache.Inst.reset(nullptr);
96 #else
97  // Windows does not maintain dependencies between dynamically loaded libraries
98  // and can unload SYCL runtime dependencies before sycl.dll's DllMain has
99  // finished. To avoid calls to nowhere, intentionally leak platform to device
100  // cache. This will prevent destructors from being called, thus no PI cleanup
101  // routines will be called in the end.
102  GlobalHandler::instance().MPlatformToDefaultContextCache.Inst.release();
103 #endif
104  GlobalHandler::instance().MPlatformCache.Inst.reset(nullptr);
105 }
106 
107 void shutdown() {
108  // First, release resources, that may access plugins.
109  GlobalHandler::instance().MScheduler.Inst.reset(nullptr);
110  GlobalHandler::instance().MProgramManager.Inst.reset(nullptr);
111 
112  // Call to GlobalHandler::instance().getPlugins() initializes plugins. If
113  // user application has loaded SYCL runtime, and never called any APIs,
114  // there's no need to load and unload plugins.
115  if (GlobalHandler::instance().MPlugins.Inst) {
116  for (plugin &Plugin : GlobalHandler::instance().getPlugins()) {
117  // PluginParameter is reserved for future use that can control
118  // some parameters in the plugin tear-down process.
119  // Currently, it is not used.
120  void *PluginParameter = nullptr;
121  Plugin.call<PiApiKind::piTearDown>(PluginParameter);
122  Plugin.unload();
123  }
124  GlobalHandler::instance().MPlugins.Inst.reset(nullptr);
125  }
126 
127  // Release the rest of global resources.
128  delete &GlobalHandler::instance();
129 }
130 
131 #ifdef _WIN32
132 extern "C" __SYCL_EXPORT BOOL WINAPI DllMain(HINSTANCE hinstDLL,
133  DWORD fdwReason,
134  LPVOID lpReserved) {
135  // Perform actions based on the reason for calling.
136  switch (fdwReason) {
137  case DLL_PROCESS_DETACH:
139  shutdown();
140  break;
141  case DLL_PROCESS_ATTACH:
142  case DLL_THREAD_ATTACH:
143  case DLL_THREAD_DETACH:
144  break;
145  }
146  return TRUE; // Successful DLL_PROCESS_ATTACH.
147 }
148 #else
149 // Release shared SYCL object implementation handles at normal destructor
150 // priority to avoid the global handler from keeping the objects alive after
151 // the backends have destroyed any state they may rely on to correctly handle
152 // further operations.
153 __attribute__((destructor)) static void syclPreunload() {
155 }
156 
157 // Setting low priority on destructor ensures it runs after all other global
158 // destructors. Priorities 0-100 are reserved by the compiler. The priority
159 // value 110 allows SYCL users to run their destructors after runtime library
160 // deinitialization.
161 __attribute__((destructor(110))) static void syclUnload() { shutdown(); }
162 #endif
163 } // namespace detail
164 } // namespace sycl
165 } // __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
T
cl::sycl::detail::__attribute__
__attribute__((destructor(110))) static void syclUnload()
Definition: global_handler.cpp:161
device_filter.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:1532
cl::sycl::detail::LockGuard
std::lock_guard< SpinLock > LockGuard
Definition: global_handler.cpp:28
plugin.hpp
pi.hpp
scheduler.hpp
cl::sycl::detail::shutdown
void shutdown()
Definition: global_handler.cpp:107
cl::sycl::detail::GlobalHandler
Wrapper class for global data structures with non-trivial destructors.
Definition: global_handler.hpp:44
platform_impl.hpp
cl::sycl::detail::device_filter_list
Definition: device_filter.hpp:37
cl
We provide new interfaces for matrix muliply in this patch:
Definition: access.hpp:13
cl::sycl::detail::XPTIRegistry
Definition: xpti_registry.hpp:32
global_handler.hpp
spinlock.hpp
cl::sycl::detail::plugin
The plugin class provides a unified interface to the underlying low-level runtimes for the device-agn...
Definition: plugin.hpp:89
program_manager.hpp
cl::sycl::detail::ProgramManager
Definition: program_manager.hpp:70
cl::sycl::detail::releaseSharedGlobalHandles
void releaseSharedGlobalHandles()
Definition: global_handler.cpp:92
__SYCL_INLINE_NAMESPACE
#define __SYCL_INLINE_NAMESPACE(X)
Definition: defines_elementary.hpp:12