Loading...
Searching...
No Matches
cuda.cpp
Go to the documentation of this file.
1/**
2 * CudaGPUDeviceBackend — CUDA GPU device backend.
3 *
4 * Provides device lifecycle management, unified memory allocation via
5 * cudaMallocManaged(), and device synchronization via cudaDeviceSynchronize().
6 *
7 * Device info (name, memory) is queried via cudaGetDeviceProperties().
8 */
9
12
13#include <cuda_runtime.h>
14#include <stdexcept>
15#include <string>
16
17namespace q3 {
18namespace execution {
19namespace gpu {
20namespace device {
21
22namespace {
23
24/**
25 * Check a CUDA runtime API return code and throw on error.
26 */
27void check_cuda_error(cudaError_t error_code, const char* operation) {
28 if (error_code != cudaSuccess) {
29 throw std::runtime_error(std::string("CudaGPUDeviceBackend: ") + operation +
30 " failed: " + cudaGetErrorString(error_code));
31 }
32}
33
34} // anonymous namespace
35
37 public:
38 /**
39 * Construct and initialize the CUDA device backend.
40 *
41 * Selects device 0 and queries its properties.
42 */
44 check_cuda_error(cudaSetDevice(0), "cudaSetDevice");
45 check_cuda_error(cudaGetDeviceProperties(&device_properties_, 0),
46 "cudaGetDeviceProperties");
47 }
48
49 /**
50 * Human-readable name of the CUDA device (e.g., "NVIDIA A100").
51 */
52 std::string device_name() const override {
53 return std::string(device_properties_.name);
54 }
55
56 /**
57 * Total device global memory in bytes.
58 */
59 size_t total_memory_bytes() const override {
60 return device_properties_.totalGlobalMem;
61 }
62
63 /**
64 * CUDA GPUs support native FP64 compute on all supported architectures.
65 */
66 bool supports_double_precision() const override {
67 return true;
68 }
69
70 /**
71 * Allocate unified (managed) memory via cudaMallocManaged().
72 *
73 * Managed memory is accessible from both host and device with automatic
74 * page migration. This simplifies the programming model at the cost of
75 * some potential performance overhead compared to explicit transfers.
76 */
77 void* allocate_unified(size_t size_bytes) override {
78 void* pointer = nullptr;
79 check_cuda_error(cudaMallocManaged(&pointer, size_bytes), "cudaMallocManaged");
80 return pointer;
81 }
82
83 /**
84 * Deallocate memory previously allocated via allocate_unified().
85 */
86 void deallocate(void* pointer) override {
87 check_cuda_error(cudaFree(pointer), "cudaFree");
88 }
89
90 /**
91 * Block until all pending GPU operations have completed.
92 */
93 void synchronize() override {
94 check_cuda_error(cudaDeviceSynchronize(), "cudaDeviceSynchronize");
95 }
96
97 private:
98 cudaDeviceProp device_properties_;
99};
100
101// ── Factory ─────────────────────────────────────────────────────────────────
102
103std::shared_ptr<GPUDeviceBackend> create_gpu_device_backend() {
104 return std::make_shared<CudaGPUDeviceBackend>();
105}
106
107} // namespace device
108} // namespace gpu
109} // namespace execution
110} // namespace q3
size_t total_memory_bytes() const override
Definition cuda.cpp:59
bool supports_double_precision() const override
Definition cuda.cpp:66
std::string device_name() const override
Definition cuda.cpp:52
void deallocate(void *pointer) override
Definition cuda.cpp:86
void * allocate_unified(size_t size_bytes) override
Definition cuda.cpp:77
std::shared_ptr< GPUDeviceBackend > create_gpu_device_backend()
Definition cuda.cpp:103