1 //===-- HostPlatformDevice.h - HostPlatformDevice class ---------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// Declaration of the HostPlatformDevice class.
13 //===----------------------------------------------------------------------===//
15 #ifndef STREAMEXECUTOR_PLATFORMS_HOST_HOSTPLATFORMDEVICE_H
16 #define STREAMEXECUTOR_PLATFORMS_HOST_HOSTPLATFORMDEVICE_H
21 #include "streamexecutor/PlatformDevice.h"
23 namespace streamexecutor {
26 /// A concrete PlatformDevice subclass that performs its work on the host rather
27 /// than offloading to an accelerator.
28 class HostPlatformDevice : public PlatformDevice {
30 std::string getName() const override { return "host"; }
32 std::string getPlatformName() const override { return "host"; }
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());
40 return static_cast<const void *>(&Spec.getHostFunction());
43 Error destroyKernel(const void *Handle) override { return Error::success(); }
45 Expected<const void *> createStream() override {
46 // TODO(jhen): Do something with threads to allow multiple streams.
50 Error destroyStream(const void *Handle) override { return Error::success(); }
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)) {
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");
62 if (!(GridSize.X == 1 && GridSize.Y == 1 && GridSize.Z == 1)) {
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");
69 (*static_cast<const std::function<void(const void *const *)> *>(
70 PKernelHandle))(ArgumentArray.getAddresses());
71 return Error::success();
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();
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();
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();
98 Error blockHostUntilDone(const void *PlatformStreamHandle) override {
99 // All host operations are synchronous anyway.
100 return Error::success();
103 Expected<void *> allocateDeviceMemory(size_t ByteCount) override {
104 return std::malloc(ByteCount);
107 Error freeDeviceMemory(const void *Handle) override {
108 std::free(const_cast<void *>(Handle));
109 return Error::success();
112 Error registerHostMemory(void *Memory, size_t ByteCount) override {
113 return Error::success();
116 Error unregisterHostMemory(const void *Memory) override {
117 return Error::success();
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();
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();
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();
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,
149 return static_cast<const T *>(Memory.getHandle())[Index];
153 static void *offset(const void *Base, size_t Offset) {
154 return const_cast<char *>(static_cast<const char *>(Base) + Offset);
159 } // namespace streamexecutor
161 #endif // STREAMEXECUTOR_PLATFORMS_HOST_HOSTPLATFORMDEVICE_H