Discussion:
[ITK-users] Problems Using GPU Filters
Andaharoo
2017-06-30 02:19:36 UTC
Permalink
I've been looking to use some of the GPU filters provided by ITK recently.
Namely the GPU anisotropic filter and binary threshold filter. I downloaded
CUDA and ran cmake again with use gpu on flag and it found all my cuda stuff
automatically. Everything appeared to build fine. I then looked up some
implementation details and examples but couldn't really find any. There was
one itk powerpoint from a long while ago that seemed to suggest I'd be able
to just put a gpu filter in the pipeline like any other filter. I liked this
implementation but it didn't work. So right now I have a pipeline that looks
like the following in order to load images with vtk, process with itk, and
then render with vtk.

vtkToItkFilter -> array of ImageToImageFilters all connected ->
itkToVtkFilter

I tried to stick the GPUBinaryThresholdImageFilter in the array like I would
a normal filter connecting it appropriately and calling update but it broke
throwing a read access violation on line 46 of the GPUGenerateData function
in itkGPUUnaryFunctorImageFilter.hxx saying otPtr.m_Pointer was nullptr.

My code goes a little something like this:

typedef itk::Image<float, 3> Image;
typedef itk::GPUBinaryThresholdImageFilter<Image, Image>
GPUBinaryThresholdFilter;
GPUBinaryThresholdFilter::Pointer filter = GPUBinaryThresholdFilter::New();
double* range = pipe->GetOutput()->GetScalarRange();
filter->SetLowerThreshold(filterWidget->getDoubleFromSlider("Lower"));
filter->SetUpperThreshold(filterWidget->getDoubleFromSlider("Upper"));
filter->SetOutsideValue(range[0]);
filter->SetInsideValue(range[1]);
filters.push_back(filter);
if (filters.size() > 0)
filter->SetInput(filters.back()->GetOutput());
else
filter->SetInput(vtkToItkLoader->GetOutput());
itkToVtkFilter->SetInput(filters.back()->GetOutput());



--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Emiliano Beronich
2017-06-30 11:52:48 UTC
Permalink
Hi Andarahoo,

GPUBinaryThresholdImageFilter should be used with GPUImage.
Try defining:
typedef itk::GPUImage<float, 3> Image;

There is a cast in the method GPUUnaryFunctorImageFilter::GenerateData
(ancester of GPUBinaryThresholdImageFilter) which may be the cause of the
null pointer:

typename GPUOutputImage::Pointer otPtr = dynamic_cast< GPUOutputImage *
( this->ProcessObject::GetOutput(0) );
Cheers,
Emiliano
I've been looking to use some of the GPU filters provided by ITK recently.
Namely the GPU anisotropic filter and binary threshold filter. I downloaded
CUDA and ran cmake again with use gpu on flag and it found all my cuda stuff
automatically. Everything appeared to build fine. I then looked up some
implementation details and examples but couldn't really find any. There was
one itk powerpoint from a long while ago that seemed to suggest I'd be able
to just put a gpu filter in the pipeline like any other filter. I liked this
implementation but it didn't work. So right now I have a pipeline that looks
like the following in order to load images with vtk, process with itk, and
then render with vtk.
vtkToItkFilter -> array of ImageToImageFilters all connected ->
itkToVtkFilter
I tried to stick the GPUBinaryThresholdImageFilter in the array like I would
a normal filter connecting it appropriately and calling update but it broke
throwing a read access violation on line 46 of the GPUGenerateData function
in itkGPUUnaryFunctorImageFilter.hxx saying otPtr.m_Pointer was nullptr.
typedef itk::Image<float, 3> Image;
typedef itk::GPUBinaryThresholdImageFilter<Image, Image>
GPUBinaryThresholdFilter;
GPUBinaryThresholdFilter::Pointer filter = GPUBinaryThresholdFilter::New(
);
double* range = pipe->GetOutput()->GetScalarRange();
filter->SetLowerThreshold(filterWidget->getDoubleFromSlider("Lower"));
filter->SetUpperThreshold(filterWidget->getDoubleFromSlider("Upper"));
filter->SetOutsideValue(range[0]);
filter->SetInsideValue(range[1]);
filters.push_back(filter);
if (filters.size() > 0)
filter->SetInput(filters.back()->GetOutput());
else
filter->SetInput(vtkToItkLoader->GetOutput());
itkToVtkFilter->SetInput(filters.back()->GetOutput());
--
View this message in context: http://itk-insight-users.
2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
Andaharoo
2017-07-25 17:05:08 UTC
Permalink
How exactly do I load/setup a GPUImage. There seem to be tons of examples on
how to make GPU filters but none on how to use them? Or convert between a
regular itk image and a GPUImage.



