diff --git a/tensor-flow-manager/.gitignore b/tensor-flow-manager/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..0c45ab0326e5898aa075cf490d2d13e2046dc16d --- /dev/null +++ b/tensor-flow-manager/.gitignore @@ -0,0 +1,8 @@ +/.settings/ +/downloads/ +/plugins/ +/target/ +/workspace/ +/.classpath +/.project +/setting.xml diff --git a/tensor-flow-manager/pom.xml b/tensor-flow-manager/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ec8c0090561a781e91c863f65b71083ee669b7a7 --- /dev/null +++ b/tensor-flow-manager/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>parent-pom-plugin</artifactId> + <version>1.0.3</version> + </parent> + <artifactId>tensor-flow-manager</artifactId> + <version>1.0.0</version> + <name>TensorFlow manager for Icy</name> + <description>This project holds the code for the TensorFlow library manager. It allows users to download, install and select the version of TensorFlow that other plugins use in Icy. + </description> + <build> + <plugins> + <!--<plugin><groupId>org.codehaus.mojo</groupId><artifactId>exec-maven-plugin</artifactId><version>1.3.2</version><executions><execution><phase>install</phase><goals><goal>java</goal></goals></execution></executions><configuration><mainClass>icy.main.Icy</mainClass></configuration></plugin>--> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <configuration> + <additionalOptions> + <additionalOption>-Xdoclint:none</additionalOption> + </additionalOptions> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>ezplug</artifactId> + </dependency> + <dependency> + <groupId>org.bioimageanalysis.icy</groupId> + <artifactId>protocols</artifactId> + </dependency> + <!-- gson library for JSON parsing --> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + <version>2.8.6</version> + </dependency> + <!-- https://mvnrepository.com/artifact/org.tensorflow/tensorflow-core-api --> + <!--<dependency> + <groupId>org.tensorflow</groupId> + <artifactId>tensorflow-core-platform-mkl</artifactId> + <version>0.2.0</version> + </dependency>--> + + <!-- <dependency> + <groupId>org.tensorflow</groupId> + <artifactId>tensorflow</artifactId> + <version>1.15.0</version> + </dependency>--> + </dependencies> + <repositories> + <repository> + <id>icy</id> + <url>https://icy-nexus.pasteur.fr/repository/Icy/</url> + </repository> + </repositories> +</project> \ No newline at end of file diff --git a/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/system/PlatformDetection.java b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/system/PlatformDetection.java new file mode 100644 index 0000000000000000000000000000000000000000..9752379a483d67663a40d71919dac0e2f933bebd --- /dev/null +++ b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/system/PlatformDetection.java @@ -0,0 +1,86 @@ +package org.bioimageanalysis.icy.system; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.SystemUtils; + +public class PlatformDetection +{ + private String os; + private String arch; + public static String OS_WINDOWS = "windows"; + public static String OS_OSX = "macosx"; + public static String OS_SOLARIS = "solaris"; + public static String OS_LINUX = "linux"; + public static String ARCH_PPC = "ppc"; + public static String ARCH_X86_32 = "x86"; + public static String ARCH_X86_64 = "x86_64"; + + public PlatformDetection() + { + // resolve OS + if (SystemUtils.IS_OS_WINDOWS) + { + this.os = OS_WINDOWS; + } + else if (SystemUtils.IS_OS_MAC_OSX) + { + this.os = OS_OSX; + } + else if (SystemUtils.IS_OS_SOLARIS) + { + this.os = OS_SOLARIS; + } + else if (SystemUtils.IS_OS_LINUX) + { + this.os = OS_LINUX; + } + else + { + throw new IllegalArgumentException("Unknown operating system " + SystemUtils.OS_NAME); + } + + // resolve architecture + Map<String, String> archMap = new HashMap<String, String>(); + archMap.put("x86", ARCH_X86_32); + archMap.put("i386", ARCH_X86_32); + archMap.put("i486", ARCH_X86_32); + archMap.put("i586", ARCH_X86_32); + archMap.put("i686", ARCH_X86_32); + archMap.put("x86_64", ARCH_X86_64); + archMap.put("amd64", ARCH_X86_64); + archMap.put("powerpc", ARCH_PPC); + this.arch = archMap.get(SystemUtils.OS_ARCH); + if (this.arch == null) + { + throw new IllegalArgumentException("Unknown architecture " + SystemUtils.OS_ARCH); + } + } + + public String getOs() + { + return os; + } + + public String getArch() + { + return arch; + } + + public void setArch(String arch) + { + this.arch = arch; + } + + public void setOs(String os) + { + this.os = os; + } + + public String toString() + { + + return os + "-" + arch; + } +} diff --git a/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/LibraryLoadingStatus.java b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/LibraryLoadingStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..db76970d0344715901655b3510e5076e80f3724c --- /dev/null +++ b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/LibraryLoadingStatus.java @@ -0,0 +1,72 @@ +package org.bioimageanalysis.icy.tensorflow.versionmanager.loading; + +import org.bioimageanalysis.icy.tensorflow.versionmanager.version.TensorFlowVersion; + +public class LibraryLoadingStatus +{ + public static final String LOADED = "Loaded"; + public static final String ALREADY_LOADED = "Already loaded"; + public static final String NOT_LOADED = "Not loaded"; + public static final String ERROR_LOADING = "Error loading"; + + public static LibraryLoadingStatus loaded(TensorFlowVersion targetVersion) + { + return new LibraryLoadingStatus(LOADED, targetVersion, targetVersion); + } + + public static LibraryLoadingStatus alreadyLoaded(TensorFlowVersion targetVersion, TensorFlowVersion loadedVersion) + { + return new LibraryLoadingStatus(ALREADY_LOADED, targetVersion, loadedVersion); + } + + public static LibraryLoadingStatus notLoaded() + { + return new LibraryLoadingStatus(NOT_LOADED, null, null); + } + + public static LibraryLoadingStatus errorLoading(TensorFlowVersion targetVersion, TensorFlowVersion loadedVersion, + String errorMessage) + { + return new LibraryLoadingStatus(ERROR_LOADING, targetVersion, loadedVersion, errorMessage); + } + + private String status; + private TensorFlowVersion targetVersion; + private TensorFlowVersion loadedVersion; + private String message; + + public LibraryLoadingStatus(String status, TensorFlowVersion targetVersion, TensorFlowVersion loadedVersion, + String message) + { + this.status = status; + this.targetVersion = targetVersion; + this.loadedVersion = loadedVersion; + this.message = message; + } + + public LibraryLoadingStatus(String status, TensorFlowVersion targetVersion, TensorFlowVersion loadedVersion) + { + this(status, targetVersion, loadedVersion, ""); + } + + public String getStatus() + { + return status; + } + + public TensorFlowVersion getTargetVersion() + { + return targetVersion; + } + + public TensorFlowVersion getLoadedVersion() + { + return loadedVersion; + } + + public String getMessage() + { + return message; + } + +} diff --git a/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/TensorFlowVersionDownloader.java b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/TensorFlowVersionDownloader.java new file mode 100644 index 0000000000000000000000000000000000000000..d41cee29bd6c411bd55df91146c0d61324a7bfc8 --- /dev/null +++ b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/TensorFlowVersionDownloader.java @@ -0,0 +1,132 @@ +package org.bioimageanalysis.icy.tensorflow.versionmanager.loading; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.nio.channels.Channels; +import java.nio.channels.ReadableByteChannel; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.Future; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import org.bioimageanalysis.icy.tensorflow.versionmanager.version.TensorFlowVersion; + +public class TensorFlowVersionDownloader +{ + private static Path downloadsPath = Paths.get(".", "downloads").toAbsolutePath(); + + public static boolean isDownloaded(TensorFlowVersion targetVersion) + { + Path versionDirectory = getVersionDirectoryPath(targetVersion); + boolean directoryExists = Files.exists(versionDirectory) && Files.isDirectory(versionDirectory); + if (directoryExists) + { + for (String jarUrl : targetVersion.getJars()) + { + Path localPath; + try + { + localPath = toLocalVersionFile(versionDirectory, jarUrl); + } + catch (MalformedURLException e) + { + e.printStackTrace(); + return false; + } + if (Files.notExists(localPath)) + { + return false; + } + } + return true; + } + return false; + } + + private static Path getVersionDirectoryPath(TensorFlowVersion targetVersion) + { + return downloadsPath.resolve("tensorflow-" + targetVersion.getVersion() + "-" + targetVersion.getOs() + "-" + + targetVersion.getMode()).toAbsolutePath(); + } + + private static Path toLocalVersionFile(Path versionDirectory, String urlString) throws MalformedURLException + { + URL url = new URL(urlString); + Path fileName = Paths.get(url.getPath()).getFileName(); + return versionDirectory.resolve(fileName); + } + + public static List<Path> download(TensorFlowVersion targetVersion) throws IOException + { + Path versionDirectory = getVersionDirectoryPath(targetVersion); + if (Files.notExists(versionDirectory)) + { + Files.createDirectories(versionDirectory); + } + ForkJoinPool pool = new ForkJoinPool(); + Future<List<Path>> resultList = pool.submit(() -> { + final AtomicInteger downloadedFiles = new AtomicInteger(); + final int totalFiles = targetVersion.getJars().size(); + return targetVersion.getJars().parallelStream().map(urlString -> { + try + { + Path resultPath = downloadFile(urlString, versionDirectory); + System.out.println("(" + downloadedFiles.incrementAndGet() + "/" + (totalFiles) + + ") File downloaded to: " + resultPath.toString()); + return resultPath; + } + catch (IOException e) + { + System.out.println("(" + downloadedFiles.incrementAndGet() + "/" + (totalFiles) + + ") File failed downloading: " + urlString); + throw new RuntimeException(e); + } + }).collect(Collectors.toList()); + }); + try + { + return resultList.get(); + } + catch (InterruptedException | ExecutionException e) + { + throw new IOException(e); + } + } + + private static Path downloadFile(String urlString, Path versionDirectory) throws IOException + { + URL url = new URL(urlString); + Path localFilePath = toLocalVersionFile(versionDirectory, urlString); + Files.deleteIfExists(localFilePath); + + ReadableByteChannel readableByteChannel = Channels.newChannel(url.openStream()); + FileOutputStream fileOutputStream = new FileOutputStream(localFilePath.toString()); + fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE); + + return localFilePath; + } + + public static List<Path> getDownloadedFilePaths(TensorFlowVersion targetVersion) + { + Path versionDirectory = getVersionDirectoryPath(targetVersion); + List<Path> pathList = targetVersion.getJars().stream().map(urlString -> { + try + { + return toLocalVersionFile(versionDirectory, urlString); + } + catch (MalformedURLException e) + { + throw new RuntimeException(e); + } + }).collect(Collectors.toList()); + return pathList; + } + +} diff --git a/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/TensorFlowVersionLoader.java b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/TensorFlowVersionLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..e2cc5c9a16153cd925695068836a1bda2768819e --- /dev/null +++ b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/loading/TensorFlowVersionLoader.java @@ -0,0 +1,15 @@ +package org.bioimageanalysis.icy.tensorflow.versionmanager.loading; + +import java.io.IOException; + +import org.bioimageanalysis.icy.tensorflow.versionmanager.version.TensorFlowVersion; + +public class TensorFlowVersionLoader +{ + + public static void load(TensorFlowVersion targetVersion) throws IOException + { + // TODO Auto-generated method stub + } + +} diff --git a/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/version/AvailableTensorFlowVersions.java b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/version/AvailableTensorFlowVersions.java new file mode 100644 index 0000000000000000000000000000000000000000..383e56eb101b2c16b3e6664f14cb8d31e8949b79 --- /dev/null +++ b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/version/AvailableTensorFlowVersions.java @@ -0,0 +1,49 @@ +package org.bioimageanalysis.icy.tensorflow.versionmanager.version; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.List; +import java.util.stream.Collectors; + +import org.bioimageanalysis.icy.system.PlatformDetection; + +import com.google.gson.Gson; + +/** + * Holds the list of available TensorFlow versions. + * + * @author Daniel Felipe Gonzalez Obando + */ +public class AvailableTensorFlowVersions +{ + public static AvailableTensorFlowVersions loadCompatibleOnly() + { + AvailableTensorFlowVersions availableVersions = load(); + String currentPlatform = new PlatformDetection().toString(); + availableVersions.setVersions(availableVersions.getVersions().stream() + .filter(v -> v.getOs().equals(currentPlatform)).collect(Collectors.toList())); + return availableVersions; + } + + public static AvailableTensorFlowVersions load() + { + BufferedReader br = new BufferedReader(new InputStreamReader( + AvailableTensorFlowVersions.class.getClassLoader().getResourceAsStream("availableTFVersions.json"))); + Gson g = new Gson(); + AvailableTensorFlowVersions availableVersions = g.fromJson(br, AvailableTensorFlowVersions.class); + return availableVersions; + } + + private List<TensorFlowVersion> versions; + + public List<TensorFlowVersion> getVersions() + { + return versions; + } + + public void setVersions(List<TensorFlowVersion> versions) + { + this.versions = versions; + } + +} diff --git a/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/version/TensorFlowVersion.java b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/version/TensorFlowVersion.java new file mode 100644 index 0000000000000000000000000000000000000000..05b2d83f59419d8bfa6ab6db00a0445e1cde80a3 --- /dev/null +++ b/tensor-flow-manager/src/main/java/org/bioimageanalysis/icy/tensorflow/versionmanager/version/TensorFlowVersion.java @@ -0,0 +1,122 @@ +package org.bioimageanalysis.icy.tensorflow.versionmanager.version; + +import java.util.List; + +/** + * An available tensor flow version with its properties and needed artifact urls. + * + * @author Daniel Felipe Gonzalez Obando + */ +public class TensorFlowVersion +{ + private String version; + private String tensorFlowVersion; + private String os; + private String mode; + private List<String> jars; + + public String getVersion() + { + return version; + } + + public void setVersion(String version) + { + this.version = version; + } + + public String getTensorFlowVersion() + { + return tensorFlowVersion; + } + + public void setTensorFlowVersion(String tensorFlowVersion) + { + this.tensorFlowVersion = tensorFlowVersion; + } + + public String getOs() + { + return os; + } + + public void setOs(String os) + { + this.os = os; + } + + public String getMode() + { + return mode; + } + + public void setMode(String mode) + { + this.mode = mode; + } + + public List<String> getJars() + { + return jars; + } + + public void setJars(List<String> jars) + { + this.jars = jars; + } + + @Override + public String toString() + { + return "TensorFlowVersion [version=" + version + ", tensorFlowVersion=" + tensorFlowVersion + ", os=" + os + + ", mode=" + mode + ", jars=" + jars + "]"; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + ((mode == null) ? 0 : mode.hashCode()); + result = prime * result + ((os == null) ? 0 : os.hashCode()); + result = prime * result + ((version == null) ? 0 : version.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TensorFlowVersion other = (TensorFlowVersion) obj; + if (mode == null) + { + if (other.mode != null) + return false; + } + else if (!mode.equals(other.mode)) + return false; + if (os == null) + { + if (other.os != null) + return false; + } + else if (!os.equals(other.os)) + return false; + if (version == null) + { + if (other.version != null) + return false; + } + else if (!version.equals(other.version)) + return false; + return true; + } + + + +} diff --git a/tensor-flow-manager/src/main/java/plugins/danyfel80/tensorflowmanager/TensorFlowManager.java b/tensor-flow-manager/src/main/java/plugins/danyfel80/tensorflowmanager/TensorFlowManager.java new file mode 100644 index 0000000000000000000000000000000000000000..f24a392d8884fd7239775ae1a8d4d4d6022a1334 --- /dev/null +++ b/tensor-flow-manager/src/main/java/plugins/danyfel80/tensorflowmanager/TensorFlowManager.java @@ -0,0 +1,164 @@ +package plugins.danyfel80.tensorflowmanager; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.List; +import java.util.Objects; + +import org.bioimageanalysis.icy.tensorflow.versionmanager.loading.LibraryLoadingStatus; +import org.bioimageanalysis.icy.tensorflow.versionmanager.loading.TensorFlowVersionDownloader; +import org.bioimageanalysis.icy.tensorflow.versionmanager.version.TensorFlowVersion; + +import icy.file.FileUtil; +import icy.plugin.PluginLoader; +import icy.plugin.abstract_.Plugin; +import icy.plugin.interface_.PluginLibrary; + +/** + * @author Daniel Felipe Gonzalez Obando + */ +public class TensorFlowManager extends Plugin implements PluginLibrary +{ + private static boolean libraryLoaded; + private static TensorFlowVersion loadedVersion; + + static + { + libraryLoaded = false; + loadedVersion = null; + } + + /** + * This method tries to check if the TensorFlow class can be reached from the {@link PluginLoader}. + * + * @return True if the class is reached and returns a version of the library. + */ + public static boolean isLibraryLoaded() + { + if (libraryLoaded) + return true; + + if (PluginLoader.isLoaded("org.tensorflow.TensorFlow")) + { + try + { + Class<?> cl = PluginLoader.loadClass("org.tensorflow.TensorFlow"); + Method method = cl.getMethod("version"); + method.invoke(cl); + } + catch (Exception e) + { + e.printStackTrace(); + } + return true; + } + return false; + } + + /** + * @return If a TensorFlow version was loaded using {@link TensorFlowManager#loadLibrary(String)} this method will return the active TensorFlow version. + * Otherwise, null is returned. + */ + public static TensorFlowVersion getLoadedVersion() + { + return loadedVersion; + } + + /** + * Loads the {@code targetVersion} library to the PluginLoader. This process includes downloading the libraries from Maven repositories if it is not locally + * available. You can also force the download of the library even if is has already been downloaded. + * + * @param targetVersion + * Target TensorFlow library version. + * @param forceDownload + * If true, library artifacts will be downloaded even if they have already been downloaded. Otherwise, if a downloaded version of the artifacts + * already exist, then it will be used. + * @return The status of the library after trying to load the library. + * @throws IOException + * If an error occurs during the download or the loading of the library. Also, if there is an already loaded version and the given target version is + * different from the one already loaded. + */ + public static synchronized LibraryLoadingStatus loadLibrary(TensorFlowVersion targetVersion, boolean forceDownload) + throws IOException + { + Objects.requireNonNull(targetVersion, "Null TensorFlow version"); + + if (!isLibraryLoaded()) + { + try + { + List<Path> libraryArtifacts; + if (!TensorFlowVersionDownloader.isDownloaded(targetVersion) || forceDownload) + { + libraryArtifacts = TensorFlowVersionDownloader.download(targetVersion); + } + else + { + libraryArtifacts = TensorFlowVersionDownloader.getDownloadedFilePaths(targetVersion); + } + loadLibraryToPluginLoader(targetVersion, libraryArtifacts); + } + catch (Exception e) + { + throw new IOException(e); + } + return LibraryLoadingStatus.loaded(targetVersion); + } + else + { + if (Objects.equals(getLoadedVersion(), targetVersion)) + { + return LibraryLoadingStatus.alreadyLoaded(targetVersion, getLoadedVersion()); + } + else + { + String message = "(loaded: " + + ((getLoadedVersion() == null) ? "Unknown" + : getLoadedVersion().getVersion() + + "-" + getLoadedVersion().getOs() + "-" + getLoadedVersion().getMode()) + + ", target: " + + ((targetVersion == null) ? "Unknown" + : targetVersion.getVersion() + "-" + targetVersion.getOs() + "-" + + targetVersion.getMode()) + + ")"; + throw new IOException("Tried loading a different TensorFlow version " + message); + } + } + } + + private static void loadLibraryToPluginLoader(TensorFlowVersion targetVersion, List<Path> libraryArtifacts) + throws IOException + { + // load jar artifacts to class loader + Path pluginPath; + pluginPath = Paths.get(".", "plugins", "danyfel80", "tensorflowmanager"); + Path libJarsPath = pluginPath.resolve("tensorflowlibs"); + FileUtil.delete(libJarsPath.toString(), true); + Files.createDirectories(libJarsPath); + for (Path downloadPath : libraryArtifacts) + { + Path targetPath = libJarsPath.resolve(downloadPath.getFileName()); + System.out.println("copying: " + targetPath); + Files.copy(downloadPath, targetPath, StandardCopyOption.REPLACE_EXISTING); + } + + PluginLoader.reload(); + + try + { + Class<?> cl = PluginLoader.loadClass("org.tensorflow.TensorFlow"); + System.out.println("Loaded library for " + cl.getSimpleName() + "-" + cl.getMethod("version").invoke(cl)); + } + catch (Exception e) + { + e.printStackTrace(); + } + + loadedVersion = targetVersion; + libraryLoaded = true; + } +} diff --git a/tensor-flow-manager/src/main/java/plugins/danyfel80/tensorflowmanager/TensorFlowVersionSelector.java b/tensor-flow-manager/src/main/java/plugins/danyfel80/tensorflowmanager/TensorFlowVersionSelector.java new file mode 100644 index 0000000000000000000000000000000000000000..a9d5de4f78b18b248c90b643720589378f38d420 --- /dev/null +++ b/tensor-flow-manager/src/main/java/plugins/danyfel80/tensorflowmanager/TensorFlowVersionSelector.java @@ -0,0 +1,170 @@ +package plugins.danyfel80.tensorflowmanager; + +import java.io.IOException; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.bioimageanalysis.icy.tensorflow.versionmanager.loading.LibraryLoadingStatus; +import org.bioimageanalysis.icy.tensorflow.versionmanager.version.AvailableTensorFlowVersions; +import org.bioimageanalysis.icy.tensorflow.versionmanager.version.TensorFlowVersion; + +import icy.gui.dialog.MessageDialog; +import icy.preferences.XMLPreferences; +import icy.system.IcyHandledException; +import icy.util.StringUtil; +import plugins.adufour.blocks.lang.Block; +import plugins.adufour.blocks.util.VarList; +import plugins.adufour.ezplug.EzPlug; +import plugins.adufour.ezplug.EzStoppable; +import plugins.adufour.ezplug.EzVarText; +import plugins.adufour.vars.lang.VarBoolean; +import plugins.adufour.vars.lang.VarString; + +/** + * This plugin allows users to select the TensorFlow version to load in memory. + * Just select one of the available versions and click the "play" button to load the library. + * Please keep in mind that only one version of TensorFlow can be loaded per Icy + * execution. An Exception will be thrown if a TensorFlow version tries to loaded after another version has already been loaded. + * + * @author Daniel Felipe Gonzalez Obando + */ +public class TensorFlowVersionSelector extends EzPlug implements EzStoppable, Block +{ + private EzVarText varInVersion; + private final static Map<String, TensorFlowVersion> versions; + static + { + versions = AvailableTensorFlowVersions.loadCompatibleOnly().getVersions().stream() + .collect(Collectors.toMap( + v -> "API " + v.getVersion() + "-" + v.getMode() + " for TF " + v.getTensorFlowVersion(), + Function.identity())); + } + + @Override + protected void initialize() + { + String[] versionStrings = versions.keySet().stream().sorted().toArray(String[]::new); + varInVersion = new EzVarText("Version", versionStrings, getDefaultVersionIndex(versionStrings), false); + addEzComponent(varInVersion); + } + + private VarString varInBlockVersion; + + @Override + public void declareInput(VarList inputMap) + { + String lastUsedVersion = getLastUsedVersion(); + lastUsedVersion = (!lastUsedVersion.equals("")) ? lastUsedVersion + : versions.keySet().stream().findFirst().orElse(""); + + varInBlockVersion = new VarString("Library version", lastUsedVersion); + } + + VarBoolean varOutLoaded; + + @Override + public void declareOutput(VarList outputMap) + { + varOutLoaded = new VarBoolean("Loaded", false); + outputMap.add("Loaded", varOutLoaded); + } + + private int getDefaultVersionIndex(String[] versionStrings) + { + String lastUsedVersion = getLastUsedVersion(); + int lastIndex = 0; + if (versions.containsKey(lastUsedVersion)) + { + for (int i = 0; i < versionStrings.length; i++) + { + if (versionStrings[i].equals(lastUsedVersion)) + { + lastIndex = i; + break; + } + } + } + return lastIndex; + } + + private String getLastUsedVersion() + { + XMLPreferences prefs = getPreferencesRoot(); + return prefs.get("lastUsed", ""); + } + + @Override + protected void execute() + { + String targetVersion = (!isHeadLess()) ? varInVersion.getValue(true) : varInBlockVersion.getValue(true); + + TensorFlowVersion version = versions.get(targetVersion); + try + { + notifyProgress(Double.NaN, "Loading TensorFlow " + version.getVersion() + "-" + version.getOs() + "-" + + version.getMode() + "..."); + LibraryLoadingStatus status = TensorFlowManager.loadLibrary(version, false); + if (status.getStatus().equals(LibraryLoadingStatus.ERROR_LOADING)) + notifyError("Error loading TensorFlow: " + status.getMessage()); + else + notifyInfo("Loaded: version=" + version.getVersion() + ", mode=" + version.getMode() + + ", for TF version=" + version.getTensorFlowVersion()); + + if (!isHeadLess()) + this.getUI().close(); + else + varOutLoaded.setValue(true); + } + catch (IOException e) + { + varOutLoaded.setValue(false); + e.printStackTrace(); + throw new IcyHandledException("Could not load TensorFlow library: ", e); + } + } + + private void notifyProgress(double progress, String message) + { + if (isHeadLess()) + { + System.out.println( + "(" + StringUtil.toString(Double.isFinite(progress) ? (progress * 100d) : 0d, 2) + "%)" + message); + } + else + { + getUI().setProgressBarValue(progress); + getUI().setProgressBarMessage(message); + } + } + + private void notifyError(String message) + { + if (isHeadLess()) + { + System.err.println(message); + } + else + { + MessageDialog.showDialog("Error", message, MessageDialog.ERROR_MESSAGE); + } + } + + private void notifyInfo(String message) + { + if (isHeadLess()) + { + System.out.println(message); + } + else + { + MessageDialog.showDialog("Success", message, MessageDialog.INFORMATION_MESSAGE); + } + } + + @Override + public void clean() + { + } + +} diff --git a/tensor-flow-manager/src/main/resources/availableTFVersions.json b/tensor-flow-manager/src/main/resources/availableTFVersions.json new file mode 100644 index 0000000000000000000000000000000000000000..c567051b8e3685a72500697cb7e4d65e2843a784 --- /dev/null +++ b/tensor-flow-manager/src/main/resources/availableTFVersions.json @@ -0,0 +1,456 @@ +{ + "versions": [ + { + "version": "1.15.0", + "tensorFlowVersion": "1.15.0", + "os": "windows-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow/1.15.0/libtensorflow-1.15.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow_jni/1.15.0/libtensorflow_jni-1.15.0.jar" + ] + }, + { + "version": "1.15.0", + "tensorFlowVersion": "1.15.0", + "os": "windows-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow/1.15.0/libtensorflow-1.15.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow_jni_gpu/1.15.0/libtensorflow_jni_gpu-1.15.0.jar" + ] + }, + { + "version": "1.15.0", + "tensorFlowVersion": "1.15.0", + "os": "macosx-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow/1.15.0/libtensorflow-1.15.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow_jni/1.15.0/libtensorflow_jni-1.15.0.jar" + ] + }, + { + "version": "1.15.0", + "tensorFlowVersion": "1.15.0", + "os": "linux-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow/1.15.0/libtensorflow-1.15.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow_jni/1.15.0/libtensorflow_jni-1.15.0.jar" + ] + }, + { + "version": "1.15.0", + "tensorFlowVersion": "1.15.0", + "os": "linux-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow/1.15.0/libtensorflow-1.15.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/libtensorflow_jni_gpu/1.15.0/libtensorflow_jni_gpu-1.15.0.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "windows-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-windows-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "windows-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-windows-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "windows-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-windows-x86_64-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "windows-x86_64", + "mode": "mkl-gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-windows-x86_64-mkl-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "linux-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-linux-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "linux-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-linux-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "linux-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-linux-x86_64-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "linux-x86_64", + "mode": "mkl-gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-linux-x86_64-mkl-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "macosx-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-macosx-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-macosx-x86_64.jar" + ] + }, + { + "version": "0.2.0", + "tensorFlowVersion": "2.3.1", + "os": "macosx-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.2.0/ndarray-0.2.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.2.0/tensorflow-core-api-0.2.0-macosx-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-macosx-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/mkl-dnn/0.21.5-1.5.4/mkl-dnn-0.21.5-1.5.4-macosx-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "windows-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-windows-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "windows-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-windows-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "windows-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-windows-x86_64-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-linux-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-linux-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-linux-x86_64-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "mkl-gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-linux-x86_64-mkl-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "macosx-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-macosx-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-macosx-x86_64.jar" + ] + }, + { + "version": "0.3.0", + "tensorFlowVersion": "2.4.1", + "os": "macosx-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.0/ndarray-0.3.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.0/tensorflow-core-api-0.3.0-macosx-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-macosx-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "windows-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-windows-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "windows-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-windows-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "windows-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-windows-x86_64-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-windows-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-linux-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-linux-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-linux-x86_64-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "linux-x86_64", + "mode": "mkl-gpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-linux-x86_64-mkl-gpu.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-linux-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "macosx-x86_64", + "mode": "cpu", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-macosx-x86_64.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-macosx-x86_64.jar" + ] + }, + { + "version": "0.3.1", + "tensorFlowVersion": "2.4.1", + "os": "macosx-x86_64", + "mode": "mkl", + "jars": [ + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1.jar", + "https://repo1.maven.org/maven2/com/google/protobuf/protobuf-java/3.8.0/protobuf-java-3.8.0.jar", + "https://repo1.maven.org/maven2/org/tensorflow/ndarray/0.3.1/ndarray-0.3.1.jar", + "https://repo1.maven.org/maven2/org/tensorflow/tensorflow-core-api/0.3.1/tensorflow-core-api-0.3.1-macosx-x86_64-mkl.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4.jar", + "https://repo1.maven.org/maven2/org/bytedeco/javacpp/1.5.4/javacpp-1.5.4-macosx-x86_64.jar" + ] + } + ] +}