#pragma once
#include <cuda.h>
#include <cuda_runtime_api.h>
#include <cstdint>
#include "xgboost/string_view.h"
namespace xgboost::cudr {
struct CuDriverApi {
using Flags = unsigned long long;
using MemGetAllocationGranularityFn = CUresult(size_t *granularity,
const CUmemAllocationProp *prop,
CUmemAllocationGranularity_flags option);
using MemCreateFn = CUresult(CUmemGenericAllocationHandle *handle, size_t size,
const CUmemAllocationProp *prop, Flags flags);
using MemMapFn = CUresult(CUdeviceptr ptr, size_t size, size_t offset,
CUmemGenericAllocationHandle handle, Flags flags);
using MemAddressReserveFn = CUresult(CUdeviceptr *ptr, size_t size, size_t alignment,
CUdeviceptr addr, Flags flags);
using MemSetAccessFn = CUresult(CUdeviceptr ptr, size_t size, const CUmemAccessDesc *desc,
size_t count);
using MemUnmapFn = CUresult(CUdeviceptr ptr, size_t size);
using MemReleaseFn = CUresult(CUmemGenericAllocationHandle handle);
using MemAddressFreeFn = CUresult(CUdeviceptr ptr, size_t size);
using GetErrorString = CUresult(CUresult error, const char **pStr);
using GetErrorName = CUresult(CUresult error, const char **pStr);
using DeviceGetAttribute = CUresult(int *pi, CUdevice_attribute attrib, CUdevice dev);
using DeviceGet = CUresult(CUdevice *device, int ordinal);
MemGetAllocationGranularityFn *cuMemGetAllocationGranularity{nullptr}; MemCreateFn *cuMemCreate{nullptr};
MemMapFn *cuMemMap{nullptr};
MemAddressReserveFn *cuMemAddressReserve{nullptr}; MemSetAccessFn *cuMemSetAccess{nullptr}; MemUnmapFn *cuMemUnmap{nullptr}; MemReleaseFn *cuMemRelease{nullptr}; MemAddressFreeFn *cuMemAddressFree{nullptr}; GetErrorString *cuGetErrorString{nullptr}; GetErrorName *cuGetErrorName{nullptr}; DeviceGetAttribute *cuDeviceGetAttribute{nullptr}; DeviceGet *cuDeviceGet{nullptr};
CuDriverApi();
void ThrowIfError(CUresult status, StringView fn, std::int32_t line, char const *file) const;
};
[[nodiscard]] CuDriverApi &GetGlobalCuDriverApi();
#define safe_cu(call) \
do { \
auto __status = (call); \
if (__status != CUDA_SUCCESS) { \
::xgboost::cudr::GetGlobalCuDriverApi().ThrowIfError(__status, #call, __LINE__, __FILE__); \
} \
} while (0)
inline auto GetAllocGranularity(CUmemAllocationProp const *prop) {
std::size_t granularity;
safe_cu(GetGlobalCuDriverApi().cuMemGetAllocationGranularity(
&granularity, prop, CU_MEM_ALLOC_GRANULARITY_RECOMMENDED));
return granularity;
}
void MakeCuMemLocation(CUmemLocationType type, CUmemLocation* loc);
[[nodiscard]] CUmemAllocationProp MakeAllocProp(CUmemLocationType type);
}