diff --git a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunAllBmzModels.java b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunAllBmzModels.java index e0b47e3b..18a361db 100644 --- a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunAllBmzModels.java +++ b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunAllBmzModels.java @@ -128,19 +128,20 @@ public static void main(String[] args) { */ public static & NativeType, R extends RealType & NativeType> void loadAndRunModel(String modelFolder, ModelDescriptor descriptor) throws Exception { - Model model = Model.createBioimageioModel(modelFolder, ENGINES_DIR); - model.loadModel(); - List> inputs = createInputs(descriptor); - List> outputs = createOutputs(descriptor); - model.runModel(inputs, outputs); - for (Tensor 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> inputs = createInputs(descriptor); + List> outputs = createOutputs(descriptor); + model.runModel(inputs, outputs); + for (Tensor 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()); } /** diff --git a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunModel.java b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunModel.java index f65abdd6..2451fd6c 100644 --- a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunModel.java +++ b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadAndRunModel.java @@ -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!!"); diff --git a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadPytorch1Pytorch2.java b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadPytorch1Pytorch2.java index c428e675..d8187970 100644 --- a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadPytorch1Pytorch2.java +++ b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadPytorch1Pytorch2.java @@ -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 inpTensor = Tensor.build("input0", "bcyx", img1); - List> inputs = new ArrayList>(); - 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 outTensor = Tensor.buildBlankTensor("output0", - "bcyx", - new long[] {1, 2, 512, 512}, - new FloatType());*/ - final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 ); - Tensor outTensor = Tensor.build("output0", "bcyx", img2); - List> outputs = new ArrayList>(); - 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 inpTensor = Tensor.build("input0", "bcyx", img1); + List> inputs = new ArrayList>(); + 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 outTensor = Tensor.buildBlankTensor("output0", + "bcyx", + new long[] {1, 2, 512, 512}, + new FloatType());*/ + final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 ); + Tensor outTensor = Tensor.build("output0", "bcyx", img2); + List> outputs = new ArrayList>(); + 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!!"); + } } /** @@ -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 inpTensor = Tensor.build("input0", "bcyx", img1); - List> inputs = new ArrayList>(); - 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 outTensor = Tensor.buildBlankTensor("output0", - "bcyx", - new long[] {1, 2, 512, 512}, - new FloatType());*/ - final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 ); - Tensor outTensor = Tensor.build("output0", "bcyx", img2); - List> outputs = new ArrayList>(); - 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 inpTensor = Tensor.build("input0", "bcyx", img1); + List> inputs = new ArrayList>(); + 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 outTensor = Tensor.buildBlankTensor("output0", + "bcyx", + new long[] {1, 2, 512, 512}, + new FloatType());*/ + final Img< FloatType > img2 = imgFactory.create( 1, 2, 512, 512 ); + Tensor outTensor = Tensor.build("output0", "bcyx", img2); + List> outputs = new ArrayList>(); + 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!!"); + } } /** diff --git a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadTensorflow1Tensorflow2.java b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadTensorflow1Tensorflow2.java index 2c69990c..cd797be9 100644 --- a/src/main/java/io/bioimage/modelrunner/example/ExampleLoadTensorflow1Tensorflow2.java +++ b/src/main/java/io/bioimage/modelrunner/example/ExampleLoadTensorflow1Tensorflow2.java @@ -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 inpTensor = Tensor.build("input_1", "bxyc", img1); - List> inputs = new ArrayList>(); - 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 outTensor0 = Tensor.buildBlankTensor( - "conv2d_19", "bxyc", new long[] {1, 512, 512, 3}, new FloatType()); - List> outputs = new ArrayList>(); - 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 inpTensor = Tensor.build("input_1", "bxyc", img1); + List> inputs = new ArrayList>(); + 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 outTensor0 = Tensor.buildBlankTensor( + "conv2d_19", "bxyc", new long[] {1, 512, 512, 3}, new FloatType()); + List> outputs = new ArrayList>(); + 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!!"); + } } /** @@ -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 inpTensor = Tensor.build("input", "byxc", img1); - List> inputs = new ArrayList>(); - 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 outTensor = Tensor.build("output", "byxc", img2); - List> outputs = new ArrayList>(); - 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 inpTensor = Tensor.build("input", "byxc", img1); + List> inputs = new ArrayList>(); + 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 outTensor = Tensor.build("output", "byxc", img2); + List> outputs = new ArrayList>(); + 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!!"); + } } /** diff --git a/src/main/java/io/bioimage/modelrunner/model/Model.java b/src/main/java/io/bioimage/modelrunner/model/Model.java index 2a872431..e117a68b 100644 --- a/src/main/java/io/bioimage/modelrunner/model/Model.java +++ b/src/main/java/io/bioimage/modelrunner/model/Model.java @@ -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; @@ -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 @@ -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();