Skip to content

Commit

Permalink
Add option for numThreads
Browse files Browse the repository at this point in the history
Add option for numThreads in both CLI and GUI
Update README.md
  • Loading branch information
shermanlo77 committed Jan 22, 2024
1 parent 3d49b14 commit c362443
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 8 deletions.
15 changes: 12 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ density. This may have applications in image processing such as image
segmentation. The filters were also implemented on an *Nvidia* GPU using *CUDA*
and *JCuda*. This speeds up the filtering by a huge margin.

Where appropriate, please cite the thesis Lo, S.E. (2020). *Characterisation of
Computed Tomography Noise in Projection Space with Applications to Additive
Manufacturing*. PhD thesis, University of Warwick, Department of Statistics.
Where appropriate, please cite the thesis

* Lo, S.E. (2020). *Characterisation of Computed Tomography Noise in Projection
Space with Applications to Additive Manufacturing*. PhD thesis, University of
Warwick, Department of Statistics.

![images of a Mandrill with a mode filter, of varying radius kernel,
applied](mandrillExample.jpg)
Expand Down Expand Up @@ -96,6 +98,12 @@ They are:

![Screenshot of the GUI](filter_gui.png)

* Number of (CPU) threads
* Number of CPU threads to use when doing mean, median and quantile filtering.
Currently, they are only implemented on the CPU. These are used as inputs
for mode filtering. Thus there will be some CPU computation even in the
GPU version of the mode filter. It will default to use all detectable
threads.
* Number of initial values
* Number of initial values for the Newton-Raphson method. Increase this for
more accurate filtering at a price of more computational time. Compared to
Expand Down Expand Up @@ -138,6 +146,7 @@ java -jar Empirical_Null_Filter-x.x.x.jar run ['cpu' or 'gpu'] \
where the options are

