Class LoopBuilder<T>
- java.lang.Object
-
- net.imglib2.loops.LoopBuilder<T>
-
public class LoopBuilder<T> extends java.lang.ObjectLoopBuilderprovides an easy way to write fast loops onRandomAccessibleIntervals. 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
RandomAccessibleIntervalsimageA,imageBandsummust have equal dimensions, but the bounds of thereIntervalscan differ.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static interfaceLoopBuilder.Chunk<T>static interfaceLoopBuilder.FiveConsumer<A,B,C,D,E>static interfaceLoopBuilder.FourConsumer<A,B,C,D>static interfaceLoopBuilder.SixConsumer<A,B,C,D,E,F>static interfaceLoopBuilder.TriConsumer<A,B,C>
-
Field Summary
Fields Modifier and Type Field Description private Dimensionsdimensionsprivate RandomAccessibleInterval<?>[]imagesprivate TaskExecutortaskExecutorprivate booleanuseFlatIterationOrder
-
Constructor Summary
Constructors Modifier Constructor Description privateLoopBuilder(RandomAccessibleInterval<?>... images)
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description private booleanallCursorsAreFast(java.util.List<IterableInterval<?>> iterableIntervals)private static booleanallEqual(java.util.List<java.lang.Object> values)private voidcheckDimensions()private booleancursorIsFast(IterableInterval<?> image)private java.util.List<IterableInterval<?>>equalIterationOrderIterableIntervals()private java.util.List<IterableInterval<?>>flatIterableIntervals()LoopBuilder<T>flatIterationOrder()LoopBuildermight use any iteration order to execute the loop.LoopBuilder<T>flatIterationOrder(boolean value)If false,LoopBuildermight use any iteration order to execute the loop.<R> java.util.List<R>forEachChunk(java.util.function.Function<LoopBuilder.Chunk<T>,R> action)This method is similar toforEachPixel(T)but more flexible when multi threading is used.voidforEachPixel(T action)private java.util.List<IterableInterval<?>>imagesAsIterableIntervals()private static RandomAccess<?>initRandomAccess(RandomAccessibleInterval<?> image)private static voidjumpFwd(java.util.List<Cursor<?>> cursors, long offset)LoopBuilder<T>multiThreaded()By defaultLoopBuilderruns the loop without multi-threading.LoopBuilder<T>multiThreaded(boolean multiThreaded)LoopBuilder<T>multiThreaded(TaskExecutor taskExecutor)By defaultLoopBuilderruns the loop without multi-threading.(package private) static <T,R>
RrunOnChunkUsingCursors(java.util.List<IterableInterval<?>> iterableIntervals, java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction, long offset, long numElements)(package private) static <T,R>
RrunOnChunkUsingRandomAccesses(RandomAccessibleInterval[] images, java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction, Interval subInterval)private <R> java.util.List<R>runUsingCursors(java.util.List<IterableInterval<?>> iterableIntervals, java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction)private <R> java.util.List<R>runUsingRandomAccesses(java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction)static <A> LoopBuilder<java.util.function.Consumer<A>>setImages(RandomAccessibleInterval<A> a)static <A,B>
LoopBuilder<java.util.function.BiConsumer<A,B>>setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b)static <A,B,C>
LoopBuilder<LoopBuilder.TriConsumer<A,B,C>>setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c)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)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)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)
-
-
-
Field Detail
-
dimensions
private final Dimensions dimensions
-
images
private final RandomAccessibleInterval<?>[] images
-
taskExecutor
private TaskExecutor taskExecutor
-
useFlatIterationOrder
private boolean useFlatIterationOrder
-
-
Constructor Detail
-
LoopBuilder
private LoopBuilder(RandomAccessibleInterval<?>... images)
-
-
Method Detail
-
setImages
public static <A> LoopBuilder<java.util.function.Consumer<A>> setImages(RandomAccessibleInterval<A> a)
- See Also:
LoopBuilder
-
setImages
public static <A,B> LoopBuilder<java.util.function.BiConsumer<A,B>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b)
- See Also:
LoopBuilder
-
setImages
public static <A,B,C> LoopBuilder<LoopBuilder.TriConsumer<A,B,C>> setImages(RandomAccessibleInterval<A> a, RandomAccessibleInterval<B> b, RandomAccessibleInterval<C> c)
- See Also:
LoopBuilder
-
setImages
public 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)
- See Also:
LoopBuilder
-
setImages
public 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)
- See Also:
LoopBuilder
-
setImages
public 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)
- See Also:
LoopBuilder
-
forEachPixel
public void forEachPixel(T action)
- See Also:
LoopBuilder
-
forEachChunk
public <R> java.util.List<R> forEachChunk(java.util.function.Function<LoopBuilder.Chunk<T>,R> action)
This method is similar toforEachPixel(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
IntTypeis used to calculate the sum, butIntTypeis 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;
-
allCursorsAreFast
private boolean allCursorsAreFast(java.util.List<IterableInterval<?>> iterableIntervals)
-
cursorIsFast
private boolean cursorIsFast(IterableInterval<?> image)
-
multiThreaded
public LoopBuilder<T> multiThreaded()
By defaultLoopBuilderruns the loop without multi-threading. Calling this method allowsLoopBuilderto use multi-threading for optimal performance.Usually, if this method is used,
LoopBuilderwill indeed use multi-threading. But that's not always the case. TheParallelizationclass can still be used to explicitly run the code single-threaded.Here is a small example for a copy method with enabled multi-threading.
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. Thepublic void copy( RandomAccessibleInterval<T> source, RandomAccessibleInterval<T> target) { LoopBuilder.setImages( source, target ).multiThreaded().forEachPixel( ( s, t ) -> t.set( s ) ); }Parallelizationclass allows the user to run the code single-threaded:
WARNING: You need to make sure that the action passed toParallelization.runSingleThreaded( () -> { copy( source, target ); } );forEachPixel(T)is thread safe.- See Also:
Parallelization
-
multiThreaded
public LoopBuilder<T> multiThreaded(boolean multiThreaded)
-
multiThreaded
public LoopBuilder<T> multiThreaded(TaskExecutor taskExecutor)
By defaultLoopBuilderruns the loop without multi-threading. Calling this method causes LoopBuilder to use the givenTaskExecutorfor multi-threading.WARNING: You need to make sure that your operation is thread safe.
-
flatIterationOrder
public LoopBuilder<T> flatIterationOrder()
LoopBuildermight use any iteration order to execute the loop. Calling this method will causeLoopBuilderto use flat iteration order, when executing the loop.WARNING: Don't use multi-threading if you want to have flat iteration order.
-
flatIterationOrder
public LoopBuilder<T> flatIterationOrder(boolean value)
If false,LoopBuildermight use any iteration order to execute the loop.If true,
LoopBuilderwill use flat iteration order, and multi threading is disabled.WARNING: Don't use multi-threading if you want to have flat iteration order.
- See Also:
FlatIterationOrder
-
checkDimensions
private void checkDimensions()
-
runUsingRandomAccesses
private <R> java.util.List<R> runUsingRandomAccesses(java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction)
-
runOnChunkUsingRandomAccesses
static <T,R> R runOnChunkUsingRandomAccesses(RandomAccessibleInterval[] images, java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction, Interval subInterval)
-
initRandomAccess
private static RandomAccess<?> initRandomAccess(RandomAccessibleInterval<?> image)
-
imagesAsIterableIntervals
private java.util.List<IterableInterval<?>> imagesAsIterableIntervals()
-
runUsingCursors
private <R> java.util.List<R> runUsingCursors(java.util.List<IterableInterval<?>> iterableIntervals, java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction)
-
runOnChunkUsingCursors
static <T,R> R runOnChunkUsingCursors(java.util.List<IterableInterval<?>> iterableIntervals, java.util.function.Function<LoopBuilder.Chunk<T>,R> chunkAction, long offset, long numElements)
-
jumpFwd
private static void jumpFwd(java.util.List<Cursor<?>> cursors, long offset)
-
equalIterationOrderIterableIntervals
private java.util.List<IterableInterval<?>> equalIterationOrderIterableIntervals()
-
flatIterableIntervals
private java.util.List<IterableInterval<?>> flatIterableIntervals()
-
allEqual
private static boolean allEqual(java.util.List<java.lang.Object> values)
-
-