Skip to content

Commit

Permalink
make model closeable
Browse files Browse the repository at this point in the history
  • Loading branch information
carlosuc3m committed Oct 3, 2024
1 parent 21f9682 commit d9bce6a
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 143 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -128,19 +128,20 @@ public static void main(String[] args) {
*/
public static <T extends RealType<T> & NativeType<T>, R extends RealType<R> & NativeType<R>>
void loadAndRunModel(String modelFolder, ModelDescriptor descriptor) throws Exception {
Model model = Model.createBioimageioModel(modelFolder, ENGINES_DIR);
model.loadModel();
List<Tensor<FloatType>> inputs = createInputs(descriptor);
List<Tensor<FloatType>> outputs = createOutputs(descriptor);
model.runModel(inputs, outputs);
for (Tensor<FloatType> tt : outputs) {
if (tt.isEmpty())
throw new Exception(descriptor.getName() + ": Output tensor is empty");
try (Model model = Model.createBioimageioModel(modelFolder, ENGINES_DIR);) {
model.loadModel();
List<Tensor<FloatType>> inputs = createInputs(descriptor);
List<Tensor<FloatType>> outputs = createOutputs(descriptor);
model.runModel(inputs, outputs);
for (Tensor<FloatType> tt : outputs) {
if (tt.isEmpty())
throw new Exception(descriptor.getName() + ": Output tensor is empty");
}

model.close();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
}

model.closeModel();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ void main(String[] args) throws LoadEngineException, Exception {
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.closeModel();
model.close();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.print("Success!!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,40 +123,40 @@ void loadAndRunPt2(String modelFolder, String modelSource) throws LoadEngineExce
// REGARD THAT the engine folders need to follow a naming convention
EngineInfo engineInfo = createEngineInfo(framework, engineVersion, enginesDir, cpu, gpu);
// Load the corresponding model, for Pytorch model_source arg is not needed
Model model = loadModel(modelFolder, modelSource, engineInfo);
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 1, 512, 512 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input0", "bcyx", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);

// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
/*Tensor<FloatType> outTensor = Tensor.buildBlankTensor("output0",
"bcyx",
new long[] {1, 2, 512, 512},
new FloatType());*/
final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 );
Tensor<FloatType> outTensor = Tensor.build("output0", "bcyx", img2);
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor);

// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.closeModel();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Pytorch 2!!");
try (Model model = loadModel(modelFolder, modelSource, engineInfo);) {
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 1, 512, 512 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input0", "bcyx", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);
// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
/*Tensor<FloatType> outTensor = Tensor.buildBlankTensor("output0",
"bcyx",
new long[] {1, 2, 512, 512},
new FloatType());*/
final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 );
Tensor<FloatType> outTensor = Tensor.build("output0", "bcyx", img2);
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor);
// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Pytorch 2!!");
}
}

/**
Expand Down Expand Up @@ -198,40 +198,40 @@ void loadAndRunPt1(String modelFolder, String modelSource) throws LoadEngineExce
// REGARD THAT the engine folders need to follow a naming convention
EngineInfo engineInfo = createEngineInfo(framework, engineVersion, enginesDir, cpu, gpu);
// Load the corresponding model, for Pytorch the arg model_source is not needed
Model model = loadModel(modelFolder, modelSource, engineInfo);
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 1, 512, 512 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input0", "bcyx", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);

// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
/*Tensor<FloatType> outTensor = Tensor.buildBlankTensor("output0",
"bcyx",
new long[] {1, 2, 512, 512},
new FloatType());*/
final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 );
Tensor<FloatType> outTensor = Tensor.build("output0", "bcyx", img2);
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor);

// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.closeModel();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Pytorch 1!!");
try (Model model = loadModel(modelFolder, modelSource, engineInfo);) {
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 1, 512, 512 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input0", "bcyx", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);
// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
/*Tensor<FloatType> outTensor = Tensor.buildBlankTensor("output0",
"bcyx",
new long[] {1, 2, 512, 512},
new FloatType());*/
final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 );
Tensor<FloatType> outTensor = Tensor.build("output0", "bcyx", img2);
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor);
// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Pytorch 1!!");
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,36 +130,37 @@ void loadAndRunTf2() throws LoadEngineException, Exception {
// REGARD THAT the engine folders need to follow a naming convention
EngineInfo engineInfo = createEngineInfo(framework, engineVersion, enginesDir, cpu, gpu);
// Load the corresponding model, for Tensorflow model_source arg is not needed
Model model = loadModel(modelFolder, null, engineInfo);
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 512, 512, 1 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input_1", "bxyc", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);

// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
Tensor<FloatType> outTensor0 = Tensor.buildBlankTensor(
"conv2d_19", "bxyc", new long[] {1, 512, 512, 3}, new FloatType());
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor0);

// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.closeModel();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Tensorflow 2!!");
try (Model model = loadModel(modelFolder, null, engineInfo)){
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 512, 512, 1 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input_1", "bxyc", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);

// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
Tensor<FloatType> outTensor0 = Tensor.buildBlankTensor(
"conv2d_19", "bxyc", new long[] {1, 512, 512, 3}, new FloatType());
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor0);

// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.close();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Tensorflow 2!!");
}
}

/**
Expand Down Expand Up @@ -202,36 +203,37 @@ void loadAndRunTf1() throws LoadEngineException, Exception {
// REGARD THAT the engine folders need to follow a naming convention
EngineInfo engineInfo = createEngineInfo(framework, engineVersion, enginesDir, cpu, gpu);
// Load the corresponding model, for Tensorflow the arg model_source is not needed
Model model = loadModel(modelFolder, null, engineInfo);
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 512, 512, 3 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input", "byxc", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);

// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
final Img< FloatType > img2 = imgFactory.create( 1, 512, 512, 33 );
Tensor<FloatType> outTensor = Tensor.build("output", "byxc", img2);
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor);

// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.closeModel();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Tensorflow 1!!");
try (Model model = loadModel(modelFolder, null, engineInfo);){
// Create an image that will be the backend of the Input Tensor
final ImgFactory< FloatType > imgFactory = new ArrayImgFactory<>( new FloatType() );
final Img< FloatType > img1 = imgFactory.create( 1, 512, 512, 3 );
// Create the input tensor with the nameand axes given by the rdf.yaml file
// and add it to the list of input tensors
Tensor<FloatType> inpTensor = Tensor.build("input", "byxc", img1);
List<Tensor<FloatType>> inputs = new ArrayList<Tensor<FloatType>>();
inputs.add(inpTensor);

// Create the output tensors defined in the rdf.yaml file with their corresponding
// name and axes and add them to the output list of tensors.
/// Regard that output tensors can be built empty without allocating memory
// or allocating memory by creating the tensor with a sample empty image, or by
// defining the dimensions and data type
final Img< FloatType > img2 = imgFactory.create( 1, 512, 512, 33 );
Tensor<FloatType> outTensor = Tensor.build("output", "byxc", img2);
List<Tensor<FloatType>> outputs = new ArrayList<Tensor<FloatType>>();
outputs.add(outTensor);

// Run the model on the input tensors. THe output tensors
// will be rewritten with the result of the execution
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
model.runModel(inputs, outputs);
System.out.println(Util.average(Util.asDoubleArray(outputs.get(0).getData())));
// The result is stored in the list of tensors "outputs"
model.close();
inputs.stream().forEach(t -> t.close());
outputs.stream().forEach(t -> t.close());
System.out.println("Success running Tensorflow 1!!");
}
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/main/java/io/bioimage/modelrunner/model/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*/
package io.bioimage.modelrunner.model;

import java.io.Closeable;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
Expand Down Expand Up @@ -68,7 +69,7 @@
*
* @author Carlos Garcia Lopez de Haro
*/
public class Model
public class Model implements Closeable
{
/**
* Whether the model is loaded or not
Expand Down Expand Up @@ -499,10 +500,11 @@ public void loadModel() throws LoadModelException
}

/**
* @Override
* Close the Deep LEarning model in the ClassLoader where the Deep Learning
* framework has been called and instantiated
*/
public void closeModel()
public void close()
{
DeepLearningEngineInterface engineInstance = getEngineClassLoader().getEngineInstance();
engineClassLoader.setEngineClassLoader();
Expand Down

0 comments on commit d9bce6a

Please sign in to comment.