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 
31 #include "itkOpenCLKernelManager.h"
32 #include "itkOpenCLContext.h"
34 #include <string>
35 
36 namespace itk
37 {
38 // Definition of GPUImageBase 1D
39 typedef struct
40 {
41  cl_float Direction;
44  cl_float Spacing;
45  cl_float Origin;
46  cl_uint Size;
48 
49 // Definition of GPUImageBase 2D
50 typedef struct
51 {
52  cl_float4 Direction;
55  cl_float2 Spacing;
56  cl_float2 Origin;
57  cl_uint2 Size;
59 
60 // Definition of GPUImageBase 3D
61 typedef 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 //----------------------------------------------------------------------------
72 template< typename ImageType >
73 void
74 SetKernelWithDirection( 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 
129 template< typename ImageType >
130 void
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 04-09-2015 for elastix by doxygen 1.8.9.1 elastix logo