public class LoopBuilder<T> extends Object
LoopBuilder provides an easy way to write fast loops on
RandomAccessibleIntervals. For example, this is a loop that
calculates the sum of two images:
RandomAccessibleInterval<DoubleType> imageA = ...
RandomAccessibleInterval<DoubleType> imageB = ...
RandomAccessibleInterval<DoubleType> sum = ...
LoopBuilder.setImages(imageA, imageB, sum).forEachPixel(
(a, b, s) -> {
s.setReal(a.getRealDouble() + b.getRealDouble());
}
);
The RandomAccessibleIntervals imageA, imageB and
sum must have equal dimensions, but the bounds of there
Intervals can differ.
| Modifier and Type | Class and Description |
|---|---|
static interface |
LoopBuilder.Chunk<T> |
static interface |
LoopBuilder.FiveConsumer<A,B,C,D,E> |
static interface |
LoopBuilder.FourConsumer<A,B,C,D> |
static interface |
LoopBuilder.SixConsumer<A,B,C,D,E,F> |
static interface |
LoopBuilder.TriConsumer<A,B,C> |
public static <A> LoopBuilder<Consumer<A>> setImages(RandomAccessibleInterval<A> a)
LoopBuilderpublic static <A,B> LoopBuilder<BiConsumer<A,B>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b)
LoopBuilderpublic static <A,B,C> LoopBuilder<LoopBuilder.TriConsumer<A,B,C>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c)
LoopBuilderpublic static <A,B,C,D> LoopBuilder<LoopBuilder.FourConsumer<A,B,C,D>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c, RandomAccessibleInterval<D> d)
LoopBuilderpublic static <A,B,C,D,E> LoopBuilder<LoopBuilder.FiveConsumer<A,B,C,D,E>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c, RandomAccessibleInterval<D> d, RandomAccessibleInterval<E> e)
LoopBuilderpublic static <A,B,C,D,E,F> LoopBuilder<LoopBuilder.SixConsumer<A,B,C,D,E,F>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c, RandomAccessibleInterval<D> d, RandomAccessibleInterval<E> e, RandomAccessibleInterval<F> f)
LoopBuilderpublic void forEachPixel(T action)
LoopBuilderpublic <R> List<R> forEachChunk(Function<LoopBuilder.Chunk<T>,R> action)
forEachPixel(T) but more flexible when multi threading is used.
The following example calculates the sum of the pixel values of an image.
Multi threading is used to improve performance. The image is split into chunks.
The chunks are processed in parallel by multiple threads. A variable
of IntType is used to calculate the sum, but IntType is not thread safe.
It's therefore necessary to have one sum variable per chunk. This can be realized as follows:
List<IntType> listOfSums = LoopBuilder.setImages( image ).multithreaded().forEachChunk(
chunk -> {
IntType sum = new IntType();
chunk.forEach( pixel -> sum.add( pixel ) ):
return sum;
}
);
IntType totalSum = new IntType();
listOfSums.forEach( sum -> totalSum.add( sum );
return totalSum;
public LoopBuilder<T> multiThreaded()
LoopBuilder runs the loop without multi-threading.
Calling this method allows LoopBuilder to use multi-threading for optimal performance.
Usually, if this method is used, LoopBuilder will indeed
use multi-threading. But that's not always the case.
The Parallelization class can still be used to explicitly run the
code single-threaded.
Here is a small example for a copy method with enabled multi-threading.
public void copy( RandomAccessibleInterval<T> source, RandomAccessibleInterval<T> target)
{
LoopBuilder.setImages( source, target ).multiThreaded().forEachPixel( ( s, t ) -> t.set( s ) );
}
This method usually runs multi-threaded. Which means good performance.
But sometimes, a user might want to run the code single-threaded.
There's no need to write a second single-threaded version of our copy method.
The Parallelization class allows the user to run the code single-threaded:
Parallelization.runSingleThreaded( () -> {
copy( source, target );
} );
WARNING: You need to make sure that the action passed to forEachPixel(T) is thread safe.Parallelizationpublic LoopBuilder<T> multiThreaded(boolean multiThreaded)
public LoopBuilder<T> multiThreaded(TaskExecutor taskExecutor)
LoopBuilder runs the loop without multi-threading.
Calling this method causes LoopBuilder to use the given TaskExecutor for multi-threading.
WARNING: You need to make sure that your operation is thread safe.
public LoopBuilder<T> flatIterationOrder()
LoopBuilder might use any iteration order to execute
the loop. Calling this method will cause LoopBuilder
to use flat iteration order, when executing the loop.
WARNING: Don't use multi-threading if you want to have flat iteration order.
public LoopBuilder<T> flatIterationOrder(boolean value)
LoopBuilder might use any iteration order
to execute the loop.
If true, LoopBuilder will use
flat iteration order, and multi threading is disabled.
WARNING: Don't use multi-threading if you want to have flat iteration order.
FlatIterationOrderCopyright © 2015–2022 ImgLib2. All rights reserved.