MLIR 24.0.0git
RocmRuntimeWrappers.cpp
Go to the documentation of this file.
1//===- RocmRuntimeWrappers.cpp - MLIR ROCM runtime wrapper library --------===//
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//
9// Implements C wrappers around the ROCM library for easy linking in ORC jit.
10// Also adds some debugging helpers that are helpful when writing MLIR code to
11// run on GPUs.
12//
13//===----------------------------------------------------------------------===//
14
15#include <cassert>
16#include <cstdint>
17#include <cstdio>
18
20
21#include "hip/hip_runtime.h"
22
23#ifdef _WIN32
24#define MLIR_ROCM_WRAPPERS_EXPORT __declspec(dllexport)
25#else
26#define MLIR_ROCM_WRAPPERS_EXPORT __attribute__((visibility("default")))
27#endif // _WIN32
28
29#define HIP_REPORT_IF_ERROR(expr) \
30 [](hipError_t result) { \
31 if (!result) \
32 return; \
33 const char *name = hipGetErrorName(result); \
34 if (!name) \
35 name = "<unknown>"; \
36 fprintf(stderr, "'%s' failed with '%s'\n", #expr, name); \
37 }(expr)
38
39thread_local static int32_t defaultDevice = 0;
40
41extern "C" MLIR_ROCM_WRAPPERS_EXPORT hipModule_t
42mgpuModuleLoad(void *data, size_t /*gpuBlobSize*/) {
43 hipModule_t module = nullptr;
44 HIP_REPORT_IF_ERROR(hipModuleLoadData(&module, data));
45 return module;
46}
47
48extern "C" MLIR_ROCM_WRAPPERS_EXPORT hipModule_t
49mgpuModuleLoadJIT(void *data, int optLevel, size_t /*assmeblySize*/) {
50 assert(false && "This function is not available in HIP.");
51 return nullptr;
52}
53
54extern "C" MLIR_ROCM_WRAPPERS_EXPORT void mgpuModuleUnload(hipModule_t module) {
55 HIP_REPORT_IF_ERROR(hipModuleUnload(module));
56}
57
58extern "C" MLIR_ROCM_WRAPPERS_EXPORT hipFunction_t
59mgpuModuleGetFunction(hipModule_t module, const char *name) {
60 hipFunction_t function = nullptr;
61 HIP_REPORT_IF_ERROR(hipModuleGetFunction(&function, module, name));
62 return function;
63}
64
65// The wrapper uses intptr_t instead of ROCM's unsigned int to match
66// the type of MLIR's index type. This avoids the need for casts in the
67// generated MLIR code.
68extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
69mgpuLaunchKernel(hipFunction_t function, intptr_t gridX, intptr_t gridY,
70 intptr_t gridZ, intptr_t blockX, intptr_t blockY,
71 intptr_t blockZ, int32_t smem, hipStream_t stream,
72 void **params, void **extra, size_t /*paramsCount*/) {
73 HIP_REPORT_IF_ERROR(hipModuleLaunchKernel(function, gridX, gridY, gridZ,
74 blockX, blockY, blockZ, smem,
75 stream, params, extra));
76}
77
78// Cooperative launch entry point. The cluster dimensions are accepted to
79// match the CUDA wrapper signature, but HIP does not support thread block
80// clusters; passing nonzero cluster dimensions is a usage error.
82 hipFunction_t function, intptr_t gridX, intptr_t gridY, intptr_t gridZ,
83 intptr_t clusterX, intptr_t clusterY, intptr_t clusterZ, intptr_t blockX,
84 intptr_t blockY, intptr_t blockZ, int32_t smem, hipStream_t stream,
85 void **params, void ** /*extra*/) {
86 if (clusterX != 0 || clusterY != 0 || clusterZ != 0) {
87 fprintf(stderr,
88 "mgpuLaunchKernelCooperative: HIP does not support thread block "
89 "clusters (got cluster=%ld,%ld,%ld)\n",
90 clusterX, clusterY, clusterZ);
91 abort();
92 }
94 hipModuleLaunchCooperativeKernel(function, gridX, gridY, gridZ, blockX,
95 blockY, blockZ, smem, stream, params));
96}
97
99 hipStream_t stream = nullptr;
100 HIP_REPORT_IF_ERROR(hipStreamCreate(&stream));
101 return stream;
102}
103
104extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
105mgpuStreamDestroy(hipStream_t stream) {
106 HIP_REPORT_IF_ERROR(hipStreamDestroy(stream));
107}
108
109extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
110mgpuStreamSynchronize(hipStream_t stream) {
111 return HIP_REPORT_IF_ERROR(hipStreamSynchronize(stream));
112}
113
114extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
115mgpuStreamWaitEvent(hipStream_t stream, hipEvent_t event) {
116 HIP_REPORT_IF_ERROR(hipStreamWaitEvent(stream, event, /*flags=*/0));
117}
118
120 hipEvent_t event = nullptr;
121 HIP_REPORT_IF_ERROR(hipEventCreateWithFlags(&event, hipEventDisableTiming));
122 return event;
123}
124
125extern "C" MLIR_ROCM_WRAPPERS_EXPORT void mgpuEventDestroy(hipEvent_t event) {
126 HIP_REPORT_IF_ERROR(hipEventDestroy(event));
127}
128
129extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
130mgpuEventSynchronize(hipEvent_t event) {
131 HIP_REPORT_IF_ERROR(hipEventSynchronize(event));
132}
133
134extern "C" MLIR_ROCM_WRAPPERS_EXPORT void mgpuEventRecord(hipEvent_t event,
135 hipStream_t stream) {
136 HIP_REPORT_IF_ERROR(hipEventRecord(event, stream));
137}
138
139extern "C" MLIR_ROCM_WRAPPERS_EXPORT void *mgpuMemAlloc(uint64_t sizeBytes,
140 hipStream_t /*stream*/,
141 bool /*isHostShared*/) {
142 void *ptr;
143 HIP_REPORT_IF_ERROR(hipMalloc(&ptr, sizeBytes));
144 return ptr;
145}
146
147extern "C" MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemFree(void *ptr,
148 hipStream_t /*stream*/) {
149 HIP_REPORT_IF_ERROR(hipFree(ptr));
150}
151
152extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
153mgpuMemcpy(void *dst, void *src, size_t sizeBytes, hipStream_t stream) {
155 hipMemcpyAsync(dst, src, sizeBytes, hipMemcpyDefault, stream));
156}
157
158extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
159mgpuMemset32(void *dst, int value, size_t count, hipStream_t stream) {
160 HIP_REPORT_IF_ERROR(hipMemsetD32Async(reinterpret_cast<hipDeviceptr_t>(dst),
161 value, count, stream));
162}
163
164extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
165mgpuMemset16(void *dst, int short value, size_t count, hipStream_t stream) {
166 HIP_REPORT_IF_ERROR(hipMemsetD16Async(reinterpret_cast<hipDeviceptr_t>(dst),
167 value, count, stream));
168}
169
170/// Helper functions for writing mlir example code
171
172// Allows to register byte array with the ROCM runtime. Helpful until we have
173// transfer functions implemented.
174extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
175mgpuMemHostRegister(void *ptr, uint64_t sizeBytes) {
176 HIP_REPORT_IF_ERROR(hipHostRegister(ptr, sizeBytes, /*flags=*/0));
177}
178
179// Allows to register a MemRef with the ROCm runtime. Helpful until we have
180// transfer functions implemented.
181extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
183 int64_t elementSizeBytes) {
184 int64_t *sizes = descriptor->sizes;
185 [[maybe_unused]] int64_t *strides = &sizes[rank];
186 int64_t runningStride = 1;
187 // Only densely packed tensors are currently supported.
188 for (int64_t i = rank - 1; i >= 0; --i) {
189 assert(strides[i] == runningStride && "Mismatch in computed dense strides");
190 runningStride *= sizes[i];
191 }
192 uint64_t sizeBytes = runningStride * elementSizeBytes;
193
194 auto *ptr = descriptor->data + descriptor->offset * elementSizeBytes;
195 mgpuMemHostRegister(ptr, sizeBytes);
196}
197
198// Allows to unregister byte array with the ROCM runtime. Helpful until we have
199// transfer functions implemented.
201 HIP_REPORT_IF_ERROR(hipHostUnregister(ptr));
202}
203
204// Allows to unregister a MemRef with the ROCm runtime. Helpful until we have
205// transfer functions implemented.
206extern "C" MLIR_ROCM_WRAPPERS_EXPORT void
208 StridedMemRefType<char, 1> *descriptor,
209 int64_t elementSizeBytes) {
210 auto ptr = descriptor->data + descriptor->offset * elementSizeBytes;
212}
213
214template <typename T>
215void mgpuMemGetDevicePointer(T *hostPtr, T **devicePtr) {
216 HIP_REPORT_IF_ERROR(hipSetDevice(0));
218 hipHostGetDevicePointer((void **)devicePtr, hostPtr, /*flags=*/0));
219}
220
222mgpuMemGetDeviceMemRef1dFloat(float *allocated, float *aligned, int64_t offset,
223 int64_t size, int64_t stride) {
224 float *devicePtr = nullptr;
225 mgpuMemGetDevicePointer(aligned, &devicePtr);
226 return {devicePtr, devicePtr, offset, {size}, {stride}};
227}
228
230mgpuMemGetDeviceMemRef1dInt32(int32_t *allocated, int32_t *aligned,
231 int64_t offset, int64_t size, int64_t stride) {
232 int32_t *devicePtr = nullptr;
233 mgpuMemGetDevicePointer(aligned, &devicePtr);
234 return {devicePtr, devicePtr, offset, {size}, {stride}};
235}
236
237extern "C" MLIR_ROCM_WRAPPERS_EXPORT void mgpuSetDefaultDevice(int32_t device) {
238 defaultDevice = device;
239 HIP_REPORT_IF_ERROR(hipSetDevice(device));
240}
static thread_local int32_t defaultDevice
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemFree(void *ptr, hipStream_t)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuSetDefaultDevice(int32_t device)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuStreamDestroy(hipStream_t stream)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuEventSynchronize(hipEvent_t event)
MLIR_ROCM_WRAPPERS_EXPORT void * mgpuMemAlloc(uint64_t sizeBytes, hipStream_t, bool)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemHostRegister(void *ptr, uint64_t sizeBytes)
Helper functions for writing mlir example code.
MLIR_ROCM_WRAPPERS_EXPORT void mgpuEventRecord(hipEvent_t event, hipStream_t stream)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemset32(void *dst, int value, size_t count, hipStream_t stream)
MLIR_ROCM_WRAPPERS_EXPORT hipModule_t mgpuModuleLoadJIT(void *data, int optLevel, size_t)
MLIR_ROCM_WRAPPERS_EXPORT hipStream_t mgpuStreamCreate()
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemHostUnregisterMemRef(int64_t rank, StridedMemRefType< char, 1 > *descriptor, int64_t elementSizeBytes)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemcpy(void *dst, void *src, size_t sizeBytes, hipStream_t stream)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuLaunchKernelCooperative(hipFunction_t function, intptr_t gridX, intptr_t gridY, intptr_t gridZ, intptr_t clusterX, intptr_t clusterY, intptr_t clusterZ, intptr_t blockX, intptr_t blockY, intptr_t blockZ, int32_t smem, hipStream_t stream, void **params, void **)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuLaunchKernel(hipFunction_t function, intptr_t gridX, intptr_t gridY, intptr_t gridZ, intptr_t blockX, intptr_t blockY, intptr_t blockZ, int32_t smem, hipStream_t stream, void **params, void **extra, size_t)
MLIR_ROCM_WRAPPERS_EXPORT hipEvent_t mgpuEventCreate()
MLIR_ROCM_WRAPPERS_EXPORT void mgpuModuleUnload(hipModule_t module)
MLIR_ROCM_WRAPPERS_EXPORT hipFunction_t mgpuModuleGetFunction(hipModule_t module, const char *name)
void mgpuMemGetDevicePointer(T *hostPtr, T **devicePtr)
MLIR_ROCM_WRAPPERS_EXPORT StridedMemRefType< float, 1 > mgpuMemGetDeviceMemRef1dFloat(float *allocated, float *aligned, int64_t offset, int64_t size, int64_t stride)
#define MLIR_ROCM_WRAPPERS_EXPORT
MLIR_ROCM_WRAPPERS_EXPORT void mgpuStreamWaitEvent(hipStream_t stream, hipEvent_t event)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemset16(void *dst, int short value, size_t count, hipStream_t stream)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuEventDestroy(hipEvent_t event)
MLIR_ROCM_WRAPPERS_EXPORT hipModule_t mgpuModuleLoad(void *data, size_t)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuStreamSynchronize(hipStream_t stream)
MLIR_ROCM_WRAPPERS_EXPORT StridedMemRefType< int32_t, 1 > mgpuMemGetDeviceMemRef1dInt32(int32_t *allocated, int32_t *aligned, int64_t offset, int64_t size, int64_t stride)
#define HIP_REPORT_IF_ERROR(expr)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemHostUnregister(void *ptr)
MLIR_ROCM_WRAPPERS_EXPORT void mgpuMemHostRegisterMemRef(int64_t rank, StridedMemRefType< char, 1 > *descriptor, int64_t elementSizeBytes)
StridedMemRef descriptor type with static rank.