InsightSoftwareConsortium / InsightSoftwareConsortium/ITK

GPU memory leakage

Open
#1,887 4 comments 0 reactions 0 assignees View on GitHub
status:Use_Milestone_Backlog type:Bug
Dominant language
C++
Stars
1.7k
Forks
748
Avg merge
1d 1h
Merged PRs (30d)
64

Description

I need to use GPUDemonsRegistrationFilter in my project. However, I find it would cause gpu memory leakage. This problem can be repeated by the following code:
```
#include "itkGPUDemonsRegistrationFilter.h"
#include "itkHistogramMatchingImageFilter.h"
#include "itkCastImageFilter.h"
#include "itkWarpImageFilter.h"
#include "itkLinearInterpolateImageFunction.h"

#include "itkImportImageFilter.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkCommand.h"
#include "itkSmartPointer.h"
#include "itkTimeProbe.h"

#include "itkGPUImage.h"
#include "itkGPUKernelManager.h"
#include "itkGPUContextManager.h"
#include "itkGPUDemonsRegistrationFilter.h"

void DIF() {
bool debug = true;

//Fill some arrays with bogus
const unsigned int Dimension = 3;
typedef float PixelType;
unsigned int width = 100;
unsigned int height = 100;
unsigned int slices = 10;
unsigned int nump = width * height * slices;
PixelType *FixedImageArray = new PixelType[nump];
PixelType *MovingImageArray = new PixelType[nump];
for (unsigned int i = 0; i < nump; ++i) {
FixedImageArray[i] = i % 5;
MovingImageArray[i] = i % 6;
}

//Import those arrays as images
typedef itk::Image< PixelType, Dimension > FixedImageType;
typedef itk::Image< PixelType, Dimension > MovingImageType;

FixedImageType::IndexType start;
start[0] = 0;
start[1] = 0;
start[2] = 0;
FixedImageType::SizeType size;
size[0] = width;
size[1] = height;
size[2] = slices;
FixedImageType::RegionType region;
region.SetSize(size);
region.SetIndex(start);

double origin[3];
origin[0] = 0.0;
origin[1] = 0.0;
origin[2] = 0.0;

double spacing[3];
spacing[0] = 1;
spacing[1] = 1;
spacing[2] = 1;

FixedImageType::Pointer FixedImage = FixedImageType::New();
FixedImage->SetRegions(region);
FixedImage->Allocate();
memcpy(FixedImage->GetBufferPointer(), FixedImageArray, sizeof(PixelType)*width * height * slices);
FixedImage->SetOrigin(origin);
FixedImage->SetSpacing(spacing);

MovingImageType::Pointer MovingImage = MovingImageType::New();
MovingImage->SetRegions(region);
MovingImage->Allocate();
memcpy(MovingImage->GetBufferPointer(), MovingImageArray, sizeof(PixelType)*width * height * slices);
MovingImage->SetOrigin(origin);
MovingImage->SetSpacing(spacing);

//convert to GPUImages
typedef float InternalPixelType;
typedef itk::GPUImage< InternalPixelType, Dimension > InternalImageType;
typedef itk::CastImageFilter< FixedImageType,
InternalImageType > FixedImageCasterType;
typedef itk::CastImageFilter< MovingImageType,
InternalImageType > MovingImageCasterType;

FixedImageCasterType::Pointer fixedImageCaster = FixedImageCasterType::New();
if (debug) fixedImageCaster->DebugOn();
MovingImageCasterType::Pointer movingImageCaster = MovingImageCasterType::New();
if (debug) movingImageCaster->DebugOn();

fixedImageCaster->SetInput(FixedImage);
movingImageCaster->SetInput(MovingImage);

InternalImageType::Pointer GPUFixedImage = fixedImageCaster->GetOutput();
if (debug) GPUFixedImage->DebugOn();

InternalImageType::Pointer GPUMovingImage = movingImageCaster->GetOutput();
if (debug) GPUMovingImage->DebugOn();

GPUFixedImage->Update();
GPUMovingImage->Update();

//Perform GPU Demons Registration
typedef itk::Vector< float, Dimension > VectorPixelType;
typedef itk::GPUImage< VectorPixelType, Dimension > DeformationFieldType;
typedef itk::GPUDemonsRegistrationFilter<
InternalImageType,
InternalImageType,
DeformationFieldType> RegistrationFilterType;

RegistrationFilterType::Pointer filter = RegistrationFilterType::New();
if (debug) filter->DebugOn();

filter->SetFixedImage(GPUFixedImage);
filter->SetMovingImage(GPUMovingImage);

filter->SetNumberOfIterations(1);
filter->SetStandardDeviations(1.0);

filter->Update();

delete[] FixedImageArray;
delete[] MovingImageArray;
}

int main(int argc, char **argv) {
unsigned int numiter = 100000;
for (unsigned int i = 0; i < numiter; ++i) {
DIF();
std::cout << "ITERATION: " << i << std::endl;
}
}
```
I use GPU Z and nvidia-smi.exe to observe the GPU memory usage. The maximum GPU usage is growing with the iteration. For example, for GPU Z, in the 0~1000 iteration, the maximum GPU usage is 160 M; in 5000 iteration, the maximum GPU usage is 170 M. When the iteration is larger than 10000, the maximum GPU usage is 190 M. For 20000 iteration, the maximum GPU usage is about 215 M.

The environment is:
win10
ITK: the latest master
vs 2015
cuda: 10.0

Any suggestion is appreciated!

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.