--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036p7590057.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Andaharoo
2017-08-01 18:15:11 UTC
Permalink
Yeah I figured this out and it allowed me to use
GPUGradientAnisotropicImageFilter.
I was using GPUGradientAnisotropicImageFilter<itkImage, itkImage> and using
GPUGradientAnisotropicImageFilter<itkImage, itkGPUImage> fixed it.

But I can't seem to use any other GPU filters unless I apply them after the
gradient anisotropic? It's not converting and I'm unable to setup my readers
to use itkGPUImage so I can't do
GPUGradientAnisotropicImageFilter<itkGPUImage, itkGPUImage>

Pipeline:
vtkImage -> vtktoitk filter -> gpu filter -> itktovtkfilter ->

Also does
GPUGradientAnisotropicImageFilter<itkGPUImage, itkImage> differ from
GPUGradientAnisotropicImageFilter<itkImage, itkGPUImage> because the output
of a gpu filter can go back to a cpu filter? This is what made me initially
think I would use GPUGradientAnisotropicImageFilter<itkImage, itkImage>

Thanks



--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036p7590114.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Andaharoo
2017-08-01 22:23:01 UTC
Permalink
I can't get the images to go from CPU to GPU on GPUMeanImageFilter,
GPUBinaryThresholdImageFilter, and GPUDiscreteGaussianImageFilter. So I
can't start my gpu pipeline with these filters. If I apply something like
GPUGradientAnisotropicImageFilter (which does work) then I can apply the
other filters confirming that it can go GPU to GPU but not CPU to GPU on
those 3 filters. Do these 3 filters not support conversion?

GPUInputImage::Pointer inPtr =
dynamic_cast<GPUInputImage*>(this->ProcessObject::GetInput(0));
inPtr was null when I debugged GPUMeanImageFilter. This line also doesn't
make sense in terms of using an Image since it would just return null if you
gave it an Image that wasn't allocated as a GPUImage. Unless the cpu image
gets converted to a gpu image elsewhere beforehand?

It seems as though only GPUInPlaceImageFilters work with CPU - GPU
conversion for me? I can't quite understand the GPUInPlaceImageFilters
source yet so I'm not so sure why GPUGradientAnisotropicImageFilter works.
They are, of course, different in terms of how they manage memory.



--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036p7590122.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com
Matt McCormick
2017-08-04 13:38:16 UTC
Permalink
Hi Andaharoo,

You may have identified a bug. I am also seeing local failures in the
regression tests for the referenced classes. I will investigate
further next week.

Thanks,
Matt
Post by Andaharoo
I can't get the images to go from CPU to GPU on GPUMeanImageFilter,
GPUBinaryThresholdImageFilter, and GPUDiscreteGaussianImageFilter. So I
can't start my gpu pipeline with these filters. If I apply something like
GPUGradientAnisotropicImageFilter (which does work) then I can apply the
other filters confirming that it can go GPU to GPU but not CPU to GPU on
those 3 filters. Do these 3 filters not support conversion?
GPUInputImage::Pointer inPtr =
dynamic_cast<GPUInputImage*>(this->ProcessObject::GetInput(0));
inPtr was null when I debugged GPUMeanImageFilter. This line also doesn't
make sense in terms of using an Image since it would just return null if you
gave it an Image that wasn't allocated as a GPUImage. Unless the cpu image
gets converted to a gpu image elsewhere beforehand?
It seems as though only GPUInPlaceImageFilters work with CPU - GPU
conversion for me? I can't quite understand the GPUInPlaceImageFilters
source yet so I'm not so sure why GPUGradientAnisotropicImageFilter works.
They are, of course, different in terms of how they manage memory.
--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036p7590122.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Matt McCormick
2017-08-11 16:22:34 UTC
Permalink
Following up, I did not have a chance to fully address this. Progress
is started here:

http://review.source.kitware.com/#/q/topic:gpu-mean-filters

The GPUMeanImageFilter tests are failing:

itkGPUMeanImageFilterTest2D
itkGPUMeanImageFilterTest3D

I will take another look in a few weeks.

Thanks,
Matt

