chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:47:05 +08:00
commit 4f3b7da785
7394 changed files with 2005594 additions and 0 deletions
@@ -0,0 +1,437 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ /* ******************************************************************************
~ *
~ *
~ * This program and the accompanying materials are made available under the
~ * terms of the Apache License, Version 2.0 which is available at
~ * https://www.apache.org/licenses/LICENSE-2.0.
~ *
~ * See the NOTICE file distributed with this work for additional
~ * information regarding copyright ownership.
~ * Unless required by applicable law or agreed to in writing, software
~ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
~ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
~ * License for the specific language governing permissions and limitations
~ * under the License.
~ *
~ * SPDX-License-Identifier: Apache-2.0
~ ******************************************************************************/
-->
<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.eclipse.deeplearning4j</groupId>
<artifactId>deeplearning4j-ui-parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>deeplearning4j-vertx</artifactId>
<properties>
<module.name>deeplearning4j.vertx</module.name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.moditect</groupId>
<artifactId>moditect-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>${vertx.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.deeplearning4j</groupId>
<artifactId>deeplearning4j-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.deeplearning4j</groupId>
<artifactId>deeplearning4j-ui-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>${jcommander.version}</version>
</dependency>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>org.eclipse.deeplearning4j</groupId>
<artifactId>deeplearning4j-common-tests</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<!-- WebJars Dependencies -->
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>babel__polyfill</artifactId>
<version>7.4.4</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>coreui__coreui</artifactId>
<version>2.1.9</version>
<exclusions>
<exclusion>
<groupId>org.webjars.npm</groupId>
<artifactId>coreui__coreui-plugin-npm-postinstall</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>coreui__icons</artifactId>
<version>0.3.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>popper.js</artifactId>
<version>1.12.9</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-migrate</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-ui</artifactId>
<version>1.10.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>modernizr</artifactId>
<!--<version>2.6.2</version>-->
<version>2.8.3-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-cookie</artifactId>
<version>1.4.1-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>fullcalendar</artifactId>
<version>1.6.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>excanvas</artifactId>
<version>3</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>cytoscape</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>cytoscape-dagre</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>dagre</artifactId>
<version>0.8.4</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>cytoscape-cola</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>cytoscape-cose-bilkent</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>cytoscape-euler</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>cytoscape-klay</artifactId>
<version>3.1.2</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>klayjs</artifactId>
<version>0.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>cytoscape-spread</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>weaverjs</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>retinajs</artifactId>
<version>0.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>flot</artifactId>
<version>0.8.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>chosen</artifactId>
<version>0.9.8</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>uniform</artifactId>
<version>2.1.2-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>noty</artifactId>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-raty</artifactId>
<version>2.5.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>imagesloaded</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>masonry</artifactId>
<version>3.1.5</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery.sparkline</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-knob</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>datatables</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery-ui-touch-punch</artifactId>
<version>0.2.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>d3js</artifactId>
<version>3.3.5</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-notify</artifactId>
<version>3.1.3-1</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>github-com-jboesch-Gritter</artifactId>
<version>1.7.4</version>
</dependency>
<!-- Fonts -->
<dependency>
<groupId>org.webjars.bowergithub.stenin-nikita</groupId>
<artifactId>open-sans</artifactId>
<version>0.1.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>font-awesome</artifactId>
<version>3.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap-glyphicons</artifactId>
<version>bdd2cbfba0</version>
</dependency>
<!-- For SameDiff UI -->
<dependency>
<groupId>org.eclipse.deeplearning4j</groupId>
<artifactId>nd4j-webjar</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<!-- Override webjars dependencies with fixed versions.
See issue #7730 for details
WebJars defines its dependencies using ranges - [3.10.0,4)
However, we want to lock down the versions, for a few reasons:
(a) When defined in a range like this, user builds will check on every build of their project
(b) It makes it harder to debug issues, if user and developers are using different versions
(c) Though in-principle this should be safe, we can't be sure that a 3rd party change won't break our UI with a new version
(d) The ranges don't always work as expected in practice: in one instance 3.0.0-beta9 was considered within the range [2.0.0,3)
-->
<!-- babel__polyfill dependencies -->
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>core-js</artifactId>
<version>2.6.5</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>regenerator-runtime</artifactId>
<version>0.13.2</version>
</dependency>
<!-- coreui__coreui dependencies -->
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>bootstrap</artifactId>
<version>4.3.1</version>
</dependency>
<!-- org.webjars.npm:cytoscape -->
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>heap</artifactId>
<version>0.2.6</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>lodash.debounce</artifactId>
<version>4.0.8</version>
</dependency>
<!-- org.webjars.npm:dagre -->
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>graphlib</artifactId>
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>cytoscape</artifactId>
<version>3.2.5</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>dagre</artifactId>
<version>0.7.4</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>graphlib</artifactId>
<version>1.0.7</version>
</dependency>
<dependency>
<groupId>org.webjars.bower</groupId>
<artifactId>lodash</artifactId>
<version>3.10.1</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>lodash</artifactId>
<version>4.17.11</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>webcola</artifactId>
<version>3.3.8</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>d3-dispatch</artifactId>
<version>1.0.5</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>d3-drag</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>d3-selection</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>d3-timer</artifactId>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>klayjs</artifactId>
<version>0.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>weaverjs</artifactId>
<version>1.2.0</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>explorercanvas</artifactId>
<version>r3-1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>2.2.2-1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>
@@ -0,0 +1,664 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.impl.MimeMapping;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.deeplearning4j.config.DL4JClassLoading;
import org.deeplearning4j.config.DL4JSystemProperties;
import org.deeplearning4j.common.util.ND4JFileUtils;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageEvent;
import org.deeplearning4j.core.storage.StatsStorageListener;
import org.deeplearning4j.core.storage.StatsStorageRouter;
import org.deeplearning4j.exception.DL4JException;
import org.deeplearning4j.ui.api.Route;
import org.deeplearning4j.ui.api.UIModule;
import org.deeplearning4j.ui.api.UIServer;
import org.deeplearning4j.ui.i18n.I18NProvider;
import org.deeplearning4j.ui.model.storage.FileStatsStorage;
import org.deeplearning4j.ui.model.storage.InMemoryStatsStorage;
import org.deeplearning4j.ui.model.storage.impl.QueueStatsStorageListener;
import org.deeplearning4j.ui.module.SameDiffModule;
import org.deeplearning4j.ui.module.convolutional.ConvolutionalListenerModule;
import org.deeplearning4j.ui.module.defaultModule.DefaultModule;
import org.deeplearning4j.ui.module.remote.RemoteReceiverModule;
import org.deeplearning4j.ui.module.train.TrainModule;
import org.deeplearning4j.ui.module.tsne.TsneModule;
import org.nd4j.common.function.Function;
import org.nd4j.common.primitives.Pair;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicBoolean;
@Slf4j
public class VertxUIServer extends AbstractVerticle implements UIServer {
public static final int DEFAULT_UI_PORT = 9000;
public static final String ASSETS_ROOT_DIRECTORY = "deeplearning4jUiAssets/";
@Getter
private static VertxUIServer instance;
@Getter
private static AtomicBoolean multiSession = new AtomicBoolean(false);
@Getter
@Setter
private static Function<String, StatsStorage> statsStorageProvider;
private static Integer instancePort;
@Getter
private static Thread shutdownHook;
/**
* Get (and, initialize if necessary) the UI server. This synchronous function will wait until the server started.
* @param port TCP socket port for {@link HttpServer} to listen
* @param multiSession in multi-session mode, multiple training sessions can be visualized in separate browser tabs.
* <br/>URL path will include session ID as a parameter, i.e.: /train becomes /train/:sessionId
* @param statsStorageProvider function that returns a StatsStorage containing the given session ID.
* <br/>Use this to auto-attach StatsStorage if an unknown session ID is passed
* as URL path parameter in multi-session mode, or leave it {@code null}.
* @return UI instance for this JVM
* @throws DL4JException if UI server failed to start;
* if the instance has already started in a different mode (multi/single-session);
* if interrupted while waiting for completion
*/
public static VertxUIServer getInstance(Integer port, boolean multiSession,
Function<String, StatsStorage> statsStorageProvider) throws DL4JException {
return getInstance(port, multiSession, statsStorageProvider, null);
}
/**
*
* Get (and, initialize if necessary) the UI server. This function will wait until the server started
* (synchronous way), or pass the given callback to handle success or failure (asynchronous way).
* @param port TCP socket port for {@link HttpServer} to listen
* @param multiSession in multi-session mode, multiple training sessions can be visualized in separate browser tabs.
* <br/>URL path will include session ID as a parameter, i.e.: /train becomes /train/:sessionId
* @param statsStorageProvider function that returns a StatsStorage containing the given session ID.
* <br/>Use this to auto-attach StatsStorage if an unknown session ID is passed
* as URL path parameter in multi-session mode, or leave it {@code null}.
* @param startCallback asynchronous deployment handler callback that will be notify of success or failure.
* If {@code null} given, then this method will wait until deployment is complete.
* If the deployment is successful the result will contain a String representing the
* unique deployment ID of the deployment.
* @return UI server instance
* @throws DL4JException if UI server failed to start;
* if the instance has already started in a different mode (multi/single-session);
* if interrupted while waiting for completion
*/
public static VertxUIServer getInstance(Integer port, boolean multiSession,
Function<String, StatsStorage> statsStorageProvider, Promise<String> startCallback)
throws DL4JException {
if (instance == null || instance.isStopped()) {
VertxUIServer.multiSession.set(multiSession);
VertxUIServer.setStatsStorageProvider(statsStorageProvider);
instancePort = port;
if (startCallback != null) {
//Launch UI server verticle and pass asynchronous callback that will be notified of completion
deploy(startCallback);
} else {
//Launch UI server verticle and wait for it to start
deploy();
}
} else if (!instance.isStopped()) {
if (multiSession && !instance.isMultiSession()) {
throw new DL4JException("Cannot return multi-session instance." +
" UIServer has already started in single-session mode at " + instance.getAddress() +
" You may stop the UI server instance, and start a new one.");
} else if (!multiSession && instance.isMultiSession()) {
throw new DL4JException("Cannot return single-session instance." +
" UIServer has already started in multi-session mode at " + instance.getAddress() +
" You may stop the UI server instance, and start a new one.");
}
}
return instance;
}
/**
* Deploy (start) {@link VertxUIServer}, waiting until starting is complete.
* @throws DL4JException if UI server failed to start;
* if interrupted while waiting for completion
*/
private static void deploy() throws DL4JException {
CountDownLatch l = new CountDownLatch(1);
Promise<String> promise = Promise.promise();
promise.future().compose(
success -> Future.future(prom -> l.countDown()),
failure -> Future.future(prom -> l.countDown())
);
deploy(promise);
// synchronous function
try {
l.await();
} catch (InterruptedException e) {
throw new DL4JException(e);
}
Future<String> future = promise.future();
if (future.failed()) {
throw new DL4JException("Deeplearning4j UI server failed to start.", future.cause());
}
}
/**
* Deploy (start) {@link VertxUIServer},
* and pass callback to handle successful or failed completion of deployment.
* @param startCallback promise that will handle success or failure of deployment.
* If the deployment is successful the result will contain a String representing the unique deployment ID of the
* deployment.
*/
private static void deploy(Promise<String> startCallback) {
log.debug("Deeplearning4j UI server is starting.");
Promise<String> promise = Promise.promise();
promise.future().compose(
success -> Future.future(prom -> startCallback.complete(success)),
failure -> Future.future(prom -> startCallback.fail(new RuntimeException(failure)))
);
Vertx vertx = Vertx.vertx();
vertx.deployVerticle(VertxUIServer.class.getName(), promise);
VertxUIServer.shutdownHook = new Thread(() -> {
if (VertxUIServer.instance != null && !VertxUIServer.instance.isStopped()) {
log.info("Deeplearning4j UI server is auto-stopping in shutdown hook.");
try {
instance.stop();
} catch (InterruptedException e) {
log.error("Interrupted stopping of Deeplearning4j UI server in shutdown hook.", e);
}
}
});
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
private List<UIModule> uiModules = new CopyOnWriteArrayList<>();
private RemoteReceiverModule remoteReceiverModule;
/**
* Loader that attaches {@code StatsStorage} provided by {@code #statsStorageProvider} for the given session ID
*/
@Getter
private Function<String, Boolean> statsStorageLoader;
//typeIDModuleMap: Records which modules are registered for which type IDs
private Map<String, List<UIModule>> typeIDModuleMap = new ConcurrentHashMap<>();
private HttpServer server;
private AtomicBoolean shutdown = new AtomicBoolean(false);
private long uiProcessingDelay = 500; //500ms. TODO make configurable
private final BlockingQueue<StatsStorageEvent> eventQueue = new LinkedBlockingQueue<>();
private List<Pair<StatsStorage, StatsStorageListener>> listeners = new CopyOnWriteArrayList<>();
private List<StatsStorage> statsStorageInstances = new CopyOnWriteArrayList<>();
private Thread uiEventRoutingThread;
public VertxUIServer() {
instance = this;
}
public static void stopInstance() throws Exception {
if(instance == null || instance.isStopped())
return;
instance.stop();
VertxUIServer.reset();
}
private static void reset() {
VertxUIServer.instance = null;
VertxUIServer.statsStorageProvider = null;
VertxUIServer.instancePort = null;
VertxUIServer.multiSession.set(false);
}
/**
* Auto-attach StatsStorage if an unknown session ID is passed as URL path parameter in multi-session mode
* @param statsStorageProvider function that returns a StatsStorage containing the given session ID
*/
public void autoAttachStatsStorageBySessionId(Function<String, StatsStorage> statsStorageProvider) {
if (statsStorageProvider != null) {
this.statsStorageLoader = (sessionId) -> {
log.info("Loading StatsStorage via StatsStorageProvider for session ID (" + sessionId + ").");
StatsStorage statsStorage = statsStorageProvider.apply(sessionId);
if (statsStorage != null) {
if (statsStorage.sessionExists(sessionId)) {
attach(statsStorage);
return true;
}
log.info("Failed to load StatsStorage via StatsStorageProvider for session ID. " +
"Session ID (" + sessionId + ") does not exist in StatsStorage.");
return false;
} else {
log.info("Failed to load StatsStorage via StatsStorageProvider for session ID (" + sessionId + "). " +
"StatsStorageProvider returned null.");
return false;
}
};
}
}
@Override
public void start(Promise<Void> startCallback) throws Exception {
//Create REST endpoints
File uploadDir = new File(System.getProperty("java.io.tmpdir"), "DL4JUI_" + System.currentTimeMillis());
uploadDir.mkdirs();
Router r = Router.router(vertx);
r.route().handler(BodyHandler.create() //NOTE: Setting this is required to receive request body content at all
.setUploadsDirectory(uploadDir.getAbsolutePath()));
r.get("/assets/*").handler(rc -> {
String path = rc.request().path();
path = path.substring(8); //Remove "/assets/", which is 8 characters
String mime;
String newPath;
if (path.contains("webjars")) {
newPath = "META-INF/resources/" + path.substring(path.indexOf("webjars"));
} else {
newPath = ASSETS_ROOT_DIRECTORY + (path.startsWith("/") ? path.substring(1) : path);
}
mime = MimeMapping.getMimeTypeForFilename(FilenameUtils.getName(newPath));
//System.out.println("PATH: " + path + " - mime = " + mime);
rc.response()
.putHeader("content-type", mime)
.sendFile(newPath);
});
if (isMultiSession()) {
r.get("/setlang/:sessionId/:to").handler(
rc -> {
String sid = rc.request().getParam("sessionID");
String to = rc.request().getParam("to");
I18NProvider.getInstance(sid).setDefaultLanguage(to);
rc.response().end();
});
} else {
r.get("/setlang/:to").handler(rc -> {
String to = rc.request().getParam("to");
I18NProvider.getInstance().setDefaultLanguage(to);
rc.response().end();
});
}
if (VertxUIServer.statsStorageProvider != null) {
autoAttachStatsStorageBySessionId(VertxUIServer.statsStorageProvider);
}
uiModules.add(new DefaultModule(isMultiSession())); //For: navigation page "/"
uiModules.add(new TrainModule());
uiModules.add(new ConvolutionalListenerModule());
uiModules.add(new TsneModule());
uiModules.add(new SameDiffModule());
remoteReceiverModule = new RemoteReceiverModule();
uiModules.add(remoteReceiverModule);
//Check service loader mechanism (Arbiter UI, etc) for modules
modulesViaServiceLoader(uiModules);
for (UIModule m : uiModules) {
List<Route> routes = m.getRoutes();
for (Route route : routes) {
switch (route.getHttpMethod()) {
case GET:
r.get(route.getRoute()).handler(rc -> route.getConsumer().accept(extractArgsFromRoute(route.getRoute(), rc), rc));
break;
case PUT:
r.put(route.getRoute()).handler(rc -> route.getConsumer().accept(extractArgsFromRoute(route.getRoute(), rc), rc));
break;
case POST:
r.post(route.getRoute()).handler(rc -> route.getConsumer().accept(extractArgsFromRoute(route.getRoute(), rc), rc));
break;
default:
throw new IllegalStateException("Unknown or not supported HTTP method: " + route.getHttpMethod());
}
}
//Determine which type IDs this module wants to receive:
List<String> typeIDs = m.getCallbackTypeIDs();
for (String typeID : typeIDs) {
List<UIModule> list = typeIDModuleMap.get(typeID);
if (list == null) {
list = Collections.synchronizedList(new ArrayList<>());
typeIDModuleMap.put(typeID, list);
}
list.add(m);
}
}
//Check port property
int port = instancePort == null ? DEFAULT_UI_PORT : instancePort;
String portProp = System.getProperty(DL4JSystemProperties.UI_SERVER_PORT_PROPERTY);
if(portProp != null && !portProp.isEmpty()){
try{
port = Integer.parseInt(portProp);
} catch (NumberFormatException e){
log.warn("Error parsing port property {}={}", DL4JSystemProperties.UI_SERVER_PORT_PROPERTY, portProp);
}
}
if (port < 0 || port > 0xFFFF) {
throw new IllegalStateException("Valid port range is 0 <= port <= 65535. The given port was " + port);
}
uiEventRoutingThread = new Thread(new StatsEventRouterRunnable());
uiEventRoutingThread.setDaemon(true);
uiEventRoutingThread.start();
server = vertx.createHttpServer()
.requestHandler(r)
.listen(port, result -> {
if (result.succeeded()) {
String address = UIServer.getInstance().getAddress();
log.info("Deeplearning4j UI server started at: {}", address);
startCallback.complete();
} else {
startCallback.fail(new RuntimeException("Deeplearning4j UI server failed to listen on port "
+ server.actualPort(), result.cause()));
}
});
}
private List<String> extractArgsFromRoute(String path, RoutingContext rc) {
if (!path.contains(":")) {
return Collections.emptyList();
}
String[] split = path.split("/");
List<String> out = new ArrayList<>();
for (String s : split) {
if (s.startsWith(":")) {
String s2 = s.substring(1);
out.add(rc.request().getParam(s2));
}
}
return out;
}
private void modulesViaServiceLoader(List<UIModule> uiModules) {
ServiceLoader<UIModule> sl = DL4JClassLoading.loadService(UIModule.class);
Iterator<UIModule> iter = sl.iterator();
if (!iter.hasNext()) {
return;
}
while (iter.hasNext()) {
UIModule module = iter.next();
Class<?> moduleClass = module.getClass();
boolean foundExisting = false;
for (UIModule mExisting : uiModules) {
if (mExisting.getClass() == moduleClass) {
foundExisting = true;
break;
}
}
if (!foundExisting) {
log.debug("Loaded UI module via service loader: {}", module.getClass());
uiModules.add(module);
}
}
}
@Override
public void stop() throws InterruptedException {
CountDownLatch l = new CountDownLatch(1);
Promise<Void> promise = Promise.promise();
promise.future().compose(
successEvent -> Future.future(prom -> l.countDown()),
failureEvent -> Future.future(prom -> l.countDown())
);
stopAsync(promise);
// synchronous function should wait until the server is stopped
l.await();
}
@Override
public void stopAsync(Promise<Void> stopCallback) {
/**
* Stop Vertx instance and release any resources held by it.
* Pass promise to {@link #stop(Promise)}.
*/
vertx.close(ar -> stopCallback.handle(ar));
}
@Override
public void stop(Promise<Void> stopCallback) {
shutdown.set(true);
stopCallback.complete();
log.info("Deeplearning4j UI server stopped.");
}
@Override
public boolean isStopped() {
return shutdown.get();
}
@Override
public boolean isMultiSession() {
return multiSession.get();
}
@Override
public String getAddress() {
return "http://localhost:" + server.actualPort();
}
@Override
public int getPort() {
return server.actualPort();
}
@Override
public void attach(StatsStorage statsStorage) {
if (statsStorage == null)
throw new IllegalArgumentException("StatsStorage cannot be null");
if (statsStorageInstances.contains(statsStorage))
return;
StatsStorageListener listener = new QueueStatsStorageListener(eventQueue);
listeners.add(new Pair<>(statsStorage, listener));
statsStorage.registerStatsStorageListener(listener);
statsStorageInstances.add(statsStorage);
for (UIModule uiModule : uiModules) {
uiModule.onAttach(statsStorage);
}
log.info("StatsStorage instance attached to UI: {}", statsStorage);
}
@Override
public void detach(StatsStorage statsStorage) {
if (statsStorage == null)
throw new IllegalArgumentException("StatsStorage cannot be null");
if (!statsStorageInstances.contains(statsStorage))
return; //No op
boolean found = false;
for (Pair<StatsStorage, StatsStorageListener> p : listeners) {
if (p.getFirst() == statsStorage) { //Same object, not equality
statsStorage.deregisterStatsStorageListener(p.getSecond());
listeners.remove(p);
found = true;
}
}
statsStorageInstances.remove(statsStorage);
for (UIModule uiModule : uiModules) {
uiModule.onDetach(statsStorage);
}
for (String sessionId : statsStorage.listSessionIDs()) {
I18NProvider.removeInstance(sessionId);
}
if (found) {
log.info("StatsStorage instance detached from UI: {}", statsStorage);
}
}
@Override
public boolean isAttached(StatsStorage statsStorage) {
return statsStorageInstances.contains(statsStorage);
}
@Override
public List<StatsStorage> getStatsStorageInstances() {
return new ArrayList<>(statsStorageInstances);
}
@Override
public void enableRemoteListener() {
if (remoteReceiverModule == null)
remoteReceiverModule = new RemoteReceiverModule();
if (remoteReceiverModule.isEnabled())
return;
enableRemoteListener(new InMemoryStatsStorage(), true);
}
@Override
public void enableRemoteListener(StatsStorageRouter statsStorage, boolean attach) {
remoteReceiverModule.setEnabled(true);
remoteReceiverModule.setStatsStorage(statsStorage);
if (attach && statsStorage instanceof StatsStorage) {
attach((StatsStorage) statsStorage);
}
}
@Override
public void disableRemoteListener() {
remoteReceiverModule.setEnabled(false);
}
@Override
public boolean isRemoteListenerEnabled() {
return remoteReceiverModule.isEnabled();
}
private class StatsEventRouterRunnable implements Runnable {
@Override
public void run() {
try {
runHelper();
} catch (Exception e) {
log.error("Unexpected exception from Event routing runnable", e);
}
}
private void runHelper() throws Exception {
log.trace("VertxUIServer.StatsEventRouterRunnable started");
//Idea: collect all event stats, and route them to the appropriate modules
while (!shutdown.get()) {
List<StatsStorageEvent> events = new ArrayList<>();
StatsStorageEvent sse = eventQueue.take(); //Blocking operation
events.add(sse);
eventQueue.drainTo(events); //Non-blocking
for (UIModule m : uiModules) {
List<String> callbackTypes = m.getCallbackTypeIDs();
List<StatsStorageEvent> out = new ArrayList<>();
for (StatsStorageEvent e : events) {
if (callbackTypes.contains(e.getTypeID())
&& statsStorageInstances.contains(e.getStatsStorage())) {
out.add(e);
}
}
m.reportStorageEvents(out);
}
events.clear();
try {
Thread.sleep(uiProcessingDelay);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
if (!shutdown.get()) {
throw new RuntimeException("Unexpected interrupted exception", e);
}
}
}
}
}
//==================================================================================================================
// CLI Launcher
@Data
private static class CLIParams {
@Parameter(names = {"-r", "--enableRemote"}, description = "Whether to enable remote or not", arity = 1)
private boolean cliEnableRemote;
@Parameter(names = {"-p", "--uiPort"}, description = "Custom HTTP port for UI", arity = 1)
private int cliPort = DEFAULT_UI_PORT;
@Parameter(names = {"-f", "--customStatsFile"}, description = "Path to create custom stats file (remote only)", arity = 1)
private String cliCustomStatsFile;
@Parameter(names = {"-m", "--multiSession"}, description = "Whether to enable multiple separate browser sessions or not", arity = 1)
private boolean cliMultiSession;
}
public void main(String[] args){
CLIParams d = new CLIParams();
new JCommander(d).parse(args);
instancePort = d.getCliPort();
UIServer.getInstance(d.isCliMultiSession(), null);
if(d.isCliEnableRemote()){
try {
File tempStatsFile = ND4JFileUtils.createTempFile("dl4j", "UIstats");
tempStatsFile.delete();
tempStatsFile.deleteOnExit();
enableRemoteListener(new FileStatsStorage(tempStatsFile), true);
} catch(Exception e) {
log.error("Failed to create temporary file for stats storage",e);
System.exit(1);
}
}
}
}
@@ -0,0 +1,25 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.api;
public enum HttpMethod {
GET, PUT, POST
}
@@ -0,0 +1,65 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.api;
import java.util.Map;
public interface I18N {
/**
* Get the specified message in the default language (according to {@link #getDefaultLanguage()}
*
* @param key Key value
* @return Message for the given key, or null if none is found/available
*/
String getMessage(String key);
/**
* Get the specified message for the specified language
*
* @param langCode ISO 639-1 language code: "en", "ja", etc
* @param key Key value for the message to retrieve
* @return Message for the given key/language pair, or null if none is found
*/
String getMessage(String langCode, String key);
/**
* Get the currently set default language as an ISO 639-1 code
*
* @return The current default language
*/
String getDefaultLanguage();
/**
* Set the default language
*
* @param langCode Language code, as an ISO 639-1 code
*/
void setDefaultLanguage(String langCode);
/**
* Get all internationalization messages for the specified language code
* @param langCode Language code
* @return Messages
*/
Map<String,String> getMessages(String langCode);
}
@@ -0,0 +1,36 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.api;
import io.vertx.ext.web.RoutingContext;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.List;
import java.util.function.*;
@Data
@AllArgsConstructor
public class Route {
private final String route;
private final HttpMethod httpMethod;
private final BiConsumer<List<String>, RoutingContext> consumer;
}
@@ -0,0 +1,75 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.api;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageEvent;
import org.deeplearning4j.ui.i18n.I18NResource;
import java.util.Collection;
import java.util.List;
public interface UIModule {
/**
* Get the list of Type IDs that should be collected from the registered {@link StatsStorage} instances, and
* passed on to the {@link #reportStorageEvents(Collection)} method.
*
* @return List of relevant Type IDs
*/
List<String> getCallbackTypeIDs();
/**
* Get a list of {@link Route} objects, that specify GET/SET etc methods, and how these should be handled.
*
* @return List of routes
*/
List<Route> getRoutes();
/**
* Whenever the {@link UIServer} receives some {@link StatsStorageEvent}s from one of the registered {@link StatsStorage}
* instances, it will filter these and pass on to the UI module those ones that match one of the Type IDs from
* {@link #getCallbackTypeIDs()}.<br>
* Typically, these will be batched together at least somewhat, rather than being reported individually.
*
* @param events List of relevant events (type IDs match one of those from {@link #getCallbackTypeIDs()}
*/
void reportStorageEvents(Collection<StatsStorageEvent> events);
/**
* Notify the UI module that the given {@link StatsStorage} instance has been attached to the UI
*
* @param statsStorage Stats storage that has been attached
*/
void onAttach(StatsStorage statsStorage);
/**
* Notify the UI module that the given {@link StatsStorage} instance has been detached from the UI
*
* @param statsStorage Stats storage that has been detached
*/
void onDetach(StatsStorage statsStorage);
/**
* @return List of internationalization resources
*/
List<I18NResource> getInternationalizationResources();
}
@@ -0,0 +1,179 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.api;
import io.vertx.core.Promise;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageRouter;
import org.deeplearning4j.core.storage.impl.RemoteUIStatsStorageRouter;
import org.deeplearning4j.exception.DL4JException;
import org.deeplearning4j.ui.VertxUIServer;
import org.nd4j.common.function.Function;
import java.util.List;
public interface UIServer {
/**
* Get (and, initialize if necessary) the UI server. This synchronous function will wait until the server started.
* Singleton pattern - all calls to getInstance() will return the same UI instance.
*
* @return UI instance for this JVM
* @throws DL4JException if UI server failed to start;
* if the instance has already started in a different mode (multi/single-session);
* if interrupted while waiting for completion
*/
static UIServer getInstance() throws DL4JException {
if (VertxUIServer.getInstance() != null && !VertxUIServer.getInstance().isStopped()) {
return VertxUIServer.getInstance();
} else {
return getInstance(false, null);
}
}
/**
* Get (and, initialize if necessary) the UI server. This synchronous function will wait until the server started.
* Singleton pattern - all calls to getInstance() will return the same UI instance.
*
* @param multiSession in multi-session mode, multiple training sessions can be visualized in separate browser tabs.
* <br/>URL path will include session ID as a parameter, i.e.: /train becomes /train/:sessionId
* @param statsStorageProvider function that returns a StatsStorage containing the given session ID.
* <br/>Use this to auto-attach StatsStorage if an unknown session ID is passed
* as URL path parameter in multi-session mode, or leave it {@code null}.
* @return UI instance for this JVM
* @throws DL4JException if UI server failed to start;
* if the instance has already started in a different mode (multi/single-session);
* if interrupted while waiting for completion
*/
static UIServer getInstance(boolean multiSession, Function<String, StatsStorage> statsStorageProvider)
throws DL4JException {
return VertxUIServer.getInstance(null, multiSession, statsStorageProvider);
}
/**
* Stop UIServer instance, if already running
*/
static void stopInstance() throws Exception {
VertxUIServer.stopInstance();
}
boolean isStopped();
/**
* Check if the instance initialized with one of the factory methods
* ({@link #getInstance()} or {@link #getInstance(boolean, Function)}) is in multi-session mode
*
* @return {@code true} if the instance is in multi-session
*/
boolean isMultiSession();
/**
* Get the address of the UI
*
* @return Address of the UI
*/
String getAddress();
/**
* Get the current port for the UI
*/
int getPort();
/**
* Attach the given StatsStorage instance to the UI, so the data can be visualized
*
* @param statsStorage StatsStorage instance to attach to the UI
*/
void attach(StatsStorage statsStorage);
/**
* Detach the specified StatsStorage instance from the UI
*
* @param statsStorage StatsStorage instance to detach. If not attached: no op.
*/
void detach(StatsStorage statsStorage);
/**
* Check whether the specified StatsStorage instance is attached to the UI instance
*
* @param statsStorage StatsStorage instance to attach
* @return True if attached
*/
boolean isAttached(StatsStorage statsStorage);
/**
* @return A list of all StatsStorage instances currently attached
*/
List<StatsStorage> getStatsStorageInstances();
/**
* Enable the remote listener functionality, storing all data in memory, and attaching the instance to the UI.
* Typically used with {@link RemoteUIStatsStorageRouter}, which will send information
* remotely to this UI instance
*
* @see #enableRemoteListener(StatsStorageRouter, boolean)
*/
void enableRemoteListener();
/**
* Enable the remote listener functionality, storing the received results in the specified StatsStorageRouter.
* If the StatsStorageRouter is a {@link StatsStorage} instance, it may (optionally) be attached to the UI,
* as if {@link #attach(StatsStorage)} was called on it.
*
* @param statsStorage StatsStorageRouter to post the received results to
* @param attach Whether to attach the given StatsStorage instance to the UI server
*/
void enableRemoteListener(StatsStorageRouter statsStorage, boolean attach);
/**
* Disable the remote listener functionality (disabled by default)
*/
void disableRemoteListener();
/**
* @return Whether the remote listener functionality is currently enabled
*/
boolean isRemoteListenerEnabled();
/**
* Stop/shut down the UI server. This synchronous function should wait until the server is stopped.
* @throws InterruptedException if the current thread is interrupted while waiting
*/
void stop() throws InterruptedException;
/**
* Stop/shut down the UI server.
* This asynchronous function should immediately return, and notify the callback {@link Promise} on completion:
* either call {@link Promise#complete} or {@link io.vertx.core.Promise#fail}.
* @param stopCallback callback {@link Promise} to notify on completion
*/
void stopAsync(Promise<Void> stopCallback);
/**
* Get shutdown hook of UI server, that will stop the server when the Runtime is stopped.
* You may de-register this shutdown hook with {@link Runtime#removeShutdownHook(Thread)},
* and add your own hook with {@link Runtime#addShutdownHook(Thread)}
* @return shutdown hook
*/
static Thread getShutdownHook() {
return VertxUIServer.getShutdownHook();
};
}
@@ -0,0 +1,183 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.i18n;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.deeplearning4j.config.DL4JClassLoading;
import org.deeplearning4j.ui.api.I18N;
import org.deeplearning4j.ui.api.UIModule;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Slf4j
public class DefaultI18N implements I18N {
public static final String DEFAULT_LANGUAGE = "en";
public static final String FALLBACK_LANGUAGE = "en"; //use this if the specified language doesn't have the requested message
private static DefaultI18N instance;
private static Map<String, I18N> sessionInstances = Collections.synchronizedMap(new HashMap<>());
private static Throwable languageLoadingException = null;
private String currentLanguage = DEFAULT_LANGUAGE;
private Map<String, Map<String, String>> messagesByLanguage = new HashMap<>();
/**
* Get global instance (used in single-session mode)
* @return global instance
*/
public static synchronized I18N getInstance() {
if (instance == null)
instance = new DefaultI18N();
return instance;
}
/**
* Get instance for session
* @param sessionId session ID for multi-session mode, leave it {@code null} for global instance
* @return instance for session, or global instance
*/
public static synchronized I18N getInstance(String sessionId) {
if (sessionId == null) {
return getInstance();
} else {
if (!sessionInstances.containsKey(sessionId)) {
sessionInstances.put(sessionId, new DefaultI18N());
}
return sessionInstances.get(sessionId);
}
}
/**
* Remove I18N instance for session
* @param sessionId session ID
* @return the previous value associated with {@code sessionId},
* or null if there was no mapping for {@code sessionId}
*/
public static synchronized I18N removeInstance(String sessionId) {
return sessionInstances.remove(sessionId);
}
private DefaultI18N() {
loadLanguages();
}
private synchronized void loadLanguages(){
ServiceLoader<UIModule> loadedModules = DL4JClassLoading.loadService(UIModule.class);
for (UIModule module : loadedModules){
List<I18NResource> resources = module.getInternationalizationResources();
for(I18NResource resource : resources){
try {
String path = resource.getResource();
int idxLast = path.lastIndexOf('.');
if (idxLast < 0) {
log.warn("Skipping language resource file: cannot infer language: {}", path);
continue;
}
String langCode = path.substring(idxLast + 1).toLowerCase();
Map<String, String> map = messagesByLanguage.computeIfAbsent(langCode, k -> new HashMap<>());
parseFile(resource, map);
} catch (Throwable t){
log.warn("Error parsing UI I18N content file; skipping: {}", resource.getResource(), t);
languageLoadingException = t;
}
}
}
}
private void parseFile(I18NResource r, Map<String,String> results){
List<String> lines;
try (InputStream is = r.getInputStream()){
lines = IOUtils.readLines(is, StandardCharsets.UTF_8);
} catch (IOException e){
log.debug("Error parsing UI I18N content file; skipping: {} - {}", r.getResource(), e.getMessage());
return;
}
int count = 0;
for (String line : lines) {
if (!line.matches(".+=.*")) {
log.debug("Invalid line in I18N file: {}, \"{}\"", r.getResource(), line);
continue;
}
int idx = line.indexOf('=');
String key = line.substring(0, idx);
String value = line.substring(Math.min(idx + 1, line.length()));
results.put(key, value);
count++;
}
log.trace("Loaded {} messages from file {}", count, r.getResource());
}
@Override
public String getMessage(String key) {
return getMessage(currentLanguage, key);
}
@Override
public String getMessage(String langCode, String key) {
Map<String, String> messagesForLanguage = messagesByLanguage.get(langCode);
String msg;
if (messagesForLanguage != null) {
msg = messagesForLanguage.get(key);
if (msg == null && !FALLBACK_LANGUAGE.equals(langCode)) {
//Try getting the result from the fallback language
return getMessage(FALLBACK_LANGUAGE, key);
}
} else {
msg = getMessage(FALLBACK_LANGUAGE, key);
}
return msg;
}
@Override
public String getDefaultLanguage() {
return currentLanguage;
}
@Override
public void setDefaultLanguage(String langCode) {
this.currentLanguage = langCode;
log.debug("UI: Set language to {}", langCode);
}
@Override
public Map<String, String> getMessages(String langCode) {
//Start with map for default language
//Then overwrite with the actual language - so any missing are reported in default language
Map<String,String> ret = new HashMap<>(messagesByLanguage.get(FALLBACK_LANGUAGE));
if(!langCode.equals(FALLBACK_LANGUAGE)){
ret.putAll(messagesByLanguage.get(langCode));
}
return ret;
}
}
@@ -0,0 +1,63 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.i18n;
import org.deeplearning4j.ui.api.I18N;
public class I18NProvider {
/**
* Current I18N instance
*/
private static I18N i18n = DefaultI18N.getInstance();
/**
* Get the current/global I18N instance (used in single-session mode)
*
* @return global instance
*/
public static I18N getInstance() {
return i18n;
}
/**
* Get instance for session (used in multi-session mode)
*
* @param sessionId session
* @return instance for session
*/
public static I18N getInstance(String sessionId) {
return DefaultI18N.getInstance(sessionId);
}
/**
* Remove I18N instance for session
*
* @param sessionId session ID
* @return the previous value associated with {@code sessionId} or null if there was no mapping for {@code sessionId}
*/
public static synchronized I18N removeInstance(String sessionId) {
return DefaultI18N.removeInstance(sessionId);
}
}
@@ -0,0 +1,38 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.i18n;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.nd4j.common.io.ClassPathResource;
import java.io.IOException;
import java.io.InputStream;
@AllArgsConstructor
@Data
public class I18NResource {
private final String resource;
public InputStream getInputStream() throws IOException {
return new ClassPathResource(resource).getInputStream();
}
}
@@ -0,0 +1,72 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.module;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageEvent;
import org.deeplearning4j.ui.api.HttpMethod;
import org.deeplearning4j.ui.api.Route;
import org.deeplearning4j.ui.api.UIModule;
import org.deeplearning4j.ui.i18n.I18NResource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class SameDiffModule implements UIModule {
public SameDiffModule() {
}
@Override
public List<String> getCallbackTypeIDs() {
return Collections.emptyList();
}
@Override
public List<Route> getRoutes() {
// Route r1 = new Route("/samediff", HttpMethod.GET, FunctionType.Supplier,
// () -> ok(org.deeplearning4j.ui.views.html.samediff.SameDiffUI.apply()));
Route r1 = new Route("/samediff", HttpMethod.GET, (path,rc) -> rc.response().sendFile("templates/SameDiffUI.html"));
return Collections.singletonList(r1);
}
@Override
public void reportStorageEvents(Collection<StatsStorageEvent> events) {
}
@Override
public void onAttach(StatsStorage statsStorage) {
}
@Override
public void onDetach(StatsStorage statsStorage) {
}
@Override
public List<I18NResource> getInternationalizationResources() {
return Collections.emptyList();
}
}
@@ -0,0 +1,125 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.module.convolutional;
import io.vertx.core.buffer.Buffer;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;
import org.deeplearning4j.core.storage.Persistable;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageEvent;
import org.deeplearning4j.core.storage.StatsStorageListener;
import org.deeplearning4j.ui.api.HttpMethod;
import org.deeplearning4j.ui.api.Route;
import org.deeplearning4j.ui.api.UIModule;
import org.deeplearning4j.ui.i18n.I18NResource;
import org.deeplearning4j.ui.model.weights.ConvolutionListenerPersistable;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@Slf4j
public class ConvolutionalListenerModule implements UIModule {
private static final String TYPE_ID = "ConvolutionalListener";
private StatsStorage lastStorage;
private String lastSessionID;
private String lastWorkerID;
private long lastTimeStamp;
@Override
public List<String> getCallbackTypeIDs() {
return Collections.singletonList(TYPE_ID);
}
@Override
public List<Route> getRoutes() {
Route r = new Route("/activations", HttpMethod.GET, (path, rc) -> rc.response().sendFile("templates/Activations.html"));
Route r2 = new Route("/activations/data", HttpMethod.GET, (path, rc) -> this.getImage(rc));
return Arrays.asList(r, r2);
}
@Override
public synchronized void reportStorageEvents(Collection<StatsStorageEvent> events) {
for (StatsStorageEvent sse : events) {
if (TYPE_ID.equals(sse.getTypeID())
&& sse.getEventType() == StatsStorageListener.EventType.PostStaticInfo) {
if (sse.getTimestamp() > lastTimeStamp) {
lastStorage = sse.getStatsStorage();
lastSessionID = sse.getSessionID();
lastWorkerID = sse.getWorkerID();
lastTimeStamp = sse.getTimestamp();
}
}
}
}
@Override
public void onAttach(StatsStorage statsStorage) {
//No-op
}
@Override
public void onDetach(StatsStorage statsStorage) {
//No-op
}
@Override
public List<I18NResource> getInternationalizationResources() {
return Collections.emptyList();
}
private void getImage(RoutingContext rc) {
if (lastTimeStamp > 0 && lastStorage != null) {
Persistable p = lastStorage.getStaticInfo(lastSessionID, TYPE_ID, lastWorkerID);
if (p instanceof ConvolutionListenerPersistable) {
ConvolutionListenerPersistable clp = (ConvolutionListenerPersistable) p;
BufferedImage bi = clp.getImg();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(bi, "png", baos);
} catch (IOException e) {
log.warn("Error displaying image", e);
}
rc.response()
.putHeader("content-type", "image/png")
.end(Buffer.buffer(baos.toByteArray()));
} else {
rc.response()
.putHeader("content-type", "image/png")
.end(Buffer.buffer(new byte[0]));
}
} else {
rc.response()
.putHeader("content-type", "image/png")
.end(Buffer.buffer(new byte[0]));
}
}
}
@@ -0,0 +1,85 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.module.defaultModule;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageEvent;
import org.deeplearning4j.ui.api.HttpMethod;
import org.deeplearning4j.ui.api.Route;
import org.deeplearning4j.ui.api.UIModule;
import org.deeplearning4j.ui.i18n.I18NResource;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class DefaultModule implements UIModule {
private final boolean multiSession;
public DefaultModule() {
this(false);
}
/**
*
* @param multiSession multi-session mode
*/
public DefaultModule(boolean multiSession) {
this.multiSession = multiSession;
}
@Override
public List<String> getCallbackTypeIDs() {
return Collections.emptyList();
}
@Override
public List<Route> getRoutes() {
Route r = new Route("/", HttpMethod.GET, (params, rc) -> rc.response()
.putHeader("location", "/train" + (multiSession ? "" : "/overview"))
.setStatusCode(HttpResponseStatus.FOUND.code())
.end()
);
return Collections.singletonList(r);
}
@Override
public void reportStorageEvents(Collection<StatsStorageEvent> events) {
//Nop-op
}
@Override
public void onAttach(StatsStorage statsStorage) {
//No-op
}
@Override
public void onDetach(StatsStorage statsStorage) {
//No-op
}
@Override
public List<I18NResource> getInternationalizationResources() {
return Collections.emptyList();
}
}
@@ -0,0 +1,207 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.module.remote;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;
import org.deeplearning4j.config.DL4JClassLoading;
import org.deeplearning4j.core.storage.*;
import org.deeplearning4j.ui.api.HttpMethod;
import org.deeplearning4j.ui.api.Route;
import org.deeplearning4j.ui.api.UIModule;
import org.deeplearning4j.ui.i18n.I18NResource;
import javax.xml.bind.DatatypeConverter;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
@Slf4j
public class RemoteReceiverModule implements UIModule {
private AtomicBoolean enabled = new AtomicBoolean(false);
private StatsStorageRouter statsStorage;
public void setEnabled(boolean enabled) {
this.enabled.set(enabled);
if (!enabled) {
this.statsStorage = null;
}
}
public boolean isEnabled() {
return enabled.get() && this.statsStorage != null;
}
public void setStatsStorage(StatsStorageRouter statsStorage) {
this.statsStorage = statsStorage;
}
@Override
public List<String> getCallbackTypeIDs() {
return Collections.emptyList();
}
@Override
public List<Route> getRoutes() {
Route r = new Route("/remoteReceive", HttpMethod.POST, (path, rc) -> this.receiveData(rc));
return Collections.singletonList(r);
}
@Override
public void reportStorageEvents(Collection<StatsStorageEvent> events) {
//No op
}
@Override
public void onAttach(StatsStorage statsStorage) {
//No op
}
@Override
public void onDetach(StatsStorage statsStorage) {
//No op
}
@Override
public List<I18NResource> getInternationalizationResources() {
return Collections.emptyList();
}
private void receiveData(RoutingContext rc) {
if (!enabled.get()) {
rc.response().setStatusCode(HttpResponseStatus.FORBIDDEN.code())
.end("UI server remote listening is currently disabled. Use UIServer.getInstance().enableRemoteListener()");
return;
}
if (statsStorage == null) {
rc.response().setStatusCode(HttpResponseStatus.INTERNAL_SERVER_ERROR.code())
.end("UI Server remote listener: no StatsStorage instance is set/available to store results");
return;
}
JsonObject jo = rc.getBodyAsJson();
Map<String,Object> map = jo.getMap();
String type = (String) map.get("type");
String dataClass = (String) map.get("class");
String data = (String) map.get("data");
if (type == null || dataClass == null || data == null) {
log.warn("Received incorrectly formatted data from remote listener (has type = " + (type != null)
+ ", has data class = " + (dataClass != null) + ", has data = " + (data != null) + ")");
rc.response().setStatusCode(HttpResponseStatus.BAD_REQUEST.code())
.end("Received incorrectly formatted data");
return;
}
switch (type.toLowerCase()) {
case "metadata":
StorageMetaData meta = getMetaData(dataClass, data);
if (meta != null) {
statsStorage.putStorageMetaData(meta);
}
break;
case "staticinfo":
Persistable staticInfo = getPersistable(dataClass, data);
if (staticInfo != null) {
statsStorage.putStaticInfo(staticInfo);
}
break;
case "update":
Persistable update = getPersistable(dataClass, data);
if (update != null) {
statsStorage.putUpdate(update);
}
break;
default:
}
rc.response().end();
}
private StorageMetaData getMetaData(String dataClass, String content) {
StorageMetaData meta;
try {
Class<?> clazz = DL4JClassLoading.loadClassByName(dataClass);
if (StorageMetaData.class.isAssignableFrom(clazz)) {
meta = clazz
.asSubclass(StorageMetaData.class)
.getDeclaredConstructor()
.newInstance();
} else {
log.warn("Skipping invalid remote data: class {} in not an instance of {}", dataClass,
StorageMetaData.class.getName());
return null;
}
} catch (Exception e) {
log.warn("Skipping invalid remote data: exception encountered for class {}", dataClass, e);
return null;
}
try {
byte[] bytes = DatatypeConverter.parseBase64Binary(content);
meta.decode(bytes);
} catch (Exception e) {
log.warn("Skipping invalid remote UI data: exception encountered when deserializing data", e);
return null;
}
return meta;
}
private Persistable getPersistable(String dataClass, String content) {
Persistable persistable;
try {
Class<?> clazz = DL4JClassLoading.loadClassByName(dataClass);
if (Persistable.class.isAssignableFrom(clazz)) {
persistable = clazz
.asSubclass(Persistable.class)
.getDeclaredConstructor()
.newInstance();
} else {
log.warn("Skipping invalid remote data: class {} in not an instance of {}", dataClass,
Persistable.class.getName());
return null;
}
} catch (Exception e) {
log.warn("Skipping invalid remote UI data: exception encountered for class {}", dataClass, e);
return null;
}
try {
byte[] bytes = DatatypeConverter.parseBase64Binary(content);
persistable.decode(bytes);
} catch (Exception e) {
log.warn("Skipping invalid remote data: exception encountered when deserializing data", e);
return null;
}
return persistable;
}
}
@@ -0,0 +1,296 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.module.train;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.AllArgsConstructor;
import lombok.Data;
import org.deeplearning4j.nn.conf.ComputationGraphConfiguration;
import org.deeplearning4j.nn.conf.MultiLayerConfiguration;
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
import org.deeplearning4j.nn.conf.graph.GraphVertex;
import org.deeplearning4j.nn.conf.graph.LayerVertex;
import org.deeplearning4j.nn.conf.layers.*;
import org.deeplearning4j.nn.conf.layers.variational.VariationalAutoencoder;
import org.deeplearning4j.nn.params.VariationalAutoencoderParamInitializer;
import java.util.*;
public class TrainModuleUtils {
@AllArgsConstructor
@Data
public static class GraphInfo {
private List<String> vertexNames;
private List<String> vertexTypes;
private List<List<Integer>> vertexInputs;
private List<Map<String, String>> vertexInfo;
@JsonIgnore
private List<String> originalVertexName;
}
public static GraphInfo buildGraphInfo(MultiLayerConfiguration config) {
List<String> vertexNames = new ArrayList<>();
List<String> originalVertexName = new ArrayList<>();
List<String> layerTypes = new ArrayList<>();
List<List<Integer>> layerInputs = new ArrayList<>();
List<Map<String, String>> layerInfo = new ArrayList<>();
vertexNames.add("Input");
originalVertexName.add(null);
layerTypes.add("Input");
layerInputs.add(Collections.emptyList());
layerInfo.add(Collections.emptyMap());
List<NeuralNetConfiguration> list = config.getConfs();
int layerIdx = 1;
for (NeuralNetConfiguration c : list) {
Layer layer = c.getLayer();
String layerName = layer.getLayerName();
if (layerName == null)
layerName = "layer" + layerIdx;
vertexNames.add(layerName);
originalVertexName.add(String.valueOf(layerIdx - 1));
String layerType = c.getLayer().getClass().getSimpleName().replaceAll("Layer$", "");
layerTypes.add(layerType);
layerInputs.add(Collections.singletonList(layerIdx - 1));
layerIdx++;
//Extract layer info
Map<String, String> map = getLayerInfo(c, layer);
layerInfo.add(map);
}
return new GraphInfo(vertexNames, layerTypes, layerInputs, layerInfo, originalVertexName);
}
public static GraphInfo buildGraphInfo(ComputationGraphConfiguration config) {
List<String> layerNames = new ArrayList<>();
List<String> layerTypes = new ArrayList<>();
List<List<Integer>> layerInputs = new ArrayList<>();
List<Map<String, String>> layerInfo = new ArrayList<>();
Map<String, GraphVertex> vertices = config.getVertices();
Map<String, List<String>> vertexInputs = config.getVertexInputs();
List<String> networkInputs = config.getNetworkInputs();
List<String> originalVertexName = new ArrayList<>();
Map<String, Integer> vertexToIndexMap = new HashMap<>();
int vertexCount = 0;
for (String s : networkInputs) {
vertexToIndexMap.put(s, vertexCount++);
layerNames.add(s);
originalVertexName.add(s);
layerTypes.add(s);
layerInputs.add(Collections.emptyList());
layerInfo.add(Collections.emptyMap());
}
for (String s : vertices.keySet()) {
vertexToIndexMap.put(s, vertexCount++);
}
for (Map.Entry<String, GraphVertex> entry : vertices.entrySet()) {
GraphVertex gv = entry.getValue();
layerNames.add(entry.getKey());
List<String> inputsThisVertex = vertexInputs.get(entry.getKey());
List<Integer> inputIndexes = new ArrayList<>();
for (String s : inputsThisVertex) {
inputIndexes.add(vertexToIndexMap.get(s));
}
layerInputs.add(inputIndexes);
if (gv instanceof LayerVertex) {
NeuralNetConfiguration c = ((LayerVertex) gv).getLayerConf();
Layer layer = c.getLayer();
String layerType = layer.getClass().getSimpleName().replaceAll("Layer$", "");
layerTypes.add(layerType);
//Extract layer info
Map<String, String> map = getLayerInfo(c, layer);
layerInfo.add(map);
} else {
String layerType = gv.getClass().getSimpleName();
layerTypes.add(layerType);
Map<String, String> thisVertexInfo = Collections.emptyMap(); //TODO
layerInfo.add(thisVertexInfo);
}
originalVertexName.add(entry.getKey());
}
return new GraphInfo(layerNames, layerTypes, layerInputs, layerInfo, originalVertexName);
}
public static GraphInfo buildGraphInfo(NeuralNetConfiguration config) {
List<String> vertexNames = new ArrayList<>();
List<String> originalVertexName = new ArrayList<>();
List<String> layerTypes = new ArrayList<>();
List<List<Integer>> layerInputs = new ArrayList<>();
List<Map<String, String>> layerInfo = new ArrayList<>();
vertexNames.add("Input");
originalVertexName.add(null);
layerTypes.add("Input");
layerInputs.add(Collections.emptyList());
layerInfo.add(Collections.emptyMap());
if (config.getLayer() instanceof VariationalAutoencoder) {
//Special case like this is a bit ugly - but it works
VariationalAutoencoder va = (VariationalAutoencoder) config.getLayer();
int[] encLayerSizes = va.getEncoderLayerSizes();
int[] decLayerSizes = va.getDecoderLayerSizes();
int layerIndex = 1;
for (int i = 0; i < encLayerSizes.length; i++) {
String name = "encoder_" + i;
vertexNames.add(name);
originalVertexName.add("e" + i);
String layerType = "VAE-Encoder";
layerTypes.add(layerType);
layerInputs.add(Collections.singletonList(layerIndex - 1));
layerIndex++;
Map<String, String> encoderInfo = new LinkedHashMap<>();
long inputSize = (i == 0 ? va.getNIn() : encLayerSizes[i - 1]);
long outputSize = encLayerSizes[i];
encoderInfo.put("Input Size", String.valueOf(inputSize));
encoderInfo.put("Layer Size", String.valueOf(outputSize));
encoderInfo.put("Num Parameters", String.valueOf((inputSize + 1) * outputSize));
encoderInfo.put("Activation Function", va.getActivationFn().toString());
layerInfo.add(encoderInfo);
}
vertexNames.add("z");
originalVertexName.add(VariationalAutoencoderParamInitializer.PZX_PREFIX);
layerTypes.add("VAE-LatentVariable");
layerInputs.add(Collections.singletonList(layerIndex - 1));
layerIndex++;
Map<String, String> latentInfo = new LinkedHashMap<>();
long inputSize = encLayerSizes[encLayerSizes.length - 1];
long outputSize = va.getNOut();
latentInfo.put("Input Size", String.valueOf(inputSize));
latentInfo.put("Layer Size", String.valueOf(outputSize));
latentInfo.put("Num Parameters", String.valueOf((inputSize + 1) * outputSize * 2));
latentInfo.put("Activation Function", va.getPzxActivationFn().toString());
layerInfo.add(latentInfo);
for (int i = 0; i < decLayerSizes.length; i++) {
String name = "decoder_" + i;
vertexNames.add(name);
originalVertexName.add("d" + i);
String layerType = "VAE-Decoder";
layerTypes.add(layerType);
layerInputs.add(Collections.singletonList(layerIndex - 1));
layerIndex++;
Map<String, String> decoderInfo = new LinkedHashMap<>();
inputSize = (i == 0 ? va.getNOut() : decLayerSizes[i - 1]);
outputSize = decLayerSizes[i];
decoderInfo.put("Input Size", String.valueOf(inputSize));
decoderInfo.put("Layer Size", String.valueOf(outputSize));
decoderInfo.put("Num Parameters", String.valueOf((inputSize + 1) * outputSize));
decoderInfo.put("Activation Function", va.getActivationFn().toString());
layerInfo.add(decoderInfo);
}
vertexNames.add("x");
originalVertexName.add(VariationalAutoencoderParamInitializer.PXZ_PREFIX);
layerTypes.add("VAE-Reconstruction");
layerInputs.add(Collections.singletonList(layerIndex - 1));
layerIndex++;
Map<String, String> reconstructionInfo = new LinkedHashMap<>();
inputSize = decLayerSizes[decLayerSizes.length - 1];
outputSize = va.getNIn();
reconstructionInfo.put("Input Size", String.valueOf(inputSize));
reconstructionInfo.put("Layer Size", String.valueOf(outputSize));
reconstructionInfo.put("Num Parameters", String
.valueOf((inputSize + 1) * va.getOutputDistribution().distributionInputSize((int) va.getNIn())));
reconstructionInfo.put("Distribution", va.getOutputDistribution().toString());
layerInfo.add(reconstructionInfo);
} else {
//VAE or similar...
Layer layer = config.getLayer();
String layerName = layer.getLayerName();
if (layerName == null)
layerName = "layer0";
vertexNames.add(layerName);
originalVertexName.add(String.valueOf("0"));
String layerType = config.getLayer().getClass().getSimpleName().replaceAll("Layer$", "");
layerTypes.add(layerType);
layerInputs.add(Collections.singletonList(0));
//Extract layer info
Map<String, String> map = getLayerInfo(config, layer);
layerInfo.add(map);
}
return new GraphInfo(vertexNames, layerTypes, layerInputs, layerInfo, originalVertexName);
}
private static Map<String, String> getLayerInfo(NeuralNetConfiguration c, Layer layer) {
Map<String, String> map = new LinkedHashMap<>();
if (layer instanceof FeedForwardLayer) {
FeedForwardLayer layer1 = (FeedForwardLayer) layer;
map.put("Input size", String.valueOf(layer1.getNIn()));
map.put("Output size", String.valueOf(layer1.getNOut()));
map.put("Num Parameters", String.valueOf(layer1.initializer().numParams(c)));
map.put("Activation Function", layer1.getActivationFn().toString());
}
if (layer instanceof ConvolutionLayer) {
ConvolutionLayer layer1 =
(ConvolutionLayer) layer;
map.put("Kernel size", Arrays.toString(layer1.getKernelSize()));
map.put("Stride", Arrays.toString(layer1.getStride()));
map.put("Padding", Arrays.toString(layer1.getPadding()));
} else if (layer instanceof SubsamplingLayer) {
SubsamplingLayer layer1 = (SubsamplingLayer) layer;
map.put("Kernel size", Arrays.toString(layer1.getKernelSize()));
map.put("Stride", Arrays.toString(layer1.getStride()));
map.put("Padding", Arrays.toString(layer1.getPadding()));
map.put("Pooling Type", layer1.getPoolingType().toString());
} else if (layer instanceof BaseOutputLayer) {
BaseOutputLayer ol = (BaseOutputLayer) layer;
if(ol.getLossFn() != null)
map.put("Loss Function", ol.getLossFn().toString());
}
return map;
}
}
@@ -0,0 +1,144 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
package org.deeplearning4j.ui.module.tsne;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.ext.web.FileUpload;
import io.vertx.ext.web.RoutingContext;
import org.apache.commons.io.FileUtils;
import org.deeplearning4j.core.storage.StatsStorage;
import org.deeplearning4j.core.storage.StatsStorageEvent;
import org.deeplearning4j.nn.conf.serde.JsonMappers;
import org.deeplearning4j.ui.api.HttpMethod;
import org.deeplearning4j.ui.api.Route;
import org.deeplearning4j.ui.api.UIModule;
import org.deeplearning4j.ui.i18n.I18NResource;
import org.nd4j.shade.jackson.core.JsonProcessingException;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
public class TsneModule implements UIModule {
private static final String UPLOADED_FILE = "UploadedFile";
private Map<String, List<String>> knownSessionIDs = Collections.synchronizedMap(new LinkedHashMap<>());
private List<String> uploadedFileLines = null;
public TsneModule() {
}
@Override
public List<String> getCallbackTypeIDs() {
return Collections.emptyList();
}
@Override
public List<Route> getRoutes() {
Route r1 = new Route("/tsne", HttpMethod.GET, (path, rc) -> rc.response().sendFile("templates/Tsne.html"));
Route r2 = new Route("/tsne/sessions", HttpMethod.GET, (path, rc) -> this.listSessions(rc));
Route r3 = new Route("/tsne/coords/:sid", HttpMethod.GET, (path, rc) -> this.getCoords(path.get(0), rc));
Route r4 = new Route("/tsne/upload", HttpMethod.POST, (path, rc) -> this.uploadFile(rc));
Route r5 = new Route("/tsne/post/:sid", HttpMethod.POST, (path, rc) -> this.postFile(path.get(0), rc));
return Arrays.asList(r1, r2, r3, r4, r5);
}
@Override
public void reportStorageEvents(Collection<StatsStorageEvent> events) {
//No-op
}
@Override
public void onAttach(StatsStorage statsStorage) {
//No-op
}
@Override
public void onDetach(StatsStorage statsStorage) {
//No-op
}
@Override
public List<I18NResource> getInternationalizationResources() {
return Collections.emptyList();
}
private String asJson(Object o){
try{
return JsonMappers.getMapper().writeValueAsString(o);
} catch (JsonProcessingException e){
throw new RuntimeException("Error converting object to JSON", e);
}
}
private void listSessions(RoutingContext rc) {
List<String> list = new ArrayList<>(knownSessionIDs.keySet());
if (uploadedFileLines != null) {
list.add(UPLOADED_FILE);
}
rc.response()
.putHeader("content-type", "application/json")
.end(asJson(list));
}
private void getCoords(String sessionId, RoutingContext rc) {
if (UPLOADED_FILE.equals(sessionId) && uploadedFileLines != null) {
rc.response()
.putHeader("content-type", "application/json")
.end(asJson(uploadedFileLines));
} else if (knownSessionIDs.containsKey(sessionId)) {
rc.response().putHeader("content-type", "application/json")
.end(asJson(knownSessionIDs.get(sessionId)));
} else {
rc.response().end();
}
}
private void uploadFile(RoutingContext rc) {
postFile(null, rc);
}
private void postFile(String sid, RoutingContext rc) {
Set<FileUpload> files = rc.fileUploads();
if(files == null || files.isEmpty()){
rc.response().end();
return;
}
FileUpload u = files.iterator().next();
File f = new File(u.uploadedFileName());
List<String> lines;
try {
lines = FileUtils.readLines(f, StandardCharsets.UTF_8);
} catch (IOException e) {
rc.response().setStatusCode(HttpResponseStatus.BAD_REQUEST.code()).end("Could not read from uploaded file");
return;
}
if(sid == null){
uploadedFileLines = lines;
} else {
knownSessionIDs.put(sid, lines);
}
rc.response().end("File uploaded: " + u.fileName() + ", " + u.contentType());
}
}
@@ -0,0 +1,26 @@
#
# /* ******************************************************************************
# *
# *
# * This program and the accompanying materials are made available under the
# * terms of the Apache License, Version 2.0 which is available at
# * https://www.apache.org/licenses/LICENSE-2.0.
# *
# * See the NOTICE file distributed with this work for additional
# * information regarding copyright ownership.
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# * License for the specific language governing permissions and limitations
# * under the License.
# *
# * SPDX-License-Identifier: Apache-2.0
# ******************************************************************************/
#
#org.deeplearning4j.ui.module.convolutional.ConvolutionalListenerModule
org.deeplearning4j.ui.module.defaultModule.DefaultModule
#org.deeplearning4j.ui.module.remote.RemoteReceiverModule
org.deeplearning4j.ui.module.train.TrainModule
#org.deeplearning4j.ui.module.tsne.TsneModule
@@ -0,0 +1,60 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
html, body {height: 100%; }
.wrapper {
display: flex;
height: 100vh;
align-items: stretch;
}
.sidebarline {
height: 2px;
width: 100%;
background-color: #212529;
margin-top: 5px;
margin-bottom: 5px;
}
#samediffsidebar {
min-width: 250px;
max-width: 250px;
min-height: 100%;
background-color: #e6e6e6;
position: relative;
}
#samediffsidebar.sidebarhidden {
margin-left: -250px;
}
#samediffcontent {
min-height: 100%;
}
#findnoderesults {
width: 100%;
height: 160px;
overflow:hidden;
overflow-y:scroll;
overflow-x:scroll;
}
@@ -0,0 +1,241 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
.app-header {
background: #080808;
}
.header-text {
display: block;
float: left;
padding-top: 10px;
padding-right: 20px;
padding-bottom: 10px;
padding-left: 60px;
margin-left: -20px;
font-size: 20px;
font-weight: 200;
color: white;
}
.header-text:active, .header-text:visited, .header-text:hover, .header-text:link {
color: white;
text-decoration: none;
}
.navbar {
padding: 0;
}
.navbar-inner {
margin-bottom: 0px;
min-height: 40px;
padding-right: 20px;
padding-left: 20px;
background: #080808;
filter: none;
text-shadow: 1px 1px 1px #0a0c0e;
border: none;
color: #fff;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
*zoom: 1;
border-bottom: 1px solid #38383D; /* rgba(0, 0, 0, 0.05); */
}
#content {
background: #ffffff;
filter: none;
min-height: 100vh;
padding: 20px 20px;
position: relative;
}
.chart-header {
height: 16px;
font-size: 16px;
line-height: 16px;
padding: 10px;
background: #eee;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
overflow: hidden;
display: block;
min-height: 36px;
}
.chart-header h2 {
font-size: 16px;
line-height: 16px;
}
.chart-box {
border: 2px solid #eee;
background: #fff !important;
margin-bottom: 28px;
padding-left: 0;
padding-right: 0;
}
.table th,
.table td {
border-top: 1px solid #eee;
padding: 5px;
}
.table-bordered {
border-color: #eee;
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered th,
.table-bordered td {
border-left: 1px solid #eee;
}
.table-bordered thead:first-child tr:first-child > th:first-child,
.table-bordered tbody:first-child tr:first-child > td:first-child,
.table-bordered tbody:first-child tr:first-child > th:first-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered thead:first-child tr:first-child > th:last-child,
.table-bordered tbody:first-child tr:first-child > td:last-child,
.table-bordered tbody:first-child tr:first-child > th:last-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered thead:last-child tr:last-child > th:first-child,
.table-bordered tbody:last-child tr:last-child > td:first-child,
.table-bordered tbody:last-child tr:last-child > th:first-child,
.table-bordered tfoot:last-child tr:last-child > td:first-child,
.table-bordered tfoot:last-child tr:last-child > th:first-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered thead:last-child tr:last-child > th:last-child,
.table-bordered tbody:last-child tr:last-child > td:last-child,
.table-bordered tbody:last-child tr:last-child > th:last-child,
.table-bordered tfoot:last-child tr:last-child > td:last-child,
.table-bordered tfoot:last-child tr:last-child > th:last-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered tfoot + tbody:last-child tr:last-child td:first-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered caption + thead tr:first-child th:first-child,
.table-bordered caption + tbody tr:first-child td:first-child,
.table-bordered colgroup + thead tr:first-child th:first-child,
.table-bordered colgroup + tbody tr:first-child td:first-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
.table-bordered caption + thead tr:first-child th:last-child,
.table-bordered caption + tbody tr:first-child td:last-child,
.table-bordered colgroup + thead tr:first-child th:last-child,
.table-bordered colgroup + tbody tr:first-child td:last-child {
-webkit-border-radius: 0px !important;
-moz-border-radius: 0px !important;
border-radius: 0px !important;
}
/* Tabs
=================================================================== */
.tab-menu.nav-tabs {
*zoom: 1;
margin-top: -46px;
padding-left: 6px;
padding-right: 6px;
padding-top: 4px;
padding-bottom: 4px;
}
.tab-menu.nav-tabs > li {
float: right;
padding-left: 6px;
padding-right: 6px;
padding-top: 4px;
padding-bottom: 4px;
}
.tab-menu.nav-tabs {
border-bottom: none;
}
.tab-menu.nav-tabs > li {
margin-bottom: -1px;
}
.tab-menu.nav-tabs > li > a {
padding-top: 10px;
padding-bottom: 10px;
line-height: 16px;
margin-left: 0px;
border: none;
-webkit-border-radius: 0px;
-moz-border-radius: 0px;
border-radius: 0px;
}
.tab-menu.nav-tabs > li > a:hover {
border: none;
}
.tab-menu.nav-tabs > .active > a {
color: #555555;
cursor: default;
background-color: #fff;
border: none;
}
.tab-menu.nav-tabs > .active > a:hover {
background-color: #fafafa;
}
@@ -0,0 +1,66 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
(function($) {
$.fn.countTo = function(options) {
// merge the default plugin settings with the custom options
options = $.extend({}, $.fn.countTo.defaults, options || {});
// how many times to update the value, and how much to increment the value on each update
var loops = Math.ceil(options.speed / options.refreshInterval),
increment = (options.to - options.from) / loops;
return $(this).each(function() {
var _this = this,
loopCount = 0,
value = options.from,
interval = setInterval(updateTimer, options.refreshInterval);
function updateTimer() {
value += increment;
loopCount++;
$(_this).html(value.toFixed(options.decimals));
if (typeof(options.onUpdate) == 'function') {
options.onUpdate.call(_this, value);
}
if (loopCount >= loops) {
clearInterval(interval);
value = options.to;
if (typeof(options.onComplete) == 'function') {
options.onComplete.call(_this, value);
}
}
}
});
};
$.fn.countTo.defaults = {
from: 0, // the number the element should start at
to: 100, // the number the element should end at
speed: 1000, // how long it should take to count between the target numbers
refreshInterval: 100, // how often the element should be updated
decimals: 0, // the number of decimal places to show
onUpdate: null, // callback method for every time the element is updated,
onComplete: null, // callback method for when the element finishes updating
};
})(jQuery);
@@ -0,0 +1,138 @@
[
{
"selector": ".uiop",
"style": {
"label": "data(label)",
"width": 30,
"height": 15,
"text-valign": "center",
"text-halign": "center",
"text-wrap": "wrap",
"font-size":6,
"shape": "roundrectangle"
}
},
{
"selector": ".uivariable",
"style": {
"label": "data(label)",
"width": 6,
"height": 6,
"text-valign": "center",
"text-halign": "left",
"text-wrap": "wrap",
"font-size":5,
"text-margin-x": -4
}
},
{
"selector": ".opoutputedge",
"style": {
"label": "data(label)",
"curve-style": "bezier",
"width": 1.5,
"line-color": "#ccc",
"target-arrow-shape": "triangle",
"source-arrow-shape": "none",
"source-arrow-color": "#A9A9A9",
"target-arrow-color": "#A9A9A9",
"arrow-scale": 0.7,
"text-wrap": "wrap",
"font-size":5,
"text-margin-x": -4,
"edge-text-rotation": "autorotate"
}
},
{
"selector": ".placeholder",
"style": {
"background-color": "#d9d9d9",
"border-width": 1,
"border-color": "#000000"
}
},
{
"selector": ".variable",
"style": {
"background-color": "#b3e6ff"
}
},
{
"selector": ".constant",
"style": {
"background-color": "#d6f5d6"
}
},
{
"selector": ".output",
"style": {
"background-color": "#ffb366",
"border-width": 1,
"border-color": "#000000"
}
},
{
"selector": ".openter",
"style": {
"background-color": "#8cd98c",
"border-width": 1,
"border-color": "#808080",
"border-style": "solid"
}
},
{
"selector": ".opexit",
"style": {
"background-color": "#ffcc99",
"border-width": 1,
"border-color": "#808080",
"border-style": "solid"
}
},
{
"selector": ".opnextiter",
"style": {
"background-color": "#ffff66",
"border-width": 1,
"border-color": "#808080",
"border-style": "solid"
}
},
{
"selector": ".opswitch",
"style": {
"background-color": "#ff6666",
"border-width": 1,
"border-color": "#808080",
"border-style": "solid"
}
},
{
"selector": ".opmerge",
"style": {
"background-color": "#d98cd9",
"border-width": 1,
"border-color": "#808080",
"border-style": "solid"
}
},
{
"selector": ".controldepedge",
"style": {
"label": "data(label)",
"curve-style": "bezier",
"width": 1.5,
"line-color": "#cce6ff",
"line-style": "dashed",
"target-arrow-shape": "triangle",
"source-arrow-shape": "none",
"source-arrow-color": "#cce6ff",
"target-arrow-color": "#cce6ff",
"arrow-scale": 0.7,
"text-wrap": "wrap",
"font-size":5,
"text-margin-x": -4,
"edge-text-rotation": "autorotate"
}
}
]
@@ -0,0 +1,307 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function extractHeaders(/*Uint8Array*/ bytes, offset){
var header1a = bytes.slice(offset+0,offset+4);
var header1b = bytes.slice(offset+4,offset+8);
var headerLength = byteArrayToInt(header1a);
var contentLength = byteArrayToInt(header1b);
return [headerLength, contentLength];
}
function byteArrayToInt(byteArray) {
var value = 0;
for ( var i = 0; i < byteArray.length; i++) {
value = (value * 256) + byteArray[i];
}
return value;
}
function decodeStaticInfo(headerContentBytes, bufferContentBytes){
var headerBuffer = new flatbuffers.ByteBuffer(headerContentBytes);
var contentBuffer = new flatbuffers.ByteBuffer(bufferContentBytes);
var header = nd4j.graph.UIStaticInfoRecord.getRootAsUIStaticInfoRecord(headerBuffer);
var infoType = header.infoType();
switch(infoType){
case nd4j.graph.UIInfoType.GRAPH_STRUCTURE:
var graphStructure = nd4j.graph.UIGraphStructure.getRootAsUIGraphStructure(contentBuffer);
return ["graph", graphStructure];
case nd4j.graph.UIInfoType.SYTEM_INFO:
var info = nd4j.graph.UISystemInfo.getRootAsUISystemInfo(contentBuffer);
return ["systeminfo", info];
case nd4j.graph.UIInfoType.START_EVENTS:
return ["startevents", null];
default:
console.log("Unknown static information type: " + infoType);
return null;
}
}
//Return graph inputs as a String[]
function uiGraphGetInputs(/*UIGraphStructure*/ graph){
var inLength = graph.inputsLength();
var inputs = [];
for( var i=0; i<inLength; i++ ){
inputs.push(graph.inputs(i));
}
return inputs;
}
//Return graph outputs as a String[]
function uiGraphGetOutputs(/*UIGraphStructure*/ graph){
var inLength = graph.outputsLength();
var outputs = [];
for( var i=0; i<inLength; i++ ){
outputs.push(graph.outputs(i));
}
return outputs;
}
//Return graph variables as nd4j.graph.UIVariable[]
function uiGraphGetVariables(/*UIGraphStructure*/ graph){
var varsLength = graph.variablesLength();
var vars = [];
for( var i=0; i<varsLength; i++ ){
vars.push(graph.variables(i));
}
return vars;
}
//Return graph variables as String[]
function uiGraphGetVariableNames(/*UIGraphStructure*/ graph){
var varsLength = graph.variablesLength();
var vars = [];
for( var i=0; i<varsLength; i++ ){
vars.push(graph.variables(i).name());
}
return vars;
}
//Returns nd4j.graph.UIOp[]
function uiGraphGetOps(/*UIGraphStructure*/ graph){
var opsLength = graph.opsLength();
var ops = [];
for( var i=0; i<opsLength; i++ ){
ops.push(graph.ops(i));
}
return ops;
}
function varTypeToString(varType){
switch (varType){
case nd4j.graph.VarType.CONSTANT:
return "constant";
case nd4j.graph.VarType.PLACEHOLDER:
return "placeholder";
case nd4j.graph.VarType.VARIABLE:
return "variable";
case nd4j.graph.VarType.ARRAY:
return "array";
default:
return "" + varType;
}
}
function varShapeToString(/*UIVariable*/ uivar){
var n = uivar.shapeLength();
if(n === 0)
return "";
var shape = [];
for( var i=0; i<n; i++ ){
var l = uivar.shape(i);
var s = l.toString();
var s2 = l.toFloat64().toString();
shape.push(s2);
}
return "[" + shape.toString() + "]";
}
function dataTypeToString(dataTypeByte){
switch (dataTypeByte){
case nd4j.graph.DataType.INHERIT:
return "INHERIT";
case nd4j.graph.DataType.BOOL:
return "BOOL";
case nd4j.graph.DataType.FLOAT8:
return "FLOAT8";
case nd4j.graph.DataType.HALF:
return "HALF";
case nd4j.graph.DataType.HALF2:
return "HALF2";
case nd4j.graph.DataType.FLOAT:
return "FLOAT";
case nd4j.graph.DataType.DOUBLE:
return "DOUBLE";
case nd4j.graph.DataType.INT8:
return "INT8";
case nd4j.graph.DataType.INT16:
return "INT16";
case nd4j.graph.DataType.INT32:
return "INT32";
case nd4j.graph.DataType.INT64:
return "INT64";
case nd4j.graph.DataType.UINT8:
return "UINT8";
case nd4j.graph.DataType.UINT16:
return "UINT16";
case nd4j.graph.DataType.UINT32:
return "UINT32";
case nd4j.graph.DataType.UINT64:
return "UINT64";
case nd4j.graph.DataType.QINT8:
return "QINT8";
case nd4j.graph.DataType.QINT16:
return "QINT16";
case nd4j.graph.DataType.BFLOAT16:
return "BFLOAT16";
case nd4j.graph.DataType.UTF8:
return "UTF8";
default:
return "" + dataTypeByte;
}
}
function dataTypeBytesPerElement(dataTypeByte){
switch (dataTypeByte){
case nd4j.graph.DataType.BOOL:
case nd4j.graph.DataType.FLOAT8:
case nd4j.graph.DataType.INT8:
case nd4j.graph.DataType.UINT8:
case nd4j.graph.DataType.QINT8:
return 1;
case nd4j.graph.DataType.HALF:
case nd4j.graph.DataType.HALF2:
case nd4j.graph.DataType.INT16:
case nd4j.graph.DataType.UINT16:
case nd4j.graph.DataType.QINT16:
case nd4j.graph.DataType.BFLOAT16:
return 2;
case nd4j.graph.DataType.FLOAT:
case nd4j.graph.DataType.INT32:
case nd4j.graph.DataType.UINT32:
return 4;
case nd4j.graph.DataType.DOUBLE:
case nd4j.graph.DataType.INT64:
case nd4j.graph.DataType.UINT64:
return 8;
case nd4j.graph.DataType.UTF8:
return 0; //TODO
default:
return "" + dataTypeByte;
}
}
function getScalar(/*FlatArray*/ flatArray, /*number[]*/ idxs){
//First: work out offset... assume C order here
var offset = 0;
// var prod = 1;
var rank = flatArray.shape(0).toFloat64(); //Note: shape is in nd4j format. So rank, shape. We're assuming C order here. Note also shape(i) returns flatbuffers long object
for( var i=0; i<rank; i++ ){
var size = flatArray.shape(i+1).toFloat64();
var stride = flatArray.shape(rank+i+1).toFloat64();
offset += stride * idxs[i];
// prod *= size.toFloat64();
}
return scalarFromFlatArrayIdx(flatArray, offset);
}
function scalarFromFlatArray(/*FlatArray*/ flatArray) {
return scalarFromFlatArrayIdx(flatArray, 0);
}
function scalarFromFlatArrayIdx(/*FlatArray*/ flatArray, idx){
//TODO OPTIMIZE THIS!
var dt = flatArray.dtype();
switch (dt){
//Skip hard to decode types for now
case nd4j.graph.DataType.FLOAT8:
case nd4j.graph.DataType.QINT8:
case nd4j.graph.DataType.HALF:
case nd4j.graph.DataType.HALF2:
case nd4j.graph.DataType.QINT16:
case nd4j.graph.DataType.BFLOAT16:
return null;
}
var bytesPerElem = dataTypeBytesPerElement(dt);
// var array = new Uint8Array(numBytes);
var dv = new DataView(new ArrayBuffer(bytesPerElem));
var byteOffset = idx * bytesPerElem;
var j=0;
for(var i=byteOffset; i<byteOffset + bytesPerElem; i++ ){
var signedByte = flatArray.buffer(i);
// array[i] = signedByte; //TODO do we need to convert here???
dv.setInt8(j++, signedByte);
}
//Note: "get(idx)" is byte offset
var out;
switch (dt){
case nd4j.graph.DataType.BOOL:
out = (dv.getUint8(0) === 0 ? "false" : "true");
break;
case nd4j.graph.DataType.INT8:
out = dv.getInt8(0);
break;
case nd4j.graph.DataType.UINT8:
out = dv.getUint8(0);
break;
case nd4j.graph.DataType.INT16:
out = dv.getInt16(0);
break;
case nd4j.graph.DataType.UINT16:
out = dv.getUint16(0);
break;
case nd4j.graph.DataType.INT32:
out = dv.getInt32(0);
break;
case nd4j.graph.DataType.UINT32:
out = dv.getUint32(0);
break;
case nd4j.graph.DataType.INT64:
//No getInt64 method... :/
//TODO Need a solution to this!
out = "<int64>";
break;
case nd4j.graph.DataType.UINT64:
out = "<uint64>";
break;
case nd4j.graph.DataType.FLOAT:
out = dv.getFloat32(0);
break;
case nd4j.graph.DataType.DOUBLE:
out = dv.getFloat64(0);
break;
case nd4j.graph.DataType.UTF8:
//TODO need to decode from bytes here
out = "<utf8>";
break;
default:
return "";
}
return out;
}
@@ -0,0 +1,258 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @enum
*/
nd4j.graph.ByteOrder = {
LE: 0,
BE: 1
};
/**
* @enum
*/
nd4j.graph.DataType = {
INHERIT: 0,
BOOL: 1,
FLOAT8: 2,
HALF: 3,
HALF2: 4,
FLOAT: 5,
DOUBLE: 6,
INT8: 7,
INT16: 8,
INT32: 9,
INT64: 10,
UINT8: 11,
UINT16: 12,
UINT32: 13,
UINT64: 14,
QINT8: 15,
QINT16: 16,
BFLOAT16: 17,
UTF8: 50
};
/**
* @constructor
*/
nd4j.graph.FlatArray = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatArray}
*/
nd4j.graph.FlatArray.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatArray=} obj
* @returns {nd4j.graph.FlatArray}
*/
nd4j.graph.FlatArray.getRootAsFlatArray = function(bb, obj) {
return (obj || new nd4j.graph.FlatArray).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {number} index
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatArray.prototype.shape = function(index) {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
};
/**
* @returns {number}
*/
nd4j.graph.FlatArray.prototype.shapeLength = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatArray.prototype.buffer = function(index) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatArray.prototype.bufferLength = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int8Array}
*/
nd4j.graph.FlatArray.prototype.bufferArray = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @returns {nd4j.graph.DataType}
*/
nd4j.graph.FlatArray.prototype.dtype = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** @type {nd4j.graph.DataType} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.DataType.INHERIT;
};
/**
* @returns {nd4j.graph.ByteOrder}
*/
nd4j.graph.FlatArray.prototype.byteOrder = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? /** @type {nd4j.graph.ByteOrder} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.ByteOrder.LE;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatArray.startFlatArray = function(builder) {
builder.startObject(4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} shapeOffset
*/
nd4j.graph.FlatArray.addShape = function(builder, shapeOffset) {
builder.addFieldOffset(0, shapeOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Long>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatArray.createShapeVector = function(builder, data) {
builder.startVector(8, data.length, 8);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatArray.startShapeVector = function(builder, numElems) {
builder.startVector(8, numElems, 8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} bufferOffset
*/
nd4j.graph.FlatArray.addBuffer = function(builder, bufferOffset) {
builder.addFieldOffset(1, bufferOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatArray.createBufferVector = function(builder, data) {
builder.startVector(1, data.length, 1);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt8(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatArray.startBufferVector = function(builder, numElems) {
builder.startVector(1, numElems, 1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.DataType} dtype
*/
nd4j.graph.FlatArray.addDtype = function(builder, dtype) {
builder.addFieldInt8(2, dtype, nd4j.graph.DataType.INHERIT);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.ByteOrder} byteOrder
*/
nd4j.graph.FlatArray.addByteOrder = function(builder, byteOrder) {
builder.addFieldInt8(3, byteOrder, nd4j.graph.ByteOrder.LE);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatArray.endFlatArray = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatArray.finishFlatArrayBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,260 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @enum
*/
nd4j.graph.ProfilingMode = {
NONE: 0,
NAN_PANIC: 1,
INF_PANIC: 2,
ANY_PANIC: 3
};
/**
* @enum
*/
nd4j.graph.ExecutionMode = {
SEQUENTIAL: 0,
STRICT: 1,
AUTO: 2
};
/**
* @enum
*/
nd4j.graph.OutputMode = {
IMPLICIT: 0,
EXPLICIT: 1,
EXPLICIT_AND_IMPLICIT: 2,
VARIABLE_SPACE: 3,
OPTIMIZED: 4
};
/**
* @enum
*/
nd4j.graph.Direction = {
FORWARD_ONLY: 0,
FORWARD_AND_BACKWARD: 1,
BACKWARD_ONLY: 2
};
/**
* @constructor
*/
nd4j.graph.FlatConfiguration = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatConfiguration}
*/
nd4j.graph.FlatConfiguration.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatConfiguration=} obj
* @returns {nd4j.graph.FlatConfiguration}
*/
nd4j.graph.FlatConfiguration.getRootAsFlatConfiguration = function(bb, obj) {
return (obj || new nd4j.graph.FlatConfiguration).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatConfiguration.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {nd4j.graph.ExecutionMode}
*/
nd4j.graph.FlatConfiguration.prototype.executionMode = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? /** @type {nd4j.graph.ExecutionMode} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.ExecutionMode.SEQUENTIAL;
};
/**
* @returns {nd4j.graph.ProfilingMode}
*/
nd4j.graph.FlatConfiguration.prototype.profilingMode = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** @type {nd4j.graph.ProfilingMode} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.ProfilingMode.NONE;
};
/**
* @returns {nd4j.graph.OutputMode}
*/
nd4j.graph.FlatConfiguration.prototype.outputMode = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? /** @type {nd4j.graph.OutputMode} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.OutputMode.IMPLICIT;
};
/**
* @returns {boolean}
*/
nd4j.graph.FlatConfiguration.prototype.timestats = function() {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? !!this.bb.readInt8(this.bb_pos + offset) : false;
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatConfiguration.prototype.footprintForward = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatConfiguration.prototype.footprintBackward = function() {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {nd4j.graph.Direction}
*/
nd4j.graph.FlatConfiguration.prototype.direction = function() {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? /** @type {nd4j.graph.Direction} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.Direction.FORWARD_ONLY;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatConfiguration.startFlatConfiguration = function(builder) {
builder.startObject(8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} id
*/
nd4j.graph.FlatConfiguration.addId = function(builder, id) {
builder.addFieldInt64(0, id, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.ExecutionMode} executionMode
*/
nd4j.graph.FlatConfiguration.addExecutionMode = function(builder, executionMode) {
builder.addFieldInt8(1, executionMode, nd4j.graph.ExecutionMode.SEQUENTIAL);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.ProfilingMode} profilingMode
*/
nd4j.graph.FlatConfiguration.addProfilingMode = function(builder, profilingMode) {
builder.addFieldInt8(2, profilingMode, nd4j.graph.ProfilingMode.NONE);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.OutputMode} outputMode
*/
nd4j.graph.FlatConfiguration.addOutputMode = function(builder, outputMode) {
builder.addFieldInt8(3, outputMode, nd4j.graph.OutputMode.IMPLICIT);
};
/**
* @param {flatbuffers.Builder} builder
* @param {boolean} timestats
*/
nd4j.graph.FlatConfiguration.addTimestats = function(builder, timestats) {
builder.addFieldInt8(4, +timestats, +false);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} footprintForward
*/
nd4j.graph.FlatConfiguration.addFootprintForward = function(builder, footprintForward) {
builder.addFieldInt64(5, footprintForward, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} footprintBackward
*/
nd4j.graph.FlatConfiguration.addFootprintBackward = function(builder, footprintBackward) {
builder.addFieldInt64(6, footprintBackward, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.Direction} direction
*/
nd4j.graph.FlatConfiguration.addDirection = function(builder, direction) {
builder.addFieldInt8(7, direction, nd4j.graph.Direction.FORWARD_ONLY);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatConfiguration.endFlatConfiguration = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatConfiguration.finishFlatConfigurationBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,495 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @constructor
*/
nd4j.graph.FlatGraph = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatGraph}
*/
nd4j.graph.FlatGraph.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatGraph=} obj
* @returns {nd4j.graph.FlatGraph}
*/
nd4j.graph.FlatGraph.getRootAsFlatGraph = function(bb, obj) {
return (obj || new nd4j.graph.FlatGraph).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatGraph.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {number} index
* @param {nd4j.graph.FlatVariable=} obj
* @returns {nd4j.graph.FlatVariable}
*/
nd4j.graph.FlatGraph.prototype.variables = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new nd4j.graph.FlatVariable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatGraph.prototype.variablesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @param {nd4j.graph.FlatNode=} obj
* @returns {nd4j.graph.FlatNode}
*/
nd4j.graph.FlatGraph.prototype.nodes = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new nd4j.graph.FlatNode).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatGraph.prototype.nodesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @param {nd4j.graph.IntPair=} obj
* @returns {nd4j.graph.IntPair}
*/
nd4j.graph.FlatGraph.prototype.outputs = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? (obj || new nd4j.graph.IntPair).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatGraph.prototype.outputsLength = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {nd4j.graph.FlatConfiguration=} obj
* @returns {nd4j.graph.FlatConfiguration|null}
*/
nd4j.graph.FlatGraph.prototype.configuration = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? (obj || new nd4j.graph.FlatConfiguration).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {number} index
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array}
*/
nd4j.graph.FlatGraph.prototype.placeholders = function(index, optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatGraph.prototype.placeholdersLength = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array}
*/
nd4j.graph.FlatGraph.prototype.lossVariables = function(index, optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatGraph.prototype.lossVariablesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatGraph.startFlatGraph = function(builder) {
builder.startObject(7);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} id
*/
nd4j.graph.FlatGraph.addId = function(builder, id) {
builder.addFieldInt64(0, id, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} variablesOffset
*/
nd4j.graph.FlatGraph.addVariables = function(builder, variablesOffset) {
builder.addFieldOffset(1, variablesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatGraph.createVariablesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatGraph.startVariablesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} nodesOffset
*/
nd4j.graph.FlatGraph.addNodes = function(builder, nodesOffset) {
builder.addFieldOffset(2, nodesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatGraph.createNodesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatGraph.startNodesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} outputsOffset
*/
nd4j.graph.FlatGraph.addOutputs = function(builder, outputsOffset) {
builder.addFieldOffset(3, outputsOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatGraph.createOutputsVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatGraph.startOutputsVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} configurationOffset
*/
nd4j.graph.FlatGraph.addConfiguration = function(builder, configurationOffset) {
builder.addFieldOffset(4, configurationOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} placeholdersOffset
*/
nd4j.graph.FlatGraph.addPlaceholders = function(builder, placeholdersOffset) {
builder.addFieldOffset(5, placeholdersOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatGraph.createPlaceholdersVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatGraph.startPlaceholdersVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} lossVariablesOffset
*/
nd4j.graph.FlatGraph.addLossVariables = function(builder, lossVariablesOffset) {
builder.addFieldOffset(6, lossVariablesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatGraph.createLossVariablesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatGraph.startLossVariablesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatGraph.endFlatGraph = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatGraph.finishFlatGraphBuffer = function(builder, offset) {
builder.finish(offset);
};
/**
* @constructor
*/
nd4j.graph.FlatDropRequest = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatDropRequest}
*/
nd4j.graph.FlatDropRequest.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatDropRequest=} obj
* @returns {nd4j.graph.FlatDropRequest}
*/
nd4j.graph.FlatDropRequest.getRootAsFlatDropRequest = function(bb, obj) {
return (obj || new nd4j.graph.FlatDropRequest).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatDropRequest.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatDropRequest.startFlatDropRequest = function(builder) {
builder.startObject(1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} id
*/
nd4j.graph.FlatDropRequest.addId = function(builder, id) {
builder.addFieldInt64(0, id, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatDropRequest.endFlatDropRequest = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @constructor
*/
nd4j.graph.FlatResponse = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatResponse}
*/
nd4j.graph.FlatResponse.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatResponse=} obj
* @returns {nd4j.graph.FlatResponse}
*/
nd4j.graph.FlatResponse.getRootAsFlatResponse = function(bb, obj) {
return (obj || new nd4j.graph.FlatResponse).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
nd4j.graph.FlatResponse.prototype.status = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatResponse.startFlatResponse = function(builder) {
builder.startObject(1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} status
*/
nd4j.graph.FlatResponse.addStatus = function(builder, status) {
builder.addFieldInt32(0, status, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatResponse.endFlatResponse = function(builder) {
var offset = builder.endObject();
return offset;
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,752 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @constructor
*/
nd4j.graph.FlatNode = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatNode}
*/
nd4j.graph.FlatNode.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatNode=} obj
* @returns {nd4j.graph.FlatNode}
*/
nd4j.graph.FlatNode.getRootAsFlatNode = function(bb, obj) {
return (obj || new nd4j.graph.FlatNode).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
nd4j.graph.FlatNode.prototype.name = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
};
/**
* @returns {nd4j.graph.OpType}
*/
nd4j.graph.FlatNode.prototype.opType = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** @type {nd4j.graph.OpType} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.OpType.TRANSFORM_FLOAT;
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatNode.prototype.opNum = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {number} index
* @param {nd4j.graph.FlatProperties=} obj
* @returns {nd4j.graph.FlatProperties}
*/
nd4j.graph.FlatNode.prototype.properties = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? (obj || new nd4j.graph.FlatProperties).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.propertiesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.input = function(index) {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.inputLength = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int32Array}
*/
nd4j.graph.FlatNode.prototype.inputArray = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @param {nd4j.graph.IntPair=} obj
* @returns {nd4j.graph.IntPair}
*/
nd4j.graph.FlatNode.prototype.inputPaired = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? (obj || new nd4j.graph.IntPair).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.inputPairedLength = function() {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.output = function(index) {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.outputLength = function() {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int32Array}
*/
nd4j.graph.FlatNode.prototype.outputArray = function() {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.extraParams = function(index) {
var offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.readFloat64(this.bb.__vector(this.bb_pos + offset) + index * 8) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.extraParamsLength = function() {
var offset = this.bb.__offset(this.bb_pos, 20);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Float64Array}
*/
nd4j.graph.FlatNode.prototype.extraParamsArray = function() {
var offset = this.bb.__offset(this.bb_pos, 20);
return offset ? new Float64Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatNode.prototype.extraInteger = function(index) {
var offset = this.bb.__offset(this.bb_pos, 22);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.extraIntegerLength = function() {
var offset = this.bb.__offset(this.bb_pos, 22);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {boolean}
*/
nd4j.graph.FlatNode.prototype.extraBools = function(index) {
var offset = this.bb.__offset(this.bb_pos, 24);
return offset ? !!this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : false;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.extraBoolsLength = function() {
var offset = this.bb.__offset(this.bb_pos, 24);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int8Array}
*/
nd4j.graph.FlatNode.prototype.extraBoolsArray = function() {
var offset = this.bb.__offset(this.bb_pos, 24);
return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.dimensions = function(index) {
var offset = this.bb.__offset(this.bb_pos, 26);
return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.dimensionsLength = function() {
var offset = this.bb.__offset(this.bb_pos, 26);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int32Array}
*/
nd4j.graph.FlatNode.prototype.dimensionsArray = function() {
var offset = this.bb.__offset(this.bb_pos, 26);
return offset ? new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.device = function() {
var offset = this.bb.__offset(this.bb_pos, 28);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.scopeId = function() {
var offset = this.bb.__offset(this.bb_pos, 30);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
nd4j.graph.FlatNode.prototype.scopeName = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 32);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
};
/**
* @param {number} index
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array}
*/
nd4j.graph.FlatNode.prototype.outputNames = function(index, optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 34);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.outputNamesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 34);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
nd4j.graph.FlatNode.prototype.opName = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 36);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
};
/**
* @param {number} index
* @returns {nd4j.graph.DataType}
*/
nd4j.graph.FlatNode.prototype.outputTypes = function(index) {
var offset = this.bb.__offset(this.bb_pos, 38);
return offset ? /** @type {nd4j.graph.DataType} */ (this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index)) : /** @type {nd4j.graph.DataType} */ (0);
};
/**
* @returns {number}
*/
nd4j.graph.FlatNode.prototype.outputTypesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 38);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int8Array}
*/
nd4j.graph.FlatNode.prototype.outputTypesArray = function() {
var offset = this.bb.__offset(this.bb_pos, 38);
return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {nd4j.graph.FlatArray=} obj
* @returns {nd4j.graph.FlatArray|null}
*/
nd4j.graph.FlatNode.prototype.scalar = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 40);
return offset ? (obj || new nd4j.graph.FlatArray).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatNode.startFlatNode = function(builder) {
builder.startObject(19);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} id
*/
nd4j.graph.FlatNode.addId = function(builder, id) {
builder.addFieldInt32(0, id, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} nameOffset
*/
nd4j.graph.FlatNode.addName = function(builder, nameOffset) {
builder.addFieldOffset(1, nameOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.OpType} opType
*/
nd4j.graph.FlatNode.addOpType = function(builder, opType) {
builder.addFieldInt8(2, opType, nd4j.graph.OpType.TRANSFORM_FLOAT);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} opNum
*/
nd4j.graph.FlatNode.addOpNum = function(builder, opNum) {
builder.addFieldInt64(3, opNum, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} propertiesOffset
*/
nd4j.graph.FlatNode.addProperties = function(builder, propertiesOffset) {
builder.addFieldOffset(4, propertiesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createPropertiesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startPropertiesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} inputOffset
*/
nd4j.graph.FlatNode.addInput = function(builder, inputOffset) {
builder.addFieldOffset(5, inputOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createInputVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startInputVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} inputPairedOffset
*/
nd4j.graph.FlatNode.addInputPaired = function(builder, inputPairedOffset) {
builder.addFieldOffset(6, inputPairedOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createInputPairedVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startInputPairedVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} outputOffset
*/
nd4j.graph.FlatNode.addOutput = function(builder, outputOffset) {
builder.addFieldOffset(7, outputOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createOutputVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startOutputVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} extraParamsOffset
*/
nd4j.graph.FlatNode.addExtraParams = function(builder, extraParamsOffset) {
builder.addFieldOffset(8, extraParamsOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createExtraParamsVector = function(builder, data) {
builder.startVector(8, data.length, 8);
for (var i = data.length - 1; i >= 0; i--) {
builder.addFloat64(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startExtraParamsVector = function(builder, numElems) {
builder.startVector(8, numElems, 8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} extraIntegerOffset
*/
nd4j.graph.FlatNode.addExtraInteger = function(builder, extraIntegerOffset) {
builder.addFieldOffset(9, extraIntegerOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Long>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createExtraIntegerVector = function(builder, data) {
builder.startVector(8, data.length, 8);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startExtraIntegerVector = function(builder, numElems) {
builder.startVector(8, numElems, 8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} extraBoolsOffset
*/
nd4j.graph.FlatNode.addExtraBools = function(builder, extraBoolsOffset) {
builder.addFieldOffset(10, extraBoolsOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<boolean>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createExtraBoolsVector = function(builder, data) {
builder.startVector(1, data.length, 1);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt8(+data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startExtraBoolsVector = function(builder, numElems) {
builder.startVector(1, numElems, 1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} dimensionsOffset
*/
nd4j.graph.FlatNode.addDimensions = function(builder, dimensionsOffset) {
builder.addFieldOffset(11, dimensionsOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createDimensionsVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startDimensionsVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} device
*/
nd4j.graph.FlatNode.addDevice = function(builder, device) {
builder.addFieldInt32(12, device, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} scopeId
*/
nd4j.graph.FlatNode.addScopeId = function(builder, scopeId) {
builder.addFieldInt32(13, scopeId, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} scopeNameOffset
*/
nd4j.graph.FlatNode.addScopeName = function(builder, scopeNameOffset) {
builder.addFieldOffset(14, scopeNameOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} outputNamesOffset
*/
nd4j.graph.FlatNode.addOutputNames = function(builder, outputNamesOffset) {
builder.addFieldOffset(15, outputNamesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createOutputNamesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startOutputNamesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} opNameOffset
*/
nd4j.graph.FlatNode.addOpName = function(builder, opNameOffset) {
builder.addFieldOffset(16, opNameOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} outputTypesOffset
*/
nd4j.graph.FlatNode.addOutputTypes = function(builder, outputTypesOffset) {
builder.addFieldOffset(17, outputTypesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<nd4j.graph.DataType>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.createOutputTypesVector = function(builder, data) {
builder.startVector(1, data.length, 1);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt8(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatNode.startOutputTypesVector = function(builder, numElems) {
builder.startVector(1, numElems, 1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} scalarOffset
*/
nd4j.graph.FlatNode.addScalar = function(builder, scalarOffset) {
builder.addFieldOffset(18, scalarOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatNode.endFlatNode = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatNode.finishFlatNodeBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,466 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @constructor
*/
nd4j.graph.FlatProperties = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatProperties}
*/
nd4j.graph.FlatProperties.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatProperties=} obj
* @returns {nd4j.graph.FlatProperties}
*/
nd4j.graph.FlatProperties.getRootAsFlatProperties = function(bb, obj) {
return (obj || new nd4j.graph.FlatProperties).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
nd4j.graph.FlatProperties.prototype.name = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.i = function(index) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.iLength = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int32Array}
*/
nd4j.graph.FlatProperties.prototype.iArray = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatProperties.prototype.l = function(index) {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.lLength = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.d = function(index) {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readFloat64(this.bb.__vector(this.bb_pos + offset) + index * 8) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.dLength = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Float64Array}
*/
nd4j.graph.FlatProperties.prototype.dArray = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? new Float64Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @param {nd4j.graph.FlatArray=} obj
* @returns {nd4j.graph.FlatArray}
*/
nd4j.graph.FlatProperties.prototype.a = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? (obj || new nd4j.graph.FlatArray).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.aLength = function() {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {boolean}
*/
nd4j.graph.FlatProperties.prototype.b = function(index) {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? !!this.bb.readInt8(this.bb.__vector(this.bb_pos + offset) + index) : false;
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.bLength = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int8Array}
*/
nd4j.graph.FlatProperties.prototype.bArray = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {number} index
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array}
*/
nd4j.graph.FlatProperties.prototype.s = function(index, optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__string(this.bb.__vector(this.bb_pos + offset) + index * 4, optionalEncoding) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.sLength = function() {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.shape = function(index) {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? this.bb.readInt32(this.bb.__vector(this.bb_pos + offset) + index * 4) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.FlatProperties.prototype.shapeLength = function() {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {Int32Array}
*/
nd4j.graph.FlatProperties.prototype.shapeArray = function() {
var offset = this.bb.__offset(this.bb_pos, 18);
return offset ? new Int32Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatProperties.startFlatProperties = function(builder) {
builder.startObject(8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} nameOffset
*/
nd4j.graph.FlatProperties.addName = function(builder, nameOffset) {
builder.addFieldOffset(0, nameOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} iOffset
*/
nd4j.graph.FlatProperties.addI = function(builder, iOffset) {
builder.addFieldOffset(1, iOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createIVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startIVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} lOffset
*/
nd4j.graph.FlatProperties.addL = function(builder, lOffset) {
builder.addFieldOffset(2, lOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Long>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createLVector = function(builder, data) {
builder.startVector(8, data.length, 8);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startLVector = function(builder, numElems) {
builder.startVector(8, numElems, 8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} dOffset
*/
nd4j.graph.FlatProperties.addD = function(builder, dOffset) {
builder.addFieldOffset(3, dOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createDVector = function(builder, data) {
builder.startVector(8, data.length, 8);
for (var i = data.length - 1; i >= 0; i--) {
builder.addFloat64(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startDVector = function(builder, numElems) {
builder.startVector(8, numElems, 8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} aOffset
*/
nd4j.graph.FlatProperties.addA = function(builder, aOffset) {
builder.addFieldOffset(4, aOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createAVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startAVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} bOffset
*/
nd4j.graph.FlatProperties.addB = function(builder, bOffset) {
builder.addFieldOffset(5, bOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<boolean>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createBVector = function(builder, data) {
builder.startVector(1, data.length, 1);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt8(+data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startBVector = function(builder, numElems) {
builder.startVector(1, numElems, 1);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} sOffset
*/
nd4j.graph.FlatProperties.addS = function(builder, sOffset) {
builder.addFieldOffset(6, sOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createSVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startSVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} shapeOffset
*/
nd4j.graph.FlatProperties.addShape = function(builder, shapeOffset) {
builder.addFieldOffset(7, shapeOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<number>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.createShapeVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt32(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatProperties.startShapeVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatProperties.endFlatProperties = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatProperties.finishFlatPropertiesBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,173 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @constructor
*/
nd4j.graph.FlatInferenceRequest = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatInferenceRequest}
*/
nd4j.graph.FlatInferenceRequest.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatInferenceRequest=} obj
* @returns {nd4j.graph.FlatInferenceRequest}
*/
nd4j.graph.FlatInferenceRequest.getRootAsFlatInferenceRequest = function(bb, obj) {
return (obj || new nd4j.graph.FlatInferenceRequest).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatInferenceRequest.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {number} index
* @param {nd4j.graph.FlatVariable=} obj
* @returns {nd4j.graph.FlatVariable}
*/
nd4j.graph.FlatInferenceRequest.prototype.variables = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new nd4j.graph.FlatVariable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatInferenceRequest.prototype.variablesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {nd4j.graph.FlatConfiguration=} obj
* @returns {nd4j.graph.FlatConfiguration|null}
*/
nd4j.graph.FlatInferenceRequest.prototype.configuration = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new nd4j.graph.FlatConfiguration).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatInferenceRequest.startFlatInferenceRequest = function(builder) {
builder.startObject(3);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} id
*/
nd4j.graph.FlatInferenceRequest.addId = function(builder, id) {
builder.addFieldInt64(0, id, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} variablesOffset
*/
nd4j.graph.FlatInferenceRequest.addVariables = function(builder, variablesOffset) {
builder.addFieldOffset(1, variablesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatInferenceRequest.createVariablesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatInferenceRequest.startVariablesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} configurationOffset
*/
nd4j.graph.FlatInferenceRequest.addConfiguration = function(builder, configurationOffset) {
builder.addFieldOffset(2, configurationOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatInferenceRequest.endFlatInferenceRequest = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatInferenceRequest.finishFlatInferenceRequestBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,336 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @constructor
*/
nd4j.graph.FlatTiming = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatTiming}
*/
nd4j.graph.FlatTiming.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatTiming=} obj
* @returns {nd4j.graph.FlatTiming}
*/
nd4j.graph.FlatTiming.getRootAsFlatTiming = function(bb, obj) {
return (obj || new nd4j.graph.FlatTiming).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
nd4j.graph.FlatTiming.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
nd4j.graph.FlatTiming.prototype.name = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
};
/**
* @param {nd4j.graph.LongPair=} obj
* @returns {nd4j.graph.LongPair|null}
*/
nd4j.graph.FlatTiming.prototype.timing = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new nd4j.graph.LongPair).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatTiming.startFlatTiming = function(builder) {
builder.startObject(3);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} id
*/
nd4j.graph.FlatTiming.addId = function(builder, id) {
builder.addFieldInt32(0, id, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} nameOffset
*/
nd4j.graph.FlatTiming.addName = function(builder, nameOffset) {
builder.addFieldOffset(1, nameOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} timingOffset
*/
nd4j.graph.FlatTiming.addTiming = function(builder, timingOffset) {
builder.addFieldOffset(2, timingOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatTiming.endFlatTiming = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @constructor
*/
nd4j.graph.FlatResult = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatResult}
*/
nd4j.graph.FlatResult.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatResult=} obj
* @returns {nd4j.graph.FlatResult}
*/
nd4j.graph.FlatResult.getRootAsFlatResult = function(bb, obj) {
return (obj || new nd4j.graph.FlatResult).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatResult.prototype.id = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {number} index
* @param {nd4j.graph.FlatVariable=} obj
* @returns {nd4j.graph.FlatVariable}
*/
nd4j.graph.FlatResult.prototype.variables = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? (obj || new nd4j.graph.FlatVariable).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatResult.prototype.variablesLength = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {number} index
* @param {nd4j.graph.FlatTiming=} obj
* @returns {nd4j.graph.FlatTiming}
*/
nd4j.graph.FlatResult.prototype.timing = function(index, obj) {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? (obj || new nd4j.graph.FlatTiming).__init(this.bb.__indirect(this.bb.__vector(this.bb_pos + offset) + index * 4), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatResult.prototype.timingLength = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatResult.prototype.footprintForward = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatResult.prototype.footprintBackward = function() {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatResult.startFlatResult = function(builder) {
builder.startObject(5);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} id
*/
nd4j.graph.FlatResult.addId = function(builder, id) {
builder.addFieldInt64(0, id, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} variablesOffset
*/
nd4j.graph.FlatResult.addVariables = function(builder, variablesOffset) {
builder.addFieldOffset(1, variablesOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatResult.createVariablesVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatResult.startVariablesVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} timingOffset
*/
nd4j.graph.FlatResult.addTiming = function(builder, timingOffset) {
builder.addFieldOffset(2, timingOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Offset>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatResult.createTimingVector = function(builder, data) {
builder.startVector(4, data.length, 4);
for (var i = data.length - 1; i >= 0; i--) {
builder.addOffset(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatResult.startTimingVector = function(builder, numElems) {
builder.startVector(4, numElems, 4);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} footprintForward
*/
nd4j.graph.FlatResult.addFootprintForward = function(builder, footprintForward) {
builder.addFieldInt64(3, footprintForward, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} footprintBackward
*/
nd4j.graph.FlatResult.addFootprintBackward = function(builder, footprintBackward) {
builder.addFieldInt64(4, footprintBackward, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatResult.endFlatResult = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatResult.finishFlatResultBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,453 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @enum
*/
nd4j.graph.OpType = {
TRANSFORM_FLOAT: 0,
TRANSFORM_SAME: 1,
TRANSFORM_BOOL: 2,
TRANSFORM_STRICT: 3,
TRANSFORM_ANY: 4,
REDUCE_FLOAT: 5,
REDUCE_SAME: 6,
REDUCE_LONG: 7,
REDUCE_BOOL: 8,
INDEX_REDUCE: 9,
SCALAR: 10,
SCALAR_BOOL: 11,
BROADCAST: 12,
BROADCAST_BOOL: 13,
PAIRWISE: 14,
PAIRWISE_BOOL: 15,
REDUCE_3: 16,
SUMMARYSTATS: 17,
SHAPE: 18,
AGGREGATION: 19,
RANDOM: 20,
CUSTOM: 21,
GRAPH: 22,
VARIABLE: 40,
BOOLEAN: 60,
LOGIC: 119
};
/**
* @enum
*/
nd4j.graph.InputType = {
UNDEFINED: 0,
NUMERIC: 1,
STRINGULAR: 2,
NUMERIC_SET: 3,
STRINGULAR_SET: 4
};
/**
* @enum
*/
nd4j.graph.OpClass = {
TRANSFORM: 0,
REDUCTION: 1,
MULTIPLICATOR: 2,
GRAPH: 3,
CONDITIONAL: 4,
LOOP: 5
};
/**
* @constructor
*/
nd4j.graph.LongPair = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.LongPair}
*/
nd4j.graph.LongPair.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.LongPair=} obj
* @returns {nd4j.graph.LongPair}
*/
nd4j.graph.LongPair.getRootAsLongPair = function(bb, obj) {
return (obj || new nd4j.graph.LongPair).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.LongPair.prototype.first = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.LongPair.prototype.second = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.LongPair.startLongPair = function(builder) {
builder.startObject(2);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} first
*/
nd4j.graph.LongPair.addFirst = function(builder, first) {
builder.addFieldInt64(0, first, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} second
*/
nd4j.graph.LongPair.addSecond = function(builder, second) {
builder.addFieldInt64(1, second, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.LongPair.endLongPair = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @constructor
*/
nd4j.graph.LongTriple = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.LongTriple}
*/
nd4j.graph.LongTriple.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.LongTriple=} obj
* @returns {nd4j.graph.LongTriple}
*/
nd4j.graph.LongTriple.getRootAsLongTriple = function(bb, obj) {
return (obj || new nd4j.graph.LongTriple).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.LongTriple.prototype.first = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.LongTriple.prototype.second = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @returns {flatbuffers.Long}
*/
nd4j.graph.LongTriple.prototype.third = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.readInt64(this.bb_pos + offset) : this.bb.createLong(0, 0);
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.LongTriple.startLongTriple = function(builder) {
builder.startObject(3);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} first
*/
nd4j.graph.LongTriple.addFirst = function(builder, first) {
builder.addFieldInt64(0, first, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} second
*/
nd4j.graph.LongTriple.addSecond = function(builder, second) {
builder.addFieldInt64(1, second, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Long} third
*/
nd4j.graph.LongTriple.addThird = function(builder, third) {
builder.addFieldInt64(2, third, builder.createLong(0, 0));
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.LongTriple.endLongTriple = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @constructor
*/
nd4j.graph.IntPair = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.IntPair}
*/
nd4j.graph.IntPair.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.IntPair=} obj
* @returns {nd4j.graph.IntPair}
*/
nd4j.graph.IntPair.getRootAsIntPair = function(bb, obj) {
return (obj || new nd4j.graph.IntPair).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
nd4j.graph.IntPair.prototype.first = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.IntPair.prototype.second = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.IntPair.startIntPair = function(builder) {
builder.startObject(2);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} first
*/
nd4j.graph.IntPair.addFirst = function(builder, first) {
builder.addFieldInt32(0, first, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} second
*/
nd4j.graph.IntPair.addSecond = function(builder, second) {
builder.addFieldInt32(1, second, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.IntPair.endIntPair = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @constructor
*/
nd4j.graph.IntTriple = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.IntTriple}
*/
nd4j.graph.IntTriple.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.IntTriple=} obj
* @returns {nd4j.graph.IntTriple}
*/
nd4j.graph.IntTriple.getRootAsIntTriple = function(bb, obj) {
return (obj || new nd4j.graph.IntTriple).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @returns {number}
*/
nd4j.graph.IntTriple.prototype.first = function() {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.IntTriple.prototype.second = function() {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @returns {number}
*/
nd4j.graph.IntTriple.prototype.third = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.IntTriple.startIntTriple = function(builder) {
builder.startObject(3);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} first
*/
nd4j.graph.IntTriple.addFirst = function(builder, first) {
builder.addFieldInt32(0, first, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} second
*/
nd4j.graph.IntTriple.addSecond = function(builder, second) {
builder.addFieldInt32(1, second, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} third
*/
nd4j.graph.IntTriple.addThird = function(builder, third) {
builder.addFieldInt32(2, third, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.IntTriple.endIntTriple = function(builder) {
var offset = builder.endObject();
return offset;
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,248 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
/**
* @const
* @namespace
*/
var nd4j = nd4j || {};
/**
* @const
* @namespace
*/
nd4j.graph = nd4j.graph || {};
/**
* @enum
*/
nd4j.graph.VarType = {
VARIABLE: 0,
CONSTANT: 1,
ARRAY: 2,
PLACEHOLDER: 3
};
/**
* @constructor
*/
nd4j.graph.FlatVariable = function() {
/**
* @type {flatbuffers.ByteBuffer}
*/
this.bb = null;
/**
* @type {number}
*/
this.bb_pos = 0;
};
/**
* @param {number} i
* @param {flatbuffers.ByteBuffer} bb
* @returns {nd4j.graph.FlatVariable}
*/
nd4j.graph.FlatVariable.prototype.__init = function(i, bb) {
this.bb_pos = i;
this.bb = bb;
return this;
};
/**
* @param {flatbuffers.ByteBuffer} bb
* @param {nd4j.graph.FlatVariable=} obj
* @returns {nd4j.graph.FlatVariable}
*/
nd4j.graph.FlatVariable.getRootAsFlatVariable = function(bb, obj) {
return (obj || new nd4j.graph.FlatVariable).__init(bb.readInt32(bb.position()) + bb.position(), bb);
};
/**
* @param {nd4j.graph.IntPair=} obj
* @returns {nd4j.graph.IntPair|null}
*/
nd4j.graph.FlatVariable.prototype.id = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 4);
return offset ? (obj || new nd4j.graph.IntPair).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @param {flatbuffers.Encoding=} optionalEncoding
* @returns {string|Uint8Array|null}
*/
nd4j.graph.FlatVariable.prototype.name = function(optionalEncoding) {
var offset = this.bb.__offset(this.bb_pos, 6);
return offset ? this.bb.__string(this.bb_pos + offset, optionalEncoding) : null;
};
/**
* @returns {nd4j.graph.DataType}
*/
nd4j.graph.FlatVariable.prototype.dtype = function() {
var offset = this.bb.__offset(this.bb_pos, 8);
return offset ? /** @type {nd4j.graph.DataType} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.DataType.INHERIT;
};
/**
* @param {number} index
* @returns {flatbuffers.Long}
*/
nd4j.graph.FlatVariable.prototype.shape = function(index) {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.readInt64(this.bb.__vector(this.bb_pos + offset) + index * 8) : this.bb.createLong(0, 0);
};
/**
* @returns {number}
*/
nd4j.graph.FlatVariable.prototype.shapeLength = function() {
var offset = this.bb.__offset(this.bb_pos, 10);
return offset ? this.bb.__vector_len(this.bb_pos + offset) : 0;
};
/**
* @param {nd4j.graph.FlatArray=} obj
* @returns {nd4j.graph.FlatArray|null}
*/
nd4j.graph.FlatVariable.prototype.ndarray = function(obj) {
var offset = this.bb.__offset(this.bb_pos, 12);
return offset ? (obj || new nd4j.graph.FlatArray).__init(this.bb.__indirect(this.bb_pos + offset), this.bb) : null;
};
/**
* @returns {number}
*/
nd4j.graph.FlatVariable.prototype.device = function() {
var offset = this.bb.__offset(this.bb_pos, 14);
return offset ? this.bb.readInt32(this.bb_pos + offset) : 0;
};
/**
* @returns {nd4j.graph.VarType}
*/
nd4j.graph.FlatVariable.prototype.variabletype = function() {
var offset = this.bb.__offset(this.bb_pos, 16);
return offset ? /** @type {nd4j.graph.VarType} */ (this.bb.readInt8(this.bb_pos + offset)) : nd4j.graph.VarType.VARIABLE;
};
/**
* @param {flatbuffers.Builder} builder
*/
nd4j.graph.FlatVariable.startFlatVariable = function(builder) {
builder.startObject(7);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} idOffset
*/
nd4j.graph.FlatVariable.addId = function(builder, idOffset) {
builder.addFieldOffset(0, idOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} nameOffset
*/
nd4j.graph.FlatVariable.addName = function(builder, nameOffset) {
builder.addFieldOffset(1, nameOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.DataType} dtype
*/
nd4j.graph.FlatVariable.addDtype = function(builder, dtype) {
builder.addFieldInt8(2, dtype, nd4j.graph.DataType.INHERIT);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} shapeOffset
*/
nd4j.graph.FlatVariable.addShape = function(builder, shapeOffset) {
builder.addFieldOffset(3, shapeOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {Array.<flatbuffers.Long>} data
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatVariable.createShapeVector = function(builder, data) {
builder.startVector(8, data.length, 8);
for (var i = data.length - 1; i >= 0; i--) {
builder.addInt64(data[i]);
}
return builder.endVector();
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} numElems
*/
nd4j.graph.FlatVariable.startShapeVector = function(builder, numElems) {
builder.startVector(8, numElems, 8);
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} ndarrayOffset
*/
nd4j.graph.FlatVariable.addNdarray = function(builder, ndarrayOffset) {
builder.addFieldOffset(4, ndarrayOffset, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {number} device
*/
nd4j.graph.FlatVariable.addDevice = function(builder, device) {
builder.addFieldInt32(5, device, 0);
};
/**
* @param {flatbuffers.Builder} builder
* @param {nd4j.graph.VarType} variabletype
*/
nd4j.graph.FlatVariable.addVariabletype = function(builder, variabletype) {
builder.addFieldInt8(6, variabletype, nd4j.graph.VarType.VARIABLE);
};
/**
* @param {flatbuffers.Builder} builder
* @returns {flatbuffers.Offset}
*/
nd4j.graph.FlatVariable.endFlatVariable = function(builder) {
var offset = builder.endObject();
return offset;
};
/**
* @param {flatbuffers.Builder} builder
* @param {flatbuffers.Offset} offset
*/
nd4j.graph.FlatVariable.finishFlatVariableBuffer = function(builder, offset) {
builder.finish(offset);
};
// Exports for Node.js and RequireJS
this.nd4j = nd4j;
@@ -0,0 +1,198 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function renderSameDiffGraph() {
document.getElementById("samediffcontent").innerHTML = "<div id=\"graphdiv\" style=\"height: 100%; width: 100%; display: table\"></div>";
if (sdGraphNodes) {
cy = cytoscape({
container: document.getElementById('graphdiv'), // container to render in
layout: {
name: samediffgraphlayout,
padding: 10,
klay : {
direction: klaylayout
}
},
elements: {
nodes: sdGraphNodes,
edges: sdGraphEdges
},
style: fetch('/assets/js/samediff/cytoscape-style.json').then(function(res){
return res.json();
}),
wheelSensitivity: 0.2
});
// cy.nodes().on("click", function(e){
// var clickedNode = e.target;
// console.log("Clicked node: " + clickedNode);
// });
// cy.nodes().once('click', function(e){
// var ele = e.target;
// console.log('clicked ' + ele.id());
// });
cy.on('click', 'node', function(e){
var ele = e.target;
console.log('clicked ' + ele.id());
onGraphNodeClick(ele.id());
});
}
}
function onGraphNodeClick(/*String*/ node){
var element = $("#sidebarmid");
var nodeId = idRestoreSlashes(node); //"while__Enter" -> "while/Enter"
//Next, find all inputs and outputs...
var type = "-";
var extra = "";
var name = "";
if(nodeId.startsWith("var-")){
name = nodeId.substring(4);
if(sdGraphVariableMap.has(name)){
type = "Variable";
var v = sdGraphVariableMap.get(name);
type = varTypeToString(v.type());
var dtype = dataTypeToString(v.datatype());
var shape = varShapeToString(v);
extra = "<b>Data type:</b> " + dtype + "<br><b>Shape:</b> " + shape;
}
} else {
type = "Op";
name = nodeId;
var op = sdGraphOpsMap.get(name); //Map<String,nd4j.graph.UIOp>
var inVars = [];
for( var i=0; i<op.inputsLength(); i++ ){
var inName = op.inputs(i);
var inVar = sdGraphVariableMap.get(inName); //nd4j.graph.UIVariable
var outputOfOpName = inVar.outputOfOp();
var pre = "";
var post = "";
if(outputOfOpName != null && outputOfOpName !== ""){
// var op = sdGraphOpsMap.get(outputOfOpName);
pre = "<span onclick='onGraphNodeClick(\"" + outputOfOpName + "\");centerViewOnNode(\"" + outputOfOpName + "\");'>";
post = "</span>";
} else {
//Not the output of an op, therefore must be a variable node
pre = "<span onclick='onGraphNodeClick(\"var-" + inName + "\");centerViewOnNode(\"var-" + inName + "\");'>";
post = "</span>";
}
var dtype = dataTypeToString(inVar.datatype());
var shape = varShapeToString(inVar);
inVars.push(pre + inName + " (" + dtype + (shape == null || shape === "" ? "" : "," + shape ) + ")" + post);
}
var outVars = [];
// var outVarsStr = "";
var inputsForOps = new Set();
var len = op.outputsLength();
for( var i=0; i<len; i++ ){
var outName = op.outputs(i);
var outVar = sdGraphVariableMap.get(outName); //nd4j.graph.UIVariable
var dtype = dataTypeToString(outVar.datatype());
var shape = varShapeToString(outVar);
outVars.push(outName + " (" + dtype + (shape == null || shape === "" ? "" : "," + shape) + ")");
// outVarsStr = outVarsStr + op.inputs(i) + "<br>";
var inputsForLength = outVar.inputsForOpLength();
for( var j=0; j<inputsForLength; j++ ){
var outOpName = outVar.inputsForOp(j);
inputsForOps.add(outOpName);
}
}
var outOpStr = "";
inputsForOps = Array.from(inputsForOps);
for(var i=0; i<inputsForOps.length; i++ ){
var s = inputsForOps[i];
outOpStr = outOpStr + "<span onclick='onGraphNodeClick(\"" + s + "\");centerViewOnNode(\"" + s + "\");'>" + s + "</span><br>";
}
extra = "<b>Op Name:</b> " + op.opName() + "<br>" +
"<b>Input Variables:</b><br>" +
inVars.join("<br>") + "<br>" +
"<b>Output Variables:</b> " + "" + "<br>" +
outVars.join("<br>") + "<br>" +
"<b>Inputs For Ops:</b><br>" + outOpStr;
}
document.getElementById("sidebarmid-content").innerHTML =
"<b>Name:</b> " + name + "<br>" +
"<b>Type:</b> " + type + "<br>" +
extra;
}
function onGraphNodeSearch(){
var value = document.getElementById("findnodetxt").value;
var results = [];
if(value != null && value !== ""){
// for( var v in values ){
// while(values.hasNe)
for(var i=0; i<sdGraphOpsList.length; i++ ){
var op = sdGraphOpsList[i];
var name = op.name();
if(name.includes(value)){
results.push(name);
}
}
//Also contant/placeholder/variable variables (these are rendered as nodes in graph)
for(var i=0; i<sdGraphVariableNames.length; i++ ){
var n = sdGraphVariableNames[i];
var vType = sdGraphVariableMap.get(n).type();
if (vType === nd4j.graph.VarType.CONSTANT || vType === nd4j.graph.VarType.PLACEHOLDER || vType === nd4j.graph.VarType.VARIABLE) {
if(n.includes(value)){
results.push(n);
}
}
}
}
var listHtml = "<ul>\n";
for( var i=0; i<results.length; i++ ){
listHtml = listHtml + "<li onclick='centerViewOnNode(\"" + results[i] + "\")'>" + results[i] + "</li>\n";
}
listHtml = listHtml + "</ul>";
document.getElementById("findnoderesults").innerHTML = listHtml;
}
function centerViewOnNode(/*String*/ clicked ){
//Find the node, and center the view on it
// var node = cy.$("#" + clicked); //"The selector `#while/Enter`is invalid"
var id = idEscapeSlashes(clicked);
if(sdGraphVariableMap.has(id)){
id = "var-" + id;
}
var node = cy.$('#' + id);
cy.center(node);
}
@@ -0,0 +1,299 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function renderLineChart(/*jquery selector*/ element, label, xDataArray, yDataArray ){
var toPlot = [];
for(var i=0; i<xDataArray.length; i++ ){
toPlot.push([xDataArray[i], yDataArray[i]]);
}
element.unbind();
var yMax = Math.max.apply(Math, yDataArray);
var yMin = Math.min.apply(Math, yDataArray);
if(yMin > 0){
yMin = 0.0;
}
var plotOptions = {
series: {
lines: {
show: true,
lineWidth: 2
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: yMin, max: yMax},
colors: ["#FA5833","rgba(65,182,240,0.3)","#000000"],
selection: {
mode: "x"
}
};
var plotData = [{data: toPlot, label: label}];
var plot = $.plot(element, plotData, plotOptions);
}
function renderHistogramSingle(/*jquery selector*/ element, label, /*nd4j.graph.UIEvent*/ evt, /*nd4j.graph.UIHistogram*/ h){
if(evt == null || h == null){
return;
}
//Histogram rendering:
var data = [];
var y = h.y();
if(h.type() === nd4j.graph.UIHistogramType.EQUAL_SPACING){
var minmaxArr = h.binranges(); //Rank 1, size 2
var min = scalarFromFlatArrayIdx(minmaxArr, 0);
var max = scalarFromFlatArrayIdx(minmaxArr, 1);
var numBins = h.numbins();
//Render this as a line chart for now. Could do this as a bar chart instead, but this provides precise control...
var step = (max-min)/numBins;
for(var i=0; i<numBins; i++ ){
var lower = min + step * i;
var upper = lower + step;
var yValue = scalarFromFlatArrayIdx(y, i);
data.push([lower,0]);
data.push([lower,yValue]);
data.push([upper,yValue]);
data.push([upper,0]);
}
} else if(h.type() === nd4j.graph.UIHistogramType.DISCRETE){
var binLabelsCount = h.binlabelsLength();
var lbl = [];
for(var i=0; i<binLabelsCount; i++ ){
lbl.push(h.binlabels(i));
}
var min = 0;
var max = 1;
var numBins = lbl.length;
//Render this as a line chart for now. Could do this as a bar chart instead, but this provides precise control...
var step = (max-min)/numBins;
for(var i=0; i<numBins; i++ ){
var lower = min + step * i;
var upper = lower + step;
var yValue = scalarFromFlatArrayIdx(y, i);
data.push([lower,0]);
data.push([lower,yValue]);
data.push([upper,yValue]);
data.push([upper,0]);
}
} else if(h.type() === nd4j.graph.UIHistogramType.CUSTOM){
var minmaxArr = h.binranges(); //Rank 2, shape [2,numBins]
var numBins = h.numbins();
for(var i=0; i<numBins; i++ ){
var lower = getScalar(minmaxArr, [0, i]);
var upper = getScalar(minmaxArr, [1, i]);
var yValue = scalarFromFlatArrayIdx(y, i);
data.push([lower,0]);
data.push([lower,yValue]);
data.push([upper,yValue]);
data.push([upper,0]);
}
}
var plotData = [{data: data, label: label, lines: { show: true, fill: true }}];
$.plot(element, plotData)
}
var sdEventNamesMap = new Map(); //Map<Integer,String> - key is name index, value is name
var sdPlotsLineChartX = new Map(); //Map<String,nd4j.graph.UIEvent>
var sdPlotsLineChartY = new Map(); //Map<String,Number[]>
var sdPlotsHistogramX = new Map(); //Map<String,nd4j.graph.UIEvent>
var sdPlotsHistogramY = new Map(); //Map<String,nd4j.graph.UIHistogram>
function readAndRenderPlotsData(){
if (file) {
var fr = new FileReader();
var fileData = new Blob([file]); //TODO Don't load the whole file into memory at once!
fr.readAsArrayBuffer(fileData);
fr.onload = function () {
var arrayBuffer = fr.result;
var bytes = new Uint8Array(arrayBuffer);
//console.log(bytes);
var currentOffset = 0;
var foundStartEvents = false;
var numBytes = bytes.length;
while(currentOffset < numBytes) {
var lengths = extractHeaders(bytes, currentOffset);
var headerLength = lengths[0];
var contentLength = lengths[1];
//TODO is there a way to do this with views, not slices?
var headerSlice = bytes.slice(currentOffset + 8, currentOffset + 8 + headerLength);
var headerBuffer = new flatbuffers.ByteBuffer(headerSlice);
var header = nd4j.graph.UIStaticInfoRecord.getRootAsUIStaticInfoRecord(headerBuffer);
currentOffset += 8 + headerLength + contentLength;
if(header.infoType() == nd4j.graph.UIInfoType.START_EVENTS){
foundStartEvents = true;
break;
}
}
if(foundStartEvents){
//"Start events" marker found... we *might* have some data to plot
sdEventNamesMap = new Map();
sdPlotsLineChartsX = new Map();
sdPlotLineChartsY = new Map();
while(currentOffset < numBytes) {
var lengths = extractHeaders(bytes, currentOffset);
var headerLength = lengths[0];
var contentLength = lengths[1];
var headerSlice = bytes.slice(currentOffset + 8, currentOffset + 8 + headerLength);
var headerBuffer = new flatbuffers.ByteBuffer(headerSlice);
var header = nd4j.graph.UIEvent.getRootAsUIEvent(headerBuffer);
//TODO only slice if it's something we want to decode...
var contentSlice = bytes.slice(currentOffset + 8 + headerLength, currentOffset + 8 + headerLength + contentLength);
var contentBuffer = new flatbuffers.ByteBuffer(contentSlice);
var nameId = header.nameIdx();
var evtType = header.eventType();
if(evtType === nd4j.graph.UIEventType.ADD_NAME){
var content = nd4j.graph.UIAddName.getRootAsUIAddName(contentBuffer);
console.log("Decoded ADD_NAME event: " + content.name());
var name = content.name();
var nameIdx = content.nameIdx();
sdEventNamesMap.set(nameIdx, name);
} else if(evtType === nd4j.graph.UIEventType.SCALAR){
var content = nd4j.graph.FlatArray.getRootAsFlatArray(contentBuffer);
var name = sdEventNamesMap.get(nameId);
var scalar = scalarFromFlatArray(content);
var dt = dataTypeToString(content.dtype());
// console.log("Decoded SCALAR event: " + scalar + " - " + dt);
if(!sdPlotsLineChartX.has(name)){
sdPlotsLineChartX.set(name, []);
sdPlotsLineChartY.set(name, []);
}
sdPlotsLineChartX.get(name).push(header);
sdPlotsLineChartY.get(name).push(scalar);
} else if(evtType === nd4j.graph.UIEventType.HISTOGRAM){
var content = nd4j.graph.UIHistogram.getRootAsUIHistogram(contentBuffer);
var name = sdEventNamesMap.get(nameId);
if(!sdPlotsHistogramX.has(name)){
sdPlotsHistogramX.set(name, []);
sdPlotsHistogramY.set(name, []);
}
sdPlotsHistogramX.get(name).push(header);
sdPlotsHistogramY.get(name).push(content);
}
//TODO other types!
currentOffset += 8 + headerLength + contentLength;
}
}
};
renderLineCharts();
renderHistograms();
}
}
function renderLineCharts(){
var contentDiv = $("#samediffcontent");
//List available charts, histograms, etc:
var lineChartKeys = Array.from(sdPlotsLineChartX.keys());
console.log("Line chart keys: " + lineChartKeys);
var content1 = "<div><b>Scalars Values</b>:\n" + lineChartKeys.join("\n") + "<br><br></div>";
contentDiv.html(content1);
for( var i=0; i<lineChartKeys.length; i++ ) {
var chartName = "sdLineChart_" + i;
var chartDivTxt = "\n<div id=\"" + chartName + "\" class=\"center\" style=\"height: 300px; max-width:750px\" ></div>";
contentDiv.append(chartDivTxt);
var element = $("#" + chartName);
var label = lineChartKeys[i];
var x = sdPlotsLineChartX.get(label); //nd4j.graph.UIEvent
var y = sdPlotsLineChartY.get(label);
//Parse to iteration. We'll want to make this customizable eventually (iteration, time, etc)
var xPlot = [];
for( var j=0; j<x.length; j++ ){
var iter = x[j].iteration();
xPlot.push(iter);
}
renderLineChart(element, label, xPlot, y);
}
}
function renderHistograms(){
var contentDiv = $("#samediffcontent");
var content1 = "<br><br><div><b>Histograms</b>: TODO<br><br></div>";
contentDiv.append(content1);
var keys = Array.from(sdPlotsHistogramX.keys());
console.log("Histogram keys: " + keys);
for( var i=0; i<keys.length; i++ ){
var chartName = "sdHistogram_" + i;
var chartDivTxt = "\n<div id=\"" + chartName + "\" class=\"center\" style=\"height: 300px; max-width:750px\" ></div>";
contentDiv.append(chartDivTxt);
var element = $("#" + chartName);
var label = keys[i];
var x = sdPlotsHistogramX.get(label); //nd4j.graph.UIEvent
var hist = sdPlotsHistogramY.get(label); //nd4j.graph.UIHistogram
var h = null;
var evt = null;
if(hist.length > 0){
evt = x[x.length-1];
h = hist[hist.length-1];
}
//Parse to iteration. We'll want to make this customizable eventually (iteration, time, etc)
var xPlot = [];
for( var j=0; j<x.length; j++ ){
var iter = x[j].iteration();
xPlot.push(iter);
}
renderHistogramSingle(element, label, evt, h);
}
}
@@ -0,0 +1,442 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function toggleSidebar(){
$('#samediffsidebar').toggleClass('sidebarhidden');
}
var selectedPage = "graph";
function samediffSetPage(pageName){
$("#sdnavgraph").removeClass("active");
$("#sdnavplots").removeClass("active");
$("#sdnaveval").removeClass("active");
$("#sdnavperf").removeClass("active");
switch(pageName){
case "graph":
$("#sdnavgraph").addClass("active");
break;
case "plots":
$("#sdnavplots").addClass("active");
break;
case "evaluation":
$("#sdnaveval").addClass("active");
break;
case "performance":
$("#sdnavperf").addClass("active");
break;
}
console.log("Selected page: " + pageName);
selectedPage = pageName;
renderContent();
}
sdGraphNodes = [];
sdGraphEdges = [];
sdGraphInputs = [];
sdGraphOutputs = [];
sdGraphVariables = [];
sdGraphVariableNames = [];
sdGraphOpsList = [];
sdGraphOpsMap = new Map();
sdGraphVariableMap = new Map();
function fileSelect(evt) {
var output = [];
file = evt.target.files[0];
output.push('<li><strong>', escape(file.name), '</strong> (', file.type || 'n/a', ') - ',
file.size, ' bytes, last modified: ',
file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() : 'n/a',
'</li>');
document.getElementById('selectedfile').innerHTML = "<strong>" + escape(file.name) + "</strong><br>" + file.size + " bytes<br>Modified: " +
(file.lastModifiedDate ? file.lastModifiedDate.toLocaleDateString() : 'n/a');
console.log("About to render graph: file " + file.name);
readGraphStructure();
}
function readGraphStructure(){
//First: load data
if (file) {
var fr = new FileReader();
var fileData = new Blob([file]); //TODO Don't load the whole file into memory at once!
fr.readAsArrayBuffer(fileData);
fr.onload = function () {
var arrayBuffer = fr.result;
var bytes = new Uint8Array(arrayBuffer);
//console.log(bytes);
var lengths = extractHeaders(bytes, 0);
var headerLength = lengths[0];
var contentLength = lengths[1];
// console.log("Header/content lengths: " + headerLength + ", " + contentLength);
//https://gist.github.com/alexvictoor/0b76764857b780ad8f83
var headerSlice = bytes.slice(8, 8 + headerLength);
var contentSlice = bytes.slice(8 + headerLength, 8 + headerLength + contentLength);
var decoded = decodeStaticInfo(headerSlice, contentSlice);
// console.log("Decoded header message: " + decoded[0]);
if (decoded[0] === "graph") {
var opCount = 0;
var phCount = 0;
var varCount = 0;
var constCount = 0;
sdGraphNodes.length = 0;
sdGraphEdges.length = 0;
var graph = decoded[1];
sdGraphInputs = uiGraphGetInputs(graph);
sdGraphOutputs = uiGraphGetOutputs(graph);
sdGraphVariables = uiGraphGetVariables(graph);
sdGraphVariableNames = uiGraphGetVariableNames(graph);
sdGraphOpsList = uiGraphGetOps(graph);
console.log("Inputs: " + sdGraphInputs);
console.log("Outputs: " + sdGraphOutputs);
console.log("Variables: " + sdGraphVariableNames);
console.log("Ops: " + sdGraphOpsList);
var mapVarNameInteger = new Map();
sdGraphVariableMap = new Map(); //Key: variable name, value: variable
var count = 0;
for (var i = 0; i < sdGraphVariables.length; i++) {
var v = sdGraphVariables[i];
var name = v.name();
mapVarNameInteger.set(count, name);
sdGraphVariableMap.set(name, v);
}
for (var i = 0; i < sdGraphVariables.length; i++) {
var v = sdGraphVariables[i];
var name = v.name();
//Add variables/constants/placeholders as a node
var vType = v.type();
switch (vType) {
case nd4j.graph.VarType.CONSTANT:
constCount++;
break;
case nd4j.graph.VarType.PLACEHOLDER:
phCount++;
break;
case nd4j.graph.VarType.VARIABLE:
varCount++;
break;
}
if (vType === nd4j.graph.VarType.CONSTANT || vType === nd4j.graph.VarType.PLACEHOLDER || vType === nd4j.graph.VarType.VARIABLE) {
var dt = dataTypeToString(v.datatype());
var shape = varShapeToString(v);
var n = "\"" + name + "\"\n" + varTypeToString(vType) + "\n" + dt + " " + shape;
var extraLabel = v.uiLabelExtra();
if (extraLabel != null && extraLabel !== "") {
n = n + "\n" + extraLabel;
}
if (vType === nd4j.graph.VarType.CONSTANT) {
var constArr = v.constantValue();
if (constArr != null) {
if (constArr.shapeLength() === 0 && constArr.bufferLength() > 0) {
var scalar = scalarFromFlatArray(constArr);
if (scalar != null && scalar !== "") {
n = n + "\nScalar val: " + scalar;
}
}
}
}
var nodeObj = {
label: n,
id: "var-" + name,
name: "var-" + name
};
var renderStyle = "";
if (vType === nd4j.graph.VarType.VARIABLE) {
renderStyle = "uivariable variable";
} else if (vType === nd4j.graph.VarType.PLACEHOLDER) {
renderStyle = "uivariable placeholder";
} else if (vType === nd4j.graph.VarType.CONSTANT) {
renderStyle = "uivariable constant";
}
sdGraphNodes.push({data: nodeObj, classes: renderStyle});
if (v.inputsForOpLength() > 0) {
for (var j = 0; j < v.inputsForOpLength(); j++) {
var opName = v.inputsForOp(j);
opName = idEscapeSlashes(opName);
var edgeObj = {
id: "edge_" + name + "_" + j,
source: "var-" + name,
target: opName,
label: ""
};
sdGraphEdges.push({data: edgeObj, classes: "opoutputedge"});
}
}
//Add variable control dependencies:
var vcdCount = v.controlDepsLength();
if (vcdCount > 0) {
for (var j = 0; j < vcdCount; j++) {
var vcd = v.controlDeps(j);
//2 possibilities: variable is a variable/constant/placeholder: source is from variable node
//Or variable is output of an op: source is from an op node
var vcdVariable = sdGraphVariableMap.get(vcd);
var sourceName;
var edgeLabel;
if (vcdVariable.type() === nd4j.graph.VarType.ARRAY) {
//Control dependency: array -> variable/const/placeholder
sourceName = vcdVariable.outputOfOp();
sourceName = idEscapeSlashes(sourceName);
edgeLabel = vcd; //Don't need to report datatype here, data is not actually used
} else {
//Control dependency: variable/const/placeholder -> variable/const/placeholder
sourceName = "var-" + vcd;
edgeLabel = "";
}
var edgeObj = {
source: sourceName,
target: "var-" + name,
label: edgeLabel
};
sdGraphEdges.push({data: edgeObj, classes: "controldepedge"});
}
}
}
count += 1;
}
//Op nodes
var mapOpNameInteger = new Map();
sdGraphOpsMap = new Map();
count = 0;
opCount = sdGraphOpsList.length;
for (var i = 0; i < sdGraphOpsList.length; i++) {
var o = sdGraphOpsList[i];
var name = o.name();
var opName = o.opName();
mapOpNameInteger.set(count, name);
sdGraphOpsMap.set(name, o);
var label = "\"" + name + "\"\n(" + opName + ")";
var e = o.uiLabelExtra();
if (e != null && e !== "") {
label = label + "\n" + e;
}
var opclasses = "uiop";
if (opName === "enter") {
opclasses = opclasses + " openter";
} else if (opName === "exit") {
opclasses = opclasses + " opexit";
} else if (opName === "next_iteration") {
opclasses = opclasses + " opnextiter";
} else if (opName === "switch") {
opclasses = opclasses + " opswitch";
} else if (opName === "merge") {
opclasses = opclasses + " opmerge";
}
var id = idEscapeSlashes(name);
var nodeObj = {
label: label,
id: id
};
sdGraphNodes.push({data: nodeObj, classes: opclasses});
//Add edges between ops:
var ol = o.outputsLength();
if (ol > 0) {
for (var j = 0; j < ol; j++) {
var outVarName = o.outputs(j);
var outVar = sdGraphVariableMap.get(outVarName);
var outVarInputCount = outVar.inputsForOpLength();
//Op -> outVar -> otherOp exists
//But we'll represent this as one edge in the graph only
var dt = dataTypeToString(outVar.datatype());
if (outVarInputCount > 0) {
for (var k = 0; k < outVarInputCount; k++) {
var opName = outVar.inputsForOp(k);
opName = idEscapeSlashes(opName);
var edgeObj = {
source: id,
target: opName,
label: outVarName + " (" + dt + ")"
};
sdGraphEdges.push({data: edgeObj, classes: "opoutputedge"});
}
}
}
}
//Add control dependencies:
var cdLength = o.controlDepsLength();
if (cdLength > 0) {
for (var j = 0; j < cdLength; j++) {
var varName = o.controlDeps(j);
//If placeholder, variable or constant, make edge from variable node
//If array, make edge from op node
var variable = sdGraphVariableMap.get(varName);
var dt = dataTypeToString(variable.datatype());
var vType = variable.type();
var edgeObj;
if (vType === nd4j.graph.VarType.CONSTANT || vType === nd4j.graph.VarType.PLACEHOLDER || vType === nd4j.graph.VarType.VARIABLE) {
edgeObj = {
source: "var-" + varName,
target: id,
label: ""
}
} else {
var inOpName = variable.outputOfOp();
inOpName = idEscapeSlashes(inOpName);
edgeObj = {
source: inOpName,
target: id,
label: "CD: " + varName + " (" + dt + ")"
};
}
sdGraphEdges.push({data: edgeObj, classes: "controldepedge"});
}
}
count += 1;
}
//Also add the outputs:
for (var i = 0; i < sdGraphOutputs.length; i++) {
var outName = sdGraphOutputs[i];
var v = sdGraphVariableMap.get(outName);
var opName = v.outputOfOp();
opName = idEscapeSlashes(opName);
if (opName != null) {
var dt = dataTypeToString(v.datatype());
var shape = varShapeToString(v);
var n = "Output: \"" + outName + "\"\n" + varTypeToString(vType) + "\n" + dt + " " + shape;
var nodeObj = {
label: n,
id: "out-" + name
};
sdGraphNodes.push({data: nodeObj, classes: "uivariable output"});
//Also add edge:
var edgeObj = {
label: "",
source: opName,
target: "out-" + name
};
sdGraphEdges.push({data: edgeObj, classes: "opoutputedge"});
}
}
//Render the side bar:
document.getElementById('selectedfile').innerHTML =
"<br><br><strong>File:</strong> " + file.name + "<br>" +
"<strong>Inputs:</strong> \"" + sdGraphInputs.join("\", \"") + "\"<br>" +
"<strong>Outputs:</strong> \"" + sdGraphOutputs.join("\", \"") + "\"<br>" +
"<strong>Placeholder Count:</strong> " + phCount + "<br>" +
"<strong>Variable Count:</strong> " + varCount + "<br>" +
"<strong>Constant Count:</strong> " + constCount + "<br>" +
"<strong>Op Count:</strong> " + opCount + "<br>";
} else if (decoded[0] === "systeminfo") {
} else if (decoded[0] === "startevents") {
}
renderContent();
};
}
}
function renderContent(){
document.getElementById("samediffcontent").innerHTML = "";
switch(selectedPage){
case "graph":
renderSameDiffGraph();
break;
case "plots":
readAndRenderPlotsData();
break;
case "evaluation":
case "performance":
//TODO
renderPageNotImplemented();
default:
renderPageNotImplemented();
}
}
function renderPageNotImplemented(){
document.getElementById("samediffcontent").innerHTML = "<br><br>Page not yet implemented: " + selectedPage + "<br>";
}
samediffgraphlayout = "klay";
klaylayout = "DOWN";
function setLayout(newLayout){
//spread( cytoscape );
if(newLayout === "klay_down"){
klaylayout = "DOWN";
newLayout = "klay";
} else if(newLayout === "klay_lr"){
klaylayout = "RIGHT";
newLayout = "klay";
}
samediffgraphlayout = newLayout;
renderContent();
}
function idEscapeSlashes(input){
return input.replace(new RegExp('/', 'g'), '__');
}
function idRestoreSlashes(input){
return input.replace(new RegExp('__', 'g'), '/');
}
@@ -0,0 +1,183 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function renderModelGraph(){
getSessionSettings(function(){
var modelGraphUrl = multiSession ? "/train/" + currSession + "/model/graph" : "/train/model/graph";
$.ajax({
url: modelGraphUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
createGraph(data);
}
});
});
}
function createGraph(data){
//Generate the elements data
var vertexNames = data["vertexNames"]; //List<String>
if (typeof vertexNames == 'undefined') return; //No data
var vertexTypes = data["vertexTypes"]; //List<String>
var vertexInputs = data["vertexInputs"]; //int[][]
var vertexInfos = data["vertexInfo"]; //List<Map<String,String>>
var vertexCount = vertexNames.length;
//Layer Styles
var layerStyles = {
"Activation": ["#CD6155", "rectangle"],
"AutoEncoder": ["#641E16","rectangle"],
"BaseOutput": ["#AF7AC5","rectangle"],
"BasePretrainNetwork": ["#512E5F","rectangle"],
"BaseRecurrent": ["#5499C7","rectangle"],
"BatchNormalization": ["#154360","rectangle"],
"Convolution": ["#1B2631","rectangle"],
"Dense": ["#EB984E","rectangle"],
"Embedding": ["#F4D03F","rectangle"],
"FeedForward": ["#7D6608","rectangle"],
"GravesBidirectionalLSTM": ["#1ABC9C","rectangle"],
"GravesLSTM": ["#6E2C00","rectangle"],
"Input": ["#145A32","vee"],
"InputTypeUtil": ["#5D6D7E","rectangle"],
"LocalResponseNormalization": ["#52BE80","rectangle"],
"Output": ["#922B21","ellipse"],
"RBM": ["#48C9B0","rectangle"],
"RnnOutput": ["#0E6251","rectangle"],
"Subsampling": ["#4D5656","rectangle"],
"L2Vertex": ["#78281F","triangle"],
"LayerVertex": ["#4A235A","triangle"],
"MergeVertex": ["#1B4F72","triangle"],
"PreprocessorVertex": ["#0B5345","triangle"],
"StackVertex": ["#186A3B","triangle"],
"SubsetVertex": ["#7E5109","triangle"],
"UnstackVertex": ["#6E2C00","triangle"],
"DuplicateToTimeSeriesVertex": ["#424949","triangle"],
"LastTimeStepVertex": ["#17202A","triangle"]
};
var nodes = [];
var edges = [];
for(var i=0; i<vertexNames.length; i++ ){
//Find correct layer color and shape
if (Object.keys(layerStyles).indexOf(vertexTypes[i]) > 0 ) {
layerColor = layerStyles[vertexTypes[i]][0];
layerShape = layerStyles[vertexTypes[i]][1];
} else {
layerColor = "#000000";
layerShape = "octagon";
}
var obj = {
id: i,
name: vertexTypes[i] + '\n(' + vertexNames[i] +')',
faveColor: layerColor,
faveShape: layerShape,
onclick: "renderLayerTable()"
};
nodes.push({ data: obj} );
//Edges:
var inputsToCurrent = vertexInputs[i];
for(var j=0; j<inputsToCurrent.length; j++ ){
var e = {
source: inputsToCurrent[j],
target: i,
faveColor: '#A9A9A9',
strength: 100
};
edges.push({ data: e} );
}
}
var elementsToRender = {
nodes: nodes,
edges: edges
};
var c = cytoscape({
container: $('#layers'),
layout: {
name: 'dagre',
padding: 10
},
style: cytoscape.stylesheet()
.selector('node')
.css({
'shape': 'data(faveShape)',
'width': '100',
'height': '50',
'content': 'data(name)',
'text-valign': 'center',
'text-outline-width': 2,
'text-outline-color': 'data(faveColor)',
'background-color': 'data(faveColor)',
'color': '#fff',
'text-wrap': 'wrap',
'font-size': '17px'
})
.selector(':selected')
.css({
'border-width': 3,
'border-color': '#333'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'opacity': 0.666,
'width': 'mapData(strength, 70, 100, 2, 6)',
'target-arrow-shape': 'triangle',
'source-arrow-shape': 'circle',
'line-color': 'data(faveColor)',
'source-arrow-color': 'data(faveColor)',
'target-arrow-color': 'data(faveColor)'
})
.selector('edge.questionable')
.css({
'line-style': 'dotted',
'target-arrow-shape': 'diamond'
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-opacity': 0
}),
elements: elementsToRender,
ready: function () {
window.cy = this;
cy.panningEnabled(true);
cy.autoungrabify(true);
cy.zoomingEnabled(true);
cy.fit(elementsToRender, 50);
}
});
c.on('click', 'node', function (evt) {
setSelectedVertex(this.id());
});
}
@@ -0,0 +1,169 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
$(function () { // on dom ready
$('#layers').cytoscape({
layout: {
name: 'dagre',
padding: 10
},
style: cytoscape.stylesheet()
.selector('node')
.css({
'shape': 'data(faveShape)',
'width': 'mapData(weight, 40, 80, 20, 60)',
'content': 'data(name)',
'text-valign': 'center',
'text-outline-width': 2,
'text-outline-color': 'data(faveColor)',
'background-color': 'data(faveColor)',
'color': '#fff'
})
.selector(':selected')
.css({
'border-width': 3,
'border-color': '#333'
})
.selector('edge')
.css({
'curve-style': 'bezier',
'opacity': 0.666,
'width': 'mapData(strength, 70, 100, 2, 6)',
'target-arrow-shape': 'triangle',
'source-arrow-shape': 'circle',
'line-color': 'data(faveColor)',
'source-arrow-color': 'data(faveColor)',
'target-arrow-color': 'data(faveColor)'
})
.selector('edge.questionable')
.css({
'line-style': 'dotted',
'target-arrow-shape': 'diamond'
})
.selector('.faded')
.css({
'opacity': 0.25,
'text-opacity': 0
}),
elements: {
nodes: [
{
data: {
id: '0',
name: 'Input',
weight: 100,
faveColor: '#6FB1FC',
faveShape: 'triangle'
// , href: '?layer=0'
}
},
{
data: {
id: '1',
name: 'Dense',
weight: 100,
faveColor: '#EDA1ED',
faveShape: 'rectangle',
// href: '?layer=1'
}
},
{
data: {
id: '2',
name: 'Convolution',
weight: 100,
faveColor: '#86B342',
faveShape: 'rectangle',
href: '#'
}
},
{data: {id: '3', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '4', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '5', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '6', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '7', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '8', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '9', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '10', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '11', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '12', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '13', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '14', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '15', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '16', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '17', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '18', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '19', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '20', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '21', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '22', name: 'Layer', weight: 100, faveColor: '#F5A45D', faveShape: 'rectangle', href: '#'}},
{data: {id: '23', name: 'Output', weight: 100, faveColor: '#FF0000', faveShape: 'ellipse', href: '#'}}
],
edges: [
{data: {source: '0', target: '1', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '1', target: '2', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '2', target: '3', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '3', target: '4', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '4', target: '5', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '5', target: '6', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '6', target: '7', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '7', target: '8', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '8', target: '9', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '9', target: '10', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '10', target: '11', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '11', target: '12', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '12', target: '13', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '13', target: '14', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '14', target: '15', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '15', target: '16', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '16', target: '17', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '17', target: '18', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '18', target: '19', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '19', target: '20', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '20', target: '21', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '21', target: '22', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '22', target: '23', faveColor: '#A9A9A9', strength: 100}},
{data: {source: '23', target: '24', faveColor: '#A9A9A9', strength: 100}}
]
},
ready: function () {
window.cy = this;
cy.panningEnabled(true);
cy.autoungrabify(true);
cy.maxZoom(5);
cy.minZoom(1);
// cy.wheelSensitivity(0);
}
});
// cy.on('tap', 'node', function () {
// window.location.href = this.data('href');
// });
cy.on('click', 'node', function (evt) {
console.log('CLICKED: id=' + this.id() + ", name=" + this.data.name);
console.log('CLICKED: id=' + this.id() + ", name=" + this.name);
});
}); // on dom ready
@@ -0,0 +1,633 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
var selectedVertex = -1;
function setSelectedVertex(vertex){
selectedVertex = vertex;
currSelectedParamHist = null; //Reset selected param
currSelectedUpdateHist = null; //Reset selected param
lastUpdateTimeModel = -2; //Reset last update time on vertex change
}
var selectedMeanMagChart = "ratios";
function setSelectMeanMagChart(selectedChart){
selectedMeanMagChart = selectedChart;
lastUpdateTimeModel = -2; //Reset last update time on selected chart change
//Tab highlighting logic
if (selectedMeanMagChart == "ratios") {
$("#ratios").attr("class", "active");
$("#paramMM").removeAttr("class");
$("#updateMM").removeAttr("class");
}
else if (selectedMeanMagChart == "paramMM") {
$("#ratios").removeAttr("class");
$("#paramMM").attr("class", "active");
$("#updateMM").removeAttr("class");
}
else {
$("#ratios").removeAttr("class");
$("#paramMM").removeAttr("class");
$("#updateMM").attr("class", "active");
}
}
var lastUpdateTimeModel = -1;
var lastUpdateSessionModel = "";
function renderModelPage(firstLoad) {
updateSessionWorkerSelect();
if(firstLoad || !lastUpdateSessionModel || lastUpdateSessionModel == "" || lastUpdateSessionModel != currSession){
executeModelUpdate();
} else {
//Check last update time first - see if data has actually changed...
$.ajax({
url: "/train/sessions/lastUpdate/" + currSession,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
if(data > lastUpdateTimeModel){
executeModelUpdate();
}
}
});
}
}
function executeModelUpdate(){
getSessionSettings(function(){
if(selectedVertex >= 0) {
var modelDataUrl = multiSession ? "/train/" + currSession + "/model/data/" + selectedVertex
: "/train/model/data/" + selectedVertex;
$.ajax({
url: modelDataUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
lastUpdateSessionModel = currSession;
lastUpdateTimeModel = data["updateTimestamp"];
setZeroState(false);
renderLayerTable(data);
renderMeanMagChart(data);
renderActivationsChart(data);
renderLearningRateChart(data);
renderParametersHistogram(data);
renderUpdatesHistogram(data);
}
});
} else {
setZeroState(true);
}
});
}
/* ---------- Zero State ---------- */
function setZeroState(enableZeroState) {
if (enableZeroState) {
$("#layerDetails").hide();
$("#zeroState").show();
}
else {
$("#layerDetails").show();
$("#zeroState").hide();
}
}
/* ---------- Layer Table Data ---------- */
function renderLayerTable(data) {
var layerInfo = data["layerInfo"];
var nRows = Object.keys(layerInfo);
//Generate row for each item in the table
var tbl = $("#layerInfo");
tbl.empty();
for (var i = 0; i < nRows.length; i++) {
tbl.append("<tr><td>" + layerInfo[i][0] + "</td><td>" + layerInfo[i][1] + "</td></tr>");
}
}
/* ---------- Mean Magnitudes Chart ---------- */
function renderMeanMagChart(data) {
var iter = data["meanMag"]["iterCounts"];
var chart = $("#meanmag");
if (chart.length) {
if(!selectedMeanMagChart){
selectedMeanMagChart = "ratios";
}
//Tab highlighting logic
if (selectedMeanMagChart == "ratios") {
$("#mmRatioTab").attr("class", "active");
$("#mmParamTab").removeAttr("class");
$("#mmUpdateTab").removeAttr("class");
}
else if (selectedMeanMagChart == "paramMM") {
$("#mmRatioTab").removeAttr("class");
$("#mmParamTab").attr("class", "active");
$("#mmUpdateTab").removeAttr("class");
}
else {
$("#mmRatioTab").removeAttr("class");
$("#mmParamTab").removeAttr("class");
$("#mmUpdateTab").attr("class", "active");
}
var isRatio = selectedMeanMagChart == "ratios";
var ratios = data["meanMag"][selectedMeanMagChart];
var keys = Object.keys(ratios);
var toPlot = [];
var overallMax = -Number.MAX_VALUE;
var overallMin = Number.MAX_VALUE;
for (var i = 0; i < keys.length; i++) {
var r = ratios[keys[i]];
var pairs = [];
for (var j = 0; j < r.length; j++) {
if(isRatio){
var l10 = Math.log10(r[j]);
if(l10 < -10 || !isFinite(l10)) l10 = -10;
pairs.push([iter[j], l10]);
} else {
pairs.push([iter[j], r[j]]);
}
}
toPlot.push({data: pairs, label: keys[i]});
var thisMax = Math.max.apply(Math, r);
var thisMin = Math.min.apply(Math, r);
overallMax = Math.max(overallMax, thisMax);
overallMin = Math.min(overallMin, thisMin);
}
if (overallMax == -Number.MAX_VALUE) overallMax = 1.0;
if (overallMin == Number.MAX_VALUE) overallMin = 0.0;
if(isRatio){
overallMax = Math.log10(overallMax);
overallMin = Math.log10(overallMin);
overallMin = Math.max(overallMin, -10);
overallMax = Math.ceil(overallMax);
overallMin = Math.floor(overallMin);
if(overallMin < -10) overallMin = -10;
}
//Trying to hide the "log10" part...
// if(isRatio){
// $("#updateRatioTitleLog10").show();
// } else {
// $("#updateRatioTitleLog10").hide();
// }
if(isRatio){
$("#updateRatioTitleSmallLog10").show();
} else {
$("#updateRatioTitleSmallLog10").hide();
}
var plot = $.plot(chart,
toPlot, {
series: {
lines: {
show: true,
lineWidth: 2,
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: overallMin, max: overallMax},
colors: ["#FA5833", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltipMMChart">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#meanmag").fadeIn(200);
}
var previousPoint = null;
$("#meanmag").bind("plothover", function (event, pos, item) {
if(!pos.x){//No data condition
$("#tooltipMMChart").remove();
previousPoint = null;
return;
}
var xPos = pos.x.toFixed(0);
$("#xMeanMagnitudes").text(xPos < 0 || xPos == "-0" ? "" : xPos);
$("#yMeanMagnitudes").text(pos.y.toFixed(2));
//Tooltip
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltipMMChart").remove();
var x = item.datapoint[0].toFixed(0);
var logy = item.datapoint[1].toFixed(5);
var y = Math.pow(10, item.datapoint[1]).toFixed(5);
if(selectedMeanMagChart == "ratios"){
showTooltip(item.pageX - chart.offset().left, item.pageY - chart.offset().top,
item.series.label + " (" + x + ", logRatio=" + logy + ", ratio=" + y + ")");
} else {
showTooltip(item.pageX - chart.offset().left, item.pageY - chart.offset().top,
item.series.label + " (" + x + ", " + y + ")");
}
}
}
else {
$("#tooltipMMChart").remove();
previousPoint = null;
}
});
}
}
/* ---------- Activations Chart ---------- */
function renderActivationsChart(data) {
var mean = data["activations"]["mean"];
var stdev = data["activations"]["stdev"];
var iter = data["activations"]["iterCount"];
var chart = $("#activations");
if (chart.length) {
var meanData = [];
var meanPlus2 = [];
var meanMinus2 = [];
var overallMin = Number.MAX_VALUE;
var overallMax = -Number.MAX_VALUE;
for (var i = 0; i < iter.length; i++) {
var mp2 = mean[i] + 2*stdev[i];
var ms2 = mean[i] - 2*stdev[i];
overallMin = Math.min(overallMin, ms2);
overallMax = Math.max(overallMax, mp2);
meanData.push([iter[i], mean[i]]);
meanPlus2.push([iter[i], mp2]);
meanMinus2.push([iter[i], ms2]);
}
if(overallMin == Number.MAX_VALUE) overallMin = 0;
if(overallMax == Number.MIN_VALUE) overallMax = 1;
var plot = $.plot(chart,
[{data: meanData, label: "Mean"},{data: meanPlus2, label: "Mean + 2*sd"}, {data: meanMinus2, label: "Mean - 2*sd"}], {
series: {
lines: {
show: true,
lineWidth: 2,
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: overallMin, max: overallMax},
colors: ["#FA5833", "#2FABE9", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltipActivationChart">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#activations").fadeIn(200);
}
var previousPoint = null;
$("#activations").bind("plothover", function (event, pos, item) {
var xPos = pos.x.toFixed(0);
$("#xActivations").text(xPos < 0 || xPos == "-0" ? "" : xPos);
$("#yActivations").text(pos.y.toFixed(2));
//Tooltip
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltipActivationChart").remove();
var x = item.datapoint[0].toFixed(0);
var y = item.datapoint[1].toFixed(5);
//TODO get raw stdev...
// var std = (meanPlus2[x] - meanData[x])/2.0; //This doesn't work
showTooltip(item.pageX - chart.offset().left, item.pageY - chart.offset().top,
// item.series.label + " (" + x + ", stdev=" + std + ")");
item.series.label + " (" + x + ", y=" + y + ")");
}
}
else {
$("#tooltipActivationChart").remove();
previousPoint = null;
}
});
}
}
/* ---------- Learning Rate Chart ---------- */
function renderLearningRateChart(data) {
var iter = data["learningRates"]["iterCounts"];
var chart = $("#learningrate");
if (chart.length) {
// var lrs_bData = [];
// var lrs_WData = [];
var lrs = data["learningRates"]["lrs"];
var keys = Object.keys(lrs);
var toPlot = [];
var overallMax = -Number.MAX_VALUE;
var overallMin = Number.MAX_VALUE;
for (var i = 0; i < keys.length; i++) {
var lr = lrs[keys[i]];
var pairs = [];
for (var j = 0; j < lr.length; j++) {
pairs.push([iter[j], lr[j]]);
}
toPlot.push({data: pairs, label: keys[i]});
var thisMax = Math.max.apply(Math, lr);
var thisMin = Math.min.apply(Math, lr);
overallMax = Math.max(overallMax, thisMax);
overallMin = Math.min(overallMin, thisMin);
}
if (overallMax == -Number.MAX_VALUE){
//No data
overallMin = 0.0;
overallMax = 1.0;
} else if(overallMin == overallMax){
overallMax = 2*overallMax;
}
overallMin = 0;
var plot = $.plot(chart,
toPlot, {
series: {
lines: {
show: true,
lineWidth: 2,
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: overallMin, max: overallMax},
colors: ["#FA5833", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltipLRChart">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#learningrate").fadeIn(200);
}
var previousPoint = null;
chart.bind("plothover", function (event, pos, item) {
if(!pos.x){//No data condition
$("#tooltipLRChart").remove();
previousPoint = null;
return;
}
var xPos = pos.x.toFixed(0);
$("#xLearningRate").text(xPos < 0 || xPos == "-0" ? "" : xPos);
$("#yLearningRate").text(pos.y.toFixed(5));
//Tooltip
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltipLRChart").remove();
var x = item.datapoint[0].toFixed(0);
var y = item.datapoint[1].toFixed(5);
showTooltip(item.pageX - chart.offset().left, item.pageY - chart.offset().top,
item.series.label + " (" + x + ", learningRate=" + y + ")");
}
}
else {
$("#tooltipLRChart").remove();
previousPoint = null;
}
});
}
}
/* ---------- Parameters Histogram ---------- */
function selectParamHist(paramName){
currSelectedParamHist = paramName;
lastUpdateTimeModel = -2; //Reset last update time on selected chart change
}
var currSelectedParamHist = null;
function renderParametersHistogram(data) {
var histograms = data["paramHist"];
var paramNames = histograms["paramNames"];
//Create buttons, add them to the div...
var buttonDiv = $("#paramHistButtonsDiv");
buttonDiv.empty();
for( var i=0; i<paramNames.length; i++ ){
var n = "paramBtn_"+paramNames[i];
var btn = $('<input id="' + n + '" class="btn btn-small"/>').attr({type:"button",name:n,value:paramNames[i]});
var onClickFn = (function(pName){
return function(){
selectParamHist(pName);
}
})(paramNames[i]);
$(document).on("click", "#" + n, onClickFn);
buttonDiv.prepend(btn);
}
if(currSelectedParamHist == null){
if(jQuery.inArray("W",paramNames)) currSelectedParamHist = "W";
else if(paramNames.length > 0) currSelectedParamHist = paramNames[0];
}
if(currSelectedParamHist != null && $("#parametershistogram").length){
var label = $("#paramhistSelected");
label.html("&nbsp&nbsp(" + currSelectedParamHist + ")");
var data;
if(data["paramHist"][currSelectedParamHist]){
var min = data["paramHist"][currSelectedParamHist]["min"];
var max = data["paramHist"][currSelectedParamHist]["max"];
var bins = data["paramHist"][currSelectedParamHist]["bins"];
var counts = data["paramHist"][currSelectedParamHist]["counts"];
var binWidth = (max-min)/bins;
var halfBin = binWidth/2.0;
data = [];
for (var i = 0; i < counts.length; i++) {
var binPos = (min + i * binWidth - halfBin);
data.push([binPos, counts[i]]);
}
} else {
data = [];
}
$.plot($("#parametershistogram"), [ data ], {
stack: null,
series: {
bars: { show: true, barWidth: binWidth }
},
colors: ["#2FABE9"]
});
}
}
/* ---------- Updates Histogram ---------- */
function selectUpdateHist(paramName){
currSelectedUpdateHist = paramName;
lastUpdateTimeModel = -2; //Reset last update time on selected chart change
}
var currSelectedUpdateHist = null;
function renderUpdatesHistogram(data) {
var histograms = data["updateHist"];
var paramNames = histograms["paramNames"];
//Create buttons, add them to the div...
var buttonDiv = $("#updateHistButtonsDiv");
buttonDiv.empty();
for( var i=0; i<paramNames.length; i++ ){
var n = "updParamBtn_"+paramNames[i];
var btn = $('<input id="' + n + '" class="btn btn-small"/>').attr({type:"button",name:n,value:paramNames[i]});
var onClickFn = (function(pName){
return function(){
selectUpdateHist(pName);
}
})(paramNames[i]);
$(document).on("click", "#" + n, onClickFn);
buttonDiv.prepend(btn);
}
if(currSelectedUpdateHist == null){
if(jQuery.inArray("W",paramNames)) currSelectedUpdateHist = "W";
else if(paramNames.length > 0) currSelectedUpdateHist = paramNames[0];
}
var chart = $("#updateshistogram");
if(currSelectedUpdateHist != null && chart.length){
var label = $("#updatehistSelected");
label.html("&nbsp&nbsp(" + currSelectedUpdateHist + ")");
var data;
if(data["updateHist"][currSelectedParamHist]) {
var min = data["updateHist"][currSelectedUpdateHist]["min"];
var max = data["updateHist"][currSelectedUpdateHist]["max"];
var bins = data["updateHist"][currSelectedUpdateHist]["bins"];
var counts = data["updateHist"][currSelectedUpdateHist]["counts"];
var binWidth = (max - min) / bins;
var halfBin = binWidth / 2.0;
data = [];
for (var i = 0; i < counts.length; i++) {
var binPos = (min + i * binWidth - halfBin);
data.push([binPos, counts[i]]);
}
} else {
data = [];
}
$.plot(chart, [ data ], {
stack: null,
series: {
bars: { show: true, barWidth: binWidth }
},
colors: ["#2FABE9"]
});
}
}
@@ -0,0 +1,529 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
var selectedChart = "stdevActivations";
function selectStdevChart(fieldName) {
selectedChart = fieldName;
lastUpdateTime = -1; //Reset update time to force reload
//Tab highlighting logic
if (selectedChart == "stdevActivations") {
$("#stdevActivations").attr("class", "active");
$("#stdevGradients").removeAttr("class");
$("#stdevUpdates").removeAttr("class");
}
else if (selectedChart == "stdevGradients") {
$("#stdevActivations").removeAttr("class");
$("#stdevGradients").attr("class", "active");
$("#stdevUpdates").removeAttr("class");
}
else {
$("#stdevActivations").removeAttr("class");
$("#stdevGradients").removeAttr("class");
$("#stdevUpdates").attr("class", "active");
}
renderOverviewPage(true);
}
/* ---------- Render page ---------- */
var lastUpdateTime = -1;
var lastUpdateSession = "";
function renderOverviewPage(forceupdate) {
updateSessionWorkerSelect();
if(forceupdate || !lastUpdateSession || lastUpdateSession == "" || lastUpdateSession != currSession){
executeOverviewUpdate();
} else {
//Check last update time first - see if data has actually changed...
$.ajax({
url: "/train/sessions/lastUpdate/" + currSession,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
if(data > lastUpdateTime){
executeOverviewUpdate();
}
}
});
}
}
function executeOverviewUpdate(){
getSessionSettings(function(){
var overviewUrl = multiSession ? "/train/" + currSession + "/overview/data" : "/train/overview/data";
$.ajax({
url: overviewUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
lastUpdateSession = currSession;
lastUpdateTime = data["updateTimestamp"];
renderScoreVsIterChart(data);
renderModelPerformanceTable(data);
renderUpdatesRatio(data);
renderStdevChart(data);
}
});
});
}
/* ---------- Score vs. Iteration Chart ---------- */
function renderScoreVsIterChart(data) {
var scoresArr = data["scores"];
var scoresIter = data["scoresIter"];
var maxScore = Math.max.apply(Math, scoresArr);
var chartMin = Math.min.apply(Math, scoresArr);
if(chartMin > 0){
chartMin = 0.0;
}
var scoreChart = $("#scoreiterchart");
scoreChart.unbind(); // prevent over-subscribing
if (scoreChart.length) {
var scoreData = [];
for (var i = 0; i < scoresArr.length; i++) {
scoreData.push([scoresIter[i], scoresArr[i]]);
}
var plotData = [{data: scoreData, label: "score"}];
// calculate a EMA line to summarize training progress
if(scoresIter.length > 10) {
var bestFitLine = EMACalc(scoresArr, 10);
var bestFitData = [];
for (var i = 0; i < bestFitLine.length; i++) {
bestFitData.push([scoresIter[i], bestFitLine[i]]);
}
plotData.push({data: bestFitData, label: "summary"});
}
// plot the chart
var plotOptions = {
series: {
lines: {
show: true,
lineWidth: 2
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: chartMin, max: maxScore},
colors: ["#FA5833","rgba(65,182,240,0.3)","#000000"],
selection: {
mode: "x"
}
};
var plot = $.plot(scoreChart, plotData, plotOptions);
// when selected, calculate best fit line
scoreChart.bind("plotselected", function (event, ranges) {
var indices = [];
var fromIdx = parseInt(ranges.xaxis.from);
var toIdx = parseInt(ranges.xaxis.to);
var scoresCopy = scoresArr.slice();
for (var i = fromIdx; i <= toIdx; i++) {
indices.push(i);
}
var bestFitLine = findLineByLeastSquares(indices, scoresCopy.slice(fromIdx,toIdx+1));
var bestFitData = [];
for (var i = 0; i < bestFitLine[0].length; i++) {
bestFitData.push([bestFitLine[0][i], bestFitLine[1][i]]);
}
plotData.push({data: bestFitData, label: "selection"});
plot.setData(plotData);
plot.draw();
});
scoreChart.bind("plotunselected", function (event) {
plotData = plotData.slice(0,2);
plot.setData(plotData);
plot.draw();
});
function showTooltip(x, y, contents) {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#scoreiterchart").fadeIn(200);
}
var previousPoint = null;
scoreChart.bind("plothover", function (event, pos, item) {
if (typeof pos.x == 'undefined') return;
var xPos = pos.x.toFixed(0);
$("#x").text(xPos < 0 || xPos == "-0" ? "" : xPos);
$("#y").text(pos.y.toFixed(5));
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltip").remove();
var x = item.datapoint[0].toFixed(0);
var y = item.datapoint[1].toFixed(5);
showTooltip(item.pageX - scoreChart.offset().left, item.pageY - scoreChart.offset().top,
"(" + x + ", " + y + ")");
}
}
else {
$("#tooltip").remove();
previousPoint = null;
}
});
}
}
/* ---------- Model Performance Table ---------- */
function renderModelPerformanceTable(data) {
/* Model */
var modelType = data["model"][0][1];
var nLayers = data["model"][1][1];
var nParams = data["model"][2][1];
/* Performance */
var startTime = data["perf"][0][1];
var totalRuntime = data["perf"][1][1];
var lastUpdate = data["perf"][2][1];
var totalParamUpdates = data["perf"][3][1];
var updatesPerSec = data["perf"][4][1];
var examplesPerSec = data["perf"][5][1];
/* Inject Model Information */
$("#modelType").html(modelType);
$("#nLayers").html(nLayers);
$("#nParams").html(nParams);
/* Inject Performance Information */
$("#startTime").html(startTime);
$("#totalRuntime").html(totalRuntime);
$("#lastUpdate").html(lastUpdate);
$("#totalParamUpdates").html(totalParamUpdates);
$("#updatesPerSec").html(updatesPerSec);
$("#examplesPerSec").html(examplesPerSec);
}
/* ---------- Ratio of Updates to Parameters Chart ---------- */
function renderUpdatesRatio(data) {
var ratios = data["updateRatios"];
var iter = data["scoresIter"];
var chart = $("#updateRatioChart");
if (chart.length) {
var keys = Object.keys(ratios);
var toPlot = [];
var overallMax = -Number.MAX_VALUE;
var overallMin = Number.MAX_VALUE;
for (var i = 0; i < keys.length; i++) {
var r = ratios[keys[i]];
var pairs = [];
for (var j = 0; j < r.length; j++) {
pairs.push([iter[j], Math.log10(r[j])]);
}
toPlot.push({data: pairs, label: keys[i]});
var thisMax = Math.max.apply(Math, r);
var thisMin = Math.min.apply(Math, r);
overallMax = Math.max(overallMax, thisMax);
overallMin = Math.min(overallMin, thisMin);
}
if (overallMax == -Number.MAX_VALUE) overallMax = 1.0;
if (overallMin == Number.MAX_VALUE) overallMin = 0.0;
overallMax = Math.log10(overallMax);
overallMin = Math.log10(overallMin);
overallMin = Math.max(overallMin, -10);
overallMax = Math.ceil(overallMax);
overallMin = Math.floor(overallMin);
var plot = $.plot(chart,
toPlot, {
series: {
lines: {
show: true,
lineWidth: 2
}
// points: {show: true},
// shadowSize: 2
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: overallMin, max: overallMax},
colors: ["#FA5833", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltipRatioChart">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#updateRatioChart").fadeIn(200);
}
var previousPoint = null;
chart.bind("plothover", function (event, pos, item) {
if (typeof pos.x == 'undefined') return;
var xPos = pos.x.toFixed(0);
$("#xRatio").text(xPos < 0 || xPos == "-0" ? "" : xPos);
$("#yLogRatio").text(pos.y.toFixed(5));
$("#yRatio").text(Math.pow(10, pos.y).toFixed(5));
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltipRatioChart").remove();
var x = item.datapoint[0].toFixed(0);
var logy = item.datapoint[1].toFixed(5);
var y = Math.pow(10, item.datapoint[1]).toFixed(5);
showTooltip(item.pageX - chart.offset().left, item.pageY - chart.offset().top,
"(" + x + ", logRatio=" + logy + ", ratio=" + y + ")");
}
}
else {
$("#tooltipRatioChart").remove();
previousPoint = null;
}
});
}
}
/* ---------- Stdev Charts ---------- */
function renderStdevChart(data) {
var selected = selectedChart;
var chart = $("#stdevChart");
if (chart.length) {
var stdevs = data[selected];
var iter = data["scoresIter"];
var keys = Object.keys(stdevs);
var toPlot = [];
var overallMax = -Number.MAX_VALUE;
var overallMin = Number.MAX_VALUE;
for (var i = 0; i < keys.length; i++) {
var r = stdevs[keys[i]];
var pairs = [];
for (var j = 0; j < r.length; j++) {
pairs.push([iter[j], Math.log10(r[j])]);
}
toPlot.push({data: pairs, label: keys[i]});
var thisMax = Math.max.apply(Math, r);
var thisMin = Math.min.apply(Math, r);
overallMax = Math.max(overallMax, thisMax);
overallMin = Math.min(overallMin, thisMin);
}
if (overallMax == -Number.MAX_VALUE) overallMax = 1.0;
if (overallMin == Number.MAX_VALUE) overallMin = 0.0;
overallMax = Math.log10(overallMax);
overallMin = Math.log10(overallMin);
overallMin = Math.max(overallMin, -10);
overallMax = Math.ceil(overallMax);
overallMin = Math.floor(overallMin);
var plot = $.plot(chart,
toPlot, {
series: {
lines: {
show: true,
lineWidth: 2
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: overallMin, max: overallMax},
colors: ["#FA5833", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltipStdevChart">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#stdevChart").fadeIn(200);
}
var previousPoint = null;
chart.bind("plothover", function (event, pos, item) {
if (typeof pos.x == 'undefined') return;
var xPos = pos.x.toFixed(0);
$("#xStdev").text(xPos < 0 || xPos == "-0" ? "" : xPos);
$("#yLogStdev").text(pos.y.toFixed(5));
$("#yStdev").text(Math.pow(10, pos.y).toFixed(5));
//Tooltip
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltipStdevChart").remove();
var x = item.datapoint[0].toFixed(0);
var logy = item.datapoint[1].toFixed(5);
var y = Math.pow(10, item.datapoint[1]).toFixed(5);
showTooltip(item.pageX - chart.offset().left, item.pageY - chart.offset().top,
item.series.label + " (" + x + ", logStdev=" + logy + ", stdev=" + y + ")");
}
}
else {
$("#tooltipStdevChart").remove();
previousPoint = null;
}
});
}
}
/* --------------- linear least squares (best fit line) ---------- */
function findLineByLeastSquares(values_x, values_y) {
var sum_x = 0;
var sum_y = 0;
var sum_xy = 0;
var sum_xx = 0;
var count = 0;
/*
* We'll use those variables for faster read/write access.
*/
var x = 0;
var y = 0;
var values_length = values_x.length;
if (values_length != values_y.length) {
throw new Error('The parameters values_x and values_y need to have same size!');
}
/*
* Nothing to do.
*/
if (values_length === 0) {
return [ [], [] ];
}
/*
* Calculate the sum for each of the parts necessary.
*/
for (var v = 0; v < values_length; v++) {
x = values_x[v];
y = values_y[v];
sum_x += x;
sum_y += y;
sum_xx += x*x;
sum_xy += x*y;
count++;
}
/*
* Calculate m and b for the formular:
* y = x * m + b
*/
var m = (count*sum_xy - sum_x*sum_y) / (count*sum_xx - sum_x*sum_x);
var b = (sum_y/count) - (m*sum_x)/count;
/*
* We will make the x and y result line now
*/
var result_values_x = [];
var result_values_y = [];
for (var v = 0; v < values_length; v++) {
x = values_x[v];
y = x * m + b;
result_values_x.push(x);
result_values_y.push(y);
}
return [result_values_x, result_values_y];
}
/* --------------- exponential moving average (best fit line) ---------- */
function EMACalc(mArray,mRange) {
var k = 2/(mRange + 1);
// first item is just the same as the first item in the input
emaArray = [mArray[0]];
// for the rest of the items, they are computed with the previous one
for (var i = 1; i < mArray.length; i++) {
emaArray.push(mArray[i] * k + emaArray[i - 1] * (1 - k));
}
return emaArray;
}
@@ -0,0 +1,383 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
selectMachine(); //Make machineID Global
var lastUpdateTimeSystem = -1;
var lastUpdateSessionSystem = "";
function renderSystemPage(firstLoad) {
updateSessionWorkerSelect();
if(firstLoad || !lastUpdateSessionSystem || lastUpdateSessionSystem == "" || lastUpdateSessionSystem != currSession){
executeSystemUpdate();
} else {
//Check last update time first - see if data has actually changed...
$.ajax({
url: "/train/sessions/lastUpdate/" + currSession,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
if(data > lastUpdateTimeSystem){
executeSystemUpdate();
}
}
});
}
}
function executeSystemUpdate(){
getSessionSettings(function(){
var systemDataUrl = multiSession ? "/train/" + currSession + "/system/data" : "/train/system/data";
$.ajax({
url: systemDataUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
lastUpdateSessionSystem = currSession;
lastUpdateTimeSystem = data["updateTimestamp"];
renderSystemMemoryChart(data);
renderSystemInformation(data);
renderGPULayout(data);
renderGpuMemoryChart(data);
}
});
});
}
function renderTabs() {
getSessionSettings(function(){
var systemDataUrl = multiSession ? "/train/" + currSession + "/system/data" : "/train/system/data";
$.ajax({
url: systemDataUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
renderMultipleTabs(data);
}
});
});
}
/* ---------- System Memory Utilization Chart ---------- */
// var systemMaxLastIter = 0;
var jvmMaxLastIter = 0;
var offHeapMaxLastIter = 0;
function renderSystemMemoryChart(data) {
var jvmCurrentFrac = data["memory"][machineID]["values"][0];
var offHeapFrac = data["memory"][machineID]["values"][1];
var systemChart = $("#systemMemoryChartPlot");
// systemMaxLastIter = data["memory"][machineID]["maxBytes"][0];
jvmMaxLastIter = data["memory"][machineID]["maxBytes"][0];
offHeapMaxLastIter = data["memory"][machineID]["maxBytes"][1];
if (systemChart.length) {
var jvmValuesData = [];
var offHeapValuesData = [];
for (var i = 0; i < jvmCurrentFrac.length; i++) {
jvmValuesData.push([i, 100.0 * jvmCurrentFrac[i]]);
offHeapValuesData.push([i, 100.0 * offHeapFrac[i]]);
}
// console.log("JVM:" + jvmValuesData);
// console.log("Off-Heap:" + offHeapValuesData);
var plot = $.plot(systemChart,
[{data: jvmValuesData, label: "JVM Memory"}, {data: offHeapValuesData, label: "Off-Heap Memory"}], {
series: {
lines: {
show: true,
lineWidth: 2
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: 0, max: 100.0},
colors: ["#FA5833", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltip">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#systemMemoryChartPlot").fadeIn(200);
}
var previousPoint = null;
systemChart.bind("plothover", function (event, pos, item) {
var xPos = pos.x.toFixed(0);
$("#x").text(xPos < 0 || xPos == "-0" ? "" : xPos);
var tempY = Math.min(100.0, pos.y);
tempY = Math.max(tempY, 0.0);
var asBytesJvm = formatBytes(tempY * jvmMaxLastIter / 100.0, 2);
var asBytesOffHeap = formatBytes(tempY * offHeapMaxLastIter / 100.0, 2);
$("#y").text(tempY.toFixed(2) + "% (" + asBytesJvm + ", " + asBytesOffHeap + ")");
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltip").remove();
var x = item.datapoint[0].toFixed(0);
var y = Math.min(100.0, item.datapoint[1]).toFixed(2);
var label = item.series.label;
var bytes;
if (label.toLowerCase().startsWith("jvm")) {
bytes = (item.datapoint[1] * jvmMaxLastIter / 100.0).toFixed(0);
} else {
bytes = (item.datapoint[1] * offHeapMaxLastIter / 100.0).toFixed(0);
}
showTooltip(item.pageX - systemChart.offset().left, item.pageY - systemChart.offset().top,
item.series.label + " (" + x + ", " + y + "%; " + formatBytes(bytes, 2) + ")");
}
}
else {
$("#tooltip").remove();
previousPoint = null;
}
});
}
}
/* ---------- GPU Utilization Chart (TBD) ---------- */
var gpuMaxLastIter = {};
function renderGpuMemoryChart(data) {
var gpuFrac = data["memory"][machineID]["values"][1];
var gpuChart = $("#gpuMemoryChartPlot");
var isDevice = data["memory"][machineID]["isDevice"];
var deviceIdxs = [];
if(isDevice ){
for(var i=0; i<isDevice.length; i++ ){
//if(isDevice[i] == false){ //For testing GPU chart on non-GPU system...
if(isDevice[i] == true){
deviceIdxs.push(i);
}
}
}
if(deviceIdxs.length == 0){
return;
}
//Do have devices -> render them...
if (gpuChart.length) {
var toRender = [];
for(var i=0; i<deviceIdxs.length; i++ ){
var seriesName = data["memory"][machineID]["seriesNames"][deviceIdxs[i]];
var thisDeviceMemFrac = data["memory"][machineID]["values"][deviceIdxs[i]];
gpuMaxLastIter[seriesName] = data["memory"][machineID]["maxBytes"][deviceIdxs[i]];
var xy = [];
for( var j=0; j<thisDeviceMemFrac.length; j++ ){
xy.push([j, 100.0 * thisDeviceMemFrac[j]])
}
toRender.push({data: xy, label: seriesName});
}
var plot = $.plot(gpuChart,
toRender, {
series: {
lines: {
show: true,
lineWidth: 2
}
},
grid: {
hoverable: true,
clickable: true,
tickColor: "#dddddd",
borderWidth: 0
},
yaxis: {min: 0, max: 100.0},
colors: ["#FA5833", "#2FABE9"]
});
function showTooltip(x, y, contents) {
$('<div id="tooltipGpu">' + contents + '</div>').css({
position: 'absolute',
display: 'none',
top: y + 8,
left: x + 10,
border: '1px solid #fdd',
padding: '2px',
'background-color': '#dfeffc',
opacity: 0.80
}).appendTo("#gpuMemoryChartPlot").fadeIn(200);
}
var previousPoint = null;
gpuChart.bind("plothover", function (event, pos, item) {
var xPos = pos.x.toFixed(0);
$("#x2").text(xPos < 0 || xPos == "-0" ? "" : xPos);
var tempY = Math.min(100.0, pos.y);
tempY = Math.max(tempY, 0.0);
$("#y2").text(tempY.toFixed(2) + "%");
if (item) {
if (previousPoint != item.dataIndex) {
previousPoint = item.dataIndex;
$("#tooltipGpu").remove();
var x = item.datapoint[0].toFixed(0);
var y = Math.min(100.0, item.datapoint[1]).toFixed(2);
var label = item.series.label;
var max = gpuMaxLastIter[item.series.label];
var bytes = (item.datapoint[1] * max / 100.0).toFixed(0);
showTooltip(item.pageX - gpuChart.offset().left, item.pageY - gpuChart.offset().top,
item.series.label + " (" + x + ", " + y + "%; " + formatBytes(bytes, 2) + ")");
}
}
else {
$("#tooltipGpu").remove();
previousPoint = null;
}
});
}
}
/* ---------- System Information ---------- */
function renderSystemInformation(data) {
/* Hardware */
var jvmAvailableProcessors = data["hardware"][machineID][2][1];
var nComputeDevices = data["hardware"][machineID][3][1];
/* Software */
var OS = data["software"][machineID][0][1];
var hostName = data["software"][machineID][1][1];
var OSArchitecture = data["software"][machineID][2][1];
var jvmName = data["software"][machineID][3][1];
var jvmVersion = data["software"][machineID][4][1];
var nd4jBackend = data["software"][machineID][5][1];
var nd4jDataType = data["software"][machineID][6][1];
/* Memory */
var currentBytesJVM = data["memory"][machineID]["currentBytes"][0];
var currentBytesOffHeap = data["memory"][machineID]["currentBytes"][1];
var isDeviceJVM = data["memory"][machineID]["isDevice"][1];
var isDeviceOffHeap = data["memory"][machineID]["isDevice"][1];
var maxBytesJVM = data["memory"][machineID]["maxBytes"][0];
var maxBytesOffHeap = data["memory"][machineID]["maxBytes"][1];
/* Inject Hardware Information */
$("#jvmAvailableProcessors").html(jvmAvailableProcessors);
$("#nComputeDevices").html(nComputeDevices);
/* Inject Software Information */
$("#OS").html(OS);
$("#hostName").html(hostName);
$("#OSArchitecture").html(OSArchitecture);
$("#jvmName").html(jvmName);
$("#jvmVersion").html(jvmVersion);
$("#nd4jBackend").html(nd4jBackend);
$("#nd4jDataType").html(nd4jDataType);
/* Inject Memory Information */
$("#currentBytesJVM").html(formatBytes(currentBytesJVM, 2));
$("#currentBytesOffHeap").html(formatBytes(currentBytesOffHeap, 2));
$("#isDeviceJVM").html(isDeviceJVM);
$("#isDeviceOffHeap").html(isDeviceOffHeap);
$("#maxBytesJVM").html(formatBytes(maxBytesJVM, 2));
$("#maxBytesOffHeap").html(formatBytes(maxBytesOffHeap, 2));
/* Inject GPU Information (TBD) */
}
/* ---------- GPU Layout ---------- */
function renderGPULayout(data) {
// var isDevice = data["memory"][machineID]["isDevice"][0];
var anyDevices = false;
var isDevice = data["memory"][machineID]["isDevice"];
if(isDevice ){
for(var i=0; i<isDevice.length; i++ ){
if(isDevice[i] == true){
anyDevices = true;
break;
}
}
}
//anyDevices = true; //For testing GPU charts on non-GPU system...
if (anyDevices == true) {
//$("#gpuTable").show();
$("#gpuMemoryChart").show();
$("#systemMemoryChart").attr("class", "box span6");
}
else {
//$("#gpuTable").hide();
$("#gpuMemoryChart").hide();
$("#systemMemoryChart").attr("class", "box span12");
}
}
/* ---------- Render System Dropdown ---------- */
function renderMultipleTabs(data) {
var nMachinesData = data["memory"];
var nMachines = Object.keys(nMachinesData);
/* Generate Tabs Depending on nMachines.length*/
for (i = 0; i < nMachines.length; i++) {
$('#systemTab').append("<li id=\"" + nMachines[i] + "\"><a href=\"javascript:void(0);\">Machine " + nMachines[i] + "</a></li>");
}
}
/* ---------- Set Machine ID Depending on Item Clicked ---------- */
function selectMachine() {
machineID = 0;
$('#systemTab').on("click", "li", function () {
machineID = $(this).attr('id');
lastUpdateTimeSystem = -1; //Reset last update time to force chart refresh
});
return machineID;
}
@@ -0,0 +1,231 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function languageSelect(languageCode, redirect){
//language code: iso639 code
var languageSettingUrl = multiSession ? "/setlang/" + currSession + "/" + languageCode : "/setlang/" + languageCode;
$.ajax({
url: languageSettingUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
redirectUrl = multiSession ? '/train/' + currSession + "/" + redirect : '/train/' + redirect;
window.location.replace(redirectUrl);
}
});
}
var multiSession = null;
var currSession = "";
var currWorkerIdx = 0;
var prevNumWorkers = 0;
function doUpdateSessionWorkerSelect() {
var sessionInfoUrl = multiSession ? "/train/" + currSession + "/info" : "/train/sessions/info";
$.ajax({
url: sessionInfoUrl,
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
var keys = Object.keys(data);
if(keys.length > 1) { //only show session selector if there are multiple sessions
var elem = $("#sessionSelect");
elem.empty();
var currSelectedIdx = 0;
for (var i = 0; i < keys.length; i++) {
if(keys[i] == currSession){
currSelectedIdx = i;
}
elem.append("<option value='" + keys[i] + "'>" + keys[i] + "</option>");
}
$("#sessionSelect option[value='" + keys[currSelectedIdx] +"']").attr("selected", "selected");
$("#sessionSelectDiv").show();
} else {
$("#sessionSelectDiv").hide();
}
//Set up worker selection...
if(data[currSession]){
var numWorkers = data[currSession]["numWorkers"];
var workers = data[currSession]["workers"];
var elem = $("#workerSelect");
elem.empty();
if(numWorkers > 1){
// if(numWorkers >= 0){ //For testing
for(var i=0; i<workers.length; i++){
elem.append("<option value='" + i + "'>" + workers[i] + "</option>");
}
$("#workerSelect option[value='" + currWorkerIdx +"']").attr("selected", "selected");
$("#workerSelectDiv").show();
} else {
$("#workerSelectDiv").hide();
}
// if workers change then reset
if(prevNumWorkers != numWorkers) {
if(numWorkers==0) {
$("#workerSelect").val("0");
selectNewWorker();
}
else selectNewWorker();
}
}
}
});
}
function getSessionIdFromUrl() {
// path is like /train/:sessionId/overview
var sessionIdRegexp = /\/train\/([^\/]+)\/(.*)/g;
var match = sessionIdRegexp.exec(window.location.pathname)
return match[1];
}
function getCurrSession(callback) {
if (multiSession) {
if (currSession == "") {
// get only once
currSession = getSessionIdFromUrl();
}
callback();
} else {
$.ajax({
url: "/train/sessions/current",
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
currSession = data;
callback();
}
});
}
}
function getSessionSettings(callback) {
// load only once
if (multiSession != null) {
getCurrSession(callback);
} else {
$.ajax({
url: "/train/multisession",
async: true,
error: function (query, status, error) {
console.log("Error getting data: " + error);
},
success: function (data) {
multiSession = data == "true";
getCurrSession(callback);
}
});
}
}
function updateSessionWorkerSelect(){
getSessionSettings(doUpdateSessionWorkerSelect);
}
function selectNewSession(){
var selector = $("#sessionSelect");
var currSelected = selector.val();
if(currSelected){
$.ajax({
url: "/train/sessions/set/" + currSelected,
async: true,
error: function (query, status, error) {
console.log("Error setting session: " + error);
},
success: function (data) {
}
});
}
}
function selectNewWorker(){
var selector = $("#workerSelect");
var currSelected = selector.val();
if(currSelected){
$.ajax({
url: "/train/workers/setByIdx/" + currSelected,
async: true,
error: function (query, status, error) {
console.log("Error setting session: " + error);
},
success: function (data) {
currWorkerIdx = currSelected;
}
});
}
}
function formatBytes(bytes, precision){
var index = 0;
var newValue = bytes;
while(newValue > 1024){
newValue = newValue/1024;
index++;
}
var unit = "";
switch (index){
case 0:
unit = "B";
break;
case 1:
unit = "kB";
break;
case 2:
unit = "MB";
break;
case 3:
unit = "GB";
break;
case 4:
unit = "TB";
break;
}
return newValue.toFixed(precision) + " " + unit;
}
/* ---------- Language Dropdown ---------- */
$('.dropmenu').click(function(e){
e.preventDefault();
$(this).parent().find('ul').slideToggle();
});
@@ -0,0 +1,67 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
function buildSessionSelector(event) {
buildSessionSelector2("/sessions?event=",event);
}
function buildSessionSelector2(urlPath, event){
$.ajax({
/*url:"/sessions?event=" + event,*/
url:urlPath + event,
async: true,
error: function (query, status, error) {
/*$.notify({
title: '<strong>No connection!</strong>',
message: 'DeepLearning4j UiServer seems to be down!'
},{
type: 'danger',
placement: {
from: "top",
align: "center"
},
});
setTimeout(buildSessionSelector(event), 2000);
*/
},
success: function( data ) {
if (data == undefined || data.length == 0) {
$("#sessionSelector").append("<option value='0' selected>No sessions available</option>");
return;
}
for (var i = 0; i < data.length; i++ ) {
$("#sessionSelector").append("<option value='"+ data[0]+"'>ID: "+data[0]+"</option>");
}
}
});
}
function getParameterByName(name) {
url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
@@ -0,0 +1,192 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
;(function($, window, document, undefined)
{
// Create the defaults once
var pluginName = "fileUpload",
defaults = {
uploadData : {},
submitData : {},
uploadOptions : {},
submitOptions : {},
before : function(){},
beforeSubmit : function(){ return true; },
success : function(){},
error : function(){},
complete : function(){}
};
// The actual plugin constructor
function Plugin(element, options)
{
this.element = element;
this.$form = $(element);
this.$uploaders = $('input[type=file]', this.element);
this.files = {};
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.init();
}
Plugin.prototype =
{
/**
* Initialize the plugin
*
* @return void
*/
init: function()
{
this.$uploaders.on('change', { context : this }, this.processFiles);
this.$form.on('submit', { context : this }, this.uploadFiles);
},
/**
* Process files after they are added
*
* @param jQuery event
* @return void
*/
processFiles: function(event)
{
var self = event.data.context;
self.files[$(event.target).attr('name')] = event.target.files;
},
/**
* Handles the file uploads
*
* @param jQuery event
* @return void
*/
uploadFiles: function(event)
{
event.stopPropagation(); // Stop stuff happening
event.preventDefault(); // Totally stop stuff happening
var self = event.data.context;
// Run the before callback
self.settings.before();
// Declare a form data object
var data = new FormData();
data.append('file_upload_incoming', '1');
// Add the files
$.each(self.files, function(key, field)
{
$.each(field, function(key, value)
{
data.append(key, value);
});
});
// If there is uploadData passed append it
$.each(self.settings.uploadData, function(key, value)
{
data.append(key, value);
});
// Perform Ajax call
$.ajax($.extend({}, {
url: self.$form.attr('action'),
type: 'POST',
data: data,
cache: false,
dataType: 'json',
processData: false, // Don't process the files, we're using FormData
contentType: false, // Set content type to false as jQuery will tell the server its a query string request
success: function(data, textStatus, jqXHR){
self.processSubmit(event, data);
self.settings.success(data);
},
error: function(jqXHR, textStatus, errorThrown){ self.settings.error(jqXHR, textStatus, errorThrown); }
}, self.settings.uploadOptions));
},
/**
* Submits form data with files
*
* @param jQuery event
* @param object
* @return void
*/
processSubmit: function(event, uploadData)
{
var self = event.data.context;
// Run the beforeSubmit callback
if(!self.settings.beforeSubmit(uploadData)) return;
// Serialize the form data
var data = self.$form.serializeArray();
// Loop through the returned array from the server and add it to the new POST
$.each(uploadData, function(key, value)
{
data.push({
'name' : key,
'value' : value
});
});
// If there is uploadData passed append it
$.each(self.settings.submitData, function(key, value)
{
data.push({
'name' : key,
'value' : value
});
});
/*
$.ajax($.extend({}, {
url: self.$form.attr('action'),
type: 'POST',
data: data,
cache: false,
dataType: 'json',
success: function(data, textStatus, jqXHR){ self.settings.success(data, textStatus, jqXHR); },
error: function(jqXHR, textStatus, errorThrown){ self.settings.error(jqXHR, textStatus, errorThrown); },
complete: function(jqXHR, textStatus){ self.settings.complete(jqXHR, textStatus); }
}, self.settings.submitOptions));*/
}
};
$.fn[pluginName] = function(options)
{
return this.each(function()
{
if(!$.data(this, "plugin_" + pluginName))
{
$.data(this, "plugin_" + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
@@ -0,0 +1,108 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
var x = [];
var y = [];
var name3 = [];
var tx = 0, ty = 0;
var ss = 1;
function zoomHandler() {
tx = d3.event.translate[0];
ty = d3.event.translate[1];
ss = d3.event.scale;
console.log('zoom called');
svg.selectAll('.u')
.data(name3)
.attr("transform", function(d, i) { return "translate(" +
((x[i]*20*ss + tx) + 400) + "," +
((y[i]*20*ss + ty) + 400) + ")";
});
}
var svg;
function drawEmbedding() {
$("#embed").empty();
var div = d3.select("#embed");
svg = div.append("svg") // svg is global
.attr("width", 60000)
.attr("height", 60000);
var g = svg.selectAll(".b")
.data(name3)
.enter().append("g")
.attr("class", "u");
g.append("text")
.attr("text-anchor", "top")
.attr("font-size", 12)
.attr("fill", "#333")
.text(function(d) { return d; });
svg.selectAll('.u')
.data(name3)
.attr("transform", function(d, i) { return "translate(" +
((x[i]*20*ss + tx) + 400) + "," +
((y[i]*20*ss + ty) + 400) + ")"; });
var zoomListener = d3.behavior.zoom()
.scaleExtent([0.1, 10])
.center([0,0])
.on("zoom", zoomHandler);
zoomListener(svg);
}
function drawTsne() {
$.ajax({
url: "/api/coords",
cache: false
})
.done(function( data ) {
for(var i = 0; i < data.length; i++) {
var split = data[i].split(',');
console.log(split.length);
var xCoord = split[0];
var yCoord = split[1];
var name2 = split[2];
x.push(xCoord);
y.push(yCoord);
name3.push(name2);
}
drawEmbedding();
});
}
$(document).ready(function() {
});
@@ -0,0 +1,270 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
var height = 700;
var width = 1024;
var x = [];
var y = [];
var name3 = [];
var renderSpace;
var xMax = 0, xMin = 0, yMax = 0, yMin = 0;
var xAxis;
var yAxis;
var xScale;
var yScale;
var currTsneSessionID = null;
function zoomFunction() {
var translateX = d3.event.translate[0];
var translateY = d3.event.translate[1];
var currentScale = d3.event.scale;
// console.log('zoom called. Scale: ' + currentScale + " translateX: " + translateX + " translateY: " + translateY);
//Redraw the x and y axis:
renderSpace.select(".x.axis").call(xAxis);
renderSpace.select(".y.axis").call(yAxis);
xAxisNode.selectAll('text').style("stroke-width", 0).style("fill", "#000000");
yAxisNode.selectAll('text').style("stroke-width", 0).style("fill", "#000000");
renderSpace.selectAll('circle')
.attr("cx", function (d, i) {
// return xScale(d.cx);
return xScale(d['xPos']);
})
.attr("cy", function (d, i) {
// return yScale(d.cy);
return yScale(d['yPos']);
});
renderSpace.selectAll(".tsneTextLabels")
.attr("x", function (d, i) {
// return xScale(d.cx);
return xScale(d['xPos']);
// return xScale(d);
})
.attr("y", function (d, i) {
// return yScale(d.cy);
return yScale(d['yPos']);
// return yScale(d);
});
}
var circleRadius = 2.0;
var textSize = "11pt";
var textColor = "red";
var gridColor = "#dddddd";
var marginLeft = 60;
var marginTop = 10;
var marginBottom = 30;
var marginRight = 10;
var widthExMargin = width - marginLeft - marginRight;
var heightExMargin = height - marginTop - marginBottom;
var zoom;
function centerFn(){
return d3.zoomIdentity.scale(0.00001);
}
function drawEmbedding() {
$("#embed").empty();
var div = d3.select("#embed");
xScale = d3.scale.linear().range([0, widthExMargin]);
yScale = d3.scale.linear().range([heightExMargin, 0]);
xAxis = d3.svg.axis().scale(xScale)
.innerTickSize(-heightExMargin) //Used as grid line
.orient("bottom").ticks(5);
yAxis = d3.svg.axis().scale(yScale)
.innerTickSize(-widthExMargin) //Used as grid line
.orient("left").ticks(5);
svg = div.append("svg") // svg is global
.attr("width", width)
.attr("height", height);
var xMin = d3.min(x);
var xMax = d3.max(x);
var yMin = d3.min(y);
var yMax = d3.max(y);
// zoom = d3.behavior.zoom()
var xRange = xMax - xMin;
var yRange = yMax - yMin;
var initialScale = 1.0 / Math.max(xRange, yRange);
zoom = d3.behavior.zoom()
.x(xScale)
.y(yScale)
.translate([widthExMargin/2, heightExMargin/2])
.scale(initialScale)
.on("zoom", zoomFunction);
var initialXScale;
var initialYScale;
if(xRange > yRange){
initialXScale = 1.0;
initialYScale = xRange / yRange;
} else {
initialXScale = yRange / xRange;
initialYScale = 1.0;
}
xScale.domain([initialXScale * xMin, initialXScale * xMax]);
yScale.domain([initialYScale * yMin, initialYScale * yMax]);
renderSpace = svg.append("g");
renderSpace.attr("transform", "translate(" + marginLeft + "," + marginTop + ")");
svg.call(zoom);
// Add the X Axis
xAxisNode = renderSpace.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + heightExMargin + ")")
.style("stroke", gridColor)
.style("stroke-width", "1.0")
.style("fill", "none")
.attr("font-size", textSize)
.call(xAxis);
xAxisNode.selectAll('text').style("stroke-width", 0).style("fill", "#000000");
// Add the Y Axis
yAxisNode = renderSpace.append("g")
.attr("class", "y axis")
.style("stroke", gridColor)
.style("stroke-width", "1.0")
.attr("font-size", textSize)
.style("fill", "none")
.call(yAxis);
yAxisNode.selectAll('text').style("stroke-width", 0).style("fill", "#000000");
// console.log("x/y min/max: " + xMin + ", " + xMax + ", " + yMin + ", " + yMax);
//Add the data
var data = x.map(function (d, i) {
return {'xPos': x[i], 'yPos': y[i], 'name': name3[i]};
});
renderSpace.selectAll("circle")
.data(data)
.enter()
.append("circle")
.style("fill", "#000000")
.attr("r", circleRadius)
.attr("cx", function (d) {
return xScale(d['xPos']);
})
.attr("cy", function (d) {
return yScale(d['yPos']);
});
renderSpace.selectAll("text")
.data(data)
.enter()
.append("text")
.text(function (d) {
return d['name'];
})
.attr("x", function (d) {
return xScale(d['xPos']);
})
.attr("y", function (d) {
return yScale(d['yPos']);
})
.attr("class", "tsneTextLabels")
.attr("font-family", "sans-serif")
.attr("font-size", textSize)
.attr("fill", textColor);
}
function drawTsne() {
if (currTsneSessionID == undefined) currTsneSessionID = "UploadedFile";
$.ajax({
url: "/tsne/coords/" + currTsneSessionID,
cache: false
})
.done(function (data) {
x = [];
y = [];
name3 = [];
if (data.length > 0) {
for (var i = 0; i < data.length; i++) {
var split = data[i].split(',');
var xCoord = parseFloat(split[0]);
var yCoord = parseFloat(split[1]);
var name2 = split[2];
x.push(xCoord);
y.push(yCoord);
name3.push(name2);
}
/*
This values could be pushed for debug purposes
x.push(10);
y.push(15);
name3.push("alpha");
*/
xMax = d3.max(x);
xMin = d3.min(x);
yMax = d3.max(y);
yMin = d3.min(y);
drawEmbedding();
} else {
$.notify({
title: '<strong>No t-SNE data available!</strong>',
message: 'Please upload something, or check again later.'
}, {
type: 'danger',
placement: {
from: "top",
align: "center"
}
});
}
});
}
function setSessionId(newID){
currTsneSessionID = newID;
drawTsne();
}
$(window).load(drawTsne());
@@ -0,0 +1,128 @@
/*
* ******************************************************************************
* *
* *
* * This program and the accompanying materials are made available under the
* * terms of the Apache License, Version 2.0 which is available at
* * https://www.apache.org/licenses/LICENSE-2.0.
* *
* * See the NOTICE file distributed with this work for additional
* * information regarding copyright ownership.
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* * License for the specific language governing permissions and limitations
* * under the License.
* *
* * SPDX-License-Identifier: Apache-2.0
* *****************************************************************************
*/
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/0eC6fl06luXEYWpBSJvXCBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/Fl4y0QdOxyyTHEGMXX8kcRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/-L14Jk06m6pUHB-5mXQQnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/I3S1wsgSg9YCurV6PUkTORJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/NYDWBdD4gIq26G5XYbHsFBJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/Pru33qjShpZSmG3z6VYwnRJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 300;
src: local('Roboto Light'), local('Roboto-Light'), url(http://fonts.gstatic.com/s/roboto/v15/Hgo13k-tfSpn0qi1SFdUfVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/ek4gzZ-GeXAPcSbHtCeQI_esZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F;
}
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/mErvLBYg_cXG3rLvUsKT_fesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/-2n2p-_Y08sg57CNWQfKNvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/u0TOpm082MNkS5K0Q4rhqvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0370-03FF;
}
/* vietnamese */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/NdF9MtnOpLzo-noMoG0miPesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0102-0103, U+1EA0-1EF9, U+20AB;
}
/* latin-ext */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/Fcx7Wwv8OzT71A3E1XOAjvesZW2xOQ-xsNqO47m55DA.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
src: local('Roboto'), local('Roboto-Regular'), url(http://fonts.gstatic.com/s/roboto/v15/CWB0XYA8bzo0kSThX0UTuA.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
@@ -0,0 +1,8 @@
train.pagetitle=DL4J Training
train.nav.overview=Übersicht
train.nav.model=Modell
train.nav.system=System
train.nav.userguide=Benutzeranleitung
train.nav.language=Sprache
train.session.label=Sitzung
train.session.worker.label=Auftrag
@@ -0,0 +1,8 @@
train.pagetitle=DL4J Training UI
train.nav.overview=Overview
train.nav.model=Model
train.nav.system=System
train.nav.userguide=User Guide
train.nav.language=Language
train.session.label=Session
train.session.worker.label=Worker
@@ -0,0 +1,8 @@
train.pagetitle=DL4J学習UI
train.nav.overview=概要
train.nav.model=モデル
train.nav.system=システム
train.nav.userguide=ユーザーガイド
train.nav.language=言語
train.session.label=セッション
train.session.worker.label=ワーカー
@@ -0,0 +1,7 @@
train.nav.overview=개요
train.nav.model=모델
train.nav.system=시스템
train.nav.userguide=사용자 가이드
train.nav.language=언어
train.session.label=Session
train.session.worker.label=Worker
@@ -0,0 +1,22 @@
train.model.layerInfoTable.title=Schichteninformation
train.model.activationsChart.title=Schichtenaktivierung
train.model.activationsChart.titleShort=Aktivierungen
train.model.lrChart.title=Parameter Lernrate
train.model.lrChart.titleShort=Lernrate
train.model.paramHistChart.title=Schichtenparameter-Histogram
train.model.updateHistChart.title=Schichtenaktualisierung-Histogram
train.model.meanmag.btn.ratio=Verhältnis
train.model.meanmag.btn.param=Parameter
train.model.meanmag.btn.update=Aktualisierungen
train.model.layerinfotable.layerName=Schichtenname
train.model.layerinfotable.layerType=Schichtentyp
train.model.layerinfotable.layerNIn=Eingangsgröße
train.model.layerinfotable.layerSize=Schichtenanzahl
train.model.layerinfotable.layerNParams=# Parameter
train.model.layerinfotable.layerActivationFn=Aktivierungsfunktion
train.model.layerinfotable.layerWeightInit=Anfangsgewichtung
train.model.layerinfotable.layerUpdater=Aktualisierung
train.model.layerinfotable.layerSubsamplingPoolingType=Pooling Art
train.model.layerinfotable.layerCnnKernel=Kernel Größe
train.model.layerinfotable.layerCnnStride=Schrittweite
train.model.layerinfotable.layerCnnPadding=Randgröße
@@ -0,0 +1,22 @@
train.model.layerInfoTable.title=Layer Information
train.model.activationsChart.title=Layer Activations
train.model.activationsChart.titleShort=Activations
train.model.lrChart.title=Parameter Learning Rates
train.model.lrChart.titleShort=Learning Rate
train.model.paramHistChart.title=Layer Parameters Histogram
train.model.updateHistChart.title=Layer Updates Histogram
train.model.meanmag.btn.ratio=Ratio
train.model.meanmag.btn.param=Param
train.model.meanmag.btn.update=Updates
train.model.layerinfotable.layerName=Layer Name
train.model.layerinfotable.layerType=Layer Type
train.model.layerinfotable.layerNIn=Input Size
train.model.layerinfotable.layerSize=Layer Size
train.model.layerinfotable.layerNParams=# Parameters
train.model.layerinfotable.layerActivationFn=Activation Function
train.model.layerinfotable.layerWeightInit=Weight Init.
train.model.layerinfotable.layerUpdater=Updater
train.model.layerinfotable.layerSubsamplingPoolingType=Pooling Type
train.model.layerinfotable.layerCnnKernel=Kernel Size
train.model.layerinfotable.layerCnnStride=Stride
train.model.layerinfotable.layerCnnPadding=Padding
@@ -0,0 +1,22 @@
train.model.layerInfoTable.title=レイヤー情報
train.model.activationsChart.title=レイヤー活性化
train.model.activationsChart.titleShort=活性化
train.model.lrChart.title=パラメータ学習率
train.model.lrChart.titleShort=学習率
train.model.paramHistChart.title=レイヤーパラメータヒストグラム
train.model.updateHistChart.title=レイヤー更新ヒストグラム
train.model.meanmag.btn.ratio=比率
train.model.meanmag.btn.param=パラメータ
train.model.meanmag.btn.update=更新
train.model.layerinfotable.layerName=レイヤー名
train.model.layerinfotable.layerType=レイヤータイプ
train.model.layerinfotable.layerNIn=入力サイズ
train.model.layerinfotable.layerSize=レイヤーサイズ
train.model.layerinfotable.layerNParams=パラメータ数
train.model.layerinfotable.layerActivationFn=活性化関数
train.model.layerinfotable.layerWeightInit=重みの初期値
train.model.layerinfotable.layerUpdater=更新の方法
train.model.layerinfotable.layerSubsamplingPoolingType=プーリングタイプ
train.model.layerinfotable.layerCnnKernel=カーネルサイズ
train.model.layerinfotable.layerCnnStride=ストライド
train.model.layerinfotable.layerCnnPadding=パディング
@@ -0,0 +1,17 @@
train.model.layerInfoTable.title=레이어 정보
train.model.activationsChart.title=레이어 액티베이션
train.model.activationsChart.titleShort=액티베이션
train.model.lrChart.title=파라미터 Learning Rates
train.model.paramHistChart.title=레이어 파라미터 히스토그램
train.model.updateHistChart.title=레이어 업데이트 히스토그램
train.model.meanmag.btn.ratio=Ratio
train.model.meanmag.btn.param=Param
train.model.meanmag.btn.update=Updates
train.model.layerinfotable.layerName=레이어 이름
train.model.layerinfotable.layerType=레이어 타입
train.model.layerinfotable.layerNIn=입력 크기
train.model.layerinfotable.layerSize=레이어 크기
train.model.layerinfotable.layerNParams=# 파라미터
train.model.layerinfotable.layerActivationFn=액티베이션 함수
train.model.layerinfotable.layerWeightInit=Weight 초기화
train.model.layerinfotable.layerCnnKernel=커널 크기
@@ -0,0 +1,22 @@
train.model.layerInfoTable.title=Информация о слое
train.model.activationsChart.title=Активации слоя
train.model.activationsChart.titleShort=Активации
train.model.lrChart.title=Скорость обучения (LR)
train.model.lrChart.titleShort=Скорость обучения
train.model.paramHistChart.title=Гистограмма параметров слоя
train.model.updateHistChart.title=Гистограмма обновлений слоя
train.model.meanmag.btn.ratio=Ratio
train.model.meanmag.btn.param=Param
train.model.meanmag.btn.update=Updates
train.model.layerinfotable.layerName=Имя слоя
train.model.layerinfotable.layerType=Тип слоя
train.model.layerinfotable.layerNIn=Кол-во входов
train.model.layerinfotable.layerSize=Размер слоя
train.model.layerinfotable.layerNParams=Кол-во параметров
train.model.layerinfotable.layerActivationFn=Функция активации
train.model.layerinfotable.layerWeightInit=Инициализация весов
train.model.layerinfotable.layerUpdater=Апдейтер
train.model.layerinfotable.layerSubsamplingPoolingType=Тип выборки
train.model.layerinfotable.layerCnnKernel=Размер ядра
train.model.layerinfotable.layerCnnStride=Шаг
train.model.layerinfotable.layerCnnPadding=Отступ
@@ -0,0 +1,22 @@
train.model.layerInfoTable.title=层详情
train.model.activationsChart.title=Layer Activations
train.model.activationsChart.titleShort=Activations
train.model.lrChart.title=Parameter Learning Rates
train.model.lrChart.titleShort=Learning Rate
train.model.paramHistChart.title=层 Parameters Histogram
train.model.updateHistChart.title=层 Updates Histogram
train.model.meanmag.btn.ratio=Ratio
train.model.meanmag.btn.param=Param
train.model.meanmag.btn.update=Updates
train.model.layerinfotable.layerName=层名称
train.model.layerinfotable.layerType=层类型
train.model.layerinfotable.layerNIn=输入大小
train.model.layerinfotable.layerSize=层大小
train.model.layerinfotable.layerNParams=参数个数
train.model.layerinfotable.layerActivationFn=激励函数
train.model.layerinfotable.layerWeightInit=权值初始化
train.model.layerinfotable.layerUpdater=更新器
train.model.layerinfotable.layerSubsamplingPoolingType=Pooling Type
train.model.layerinfotable.layerCnnKernel=内核大小
train.model.layerinfotable.layerCnnStride=Stride
train.model.layerinfotable.layerCnnPadding=填充值
@@ -0,0 +1,20 @@
train.overview.charts.iteration=Durchgang
train.overview.chart.scoreTitle=Modellverhältnis: Bewertung/Durchgang
train.overview.chart.scoreTitleShort=Bewertung
train.overview.chart.updateRatioTitle=Aktualisierung:Parameter Verhältnis (Mean Magnitudes)
train.overview.chart.updateRatioTitleShort=Verhältnis
train.overview.chart.stdevTitle=Standardabweichungen
train.overview.chart.stdevTitleShort=SD
train.overview.chart.stdevBtn.activations=Aktivierungen
train.overview.chart.stdevBtn.gradients=Anstiege
train.overview.chart.stdevBtn.updates=Aktualisierungen
train.overview.perftable.title=Modell und Trainingsinformation
train.overview.perftable.startTime=Startzeit
train.overview.perftable.totalRuntime=Laufzeit
train.overview.perftable.lastUpdate=Letzte Aktualisierung
train.overview.perftable.totalParamUpdates=Gesamte Parameter Aktualisierungen
train.overview.perftable.updatesPerSec=Aktualisierungen/sec
train.overview.perftable.examplesPerSec=Beispiele/sec
train.overview.modeltable.modeltype=Modelltyp
train.overview.modeltable.nParams=Anzahl der Parameter
train.overview.modeltable.nLayers=Schichten
@@ -0,0 +1,20 @@
train.overview.charts.iteration=Iteration
train.overview.chart.scoreTitle=Model Score vs. Iteration
train.overview.chart.scoreTitleShort=Score
train.overview.chart.updateRatioTitle=Update:Parameter Ratios (Mean Magnitudes)
train.overview.chart.updateRatioTitleShort=Ratio
train.overview.chart.stdevTitle=Standard Deviations
train.overview.chart.stdevTitleShort=St. Dev
train.overview.chart.stdevBtn.activations=Activations
train.overview.chart.stdevBtn.gradients=Gradients
train.overview.chart.stdevBtn.updates=Updates
train.overview.perftable.title=Model and Training Information
train.overview.perftable.startTime=Start Time
train.overview.perftable.totalRuntime=Total Runtime
train.overview.perftable.lastUpdate=Last Update
train.overview.perftable.totalParamUpdates=Total Parameter Updates
train.overview.perftable.updatesPerSec=Updates/sec
train.overview.perftable.examplesPerSec=Examples/sec
train.overview.modeltable.modeltype=Model Type
train.overview.modeltable.nParams=Total Parameters
train.overview.modeltable.nLayers=Layers
@@ -0,0 +1,20 @@
train.overview.charts.iteration=反復
train.overview.chart.scoreTitle=モデルスコア対反復
train.overview.chart.scoreTitleShort=スコア
train.overview.chart.updateRatioTitle=更新:パラメータの比率(平均大きさ)
train.overview.chart.updateRatioTitleShort=比率
train.overview.chart.stdevTitle=標準偏差
train.overview.chart.stdevTitleShort=SD
train.overview.chart.stdevBtn.activations=活性化
train.overview.chart.stdevBtn.gradients=勾配
train.overview.chart.stdevBtn.updates=更新
train.overview.perftable.title=モデルと学習の情報
train.overview.perftable.startTime=開始時間
train.overview.perftable.totalRuntime=合計実行時間
train.overview.perftable.lastUpdate=最後の更新
train.overview.perftable.totalParamUpdates=合計パラメータ更新
train.overview.perftable.updatesPerSec=更新/秒
train.overview.perftable.examplesPerSec=標本/秒
train.overview.modeltable.modeltype=モデルタイプ
train.overview.modeltable.nParams=パラメータ数
train.overview.modeltable.nLayers=レイヤー数
@@ -0,0 +1,20 @@
train.overview.charts.iteration=이터레이션
train.overview.chart.scoreTitle=모델 점수 vs. 이터레이션
train.overview.chart.scoreTitleShort=점수
train.overview.chart.updateRatioTitle=업데이트:파라미터 비율 (Mean Magnitudes)
train.overview.chart.updateRatioTitleShort=비율
train.overview.chart.stdevTitle=표준편차
train.overview.chart.stdevTitleShort=표준편차
train.overview.chart.stdevBtn.activations=액티베이션
train.overview.chart.stdevBtn.gradients=그레디언트
train.overview.chart.stdevBtn.updates=업데이트
train.overview.perftable.title=모델 및 학습 정보
train.overview.perftable.startTime=시작 시간
train.overview.perftable.totalRuntime=전체 실행시간
train.overview.perftable.lastUpdate=마지막 업데이트
train.overview.perftable.totalParamUpdates=전체 파라미터 업데이트
train.overview.perftable.updatesPerSec=업데이트/초
train.overview.perftable.examplesPerSec=Examples/초
train.overview.modeltable.modeltype=모델 종류
train.overview.modeltable.nParams=전체 파라미터 수
train.overview.modeltable.nLayers=레이어 수
@@ -0,0 +1,20 @@
train.overview.charts.iteration=Итерация
train.overview.chart.scoreTitle=Оценка модели в динамике
train.overview.chart.scoreTitleShort=Оценка модели
train.overview.chart.updateRatioTitle=Соотношения параметров (ср. величины)
train.overview.chart.updateRatioTitleShort=Соотношения
train.overview.chart.stdevTitle=Стандартное отклонение
train.overview.chart.stdevTitleShort=Стд. Откл.
train.overview.chart.stdevBtn.activations=Активации
train.overview.chart.stdevBtn.gradients=Градиенты
train.overview.chart.stdevBtn.updates=Обновления
train.overview.perftable.title=Информация о модели и обучении
train.overview.perftable.startTime=Время начала
train.overview.perftable.totalRuntime=Всего прошло
train.overview.perftable.lastUpdate=Последнее обновление
train.overview.perftable.totalParamUpdates=Всего обновлений
train.overview.perftable.updatesPerSec=Обновлений/сек
train.overview.perftable.examplesPerSec=Сэмплов/сек
train.overview.modeltable.modeltype=Тип модели
train.overview.modeltable.nParams=Всего параметров
train.overview.modeltable.nLayers=Кол-во слоев
@@ -0,0 +1,20 @@
train.overview.charts.iteration=Iteration
train.overview.chart.scoreTitle=模型评分与迭代
train.overview.chart.scoreTitleShort=评分
train.overview.chart.updateRatioTitle=更新:参数比率(平均幅度)
train.overview.chart.updateRatioTitleShort=比例
train.overview.chart.stdevTitle=标准差
train.overview.chart.stdevTitleShort=标准差
train.overview.chart.stdevBtn.activations=激活
train.overview.chart.stdevBtn.gradients=梯度
train.overview.chart.stdevBtn.updates=更新
train.overview.perftable.title=模型和训练详情
train.overview.perftable.startTime=开始时间
train.overview.perftable.totalRuntime=总运行时间
train.overview.perftable.lastUpdate=最后更新
train.overview.perftable.totalParamUpdates=总参数更新
train.overview.perftable.updatesPerSec=更新 / 秒
train.overview.perftable.examplesPerSec=例子 / 秒
train.overview.modeltable.modeltype=模型类型
train.overview.modeltable.nParams=总参数
train.overview.modeltable.nLayers=层
@@ -0,0 +1,8 @@
train.pagetitle=Интерфейс визуализации DeepLearning4j
train.nav.overview=Общая информация
train.nav.model=Модель
train.nav.system=Система
train.nav.userguide=Доп. информация
train.nav.language=Язык
train.session.label=Сессия
train.session.worker.label=Поток
@@ -0,0 +1,24 @@
train.system.title=Systeminformationen
train.system.selectMachine=Maschinenauswahl
train.system.chart.memoryShort=Speicher
train.system.chart.systemMemoryTitle=JVM und Off-Heap Speichernutzung
train.system.chart.gpuMemoryTitle=GPU Speichernutzung
train.system.chart.key.jvm=JVM Speicher
train.system.chart.key.offHeap=Off Heap Speicher
train.system.hwTable.title=Hardware Informationen
train.system.hwTable.jvmCurrent=JVM aktuelle Speichernutzung
train.system.hwTable.jvmMax=JVM maximale Speichernutzung
train.system.hwTable.offHeapCurrent=Off-Heap aktuelle Speichernutzung
train.system.hwTable.offHeapMax=Off-Heap maximale Speichernutzung
train.system.hwTable.jvmProcs=JVM verfügbare Prozessoren
train.system.hwTable.computeDevices=# Anzahl der Berechnungsinstanzen
train.system.hwTable.deviceMemory=Instanzspeicher
train.system.hwTable.deviceName=Instanzname
train.system.swTable.title=Software Informationen
train.system.swTable.hostname=Rechnername
train.system.swTable.os=OS
train.system.swTable.osArch=OS Architektur
train.system.swTable.jvmName=JVM Name
train.system.swTable.jvmVersion=JVM Version
train.system.swTable.nd4jBackend=ND4J Backend
train.system.swTable.nd4jDataType=ND4J Data Type
@@ -0,0 +1,24 @@
train.system.title=System Details
train.system.selectMachine=Select Machine
train.system.chart.memoryShort=Memory
train.system.chart.systemMemoryTitle=JVM and Off-Heap Memory Utilization
train.system.chart.gpuMemoryTitle=GPU Memory Utilization
train.system.chart.key.jvm=JVM Memory
train.system.chart.key.offHeap=Off Heap Memory
train.system.hwTable.title=Hardware Information
train.system.hwTable.jvmCurrent=JVM Current Memory
train.system.hwTable.jvmMax=JVM Max Memory
train.system.hwTable.offHeapCurrent=Off-Heap Current Memory
train.system.hwTable.offHeapMax=Off-Heap Max Memory
train.system.hwTable.jvmProcs=JVM Available Processors
train.system.hwTable.computeDevices=# Compute Devices
train.system.hwTable.deviceMemory=Device Memory
train.system.hwTable.deviceName=Device Name
train.system.swTable.title=Software Information
train.system.swTable.hostname=Host Name
train.system.swTable.os=OS
train.system.swTable.osArch=OS Architecture
train.system.swTable.jvmName=JVM Name
train.system.swTable.jvmVersion=JVM Version
train.system.swTable.nd4jBackend=ND4J Backend
train.system.swTable.nd4jDataType=ND4J Data Type
@@ -0,0 +1,24 @@
train.system.title=システム詳細
train.system.selectMachine=マシンを選択
train.system.chart.memoryShort=メモリ
train.system.chart.systemMemoryTitle=JVMとオフヒープのメモリ使用率
train.system.chart.gpuMemoryTitle=GPUメモリ使用率
train.system.chart.key.jvm=JVMメモリ
train.system.chart.key.offHeap=オフヒープメモリ
train.system.hwTable.title=ハードウェアの情報
train.system.hwTable.jvmCurrent=JVM現在メモリ
train.system.hwTable.jvmMax=JVM最大メモリ
train.system.hwTable.offHeapCurrent=オフヒープ現在メモリ
train.system.hwTable.offHeapMax=オフヒープ最大メモリ
train.system.hwTable.jvmProcs=JVM使用可能プロセッサ
train.system.hwTable.computeDevices=計算デバイス数
train.system.hwTable.deviceMemory=デバイスメモリ
train.system.hwTable.deviceName=デバイス名
train.system.swTable.title=ソフトウェアの情報
train.system.swTable.hostname=ホスト名
train.system.swTable.os=OSの種類
train.system.swTable.osArch=OSのアーキテクチャ
train.system.swTable.jvmName=JVM名
train.system.swTable.jvmVersion=JVMバージョン
train.system.swTable.nd4jBackend=ND4Jバックエンド
train.system.swTable.nd4jDataType=ND4Jデータ型
@@ -0,0 +1,24 @@
train.system.title=시스템 상세
train.system.selectMachine=Select Machine
train.system.chart.memoryShort=메모리
train.system.chart.systemMemoryTitle=JVM and Off-Heap Memory Utilization
train.system.chart.gpuMemoryTitle=GPU Memory Utilization
train.system.chart.key.jvm=JVM Memory
train.system.chart.key.offHeap=Off Heap Memory
train.system.hwTable.title=하드웨어 정보
train.system.hwTable.jvmCurrent=JVM 현재 메모리
train.system.hwTable.jvmMax=JVM 최대 메모리
train.system.hwTable.offHeapCurrent=Off-Heap 현재 메모리
train.system.hwTable.offHeapMax=Off-Heap 최대 메모리
train.system.hwTable.jvmProcs=JVM 사용가능 프로세서
train.system.hwTable.computeDevices=# Compute Devices
train.system.hwTable.deviceMemory=디바이스 메모리
train.system.hwTable.deviceName=Device Name
train.system.swTable.title=소프트웨어 정보
train.system.swTable.hostname=호스트 이름
train.system.swTable.os=운영체제
train.system.swTable.osArch=운영체제 구조
train.system.swTable.jvmName=JVM 이름
train.system.swTable.jvmVersion=JVM 버젼
train.system.swTable.nd4jBackend=ND4J Backend
train.system.swTable.nd4jDataType=ND4J 데이터 타입
@@ -0,0 +1,25 @@
train.system.title=Информация о системе
train.system.chart.memoryShort=Память
train.system.chart.jvmTitle=Использование памяти JVM
train.system.chart.offHeapTitle=Использование Off-Heap памяти
train.system.hwTable.title=Информация об оборудовании
train.system.hwTable.jvmCurrent=Занято JVM памяти
train.system.hwTable.jvmMax=Максимум JVM памяти
train.system.hwTable.offHeapCurrent=Занято Off-Heap памяти
train.system.hwTable.offHeapMax=Максимум Off-Heap памяти
train.system.hwTable.jvmProcs=Кол-во ядер
train.system.hwTable.computeDevices=Кол-во GPU
train.system.hwTable.deviceMemory=Память GPU
train.system.swTable.title=Информация о JVM и системе
train.system.swTable.hostname=Имя хоста
train.system.swTable.os=OS
train.system.swTable.osArch=Архитектура
train.system.swTable.jvmName=Название JVM
train.system.swTable.jvmVersion=Версия JVM
train.system.swTable.nd4jBackend=Используемый бэкенд
train.system.swTable.nd4jDataType=Используемый тип данных
train.system.chart.systemMemoryTitle=Общее использование памяти
train.system.chart.gpuMemoryTitle=Использование памяти GPU
train.system.selectMachine=Выберите сервер
train.system.chart.key.jvm=Память JVM
train.system.chart.key.offHeap=Off-Heap память
@@ -0,0 +1,24 @@
train.system.title=System Details
train.system.selectMachine=Select Machine
train.system.chart.memoryShort=Memory
train.system.chart.systemMemoryTitle=JVM and Off-Heap Memory Utilization
train.system.chart.gpuMemoryTitle=GPU Memory Utilization
train.system.chart.key.jvm=JVM Memory
train.system.chart.key.offHeap=Off Heap Memory
train.system.hwTable.title=硬件信息
train.system.hwTable.jvmCurrent=JVM当前内存
train.system.hwTable.jvmMax=JVM最大内存
train.system.hwTable.offHeapCurrent=堆外内存当前内存
train.system.hwTable.offHeapMax=堆外内存最大内存
train.system.hwTable.jvmProcs=JVM可用处理器
train.system.hwTable.computeDevices=计算机设备的数量
train.system.hwTable.deviceMemory=Device Memory
train.system.hwTable.deviceName=Device Name
train.system.swTable.title=Software Information
train.system.swTable.hostname=主机名
train.system.swTable.os=操作系统
train.system.swTable.osArch=操作系统架构
train.system.swTable.jvmName=JVM名
train.system.swTable.jvmVersion=JVM版本
train.system.swTable.nd4jBackend=ND4J后端
train.system.swTable.nd4jDataType=ND4J数据类型
@@ -0,0 +1,7 @@
train.pagetitle=DL4J Training UI
train.nav.overview=概述
train.nav.model=模型
train.nav.system=系统
train.nav.language=语言
train.session.label=Session
train.session.worker.label=Worker
@@ -0,0 +1,268 @@
<!DOCTYPE html>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~
~
~ This program and the accompanying materials are made available under the
~ terms of the Apache License, Version 2.0 which is available at
~ https://www.apache.org/licenses/LICENSE-2.0.
~
~ See the NOTICE file distributed with this work for additional
~ information regarding copyright ownership.
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
~ License for the specific language governing permissions and limitations
~ under the License.
~
~ SPDX-License-Identifier: Apache-2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>${train\.pagetitle}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/assets/webjars/coreui__coreui/2.1.9/dist/css/coreui.min.css">
<link rel="stylesheet" href="/assets/css/style.css">
<script src="/assets/webjars/jquery/3.4.1/dist/jquery.min.js"></script>
<script src="/assets/webjars/popper.js/1.12.9/dist/umd/popper.min.js"></script>
<script src="/assets/webjars/bootstrap/4.3.1/dist/js/bootstrap.min.js"></script>
<script src="/assets/webjars/coreui__coreui/2.1.9/dist/js/coreui.min.js"></script>
<!-- Icons -->
<link rel="stylesheet" href="/assets/webjars/coreui__icons/0.3.0/css/coreui-icons.min.css"></script>
<link rel="shortcut icon" href="/assets/img/favicon.ico">
</head>
<body class="app sidebar-show aside-menu-show">
<header class="app-header navbar">
<a class="header-text" href="#"><span>${train\.pagetitle}</span></a>
<div id="sessionSelectDiv" style="display:none; float:right;">
<div style="color:white;">${train\.session\.label}</div>
<select id="sessionSelect" onchange='selectNewSession()'>
<option>(Session ID)</option>
</select>
</div>
<div id="workerSelectDiv" style="display:none; float:right">
<div style="color:white;">${train\.session\.worker\.label}</div>
<select id="workerSelect" onchange='selectNewWorker()'>
<option>(Worker ID)</option>
</select>
</div>
</header>
<!-- End Header -->
<div class="app-body">
<div class="sidebar">
<nav class="sidebar-nav">
<ul class="nav">
<li class="nav-item"><a class="nav-link" href="overview"><i class="nav-icon cui-chart"></i>${train\.nav\.overview}</a></li>
<li class="nav-item"><a class="nav-link" href="model"><i class="nav-icon cui-graph"></i>${train\.nav\.model}</a></li>
<li class="nav-item"><a class="nav-link" href="system"><i class="nav-icon cui-speedometer"></i>${train\.nav\.system}</a></li>
<li class="nav-item nav-dropdown">
<a class="nav-link nav-dropdown-toggle" href="#">
<i class="nav-icon cui-globe"></i> ${train\.nav\.language}
</a>
<ul class="nav-dropdown-items">
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('en', 'overview')"><i class="icon-file-alt"></i>English</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('de', 'overview')"><i class="icon-file-alt"></i>Deutsch</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ja', 'overview')"><i class="icon-file-alt"></i>日本語</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('zh', 'overview')"><i class="icon-file-alt"></i>中文</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ko', 'overview')"><i class="icon-file-alt"></i>한글</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ru', 'overview')"><i class="icon-file-alt"></i>русский</a></li>
</ul>
</li>
</ul>
</nav>
</div>
<style>
/* Graph */
#layers {
height: 725px; /* IE8 */
height: 90vh;
width: 100%;
border: 2px solid #eee;
}
</style>
<!-- Start Content -->
<div id="content">
<div class="row">
<div class="col">
<div id="layers"></div>
</div>
<!-- Start Layer Details -->
<div class="col" id="layerDetails" style="width:50pc">
<div class="box">
<div class="chart-header">
<h2><b>${train\.model\.layerInfoTable\.title}</b></h2>
</div>
<div class="box-content">
<table class="table table-bordered table-striped table-condensed" id="layerInfo"></table>
</div>
</div>
<div class="box">
<div class="chart-header">
<h2><b>${train\.overview\.chart\.updateRatioTitle}</b></h2><p id="updateRatioTitleLog10"><b>: log<sub>10</sub></b></p>
<ul class="nav tab-menu nav-tabs" style="position:absolute; margin-top: -60px; right: 27px;">
<li id="mmRatioTab"><a href="javascript:void(0);" onclick="setSelectMeanMagChart('ratios')">${train\.model\.meanmag\.btn\.ratio}</a></li>
<li id="mmParamTab"><a href="javascript:void(0);" onclick="setSelectMeanMagChart('paramMM')">${train\.model\.meanmag\.btn\.param}</a></li>
<li id="mmUpdateTab"><a href="javascript:void(0);" onclick="setSelectMeanMagChart('updateMM')">${train\.model\.meanmag\.btn\.update}</a></li>
</ul>
</div>
<div class="box-content">
<div id="meanmag" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><span id="updateRatioTitleSmallLog10"><b>log<sub>
10</sub> ${train\.overview\.chart\.updateRatioTitleShort}</b></span> <span id="yMeanMagnitudes">0</span>, <b>${train\.overview\.charts\.iteration}:</b> <span id="xMeanMagnitudes">0</span></p>
</div>
</div>
<div class="box">
<div class="chart-header">
<h2><b>${train\.model\.activationsChart\.title}</b></h2>
</div>
<div class="box-content">
<div id="activations" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.model\.activationsChart\.titleShort}
:</b> <span id="yActivations">0</span>
, <b>${train\.overview\.charts\.iteration}
:</b> <span id="xActivations">0</span></p>
</div>
</div>
<div class="box">
<div class="chart-header">
<h2><b>${train\.model\.paramHistChart\.title}</b></h2>
<div id="paramhistSelected" style="float: left"></div>
<div id="paramHistButtonsDiv" style="float: right"></div>
</div>
<div class="box-content">
<div id="parametershistogram" class="center" style="height: 300px;"></div>
</div>
</div>
<div class="box">
<div class="chart-header">
<h2><b>${train\.model\.updateHistChart\.title}</b></h2>
<div id="updatehistSelected" style="float: left"></div>
<div id="updateHistButtonsDiv" style="float: right"></div>
</div>
<div class="box-content">
<div id="updateshistogram" class="center" style="height: 300px;"></div>
</div>
</div>
<div class="box">
<div class="chart-header">
<h2><b>${train\.model\.lrChart\.title}</b></h2>
</div>
<div class="box-content">
<div id="learningrate" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.model\.lrChart\.titleShort}
:</b> <span id="yLearningRate">0</span>
, <b>${train\.overview\.charts\.iteration}
:</b> <span id="xLearningRate">0</span></p>
</div>
</div>
</div>
<!-- End Layer Details-->
<!-- Begin Zero State -->
<div class="col" id="zeroState">
<div class="box">
<div class="chart-header">
<h2><b>Getting Started</b></h2>
</div>
<div class="box-content">
<div class="page-header">
<h1>Layer Visualization UI</h1>
</div>
<div class="row-fluid">
<div class="span12">
<h2>Overview</h2>
<p>
The layer visualization UI renders network structure dynamically. Users can inspect node layer parameters by clicking on the various elements of the GUI to see general information as well as overall network information such as performance.
</p>
<h2>Actions</h2>
<p>On the <b>left</b>, you will find an interactive layer visualization.</p>
<p>
<ul>
<li><b>Clicking</b> - Click on a layer to load network performance metrics.</li>
<li><b>Scrolling</b>
- Drag the GUI with your mouse or touchpad to move the model around. </li>
</ul>
</p>
</div>
</div>
</div>
</div>
</div>
<!-- End Zero State-->
</div>
</div>
<!-- End Content -->
</div> <!-- End Container -->
</div> <!-- End Row Fluid-->
<!-- Start JavaScript-->
<script src="/assets/webjars/modernizr/2.8.3/modernizr.min.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.pie.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.stack.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.resize.min.js"></script>
<script src="/assets/webjars/chosen/0.9.8/chosen/chosen.jquery.min.js"></script>
<script src="/assets/webjars/uniform/2.1.2/jquery.uniform.min.js"></script>
<script src="/assets/webjars/noty/2.2.2/jquery.noty.packaged.js"></script>
<script src="/assets/webjars/jquery-raty/2.5.2/jquery.raty.min.js"></script>
<script src="/assets/webjars/imagesloaded/2.1.1/jquery.imagesloaded.min.js"></script>
<script src="/assets/webjars/masonry/3.1.5/masonry.pkgd.min.js"></script>
<script src="/assets/webjars/jquery-knob/1.2.2/jquery.knob.min.js"></script>
<script src="/assets/webjars/jquery.sparkline/2.1.2/jquery.sparkline.min.js"></script>
<script src="/assets/webjars/retinajs/0.0.2/retina.js"></script>
<script src="/assets/webjars/dagre/0.8.4/dist/dagre.min.js"></script>
<script src="/assets/webjars/cytoscape/3.3.3/dist/cytoscape.min.js"></script>
<script src="/assets/webjars/cytoscape-dagre/2.1.0/cytoscape-dagre.js"></script>
<script src="/assets/webjars/github-com-jboesch-Gritter/1.7.4/jquery.gritter.js"></script>
<script src="/assets/js/train/model.js"></script> <!-- Charts and tables are generated here! -->
<script src="/assets/js/train/model-graph.js"></script> <!-- Layer graph generated here! -->
<script src="/assets/js/train/train.js"></script> <!-- Common (lang selection, etc) -->
<script src="/assets/js/counter.js"></script>
<!-- Execute once on page load -->
<script>
$(document).ready(function () {
renderModelGraph();
renderModelPage(true);
});
</script>
<!-- Execute periodically (every 2 sec) -->
<script>
setInterval(function () {
renderModelPage(false);
}, 2000);
</script>
</body>
</html>
@@ -0,0 +1,223 @@
<!DOCTYPE html>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~
~
~ This program and the accompanying materials are made available under the
~ terms of the Apache License, Version 2.0 which is available at
~ https://www.apache.org/licenses/LICENSE-2.0.
~
~ See the NOTICE file distributed with this work for additional
~ information regarding copyright ownership.
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
~ License for the specific language governing permissions and limitations
~ under the License.
~
~ SPDX-License-Identifier: Apache-2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>${train\.pagetitle}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/assets/webjars/coreui__coreui/2.1.9/dist/css/coreui.min.css">
<link rel="stylesheet" href="/assets/css/style.css">
<script src="/assets/webjars/jquery/3.4.1/dist/jquery.min.js"></script>
<script src="/assets/webjars/popper.js/1.12.9/dist/umd/popper.min.js"></script>
<script src="/assets/webjars/bootstrap/4.3.1/dist/js/bootstrap.min.js"></script>
<script src="/assets/webjars/coreui__coreui/2.1.9/dist/js/coreui.min.js"></script>
<!-- Icons -->
<link rel="stylesheet" href="/assets/webjars/coreui__icons/0.3.0/css/coreui-icons.min.css"></script>
<link rel="shortcut icon" href="/assets/img/favicon.ico">
</head>
<body class="app sidebar-show aside-menu-show">
<header class="app-header navbar">
<a class="header-text" href="#"><span>${train\.pagetitle}</span></a>
<div id="sessionSelectDiv" style="display:none; float:right;">
<div style="color:white;">${train\.session\.label}</div>
<select id="sessionSelect" onchange='selectNewSession()'>
<option>(Session ID)</option>
</select>
</div>
<div id="workerSelectDiv" style="display:none; float:right">
<div style="color:white;">${train\.session\.worker\.label}</div>
<select id="workerSelect" onchange='selectNewWorker()'>
<option>(Worker ID)</option>
</select>
</div>
</header>
<div class="app-body">
<div class="sidebar">
<nav class="sidebar-nav">
<ul class="nav">
<li class="nav-item"><a class="nav-link" href="overview"><i class="nav-icon cui-chart"></i>${train\.nav\.overview}</a></li>
<li class="nav-item"><a class="nav-link" href="model"><i class="nav-icon cui-graph"></i>${train\.nav\.model}</a></li>
<li class="nav-item"><a class="nav-link" href="system"><i class="nav-icon cui-speedometer"></i>${train\.nav\.system}</a></li>
<li class="nav-item nav-dropdown">
<a class="nav-link nav-dropdown-toggle" href="#">
<i class="nav-icon cui-globe"></i> ${train\.nav\.language}
</a>
<ul class="nav-dropdown-items">
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('en', 'overview')"><i class="icon-file-alt"></i>English</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('de', 'overview')"><i class="icon-file-alt"></i>Deutsch</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ja', 'overview')"><i class="icon-file-alt"></i>日本語</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('zh', 'overview')"><i class="icon-file-alt"></i>中文</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ko', 'overview')"><i class="icon-file-alt"></i>한글</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ru', 'overview')"><i class="icon-file-alt"></i>русский</a></li>
</ul>
</li>
</ul>
</nav>
</div>
<main id="content" class="main">
<div class="row">
<div class="col-8 chart-box">
<div class="chart-header">
<h2><b>${train\.overview\.chart\.scoreTitle}</b></h2>
</div>
<div>
<div id="scoreiterchart" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.overview\.chart\.scoreTitleShort}
:</b> <span id="y">0</span>, <b>${train\.overview\.charts\.iteration}
:</b> <span id="x">
0</span></p>
</div>
</div>
<!-- End Score Chart-->
<!-- Start Model Table-->
<div class="col-4 chart-box">
<div class="chart-header">
<h2><b>${train\.overview\.perftable\.title}</b></h2>
</div>
<div>
<table class="table table-bordered table-striped table-condensed">
<tr>
<td>${train\.overview\.modeltable\.modeltype}</td>
<td id="modelType">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.modeltable\.nLayers}</td>
<td id="nLayers">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.modeltable\.nParams}</td>
<td id="nParams">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.perftable\.startTime}</td>
<td id="startTime">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.perftable\.totalRuntime}</td>
<td id="totalRuntime">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.perftable\.lastUpdate}</td>
<td id="lastUpdate">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.perftable\.totalParamUpdates}</td>
<td id="totalParamUpdates">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.perftable\.updatesPerSec}</td>
<td id="updatesPerSec">Loading...</td>
</tr>
<tr>
<td>${train\.overview\.perftable\.examplesPerSec}</td>
<td id="examplesPerSec">Loading...</td>
</tr>
</table>
</div>
</div>
<!--End Model Table -->
</div>
<div class="row">
<!--Start Ratio Table -->
<div class="col chart-box">
<div class="chart-header">
<h2><b>${train\.overview\.chart\.updateRatioTitle}: log<sub>10</sub></b></h2>
</div>
<div class="box-content">
<div id="updateRatioChart" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.overview\.chart\.updateRatioTitleShort}
:</b> <span id="yRatio">0</span>, <b>log<sub>
10</sub> ${train\.overview\.chart\.updateRatioTitleShort}
:</b> <span id="yLogRatio">0</span>
, <b>${train\.overview\.charts\.iteration}:</b> <span id="xRatio">
0</span></p>
</div>
</div>
<!--End Ratio Table -->
<!--Start Variance Table -->
<div class="col chart-box">
<div class="chart-header">
<h2><b>${train\.overview\.chart\.stdevTitle}: log<sub>10</sub></b></h2>
<ul class="nav tab-menu nav-tabs" style="position:absolute; margin-top: -30px; right: 22px;">
<li class="active" id="stdevActivations"><a href="javascript:void(0);" onclick="selectStdevChart('stdevActivations')">${train\.overview\.chart\.stdevBtn\.activations}</a></li>
<li id="stdevGradients"><a href="javascript:void(0);" onclick="selectStdevChart('stdevGradients')">${train\.overview\.chart\.stdevBtn\.gradients}</a></li>
<li id="stdevUpdates"><a href="javascript:void(0);" onclick="selectStdevChart('stdevUpdates')">${train\.overview\.chart\.stdevBtn\.updates}</a></li>
</ul>
</div>
<div class="box-content">
<div id="stdevChart" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.overview\.chart\.stdevTitleShort}
:</b> <span id="yStdev">0</span>, <b>log<sub>
10</sub> ${train\.overview\.chart\.stdevTitleShort}
:</b> <span id="yLogStdev">0</span>
, <b>${train\.overview\.charts\.iteration}:</b> <span id="xStdev">
0</span></p>
</div>
</div>
<!-- End Variance Table -->
</div>
</main>
</div>
<script src="/assets/webjars/fullcalendar/1.6.4/fullcalendar.min.js"></script>
<script src="/assets/webjars/excanvas/3/excanvas.js"></script>
<script src="/assets/webjars/retinajs/0.0.2/retina.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.pie.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.stack.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.resize.min.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.selection.js"></script>
<script src="/assets/js/train/overview.js"></script> <!-- Charts and tables are generated here! -->
<script src="/assets/js/train/train.js"></script> <!-- Common (lang selection, etc) -->
<script src="/assets/js/counter.js"></script>
<!-- Execute once on page load -->
<script>
$(document).ready(function () {
renderOverviewPage(true);
});
</script>
<!-- Execute periodically (every 2 sec) -->
<script>
setInterval(function () {
renderOverviewPage(false);
}, 2000);
</script>
</body>
</html>
@@ -0,0 +1,260 @@
<!DOCTYPE html>
<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~
~
~ This program and the accompanying materials are made available under the
~ terms of the Apache License, Version 2.0 which is available at
~ https://www.apache.org/licenses/LICENSE-2.0.
~
~ See the NOTICE file distributed with this work for additional
~ information regarding copyright ownership.
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
~ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
~ License for the specific language governing permissions and limitations
~ under the License.
~
~ SPDX-License-Identifier: Apache-2.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
<html lang="en">
<head>
<meta charset="utf-8">
<title>${train\.pagetitle}</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="/assets/webjars/coreui__coreui/2.1.9/dist/css/coreui.min.css">
<link rel="stylesheet" href="/assets/css/style.css">
<script src="/assets/webjars/jquery/3.4.1/dist/jquery.min.js"></script>
<script src="/assets/webjars/popper.js/1.12.9/dist/umd/popper.min.js"></script>
<script src="/assets/webjars/bootstrap/4.3.1/dist/js/bootstrap.min.js"></script>
<script src="/assets/webjars/coreui__coreui/2.1.9/dist/js/coreui.min.js"></script>
<!-- Icons -->
<link rel="stylesheet" href="/assets/webjars/coreui__icons/0.3.0/css/coreui-icons.min.css"></script>
<link rel="shortcut icon" href="/assets/img/favicon.ico">
</head>
<body class="app sidebar-show aside-menu-show">
<header class="app-header navbar">
<a class="header-text" href="#"><span>${train\.pagetitle}</span></a>
<div id="sessionSelectDiv" style="display:none; float:right;">
<div style="color:white;">${train\.session\.label}</div>
<select id="sessionSelect" onchange='selectNewSession()'>
<option>(Session ID)</option>
</select>
</div>
<div id="workerSelectDiv" style="display:none; float:right">
<div style="color:white;">${train\.session\.worker\.label}</div>
<select id="workerSelect" onchange='selectNewWorker()'>
<option>(Worker ID)</option>
</select>
</div>
</header>
<div class="app-body">
<div class="sidebar">
<nav class="sidebar-nav">
<ul class="nav">
<li class="nav-item"><a class="nav-link" href="overview"><i class="nav-icon cui-chart"></i>${train\.nav\.overview}</a></li>
<li class="nav-item"><a class="nav-link" href="model"><i class="nav-icon cui-graph"></i>${train\.nav\.model}</a></li>
<li class="nav-item"><a class="nav-link" href="system"><i class="nav-icon cui-speedometer"></i>${train\.nav\.system}</a></li>
<li class="nav-item nav-dropdown">
<a class="nav-link nav-dropdown-toggle" href="#">
<i class="nav-icon cui-globe"></i> ${train\.nav\.language}
</a>
<ul class="nav-dropdown-items">
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('en', 'overview')"><i class="icon-file-alt"></i>English</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('de', 'overview')"><i class="icon-file-alt"></i>Deutsch</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ja', 'overview')"><i class="icon-file-alt"></i>日本語</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('zh', 'overview')"><i class="icon-file-alt"></i>中文</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ko', 'overview')"><i class="icon-file-alt"></i>한글</a></li>
<li class="nav-item"><a class="nav-link" href="javascript:void(0);" onclick="languageSelect('ru', 'overview')"><i class="icon-file-alt"></i>русский</a></li>
</ul>
</li>
</ul>
</nav>
</div>
<!-- Start Content -->
<main id="content" class="main">
<div class="row-fluid">
<div class="box span12">
<div class="chart-header">
<h2><b>${train\.system\.title}</b></h2>
<div class="btn-group" style="margin-top: -11px; position:absolute; right: 40px;">
<button class="btn dropdown-toggle btn-primary" data-toggle="dropdown">${train\.system\.selectMachine} <span class="caret"></span></button>
<ul class="dropdown-menu" id="systemTab"></ul>
</div>
</div>
<div class="box-content">
<!--Start System Information -->
<div class="tab-content">
<div class="tab-pane active">
<!-- System Memory Utilization Chart -->
<div class="row-fluid">
<div class="box span12" id="systemMemoryChart">
<div class="chart-header">
<h2><b>${train\.system\.chart\.systemMemoryTitle} %</b></h2>
</div>
<div class="box-content">
<div id="systemMemoryChartPlot" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.system\.chart\.memoryShort}:</b> <span id="y">0</span>, <b>
${train\.overview\.charts\.iteration}:</b> <span id="x">0</span></p>
</div>
</div>
<!-- GPU Memory Utlization Chart -->
<div class="box span6" id="gpuMemoryChart">
<div class="chart-header">
<h2><b>${train\.system\.chart\.gpuMemoryTitle} %</b></h2>
</div>
<div class="box-content">
<div id="gpuMemoryChartPlot" class="center" style="height: 300px;" ></div>
<p id="hoverdata"><b>${train\.system\.chart\.memoryShort}:</b> <span id="y2">0</span>, <b>
${train\.overview\.charts\.iteration}:</b> <span id="x2">0</span></p>
</div>
</div>
</div>
<!-- Tables -->
<div class="row-fluid">
<!-- Hardware Information -->
<div class="box span12">
<div class="chart-header">
<h2><b>${train\.system\.hwTable\.title}</b></h2>
</div>
<div class="box-content">
<table class="table table-striped">
<thead>
<tr>
<th>${train\.system\.hwTable\.jvmCurrent}</th>
<th>${train\.system\.hwTable\.jvmMax}</th>
<th>${train\.system\.hwTable\.offHeapCurrent}</th>
<th>${train\.system\.hwTable\.offHeapMax}</th>
<th>${train\.system\.hwTable\.jvmProcs}</th>
<th>${train\.system\.hwTable\.computeDevices}</th>
</tr>
</thead>
<tbody>
<tr>
<td id="currentBytesJVM">Loading...</td>
<td id="maxBytesJVM">Loading...</td>
<td id="currentBytesOffHeap">Loading...</td>
<td id="maxBytesOffHeap">Loading...</td>
<td id="jvmAvailableProcessors">Loading...</td>
<td id="nComputeDevices">Loading...</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="row-fluid">
<!-- Software Information -->
<div class="box span12">
<div class="chart-header">
<h2><b>${train\.system\.swTable\.title}</b></h2>
</div>
<div class="box-content">
<table class="table table-striped">
<thead>
<tr>
<th>${train\.system\.swTable\.hostname}</th>
<th>${train\.system\.swTable\.os}</th>
<th>${train\.system\.swTable\.osArch}</th>
<th>${train\.system\.swTable\.jvmName}</th>
<th>${train\.system\.swTable\.jvmVersion}</th>
<th>${train\.system\.swTable\.nd4jBackend}</th>
<th>${train\.system\.swTable\.nd4jDataType}</th>
</tr>
</thead>
<tbody>
<tr>
<td id="hostName">Loading...</td>
<td id="OS">Loading...</td>
<td id="OSArchitecture">Loading...</td>
<td id="jvmName">Loading...</td>
<td id="jvmVersion">Loading...</td>
<td id="nd4jBackend">Loading...</td>
<td id="nd4jDataType">Loading...</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<!-- End System Tab -->
</div>
</div>
</div>
<!-- End System Tab -->
</div><!-- End Row Fluid-->
</main><!-- End Content -->
</div><!-- End Container-->
</div><!-- End Row Fluid-->
<!-- Start JavaScript-->
<script src="/assets/webjars/jquery/2.2.0/jquery.min.js"></script>
<script src="/assets/webjars/jquery-ui/1.10.2/ui/minified/jquery-ui.min.js"></script>
<script src="/assets/webjars/jquery-migrate/1.2.1/jquery-migrate.min.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.pie.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.stack.js"></script>
<script src="/assets/webjars/flot/0.8.3/jquery.flot.resize.min.js"></script>
<script src="/assets/webjars/chosen/0.9.8/chosen/chosen.jquery.min.js"></script>
<script src="/assets/webjars/uniform/2.1.2/jquery.uniform.min.js"></script>
<script src="/assets/webjars/noty/2.2.2/jquery.noty.packaged.js"></script>
<script src="/assets/webjars/jquery-raty/2.5.2/jquery.raty.min.js"></script>
<script src="/assets/webjars/imagesloaded/2.1.1/jquery.imagesloaded.min.js"></script>
<script src="/assets/webjars/masonry/3.1.5/masonry.pkgd.min.js"></script>
<script src="/assets/webjars/jquery-knob/1.2.2/jquery.knob.min.js"></script>
<script src="/assets/webjars/jquery.sparkline/2.1.2/jquery.sparkline.min.js"></script>
<script src="/assets/webjars/retinajs/0.0.2/retina.js"></script>
<script src="/assets/js/train/system.js"></script> <!-- Charts and tables are generated here! -->
<script src="/assets/js/train/train.js"></script> <!-- Common (lang selection, etc) -->
<script src="/assets/js/counter.js"></script>
<!-- Execute once on page load -->
<script>
$(document).ready(function () {
renderSystemPage(true);
renderTabs();
selectMachine();
/* Default GPU to hidden */
$("#gpuTable").hide();
$("#gpuMemoryChart").hide();
});
</script>
<!--Execute periodically (every 2 sec) -->
<script>
setInterval(function () {
renderSystemPage(false);
}, 2000);
</script>
<!--End JavaScript-->
</body>
</html>