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, cl_uint & argIdx,
133 const typename ImageType::Pointer & image,
134 typename GPUDataManager::Pointer & imageBase,
135 const bool copyImage,
136 const bool copyImageBase )
137{
138 if( ImageType::ImageDimension > 3 || ImageType::ImageDimension < 1 )
139 {
140 itkGenericExceptionMacro( "SetKernelWithITKImage only supports 1D/2D/3D images." );
141 }
142 // Perform the safe check
143 if( kernelManager.IsNull() )
144 {
145 itkGenericExceptionMacro( << "The kernel manager is NULL." );
146 return;
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 return;
154 }
155
156 // Set ITK image to the kernelManager
157 if( copyImage )
158 {
159 kernelManager->SetKernelArgWithImage( kernelIdx, argIdx++, image->GetGPUDataManager() );
160 }
161
162 // Set ITK image base to the kernelManager
163 if( copyImageBase )
164 {
165 const unsigned int ImageDim = (unsigned int)( ImageType::ImageDimension );
166 GPUImageBase1D imageBase1D;
167 GPUImageBase2D imageBase2D;
168 GPUImageBase3D imageBase3D;
169
170 // Set size
171 typename ImageType::RegionType largestPossibleRegion;
172 if( image.IsNotNull() )
173 {
174 largestPossibleRegion = image->GetLargestPossibleRegion();
175 }
176
177 typedef unsigned int size_type;
178 size_type size[ ImageType::ImageDimension ];
179 for( unsigned int i = 0; i < ImageDim; i++ )
180 {
181 if( image.IsNotNull() )
182 {
183 size[ i ] = static_cast< size_type >( largestPossibleRegion.GetSize()[ i ] );
184 }
185 else
186 {
187 size[ i ] = 0;
188 }
189 }
190 if( ImageDim == 1 )
191 {
192 imageBase1D.Size = size[ 0 ];
193 }
194 else if( ImageDim == 2 )
195 {
196 for( unsigned int i = 0; i < ImageDim; i++ )
197 {
198 imageBase2D.Size.s[ i ] = size[ i ];
199 }
200 }
201 else if( ImageDim == 3 )
202 {
203 for( unsigned int i = 0; i < ImageDim; i++ )
204 {
205 imageBase3D.Size.s[ i ] = size[ i ];
206 }
207 }
208
209 // Set spacing
210 float spacing[ ImageType::ImageDimension ];
211 for( unsigned int i = 0; i < ImageDim; i++ )
212 {
213 if( image.IsNotNull() )
214 {
215 spacing[ i ] = static_cast< float >( image->GetSpacing()[ i ] );
216 }
217 else
218 {
219 spacing[ i ] = 0.0f;
220 }
221 }
222 if( ImageDim == 1 )
223 {
224 imageBase1D.Spacing = spacing[ 0 ];
225 }
226 else if( ImageDim == 2 )
227 {
228 for( unsigned int i = 0; i < ImageDim; i++ )
229 {
230 imageBase2D.Spacing.s[ i ] = spacing[ i ];
231 }
232 }
233 else if( ImageDim == 3 )
234 {
235 for( unsigned int i = 0; i < ImageDim; i++ )
236 {
237 imageBase3D.Spacing.s[ i ] = spacing[ i ];
238 }
239 }
240
241 // Set origin
242 float origin[ ImageType::ImageDimension ];
243 for( unsigned int i = 0; i < ImageDim; i++ )
244 {
245 if( image.IsNotNull() )
246 {
247 origin[ i ] = static_cast< float >( image->GetOrigin()[ i ] );
248 }
249 else
250 {
251 origin[ i ] = 0.0f;
252 }
253 }
254 if( ImageDim == 1 )
255 {
256 imageBase1D.Origin = origin[ 0 ];
257 }
258 else if( ImageDim == 2 )
259 {
260 for( unsigned int i = 0; i < ImageDim; i++ )
261 {
262 imageBase2D.Origin.s[ i ] = origin[ i ];
263 }
264 }
265 else if( ImageDim == 3 )
266 {
267 for( unsigned int i = 0; i < ImageDim; i++ )
268 {
269 imageBase3D.Origin.s[ i ] = origin[ i ];
270 }
271 }
272
273 if( image.IsNotNull() )
274 {
275 SetKernelWithDirection< ImageType >( image->GetDirection(),
276 imageBase1D.Direction,
277 imageBase2D.Direction,
278 imageBase3D.Direction );
279
280 SetKernelWithDirection< ImageType >( image->GetIndexToPhysicalPoint(),
281 imageBase1D.IndexToPhysicalPoint,
282 imageBase2D.IndexToPhysicalPoint,
283 imageBase3D.IndexToPhysicalPoint );
284
285 SetKernelWithDirection< ImageType >( image->GetPhysicalPointToIndex(),
286 imageBase1D.PhysicalPointToIndex,
287 imageBase2D.PhysicalPointToIndex,
288 imageBase3D.PhysicalPointToIndex );
289 }
290 else
291 {
292 typename ImageType::DirectionType dir_null;
293 dir_null.Fill( 0 );
294 SetKernelWithDirection< ImageType >( dir_null,
295 imageBase1D.Direction,
296 imageBase2D.Direction,
297 imageBase3D.Direction );
298
299 SetKernelWithDirection< ImageType >( dir_null,
300 imageBase1D.IndexToPhysicalPoint,
301 imageBase2D.IndexToPhysicalPoint,
302 imageBase3D.IndexToPhysicalPoint );
303
304 SetKernelWithDirection< ImageType >( dir_null,
305 imageBase1D.PhysicalPointToIndex,
306 imageBase2D.PhysicalPointToIndex,
307 imageBase3D.PhysicalPointToIndex );
308 }
309
310 // Set image base
311 imageBase->Initialize();
312 imageBase->SetBufferFlag( CL_MEM_READ_ONLY );
313 if( ImageDim == 1 )
314 {
315 imageBase->SetBufferSize( sizeof( GPUImageBase1D ) );
316 }
317 else if( ImageDim == 2 )
318 {
319 imageBase->SetBufferSize( sizeof( GPUImageBase2D ) );
320 }
321 else if( ImageDim == 3 )
322 {
323 imageBase->SetBufferSize( sizeof( GPUImageBase3D ) );
324 }
325
326 imageBase->Allocate();
327
328 if( ImageDim == 1 )
329 {
330 imageBase->SetCPUBufferPointer( &imageBase1D );
331 }
332 else if( ImageDim == 2 )
333 {
334 imageBase->SetCPUBufferPointer( &imageBase2D );
335 }
336 else if( ImageDim == 3 )
337 {
338 imageBase->SetCPUBufferPointer( &imageBase3D );
339 }
340
341 imageBase->SetGPUDirtyFlag( true );
342 imageBase->UpdateGPUBuffer();
343
344 kernelManager->SetKernelArgWithImage( kernelIdx, argIdx++, imageBase );
345 }
346}
347
348
349} // end namespace itk
350
351#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 1667476801 for elastix by doxygen 1.9.4 elastix logo