Skip to content

Commit

Permalink
update jdll to improve .npy file to imglib2 array tensor conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosuc3m committed Oct 17, 2023
1 parent 3c1696b commit cee4d1f
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>org.scijava</groupId>
<artifactId>pom-scijava</artifactId>
<version>36.0.0</version>
<version>37.0.0</version>
<relativePath />
</parent>

Expand Down
57 changes: 46 additions & 11 deletions src/main/java/io/bioimage/modelrunner/numpy/DecodeNumpy.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,25 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import io.bioimage.modelrunner.tensor.Utils;
import io.bioimage.modelrunner.utils.IndexingUtils;
import net.imglib2.Cursor;
import net.imglib2.RandomAccessibleInterval;
import net.imglib2.img.Img;
import net.imglib2.img.array.ArrayImgFactory;
import net.imglib2.img.array.ArrayImgs;
import net.imglib2.img.basictypeaccess.ByteAccess;
import net.imglib2.img.basictypeaccess.DoubleAccess;
import net.imglib2.img.basictypeaccess.FloatAccess;
import net.imglib2.img.basictypeaccess.IntAccess;
import net.imglib2.img.basictypeaccess.LongAccess;
import net.imglib2.img.basictypeaccess.ShortAccess;
import net.imglib2.img.basictypeaccess.nio.ByteBufferAccess;
import net.imglib2.img.basictypeaccess.nio.DoubleBufferAccess;
import net.imglib2.img.basictypeaccess.nio.FloatBufferAccess;
import net.imglib2.img.basictypeaccess.nio.IntBufferAccess;
import net.imglib2.img.basictypeaccess.nio.LongBufferAccess;
import net.imglib2.img.basictypeaccess.nio.ShortBufferAccess;
import net.imglib2.type.NativeType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.type.numeric.integer.ByteType;
Expand Down Expand Up @@ -305,28 +319,49 @@ private static void readData(DataInputStream dis, ByteBuffer data, int len) thro
* If the tensor type is not supported.
*/
@SuppressWarnings("unchecked")
public static <T extends NativeType<T>> Img<T> build(ByteBuffer buf, ByteOrder byteOrder, String dtype, long[] shape) throws IllegalArgumentException
public static <T extends NativeType<T>> RandomAccessibleInterval<T> build(ByteBuffer buf, ByteOrder byteOrder, String dtype, long[] shape) throws IllegalArgumentException
{
long[] transposedShape = new long[shape.length];
for (int i = 0; i < shape.length; i ++)
transposedShape[i] = shape[shape.length - i - 1];
if (dtype.equals("int8")) {
return (Img<T>) buildInt8(buf, byteOrder, shape);
ByteAccess access = new ByteBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.bytes( access, shape ));
//return (Img<T>) buildInt8(buf, byteOrder, shape);
} else if (dtype.equals("uint8")) {
return (Img<T>) buildUInt8(buf, byteOrder, shape);
ByteAccess access = new ByteBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.unsignedBytes( access, shape ));
//return (Img<T>) buildUInt8(buf, byteOrder, shape);
} else if (dtype.equals("int16")) {
return (Img<T>) buildInt16(buf, byteOrder, shape);
ShortAccess access = new ShortBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.shorts( access, shape ));
//return (Img<T>) buildInt16(buf, byteOrder, shape);
} else if (dtype.equals("uint16")) {
return (Img<T>) buildUInt16(buf, byteOrder, shape);
ShortAccess access = new ShortBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.unsignedShorts( access, shape ));
//return (Img<T>) buildUInt16(buf, byteOrder, shape);
} else if (dtype.equals("int32")) {
return (Img<T>) buildInt32(buf, byteOrder, shape);
IntAccess access = new IntBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.ints( access, shape ));
//return (Img<T>) buildInt32(buf, byteOrder, shape);
} else if (dtype.equals("uint32")) {
return (Img<T>) buildUInt32(buf, byteOrder, shape);
IntAccess access = new IntBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.unsignedInts( access, shape ));
//return (Img<T>) buildUInt32(buf, byteOrder, shape);
} else if (dtype.equals("int64")) {
return (Img<T>) buildInt64(buf, byteOrder, shape);
LongAccess access = new LongBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.longs( access, shape ));
//return (Img<T>) buildInt64(buf, byteOrder, shape);
} else if (dtype.equals("float32")) {
return (Img<T>) buildFloat32(buf, byteOrder, shape);
FloatAccess access = new FloatBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.floats( access, shape ));
//return (Img<T>) buildFloat32(buf, byteOrder, shape);
} else if (dtype.equals("float64")) {
return (Img<T>) buildFloat64(buf, byteOrder, shape);
DoubleAccess access = new DoubleBufferAccess(buf, true);
return (RandomAccessibleInterval<T>) Utils.transpose(ArrayImgs.doubles( access, shape ));
//return (Img<T>) buildFloat64(buf, byteOrder, shape);
} else if (dtype.equals("bool")) {
return (Img<T>) buildBoolean(buf, byteOrder, shape);
return (RandomAccessibleInterval<T>) Utils.transpose(buildBoolean(buf, byteOrder, shape));
} else {
throw new IllegalArgumentException("Unsupported data type of numpy array: " + dtype);
}
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/io/bioimage/modelrunner/tensor/Utils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*-
* #%L
* Use deep learning frameworks from Java in an agnostic and isolated way.
* %%
* Copyright (C) 2022 - 2023 Institut Pasteur and BioImage.IO developers.
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
package io.bioimage.modelrunner.tensor;

import net.imglib2.RandomAccessibleInterval;
import net.imglib2.transform.integer.MixedTransform;
import net.imglib2.type.numeric.NumericType;
import net.imglib2.type.numeric.RealType;
import net.imglib2.util.Intervals;
import net.imglib2.view.MixedTransformView;
import net.imglib2.view.Views;

/**
* Provide static methods that can be used to make transformations on tensors
*
* @author Carlos Garcia Lopez de Haro
*/
public final class Utils
{
/**
* Method that transposes every dimension of a {@link RandomAccessibleInterval}.
* If a {@link RandomAccessibleInterval} with {3, 256, 512} dimensions is provided,
* it will be converted into one of {512, 256, 3}
* @param <T>
* possible data types of the {@link RandomAccessibleInterval}
* @param rai
* {@link RandomAccessibleInterval} to be transposed
* @return the transposed {@link RandomAccessibleInterval}
*/
public static <T extends NumericType<T> & RealType<T>>
RandomAccessibleInterval<T> transpose(RandomAccessibleInterval<T> rai){
long[] tensorShape = rai.dimensionsAsLongArray();
MixedTransform t = new MixedTransform( tensorShape.length, tensorShape.length );
int[] transposeAxesOrderChange = new int[tensorShape.length];
for (int i = 0; i < tensorShape.length; i ++) transposeAxesOrderChange[i] = tensorShape.length - 1 - i;
t.setComponentMapping(transposeAxesOrderChange);
long[] minMax = new long[tensorShape.length];
for (int i = 0; i < tensorShape.length; i ++) minMax[i * 2 + 1] = tensorShape[i];
return Views.interval(new MixedTransformView<T>( rai, t ),
Intervals.createMinMax(tensorShape));
}
}

0 comments on commit cee4d1f

Please sign in to comment.