[ITK-users] ITK Image data pointer and GPU algorithms

Kabelitz, Gordian Gordian.Kabelitz at medma.uni-heidelberg.de
Thu Mar 2 11:24:19 EST 2017


Hello,

i want to copy my image data on the GPU. Therefore I need to retrieve my image data from the itk::Image class. The method that seems suitable is GetBufferPointer. Hence, I know the size of my image and the pixel type I could get a pointer to the image data.
I cant use itk::GPUImage because my algorithm is not implemented in ITK. My idea is to get the data pointer, do my computation and 
My code looks like:

// get float pointer to image data
ImageType::Pointer image = reader->GetOutput();
Image->Update();

float* data = image.GetBufferPointer();
// copy image data to gpu
gpu_dev->setVoxels(dimension, voxelSize, data);
[...]

My setVoxels() method is at the end of this mail.

When I try to access the memory on the gpu where the data should be stored (at least in my imagination) I get an error.
The error occurs at the checking line for the data input.

I read [1]  and tried the suggested methods. But I want to work directly on the data and don't want to make any copy.
But couldn't get any closer to a solution.

My questions are:
1. Is there a good way to retrieve my image data other than suggested in [1] (less copying)?
2. Is it error-prone to change the image data without using itk?
3. Can I work directly on the itk::image data without making a copy?

[1]: https://itk.org/CourseWare/Training/GettingStarted-V.pdf

Thank you.
Sincerely,
Gordian


bool CProjection::setVoxels( const int* dimension, const float* voxelSize, const float* data)
{
	// check input
	std::cout << "CUDA: Dimension:" << dimension[0] << ", " << dimension[1] << ", " << dimension[2] << "\n";
	std::cout << "CUDA: Spacing:" << voxelSize[0] << ", " << voxelSize[1] << ", " << voxelSize[2] << "\n";
	std::cout << "CUDA: Data (3 values):" << data[0] << ", " << data[10] << ", " << data[100] << std::endl;

	cudaExtent volumeSize = make_cudaExtent(dimension[0], dimension[1], dimension[2]);
	volArray_dev = 0;

	// create 3D array
	const cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
	DS_ERROR_CHECK(cudaMalloc3DArray(&volArray_dev, &channelDesc, volumeSize));

	// copy data to 3D array
	cudaMemcpy3DParms copyParams = { 0 };
	copyParams.srcPtr = make_cudaPitchedPtr((void*)data, volumeSize.width * sizeof(float), volumeSize.width, volumeSize.height);
	copyParams.dstArray = volArray_dev;
	copyParams.extent = volumeSize;
	copyParams.kind = cudaMemcpyHostToDevice;

	DS_ERROR_CHECK(cudaMemcpy3D(&copyParams));
	
	// set texture parameters
	tex_vox.normalized = false; //do not access with normalized texture coordinates

	//use point access
	tex_vox.filterMode = cudaFilterModePoint;
	// clamp texture edges for out of boundary access
	tex_vox.addressMode[0] = cudaAddressModeClamp;
	tex_vox.addressMode[1] = cudaAddressModeClamp;
	tex_vox.addressMode[2] = cudaAddressModeClamp;

	// bind array to 3D texture
	DS_ERROR_CHECK(cudaBindTextureToArray(tex_vox, volArray_dev, channelDesc));

	//Set volume information on host and dev
	for (int i = 0; i < 3; i++) {
		volDimension_host[i] = dimension[i];
		voxSize_host[i] = voxelSize[i];
	}

	DS_ERROR_CHECK(cudaMemcpyToSymbol(dc_voxDim, volDimension_host, 3 * sizeof(int)));
	DS_ERROR_CHECK(cudaMemcpyToSymbol(dc_voxSize, voxSize_host, 3 * sizeof(float)));

	voxelsSet = true;
	return voxelsSet; //on success
}







More information about the Insight-users mailing list