package edu.stanford.rsl.conrad.cuda; import java.util.Random; import org.junit.Test; import edu.stanford.rsl.conrad.filtering.multiprojection.anisotropic.AnisotropicFilterFunction; import edu.stanford.rsl.conrad.utils.Configuration; import edu.stanford.rsl.conrad.volume3d.ParallelVolumeOperator; import edu.stanford.rsl.conrad.volume3d.Volume3D; import edu.stanford.rsl.conrad.volume3d.VolumeOperator; public class CUDAVolumeTest { protected int [] size = {130, 152, 124}; protected float [] dim = {1f, 1f, 1f}; protected CUDAVolumeOperator cuop = new CUDAVolumeOperator(); protected VolumeOperator op = new ParallelVolumeOperator(); protected void assertVolumeEquality(Volume3D one, Volume3D two){ op.subtractVolume(one, two); op.abs(one); double maxAbsoluteError = op.max(one); System.out.println("Max Error: " + maxAbsoluteError); org.junit.Assert.assertTrue(maxAbsoluteError < 0.00001); } protected void assertWeakVolumeEquality(Volume3D one, Volume3D two){ op.subtractVolume(one, two); op.abs(one); double maxAbsoluteError = op.mean(one); System.out.println("Mean Error: " + maxAbsoluteError); org.junit.Assert.assertTrue(maxAbsoluteError < 0.001); } protected void assertVolumeDifference(Volume3D one, Volume3D two){ op.subtractVolume(one, two); op.abs(one); double maxAbsoluteError = op.max(one); org.junit.Assert.assertFalse(maxAbsoluteError < 0.000001); } public CUDAVolume3D createCUDACopy (Volume3D vol){ CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createVolume(size, dim, 1); float [][][] temp = cudaVol.data; cudaVol.data = vol.data; cudaVol.updateOnDevice(); cudaVol.data = temp; return cudaVol; } @Test public void testMax(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); float cpu = op.max(one); float gpu = cuop.max(cudaVol); cudaVol.fetch(); org.junit.Assert.assertTrue(cpu == gpu); cudaVol.destroy(); one.destroy(); } @Test public void testMin(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); float cpu = op.min(one); float gpu = cuop.min(cudaVol); cudaVol.fetch(); org.junit.Assert.assertTrue(cpu == gpu); cudaVol.destroy(); one.destroy(); } @Test public void testMean(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); float cpu = op.mean(one); float gpu = cuop.mean(cudaVol); cudaVol.fetch(); //System.out.println(cpu + " " + gpu); org.junit.Assert.assertTrue(Math.abs(cpu - gpu) < 0.00001); cudaVol.destroy(); one.destroy(); } @Test public void testAbs(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); op.abs(one); cuop.abs(cudaVol); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testAddScalar(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); op.addScalar(one, 1.0f, 0.0f); cuop.addScalar(cudaVol, 1.0f, 0.0f); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testAddVolume(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); Volume3D two = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); CUDAVolume3D cudaVol2 = createCUDACopy(two); op.addVolume(one, two); cuop.addVolume(cudaVol, cudaVol2); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); cudaVol2.destroy(); one.destroy(); two.destroy(); } @Test public void testAddVolumeWeight(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); Volume3D two = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); CUDAVolume3D cudaVol2 = createCUDACopy(two); op.addVolume(one, two, 2.0); cuop.addVolume(cudaVol, cudaVol2, 2.0); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); cudaVol2.destroy(); one.destroy(); two.destroy(); } @Test public void testCreateHighPassFilter(){ Configuration.loadConfiguration(); Volume3D one = op.createHighPassFilter(3, size, dim, 2, 1.5f); cuop.initCUDA(); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createHighPassFilter(3, size, dim, 2, 1.5f); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testCreateLowPassFilter(){ Configuration.loadConfiguration(); Volume3D one = op.createLowPassFilter(3, size, dim, 1.5f); cuop.initCUDA(); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createLowPassFilter(3, size, dim, 1.5f); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testCreateVolume(){ Configuration.loadConfiguration(); Volume3D vol = op.createVolume(size , dim, 1); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createVolume(size, dim, 1); cudaVol.fetch(); assertVolumeEquality(vol, cudaVol); cudaVol.destroy(); vol.destroy(); } @Test public void testDivideByVolume(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); Volume3D two = createRandomVolume(); op.multiplyScalar(one, 1000, 0); op.addScalar(two, 10, 0); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); CUDAVolume3D cudaVol2 = createCUDACopy(two); op.divideByVolume(one, two); cuop.divideByVolume(cudaVol, cudaVol2); cudaVol.fetch(); assertWeakVolumeEquality(one, cudaVol); cudaVol.destroy(); cudaVol2.destroy(); one.destroy(); two.destroy(); } @Test public void testDivideScalar(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); op.divideScalar(one, 3.0f, 0.0f); cuop.divideScalar(cudaVol, 3.0f, 0.0f); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testFFTShift(){ Configuration.loadConfiguration(); Volume3D one = createRandomVolume(); cuop.initCUDA(); CUDAVolume3D cudaVol = createCUDACopy(one); op.fftShift(one); cuop.fftShift(cudaVol); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testfilt_cos2_quad(){ Configuration.loadConfiguration(); cuop.initCUDA(); float [] [] dirs = new float [6][3]; AnisotropicFilterFunction.filt_get_filt_dirs(3, dirs); Volume3D one = op.createDirectionalWeights(3, size, dim, dirs[0], 1, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createDirectionalWeights(3, size, dim, dirs[0], 1, VolumeOperator.FILTER_TYPE.QUADRATIC); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testfilt_cos2r(){ Configuration.loadConfiguration(); cuop.initCUDA(); float [] [] dirs = new float [6][3]; AnisotropicFilterFunction.filt_get_filt_dirs(3, dirs); Volume3D one = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[0], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.NORMAL); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[0], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.NORMAL); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testfilt_cos2r_quad(){ Configuration.loadConfiguration(); cuop.initCUDA(); float [] [] dirs = new float [6][3]; AnisotropicFilterFunction.filt_get_filt_dirs(3, dirs); Volume3D one = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[0], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[0], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testfilt_gauss(){ Configuration.loadConfiguration(); cuop.initCUDA(); Volume3D one = op.createGaussLowPassFilter(3, size, dim, 2); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.createGaussLowPassFilter(3, size, dim, 2); cudaVol.fetch(); assertVolumeEquality(one, cudaVol); cudaVol.destroy(); one.destroy(); } @Test public void testfilt_solve_max_eigenValue(){ Configuration.loadConfiguration(); cuop.initCUDA(); int [] size = {30, 30, 30}; this.size = size; float [] [] dirs = new float [6][3]; AnisotropicFilterFunction.filt_get_filt_dirs(3, dirs); Volume3D a11 = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[0], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); Volume3D a12 = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[1], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); Volume3D a13 = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[2], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); Volume3D a22 = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[3], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); Volume3D a23 = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[4], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); Volume3D a33 = op.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[5], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); op.real(a11); op.real(a12); op.real(a13); op.real(a22); op.real(a23); op.real(a33); Volume3D [][] st = new Volume3D[3][3]; st[0][0] = a11; st[0][1] = a12; st[0][2] = a13; st[1][0] = a12; st[1][1] = a22; st[1][2] = a23; st[2][0] = a13; st[2][1] = a23; st[2][2] = a33; CUDAVolume3D ca11 = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[0], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D ca12 = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[1], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D ca13 = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[2], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D ca22 = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[3], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D ca23 = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[4], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); CUDAVolume3D ca33 = (CUDAVolume3D) cuop.createExponentialDirectionalHighPassFilter(3, size, dim, dirs[5], 1, 2.0f, 1.5f, VolumeOperator.FILTER_TYPE.QUADRATIC); cuop.real(ca11); cuop.real(ca12); cuop.real(ca13); cuop.real(ca22); cuop.real(ca23); cuop.real(ca33); CUDAVolume3D [][] cst = new CUDAVolume3D[3][3]; cst[0][0] = ca11; cst[0][1] = ca12; cst[0][2] = ca13; cst[1][1] = ca22; cst[1][2] = ca23; cst[2][2] = ca33; //new ImageJ(); Volume3D one = op.solveMaximumEigenvalue(st); //one.getImagePlus("CPU Result").show(); CUDAVolume3D cudaVol = (CUDAVolume3D) cuop.solveMaximumEigenvalue(cst); cudaVol.fetch(); //cudaVol.getImagePlus("CUDA Result").show(); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } assertWeakVolumeEquality(one, cudaVol); a11.destroy(); a12.destroy(); a13.destroy(); a22.destroy(); a23.destroy(); a33.destroy(); ca11.destroy(); ca12.destroy(); ca13.destroy(); ca22.destroy(); ca23.destroy(); ca33.destroy(); cudaVol.destroy(); one.destroy(); } public Volume3D createRandomVolume(){ Volume3D vol = op.createVolume(size , dim, 1); Random rand = new Random(); for (int i = 0; i < size[0]; i++) for (int j = 0; j < size[1]; j++) for (int k = 0; k < size[2]; k++) { vol.data[i][j][k] = (rand.nextFloat() - 0.5f)*2; } return vol; } @Test public void testRandomVolume(){ Volume3D one = createRandomVolume(); Volume3D two = createRandomVolume(); assertVolumeDifference(one, two); } } /* * Copyright (C) 2010-2014 - Andreas Maier * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */