# GPUDemon running puzzles.

**URL:** <https://discourse.itk.org/t/gpudemon-running-puzzles/5353>\
**Category:** Algorithms\
**Tags:** registration\
**Created:** [September 22, 2022, 7:49am UTC](https://discourse.itk.org/t/gpudemon-running-puzzles/5353 "2022-09-22T07:49:00Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Hongying\_Feng](https://discourse.itk.org/user_avatar/discourse.itk.org/hongying_feng/32/1984_2.png) [@Hongying\_Feng](https://discourse.itk.org/u/Hongying_Feng)\
**Post date:** [September 22, 2022, 7:49am UTC](https://discourse.itk.org/t/gpudemon-running-puzzles/5353/1 "2022-09-22T07:49:00Z")

</div>

Hi,

I am trying to use the GPUDemonRegistrationFilter to speed up the Registration. Here is how I implement it.  
First, I used the following iteration observer.

class CommandIterationUpdate : public itk::Command  
{  
public:  
using Self = CommandIterationUpdate;  
using Superclass = itk::Command;  
using Pointer = itk::SmartPointer;  
itkNewMacro(Self);  
protected:  
CommandIterationUpdate() = default;  
// define ITK short-hand types  
using InternalPixelType = float;  
using GPUImageType = itk::GPUImage\<InternalPixelType, 3\>;  
using VectorPixelType = itk::Vector\<float, 3\>;  
using GPUDisplacementFieldType = itk::GPUImage\<VectorPixelType, 3\>;  
using GPURegistrationFilterType =  
itk::GPUDemonsRegistrationFilter\<GPUImageType,  
GPUImageType,  
GPUDisplacementFieldType\>;  
public:  
void  
Execute(const itk::Object\*, const itk::EventObject&) override  
{  
std::cout \<\< “Warning: The const Execute method shouldn’t be called”  
\<\< std::endl;  
}  
void  
Execute(itk::Object\* caller, const itk::EventObject& event) override  
{  
auto\* filter = static\_cast\<GPURegistrationFilterType\*\>(caller);  
if (!(itk::IterationEvent().CheckEvent(&event)))  
{  
return;  
}  
if (filter)  
{  
filter-\>SetMaximumRMSError(MaxRmsE[RmsCounter]);  
std::cout \<\< filter-\>GetMetric()  
\<\< " RMS Change: " \<\< filter-\>GetRMSChange() \<\< std::endl;  
std::cout \<\< "Level Tolerance= " \<\< filter-\>GetMaximumRMSError()  
\<\< std::endl;  
}  
}  
};

Then I did the registration like a CPU demon by just replacing the image and filter to the GPU version.

```
auto fixedImageCaster = ImageCasterType::New();
fixedImageCaster->SetInput(targetReader->GetOutput());
auto movingImageCaster = ImageCasterType::New();
movingImageCaster->SetInput(matcher->GetOutput());
GPUImageType::Pointer GPUFixedImage = fixedImageCaster->GetOutput();
GPUImageType::Pointer GPUMovingImage = movingImageCaster->GetOutput();

```

The matcher is a HistogramMatchingImageFilter that I did with CPU images. And then the GPU filter.

```
using VectorPixelType = itk::Vector<float, Dimension>;
using DisplacementFieldType = itk::Image<VectorPixelType, Dimension>;
using GPUDisplacementFieldType = itk::GPUImage<VectorPixelType, Dimension>;
using GPURegistrationFilterType =
    itk::GPUDemonsRegistrationFilter<GPUImageType,
    GPUImageType,
    GPUDisplacementFieldType>;
auto GPUfilter = GPURegistrationFilterType::New();
GPUfilter->SetStandardDeviations(1.0);
GPUfilter->SetNumberOfIterations(40);
GPUfilter->SetFixedImage(GPUFixedImage);
GPUfilter->SetMovingImage(GPUMovingImage);
 auto observer = CommandIterationUpdate::New();
 GPUfilter->AddObserver(itk::IterationEvent(), observer);
try
{
    GPUfilter->Update();
}
catch (const itk::ExceptionObject& excp)
{
    std::cerr << excp << std::endl;
    return EXIT_FAILURE;
}

```

The compiling was correct and after I execute it with an example, I got someting as follows.

Platform : NVIDIA CUDA  
NVIDIA GeForce GTX 1060 6GB  
Maximum Work Item Sizes : { 1024, 1024, 64 }  
Maximum Work Group Size : 1024  
Alignment in bits of the base address : 4096  
Smallest alignment in bytes for any data type : 128  
cl\_khr\_global\_int32\_base\_atomics cl\_khr\_global\_int32\_extended\_atomics cl\_khr\_local\_int32\_base\_atomics cl\_khr\_local\_int32\_extended\_atomics cl\_khr\_fp64 cl\_khr\_3d\_image\_writes cl\_khr\_byte\_addressable\_store cl\_khr\_icd cl\_khr\_gl\_sharing cl\_nv\_compiler\_options cl\_nv\_device\_attribute\_query cl\_nv\_pragma\_unroll cl\_nv\_d3d10\_sharing cl\_khr\_d3d10\_sharing cl\_nv\_d3d11\_sharing cl\_nv\_copy\_opts cl\_nv\_create\_buffer cl\_khr\_int64\_base\_atomics cl\_khr\_int64\_extended\_atomics cl\_khr\_device\_uuid cl\_khr\_pci\_bus\_info cl\_khr\_external\_semaphore cl\_khr\_external\_memory cl\_khr\_external\_semaphore\_win32 cl\_khr\_external\_memory\_win32  
5334.71 RMS Change: 0.267018  
Level Tolerance= 0.8

It seemed that CUDA worked. However, I set the iteration to 40 while the observer only gave me 1 print. There should be 40 prints. Dose anyone know what is going on?  
Thanks a lot!
