Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 101 additions & 15 deletions src/dsp/ConvFactory.java
Original file line number Diff line number Diff line change
@@ -1,41 +1,127 @@
//package dsp;
//
//import dsp.gpu.ConvGpu;
//import dsp.cpu.Conv;
//import dsp.tornado.*;
//import ij.IJ;
//
//public class ConvFactory {
// private static boolean useGPU = false;
// private static ConvGpu gpuInstance = null;
//
// public static IConv createConv() {
// if (useGPU) {
// try {
// if (gpuInstance == null) {
// gpuInstance = new ConvGpu();
// }
// return gpuInstance;
// } catch (Exception e) {
// IJ.log("GPU initialization failed, falling back to CPU: " + e.getMessage());
// return new Conv();
// }
// } else {
// return new Conv();
// }
// }
//
// public static void cleanup() {
// if (gpuInstance != null) {
// gpuInstance.cleanup();
// gpuInstance = null;
// }
// }
//
// public static void setUseGPU(boolean useGPU) {
// ConvFactory.useGPU = useGPU;
// }
//
// public static boolean isUsingGPU() {
// return useGPU;
// }
//}

package dsp;

import dsp.gpu.ConvGpu;
import dsp.cpu.Conv;
import dsp.tornado.ConvTornado;
import ij.IJ;

