[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(©Params));
// 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