Fix a race condition between the "ephemeral watchpoint disabling" and commands the...
[lldb.git] / parallel-libs / streamexecutor / include / streamexecutor / platforms / host / HostPlatformDevice.h
1 //===-- HostPlatformDevice.h - HostPlatformDevice class ---------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// Declaration of the HostPlatformDevice class.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef STREAMEXECUTOR_PLATFORMS_HOST_HOSTPLATFORMDEVICE_H
16 #define STREAMEXECUTOR_PLATFORMS_HOST_HOSTPLATFORMDEVICE_H
17
18 #include <cstdlib>
19 #include <cstring>
20
21 #include "streamexecutor/PlatformDevice.h"
22
23 namespace streamexecutor {
24 namespace host {
25
26 /// A concrete PlatformDevice subclass that performs its work on the host rather
27 /// than offloading to an accelerator.
28 class HostPlatformDevice : public PlatformDevice {
29 public:
30   std::string getName() const override { return "host"; }
31
32   std::string getPlatformName() const override { return "host"; }
33
34   Expected<const void *>
35   createKernel(const MultiKernelLoaderSpec &Spec) override {
36     if (!Spec.hasHostFunction()) {
37       return make_error("no host implementation available for kernel " +
38                         Spec.getKernelName());
39     }
40     return static_cast<const void *>(&Spec.getHostFunction());
41   }
42
43   Error destroyKernel(const void *Handle) override { return Error::success(); }
44
45   Expected<const void *> createStream() override {
46     // TODO(jhen): Do something with threads to allow multiple streams.
47     return this;
48   }
49
50   Error destroyStream(const void *Handle) override { return Error::success(); }
51
52   Error launch(const void *PlatformStreamHandle, BlockDimensions BlockSize,
53                GridDimensions GridSize, const void *PKernelHandle,
54                const PackedKernelArgumentArrayBase &ArgumentArray) override {
55     // TODO(jhen): Can we do something with BlockSize and GridSize?
56     if (!(BlockSize.X == 1 && BlockSize.Y == 1 && BlockSize.Z == 1)) {
57       return make_error(
58           "Block dimensions were (" + llvm::Twine(BlockSize.X) + "," +
59           llvm::Twine(BlockSize.Y) + "," + llvm::Twine(BlockSize.Z) +
60           "), but only size (1,1,1) is permitted for this platform");
61     }
62     if (!(GridSize.X == 1 && GridSize.Y == 1 && GridSize.Z == 1)) {
63       return make_error(
64           "Grid dimensions were (" + llvm::Twine(GridSize.X) + "," +
65           llvm::Twine(GridSize.Y) + "," + llvm::Twine(GridSize.Z) +
66           "), but only size (1,1,1) is permitted for this platform");
67     }
68
69     (*static_cast<const std::function<void(const void *const *)> *>(
70         PKernelHandle))(ArgumentArray.getAddresses());
71     return Error::success();
72   }
73
74   Error copyD2H(const void *PlatformStreamHandle, const void *DeviceSrcHandle,
75                 size_t SrcByteOffset, void *HostDst, size_t DstByteOffset,
76                 size_t ByteCount) override {
77     std::memcpy(offset(HostDst, DstByteOffset),
78                 offset(DeviceSrcHandle, SrcByteOffset), ByteCount);
79     return Error::success();
80   }
81
82   Error copyH2D(const void *PlatformStreamHandle, const void *HostSrc,
83                 size_t SrcByteOffset, const void *DeviceDstHandle,
84                 size_t DstByteOffset, size_t ByteCount) override {
85     std::memcpy(offset(DeviceDstHandle, DstByteOffset),
86                 offset(HostSrc, SrcByteOffset), ByteCount);
87     return Error::success();
88   }
89
90   Error copyD2D(const void *PlatformStreamHandle, const void *DeviceSrcHandle,
91                 size_t SrcByteOffset, const void *DeviceDstHandle,
92                 size_t DstByteOffset, size_t ByteCount) override {
93     std::memcpy(offset(DeviceDstHandle, DstByteOffset),
94                 offset(DeviceSrcHandle, SrcByteOffset), ByteCount);
95     return Error::success();
96   }
97
98   Error blockHostUntilDone(const void *PlatformStreamHandle) override {
99     // All host operations are synchronous anyway.
100     return Error::success();
101   }
102
103   Expected<void *> allocateDeviceMemory(size_t ByteCount) override {
104     return std::malloc(ByteCount);
105   }
106
107   Error freeDeviceMemory(const void *Handle) override {
108     std::free(const_cast<void *>(Handle));
109     return Error::success();
110   }
111
112   Error registerHostMemory(void *Memory, size_t ByteCount) override {
113     return Error::success();
114   }
115
116   Error unregisterHostMemory(const void *Memory) override {
117     return Error::success();
118   }
119
120   Error synchronousCopyD2H(const void *DeviceSrcHandle, size_t SrcByteOffset,
121                            void *HostDst, size_t DstByteOffset,
122                            size_t ByteCount) override {
123     std::memcpy(offset(HostDst, DstByteOffset),
124                 offset(DeviceSrcHandle, SrcByteOffset), ByteCount);
125     return Error::success();
126   }
127
128   Error synchronousCopyH2D(const void *HostSrc, size_t SrcByteOffset,
129                            const void *DeviceDstHandle, size_t DstByteOffset,
130                            size_t ByteCount) override {
131     std::memcpy(offset(DeviceDstHandle, DstByteOffset),
132                 offset(HostSrc, SrcByteOffset), ByteCount);
133     return Error::success();
134   }
135
136   Error synchronousCopyD2D(const void *DeviceSrcHandle, size_t SrcByteOffset,
137                            const void *DeviceDstHandle, size_t DstByteOffset,
138                            size_t ByteCount) override {
139     std::memcpy(offset(DeviceDstHandle, DstByteOffset),
140                 offset(DeviceSrcHandle, SrcByteOffset), ByteCount);
141     return Error::success();
142   }
143
144   /// Gets the value at the given index from a GlobalDeviceMemory<T> instance
145   /// created by this class.
146   template <typename T>
147   static T getDeviceValue(const streamexecutor::GlobalDeviceMemory<T> &Memory,
148                           size_t Index) {
149     return static_cast<const T *>(Memory.getHandle())[Index];
150   }
151
152 private:
153   static void *offset(const void *Base, size_t Offset) {
154     return const_cast<char *>(static_cast<const char *>(Base) + Offset);
155   }
156 };
157
158 } // namespace host
159 } // namespace streamexecutor
160
161 #endif // STREAMEXECUTOR_PLATFORMS_HOST_HOSTPLATFORMDEVICE_H