public class ConvFactory {
private static boolean useGPU = false;

//CH - instead of having two possibilities, added an enum to store three possibilities for now
// The three possible engines
public enum Backend { CPU, GPU, TORNADO }

// Which engine is currently selected (default CPU)
private static Backend backend = Backend.CPU;

// Reusable instances (so we don't recreate every time)
private static ConvGpu gpuInstance = null;
private static ConvTornado tornadoInstance = null;

public static IConv createConv() {
if (useGPU) {
try {
if (gpuInstance == null) {
gpuInstance = new ConvGpu();
System.out.println("@@@@@ createConv CALLED, backend=" + backend);
switch (backend) {

case GPU:
try {
if (gpuInstance == null) {
gpuInstance = new ConvGpu();
//CH - added logs for understanding purposes
System.out.println(">>> GPU: ConvGPU Instance created successfully");
}
return gpuInstance;
} catch (Exception e) {
System.out.println("GPU failed, using CPU: " + e.getMessage());
return new Conv();
}

case TORNADO:
System.out.println("checker_1");
try {
if (tornadoInstance == null) {
tornadoInstance = new ConvTornado();
System.out.println(">>> Using ConvTornado");
}
return tornadoInstance;
} catch (Exception e) {
System.out.println("Tornado failed, using CPU: " + e.getMessage());
return new Conv();
}
return gpuInstance;
} catch (Exception e) {
IJ.log("GPU initialization failed, falling back to CPU: " + e.getMessage());

case CPU:
default:
return new Conv();
}
} else {
return new Conv();
}
}

public static void setBackend(Backend b) {
backend = b;
}

public static Backend getBackend() {
return backend;
}

public static void cleanup() {
if (gpuInstance != null) {
gpuInstance.cleanup();
gpuInstance = null;
}
if (tornadoInstance != null) {
tornadoInstance.cleanup();
tornadoInstance = null;
}
}

// CH - rewritten the following functions to reroute to tornado insteead of jcuda, and to read the value of backend to answer
public static void setUseGPU(boolean useGPU) {
ConvFactory.useGPU = useGPU;
backend=useGPU? Backend.TORNADO : Backend.CPU;
}

public static boolean isUsingGPU() {
return useGPU;
return backend != Backend.CPU;
}

}
5 changes: 5 additions & 0 deletions src/dsp/IConv.java

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a good idea to include void convolveStructGrad(FloatProcessor src, float[] kernx, float[] kern_diff1,
FloatProcessor gradx, FloatProcessor grady);
void convolveStructSmooth(float[] kernx, float[] kern_diff1,
FloatProcessor gx2, FloatProcessor gy2, FloatProcessor gxy) at the interface level. These are concrete applications.

Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,9 @@ public interface IConv {
void convolveFloat1D(FloatProcessor fp, float[] kernel, int xdir);
void convolveFloat1D(ImageStack is, float[] kernel, int xdir);
void convolveFloat1D(ImageProcessor ip, float[] kernel, int kw, int kh);
void convolveSep3(FloatProcessor src, float[] kernx, float[] kern_diff1, float[] kern_diff2,FloatProcessor gradx, FloatProcessor grady,FloatProcessor lap_xx, FloatProcessor lap_yy, FloatProcessor lap_xy);
void convolveStructGrad(FloatProcessor src, float[] kernx, float[] kern_diff1,
FloatProcessor gradx, FloatProcessor grady);
void convolveStructSmooth(float[] kernx, float[] kern_diff1,
FloatProcessor gx2, FloatProcessor gy2, FloatProcessor gxy);
}
61 changes: 61 additions & 0 deletions src/dsp/cpu/Conv.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,55 @@ public class Conv implements IConv {

public static boolean debug=false;

//CH - adding this to decrease the time utilization with multiple convolveFloat1D calls
@Override
public void convolveSep3(FloatProcessor src, float[] kernx, float[] kern_diff1, float[] kern_diff2,
FloatProcessor gradx, FloatProcessor grady,
FloatProcessor lap_xx, FloatProcessor lap_yy, FloatProcessor lap_xy) {

long tCpu = System.nanoTime();

convolveFloat1D(gradx, kern_diff1, Ox);
convolveFloat1D(gradx, kernx, Oy);

convolveFloat1D(grady, kern_diff1, Oy);
convolveFloat1D(grady, kernx, Ox);

convolveFloat1D(lap_xx, kern_diff2, Ox);
convolveFloat1D(lap_xx, kernx, Oy);

convolveFloat1D(lap_yy, kern_diff2, Oy);
convolveFloat1D(lap_yy, kernx, Ox);

convolveFloat1D(lap_xy, kern_diff1, Oy);
convolveFloat1D(lap_xy, kern_diff1, Ox);
System.out.println("sep3 CPU conv = " + (System.nanoTime()-tCpu)/1e6 + "ms");
}

// CH - replacement methods for cpu convolution in structure tensor
@Override
public void convolveStructGrad(FloatProcessor src, float[] kernx, float[] kern_diff1,
FloatProcessor gradx, FloatProcessor grady) {
long t = System.nanoTime();
int n = src.getWidth() * src.getHeight();
System.arraycopy(src.getPixels(), 0, gradx.getPixels(), 0, n);
System.arraycopy(src.getPixels(), 0, grady.getPixels(), 0, n);
convolveFloat1D(gradx, kern_diff1, Ox); convolveFloat1D(gradx, kernx, Oy);
convolveFloat1D(grady, kern_diff1, Oy); convolveFloat1D(grady, kernx, Ox);
System.out.println("stgrad CPU = " + (System.nanoTime()-t)/1e6 + "ms");
}

@Override
public void convolveStructSmooth(float[] kernx, float[] kern_diff1,
FloatProcessor gx2, FloatProcessor gy2, FloatProcessor gxy) {
long t = System.nanoTime();
convolveFloat1D(gx2, kern_diff1, Ox); convolveFloat1D(gx2, kernx, Oy);
convolveFloat1D(gy2, kern_diff1, Oy); convolveFloat1D(gy2, kernx, Ox);
convolveFloat1D(gxy, kern_diff1, Oy); convolveFloat1D(gxy, kernx, Ox);
System.out.println("stsmooth CPU = " + (System.nanoTime()-t)/1e6 + "ms");
}


/**
* It is used for semi-separable convolution
* @param ip
Expand All @@ -62,6 +111,9 @@ public void convolveSemiSep(FloatProcessor ip, float[] kernx, float[] kern_diff)
FloatProcessor ipx = null;
final Rectangle roi=ip.getRoi();

long tCpu = System.nanoTime();


synchronized(this) {
ip2 = (FloatProcessor)ip.duplicate();
ip2.setRoi(roi);
Expand All @@ -85,6 +137,9 @@ public void convolveSemiSep(FloatProcessor ip, float[] kernx, float[] kern_diff)
convolveFloat1D(ip2, kern_diff, 1, kern_diff.length); // y direction
add(ip2, ipx, ip2.getRoi());
ip.setPixels(ip2.getPixels());

System.out.println("semiSep CPU conv = " + (System.nanoTime()-tCpu)/1e6 + "ms");

}


Expand Down Expand Up @@ -140,10 +195,13 @@ public void convolveSepIter(FloatProcessor ip, float[] kernx, float[] kern_diff)
*/
@Override
public void convolveSep(ImageProcessor ip, float[] kernx, float[] kern_diff) {
long tCpu = System.nanoTime();
convolveFloat1D(ip, kern_diff, kern_diff.length, 1); // x direction
//ipx.setSnapshotPixels(null);
convolveFloat1D(ip, kernx, 1, kernx.length); // y direction
//new ImagePlus("cx", ipx).show();
System.out.println("sep CPU conv = " + (System.nanoTime()-tCpu)/1e6 + "ms");

}

/**
Expand Down Expand Up @@ -302,6 +360,7 @@ private void add(ImageProcessor dest, ImageProcessor src, Rectangle r) {
@Override
public boolean convolveFloat(ImageProcessor ip, float[] kernel, int kw, int kh) {

long tCpu = System.nanoTime();
int width = ip.getWidth();
int height = ip.getHeight();
Rectangle r = ip.getRoi();
Expand Down Expand Up @@ -345,6 +404,8 @@ public boolean convolveFloat(ImageProcessor ip, float[] kernel, int kw, int kh)
}
if (nonRectRoi)
ip.reset(ip.getMask());

System.out.println("conv2d CPU = " + (System.nanoTime()-tCpu)/1e6 + "ms");
return true;
}

Expand Down
27 changes: 27 additions & 0 deletions src/dsp/gpu/ConvGpu.java

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion is to define a separate application Interface wehre you define the methods and then to inherit both interfaces.

Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,25 @@ public ConvGpu() {
}
}

// CH - replacement methods for cpu convolution in structure tensor
@Override
public void convolveStructGrad(FloatProcessor src, float[] kernx, float[] kern_diff1,
FloatProcessor gradx, FloatProcessor grady) {
int n = src.getWidth() * src.getHeight();
System.arraycopy(src.getPixels(), 0, gradx.getPixels(), 0, n);
System.arraycopy(src.getPixels(), 0, grady.getPixels(), 0, n);
convolveFloat1D(gradx, kern_diff1, Ox); convolveFloat1D(gradx, kernx, Oy);
convolveFloat1D(grady, kern_diff1, Oy); convolveFloat1D(grady, kernx, Ox);
}

@Override
public void convolveStructSmooth(float[] kernx, float[] kern_diff1,
FloatProcessor gx2, FloatProcessor gy2, FloatProcessor gxy) {
convolveFloat1D(gx2, kern_diff1, Ox); convolveFloat1D(gx2, kernx, Oy);
convolveFloat1D(gy2, kern_diff1, Oy); convolveFloat1D(gy2, kernx, Ox);
convolveFloat1D(gxy, kern_diff1, Oy); convolveFloat1D(gxy, kernx, Ox);
}

@Override
public void convolveSemiSep(FloatProcessor ip, float[] kernx, float[] kern_diff) {
FloatProcessor ip2 = null;
Expand All @@ -95,6 +114,14 @@ public void convolveSemiSep(FloatProcessor ip, float[] kernx, float[] kern_diff)
add(ip2, ipx, ip2.getRoi());
ip.setPixels(ip2.getPixels());
}

@Override
public void convolveSep3(FloatProcessor src, float[] kernx, float[] kern_diff1, float[] kern_diff2,
FloatProcessor gradx, FloatProcessor grady,
FloatProcessor lap_xx, FloatProcessor lap_yy, FloatProcessor lap_xy)
{

}

@Override
public void convolveSemiSepIter(FloatProcessor ip, float[] kernx, float[] kern_diff) {
Expand Down
Loading