Skip to content

Commit

Permalink
WIP: Add user-facing options config for TensorFlow
Browse files Browse the repository at this point in the history
Unfortunately, there are still some challenges.

* For mode, we need to set org.tensorflow.NativeLibrary.MODE=something
  BEFORE the DefaultTensorFlowService class loads. I.e.: before the
  SciJava Context is created. So: in effect, we would need a restart.

* For graphics card selection, we need to set CUDA_VISIBLE_DEVICES
  and/or CUDA_DEVICE_ORDER env vars, again BEFORE TensorFlow
  initializes, i.e. before SciJava context is created.
  So again: restart.

But even with a restart: how do we ensure that when the JVM starts up,
that these sys props and env vars are set early enough? What machinery
could do this? We do not have anything in place. We could have a file
containing desired key/values, that the launcher Java code reads and
sets as early as possible -- before instantiating the SciJava Context.
But this would be a new feature. Perhaps it could be part of ImageJ.cfg.

An alternative could be to make sure the TensorFlowService does not
reference any TensorFlow classes. E.g., similar to LegacyService and
IJ1Helper, it _might_ work to have something like
tfService.actions().loadModel(...) as a level of indirection. Might be
worth trying, but even if it works, it is quite ugly and unintuitive.
Before we do that, let's verify whether creating an SJ context really
initializes TF early -- maybe it doesn't.

We could submit a pull request to the TensorFlow project that defers
the loading of the native library until the first time any TensorFlow
operation is performed. I.e.: eliminate the static initializers, since
they create problems as described above. But it would be a non-trivial
change to TensorFlow to do that, potentially more difficult to maintain.
  • Loading branch information
ctrueden committed Dec 11, 2018
1 parent 1272efd commit 47f6d33
Showing 1 changed file with 76 additions and 0 deletions.
76 changes: 76 additions & 0 deletions src/main/java/net/imagej/tensorflow/options/OptionsTensorFlow.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*-
* #%L
* ImageJ/TensorFlow integration.
* %%
* Copyright (C) 2017 Board of Regents of the University of
* Wisconsin-Madison and Google, Inc.
* %%
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
* #L%
*/

package net.imagej.tensorflow.options;

import java.util.Arrays;
import java.util.List;

import org.scijava.module.MutableModuleItem;
import org.scijava.options.OptionsPlugin;
import org.scijava.plugin.Parameter;
import org.scijava.plugin.Plugin;

/**
* Options for TensorFlow in ImageJ.
*
* @author Curtis Rueden
*/
@Plugin(type = OptionsPlugin.class, menuPath = "Edit > Options > TensorFlow...")
public class OptionsTensorFlow extends OptionsPlugin {

@Parameter(label = "Mode", choices = {"GPU", "CPU", "Auto"})
private String mode = "Auto";

@Parameter(label = "Graphics card")
private String graphicsCard = "Auto";

@Override
public void initialize() {
final MutableModuleItem<String> graphicsCardInput = //
getInfo().getMutableInput("graphicsCard", String.class);
graphicsCardInput.setChoices(graphicsCardChoices());
}

private List<String> graphicsCardChoices() {
// FIXME: Discover available graphics cards.
// For details on how, see:
// https://github.com/CSBDeep/CSBDeep_website/wiki/CSBDeep-in-Fiji-%E2%80%93-Installation#multiple-gpus
return Arrays.asList("Card1", "Card2");
}

public String getMode() {
return mode;
}

public String getGraphicsCard() {
return graphicsCard;
}
}

0 comments on commit 47f6d33

Please sign in to comment.