34
34
35
35
package net .imglib2 .algorithm .gradient ;
36
36
37
- import java .util .ArrayList ;
38
- import java .util .List ;
39
- import java .util .concurrent .Callable ;
40
37
import java .util .concurrent .ExecutionException ;
41
38
import java .util .concurrent .ExecutorService ;
42
- import java .util .concurrent .Future ;
43
39
44
40
import net .imglib2 .Cursor ;
45
- import net .imglib2 .FinalInterval ;
46
41
import net .imglib2 .RandomAccessible ;
47
42
import net .imglib2 .RandomAccessibleInterval ;
48
43
import net .imglib2 .loops .LoopBuilder ;
44
+ import net .imglib2 .parallel .TaskExecutor ;
45
+ import net .imglib2 .parallel .Parallelization ;
46
+ import net .imglib2 .parallel .TaskExecutors ;
49
47
import net .imglib2 .type .numeric .NumericType ;
50
48
import net .imglib2 .util .Intervals ;
51
- import net .imglib2 .view .IntervalView ;
52
49
import net .imglib2 .view .Views ;
53
50
54
51
/**
@@ -98,7 +95,7 @@ public static < T extends NumericType< T > > void gradientCentralDifference2( fi
98
95
* @param source
99
96
* source image, has to provide valid data in the interval of the
100
97
* gradient image plus a one pixel border in dimension.
101
- * @param gradient
98
+ * @param result
102
99
* output image
103
100
* @param dimension
104
101
* along which dimension the partial derivatives are computed
@@ -110,57 +107,42 @@ public static < T extends NumericType< T > > void gradientCentralDifference2( fi
110
107
*/
111
108
public static < T extends NumericType < T > > void gradientCentralDifferenceParallel (
112
109
final RandomAccessible < T > source ,
113
- final RandomAccessibleInterval < T > gradient ,
110
+ final RandomAccessibleInterval < T > result ,
114
111
final int dimension ,
115
112
final int nTasks ,
116
113
final ExecutorService es ) throws InterruptedException , ExecutionException
117
114
{
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
+ }
159
120
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 ) );
161
140
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
+ } );
164
146
}
165
147
166
148
// fast version
@@ -181,13 +163,8 @@ public static < T extends NumericType< T > > void gradientCentralDifferenceParal
181
163
public static < T extends NumericType < T > > void gradientCentralDifference ( final RandomAccessible < T > source ,
182
164
final RandomAccessibleInterval < T > result , final int dimension )
183
165
{
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 );
191
168
} );
192
169
}
193
170
0 commit comments