* `-r` radius of kernel
* `-n` number of CPU threads
* `-i` number of initial points for Newton-Raphson
* `-s` number of steps for Newton-Raphson
* `-t` stopping condition tolerance for Newton-Raphson (recommend negative
Expand Down
Binary file modified filter_gui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>uk.ac.warwick.sip</groupId>
<artifactId>Empirical_Null_Filter</artifactId>
<version>2.2.0</version>
<version>2.3.0</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
9 changes: 8 additions & 1 deletion src/Empirical_Null_Filter.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
* <li>image file to run filter on</li>
* <li>path to save filtered image to in .png format</li>
* <li>[-r radius of the kernel]</li>
* <li>[-n number of threads]</li>
* <li>[-i number of initial points for Newton-Raphson]</li>
* <li>[-s number of steps for Newton-Raphson]</li>
* <li>[-t stopping condition tolerance for Newton-Raphson (recommend negative number), only for
Expand All @@ -52,7 +53,7 @@ public Empirical_Null_Filter() {

public static void main(String[] args) throws Exception {
System.out.println("MIT License - please see LICENSE");
System.out.println("Copyright (c) 2019-2023 Sherman Lo");
System.out.println("Copyright (c) 2019-2024 Sherman Lo");
System.out.println("Please see https://github.com/shermanlo77/modefilter or README.md");
System.out.println();

Expand Down Expand Up @@ -113,6 +114,11 @@ private static void parseArg(String[] args, int argsIndex, EmpiricalNullFilter f
radius = Float.parseFloat(args[argsIndex++]);
filter.setRadius(radius);
break;
case "-n": // number of threads
int numThreads;
numThreads = Integer.parseInt(args[argsIndex++]);
filter.setNumThreads(numThreads);
break;
case "-i": // number of initial values
int nInitial;
nInitial = Integer.parseInt(args[argsIndex++]);
Expand Down Expand Up @@ -258,6 +264,7 @@ public static void printManual() {
System.out.println();
System.out.println("Options:");
System.out.println("-r radius of kernel");
System.out.println("-n number of threads");
System.out.println("-i number of initial points for Newton-Raphson");
System.out.println("-s number of steps for Newton-Raphson");
System.out.println(
Expand Down
28 changes: 26 additions & 2 deletions src/uk/ac/warwick/sip/empiricalnullfilter/EmpiricalNullFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public class EmpiricalNullFilter implements ExtendedPlugInFilter, DialogListener
/** values used in the previous filtering */
private static double lastRadius = 0;
/** values used in the previous filtering */
private static int lastNumThreads = Prefs.getThreads();
/** values used in the previous filtering */
private static int lastNInitial = EmpiricalNull.N_INITIAL;
/** values used in the previous filtering */
private static int lastNStep = EmpiricalNull.N_STEP;
Expand Down Expand Up @@ -149,7 +151,7 @@ public class EmpiricalNullFilter implements ExtendedPlugInFilter, DialogListener

// MULTITHREADING RELATED
/** number of threads */
private int numThreads = Prefs.getThreads();
private int numThreads = lastNumThreads;
/**
* Current state of processing is in class variables. Thus, stack parallelization must be done
* ONLY with one thread for the image
Expand Down Expand Up @@ -251,6 +253,7 @@ public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {

if (Macro.getOptions() == null) { // interactive only: remember settings
lastRadius = this.radius;
lastNumThreads = this.numThreads;
lastNInitial = this.nInitial;
lastNStep = this.nStep;
lastLog10Tolerance = this.log10Tolerance;
Expand All @@ -269,6 +272,7 @@ public void showOptionsInDialog(GenericDialog genericDialog) {
// add fields for the empirical null tuning parameters
// integers do not show decimal points
genericDialog.addMessage("Advanced options");
genericDialog.addNumericField("number of threads", this.getNumThreads(), 0, 3, null);
genericDialog.addNumericField("number of initial values", this.getNInitial(), 0, 6, null);
genericDialog.addNumericField("number of steps", this.getNStep(), 0, 6, null);
genericDialog.addNumericField("log tolerance", this.getLog10Tolerance(), 2, 6, null);
Expand Down Expand Up @@ -310,6 +314,7 @@ public boolean dialogItemChanged(GenericDialog genericDialog, AWTEvent e) {

protected void changeValueFromDialog(GenericDialog genericDialog) throws InvalidValueException {
try {
this.setNumThreads((int) genericDialog.getNextNumber());
this.setNInitial((int) genericDialog.getNextNumber());
this.setNStep((int) genericDialog.getNextNumber());
this.setLog10Tolerance((float) genericDialog.getNextNumber());
Expand Down Expand Up @@ -756,7 +761,26 @@ protected void updateOutputImages(float[][] values, int valuesP, float[] nullMea
}
}

// =====STATIC FUNCTIONS AND PROCEDURES=====
/**
* Set number of threads
*
* @param numThreads must be 1 or bigger
* @throws InvalidValueException
*/
public void setNumThreads(int numThreads) throws InvalidValueException {
if (numThreads > 0) {
this.numThreads = numThreads;
} else {
throw new InvalidValueException("number of threads must be positive");
}
}

/**
* @return number of threads to use
*/
public int getNumThreads() {
return this.numThreads;
}

/**
* Set number of initial points
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
*
* Runs the compiled CUDA code. The CUDA cude is compiled into a .ptx file which is then used by the
* JCuda package. Tries to be as similar as the CPU version. Main difference is how the mode
* soutions are shared. They are shared within block neighbours. Performance is affected by block
* solutions are shared. They are shared within block neighbours. Performance is affected by block
* dimensions, 16x16 and 32x32 were found to be best from very from quick experimenting and
* eyeballing. Tolerance for Newton-Raphson is disabled as this introduces branching in GPU code.
*
* Multiple CPU threads are used in std, median and quantile filtering
*/

package uk.ac.warwick.sip.empiricalnullfilter;
Expand Down Expand Up @@ -66,6 +68,8 @@ public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
@Override
public void showOptionsInDialog(GenericDialog genericDialog) {
genericDialog.addMessage("Advanced options");

genericDialog.addNumericField("number of threads", this.getNumThreads(), 0, 3, null);
genericDialog.addNumericField("number of initial values", this.getNInitial(), 0, 6, null);
genericDialog.addNumericField("number of steps", this.getNStep(), 0, 6, null);
genericDialog.addMessage("GPU options");
Expand All @@ -79,6 +83,7 @@ public void showOptionsInDialog(GenericDialog genericDialog) {
@Override
protected void changeValueFromDialog(GenericDialog genericDialog) throws InvalidValueException {
try {
this.setNumThreads((int) genericDialog.getNextNumber());
this.setNInitial((int) genericDialog.getNextNumber());
this.setNStep((int) genericDialog.getNextNumber());
this.setBlockDimX((int) genericDialog.getNextNumber());
Expand Down Expand Up @@ -151,6 +156,11 @@ protected void doFiltering(final Cache cache) {
rankFilters.imageProcessor = this.imageProcessor;
rankFilters.roi = this.roi;
rankFilters.setRadius(this.getRadius());
try {
rankFilters.setNumThreads(this.getNumThreads());
} catch (InvalidValueException exception) {
throw new RuntimeException(exception);
}
rankFilters.filter();

Rectangle roiRectangle = this.imageProcessor.getRoi();
Expand Down

0 comments on commit c362443

Please sign in to comment.