3434
3535package net .imglib2 .algorithm .gradient ;
3636
37- import java .util .ArrayList ;
38- import java .util .List ;
39- import java .util .concurrent .Callable ;
4037import java .util .concurrent .ExecutionException ;
4138import java .util .concurrent .ExecutorService ;
42- import java .util .concurrent .Future ;
4339
4440import net .imglib2 .Cursor ;
45- import net .imglib2 .FinalInterval ;
4641import net .imglib2 .RandomAccessible ;
4742import net .imglib2 .RandomAccessibleInterval ;
4843import net .imglib2 .loops .LoopBuilder ;
44+ import net .imglib2 .parallel .TaskExecutor ;
45+ import net .imglib2 .parallel .Parallelization ;
46+ import net .imglib2 .parallel .TaskExecutors ;
4947import net .imglib2 .type .numeric .NumericType ;
5048import net .imglib2 .util .Intervals ;
51- import net .imglib2 .view .IntervalView ;
5249import net .imglib2 .view .Views ;
5350
5451/**
@@ -98,7 +95,7 @@ public static < T extends NumericType< T > > void gradientCentralDifference2( fi
9895 * @param source
9996 * source image, has to provide valid data in the interval of the
10097 * gradient image plus a one pixel border in dimension.
101- * @param gradient
98+ * @param result
10299 * output image
103100 * @param dimension
104101 * along which dimension the partial derivatives are computed
@@ -110,57 +107,42 @@ public static < T extends NumericType< T > > void gradientCentralDifference2( fi
110107 */
111108 public static < T extends NumericType < T > > void gradientCentralDifferenceParallel (
112109 final RandomAccessible < T > source ,
113- final RandomAccessibleInterval < T > gradient ,
110+ final RandomAccessibleInterval < T > result ,
114111 final int dimension ,
115112 final int nTasks ,
116113 final ExecutorService es ) throws InterruptedException , ExecutionException
117114 {
118- final int nDim = source .numDimensions ();
119- if ( nDim < 2 )
120- {
121- gradientCentralDifference ( source , gradient , dimension );
122- return ;
123- }
124-
125- long dimensionMax = Long .MIN_VALUE ;
126- int dimensionArgMax = -1 ;
127-
128- for ( int d = 0 ; d < nDim ; ++d )
129- {
130- final long size = gradient .dimension ( d );
131- if ( d != dimension && size > dimensionMax )
132- {
133- dimensionMax = size ;
134- dimensionArgMax = d ;
135- }
136- }
137-
138- final long stepSize = Math .max ( dimensionMax / nTasks , 1 );
139- final long stepSizeMinusOne = stepSize - 1 ;
140- final long min = gradient .min ( dimensionArgMax );
141- final long max = gradient .max ( dimensionArgMax );
142-
143- final ArrayList < Callable < Void > > tasks = new ArrayList <>();
144- for ( long currentMin = min , minZeroBase = 0 ; minZeroBase < dimensionMax ; currentMin += stepSize , minZeroBase += stepSize )
145- {
146- final long currentMax = Math .min ( currentMin + stepSizeMinusOne , max );
147- final long [] mins = new long [ nDim ];
148- final long [] maxs = new long [ nDim ];
149- gradient .min ( mins );
150- gradient .max ( maxs );
151- mins [ dimensionArgMax ] = currentMin ;
152- maxs [ dimensionArgMax ] = currentMax ;
153- final IntervalView < T > currentInterval = Views .interval ( gradient , new FinalInterval ( mins , maxs ) );
154- tasks .add ( () -> {
155- gradientCentralDifference ( source , currentInterval , dimension );
156- return null ;
157- } );
158- }
115+ TaskExecutor taskExecutor = TaskExecutors .forExecutorServiceAndNumTasks ( es , nTasks );
116+ Parallelization .runWithExecutor ( taskExecutor , () -> {
117+ gradientCentralDerivativeParallel ( source , result , dimension );
118+ } );
119+ }
159120
160- final List < Future < Void > > futures = es .invokeAll ( tasks );
121+ /**
122+ * Compute the partial derivative (central difference approximation) of source
123+ * in a particular dimension:
124+ * {@code d_f( x ) = ( f( x + e ) - f( x - e ) ) / 2},
125+ * where {@code e} is the unit vector along that dimension.
126+ *
127+ * @param source
128+ * source image, has to provide valid data in the interval of the
129+ * gradient image plus a one pixel border in dimension.
130+ * @param result
131+ * output image
132+ * @param dimension
133+ * along which dimension the partial derivatives are computed
134+ */
135+ private static <T extends NumericType < T >> void gradientCentralDerivativeParallel ( RandomAccessible <T > source ,
136+ RandomAccessibleInterval <T > result , int dimension )
137+ {
138+ final RandomAccessibleInterval <T > back = Views .interval ( source , Intervals .translate ( result , -1 , dimension ) );
139+ final RandomAccessibleInterval <T > front = Views .interval ( source , Intervals .translate ( result , 1 , dimension ) );
161140
162- for ( final Future < Void > f : futures )
163- f .get ();
141+ LoopBuilder .setImages ( result , back , front ).multiThreaded ().forEachPixel ( ( r , b , f ) -> {
142+ r .set ( f );
143+ r .sub ( b );
144+ r .mul ( 0.5 );
145+ } );
164146 }
165147
166148 // fast version
@@ -181,13 +163,8 @@ public static < T extends NumericType< T > > void gradientCentralDifferenceParal
181163 public static < T extends NumericType < T > > void gradientCentralDifference ( final RandomAccessible < T > source ,
182164 final RandomAccessibleInterval < T > result , final int dimension )
183165 {
184- final RandomAccessibleInterval < T > back = Views .interval ( source , Intervals .translate ( result , -1 , dimension ) );
185- final RandomAccessibleInterval < T > front = Views .interval ( source , Intervals .translate ( result , 1 , dimension ) );
186-
187- LoopBuilder .setImages ( result , back , front ).forEachPixel ( ( r , b , f ) -> {
188- r .set ( f );
189- r .sub ( b );
190- r .mul ( 0.5 );
166+ Parallelization .runSingleThreaded ( () -> {
167+ gradientCentralDerivativeParallel ( source , result , dimension );
191168 } );
192169 }
193170
0 commit comments