Grangeat-based 2D/3D image registration
Loading...
Searching...
No Matches
CUDATexture.h
Go to the documentation of this file.
1#pragma once
2
3#include "Texture.h"
4
5namespace reg23 {
6
8public:
9 CUDATexture2D(const at::Tensor &tensor, const std::string &addressModeX, const std::string &addressModeY);
10
11 CUDATexture2D(const at::Tensor &tensor, Vec<TextureAddressMode, 2> addressModes);
12
13 [[nodiscard]] unsigned long long Handle() const;
14
15 [[nodiscard]] at::Tensor SizeTensor() const;
16
24 void CleanUp() noexcept;
25
26#ifdef __CUDACC__
27
28 [[nodiscard]] Vec<int64_t, 2> Size() const {
29 return Vec<int64_t, 2>::FromIntArrayRef(backingTensor.sizes()).Flipped();
30 }
31
32 // no copy
33 CUDATexture2D(const CUDATexture2D &) = delete;
34
35 void operator=(const CUDATexture2D &) = delete;
36
37 // yes move
38 CUDATexture2D(CUDATexture2D &&other) noexcept
39 : backingTensor(std::move(other.backingTensor)), arrayHandle(other.arrayHandle),
40 textureHandle(other.textureHandle) {
41 other.arrayHandle = nullptr;
42 other.textureHandle = 0;
43 }
44
45 CUDATexture2D &operator=(CUDATexture2D &&other) noexcept {
46 cudaError_t err;
47 if (textureHandle) {
48 err = cudaDestroyTextureObject(textureHandle);
49 if (err != cudaSuccess) {
50 std::cerr << "cudaDestroyTextureObject failed: " << cudaGetErrorString(err) << std::endl;
51 std::terminate();
52 }
53#ifdef DEBUG
54 std::cout << "[C++] CUDA texture " << static_cast<uint64_t>(textureHandle) << " destroyed." << std::endl;
55#endif
56 }
57 if (arrayHandle) {
58 err = cudaFreeArray(arrayHandle);
59 if (err != cudaSuccess) {
60 std::cerr << "cudaFreeArray failed: " << cudaGetErrorString(err) << std::endl;
61 std::terminate();
62 }
63#ifdef DEBUG
64 std::cout << "[C++] CUDA array freed." << std::endl;
65#endif
66 }
67 backingTensor = std::move(other.backingTensor);
68 arrayHandle = other.arrayHandle;
69 textureHandle = other.textureHandle;
70 other.arrayHandle = nullptr;
71 other.textureHandle = 0;
72 return *this;
73 }
74
75 ~CUDATexture2D() {
76 CleanUp();
77 }
78
79private:
80 at::Tensor backingTensor{};
81 cudaArray_t arrayHandle = nullptr;
82 cudaTextureObject_t textureHandle = 0;
83
84#endif
85};
86
88public:
89 CUDATexture3D(const at::Tensor &tensor, const std::string &addressModeX, const std::string &addressModeY,
90 const std::string &addressModeZ);
91
92 CUDATexture3D(const at::Tensor &tensor, Vec<TextureAddressMode, 3> addressModes);
93
94 [[nodiscard]] unsigned long long Handle() const;
95
96 [[nodiscard]] at::Tensor SizeTensor() const;
97
105 void CleanUp() noexcept;
106
107#ifdef __CUDACC__
108
109 [[nodiscard]] Vec<int64_t, 3> Size() const {
110 return Vec<int64_t, 3>::FromIntArrayRef(backingTensor.sizes()).Flipped();
111 }
112
113 // no copy
114 CUDATexture3D(const CUDATexture3D &) = delete;
115
116 void operator=(const CUDATexture3D &) = delete;
117
118 // yes move
119 CUDATexture3D(CUDATexture3D &&other) noexcept
120 : backingTensor(std::move(other.backingTensor)), arrayHandle(other.arrayHandle),
121 textureHandle(other.textureHandle) {
122 other.arrayHandle = nullptr;
123 other.textureHandle = 0;
124 }
125
126 CUDATexture3D &operator=(CUDATexture3D &&other) noexcept {
127 cudaError_t err;
128 if (textureHandle) {
129 err = cudaDestroyTextureObject(textureHandle);
130 if (err != cudaSuccess) {
131 std::cerr << "cudaDestroyTextureObject failed: " << cudaGetErrorString(err) << std::endl << std::flush;
132 std::terminate();
133 }
134#ifdef DEBUG
135 std::cout << "[C++] CUDA texture " << static_cast<uint64_t>(textureHandle) << " destroyed." << std::endl <<
136 std::flush;
137#endif
138 }
139 if (arrayHandle) {
140 err = cudaFreeArray(arrayHandle);
141 if (err != cudaSuccess) {
142 std::cerr << "cudaFreeArray failed: " << cudaGetErrorString(err) << std::endl << std::flush;
143 std::terminate();
144 }
145#ifdef DEBUG
146 std::cout << "[C++] CUDA array freed." << std::endl << std::flush;
147#endif
148 }
149 backingTensor = std::move(other.backingTensor);
150 arrayHandle = other.arrayHandle;
151 textureHandle = other.textureHandle;
152 other.arrayHandle = nullptr;
153 other.textureHandle = 0;
154 return *this;
155 }
156
157 ~CUDATexture3D() {
158#ifdef DEBUG
159 std::cout << "[C++] CUDATexture3D destructing." << std::endl << std::flush;
160#endif
161 CleanUp();
162 }
163
164private:
165 at::Tensor backingTensor{};
166 cudaArray_t arrayHandle = nullptr;
167 cudaTextureObject_t textureHandle = 0;
168
169#endif
170};
171
172
173} // namespace reg23
Definition CUDATexture.h:7
unsigned long long Handle() const
CUDATexture2D(const at::Tensor &tensor, const std::string &addressModeX, const std::string &addressModeY)
CUDATexture2D(const at::Tensor &tensor, Vec< TextureAddressMode, 2 > addressModes)
at::Tensor SizeTensor() const
void CleanUp() noexcept
Cleans up the underlying PyTorch tensor, CUDA texture and CUDA array.
Definition CUDATexture.h:87
CUDATexture3D(const at::Tensor &tensor, const std::string &addressModeX, const std::string &addressModeY, const std::string &addressModeZ)
CUDATexture3D(const at::Tensor &tensor, Vec< TextureAddressMode, 3 > addressModes)
void CleanUp() noexcept
Cleans up the underlying PyTorch tensor, CUDA texture and CUDA array.
unsigned long long Handle() const
at::Tensor SizeTensor() const
A simple vector class derived from std::array<T, N>, providing overrides for all useful operators.
Definition Vec.h:21
__host__ static __device__ constexpr Vec FromIntArrayRef(const at::IntArrayRef &v)
Construct a Vec from an at::IntArrayRef (this is the type of at::Tensor::sizes())
Definition Vec.h:82
__host__ __device__ constexpr Vec Flipped() const
Construct a Vec with the same elements, but in the reverse order.
Definition Vec.h:161
Definition GridSample3DCPU.cpp:6