Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
CudaInterface.h
Go to the documentation of this file.
1/*
2 * Project: RooFit
3 * Author:
4 * Jonas Rembser, CERN 2023
5 *
6 * Copyright (c) 2023, CERN
7 *
8 * Redistribution and use in source and binary forms,
9 * with or without modification, are permitted according to the terms
10 * listed in LICENSE (http://roofit.sourceforge.net/license.txt)
11 */
12
13#ifndef CudaInterface_h
14#define CudaInterface_h
15
16#include <cstddef>
17#include <memory>
18
19#ifdef __CUDACC__
20#include <sstream>
21#include <stdexcept>
22#include <string>
23
24#define ERRCHECK(err) RooBatchCompute::CudaInterface::checkCudaErrors((err), __func__, __FILE__, __LINE__)
25
26namespace RooBatchCompute {
27namespace CudaInterface {
28
29inline void checkCudaErrors(cudaError_t error, std::string const &func, std::string const &file, int line)
30{
31 if (error != cudaSuccess) {
32 std::stringstream errMsg;
33 errMsg << func << "(), " << file << ":" << std::to_string(line) << " : " << cudaGetErrorString(error);
34 throw std::runtime_error(errMsg.str());
35 }
36}
37
38} // namespace CudaInterface
39} // namespace RooBatchCompute
40#endif // __CUDACC__
41
42namespace RooBatchCompute {
43
44/*
45 * C++ interface around CUDA functionality.
46 *
47 * Generally, if the call to the underlying CUDA function does not return
48 * `cudaSuccess`, a `std::runtime_error` is thrown.
49 *
50 * \ingroup RooFitCuda
51 */
52namespace CudaInterface {
53
54/// \cond ROOFIT_INTERNAL
55
56template <class T>
57struct Deleter {
58 void operator()(void *ptr);
59};
60
61/// \endcond
62
63/*
64 * Wrapper around cudaStream_t.
65 */
67public:
68 CudaStream();
69
70// When compiling with NVCC, we allow setting and getting the actual CUDA objects from the wrapper.
71#ifdef __CUDACC__
72 inline cudaStream_t *get() { return reinterpret_cast<cudaStream_t *&>(_ptr); }
73 inline operator cudaStream_t() { return *reinterpret_cast<cudaStream_t *>(_ptr.get()); }
74#endif
75private:
76 std::unique_ptr<void, Deleter<CudaStream>> _ptr;
77};
78
79/// \cond ROOFIT_INTERNAL
80void copyHostToDeviceImpl(const void *src, void *dest, std::size_t n, CudaStream * = nullptr);
81void copyDeviceToHostImpl(const void *src, void *dest, std::size_t n, CudaStream * = nullptr);
82void copyDeviceToDeviceImpl(const void *src, void *dest, std::size_t n, CudaStream * = nullptr);
83/// \endcond
84
85/**
86 * Copies data from the host to the CUDA device.
87 *
88 * @param[in] src Pointer to the source memory on the host.
89 * @param[in] dest Pointer to the destination memory on the device.
90 * @param[in] n Number of bytes to copy.
91 * @param[in] stream CudaStream for asynchronous memory transfer (optional).
92 */
93template <class T>
94void copyHostToDevice(const T *src, T *dest, std::size_t n, CudaStream *stream = nullptr)
95{
96 copyHostToDeviceImpl(src, dest, sizeof(T) * n, stream);
97}
98
99/**
100 * Copies data from the CUDA device to the host.
101 *
102 * @param[in] src Pointer to the source memory on the device.
103 * @param[in] dest Pointer to the destination memory on the host.
104 * @param[in] n Number of bytes to copy.
105 * @param[in] stream CudaStream for asynchronous memory transfer (optional).
106 */
107template <class T>
108void copyDeviceToHost(const T *src, T *dest, std::size_t n, CudaStream *stream = nullptr)
109{
110 copyDeviceToHostImpl(src, dest, sizeof(T) * n, stream);
111}
112
113/**
114 * Copies data from the CUDA device to the CUDA device.
115 *
116 * @param[in] src Pointer to the source memory on the device.
117 * @param[in] dest Pointer to the destination memory on the device.
118 * @param[in] n Number of bytes to copy.
119 * @param[in] stream CudaStream for asynchronous memory transfer (optional).
120 */
121template <class T>
122void copyDeviceToDevice(const T *src, T *dest, std::size_t n, CudaStream *stream = nullptr)
123{
124 copyDeviceToDeviceImpl(src, dest, sizeof(T) * n, stream);
125}
126
127/// \cond ROOFIT_INTERNAL
128
129// The user should not use these "Memory" classes directly, but instead the typed
130// "Array" classes. That's why we tell doxygen that this is internal.
131
132class DeviceMemory {
133public:
134 DeviceMemory(std::size_t n, std::size_t typeSize);
135
136 std::size_t size() const { return _size; }
137 void *data() { return _data.get(); }
138 void const *data() const { return _data.get(); }
139
140private:
141 std::unique_ptr<void, Deleter<DeviceMemory>> _data;
142 std::size_t _size = 0;
143};
144
145class PinnedHostMemory {
146public:
147 PinnedHostMemory(std::size_t n, std::size_t typeSize);
148
149 std::size_t size() const { return _size; }
150 void *data() { return _data.get(); }
151 void const *data() const { return _data.get(); }
152
153private:
154 std::unique_ptr<void, Deleter<PinnedHostMemory>> _data;
155 std::size_t _size = 0;
156};
157/// \endcond
158
159/**
160 * @class Array
161 * @brief A templated class for managing an array of data using a specified memory type.
162 *
163 * The Array class provides a convenient interface for managing an array of
164 * data using different memory types (e.g., memory on the host or device).
165 * The memory is automatically freed at the end of the lifetime.
166 *
167 * @tparam Data_t The type of data elements to be stored in the array.
168 * @tparam Memory_t The type of memory that provides storage for the array.
169 */
170template <class Data_t, class Memory_t>
171class Array : public Memory_t {
172public:
173 /**
174 * @brief Constructor to create an Array object with a specified size.
175 * @param n The size of the array (number of elements).
176 */
177 Array(std::size_t n) : Memory_t{n, sizeof(Data_t)} {}
178
179 // Needs to be declared explicitly for doxygen to mention it.
180 /**
181 * @brief Get the size of the array.
182 * @return The size of the array (number of elements).
183 *
184 * This function returns the number of elements in the array.
185 */
186 inline std::size_t size() const { return Memory_t::size(); }
187
188 /**
189 * @brief Get a pointer to the start of the array.
190 * @return A pointer to the start of the array.
191 *
192 * This function returns a pointer to the underlying memory.
193 * It allows direct manipulation of array elements.
194 */
195 inline Data_t *data() { return static_cast<Data_t *>(Memory_t::data()); }
196
197 /**
198 * @brief Get a const pointer to the start of the array.
199 * @return A const pointer to the start of the array.
200 *
201 * This function returns a const pointer to the underlying memory.
202 * It allows read-only access to array elements.
203 */
204 inline Data_t const *data() const { return static_cast<Data_t const *>(Memory_t::data()); }
205};
206
207/**
208 * An array of specific type that is allocated on the device with `cudaMalloc` and freed with `cudaFree`.
209 */
210template <class T>
212
213/**
214 * A pinned array of specific type that allocated on the host with `cudaMallocHost` and freed with `cudaFreeHost`.
215 * The memory is "pinned", i.e. page-locked and accessible to the device for fast copying.
216 * \see The documentation of `cudaMallocHost` on <a
217 * href="https://developer.download.nvidia.com/compute/DevZone/docs/html/C/doc/html/group__CUDART__HIGHLEVEL_ge439496de696b166ba457dab5dd4f356.html">developer.download.nvidia.com</a>.
218 */
219template <class T>
221
222} // namespace CudaInterface
223} // namespace RooBatchCompute
224
225#endif
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t dest
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
A templated class for managing an array of data using a specified memory type.
Array(std::size_t n)
Constructor to create an Array object with a specified size.
Data_t * data()
Get a pointer to the start of the array.
Data_t const * data() const
Get a const pointer to the start of the array.
std::size_t size() const
Get the size of the array.
CudaStream()
Creates a new CUDA stream.
std::unique_ptr< void, Deleter< CudaStream > > _ptr
TLine * line
const Int_t n
Definition legend1.C:16
void copyDeviceToDevice(const T *src, T *dest, std::size_t n, CudaStream *stream=nullptr)
Copies data from the CUDA device to the CUDA device.
void copyHostToDevice(const T *src, T *dest, std::size_t n, CudaStream *stream=nullptr)
Copies data from the host to the CUDA device.
void copyDeviceToHost(const T *src, T *dest, std::size_t n, CudaStream *stream=nullptr)
Copies data from the CUDA device to the host.
Namespace for dispatching RooFit computations to various backends.