On Fri, Aug 4, 2017 at 9:38 AM, Matt McCormick
Post by Matt McCormick
Hi Andaharoo,
You may have identified a bug. I am also seeing local failures in the
regression tests for the referenced classes. I will investigate
further next week.
Thanks,
Matt
Post by Andaharoo
I can't get the images to go from CPU to GPU on GPUMeanImageFilter,
GPUBinaryThresholdImageFilter, and GPUDiscreteGaussianImageFilter. So I
can't start my gpu pipeline with these filters. If I apply something like
GPUGradientAnisotropicImageFilter (which does work) then I can apply the
other filters confirming that it can go GPU to GPU but not CPU to GPU on
those 3 filters. Do these 3 filters not support conversion?
GPUInputImage::Pointer inPtr =
dynamic_cast<GPUInputImage*>(this->ProcessObject::GetInput(0));
inPtr was null when I debugged GPUMeanImageFilter. This line also doesn't
make sense in terms of using an Image since it would just return null if you
gave it an Image that wasn't allocated as a GPUImage. Unless the cpu image
gets converted to a gpu image elsewhere beforehand?
It seems as though only GPUInPlaceImageFilters work with CPU - GPU
conversion for me? I can't quite understand the GPUInPlaceImageFilters
source yet so I'm not so sure why GPUGradientAnisotropicImageFilter works.
They are, of course, different in terms of how they manage memory.
--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036p7590122.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Matt McCormick
2017-09-08 18:34:50 UTC
Permalink
The failing tests I observed may have been due to local driver issues.

These fixes will be available in the 4.12.2 release.

Thanks,
Matt

On Fri, Aug 11, 2017 at 12:22 PM, Matt McCormick
Post by Matt McCormick
Following up, I did not have a chance to fully address this. Progress
http://review.source.kitware.com/#/q/topic:gpu-mean-filters
itkGPUMeanImageFilterTest2D
itkGPUMeanImageFilterTest3D
I will take another look in a few weeks.
Thanks,
Matt
On Fri, Aug 4, 2017 at 9:38 AM, Matt McCormick
Post by Matt McCormick
Hi Andaharoo,
You may have identified a bug. I am also seeing local failures in the
regression tests for the referenced classes. I will investigate
further next week.
Thanks,
Matt
Post by Andaharoo
I can't get the images to go from CPU to GPU on GPUMeanImageFilter,
GPUBinaryThresholdImageFilter, and GPUDiscreteGaussianImageFilter. So I
can't start my gpu pipeline with these filters. If I apply something like
GPUGradientAnisotropicImageFilter (which does work) then I can apply the
other filters confirming that it can go GPU to GPU but not CPU to GPU on
those 3 filters. Do these 3 filters not support conversion?
GPUInputImage::Pointer inPtr =
dynamic_cast<GPUInputImage*>(this->ProcessObject::GetInput(0));
inPtr was null when I debugged GPUMeanImageFilter. This line also doesn't
make sense in terms of using an Image since it would just return null if you
gave it an Image that wasn't allocated as a GPUImage. Unless the cpu image
gets converted to a gpu image elsewhere beforehand?
It seems as though only GPUInPlaceImageFilters work with CPU - GPU
conversion for me? I can't quite understand the GPUInPlaceImageFilters
source yet so I'm not so sure why GPUGradientAnisotropicImageFilter works.
They are, of course, different in terms of how they manage memory.
--
View this message in context: http://itk-insight-users.2283740.n2.nabble.com/Problems-Using-GPU-Filters-tp7590036p7590122.html
Sent from the ITK Insight Users mailing list archive at Nabble.com.
_____________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Andaharoo
2017-09-14 01:46:57 UTC
Permalink
I pulled the latest branch on github and this issue is still present on all
my systems. Here is a clear example of code that does not work.

typedef itk::GPUImage<unsigned char, 3> GPUImage;
typedef itk::Image<unsigned char, 3> Image;

// Read image with VTK
vtkSmartPointer<vtkPNGReader> reader = vtkSmartPointer<vtkPNGReader>::New();
reader->SetFileName("test.png");
reader->Update();

// Convert VTK to ITK
typedef itk::VTKImageToImageFilter<Image> VtkToItkFilter;
VtkToItkFilter::Pointer vtkToItkFilter = VtkToItkFilter::New();
vtkToItkFilter->SetInput(cast->GetOutput());
vtkToItkFilter->Update();

// GPU Binary Thresholding
typedef itk::GPUBinaryThresholdImageFilter<Image, GPUImage>
GPUBinaryThresholdFilterType;
GPUBinaryThresholdFilterType::Pointer binaryThresholdFilter =
GPUBinaryThresholdFilterType::New();
binaryThresholdFilter->SetInput(vtkToItkFilter->GetOutput());
binaryThresholdFilter->SetLowerThreshold(150.0);
binaryThresholdFilter->SetUpperThreshold(250.0);
binaryThresholdFilter->SetOutsideValue(0);
binaryThresholdFilter->SetInsideValue(355.0);
binaryThresholdFilter->Update();

