go home Home | Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages
itkGPUKernelManagerHelperFunctions.h
Go to the documentation of this file.
1/*=========================================================================
2 *
3 * Copyright UMC Utrecht and contributors
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0.txt
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *=========================================================================*/
18//
19// \author Denis P. Shamonin and Marius Staring. Division of Image Processing,
20// Department of Radiology, Leiden, The Netherlands
21//
22// \note This work was funded by the Netherlands Organisation for
23// Scientific Research (NWO NRG-2010.02 and NWO 639.021.124).
24//
25
26#ifndef itkGPUKernelManagerHelperFunctions_h
27#define itkGPUKernelManagerHelperFunctions_h
28
29#include "itkGPUImage.h"
30
32#include "itkOpenCLContext.h"
34#include <string>
35
36namespace itk
37{
38// Definition of GPUImageBase 1D
39typedef struct
40{
41 cl_float Direction;
44 cl_float Spacing;
45 cl_float Origin;
46 cl_uint Size;
48
49// Definition of GPUImageBase 2D
50typedef struct
51{
52 cl_float4 Direction;
55 cl_float2 Spacing;
56 cl_float2 Origin;
57 cl_uint2 Size;
59
60// Definition of GPUImageBase 3D
61typedef struct
62{
63 cl_float16 Direction; // OpenCL does not have float9
64 cl_float16 IndexToPhysicalPoint; // OpenCL does not have float9
65 cl_float16 PhysicalPointToIndex; // OpenCL does not have float9
66 cl_float3 Spacing;
67 cl_float3 Origin;
68 cl_uint3 Size;
70
71//----------------------------------------------------------------------------
72template <typename ImageType>
73void
74SetKernelWithDirection(const typename ImageType::DirectionType & dir,
75 cl_float & direction1d,
76 cl_float4 & direction2d,
77 cl_float16 & direction3d)
78{
79 const unsigned int ImageDim = (unsigned int)(ImageType::ImageDimension);
80
81 if (ImageDim == 1)
82 {
83 float direction = 0.0f;
84 direction = static_cast<float>(dir[0][0]);
85 direction1d = direction;
86 }
87 else if (ImageDim == 2)
88 {
89 float direction[4];
90 unsigned int index = 0;
91 for (unsigned int i = 0; i < ImageDim; ++i)
92 {
93 for (unsigned int j = 0; j < ImageDim; ++j)
94 {
95 direction[index] = static_cast<float>(dir[i][j]);
96 ++index;
97 }
98 }
99 for (unsigned int i = 0; i < 4; ++i)
100 {
101 direction2d.s[i] = direction[i];
102 }
103 }
104 else
105 {
106 // OpenCL does not support float9 therefore we are using float16
107 float direction[16];
108 unsigned int index = 0;
109 for (unsigned int i = 0; i < ImageDim; ++i)
110 {
111 for (unsigned int j = 0; j < ImageDim; ++j)
112 {
113 direction[index] = static_cast<float>(dir[i][j]);
114 ++index;
115 }
116 }
117 for (unsigned int i = 9; i < 16; ++i)
118 {
119 direction[i] = 0.0f;
120 }
121 for (unsigned int i = 0; i < 16; ++i)
122 {
123 direction3d.s[i] = direction[i];
124 }
125 }
126}
127
128
129template <typename ImageType>
130void
132 const int kernelIdx,
133 cl_uint & argIdx,
134 const typename ImageType::Pointer & image,
135 typename GPUDataManager::Pointer & imageBase,
136 const bool copyImage,
137 const bool copyImageBase)
138{
139 if (ImageType::ImageDimension > 3 || ImageType::ImageDimension < 1)
140 {
141 itkGenericExceptionMacro("SetKernelWithITKImage only supports 1D/2D/3D images.");
142 }
143 // Perform the safe check
144 if (kernelManager.IsNull())
145 {
146 itkGenericExceptionMacro(<< "The kernel manager is NULL.");
147 }
148
149 if (image.IsNull())
150 {
151 itkGenericExceptionMacro(<< "The ITK image is NULL. "
152 "Unable to set ITK image information to the kernel manager.");
153 }
154
155 // Set ITK image to the kernelManager
156 if (copyImage)
157 {
158 kernelManager->SetKernelArgWithImage(kernelIdx, argIdx++, image->GetGPUDataManager());
159 }
160
161 // Set ITK image base to the kernelManager
162 if (copyImageBase)
163 {
164 const unsigned int ImageDim = (unsigned int)(ImageType::ImageDimension);
165 GPUImageBase1D imageBase1D;
166 GPUImageBase2D imageBase2D;
167 GPUImageBase3D imageBase3D;
168
169 // Set size
170 typename ImageType::RegionType largestPossibleRegion;
171 if (image.IsNotNull())
172 {
173 largestPossibleRegion = image->GetLargestPossibleRegion();
174 }
175
176 using size_type = unsigned int;
177 size_type size[ImageType::ImageDimension];
178 for (unsigned int i = 0; i < ImageDim; ++i)
179 {
180 if (image.IsNotNull())
181 {
182 size[i] = static_cast<size_type>(largestPossibleRegion.GetSize()[i]);
183 }
184 else
185 {
186 size[i] = 0;
187 }
188 }
189 if (ImageDim == 1)
190 {
191 imageBase1D.Size = size[0];
192 }
193 else if (ImageDim == 2)
194 {
195 for (unsigned int i = 0; i < ImageDim; ++i)
196 {
197 imageBase2D.Size.s[i] = size[i];
198 }
199 }
200 else if (ImageDim == 3)
201 {
202 for (unsigned int i = 0; i < ImageDim; ++i)
203 {
204 imageBase3D.Size.s[i] = size[i];
205 }
206 }
207
208 // Set spacing
209 float spacing[ImageType::ImageDimension];
210 for (unsigned int i = 0; i < ImageDim; ++i)
211 {
212 if (image.IsNotNull())
213 {
214 spacing[i] = static_cast<float>(image->GetSpacing()[i]);
215 }
216 else
217 {
218 spacing[i] = 0.0f;
219 }
220 }
221 if (ImageDim == 1)
222 {
223 imageBase1D.Spacing = spacing[0];
224 }
225 else if (ImageDim == 2)
226 {
227 for (unsigned int i = 0; i < ImageDim; ++i)
228 {
229 imageBase2D.Spacing.s[i] = spacing[i];
230 }
231 }
232 else if (ImageDim == 3)
233 {
234 for (unsigned int i = 0; i < ImageDim; ++i)
235 {
236 imageBase3D.Spacing.s[i] = spacing[i];
237 }
238 }
239
240 // Set origin
241 float origin[ImageType::ImageDimension];
242 for (unsigned int i = 0; i < ImageDim; ++i)
243 {
244 if (image.IsNotNull())
245 {
246 origin[i] = static_cast<float>(image->GetOrigin()[i]);
247 }
248 else
249 {
250 origin[i] = 0.0f;
251 }
252 }
253 if (ImageDim == 1)
254 {
255 imageBase1D.Origin = origin[0];
256 }
257 else if (ImageDim == 2)
258 {
259 for (unsigned int i = 0; i < ImageDim; ++i)
260 {
261 imageBase2D.Origin.s[i] = origin[i];
262 }
263 }
264 else if (ImageDim == 3)
265 {
266 for (unsigned int i = 0; i < ImageDim; ++i)
267 {
268 imageBase3D.Origin.s[i] = origin[i];
269 }
270 }
271
272 if (image.IsNotNull())
273 {
274 SetKernelWithDirection<ImageType>(
275 image->GetDirection(), imageBase1D.Direction, imageBase2D.Direction, imageBase3D.Direction);
276
277 SetKernelWithDirection<ImageType>(image->GetIndexToPhysicalPoint(),
278 imageBase1D.IndexToPhysicalPoint,
279 imageBase2D.IndexToPhysicalPoint,
280 imageBase3D.IndexToPhysicalPoint);
281
282 SetKernelWithDirection<ImageType>(image->GetPhysicalPointToIndex(),
283 imageBase1D.PhysicalPointToIndex,
284 imageBase2D.PhysicalPointToIndex,
285 imageBase3D.PhysicalPointToIndex);
286 }
287 else
288 {
289 typename ImageType::DirectionType dir_null;
290 dir_null.Fill(0);
291 SetKernelWithDirection<ImageType>(dir_null, imageBase1D.Direction, imageBase2D.Direction, imageBase3D.Direction);
292
293 SetKernelWithDirection<ImageType>(
294 dir_null, imageBase1D.IndexToPhysicalPoint, imageBase2D.IndexToPhysicalPoint, imageBase3D.IndexToPhysicalPoint);
295
296 SetKernelWithDirection<ImageType>(
297 dir_null, imageBase1D.PhysicalPointToIndex, imageBase2D.PhysicalPointToIndex, imageBase3D.PhysicalPointToIndex);
298 }
299
300 // Set image base
301 imageBase->Initialize();
302 imageBase->SetBufferFlag(CL_MEM_READ_ONLY);
303 if (ImageDim == 1)
304 {
305 imageBase->SetBufferSize(sizeof(GPUImageBase1D));
306 }
307 else if (ImageDim == 2)
308 {
309 imageBase->SetBufferSize(sizeof(GPUImageBase2D));
310 }
311 else if (ImageDim == 3)
312 {
313 imageBase->SetBufferSize(sizeof(GPUImageBase3D));
314 }
315
316 imageBase->Allocate();
317
318 if (ImageDim == 1)
319 {
320 imageBase->SetCPUBufferPointer(&imageBase1D);
321 }
322 else if (ImageDim == 2)
323 {
324 imageBase->SetCPUBufferPointer(&imageBase2D);
325 }
326 else if (ImageDim == 3)
327 {
328 imageBase->SetCPUBufferPointer(&imageBase3D);
329 }
330
331 imageBase->SetGPUDirtyFlag(true);
332 imageBase->UpdateGPUBuffer();
333
334 kernelManager->SetKernelArgWithImage(kernelIdx, argIdx++, imageBase);
335 }
336}
337
338
339} // end namespace itk
340
341#endif /* itkGPUKernelManagerHelperFunctions_h */
void SetKernelWithITKImage(OpenCLKernelManager::Pointer &kernelManager, const int kernelIdx, cl_uint &argIdx, const typename ImageType::Pointer &image, typename GPUDataManager::Pointer &imageBase, const bool copyImage, const bool copyImageBase)
void SetKernelWithDirection(const typename ImageType::DirectionType &dir, cl_float &direction1d, cl_float4 &direction2d, cl_float16 &direction3d)


Generated on 2023-01-13 for elastix by doxygen 1.9.6 elastix logo