Skip to content

Releases: andyschwarzl/gpuNUFFT

Python support

04 Apr 11:04
9080481
Compare
Choose a tag to compare

Added interface to support Python.

Bindings written by Chaithya G R and Carole Lazarus.

Improved deapodization

15 Jun 14:07
Compare
Choose a tag to compare
  • Apply deapodization by computing inverse FFT of gridding kernel (allows for correct scaling independent of kernel width)
  • Apply sqrt of density compensation in both forward and adjoint operation (better usability in iterative algorithms)

2D performance upgrade

11 May 14:02
Compare
Choose a tag to compare

Processing of multiple coils at once depending on available resources

GPU Arrays

17 Feb 20:04
Compare
Choose a tag to compare
GPU Arrays Pre-release
Pre-release

GPU Arrays

The gpuNUFFT operator now supports data vectors which are already located on the GPU device, which is exemplarily necessary when performing iterative reconstructions in standalone CPP applications. The Matlab interface is not affected by this extension.

See corresponding test case:

TEST(TestForwardBackward,Test_GpuArray)
{
  //Test the same as above but use GpuArray data structure  
  int kernel_width = 3;
  float osf = 1.25;//oversampling ratio
  int sector_width = 8;
  //Data
  int data_entries = 2;
  DType2* data = (DType2*) calloc(data_entries,sizeof(DType2)); //2* re + im
  data[0].x = 5;//Re
  data[0].y = 0;//Im
  data[1].x = 1;//Re
  data[1].y = 0;//Im

  //Coords
  //Scaled between -0.5 and 0.5
  //in triplets (x,y,z) as structure of array
  //p0 = (0,0,0)
  //p1 0 (0.25,0.25,0.25)
  DType* coords = (DType*) calloc(3*data_entries,sizeof(DType));//3* x,y,z
  coords[0] = 0.00; //x0
  coords[1] = 0.25; //x1

  coords[2] = 0.00; //y0
  coords[3] = 0.25; //y1

  coords[4] = 0.00; //z0
  coords[5] = 0.25; //z1

  //Input data array, complex values
  //and copy to GPU 
  gpuNUFFT::GpuArray<DType2> dataArray_gpu;
  dataArray_gpu.dim.length = data_entries;
  allocateAndCopyToDeviceMem<DType2>(&dataArray_gpu.data,data,data_entries);

  //Input array containing trajectory in k-space
  gpuNUFFT::Array<DType> kSpaceData;
  kSpaceData.data = coords;
  kSpaceData.dim.length = data_entries;

  gpuNUFFT::Dimensions imgDims;
  imgDims.width = 64;
  imgDims.height = 64;
  imgDims.depth = 64;

  //precomputation performed by factory
  gpuNUFFT::GpuNUFFTOperatorFactory factory; 
  gpuNUFFT::GpuNUFFTOperator *gpuNUFFTOp =    
  factory.createGpuNUFFTOperator(kSpaceData,kernel_width,sector_width,osf,imgDims);

  //Output Array
  gpuNUFFT::GpuArray<CufftType> imgArray_gpu;
  imgArray_gpu.dim = imgDims;
  allocateDeviceMem<CufftType>(&imgArray_gpu.data,imgArray_gpu.count());

  //Perform FT^H Operation
  gpuNUFFTOp->performGpuNUFFTAdj(dataArray_gpu, imgArray_gpu);

  //Perform FT Operation
  gpuNUFFTOp->performForwardGpuNUFFT(imgArray_gpu,dataArray_gpu);
  copyFromDevice(dataArray_gpu.data,data,data_entries);

  printf("contrast %f \n",data[0].x/data[1].x);
  EXPECT_NEAR(data[0].x/data[1].x,5.0,epsilon);

  free(data);
  free(coords);
  freeTotalDeviceMemory(dataArray_gpu.data,imgArray_gpu.data,NULL);

  delete gpuNUFFTOp;
}

Memory estimator

Additionally to the initialization step of the gpuNUFFT operator a rough memory estimation is performed, in order to avoid crashes when the problem data exceeds the total device memory. To handle this, an exception is thrown and a Matlab error is returned.

Automatic coil summation

14 Aug 16:11
Compare
Choose a tag to compare

Arbitrary sector widths

The sector width parameter can now be arbitrarily chosen in such manner that the total grid dimension (image dim * oversampling factor) does not have to be an integer multiple of the sector width, e.g.:

imgDim = [256,256,240]; 
sw = 8; 
osf = 1.125; 
% imgDim * osf ./ sw = [36, 36, 33.75] 
...
FT = gpuNUFFT(k',w,osf,kw,sw,imgDim); % still works
...

Automatic coil summation

If the gpuNUFFT operator is initialized with coil sensitivities following steps are performed automatically on the GPU:

%without sens data
FT = gpuNUFFT(k',w,osf,wg,sw,[N,N,nSl]);

%with sens data
FT = gpuNUFFT(k',w,osf,wg,sw,[N,N,nSl],sens);

Adjoint operation: sum over coils as final step

% the block
for ii = 1:nc
    y = y + conj(sens(:,:,:,ii) .* FH(data(:,ii)); 
end

% can be replaced by 
y = FH(data);

Forward operation: loop over coils

% the block
img = repmat(img,[1,1,1,nCh]);
for ii = 1:nc
    data(:,ii) = F( sens(:,:,:,ii) .* img(:,:,:,ii) ); 
end

% can be replaced by 
y = F(img);

Varying dimensions in x, y and z

06 Jun 11:26
Compare
Choose a tag to compare

Varying dimensions in all directions, e.g. 3d grids with 256x128x64 or 2d grids with 256x128 are supported now.

Texture lookup, balanced workload, sensitivity data

03 Jun 11:45
Compare
Choose a tag to compare
  • Use textures for kernel lookup
  • Use textures for data readout
  • Balanced and textured gridding to work more efficiently
  • Apply sens data on GPU
  • Automatically export mex-files into gpuNUFFT/@gpuNUFFT/private folder
  • Refactored initialization params of MATLAB Operator

Anisotropic grid support

07 Apr 19:42
Compare
Choose a tag to compare

Now anisotropic grid sizes, e.g. 128x128x64 are supported. Generated test data and MATLAB scripts are added in the demo folder.

Parallel precomputation

10 Mar 21:24
Compare
Choose a tag to compare

This release contains the precomputation step on the GPU. This will lead to better performance if it is neccessary to continuously create the Gridding Operator, e.g. when the k-Space trajectory is shifted per iteration step.