DPC++ Runtime
Runtime libraries for oneAPI DPC++
pi_esimd_emulator.hpp
Go to the documentation of this file.
1 //===---------- pi_esimd_emulator.hpp - CM Emulation Plugin ---------------===//
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 
14 
15 #pragma once
16 
17 #include <CL/sycl/detail/pi.h>
18 #include <atomic>
19 #include <cassert>
20 #include <iostream>
21 #include <mutex>
22 #include <unordered_map>
23 
24 #include <malloc.h>
25 
26 // This version should be incremented for any change made to this file or its
27 // corresponding .cpp file.
28 #define _PI_ESIMD_PLUGIN_VERSION 1
29 
30 #define _PI_ESIMD_PLUGIN_VERSION_STRING \
31  _PI_PLUGIN_VERSION_STRING(_PI_ESIMD_PLUGIN_VERSION)
32 
33 namespace cm_support {
34 #include <cm_rt.h>
35 } // namespace cm_support
36 
37 template <class To, class From> To pi_cast(From Value) {
38  // TODO: see if more sanity checks are possible.
39  assert(sizeof(From) == sizeof(To));
40  return (To)(Value);
41 }
42 
43 template <> uint32_t pi_cast(uint64_t Value) {
44  // Cast value and check that we don't lose any information.
45  uint32_t CastedValue = (uint32_t)(Value);
46  assert((uint64_t)CastedValue == Value);
47  return CastedValue;
48 }
49 
50 // TODO: Currently die is defined in each plugin. Probably some
51 // common header file with utilities should be created.
52 [[noreturn]] void die(const char *Message) {
53  std::cerr << "die: " << Message << std::endl;
54  std::terminate();
55 }
56 
57 // Base class to store common data
58 struct _pi_object {
59  _pi_object() : RefCount{1} {}
60 
61  std::atomic<pi_uint32> RefCount;
62 
63  virtual ~_pi_object() = default;
64 };
65 struct _pi_platform {
66  _pi_platform() = default;
67 
68  // Single-entry Cache pi_devices for reuse
69  std::unique_ptr<_pi_device> PiDeviceCache;
70  std::mutex PiDeviceCacheMutex;
71  bool DeviceCachePopulated = false;
72 
73  // Check the device cache and load it if necessary.
75 
76  // Keep Version information.
77  std::string CmEmuVersion;
78 };
79 
80 struct _pi_device : _pi_object {
81  _pi_device(pi_platform ArgPlt, cm_support::CmDevice *ArgCmDev,
82  std::string ArgVersionStr)
83  : Platform{ArgPlt}, CmDevicePtr{ArgCmDev}, VersionStr{ArgVersionStr} {}
84 
86  // TODO: Check if serialization is required when ESIMD_EMULATOR
87  // plug-in calls CM runtime functions
88  cm_support::CmDevice *CmDevicePtr = nullptr;
89 
90  std::string VersionStr;
91 };
92 
93 struct _pi_context : _pi_object {
94  _pi_context(pi_device ArgDevice) : Device{ArgDevice} {}
95 
96  // One-to-one mapping between Context and Device
98 
99  // Map SVM memory starting address to corresponding
100  // CmBufferSVM object. CmBufferSVM object is needed to release memory.
101  std::unordered_map<void *, cm_support::CmBufferSVM *> Addr2CmBufferSVM;
102  // A lock guarding access to Addr2CmBufferSVM
104 
105  bool checkSurfaceArgument(pi_mem_flags Flags, void *HostPtr);
106 };
107 
108 struct _pi_queue : _pi_object {
109  _pi_queue(pi_context ContextArg, cm_support::CmQueue *CmQueueArg)
110  : Context{ContextArg}, CmQueuePtr{CmQueueArg} {}
111 
112  // Keeps the PI context to which this queue belongs.
113  pi_context Context = nullptr;
114  cm_support::CmQueue *CmQueuePtr = nullptr;
115 };
116 
118  // 'UP' means 'User-Provided' in CM Lib - corresponding to
119  // Buffer/Image created with PI_MEM_FLAGS_HOST_PTR_USE option in
120  // SYCL
121  enum SurfaceType {
127  };
129 
130  union {
131  cm_support::CmBuffer *RegularBufPtr = nullptr;
132  cm_support::CmBufferUP *UPBufPtr;
133  cm_support::CmSurface2D *RegularImgPtr;
134  cm_support::CmSurface2DUP *UPImgPtr;
135  };
136 };
137 
138 struct _pi_mem : _pi_object {
140 
141  // To be used for piEnqueueMemBufferMap
142  char *MapHostPtr = nullptr;
143 
144  std::mutex SurfaceLock;
145 
146  // Surface index
147 
148  unsigned int SurfaceIndex;
149  // Supplementary data to keep track of the mappings of this memory
150  // created with piEnqueueMemBufferMap
151  struct Mapping {
152  // The offset in the buffer giving the start of the mapped region.
153  size_t Offset = 0;
154  // The size of the mapped region.
155  size_t Size = 0;
156  };
157 
158  // The key is the host pointer representing an active mapping.
159  // The value is the information needed to maintain/undo the mapping.
160  // TODO : std::unordered_map is imported from L0.
161  // Use std::stack for strict LIFO behavior checking?
162  std::unordered_map<void *, Mapping> Mappings;
163  // Supporing multi-threaded mapping/unmapping calls
164  std::mutex MappingsMutex;
165 
167 
168  // Destructor for invoking buffer/image destory calls in CM Runtime
169  ~_pi_mem();
170 
171 protected:
172  _pi_mem(pi_context ctxt, char *HostPtr, cm_surface_ptr_t SurfacePtrArg,
173  unsigned int SurfaceIdxArg)
174  : Context{ctxt}, MapHostPtr{HostPtr}, SurfaceIndex{SurfaceIdxArg},
175  SurfacePtr{SurfacePtrArg} {}
176 };
177 
178 struct _pi_buffer final : _pi_mem {
179  // Buffer/Sub-buffer constructor
180  _pi_buffer(pi_context ctxt, char *HostPtr, cm_surface_ptr_t SurfacePtrArg,
181  unsigned int SurfaceIdxArg, size_t SizeArg)
182  : _pi_mem(ctxt, HostPtr, SurfacePtrArg, SurfaceIdxArg), Size{SizeArg} {}
183 
184  size_t Size;
185 };
186 
187 struct _pi_image final : _pi_mem {
188  // Image constructor
189  _pi_image(pi_context ctxt, char *HostPtr, cm_surface_ptr_t SurfacePtrArg,
190  unsigned int SurfaceIdxArg, size_t WidthArg, size_t HeightArg,
191  size_t BPPArg)
192  : _pi_mem(ctxt, HostPtr, SurfacePtrArg, SurfaceIdxArg), Width{WidthArg},
193  Height{HeightArg}, BytesPerPixel{BPPArg} {}
194 
195  size_t Width;
196  size_t Height;
198 };
199 
200 struct _pi_event : _pi_object {
202 
203  cm_support::CmEvent *CmEventPtr = nullptr;
204  cm_support::CmQueue *OwnerQueue = nullptr;
205  pi_context Context = nullptr;
206  bool IsDummyEvent = false;
207 };
208 
209 struct _pi_program : _pi_object {
211 
212  // Keep the context of the program.
214 };
215 
216 struct _pi_kernel : _pi_object {
218 };
219 
_pi_queue::_pi_queue
_pi_queue(pi_context ContextArg, cm_support::CmQueue *CmQueueArg)
Definition: pi_esimd_emulator.hpp:109
_pi_object::RefCount
std::atomic< pi_uint32 > RefCount
Definition: pi_esimd_emulator.hpp:61
cm_surface_ptr_t::TypeUserProvidedImage
@ TypeUserProvidedImage
Definition: pi_esimd_emulator.hpp:126
die
void die(const char *Message)
Definition: pi_esimd_emulator.hpp:52
_pi_mem
PI Mem mapping to CUDA memory allocations, both data and texture/surface.
Definition: pi_cuda.hpp:221
_pi_context::_pi_context
_pi_context(pi_device ArgDevice)
Definition: pi_esimd_emulator.hpp:94
_pi_mem::Mapping
Definition: pi_esimd_emulator.hpp:151
_pi_device::CmDevicePtr
cm_support::CmDevice * CmDevicePtr
Definition: pi_esimd_emulator.hpp:88
esimd_emulator_device_interface.hpp
pi.h
_pi_image::Width
size_t Width
Definition: pi_esimd_emulator.hpp:195
_pi_mem::Mapping::Offset
size_t Offset
Definition: pi_esimd_emulator.hpp:153
_pi_mem::Mappings
std::unordered_map< void *, Mapping > Mappings
Definition: pi_esimd_emulator.hpp:162
_pi_buffer
Definition: pi_esimd_emulator.hpp:178
_pi_platform::PiDeviceCacheMutex
std::mutex PiDeviceCacheMutex
Definition: pi_esimd_emulator.hpp:70
_pi_image
Definition: pi_esimd_emulator.hpp:187
cm_surface_ptr_t::TypeNone
@ TypeNone
Definition: pi_esimd_emulator.hpp:122
cm_surface_ptr_t
Definition: pi_esimd_emulator.hpp:117
_pi_result
_pi_result
Definition: pi.h:105
_pi_event::CmEventPtr
cm_support::CmEvent * CmEventPtr
Definition: pi_esimd_emulator.hpp:203
_pi_object::~_pi_object
virtual ~_pi_object()=default
_pi_device::_pi_device
_pi_device(pi_platform ArgPlt, cm_support::CmDevice *ArgCmDev, std::string ArgVersionStr)
Definition: pi_esimd_emulator.hpp:81
cm_support
Definition: pi_esimd_emulator.hpp:33
_pi_device::VersionStr
std::string VersionStr
Definition: pi_esimd_emulator.hpp:90
_pi_platform
A PI platform stores all known PI devices, in the CUDA plugin this is just a vector of available devi...
Definition: pi_cuda.hpp:72
_pi_object
Definition: pi_esimd_emulator.hpp:58
_pi_kernel
Implementation of a PI Kernel for CUDA.
Definition: pi_cuda.hpp:773
pi_cast
To pi_cast(From Value)
Definition: pi_esimd_emulator.hpp:37
_pi_platform::_pi_platform
_pi_platform()=default
cm_surface_ptr_t::RegularBufPtr
cm_support::CmBuffer * RegularBufPtr
Definition: pi_esimd_emulator.hpp:131
_pi_mem::Context
pi_context Context
Definition: pi_esimd_emulator.hpp:139
_pi_mem::~_pi_mem
~_pi_mem()
Definition: pi_cuda.hpp:362
cm_surface_ptr_t::RegularImgPtr
cm_support::CmSurface2D * RegularImgPtr
Definition: pi_esimd_emulator.hpp:133
_pi_queue
PI queue mapping on to CUstream objects.
Definition: pi_cuda.hpp:392
_pi_context::Addr2CmBufferSVMLock
std::mutex Addr2CmBufferSVMLock
Definition: pi_esimd_emulator.hpp:103
_pi_mem::MapHostPtr
char * MapHostPtr
Definition: pi_esimd_emulator.hpp:142
cm_surface_ptr_t::tag
SurfaceType tag
Definition: pi_esimd_emulator.hpp:128
_pi_mem::SurfacePtr
cm_surface_ptr_t SurfacePtr
Definition: pi_esimd_emulator.hpp:166
_pi_platform::PiDeviceCache
std::unique_ptr< _pi_device > PiDeviceCache
Definition: pi_esimd_emulator.hpp:69
pi_mem_flags
pi_bitfield pi_mem_flags
Definition: pi.h:524
_pi_queue::Context
pi_context Context
Definition: pi_esimd_emulator.hpp:113
_pi_mem::Mapping::Size
size_t Size
Definition: pi_esimd_emulator.hpp:155
_pi_platform::DeviceCachePopulated
bool DeviceCachePopulated
Definition: pi_esimd_emulator.hpp:71
_pi_device::Platform
pi_platform Platform
Definition: pi_esimd_emulator.hpp:85
_pi_program::Context
pi_context Context
Definition: pi_esimd_emulator.hpp:213
_pi_mem::_pi_mem
_pi_mem(pi_context ctxt, char *HostPtr, cm_surface_ptr_t SurfacePtrArg, unsigned int SurfaceIdxArg)
Definition: pi_esimd_emulator.hpp:172
_pi_platform::CmEmuVersion
std::string CmEmuVersion
Definition: pi_esimd_emulator.hpp:77
_pi_image::BytesPerPixel
size_t BytesPerPixel
Definition: pi_esimd_emulator.hpp:197
_pi_program
Implementation of PI Program on CUDA Module object.
Definition: pi_cuda.hpp:718
cm_surface_ptr_t::TypeRegularImage
@ TypeRegularImage
Definition: pi_esimd_emulator.hpp:125
_pi_image::Height
size_t Height
Definition: pi_esimd_emulator.hpp:196
_pi_kernel::_pi_kernel
_pi_kernel()
Definition: pi_esimd_emulator.hpp:217
cm_surface_ptr_t::UPBufPtr
cm_support::CmBufferUP * UPBufPtr
Definition: pi_esimd_emulator.hpp:132
_pi_context::Addr2CmBufferSVM
std::unordered_map< void *, cm_support::CmBufferSVM * > Addr2CmBufferSVM
Definition: pi_esimd_emulator.hpp:101
_pi_event::_pi_event
_pi_event()
Definition: pi_esimd_emulator.hpp:201
_pi_program::_pi_program
_pi_program()
Definition: pi_esimd_emulator.hpp:210
_pi_queue::CmQueuePtr
cm_support::CmQueue * CmQueuePtr
Definition: pi_esimd_emulator.hpp:114
_pi_event
PI Event mapping to CUevent.
Definition: pi_cuda.hpp:590
_pi_mem::MappingsMutex
std::mutex MappingsMutex
Definition: pi_esimd_emulator.hpp:164
cm_surface_ptr_t::TypeRegularBuffer
@ TypeRegularBuffer
Definition: pi_esimd_emulator.hpp:123
cm_surface_ptr_t::UPImgPtr
cm_support::CmSurface2DUP * UPImgPtr
Definition: pi_esimd_emulator.hpp:134
_pi_mem::SurfaceIndex
unsigned int SurfaceIndex
Definition: pi_esimd_emulator.hpp:148
cm_surface_ptr_t::TypeUserProvidedBuffer
@ TypeUserProvidedBuffer
Definition: pi_esimd_emulator.hpp:124
cm_surface_ptr_t::SurfaceType
SurfaceType
Definition: pi_esimd_emulator.hpp:121
_pi_object::_pi_object
_pi_object()
Definition: pi_esimd_emulator.hpp:59
_pi_buffer::_pi_buffer
_pi_buffer(pi_context ctxt, char *HostPtr, cm_surface_ptr_t SurfacePtrArg, unsigned int SurfaceIdxArg, size_t SizeArg)
Definition: pi_esimd_emulator.hpp:180
_pi_platform::populateDeviceCacheIfNeeded
pi_result populateDeviceCacheIfNeeded()
Definition: pi_esimd_emulator.cpp:524
_pi_event::IsDummyEvent
bool IsDummyEvent
Definition: pi_esimd_emulator.hpp:206
_pi_image::_pi_image
_pi_image(pi_context ctxt, char *HostPtr, cm_surface_ptr_t SurfacePtrArg, unsigned int SurfaceIdxArg, size_t WidthArg, size_t HeightArg, size_t BPPArg)
Definition: pi_esimd_emulator.hpp:189
_pi_mem::SurfaceLock
std::mutex SurfaceLock
Definition: pi_esimd_emulator.hpp:144
_pi_context::Device
pi_device Device
Definition: pi_esimd_emulator.hpp:97
_pi_event::OwnerQueue
cm_support::CmQueue * OwnerQueue
Definition: pi_esimd_emulator.hpp:204
_pi_context
PI context mapping to a CUDA context object.
Definition: pi_cuda.hpp:159
_pi_event::Context
pi_context Context
Definition: pi_esimd_emulator.hpp:205
_pi_device
PI device mapping to a CUdevice.
Definition: pi_cuda.hpp:82
_pi_context::checkSurfaceArgument
bool checkSurfaceArgument(pi_mem_flags Flags, void *HostPtr)
Definition: pi_esimd_emulator.cpp:906
_pi_buffer::Size
size_t Size
Definition: pi_esimd_emulator.hpp:184