GPU Gradient Anisotropic is the only gpu filter that works in this example.
Probably because it's the only in place gpu filter. I've tried replacing
"<Image>" with "<GPUImage>" as well.

With the <Image, GPUImage> scenario I get read access violation as
GPUDataManager is null. Expect when using gpu gradient anisotropic.

With <GPUImage, GPUImage> and <GPUImage> on the conversion filter, the
conversion filter fails to generate data.

And as stated in earlier messages, if I first use gpu gradient anisotropic
(only gpu filter that works after vtktoitk) I can then successfully apply
gpu binary thresholding.
I'd look further into the issue but I'm not really sure where gpu images
even get allocated so it would be hard for me to debug. Perhaps I can write
my own gpu filters using gradient anisotropic as reference.



--
Sent from: http://itk-insight-users.2283740.n2.nabble.com/
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users
Matt McCormick
2017-09-14 19:32:17 UTC
Permalink
Thank you for example code and description.


To improve performance and reduce memory usage, ITK re-uses memory
when possible. For example, many filters have an option to run in
place on their inputs.


The VTK bridge and GPU filters are special cases that may be
conflicting here. The GPU data manager moves ITK memory from the CPU
to GPU when required. However, the VTK bridge tries to prevent copying
the memory allocated by VTK.


There are a few approaches that can be taken.


First, consider using itk::ImageFileReader instead of vtkPNGReader
then VTKImageToImageFilter. This has the added advantage that it will
automatically also support many other file formats.

Second, place an ITK filter, like CastImageFilter, after the VTK
bridge filter and before the GPU filter. However, may sure to call
.InPlaceOff().


If you are considering writing your own GPU filters, you may also be
interested in this module [1]. This is a work in progress, but it will
allow writing filters that use ArrayFire underneath the hood.
ArrayFire is easier to program with than OpenCL, and it is optimized
for many GPGPU architectures.


[1] https://github.com/InsightSoftwareConsortium/ITKArrayFire
Post by Andaharoo
I pulled the latest branch on github and this issue is still present on all
my systems. Here is a clear example of code that does not work.
typedef itk::GPUImage<unsigned char, 3> GPUImage;
typedef itk::Image<unsigned char, 3> Image;
// Read image with VTK
vtkSmartPointer<vtkPNGReader> reader = vtkSmartPointer<vtkPNGReader>::New();
reader->SetFileName("test.png");
reader->Update();
// Convert VTK to ITK
typedef itk::VTKImageToImageFilter<Image> VtkToItkFilter;
VtkToItkFilter::Pointer vtkToItkFilter = VtkToItkFilter::New();
vtkToItkFilter->SetInput(cast->GetOutput());
vtkToItkFilter->Update();
// GPU Binary Thresholding
typedef itk::GPUBinaryThresholdImageFilter<Image, GPUImage>
GPUBinaryThresholdFilterType;
GPUBinaryThresholdFilterType::Pointer binaryThresholdFilter =
GPUBinaryThresholdFilterType::New();
binaryThresholdFilter->SetInput(vtkToItkFilter->GetOutput());
binaryThresholdFilter->SetLowerThreshold(150.0);
binaryThresholdFilter->SetUpperThreshold(250.0);
binaryThresholdFilter->SetOutsideValue(0);
binaryThresholdFilter->SetInsideValue(355.0);
binaryThresholdFilter->Update();
GPU Gradient Anisotropic is the only gpu filter that works in this example.
Probably because it's the only in place gpu filter. I've tried replacing
"<Image>" with "<GPUImage>" as well.
With the <Image, GPUImage> scenario I get read access violation as
GPUDataManager is null. Expect when using gpu gradient anisotropic.
With <GPUImage, GPUImage> and <GPUImage> on the conversion filter, the
conversion filter fails to generate data.
And as stated in earlier messages, if I first use gpu gradient anisotropic
(only gpu filter that works after vtktoitk) I can then successfully apply
gpu binary thresholding.
I'd look further into the issue but I'm not really sure where gpu images
even get allocated so it would be hard for me to debug. Perhaps I can write
my own gpu filters using gradient anisotropic as reference.
--
Sent from: http://itk-insight-users.2283740.n2.nabble.com/
_____________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
http://www.kitware.com/products/protraining.php
http://www.itk.org/Wiki/ITK_FAQ
http://public.kitware.com/mailman/listinfo/insight-users
_____________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html

Kitware offers ITK Training Courses, for more information visit:
http://www.kitware.com/products/protraining.php

Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ

Follow this link to subscribe/unsubscribe:
http://public.kitware.com/mailman/listinfo/insight-users

Continue reading on narkive:
Loading...