chore: import upstream snapshot with attribution
This commit is contained in:
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.activation;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Adam Gibson
|
||||
*/
|
||||
public @Data @NoArgsConstructor class PathUpdate implements Serializable {
|
||||
private String path;
|
||||
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.nearestneighbors.word2vec;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Adam Gibson
|
||||
*/
|
||||
public class NearestNeighborsQuery implements Serializable {
|
||||
private String word;
|
||||
private int numWords;
|
||||
|
||||
public NearestNeighborsQuery(String word, int numWords) {
|
||||
this.word = word;
|
||||
this.numWords = numWords;
|
||||
}
|
||||
|
||||
public NearestNeighborsQuery() {}
|
||||
|
||||
public String getWord() {
|
||||
return word;
|
||||
}
|
||||
|
||||
public void setWord(String word) {
|
||||
this.word = word;
|
||||
}
|
||||
|
||||
public int getNumWords() {
|
||||
return numWords;
|
||||
}
|
||||
|
||||
public void setNumWords(int numWords) {
|
||||
this.numWords = numWords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
NearestNeighborsQuery that = (NearestNeighborsQuery) o;
|
||||
|
||||
if (numWords != that.numWords)
|
||||
return false;
|
||||
return !(word != null ? !word.equals(that.word) : that.word != null);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = word != null ? word.hashCode() : 0;
|
||||
result = 31 * result + numWords;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.renders;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Adam Gibson
|
||||
*/
|
||||
public @Data @NoArgsConstructor class PathUpdate implements Serializable {
|
||||
private String path;
|
||||
|
||||
|
||||
}
|
||||
+789
@@ -0,0 +1,789 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.bytedeco.javacpp.Pointer;
|
||||
import org.deeplearning4j.config.DL4JClassLoading;
|
||||
import org.deeplearning4j.core.storage.StatsStorageRouter;
|
||||
import org.deeplearning4j.core.storage.StorageMetaData;
|
||||
import org.deeplearning4j.core.storage.listener.RoutingIterationListener;
|
||||
import org.deeplearning4j.nn.api.Layer;
|
||||
import org.deeplearning4j.nn.api.Model;
|
||||
import org.deeplearning4j.nn.conf.NeuralNetConfiguration;
|
||||
import org.deeplearning4j.nn.gradient.Gradient;
|
||||
import org.deeplearning4j.nn.graph.ComputationGraph;
|
||||
import org.deeplearning4j.nn.multilayer.MultiLayerNetwork;
|
||||
import org.deeplearning4j.ui.model.stats.api.*;
|
||||
import org.deeplearning4j.ui.model.storage.FileStatsStorage;
|
||||
import org.deeplearning4j.ui.model.storage.InMemoryStatsStorage;
|
||||
import org.deeplearning4j.ui.model.stats.impl.DefaultStatsInitializationConfiguration;
|
||||
import org.deeplearning4j.ui.model.stats.impl.DefaultStatsUpdateConfiguration;
|
||||
import org.deeplearning4j.core.util.UIDProvider;
|
||||
import org.nd4j.linalg.api.buffer.util.DataTypeUtil;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
import org.nd4j.nativeblas.NativeOps;
|
||||
import org.nd4j.nativeblas.NativeOpsHolder;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.management.GarbageCollectorMXBean;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public abstract class BaseStatsListener implements RoutingIterationListener {
|
||||
public static final String TYPE_ID = "StatsListener";
|
||||
|
||||
private enum StatType {
|
||||
Mean, Stdev, MeanMagnitude
|
||||
}
|
||||
|
||||
private StatsStorageRouter router;
|
||||
private final StatsInitializationConfiguration initConfig;
|
||||
private StatsUpdateConfiguration updateConfig;
|
||||
private String sessionID;
|
||||
private String workerID;
|
||||
|
||||
private transient List<GarbageCollectorMXBean> gcBeans;
|
||||
private Map<String, Pair<Long, Long>> gcStatsAtLastReport;
|
||||
|
||||
//NOTE: may have multiple models, due to multiple pretrain layers all using the same StatsListener
|
||||
private List<ModelInfo> modelInfos = new ArrayList<>();
|
||||
|
||||
private Map<String, Histogram> activationHistograms;
|
||||
private Map<String, Double> meanActivations; //TODO replace with Eclipse collections primitive maps...
|
||||
private Map<String, Double> stdevActivations;
|
||||
private Map<String, Double> meanMagActivations;
|
||||
|
||||
private Map<String, Histogram> gradientHistograms;
|
||||
private Map<String, Double> meanGradients; //TODO replace with Eclipse collections primitive maps...
|
||||
private Map<String, Double> stdevGradient;
|
||||
private Map<String, Double> meanMagGradients;
|
||||
|
||||
private static class ModelInfo implements Serializable {
|
||||
private final Model model;
|
||||
private long initTime;
|
||||
private long lastReportTime = -1;
|
||||
private int lastReportIteration = -1;
|
||||
private int examplesSinceLastReport = 0;
|
||||
private int minibatchesSinceLastReport = 0;
|
||||
|
||||
private long totalExamples = 0;
|
||||
private long totalMinibatches = 0;
|
||||
|
||||
private int iterCount = 0;
|
||||
|
||||
private ModelInfo(Model model) {
|
||||
this.model = model;
|
||||
}
|
||||
}
|
||||
|
||||
private ModelInfo getModelInfo(Model model) {
|
||||
ModelInfo mi = null;
|
||||
for (ModelInfo m : modelInfos) {
|
||||
if (m.model == model) {
|
||||
mi = m;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mi == null) {
|
||||
mi = new ModelInfo(model);
|
||||
modelInfos.add(mi);
|
||||
}
|
||||
return mi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected at every iteration.
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
*/
|
||||
public BaseStatsListener(StatsStorageRouter router) {
|
||||
this(router, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected every n >= 1 time steps
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
* @param listenerFrequency Frequency with which to collect stats information
|
||||
*/
|
||||
public BaseStatsListener(StatsStorageRouter router, int listenerFrequency) {
|
||||
this(router, null, new DefaultStatsUpdateConfiguration.Builder().reportingFrequency(listenerFrequency).build(),
|
||||
null, null);
|
||||
}
|
||||
|
||||
public BaseStatsListener(StatsStorageRouter router, StatsInitializationConfiguration initConfig,
|
||||
StatsUpdateConfiguration updateConfig, String sessionID, String workerID) {
|
||||
this.router = router;
|
||||
if (initConfig == null) {
|
||||
this.initConfig = new DefaultStatsInitializationConfiguration(true, true, true);
|
||||
} else {
|
||||
this.initConfig = initConfig;
|
||||
}
|
||||
if (updateConfig == null) {
|
||||
this.updateConfig = new DefaultStatsUpdateConfiguration.Builder().build();
|
||||
} else {
|
||||
this.updateConfig = updateConfig;
|
||||
}
|
||||
if (sessionID == null) {
|
||||
//TODO handle syncing session IDs across different listeners in the same model...
|
||||
this.sessionID = UUID.randomUUID().toString();
|
||||
} else {
|
||||
this.sessionID = sessionID;
|
||||
}
|
||||
if (workerID == null) {
|
||||
this.workerID = UIDProvider.getJVMUID() + "_" + Thread.currentThread().getId();
|
||||
} else {
|
||||
this.workerID = workerID;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract StatsInitializationReport getNewInitializationReport();
|
||||
|
||||
public abstract StatsReport getNewStatsReport();
|
||||
|
||||
// public abstract StorageMetaData getNewStorageMetaData();
|
||||
public abstract StorageMetaData getNewStorageMetaData(long initTime, String sessionID, String workerID);
|
||||
// Class<? extends StatsInitializationReport> initializationReportClass,
|
||||
// Class<? extends StatsReport> statsReportClass);
|
||||
//new SbeStorageMetaData(initTime, getSessionID(model), TYPE_ID, workerID, SbeStatsInitializationReport.class, SbeStatsReport.class);
|
||||
|
||||
|
||||
public StatsInitializationConfiguration getInitConfig() {
|
||||
return initConfig;
|
||||
}
|
||||
|
||||
public StatsUpdateConfiguration getUpdateConfig() {
|
||||
return updateConfig;
|
||||
}
|
||||
|
||||
public void setUpdateConfig(StatsUpdateConfiguration newConfig) {
|
||||
this.updateConfig = newConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStorageRouter(StatsStorageRouter router) {
|
||||
this.router = router;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsStorageRouter getStorageRouter() {
|
||||
return router;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorkerID(String workerID) {
|
||||
this.workerID = workerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorkerID() {
|
||||
return workerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionID(String sessionID) {
|
||||
this.sessionID = sessionID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSessionID() {
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
private String getSessionID(Model model) {
|
||||
if (model instanceof MultiLayerNetwork || model instanceof ComputationGraph)
|
||||
return sessionID;
|
||||
if (model instanceof Layer) {
|
||||
//Keep in mind MultiLayerNetwork implements Layer also...
|
||||
Layer l = (Layer) model;
|
||||
int layerIdx = l.getIndex();
|
||||
return sessionID + "_layer" + layerIdx;
|
||||
}
|
||||
return sessionID; //Should never happen
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEpochStart(Model model) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEpochEnd(Model model) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onForwardPass(Model model, List<INDArray> activations) {
|
||||
int iterCount = getModelInfo(model).iterCount;
|
||||
if (calcFromActivations() && (iterCount == 0 || iterCount % updateConfig.reportingFrequency() == 0)) {
|
||||
//Assumption: we have input, layer 0, layer 1, ...
|
||||
Map<String, INDArray> activationsMap = new HashMap<>();
|
||||
int count = 0;
|
||||
for (INDArray arr : activations) {
|
||||
String layerName = (count == 0 ? "input" : String.valueOf(count - 1));
|
||||
activationsMap.put(layerName, arr);
|
||||
count++;
|
||||
}
|
||||
onForwardPass(model, activationsMap);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onForwardPass(Model model, Map<String, INDArray> activations) {
|
||||
int iterCount = getModelInfo(model).iterCount;
|
||||
if (calcFromActivations() && updateConfig.reportingFrequency() > 0
|
||||
&& (iterCount == 0 || iterCount % updateConfig.reportingFrequency() == 0)) {
|
||||
if (updateConfig.collectHistograms(StatsType.Activations)) {
|
||||
activationHistograms = getHistograms(activations, updateConfig.numHistogramBins(StatsType.Activations));
|
||||
}
|
||||
if (updateConfig.collectMean(StatsType.Activations)) {
|
||||
meanActivations = calculateSummaryStats(activations, StatType.Mean);
|
||||
}
|
||||
if (updateConfig.collectStdev(StatsType.Activations)) {
|
||||
stdevActivations = calculateSummaryStats(activations, StatType.Stdev);
|
||||
}
|
||||
if (updateConfig.collectMeanMagnitudes(StatsType.Activations)) {
|
||||
meanMagActivations = calculateSummaryStats(activations, StatType.MeanMagnitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGradientCalculation(Model model) {
|
||||
int iterCount = getModelInfo(model).iterCount;
|
||||
if (calcFromGradients() && updateConfig.reportingFrequency() > 0
|
||||
&& (iterCount == 0 || iterCount % updateConfig.reportingFrequency() == 0)) {
|
||||
Gradient g = model.gradient();
|
||||
if (updateConfig.collectHistograms(StatsType.Gradients)) {
|
||||
gradientHistograms = getHistograms(g.gradientForVariable(), updateConfig.numHistogramBins(StatsType.Gradients));
|
||||
}
|
||||
|
||||
if (updateConfig.collectMean(StatsType.Gradients)) {
|
||||
meanGradients = calculateSummaryStats(g.gradientForVariable(), StatType.Mean);
|
||||
}
|
||||
if (updateConfig.collectStdev(StatsType.Gradients)) {
|
||||
stdevGradient = calculateSummaryStats(g.gradientForVariable(), StatType.Stdev);
|
||||
}
|
||||
if (updateConfig.collectMeanMagnitudes(StatsType.Gradients)) {
|
||||
meanMagGradients = calculateSummaryStats(g.gradientForVariable(), StatType.MeanMagnitude);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean calcFromActivations() {
|
||||
return updateConfig.collectMean(StatsType.Activations) || updateConfig.collectStdev(StatsType.Activations)
|
||||
|| updateConfig.collectMeanMagnitudes(StatsType.Activations)
|
||||
|| updateConfig.collectHistograms(StatsType.Activations);
|
||||
}
|
||||
|
||||
private boolean calcFromGradients() {
|
||||
return updateConfig.collectMean(StatsType.Gradients) || updateConfig.collectStdev(StatsType.Gradients)
|
||||
|| updateConfig.collectMeanMagnitudes(StatsType.Gradients)
|
||||
|| updateConfig.collectHistograms(StatsType.Gradients);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackwardPass(Model model) {
|
||||
//No op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iterationDone(Model model, int iteration, int epoch) {
|
||||
|
||||
ModelInfo modelInfo = getModelInfo(model);
|
||||
boolean backpropParamsOnly = backpropParamsOnly(model);
|
||||
|
||||
long currentTime = getTime();
|
||||
if (modelInfo.iterCount == 0) {
|
||||
modelInfo.initTime = currentTime;
|
||||
doInit(model);
|
||||
}
|
||||
|
||||
if (updateConfig.collectPerformanceStats()) {
|
||||
updateExamplesMinibatchesCounts(model);
|
||||
}
|
||||
|
||||
if (updateConfig.reportingFrequency() > 1 && (iteration == 0 || iteration % updateConfig.reportingFrequency() != 0)) {
|
||||
modelInfo.iterCount = iteration;
|
||||
return;
|
||||
}
|
||||
|
||||
StatsReport report = getNewStatsReport();
|
||||
report.reportIDs(getSessionID(model), TYPE_ID, workerID, System.currentTimeMillis()); //TODO support NTP time
|
||||
|
||||
//--- Performance and System Stats ---
|
||||
if (updateConfig.collectPerformanceStats()) {
|
||||
//Stats to collect: total runtime, total examples, total minibatches, iterations/second, examples/second
|
||||
double examplesPerSecond;
|
||||
double minibatchesPerSecond;
|
||||
if (modelInfo.iterCount == 0) {
|
||||
//Not possible to work out perf/second: first iteration...
|
||||
examplesPerSecond = 0.0;
|
||||
minibatchesPerSecond = 0.0;
|
||||
} else {
|
||||
long deltaTimeMS = currentTime - modelInfo.lastReportTime;
|
||||
examplesPerSecond = 1000.0 * modelInfo.examplesSinceLastReport / deltaTimeMS;
|
||||
minibatchesPerSecond = 1000.0 * modelInfo.minibatchesSinceLastReport / deltaTimeMS;
|
||||
}
|
||||
long totalRuntimeMS = currentTime - modelInfo.initTime;
|
||||
report.reportPerformance(totalRuntimeMS, modelInfo.totalExamples, modelInfo.totalMinibatches,
|
||||
examplesPerSecond, minibatchesPerSecond);
|
||||
|
||||
modelInfo.examplesSinceLastReport = 0;
|
||||
modelInfo.minibatchesSinceLastReport = 0;
|
||||
}
|
||||
|
||||
if (updateConfig.collectMemoryStats()) {
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
long jvmTotal = runtime.totalMemory();
|
||||
long jvmMax = runtime.maxMemory();
|
||||
|
||||
//Off-heap memory
|
||||
long offheapTotal = Pointer.totalBytes();
|
||||
long offheapMax = Pointer.maxBytes();
|
||||
|
||||
//GPU
|
||||
long[] gpuCurrentBytes = null;
|
||||
long[] gpuMaxBytes = null;
|
||||
NativeOps nativeOps =Nd4j.getNativeOps();
|
||||
int nDevices = nativeOps.getAvailableDevices();
|
||||
if (nDevices > 0) {
|
||||
gpuCurrentBytes = new long[nDevices];
|
||||
gpuMaxBytes = new long[nDevices];
|
||||
for (int i = 0; i < nDevices; i++) {
|
||||
try {
|
||||
gpuMaxBytes[i] = nativeOps.getDeviceTotalMemory(0);
|
||||
gpuCurrentBytes[i] = gpuMaxBytes[i] - nativeOps.getDeviceFreeMemory(0);
|
||||
} catch (Exception e) {
|
||||
log.error("",e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
report.reportMemoryUse(jvmTotal, jvmMax, offheapTotal, offheapMax, gpuCurrentBytes, gpuMaxBytes);
|
||||
}
|
||||
|
||||
if (updateConfig.collectGarbageCollectionStats()) {
|
||||
if (modelInfo.lastReportIteration == -1 || gcBeans == null) {
|
||||
//Haven't reported GC stats before...
|
||||
gcBeans = ManagementFactory.getGarbageCollectorMXBeans();
|
||||
gcStatsAtLastReport = new HashMap<>();
|
||||
for (GarbageCollectorMXBean bean : gcBeans) {
|
||||
long count = bean.getCollectionCount();
|
||||
long timeMs = bean.getCollectionTime();
|
||||
gcStatsAtLastReport.put(bean.getName(), new Pair<>(count, timeMs));
|
||||
}
|
||||
} else {
|
||||
for (GarbageCollectorMXBean bean : gcBeans) {
|
||||
long count = bean.getCollectionCount();
|
||||
long timeMs = bean.getCollectionTime();
|
||||
Pair<Long, Long> lastStats = gcStatsAtLastReport.get(bean.getName());
|
||||
long deltaGCCount = count - lastStats.getFirst();
|
||||
long deltaGCTime = timeMs - lastStats.getSecond();
|
||||
|
||||
lastStats.setFirst(count);
|
||||
lastStats.setSecond(timeMs);
|
||||
report.reportGarbageCollection(bean.getName(), (int) deltaGCCount, (int) deltaGCTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--- General ---
|
||||
report.reportScore(model.score()); //Always report score
|
||||
|
||||
if (updateConfig.collectLearningRates()) {
|
||||
Map<String, Double> lrs = new HashMap<>();
|
||||
if (model instanceof MultiLayerNetwork) {
|
||||
//Need to append "0_", "1_" etc to param names from layers...
|
||||
int layerIdx = 0;
|
||||
for (Layer l : ((MultiLayerNetwork) model).getLayers()) {
|
||||
NeuralNetConfiguration conf = l.conf();
|
||||
List<String> paramkeys = l.conf().getLayer().initializer().paramKeys(l.conf().getLayer());
|
||||
for (String s : paramkeys) {
|
||||
double lr = conf.getLayer().getUpdaterByParam(s).getLearningRate(l.getIterationCount(), l.getEpochCount());
|
||||
if (Double.isNaN(lr)) {
|
||||
//Edge case: No-Op updater, AdaDelta etc - don't have a LR hence return NaN for IUpdater.getLearningRate
|
||||
lr = 0.0;
|
||||
}
|
||||
lrs.put(layerIdx + "_" + s, lr);
|
||||
}
|
||||
layerIdx++;
|
||||
}
|
||||
} else if (model instanceof ComputationGraph) {
|
||||
for (Layer l : ((ComputationGraph) model).getLayers()) {
|
||||
NeuralNetConfiguration conf = l.conf();
|
||||
String layerName = conf.getLayer().getLayerName();
|
||||
List<String> paramkeys = l.conf().getLayer().initializer().paramKeys(l.conf().getLayer());
|
||||
for (String s : paramkeys) {
|
||||
double lr = conf.getLayer().getUpdaterByParam(s).getLearningRate(l.getIterationCount(), l.getEpochCount());
|
||||
if (Double.isNaN(lr)) {
|
||||
//Edge case: No-Op updater, AdaDelta etc - don't have a LR hence return NaN for IUpdater.getLearningRate
|
||||
lr = 0.0;
|
||||
}
|
||||
lrs.put(layerName + "_" + s, lr);
|
||||
}
|
||||
}
|
||||
} else if (model instanceof Layer) {
|
||||
Layer l = (Layer) model;
|
||||
List<String> paramkeys = l.conf().getLayer().initializer().paramKeys(l.conf().getLayer());
|
||||
for (String s : paramkeys) {
|
||||
double lr = l.conf().getLayer().getUpdaterByParam(s).getLearningRate(l.getIterationCount(), l.getEpochCount());
|
||||
lrs.put(s, lr);
|
||||
}
|
||||
}
|
||||
report.reportLearningRates(lrs);
|
||||
}
|
||||
|
||||
|
||||
//--- Histograms ---
|
||||
|
||||
if (updateConfig.collectHistograms(StatsType.Parameters)) {
|
||||
Map<String, Histogram> paramHistograms = getHistograms(model.paramTable(backpropParamsOnly),
|
||||
updateConfig.numHistogramBins(StatsType.Parameters));
|
||||
report.reportHistograms(StatsType.Parameters, paramHistograms);
|
||||
}
|
||||
|
||||
if (updateConfig.collectHistograms(StatsType.Gradients)) {
|
||||
report.reportHistograms(StatsType.Gradients, gradientHistograms);
|
||||
}
|
||||
|
||||
if (updateConfig.collectHistograms(StatsType.Updates)) {
|
||||
Map<String, Histogram> updateHistograms = getHistograms(model.gradient().gradientForVariable(),
|
||||
updateConfig.numHistogramBins(StatsType.Updates));
|
||||
report.reportHistograms(StatsType.Updates, updateHistograms);
|
||||
}
|
||||
|
||||
if (updateConfig.collectHistograms(StatsType.Activations)) {
|
||||
report.reportHistograms(StatsType.Activations, activationHistograms);
|
||||
}
|
||||
|
||||
|
||||
//--- Summary Stats: Mean, Variance, Mean Magnitudes ---
|
||||
|
||||
if (updateConfig.collectMean(StatsType.Parameters)) {
|
||||
Map<String, Double> meanParams = calculateSummaryStats(model.paramTable(backpropParamsOnly), StatType.Mean);
|
||||
report.reportMean(StatsType.Parameters, meanParams);
|
||||
}
|
||||
|
||||
if (updateConfig.collectMean(StatsType.Gradients)) {
|
||||
report.reportMean(StatsType.Gradients, meanGradients);
|
||||
}
|
||||
|
||||
if (updateConfig.collectMean(StatsType.Updates)) {
|
||||
Map<String, Double> meanUpdates =
|
||||
calculateSummaryStats(model.gradient().gradientForVariable(), StatType.Mean);
|
||||
report.reportMean(StatsType.Updates, meanUpdates);
|
||||
}
|
||||
|
||||
if (updateConfig.collectMean(StatsType.Activations)) {
|
||||
report.reportMean(StatsType.Activations, meanActivations);
|
||||
}
|
||||
|
||||
|
||||
if (updateConfig.collectStdev(StatsType.Parameters)) {
|
||||
Map<String, Double> stdevParams =
|
||||
calculateSummaryStats(model.paramTable(backpropParamsOnly), StatType.Stdev);
|
||||
report.reportStdev(StatsType.Parameters, stdevParams);
|
||||
}
|
||||
|
||||
if (updateConfig.collectStdev(StatsType.Gradients)) {
|
||||
report.reportStdev(StatsType.Gradients, stdevGradient);
|
||||
}
|
||||
|
||||
if (updateConfig.collectStdev(StatsType.Updates)) {
|
||||
Map<String, Double> stdevUpdates =
|
||||
calculateSummaryStats(model.gradient().gradientForVariable(), StatType.Stdev);
|
||||
report.reportStdev(StatsType.Updates, stdevUpdates);
|
||||
}
|
||||
|
||||
if (updateConfig.collectStdev(StatsType.Activations)) {
|
||||
report.reportStdev(StatsType.Activations, stdevActivations);
|
||||
}
|
||||
|
||||
|
||||
if (updateConfig.collectMeanMagnitudes(StatsType.Parameters)) {
|
||||
Map<String, Double> meanMagParams =
|
||||
calculateSummaryStats(model.paramTable(backpropParamsOnly), StatType.MeanMagnitude);
|
||||
report.reportMeanMagnitudes(StatsType.Parameters, meanMagParams);
|
||||
}
|
||||
|
||||
if (updateConfig.collectMeanMagnitudes(StatsType.Gradients)) {
|
||||
report.reportMeanMagnitudes(StatsType.Gradients, meanMagGradients);
|
||||
}
|
||||
|
||||
if (updateConfig.collectMeanMagnitudes(StatsType.Updates)) {
|
||||
Map<String, Double> meanMagUpdates =
|
||||
calculateSummaryStats(model.gradient().gradientForVariable(), StatType.MeanMagnitude);
|
||||
report.reportMeanMagnitudes(StatsType.Updates, meanMagUpdates);
|
||||
}
|
||||
|
||||
if (updateConfig.collectMeanMagnitudes(StatsType.Activations)) {
|
||||
report.reportMeanMagnitudes(StatsType.Activations, meanMagActivations);
|
||||
}
|
||||
|
||||
|
||||
long endTime = getTime();
|
||||
report.reportStatsCollectionDurationMS((int) (endTime - currentTime)); //Amount of time required to alculate all histograms, means etc.
|
||||
modelInfo.lastReportTime = currentTime;
|
||||
modelInfo.lastReportIteration = iteration;
|
||||
report.reportIterationCount(iteration);
|
||||
|
||||
this.router.putUpdate(report);
|
||||
|
||||
modelInfo.iterCount = iteration;
|
||||
activationHistograms = null;
|
||||
meanActivations = null;
|
||||
stdevActivations = null;
|
||||
meanMagActivations = null;
|
||||
gradientHistograms = null;
|
||||
meanGradients = null;
|
||||
stdevGradient = null;
|
||||
meanMagGradients = null;
|
||||
}
|
||||
|
||||
private long getTime() {
|
||||
//Abstraction to allow NTP to be plugged in later...
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private void doInit(Model model) {
|
||||
boolean backpropParamsOnly = backpropParamsOnly(model);
|
||||
long initTime = System.currentTimeMillis(); //TODO support NTP
|
||||
StatsInitializationReport initReport = getNewInitializationReport();
|
||||
initReport.reportIDs(getSessionID(model), TYPE_ID, workerID, initTime);
|
||||
|
||||
if (initConfig.collectSoftwareInfo()) {
|
||||
OperatingSystemMXBean osBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
String arch = osBean.getArch();
|
||||
String osName = osBean.getName();
|
||||
String jvmName = runtime.getVmName();
|
||||
String jvmVersion = System.getProperty("java.version");
|
||||
String jvmSpecVersion = runtime.getSpecVersion();
|
||||
|
||||
String nd4jBackendClass = Nd4j.getNDArrayFactory().getClass().getName();
|
||||
String nd4jDataTypeName = DataTypeUtil.getDtypeFromContext().name();
|
||||
|
||||
String hostname = System.getenv("COMPUTERNAME");
|
||||
if (hostname == null || hostname.isEmpty()) {
|
||||
try {
|
||||
Process proc = Runtime.getRuntime().exec("hostname");
|
||||
try (InputStream stream = proc.getInputStream()) {
|
||||
hostname = IOUtils.toString(stream);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
|
||||
Properties p = Nd4j.getExecutioner().getEnvironmentInformation();
|
||||
Map<String, String> envInfo = new HashMap<>();
|
||||
for (Map.Entry<Object, Object> e : p.entrySet()) {
|
||||
Object v = e.getValue();
|
||||
String value = (v == null ? "" : v.toString());
|
||||
envInfo.put(e.getKey().toString(), value);
|
||||
}
|
||||
|
||||
initReport.reportSoftwareInfo(arch, osName, jvmName, jvmVersion, jvmSpecVersion, nd4jBackendClass,
|
||||
nd4jDataTypeName, hostname, UIDProvider.getJVMUID(), envInfo);
|
||||
}
|
||||
|
||||
if (initConfig.collectHardwareInfo()) {
|
||||
int availableProcessors = Runtime.getRuntime().availableProcessors();
|
||||
NativeOps nativeOps =Nd4j.getNativeOps();
|
||||
int nDevices = nativeOps.getAvailableDevices();
|
||||
|
||||
long[] deviceTotalMem = null;
|
||||
String[] deviceDescription = null; //TODO
|
||||
if (nDevices > 0) {
|
||||
deviceTotalMem = new long[nDevices];
|
||||
deviceDescription = new String[nDevices];
|
||||
for (int i = 0; i < nDevices; i++) {
|
||||
try {
|
||||
deviceTotalMem[i] = nativeOps.getDeviceTotalMemory(i);
|
||||
deviceDescription[i] = nativeOps.getDeviceName(i);
|
||||
if (nDevices > 1) {
|
||||
deviceDescription[i] = deviceDescription[i] + " (" + i + ")";
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.debug("Error getting device info", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
long jvmMaxMemory = Runtime.getRuntime().maxMemory();
|
||||
long offheapMaxMemory = Pointer.maxBytes();
|
||||
|
||||
initReport.reportHardwareInfo(availableProcessors, nDevices, jvmMaxMemory, offheapMaxMemory, deviceTotalMem,
|
||||
deviceDescription, UIDProvider.getHardwareUID());
|
||||
}
|
||||
|
||||
if (initConfig.collectModelInfo()) {
|
||||
String jsonConf;
|
||||
int numLayers;
|
||||
long numParams;
|
||||
if (model instanceof MultiLayerNetwork) {
|
||||
MultiLayerNetwork net = ((MultiLayerNetwork) model);
|
||||
jsonConf = net.getLayerWiseConfigurations().toJson();
|
||||
numLayers = net.getnLayers();
|
||||
numParams = net.numParams();
|
||||
} else if (model instanceof ComputationGraph) {
|
||||
ComputationGraph cg = ((ComputationGraph) model);
|
||||
jsonConf = cg.getConfiguration().toJson();
|
||||
numLayers = cg.getNumLayers();
|
||||
numParams = cg.numParams();
|
||||
} else if (model instanceof Layer) {
|
||||
Layer l = (Layer) model;
|
||||
jsonConf = l.conf().toJson();
|
||||
numLayers = 1;
|
||||
numParams = l.numParams();
|
||||
} else {
|
||||
throw new RuntimeException("Invalid model: Expected MultiLayerNetwork or ComputationGraph. Got: "
|
||||
+ (model == null ? null : model.getClass()));
|
||||
}
|
||||
|
||||
Map<String, INDArray> paramMap = model.paramTable(backpropParamsOnly);
|
||||
String[] paramNames = new String[paramMap.size()];
|
||||
int i = 0;
|
||||
for (String s : paramMap.keySet()) { //Assuming sensible iteration order - LinkedHashMaps are used in MLN/CG for example
|
||||
paramNames[i++] = s;
|
||||
}
|
||||
|
||||
initReport.reportModelInfo(model.getClass().getName(), jsonConf, paramNames, numLayers, numParams);
|
||||
}
|
||||
|
||||
StorageMetaData meta = getNewStorageMetaData(initTime, getSessionID(model), workerID);
|
||||
|
||||
router.putStorageMetaData(meta);
|
||||
router.putStaticInfo(initReport); //TODO error handling
|
||||
}
|
||||
|
||||
private Map<Integer, Pointer> devPointers = new HashMap<>();
|
||||
|
||||
private synchronized Pointer getDevicePointer(int device) {
|
||||
if (devPointers.containsKey(device)) {
|
||||
return devPointers.get(device);
|
||||
}
|
||||
try {
|
||||
Pointer pointer = DL4JClassLoading.createNewInstance(
|
||||
"org.nd4j.jita.allocator.pointers.CudaPointer",
|
||||
Pointer.class,
|
||||
new Class[] { long.class },
|
||||
new Object[]{(long) device});
|
||||
|
||||
devPointers.put(device, pointer);
|
||||
return pointer;
|
||||
} catch (Throwable t) {
|
||||
devPointers.put(device, null); //Stops attempting the failure again later...
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateExamplesMinibatchesCounts(Model model) {
|
||||
ModelInfo modelInfo = getModelInfo(model);
|
||||
int examplesThisMinibatch = 0;
|
||||
if (model instanceof MultiLayerNetwork) {
|
||||
examplesThisMinibatch = model.batchSize();
|
||||
} else if (model instanceof ComputationGraph) {
|
||||
examplesThisMinibatch = model.batchSize();
|
||||
} else if (model instanceof Layer) {
|
||||
examplesThisMinibatch = ((Layer) model).getInputMiniBatchSize();
|
||||
}
|
||||
modelInfo.examplesSinceLastReport += examplesThisMinibatch;
|
||||
modelInfo.totalExamples += examplesThisMinibatch;
|
||||
modelInfo.minibatchesSinceLastReport++;
|
||||
modelInfo.totalMinibatches++;
|
||||
}
|
||||
|
||||
private boolean backpropParamsOnly(Model model) {
|
||||
//For pretrain layers (VAE, AE) we *do* want pretrain params also; for MLN and CG we only want backprop params
|
||||
// as we only have backprop gradients
|
||||
return model instanceof MultiLayerNetwork || model instanceof ComputationGraph;
|
||||
}
|
||||
|
||||
private static Map<String, Double> calculateSummaryStats(Map<String, INDArray> source, StatType statType) {
|
||||
Map<String, Double> out = new LinkedHashMap<>();
|
||||
|
||||
if (source == null)
|
||||
return out;
|
||||
|
||||
for (Map.Entry<String, INDArray> entry : source.entrySet()) {
|
||||
String name = entry.getKey();
|
||||
double value;
|
||||
switch (statType) {
|
||||
case Mean:
|
||||
value = entry.getValue().meanNumber().doubleValue();
|
||||
break;
|
||||
case Stdev:
|
||||
value = entry.getValue().stdNumber().doubleValue();
|
||||
break;
|
||||
case MeanMagnitude:
|
||||
value = entry.getValue().norm1Number().doubleValue() / entry.getValue().length();
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException(); //Should never happen
|
||||
}
|
||||
out.put(name, value);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private static Map<String, Histogram> getHistograms(Map<String, INDArray> map, int nBins) {
|
||||
Map<String, Histogram> out = new LinkedHashMap<>();
|
||||
|
||||
if (map == null)
|
||||
return out;
|
||||
|
||||
for (Map.Entry<String, INDArray> entry : map.entrySet()) {
|
||||
|
||||
org.nd4j.linalg.api.ops.impl.transforms.Histogram hOp =
|
||||
new org.nd4j.linalg.api.ops.impl.transforms.Histogram(entry.getValue(), nBins);
|
||||
Nd4j.exec(hOp);
|
||||
|
||||
INDArray bins = hOp.getOutputArgument(0);
|
||||
int[] count = new int[nBins];
|
||||
for (int i = 0; i < bins.length(); i++) {
|
||||
count[i] = (int) bins.getDouble(i);
|
||||
}
|
||||
|
||||
double min = entry.getValue().minNumber().doubleValue();
|
||||
double max = entry.getValue().maxNumber().doubleValue();
|
||||
|
||||
Histogram h = new Histogram(min, max, nBins, count);
|
||||
|
||||
out.put(entry.getKey(), h);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract BaseStatsListener clone();
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.deeplearning4j.core.storage.StatsStorageRouter;
|
||||
import org.deeplearning4j.core.storage.StorageMetaData;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationConfiguration;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationReport;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsReport;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsUpdateConfiguration;
|
||||
import org.deeplearning4j.ui.model.storage.FileStatsStorage;
|
||||
import org.deeplearning4j.ui.model.storage.InMemoryStatsStorage;
|
||||
import org.deeplearning4j.ui.model.storage.impl.JavaStorageMetaData;
|
||||
import org.deeplearning4j.ui.model.stats.impl.DefaultStatsUpdateConfiguration;
|
||||
import org.deeplearning4j.ui.model.stats.impl.java.JavaStatsInitializationReport;
|
||||
import org.deeplearning4j.ui.model.stats.impl.java.JavaStatsReport;
|
||||
|
||||
@Slf4j
|
||||
public class J7StatsListener extends BaseStatsListener {
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected at every iteration. Equivalent to {@link #J7StatsListener(StatsStorageRouter, int)}
|
||||
* with {@code listenerFrequency == 1}
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
*/
|
||||
public J7StatsListener(StatsStorageRouter router) {
|
||||
this(router, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected every n >= 1 time steps
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
* @param listenerFrequency Frequency with which to collect stats information
|
||||
*/
|
||||
public J7StatsListener(StatsStorageRouter router, int listenerFrequency) {
|
||||
this(router, null, new DefaultStatsUpdateConfiguration.Builder().reportingFrequency(listenerFrequency).build(),
|
||||
null, null);
|
||||
}
|
||||
|
||||
public J7StatsListener(StatsStorageRouter router, StatsInitializationConfiguration initConfig,
|
||||
StatsUpdateConfiguration updateConfig, String sessionID, String workerID) {
|
||||
super(router, initConfig, updateConfig, sessionID, workerID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsInitializationReport getNewInitializationReport() {
|
||||
return new JavaStatsInitializationReport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsReport getNewStatsReport() {
|
||||
return new JavaStatsReport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageMetaData getNewStorageMetaData(long initTime, String sessionID, String workerID) {
|
||||
return new JavaStorageMetaData(initTime, sessionID, TYPE_ID, workerID,
|
||||
JavaStatsInitializationReport.class, JavaStatsReport.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public J7StatsListener clone() {
|
||||
return new J7StatsListener(this.getStorageRouter(), this.getInitConfig(), this.getUpdateConfig(), null, null);
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.deeplearning4j.core.storage.StatsStorageRouter;
|
||||
import org.deeplearning4j.core.storage.StorageMetaData;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationConfiguration;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationReport;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsReport;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsUpdateConfiguration;
|
||||
import org.deeplearning4j.ui.model.storage.FileStatsStorage;
|
||||
import org.deeplearning4j.ui.model.storage.InMemoryStatsStorage;
|
||||
import org.deeplearning4j.ui.model.storage.impl.SbeStorageMetaData;
|
||||
import org.deeplearning4j.ui.model.stats.impl.DefaultStatsUpdateConfiguration;
|
||||
import org.deeplearning4j.ui.model.stats.impl.SbeStatsInitializationReport;
|
||||
import org.deeplearning4j.ui.model.stats.impl.SbeStatsReport;
|
||||
|
||||
@Slf4j
|
||||
public class StatsListener extends BaseStatsListener {
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected at every iteration. Equivalent to {@link #StatsListener(StatsStorageRouter, int)}
|
||||
* with {@code listenerFrequency == 1}
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
*/
|
||||
public StatsListener(StatsStorageRouter router) {
|
||||
this(router, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected every n >= 1 time steps
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
* @param listenerFrequency Frequency with which to collect stats information
|
||||
*/
|
||||
public StatsListener(StatsStorageRouter router, int listenerFrequency) {
|
||||
this(router, listenerFrequency, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a StatsListener with network information collected every n >= 1 time steps
|
||||
*
|
||||
* @param router Where/how to store the calculated stats. For example, {@link InMemoryStatsStorage} or
|
||||
* {@link FileStatsStorage}
|
||||
* @param listenerFrequency Frequency with which to collect stats information
|
||||
* @param sessionId The Session ID for storing the stats, optional (may be null)
|
||||
*/
|
||||
public StatsListener(StatsStorageRouter router, int listenerFrequency, String sessionId) {
|
||||
this(router, null, new DefaultStatsUpdateConfiguration.Builder().reportingFrequency(listenerFrequency).build(),
|
||||
sessionId, null);
|
||||
}
|
||||
|
||||
public StatsListener(StatsStorageRouter router, StatsInitializationConfiguration initConfig,
|
||||
StatsUpdateConfiguration updateConfig, String sessionID, String workerID) {
|
||||
super(router, initConfig, updateConfig, sessionID, workerID);
|
||||
}
|
||||
|
||||
public StatsListener clone() {
|
||||
return new StatsListener(this.getStorageRouter(), this.getInitConfig(), this.getUpdateConfig(), null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsInitializationReport getNewInitializationReport() {
|
||||
return new SbeStatsInitializationReport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StatsReport getNewStatsReport() {
|
||||
return new SbeStatsReport();
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageMetaData getNewStorageMetaData(long initTime, String sessionID, String workerID) {
|
||||
return new SbeStorageMetaData(initTime, sessionID, BaseStatsListener.TYPE_ID, workerID,
|
||||
SbeStatsInitializationReport.class, SbeStatsReport.class);
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class Histogram implements Serializable {
|
||||
private double min;
|
||||
private double max;
|
||||
private int nBins;
|
||||
private int[] binCounts;
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import org.deeplearning4j.ui.model.stats.StatsListener;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface StatsInitializationConfiguration extends Serializable {
|
||||
|
||||
/**
|
||||
* Should software configuration information be collected? For example, OS, JVM, and ND4J backend details
|
||||
*
|
||||
* @return true if software information should be collected; false if not
|
||||
*/
|
||||
boolean collectSoftwareInfo();
|
||||
|
||||
/**
|
||||
* Should hardware configuration information be collected? JVM available processors, number of devices, total memory for each device
|
||||
*
|
||||
* @return true if hardware information should be collected
|
||||
*/
|
||||
boolean collectHardwareInfo();
|
||||
|
||||
/**
|
||||
* Should model information be collected? Model class, configuration (JSON), number of layers, number of parameters, etc.
|
||||
*
|
||||
* @return true if model information should be collected
|
||||
*/
|
||||
boolean collectModelInfo();
|
||||
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import org.deeplearning4j.core.storage.Persistable;
|
||||
import org.deeplearning4j.ui.model.stats.StatsListener;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface StatsInitializationReport extends Persistable {
|
||||
|
||||
void reportIDs(String sessionID, String typeID, String workerID, long timestamp);
|
||||
|
||||
/**
|
||||
* @param arch Operating system architecture, as reported by JVM
|
||||
* @param osName Operating system name
|
||||
* @param jvmName JVM name
|
||||
* @param jvmVersion JVM version
|
||||
* @param jvmSpecVersion JVM Specification version (for example, 1.8)
|
||||
* @param nd4jBackendClass ND4J backend Factory class
|
||||
* @param nd4jDataTypeName ND4J datatype name
|
||||
* @param hostname Hostname for the machine, if available
|
||||
* @param jvmUID A unique identified for the current JVM. Should be shared by all instances in the same JVM.
|
||||
* Should vary for different JVMs on the same machine.
|
||||
* @param swEnvironmentInfo Environment information: Usually from Nd4j.getExecutioner().getEnvironmentInformation()
|
||||
*/
|
||||
void reportSoftwareInfo(String arch, String osName, String jvmName, String jvmVersion, String jvmSpecVersion,
|
||||
String nd4jBackendClass, String nd4jDataTypeName, String hostname, String jvmUID,
|
||||
Map<String, String> swEnvironmentInfo);
|
||||
|
||||
/**
|
||||
* @param jvmAvailableProcessors Number of available processor cores according to the JVM
|
||||
* @param numDevices Number of compute devices (GPUs)
|
||||
* @param jvmMaxMemory Maximum memory for the JVM
|
||||
* @param offHeapMaxMemory Maximum off-heap memory
|
||||
* @param deviceTotalMemory GPU memory by device: same length as numDevices. May be null, if numDevices is 0
|
||||
* @param deviceDescription Description of each device. May be null, if numDevices is 0
|
||||
* @param hardwareUID A unique identifier for the machine. Should be shared by all instances running on
|
||||
* the same machine, including in different JVMs
|
||||
*
|
||||
*/
|
||||
void reportHardwareInfo(int jvmAvailableProcessors, int numDevices, long jvmMaxMemory, long offHeapMaxMemory,
|
||||
long[] deviceTotalMemory, String[] deviceDescription, String hardwareUID);
|
||||
|
||||
|
||||
/**
|
||||
* Report the model information
|
||||
*
|
||||
* @param modelClassName Model class name: i.e., type of model
|
||||
* @param modelConfigJson Model configuration, as JSON string
|
||||
* @param numLayers Number of layers in the model
|
||||
* @param numParams Number of parameters in the model
|
||||
*/
|
||||
void reportModelInfo(String modelClassName, String modelConfigJson, String[] paramNames, int numLayers,
|
||||
long numParams);
|
||||
|
||||
|
||||
boolean hasSoftwareInfo();
|
||||
|
||||
boolean hasHardwareInfo();
|
||||
|
||||
boolean hasModelInfo();
|
||||
|
||||
String getSwArch();
|
||||
|
||||
String getSwOsName();
|
||||
|
||||
String getSwJvmName();
|
||||
|
||||
String getSwJvmVersion();
|
||||
|
||||
String getSwJvmSpecVersion();
|
||||
|
||||
String getSwNd4jBackendClass();
|
||||
|
||||
String getSwNd4jDataTypeName();
|
||||
|
||||
String getSwHostName();
|
||||
|
||||
String getSwJvmUID();
|
||||
|
||||
Map<String, String> getSwEnvironmentInfo();
|
||||
|
||||
int getHwJvmAvailableProcessors();
|
||||
|
||||
int getHwNumDevices();
|
||||
|
||||
long getHwJvmMaxMemory();
|
||||
|
||||
long getHwOffHeapMaxMemory();
|
||||
|
||||
long[] getHwDeviceTotalMemory();
|
||||
|
||||
String[] getHwDeviceDescription();
|
||||
|
||||
String getHwHardwareUID();
|
||||
|
||||
String getModelClassName();
|
||||
|
||||
String getModelConfigJson();
|
||||
|
||||
String[] getModelParamNames();
|
||||
|
||||
int getModelNumLayers();
|
||||
|
||||
long getModelNumParams();
|
||||
|
||||
}
|
||||
+322
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import org.deeplearning4j.core.storage.Persistable;
|
||||
import org.deeplearning4j.ui.model.stats.StatsListener;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface StatsReport extends Persistable {
|
||||
|
||||
void reportIDs(String sessionID, String typeID, String workerID, long timestamp);
|
||||
|
||||
/**
|
||||
* Report the current iteration number
|
||||
*/
|
||||
void reportIterationCount(int iterationCount);
|
||||
|
||||
/**
|
||||
* Get the current iteration number
|
||||
*/
|
||||
int getIterationCount();
|
||||
|
||||
/**
|
||||
* Report the number of milliseconds required to calculate all of the stats. This is effectively the
|
||||
* amount of listener overhead
|
||||
*/
|
||||
void reportStatsCollectionDurationMS(int statsCollectionDurationMS);
|
||||
|
||||
/**
|
||||
* Get the number of millisecons required to calculate al of the stats. This is effectively the amount of
|
||||
* listener overhead.
|
||||
*/
|
||||
int getStatsCollectionDurationMs();
|
||||
|
||||
/**
|
||||
* Report model score at the current iteration
|
||||
*/
|
||||
void reportScore(double currentScore);
|
||||
|
||||
/**
|
||||
* Get the score at the current iteration
|
||||
*/
|
||||
double getScore();
|
||||
|
||||
/**
|
||||
* Report the learning rates by parameter
|
||||
*/
|
||||
void reportLearningRates(Map<String, Double> learningRatesByParam);
|
||||
|
||||
/**
|
||||
* Get the learning rates by parameter
|
||||
*/
|
||||
Map<String, Double> getLearningRates();
|
||||
|
||||
|
||||
//--- Performance and System Stats ---
|
||||
|
||||
/**
|
||||
* Report the memory stats at this iteration
|
||||
*
|
||||
* @param jvmCurrentBytes Current bytes used by the JVM
|
||||
* @param jvmMaxBytes Max bytes usable by the JVM (heap)
|
||||
* @param offHeapCurrentBytes Current off-heap bytes used
|
||||
* @param offHeapMaxBytes Maximum off-heap bytes
|
||||
* @param deviceCurrentBytes Current bytes used by each device (GPU, etc). May be null if no devices are present
|
||||
* @param deviceMaxBytes Maximum bytes for each device (GPU, etc). May be null if no devices are present
|
||||
*/
|
||||
void reportMemoryUse(long jvmCurrentBytes, long jvmMaxBytes, long offHeapCurrentBytes, long offHeapMaxBytes,
|
||||
long[] deviceCurrentBytes, long[] deviceMaxBytes);
|
||||
|
||||
/**
|
||||
* Get JVM memory - current bytes used
|
||||
*/
|
||||
long getJvmCurrentBytes();
|
||||
|
||||
/**
|
||||
* Get JVM memory - max available bytes
|
||||
*/
|
||||
long getJvmMaxBytes();
|
||||
|
||||
/**
|
||||
* Get off-heap memory - current bytes used
|
||||
*/
|
||||
long getOffHeapCurrentBytes();
|
||||
|
||||
/**
|
||||
* Get off-heap memory - max available bytes
|
||||
*/
|
||||
long getOffHeapMaxBytes();
|
||||
|
||||
/**
|
||||
* Get device (GPU, etc) current bytes - may be null if no compute devices are present in the system
|
||||
*/
|
||||
long[] getDeviceCurrentBytes();
|
||||
|
||||
/**
|
||||
* Get device (GPU, etc) maximum bytes - may be null if no compute devices are present in the system
|
||||
*/
|
||||
long[] getDeviceMaxBytes();
|
||||
|
||||
/**
|
||||
* Report the performance stats (since the last report)
|
||||
*
|
||||
* @param totalRuntimeMs Overall runtime since initialization
|
||||
* @param totalExamples Total examples processed since initialization
|
||||
* @param totalMinibatches Total number of minibatches (iterations) since initialization
|
||||
* @param examplesPerSecond Examples per second since last report
|
||||
* @param minibatchesPerSecond Minibatches per second since last report
|
||||
*/
|
||||
void reportPerformance(long totalRuntimeMs, long totalExamples, long totalMinibatches, double examplesPerSecond,
|
||||
double minibatchesPerSecond);
|
||||
|
||||
/**
|
||||
* Get the total runtime since listener/model initialization
|
||||
*/
|
||||
long getTotalRuntimeMs();
|
||||
|
||||
/**
|
||||
* Get total number of examples that have been processed since initialization
|
||||
*/
|
||||
long getTotalExamples();
|
||||
|
||||
/**
|
||||
* Get the total number of minibatches that have been processed since initialization
|
||||
*/
|
||||
long getTotalMinibatches();
|
||||
|
||||
/**
|
||||
* Get examples per second since the last report
|
||||
*/
|
||||
double getExamplesPerSecond();
|
||||
|
||||
/**
|
||||
* Get the number of minibatches per second, since the last report
|
||||
*/
|
||||
double getMinibatchesPerSecond();
|
||||
|
||||
/**
|
||||
* Report Garbage collection stats
|
||||
*
|
||||
* @param gcName Garbage collector name
|
||||
* @param deltaGCCount Change in the total number of garbage collections, since last report
|
||||
* @param deltaGCTime Change in the amount of time (milliseconds) for garbage collection, since last report
|
||||
*/
|
||||
void reportGarbageCollection(String gcName, int deltaGCCount, int deltaGCTime);
|
||||
|
||||
/**
|
||||
* Get the garbage collection stats: Pair contains GC name and the delta count/time values
|
||||
*/
|
||||
List<Pair<String, int[]>> getGarbageCollectionStats();
|
||||
|
||||
//--- Histograms ---
|
||||
|
||||
/**
|
||||
* Report histograms for all parameters, for a given {@link StatsType}
|
||||
*
|
||||
* @param statsType StatsType: Parameters, Updates, Activations
|
||||
* @param histogram Histogram values for all parameters
|
||||
*/
|
||||
void reportHistograms(StatsType statsType, Map<String, Histogram> histogram);
|
||||
|
||||
/**
|
||||
* Get the histograms for all parameters, for a given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type (Params/updatse/activations) to get histograms for
|
||||
* @return Histograms by parameter name, or null if not available
|
||||
*/
|
||||
Map<String, Histogram> getHistograms(StatsType statsType);
|
||||
|
||||
//--- Summary Stats: Mean, Variance, Mean Magnitudes ---
|
||||
|
||||
/**
|
||||
* Report the mean values for each parameter, the given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type to report
|
||||
* @param mean Map of mean values, by parameter
|
||||
*/
|
||||
void reportMean(StatsType statsType, Map<String, Double> mean);
|
||||
|
||||
/**
|
||||
* Get the mean values for each parameter for the given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type to get mean values for
|
||||
* @return Map of mean values by parameter
|
||||
*/
|
||||
Map<String, Double> getMean(StatsType statsType);
|
||||
|
||||
/**
|
||||
* Report the standard deviation values for each parameter for the given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type to report std. dev values for
|
||||
* @param stdev Map of std dev values by parameter
|
||||
*/
|
||||
void reportStdev(StatsType statsType, Map<String, Double> stdev);
|
||||
|
||||
/**
|
||||
* Get the standard deviation values for each parameter for the given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type to get std dev values for
|
||||
* @return Map of stdev values by parameter
|
||||
*/
|
||||
Map<String, Double> getStdev(StatsType statsType);
|
||||
|
||||
/**
|
||||
* Report the mean magnitude values for each parameter for the given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type to report mean magnitude values for
|
||||
* @param meanMagnitudes Map of mean magnitude values by parameter
|
||||
*/
|
||||
void reportMeanMagnitudes(StatsType statsType, Map<String, Double> meanMagnitudes);
|
||||
|
||||
/**
|
||||
* Report any metadata for the DataSet
|
||||
*
|
||||
* @param dataSetMetaData MetaData for the DataSet
|
||||
* @param metaDataClass Class of the metadata. Can be later retieved using {@link #getDataSetMetaDataClassName()}
|
||||
*/
|
||||
void reportDataSetMetaData(List<Serializable> dataSetMetaData, Class<?> metaDataClass);
|
||||
|
||||
/**
|
||||
* Report any metadata for the DataSet
|
||||
*
|
||||
* @param dataSetMetaData MetaData for the DataSet
|
||||
* @param metaDataClass Class of the metadata. Can be later retieved using {@link #getDataSetMetaDataClassName()}
|
||||
*/
|
||||
void reportDataSetMetaData(List<Serializable> dataSetMetaData, String metaDataClass);
|
||||
|
||||
/**
|
||||
* Get the mean magnitude values for each parameter for the given StatsType (Parameters/Updates/Activations)
|
||||
*
|
||||
* @param statsType Stats type to get mean magnitude values for
|
||||
* @return Map of mean magnitude values by parameter
|
||||
*/
|
||||
Map<String, Double> getMeanMagnitudes(StatsType statsType);
|
||||
|
||||
/**
|
||||
* Get the DataSet metadata, if any (null otherwise).
|
||||
* Note: due to serialization issues, this may in principle throw an unchecked exception related
|
||||
* to class availability, serialization etc.
|
||||
*
|
||||
* @return List of DataSet metadata, if any.
|
||||
*/
|
||||
List<Serializable> getDataSetMetaData();
|
||||
|
||||
/**
|
||||
* Get the class
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String getDataSetMetaDataClassName();
|
||||
|
||||
/**
|
||||
* Return whether the score is present (has been reported)
|
||||
*/
|
||||
boolean hasScore();
|
||||
|
||||
/**
|
||||
* Return whether the learning rates are present (have been reported)
|
||||
*/
|
||||
boolean hasLearningRates();
|
||||
|
||||
/**
|
||||
* Return whether memory use has been reported
|
||||
*/
|
||||
boolean hasMemoryUse();
|
||||
|
||||
/**
|
||||
* Return whether performance stats (total time, total examples etc) have been reported
|
||||
*/
|
||||
boolean hasPerformance();
|
||||
|
||||
/**
|
||||
* Return whether garbage collection information has been reported
|
||||
*/
|
||||
boolean hasGarbageCollection();
|
||||
|
||||
/**
|
||||
* Return whether histograms have been reported, for the given stats type (Parameters, Updates, Activations)
|
||||
*
|
||||
* @param statsType Stats type
|
||||
*/
|
||||
boolean hasHistograms(StatsType statsType);
|
||||
|
||||
/**
|
||||
* Return whether the summary stats (mean, standard deviation, mean magnitudes) have been reported for the
|
||||
* given stats type (Parameters, Updates, Activations)
|
||||
*
|
||||
* @param statsType stats type (Parameters, Updates, Activations)
|
||||
* @param summaryType Summary statistic type (mean, stdev, mean magnitude)
|
||||
*/
|
||||
boolean hasSummaryStats(StatsType statsType, SummaryType summaryType);
|
||||
|
||||
|
||||
/**
|
||||
* Return whether any DataSet metadata is present or not
|
||||
*
|
||||
* @return True if DataSet metadata is present
|
||||
*/
|
||||
boolean hasDataSetMetaData();
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import org.deeplearning4j.ui.model.stats.StatsListener;
|
||||
|
||||
public enum StatsType {
|
||||
|
||||
Parameters, Gradients, Updates, Activations
|
||||
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public interface StatsUpdateConfiguration extends Serializable {
|
||||
|
||||
/**
|
||||
* Get the reporting frequency, in terms of listener calls
|
||||
*/
|
||||
int reportingFrequency();
|
||||
|
||||
//TODO
|
||||
//boolean useNTPTimeSource();
|
||||
|
||||
//--- Performance and System Stats ---
|
||||
|
||||
/**
|
||||
* Should performance stats be collected/reported?
|
||||
* Total time, total examples, total batches, Minibatches/second, examples/second
|
||||
*/
|
||||
boolean collectPerformanceStats();
|
||||
|
||||
/**
|
||||
* Should JVM, off-heap and memory stats be collected/reported?
|
||||
*/
|
||||
boolean collectMemoryStats();
|
||||
|
||||
/**
|
||||
* Should garbage collection stats be collected and reported?
|
||||
*/
|
||||
boolean collectGarbageCollectionStats();
|
||||
|
||||
//TODO
|
||||
// boolean collectDataSetMetaData();
|
||||
|
||||
//--- General ---
|
||||
|
||||
/**
|
||||
* Should per-parameter type learning rates be collected and reported?
|
||||
*/
|
||||
boolean collectLearningRates();
|
||||
|
||||
//--- Histograms ---
|
||||
|
||||
/**
|
||||
* Should histograms (per parameter type, or per layer for activations) of the given type be collected?
|
||||
*
|
||||
* @param type Stats type: Parameters, Updates, Activations
|
||||
*/
|
||||
boolean collectHistograms(StatsType type);
|
||||
|
||||
/**
|
||||
* Get the number of histogram bins to use for the given type (for use with {@link #collectHistograms(StatsType)}
|
||||
*
|
||||
* @param type Stats type: Parameters, Updates, Activatinos
|
||||
*/
|
||||
int numHistogramBins(StatsType type);
|
||||
|
||||
//--- Summary Stats: Mean, Variance, Mean Magnitudes ---
|
||||
|
||||
/**
|
||||
* Should the mean values (per parameter type, or per layer for activations) be collected?
|
||||
*
|
||||
* @param type Stats type: Parameters, Updates, Activations
|
||||
*/
|
||||
boolean collectMean(StatsType type);
|
||||
|
||||
/**
|
||||
* Should the standard devication values (per parameter type, or per layer for activations) be collected?
|
||||
*
|
||||
* @param type Stats type: Parameters, Updates, Activations
|
||||
*/
|
||||
boolean collectStdev(StatsType type);
|
||||
|
||||
/**
|
||||
* Should the mean magnitude values (per parameter type, or per layer for activations) be collected?
|
||||
*
|
||||
* @param type Stats type: Parameters, Updates, Activations
|
||||
*/
|
||||
boolean collectMeanMagnitudes(StatsType type);
|
||||
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.api;
|
||||
|
||||
import org.deeplearning4j.ui.model.stats.StatsListener;
|
||||
|
||||
public enum SummaryType {
|
||||
Mean, Stdev, MeanMagnitudes
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationConfiguration;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DefaultStatsInitializationConfiguration implements StatsInitializationConfiguration {
|
||||
|
||||
private final boolean collectSoftwareInfo;
|
||||
private final boolean collectHardwareInfo;
|
||||
private final boolean collectModelInfo;
|
||||
|
||||
@Override
|
||||
public boolean collectSoftwareInfo() {
|
||||
return collectSoftwareInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectHardwareInfo() {
|
||||
return collectHardwareInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectModelInfo() {
|
||||
return collectModelInfo;
|
||||
}
|
||||
}
|
||||
+308
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsType;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsUpdateConfiguration;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class DefaultStatsUpdateConfiguration implements StatsUpdateConfiguration {
|
||||
|
||||
public static final int DEFAULT_REPORTING_FREQUENCY = 10;
|
||||
|
||||
private int reportingFrequency = DEFAULT_REPORTING_FREQUENCY;
|
||||
private boolean collectPerformanceStats = true;
|
||||
private boolean collectMemoryStats = true;
|
||||
private boolean collectGarbageCollectionStats = true;
|
||||
private boolean collectLearningRates = true;
|
||||
private boolean collectHistogramsParameters = true;
|
||||
private boolean collectHistogramsGradients = true;
|
||||
private boolean collectHistogramsUpdates = true;
|
||||
private boolean collectHistogramsActivations = true;
|
||||
private int numHistogramBins = 20;
|
||||
private boolean collectMeanParameters = true;
|
||||
private boolean collectMeanGradients = true;
|
||||
private boolean collectMeanUpdates = true;
|
||||
private boolean collectMeanActivations = true;
|
||||
private boolean collectStdevParameters = true;
|
||||
private boolean collectStdevGradients = true;
|
||||
private boolean collectStdevUpdates = true;
|
||||
private boolean collectStdevActivations = true;
|
||||
private boolean collectMeanMagnitudesParameters = true;
|
||||
private boolean collectMeanMagnitudesGradients = true;
|
||||
private boolean collectMeanMagnitudesUpdates = true;
|
||||
private boolean collectMeanMagnitudesActivations = true;
|
||||
|
||||
private DefaultStatsUpdateConfiguration(Builder b) {
|
||||
this.reportingFrequency = b.reportingFrequency;
|
||||
this.collectPerformanceStats = b.collectPerformanceStats;
|
||||
this.collectMemoryStats = b.collectMemoryStats;
|
||||
this.collectGarbageCollectionStats = b.collectGarbageCollectionStats;
|
||||
this.collectLearningRates = b.collectLearningRates;
|
||||
this.collectHistogramsParameters = b.collectHistogramsParameters;
|
||||
this.collectHistogramsGradients = b.collectHistogramsGradients;
|
||||
this.collectHistogramsUpdates = b.collectHistogramsUpdates;
|
||||
this.collectHistogramsActivations = b.collectHistogramsActivations;
|
||||
this.numHistogramBins = b.numHistogramBins;
|
||||
this.collectMeanParameters = b.collectMeanParameters;
|
||||
this.collectMeanGradients = b.collectMeanGradients;
|
||||
this.collectMeanUpdates = b.collectMeanUpdates;
|
||||
this.collectMeanActivations = b.collectMeanActivations;
|
||||
this.collectStdevParameters = b.collectStdevParameters;
|
||||
this.collectStdevGradients = b.collectStdevGradients;
|
||||
this.collectStdevUpdates = b.collectStdevUpdates;
|
||||
this.collectStdevActivations = b.collectStdevActivations;
|
||||
this.collectMeanMagnitudesParameters = b.collectMeanMagnitudesParameters;
|
||||
this.collectMeanMagnitudesGradients = b.collectMeanMagnitudesGradients;
|
||||
this.collectMeanMagnitudesUpdates = b.collectMeanMagnitudesUpdates;
|
||||
this.collectMeanMagnitudesActivations = b.collectMeanMagnitudesActivations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int reportingFrequency() {
|
||||
return reportingFrequency;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectPerformanceStats() {
|
||||
return collectPerformanceStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectMemoryStats() {
|
||||
return collectMemoryStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectGarbageCollectionStats() {
|
||||
return collectGarbageCollectionStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectLearningRates() {
|
||||
return collectLearningRates;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectHistograms(StatsType type) {
|
||||
switch (type) {
|
||||
case Parameters:
|
||||
return collectHistogramsParameters;
|
||||
case Gradients:
|
||||
return collectStdevGradients;
|
||||
case Updates:
|
||||
return collectHistogramsUpdates;
|
||||
case Activations:
|
||||
return collectHistogramsActivations;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int numHistogramBins(StatsType type) {
|
||||
return numHistogramBins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectMean(StatsType type) {
|
||||
switch (type) {
|
||||
case Parameters:
|
||||
return collectMeanParameters;
|
||||
case Gradients:
|
||||
return collectMeanGradients;
|
||||
case Updates:
|
||||
return collectMeanUpdates;
|
||||
case Activations:
|
||||
return collectMeanActivations;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectStdev(StatsType type) {
|
||||
switch (type) {
|
||||
case Parameters:
|
||||
return collectStdevParameters;
|
||||
case Gradients:
|
||||
return collectStdevGradients;
|
||||
case Updates:
|
||||
return collectStdevUpdates;
|
||||
case Activations:
|
||||
return collectStdevActivations;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collectMeanMagnitudes(StatsType type) {
|
||||
switch (type) {
|
||||
case Parameters:
|
||||
return collectMeanMagnitudesParameters;
|
||||
case Gradients:
|
||||
return collectMeanMagnitudesGradients;
|
||||
case Updates:
|
||||
return collectMeanMagnitudesUpdates;
|
||||
case Activations:
|
||||
return collectMeanMagnitudesActivations;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private int reportingFrequency = DEFAULT_REPORTING_FREQUENCY;
|
||||
private boolean collectPerformanceStats = true;
|
||||
private boolean collectMemoryStats = true;
|
||||
private boolean collectGarbageCollectionStats = true;
|
||||
private boolean collectLearningRates = true;
|
||||
private boolean collectHistogramsParameters = true;
|
||||
private boolean collectHistogramsGradients = true;
|
||||
private boolean collectHistogramsUpdates = true;
|
||||
private boolean collectHistogramsActivations = true;
|
||||
private int numHistogramBins = 20;
|
||||
private boolean collectMeanParameters = true;
|
||||
private boolean collectMeanGradients = true;
|
||||
private boolean collectMeanUpdates = true;
|
||||
private boolean collectMeanActivations = true;
|
||||
private boolean collectStdevParameters = true;
|
||||
private boolean collectStdevGradients = true;
|
||||
private boolean collectStdevUpdates = true;
|
||||
private boolean collectStdevActivations = true;
|
||||
private boolean collectMeanMagnitudesParameters = true;
|
||||
private boolean collectMeanMagnitudesGradients = true;
|
||||
private boolean collectMeanMagnitudesUpdates = true;
|
||||
private boolean collectMeanMagnitudesActivations = true;
|
||||
|
||||
public Builder reportingFrequency(int reportingFrequency) {
|
||||
this.reportingFrequency = reportingFrequency;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectPerformanceStats(boolean collectPerformanceStats) {
|
||||
this.collectPerformanceStats = collectPerformanceStats;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMemoryStats(boolean collectMemoryStats) {
|
||||
this.collectMemoryStats = collectMemoryStats;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectGarbageCollectionStats(boolean collectGarbageCollectionStats) {
|
||||
this.collectGarbageCollectionStats = collectGarbageCollectionStats;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectLearningRates(boolean collectLearningRates) {
|
||||
this.collectLearningRates = collectLearningRates;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectHistogramsParameters(boolean collectHistogramsParameters) {
|
||||
this.collectHistogramsParameters = collectHistogramsParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectHistogramsGradients(boolean collectHistogramsGradients) {
|
||||
this.collectHistogramsGradients = collectHistogramsGradients;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectHistogramsUpdates(boolean collectHistogramsUpdates) {
|
||||
this.collectHistogramsUpdates = collectHistogramsUpdates;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectHistogramsActivations(boolean isCollectHistogramsActivations) {
|
||||
this.collectHistogramsActivations = isCollectHistogramsActivations;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder numHistogramBins(int numHistogramBins) {
|
||||
this.numHistogramBins = numHistogramBins;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanParameters(boolean collectMeanParameters) {
|
||||
this.collectMeanParameters = collectMeanParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanGradients(boolean collectMeanGradients) {
|
||||
this.collectMeanGradients = collectMeanGradients;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanUpdates(boolean collectMeanUpdates) {
|
||||
this.collectMeanUpdates = collectMeanUpdates;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanActivations(boolean collectMeanActivations) {
|
||||
this.collectMeanActivations = collectMeanActivations;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectStdevParameters(boolean collectStdevParameters) {
|
||||
this.collectStdevParameters = collectStdevParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectStdevGradients(boolean collectStdevGradients) {
|
||||
this.collectStdevGradients = collectStdevGradients;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectStdevUpdates(boolean collectStdevUpdates) {
|
||||
this.collectStdevUpdates = collectStdevUpdates;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectStdevActivations(boolean collectStdevActivations) {
|
||||
this.collectStdevActivations = collectStdevActivations;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanMagnitudesParameters(boolean collectMeanMagnitudesParameters) {
|
||||
this.collectMeanMagnitudesParameters = collectMeanMagnitudesParameters;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanMagnitudesGradients(boolean collectMeanMagnitudesGradients) {
|
||||
this.collectMeanMagnitudesGradients = collectMeanMagnitudesGradients;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanMagnitudesUpdates(boolean collectMeanMagnitudesUpdates) {
|
||||
this.collectMeanMagnitudesUpdates = collectMeanMagnitudesUpdates;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder collectMeanMagnitudesActivations(boolean collectMeanMagnitudesActivations) {
|
||||
this.collectMeanMagnitudesActivations = collectMeanMagnitudesActivations;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DefaultStatsUpdateConfiguration build() {
|
||||
return new DefaultStatsUpdateConfiguration(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
+468
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.impl;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
import org.agrona.concurrent.UnsafeBuffer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationReport;
|
||||
import org.deeplearning4j.ui.model.stats.sbe.*;
|
||||
import org.deeplearning4j.ui.model.storage.AgronaPersistable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class SbeStatsInitializationReport implements StatsInitializationReport, AgronaPersistable {
|
||||
|
||||
private String sessionID;
|
||||
private String typeID;
|
||||
private String workerID;
|
||||
private long timeStamp;
|
||||
|
||||
private boolean hasSoftwareInfo;
|
||||
private boolean hasHardwareInfo;
|
||||
private boolean hasModelInfo;
|
||||
|
||||
private String swArch;
|
||||
private String swOsName;
|
||||
private String swJvmName;
|
||||
private String swJvmVersion;
|
||||
private String swJvmSpecVersion;
|
||||
private String swNd4jBackendClass;
|
||||
private String swNd4jDataTypeName;
|
||||
private String swHostName;
|
||||
private String swJvmUID;
|
||||
private Map<String, String> swEnvironmentInfo;
|
||||
|
||||
private int hwJvmAvailableProcessors;
|
||||
private int hwNumDevices;
|
||||
private long hwJvmMaxMemory;
|
||||
private long hwOffHeapMaxMemory;
|
||||
private long[] hwDeviceTotalMemory;
|
||||
private String[] hwDeviceDescription;
|
||||
private String hwHardwareUID;
|
||||
|
||||
private String modelClassName;
|
||||
private String modelConfigJson;
|
||||
private String[] modelParamNames;
|
||||
private int modelNumLayers;
|
||||
private long modelNumParams;
|
||||
|
||||
@Override
|
||||
public void reportIDs(String sessionID, String typeID, String workerID, long timeStamp) {
|
||||
this.sessionID = sessionID;
|
||||
this.typeID = typeID;
|
||||
this.workerID = workerID;
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportSoftwareInfo(String arch, String osName, String jvmName, String jvmVersion, String jvmSpecVersion,
|
||||
String nd4jBackendClass, String nd4jDataTypeName, String hostname, String jvmUid,
|
||||
Map<String, String> swEnvironmentInfo) {
|
||||
this.swArch = arch;
|
||||
this.swOsName = osName;
|
||||
this.swJvmName = jvmName;
|
||||
this.swJvmVersion = jvmVersion;
|
||||
this.swJvmSpecVersion = jvmSpecVersion;
|
||||
this.swNd4jBackendClass = nd4jBackendClass;
|
||||
this.swNd4jDataTypeName = nd4jDataTypeName;
|
||||
this.swHostName = hostname;
|
||||
this.swJvmUID = jvmUid;
|
||||
this.swEnvironmentInfo = swEnvironmentInfo;
|
||||
hasSoftwareInfo = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportHardwareInfo(int jvmAvailableProcessors, int numDevices, long jvmMaxMemory, long offHeapMaxMemory,
|
||||
long[] deviceTotalMemory, String[] deviceDescription, String hardwareUID) {
|
||||
this.hwJvmAvailableProcessors = jvmAvailableProcessors;
|
||||
this.hwNumDevices = numDevices;
|
||||
this.hwJvmMaxMemory = jvmMaxMemory;
|
||||
this.hwOffHeapMaxMemory = offHeapMaxMemory;
|
||||
this.hwDeviceTotalMemory = deviceTotalMemory;
|
||||
this.hwDeviceDescription = deviceDescription;
|
||||
this.hwHardwareUID = hardwareUID;
|
||||
hasHardwareInfo = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportModelInfo(String modelClassName, String modelConfigJson, String[] modelParamNames, int numLayers,
|
||||
long numParams) {
|
||||
this.modelClassName = modelClassName;
|
||||
this.modelConfigJson = modelConfigJson;
|
||||
this.modelParamNames = modelParamNames;
|
||||
this.modelNumLayers = numLayers;
|
||||
this.modelNumParams = numParams;
|
||||
hasModelInfo = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSoftwareInfo() {
|
||||
return hasSoftwareInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHardwareInfo() {
|
||||
return hasHardwareInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModelInfo() {
|
||||
return hasModelInfo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void clearHwFields() {
|
||||
hwDeviceTotalMemory = null;
|
||||
hwDeviceDescription = null;
|
||||
hwHardwareUID = null;
|
||||
}
|
||||
|
||||
private void clearSwFields() {
|
||||
swArch = null;
|
||||
swOsName = null;
|
||||
swJvmName = null;
|
||||
swJvmVersion = null;
|
||||
swJvmSpecVersion = null;
|
||||
swNd4jBackendClass = null;
|
||||
swNd4jDataTypeName = null;
|
||||
swHostName = null;
|
||||
swJvmUID = null;
|
||||
}
|
||||
|
||||
private void clearModelFields() {
|
||||
modelClassName = null;
|
||||
modelConfigJson = null;
|
||||
modelParamNames = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSessionID() {
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeID() {
|
||||
return typeID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorkerID() {
|
||||
return workerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeStamp() {
|
||||
return timeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int encodingLengthBytes() {
|
||||
//TODO reuse the byte[]s here, to avoid converting them twice...
|
||||
|
||||
//First: need to determine how large a buffer to use.
|
||||
//Buffer is composed of:
|
||||
//(a) Header: 8 bytes (4x uint16 = 8 bytes)
|
||||
//(b) Fixed length entries length (sie.BlockLength())
|
||||
//(c) Group 1: Hardware devices (GPUs) max memory: 4 bytes header + nEntries * 8 (int64) + nEntries * variable length Strings (header + content) = 4 + 8*n + content
|
||||
//(d) Group 2: Software device info: 4 bytes header + 2x variable length Strings for each
|
||||
//(d) Group 3: Parameter names: 4 bytes header + nEntries * variable length strings (header + content) = 4 + content
|
||||
//(e) Variable length fields: 15 String length fields. Size: 4 bytes header, plus content. 60 bytes header
|
||||
//Fixed length + repeating groups + variable length...
|
||||
StaticInfoEncoder sie = new StaticInfoEncoder();
|
||||
int bufferSize = 8 + sie.sbeBlockLength() + 4 + 4 + 60; //header + fixed values + group headers + variable length headers
|
||||
|
||||
//For variable length field lengths: easist way is simply to convert to UTF-8
|
||||
//Of course, it is possible to calculate it first - but we might as well convert (1 pass), rather than count then convert (2 passes)
|
||||
byte[] bSessionId = SbeUtil.toBytes(true, sessionID);
|
||||
byte[] bTypeId = SbeUtil.toBytes(true, typeID);
|
||||
byte[] bWorkerId = SbeUtil.toBytes(true, workerID);
|
||||
|
||||
byte[] bswArch = SbeUtil.toBytes(hasSoftwareInfo, swArch);
|
||||
byte[] bswOsName = SbeUtil.toBytes(hasSoftwareInfo, swOsName);
|
||||
byte[] bswJvmName = SbeUtil.toBytes(hasSoftwareInfo, swJvmName);
|
||||
byte[] bswJvmVersion = SbeUtil.toBytes(hasSoftwareInfo, swJvmVersion);
|
||||
byte[] bswJvmSpecVersion = SbeUtil.toBytes(hasSoftwareInfo, swJvmSpecVersion);
|
||||
byte[] bswNd4jBackendClass = SbeUtil.toBytes(hasSoftwareInfo, swNd4jBackendClass);
|
||||
byte[] bswNd4jDataTypeName = SbeUtil.toBytes(hasSoftwareInfo, swNd4jDataTypeName);
|
||||
byte[] bswHostname = SbeUtil.toBytes(hasSoftwareInfo, swHostName);
|
||||
byte[] bswJvmUID = SbeUtil.toBytes(hasSoftwareInfo, swJvmUID);
|
||||
byte[] bHwHardwareUID = SbeUtil.toBytes(hasHardwareInfo, hwHardwareUID);
|
||||
byte[] bmodelConfigClass = SbeUtil.toBytes(hasModelInfo, modelClassName);
|
||||
byte[] bmodelConfigJson = SbeUtil.toBytes(hasModelInfo, modelConfigJson);
|
||||
|
||||
byte[][] bhwDeviceDescription = SbeUtil.toBytes(hasHardwareInfo, hwDeviceDescription);
|
||||
byte[][][] bswEnvInfo = SbeUtil.toBytes(swEnvironmentInfo);
|
||||
byte[][] bModelParamNames = SbeUtil.toBytes(hasModelInfo, modelParamNames);
|
||||
|
||||
|
||||
|
||||
bufferSize += bSessionId.length + bTypeId.length + bWorkerId.length;
|
||||
|
||||
bufferSize += 4; //swEnvironmentInfo group header (always present)
|
||||
if (hasSoftwareInfo) {
|
||||
bufferSize += SbeUtil.length(bswArch);
|
||||
bufferSize += SbeUtil.length(bswOsName);
|
||||
bufferSize += SbeUtil.length(bswJvmName);
|
||||
bufferSize += SbeUtil.length(bswJvmVersion);
|
||||
bufferSize += SbeUtil.length(bswJvmSpecVersion);
|
||||
bufferSize += SbeUtil.length(bswNd4jBackendClass);
|
||||
bufferSize += SbeUtil.length(bswNd4jDataTypeName);
|
||||
bufferSize += SbeUtil.length(bswHostname);
|
||||
bufferSize += SbeUtil.length(bswJvmUID);
|
||||
//For each entry: 2 variable-length headers (2x4 bytes each) + content
|
||||
int envCount = (bswEnvInfo != null ? bswEnvInfo.length : 0);
|
||||
bufferSize += envCount * 8;
|
||||
bufferSize += SbeUtil.length(bswEnvInfo);
|
||||
}
|
||||
int nHWDeviceStats = hwNumDevices;
|
||||
if (!hasHardwareInfo)
|
||||
nHWDeviceStats = 0;
|
||||
if (hasHardwareInfo) {
|
||||
//Device info group:
|
||||
bufferSize += hwNumDevices * 8; //fixed content in group: int64 -> 8 bytes. Encode an entry, even if hwDeviceTotalMemory is null
|
||||
bufferSize += hwNumDevices * 4; //uint32: 4 bytes per entry for var length header...; as above
|
||||
bufferSize += SbeUtil.length(bhwDeviceDescription);
|
||||
bufferSize += SbeUtil.length(bHwHardwareUID);
|
||||
}
|
||||
if (hasModelInfo) {
|
||||
bufferSize += SbeUtil.length(bmodelConfigClass);
|
||||
bufferSize += SbeUtil.length(bmodelConfigJson);
|
||||
bufferSize += SbeUtil.length(bModelParamNames);
|
||||
bufferSize += (bModelParamNames == null ? 0 : bModelParamNames.length * 4); //uint32: 4 bytes per entry for var length header...
|
||||
}
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
byte[] bytes = new byte[encodingLengthBytes()];
|
||||
MutableDirectBuffer buffer = new UnsafeBuffer(bytes);
|
||||
encode(buffer);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer buffer) {
|
||||
encode(new UnsafeBuffer(buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(MutableDirectBuffer buffer) {
|
||||
|
||||
MessageHeaderEncoder enc = new MessageHeaderEncoder();
|
||||
StaticInfoEncoder sie = new StaticInfoEncoder();
|
||||
|
||||
byte[] bSessionId = SbeUtil.toBytes(true, sessionID);
|
||||
byte[] bTypeId = SbeUtil.toBytes(true, typeID);
|
||||
byte[] bWorkerId = SbeUtil.toBytes(true, workerID);
|
||||
|
||||
byte[] bswArch = SbeUtil.toBytes(hasSoftwareInfo, swArch);
|
||||
byte[] bswOsName = SbeUtil.toBytes(hasSoftwareInfo, swOsName);
|
||||
byte[] bswJvmName = SbeUtil.toBytes(hasSoftwareInfo, swJvmName);
|
||||
byte[] bswJvmVersion = SbeUtil.toBytes(hasSoftwareInfo, swJvmVersion);
|
||||
byte[] bswJvmSpecVersion = SbeUtil.toBytes(hasSoftwareInfo, swJvmSpecVersion);
|
||||
byte[] bswNd4jBackendClass = SbeUtil.toBytes(hasSoftwareInfo, swNd4jBackendClass);
|
||||
byte[] bswNd4jDataTypeName = SbeUtil.toBytes(hasSoftwareInfo, swNd4jDataTypeName);
|
||||
byte[] bswHostname = SbeUtil.toBytes(hasSoftwareInfo, swHostName);
|
||||
byte[] bswJvmUID = SbeUtil.toBytes(hasSoftwareInfo, swJvmUID);
|
||||
byte[] bHwHardwareUID = SbeUtil.toBytes(hasHardwareInfo, hwHardwareUID);
|
||||
byte[] bmodelConfigClass = SbeUtil.toBytes(hasModelInfo, modelClassName);
|
||||
byte[] bmodelConfigJson = SbeUtil.toBytes(hasModelInfo, modelConfigJson);
|
||||
|
||||
byte[][] bhwDeviceDescription = SbeUtil.toBytes(hasHardwareInfo, hwDeviceDescription);
|
||||
byte[][][] bswEnvInfo = SbeUtil.toBytes(swEnvironmentInfo);
|
||||
byte[][] bModelParamNames = SbeUtil.toBytes(hasModelInfo, modelParamNames);
|
||||
|
||||
enc.wrap(buffer, 0).blockLength(sie.sbeBlockLength()).templateId(sie.sbeTemplateId())
|
||||
.schemaId(sie.sbeSchemaId()).version(sie.sbeSchemaVersion());
|
||||
|
||||
int offset = enc.encodedLength(); //Expect 8 bytes...
|
||||
|
||||
//Fixed length fields: always encoded, whether present or not.
|
||||
sie.wrap(buffer, offset).time(timeStamp).fieldsPresent().softwareInfo(hasSoftwareInfo)
|
||||
.hardwareInfo(hasHardwareInfo).modelInfo(hasModelInfo);
|
||||
sie.hwJvmProcessors(hwJvmAvailableProcessors).hwNumDevices((short) hwNumDevices).hwJvmMaxMemory(hwJvmMaxMemory)
|
||||
.hwOffheapMaxMemory(hwOffHeapMaxMemory).modelNumLayers(modelNumLayers)
|
||||
.modelNumParams(modelNumParams);
|
||||
//Device info group...
|
||||
StaticInfoEncoder.HwDeviceInfoGroupEncoder hwdEnc = sie.hwDeviceInfoGroupCount(hwNumDevices);
|
||||
int nHWDeviceStats = (hasHardwareInfo ? hwNumDevices : 0);
|
||||
for (int i = 0; i < nHWDeviceStats; i++) {
|
||||
long maxMem = hwDeviceTotalMemory == null || hwDeviceTotalMemory.length <= i ? 0 : hwDeviceTotalMemory[i];
|
||||
byte[] descr = bhwDeviceDescription == null || bhwDeviceDescription.length <= i ? SbeUtil.EMPTY_BYTES
|
||||
: bhwDeviceDescription[i];
|
||||
if (descr == null)
|
||||
descr = SbeUtil.EMPTY_BYTES;
|
||||
hwdEnc.next().deviceMemoryMax(maxMem).putDeviceDescription(descr, 0, descr.length);
|
||||
}
|
||||
|
||||
//Environment info group
|
||||
int numEnvValues = (hasSoftwareInfo && swEnvironmentInfo != null ? swEnvironmentInfo.size() : 0);
|
||||
StaticInfoEncoder.SwEnvironmentInfoEncoder swEnv = sie.swEnvironmentInfoCount(numEnvValues);
|
||||
if (numEnvValues > 0) {
|
||||
byte[][][] mapAsBytes = SbeUtil.toBytes(swEnvironmentInfo);
|
||||
for (byte[][] entryBytes : mapAsBytes) {
|
||||
swEnv.next().putEnvKey(entryBytes[0], 0, entryBytes[0].length).putEnvValue(entryBytes[1], 0,
|
||||
entryBytes[1].length);
|
||||
}
|
||||
}
|
||||
|
||||
int nParamNames = modelParamNames == null ? 0 : modelParamNames.length;
|
||||
StaticInfoEncoder.ModelParamNamesEncoder mpnEnc = sie.modelParamNamesCount(nParamNames);
|
||||
for (int i = 0; i < nParamNames; i++) {
|
||||
mpnEnc.next().putModelParamNames(bModelParamNames[i], 0, bModelParamNames[i].length);
|
||||
}
|
||||
|
||||
//In the case of !hasSoftwareInfo: these will all be empty byte arrays... still need to encode them (for 0 length) however
|
||||
sie.putSessionID(bSessionId, 0, bSessionId.length).putTypeID(bTypeId, 0, bTypeId.length)
|
||||
.putWorkerID(bWorkerId, 0, bWorkerId.length).putSwArch(bswArch, 0, bswArch.length)
|
||||
.putSwOsName(bswOsName, 0, bswOsName.length).putSwJvmName(bswJvmName, 0, bswJvmName.length)
|
||||
.putSwJvmVersion(bswJvmVersion, 0, bswJvmVersion.length)
|
||||
.putSwJvmSpecVersion(bswJvmSpecVersion, 0, bswJvmSpecVersion.length)
|
||||
.putSwNd4jBackendClass(bswNd4jBackendClass, 0, bswNd4jBackendClass.length)
|
||||
.putSwNd4jDataTypeName(bswNd4jDataTypeName, 0, bswNd4jDataTypeName.length)
|
||||
.putSwHostName(bswHostname, 0, bswHostname.length).putSwJvmUID(bswJvmUID, 0, bswJvmUID.length)
|
||||
.putHwHardwareUID(bHwHardwareUID, 0, bHwHardwareUID.length);
|
||||
//Similar: !hasModelInfo -> empty byte[]
|
||||
sie.putModelConfigClassName(bmodelConfigClass, 0, bmodelConfigClass.length).putModelConfigJson(bmodelConfigJson,
|
||||
0, bmodelConfigJson.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(OutputStream outputStream) throws IOException {
|
||||
//TODO there may be more efficient way of doing this
|
||||
outputStream.write(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] decode) {
|
||||
MutableDirectBuffer buffer = new UnsafeBuffer(decode);
|
||||
decode(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuffer buffer) {
|
||||
decode(new UnsafeBuffer(buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(DirectBuffer buffer) {
|
||||
//TODO we could do this much more efficiently, with buffer re-use, etc.
|
||||
MessageHeaderDecoder dec = new MessageHeaderDecoder();
|
||||
StaticInfoDecoder sid = new StaticInfoDecoder();
|
||||
dec.wrap(buffer, 0);
|
||||
|
||||
final int blockLength = dec.blockLength();
|
||||
final int version = dec.version();
|
||||
|
||||
final int headerLength = dec.encodedLength();
|
||||
//TODO: in general, we should check the header, version, schema etc. But we don't have any other versions yet.
|
||||
|
||||
sid.wrap(buffer, headerLength, blockLength, version);
|
||||
timeStamp = sid.time();
|
||||
InitFieldsPresentDecoder fields = sid.fieldsPresent();
|
||||
hasSoftwareInfo = fields.softwareInfo();
|
||||
hasHardwareInfo = fields.hardwareInfo();
|
||||
hasModelInfo = fields.modelInfo();
|
||||
|
||||
//These fields: always present, even if !hasHardwareInfo
|
||||
hwJvmAvailableProcessors = sid.hwJvmProcessors();
|
||||
hwNumDevices = sid.hwNumDevices();
|
||||
hwJvmMaxMemory = sid.hwJvmMaxMemory();
|
||||
hwOffHeapMaxMemory = sid.hwOffheapMaxMemory();
|
||||
modelNumLayers = sid.modelNumLayers();
|
||||
modelNumParams = sid.modelNumParams();
|
||||
|
||||
//Hardware device info group
|
||||
StaticInfoDecoder.HwDeviceInfoGroupDecoder hwDeviceInfoGroupDecoder = sid.hwDeviceInfoGroup();
|
||||
int count = hwDeviceInfoGroupDecoder.count();
|
||||
if (count > 0) {
|
||||
hwDeviceTotalMemory = new long[count];
|
||||
hwDeviceDescription = new String[count];
|
||||
}
|
||||
int i = 0;
|
||||
for (StaticInfoDecoder.HwDeviceInfoGroupDecoder hw : hwDeviceInfoGroupDecoder) {
|
||||
hwDeviceTotalMemory[i] = hw.deviceMemoryMax();
|
||||
hwDeviceDescription[i++] = hw.deviceDescription();
|
||||
}
|
||||
|
||||
//Environment info group
|
||||
i = 0;
|
||||
StaticInfoDecoder.SwEnvironmentInfoDecoder swEnvDecoder = sid.swEnvironmentInfo();
|
||||
if (swEnvDecoder.count() > 0) {
|
||||
swEnvironmentInfo = new HashMap<>();
|
||||
}
|
||||
for (StaticInfoDecoder.SwEnvironmentInfoDecoder env : swEnvDecoder) {
|
||||
String key = env.envKey();
|
||||
String value = env.envValue();
|
||||
swEnvironmentInfo.put(key, value);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
StaticInfoDecoder.ModelParamNamesDecoder mpdec = sid.modelParamNames();
|
||||
int mpnCount = mpdec.count();
|
||||
modelParamNames = new String[mpnCount];
|
||||
for (StaticInfoDecoder.ModelParamNamesDecoder mp : mpdec) {
|
||||
modelParamNames[i++] = mp.modelParamNames();
|
||||
}
|
||||
//Variable length data. Even if it is missing: still needs to be read, to advance buffer
|
||||
//Again, the exact order of these calls matters here
|
||||
sessionID = sid.sessionID();
|
||||
typeID = sid.typeID();
|
||||
workerID = sid.workerID();
|
||||
swArch = sid.swArch();
|
||||
swOsName = sid.swOsName();
|
||||
swJvmName = sid.swJvmName();
|
||||
swJvmVersion = sid.swJvmVersion();
|
||||
swJvmSpecVersion = sid.swJvmSpecVersion();
|
||||
swNd4jBackendClass = sid.swNd4jBackendClass();
|
||||
swNd4jDataTypeName = sid.swNd4jDataTypeName();
|
||||
swHostName = sid.swHostName();
|
||||
swJvmUID = sid.swJvmUID();
|
||||
if (!hasSoftwareInfo)
|
||||
clearSwFields();
|
||||
hwHardwareUID = sid.hwHardwareUID();
|
||||
if (!hasHardwareInfo)
|
||||
clearHwFields();
|
||||
modelClassName = sid.modelConfigClassName();
|
||||
modelConfigJson = sid.modelConfigJson();
|
||||
if (!hasModelInfo)
|
||||
clearModelFields();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream inputStream) throws IOException {
|
||||
byte[] bytes = IOUtils.toByteArray(inputStream);
|
||||
decode(bytes);
|
||||
}
|
||||
}
|
||||
+1181
File diff suppressed because it is too large
Load Diff
+131
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.impl;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Map;
|
||||
|
||||
public class SbeUtil {
|
||||
|
||||
public static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
public static final byte[] EMPTY_BYTES = new byte[0]; //Also equivalent to "".getBytes(UTF8);
|
||||
|
||||
private SbeUtil() {}
|
||||
|
||||
public static int length(byte[] bytes) {
|
||||
if (bytes == null)
|
||||
return 0;
|
||||
return bytes.length;
|
||||
}
|
||||
|
||||
public static int length(byte[][] bytes) {
|
||||
if (bytes == null)
|
||||
return 0;
|
||||
int count = 0;
|
||||
for (int i = 0; i < bytes.length; i++) {
|
||||
if (bytes[i] != null)
|
||||
count += bytes[i].length;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int length(byte[][][] bytes) {
|
||||
if (bytes == null)
|
||||
return 0;
|
||||
int count = 0;
|
||||
for (byte[][] arr : bytes) {
|
||||
count += length(arr);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int length(String str) {
|
||||
if (str == null)
|
||||
return 0;
|
||||
return str.length();
|
||||
}
|
||||
|
||||
public static int length(String[] arr) {
|
||||
if (arr == null || arr.length == 0)
|
||||
return 0;
|
||||
int sum = 0;
|
||||
for (String s : arr)
|
||||
sum += length(s);
|
||||
return sum;
|
||||
}
|
||||
|
||||
public static byte[] toBytes(boolean present, String str) {
|
||||
if (!present || str == null)
|
||||
return EMPTY_BYTES;
|
||||
return str.getBytes(UTF8);
|
||||
}
|
||||
|
||||
public static byte[][] toBytes(boolean present, String[] str) {
|
||||
if (str == null)
|
||||
return null;
|
||||
byte[][] b = new byte[str.length][0];
|
||||
for (int i = 0; i < str.length; i++) {
|
||||
if (str[i] == null)
|
||||
continue;
|
||||
b[i] = toBytes(present, str[i]);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public static byte[][][] toBytes(Map<String, String> map) {
|
||||
if (map == null)
|
||||
return null;
|
||||
byte[][][] b = new byte[map.size()][2][0];
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
b[i][0] = toBytes(true, entry.getKey());
|
||||
b[i][1] = toBytes(true, entry.getValue());
|
||||
i++;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public static byte[] toBytesSerializable(Serializable serializable) {
|
||||
if (serializable == null)
|
||||
return EMPTY_BYTES;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(serializable);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected IOException during serialization", e);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
public static Serializable fromBytesSerializable(byte[] bytes) {
|
||||
if (bytes == null || bytes.length == 0)
|
||||
return null;
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
|
||||
return (Serializable) ois.readObject();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected IOException during deserialization", e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.impl.java;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsInitializationReport;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class JavaStatsInitializationReport implements StatsInitializationReport {
|
||||
|
||||
private String sessionID;
|
||||
private String typeID;
|
||||
private String workerID;
|
||||
private long timeStamp;
|
||||
|
||||
private boolean hasSoftwareInfo;
|
||||
private boolean hasHardwareInfo;
|
||||
private boolean hasModelInfo;
|
||||
|
||||
private String swArch;
|
||||
private String swOsName;
|
||||
private String swJvmName;
|
||||
private String swJvmVersion;
|
||||
private String swJvmSpecVersion;
|
||||
private String swNd4jBackendClass;
|
||||
private String swNd4jDataTypeName;
|
||||
private String swHostName;
|
||||
private String swJvmUID;
|
||||
private Map<String, String> swEnvironmentInfo;
|
||||
|
||||
private int hwJvmAvailableProcessors;
|
||||
private int hwNumDevices;
|
||||
private long hwJvmMaxMemory;
|
||||
private long hwOffHeapMaxMemory;
|
||||
private long[] hwDeviceTotalMemory;
|
||||
private String[] hwDeviceDescription;
|
||||
private String hwHardwareUID;
|
||||
|
||||
private String modelClassName;
|
||||
private String modelConfigJson;
|
||||
private String[] modelParamNames;
|
||||
private int modelNumLayers;
|
||||
private long modelNumParams;
|
||||
|
||||
@Override
|
||||
public void reportIDs(String sessionID, String typeID, String workerID, long timeStamp) {
|
||||
this.sessionID = sessionID;
|
||||
this.typeID = typeID;
|
||||
this.workerID = workerID;
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportSoftwareInfo(String arch, String osName, String jvmName, String jvmVersion, String jvmSpecVersion,
|
||||
String nd4jBackendClass, String nd4jDataTypeName, String hostname, String jvmUid,
|
||||
Map<String, String> swEnvironmentInfo) {
|
||||
this.swArch = arch;
|
||||
this.swOsName = osName;
|
||||
this.swJvmName = jvmName;
|
||||
this.swJvmVersion = jvmVersion;
|
||||
this.swJvmSpecVersion = jvmSpecVersion;
|
||||
this.swNd4jBackendClass = nd4jBackendClass;
|
||||
this.swNd4jDataTypeName = nd4jDataTypeName;
|
||||
this.swHostName = hostname;
|
||||
this.swJvmUID = jvmUid;
|
||||
this.swEnvironmentInfo = swEnvironmentInfo;
|
||||
hasSoftwareInfo = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportHardwareInfo(int jvmAvailableProcessors, int numDevices, long jvmMaxMemory, long offHeapMaxMemory,
|
||||
long[] deviceTotalMemory, String[] deviceDescription, String hardwareUID) {
|
||||
this.hwJvmAvailableProcessors = jvmAvailableProcessors;
|
||||
this.hwNumDevices = numDevices;
|
||||
this.hwJvmMaxMemory = jvmMaxMemory;
|
||||
this.hwOffHeapMaxMemory = offHeapMaxMemory;
|
||||
this.hwDeviceTotalMemory = deviceTotalMemory;
|
||||
this.hwDeviceDescription = deviceDescription;
|
||||
this.hwHardwareUID = hardwareUID;
|
||||
hasHardwareInfo = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportModelInfo(String modelClassName, String modelConfigJson, String[] modelParamNames, int numLayers,
|
||||
long numParams) {
|
||||
this.modelClassName = modelClassName;
|
||||
this.modelConfigJson = modelConfigJson;
|
||||
this.modelParamNames = modelParamNames;
|
||||
this.modelNumLayers = numLayers;
|
||||
this.modelNumParams = numParams;
|
||||
hasModelInfo = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSoftwareInfo() {
|
||||
return hasSoftwareInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHardwareInfo() {
|
||||
return hasHardwareInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasModelInfo() {
|
||||
return hasModelInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int encodingLengthBytes() {
|
||||
//TODO - presumably a more efficient way to do this
|
||||
byte[] encoded = encode();
|
||||
return encoded.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(this);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer buffer) {
|
||||
buffer.put(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(OutputStream outputStream) throws IOException {
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {
|
||||
oos.writeObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] decode) {
|
||||
JavaStatsInitializationReport r;
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(decode))) {
|
||||
r = (JavaStatsInitializationReport) ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
|
||||
Field[] fields = JavaStatsInitializationReport.class.getDeclaredFields();
|
||||
for (Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
f.set(this, f.get(r));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuffer buffer) {
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
buffer.get(bytes);
|
||||
decode(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream inputStream) throws IOException {
|
||||
decode(IOUtils.toByteArray(inputStream));
|
||||
}
|
||||
}
|
||||
+390
@@ -0,0 +1,390 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.impl.java;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.ToString;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.deeplearning4j.ui.model.stats.api.Histogram;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsReport;
|
||||
import org.deeplearning4j.ui.model.stats.api.StatsType;
|
||||
import org.deeplearning4j.ui.model.stats.api.SummaryType;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@EqualsAndHashCode
|
||||
@ToString
|
||||
@Data
|
||||
public class JavaStatsReport implements StatsReport {
|
||||
|
||||
private String sessionID;
|
||||
private String typeID;
|
||||
private String workerID;
|
||||
private long timeStamp;
|
||||
|
||||
private int iterationCount;
|
||||
private int statsCollectionDurationMs;
|
||||
private double score;
|
||||
|
||||
private long jvmCurrentBytes;
|
||||
private long jvmMaxBytes;
|
||||
private long offHeapCurrentBytes;
|
||||
private long offHeapMaxBytes;
|
||||
private long[] deviceCurrentBytes;
|
||||
private long[] deviceMaxBytes;
|
||||
|
||||
private long totalRuntimeMs;
|
||||
private long totalExamples;
|
||||
private long totalMinibatches;
|
||||
private double examplesPerSecond;
|
||||
private double minibatchesPerSecond;
|
||||
|
||||
private List<GCStats> gcStats;
|
||||
|
||||
private Map<String, Double> learningRatesByParam;
|
||||
private Map<StatsType, Map<String, Histogram>> histograms;
|
||||
private Map<StatsType, Map<String, Double>> meanValues;
|
||||
private Map<StatsType, Map<String, Double>> stdevValues;
|
||||
private Map<StatsType, Map<String, Double>> meanMagnitudeValues;
|
||||
|
||||
private String metaDataClassName;
|
||||
//Store in serialized form; deserialize iff required. Might save us some class not found (or, version) errors, if
|
||||
// metadata is saved but is never used
|
||||
private List<byte[]> dataSetMetaData;
|
||||
|
||||
private boolean scorePresent;
|
||||
private boolean memoryUsePresent;
|
||||
private boolean performanceStatsPresent;
|
||||
|
||||
public JavaStatsReport() {
|
||||
//No-Arg constructor only for deserialization
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reportIDs(String sessionID, String typeID, String workerID, long timeStamp) {
|
||||
this.sessionID = sessionID;
|
||||
this.typeID = typeID;
|
||||
this.workerID = workerID;
|
||||
this.timeStamp = timeStamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportIterationCount(int iterationCount) {
|
||||
this.iterationCount = iterationCount;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void reportStatsCollectionDurationMS(int statsCollectionDurationMS) {
|
||||
this.statsCollectionDurationMs = statsCollectionDurationMS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportScore(double currentScore) {
|
||||
this.score = currentScore;
|
||||
this.scorePresent = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportLearningRates(Map<String, Double> learningRatesByParam) {
|
||||
this.learningRatesByParam = learningRatesByParam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportMemoryUse(long jvmCurrentBytes, long jvmMaxBytes, long offHeapCurrentBytes, long offHeapMaxBytes,
|
||||
long[] deviceCurrentBytes, long[] deviceMaxBytes) {
|
||||
this.jvmCurrentBytes = jvmCurrentBytes;
|
||||
this.jvmMaxBytes = jvmMaxBytes;
|
||||
this.offHeapCurrentBytes = offHeapCurrentBytes;
|
||||
this.offHeapMaxBytes = offHeapMaxBytes;
|
||||
this.deviceCurrentBytes = deviceCurrentBytes;
|
||||
this.deviceMaxBytes = deviceMaxBytes;
|
||||
this.memoryUsePresent = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportPerformance(long totalRuntimeMs, long totalExamples, long totalMinibatches,
|
||||
double examplesPerSecond, double minibatchesPerSecond) {
|
||||
this.totalRuntimeMs = totalRuntimeMs;
|
||||
this.totalExamples = totalExamples;
|
||||
this.totalMinibatches = totalMinibatches;
|
||||
this.examplesPerSecond = examplesPerSecond;
|
||||
this.minibatchesPerSecond = minibatchesPerSecond;
|
||||
this.performanceStatsPresent = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportGarbageCollection(String gcName, int deltaGCCount, int deltaGCTime) {
|
||||
if (gcStats == null)
|
||||
gcStats = new ArrayList<>();
|
||||
gcStats.add(new GCStats(gcName, deltaGCCount, deltaGCTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Pair<String, int[]>> getGarbageCollectionStats() {
|
||||
if (gcStats == null)
|
||||
return null;
|
||||
List<Pair<String, int[]>> temp = new ArrayList<>();
|
||||
for (GCStats g : gcStats) {
|
||||
temp.add(new Pair<>(g.gcName, new int[] {g.getDeltaGCCount(), g.getDeltaGCTime()}));
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportHistograms(StatsType statsType, Map<String, Histogram> histogram) {
|
||||
if (this.histograms == null)
|
||||
this.histograms = new HashMap<>();
|
||||
this.histograms.put(statsType, histogram);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Histogram> getHistograms(StatsType statsType) {
|
||||
if (histograms == null)
|
||||
return null;
|
||||
return histograms.get(statsType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportMean(StatsType statsType, Map<String, Double> mean) {
|
||||
if (this.meanValues == null)
|
||||
this.meanValues = new HashMap<>();
|
||||
this.meanValues.put(statsType, mean);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getMean(StatsType statsType) {
|
||||
if (this.meanValues == null)
|
||||
return null;
|
||||
return meanValues.get(statsType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportStdev(StatsType statsType, Map<String, Double> stdev) {
|
||||
if (this.stdevValues == null)
|
||||
this.stdevValues = new HashMap<>();
|
||||
this.stdevValues.put(statsType, stdev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getStdev(StatsType statsType) {
|
||||
if (this.stdevValues == null)
|
||||
return null;
|
||||
return stdevValues.get(statsType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportMeanMagnitudes(StatsType statsType, Map<String, Double> meanMagnitudes) {
|
||||
if (this.meanMagnitudeValues == null)
|
||||
this.meanMagnitudeValues = new HashMap<>();
|
||||
this.meanMagnitudeValues.put(statsType, meanMagnitudes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportDataSetMetaData(List<Serializable> dataSetMetaData, Class<?> metaDataClass) {
|
||||
reportDataSetMetaData(dataSetMetaData, (metaDataClass == null ? null : metaDataClass.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportDataSetMetaData(List<Serializable> dataSetMetaData, String metaDataClass) {
|
||||
if (dataSetMetaData != null) {
|
||||
this.dataSetMetaData = new ArrayList<>();
|
||||
for (Serializable s : dataSetMetaData) {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(s);
|
||||
oos.flush();
|
||||
oos.close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unexpected IOException from ByteArrayOutputStream", e);
|
||||
}
|
||||
byte[] b = baos.toByteArray();
|
||||
this.dataSetMetaData.add(b);
|
||||
}
|
||||
} else {
|
||||
this.dataSetMetaData = null;
|
||||
}
|
||||
this.metaDataClassName = metaDataClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getMeanMagnitudes(StatsType statsType) {
|
||||
if (this.meanMagnitudeValues == null)
|
||||
return null;
|
||||
return this.meanMagnitudeValues.get(statsType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Serializable> getDataSetMetaData() {
|
||||
if (dataSetMetaData == null || dataSetMetaData.isEmpty())
|
||||
return null;
|
||||
|
||||
List<Serializable> l = new ArrayList<>();
|
||||
for (byte[] b : dataSetMetaData) {
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(b))) {
|
||||
l.add((Serializable) ois.readObject());
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDataSetMetaDataClassName() {
|
||||
return metaDataClassName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Double> getLearningRates() {
|
||||
return this.learningRatesByParam;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasScore() {
|
||||
return scorePresent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLearningRates() {
|
||||
return learningRatesByParam != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMemoryUse() {
|
||||
return memoryUsePresent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPerformance() {
|
||||
return performanceStatsPresent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasGarbageCollection() {
|
||||
return gcStats != null && !gcStats.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasHistograms(StatsType statsType) {
|
||||
if (histograms == null)
|
||||
return false;
|
||||
return histograms.containsKey(statsType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSummaryStats(StatsType statsType, SummaryType summaryType) {
|
||||
switch (summaryType) {
|
||||
case Mean:
|
||||
return meanValues != null && meanValues.containsKey(statsType);
|
||||
case Stdev:
|
||||
return stdevValues != null && stdevValues.containsKey(statsType);
|
||||
case MeanMagnitudes:
|
||||
return meanMagnitudeValues != null && meanMagnitudeValues.containsKey(statsType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDataSetMetaData() {
|
||||
return dataSetMetaData != null || metaDataClassName != null;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
private static class GCStats implements Serializable {
|
||||
private String gcName;
|
||||
private int deltaGCCount;
|
||||
private int deltaGCTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int encodingLengthBytes() {
|
||||
//TODO - presumably a more efficient way to do this
|
||||
byte[] encoded = encode();
|
||||
return encoded.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(this);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer buffer) {
|
||||
buffer.put(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(OutputStream outputStream) throws IOException {
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {
|
||||
oos.writeObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] decode) {
|
||||
JavaStatsReport r;
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(decode))) {
|
||||
r = (JavaStatsReport) ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
|
||||
Field[] fields = JavaStatsReport.class.getDeclaredFields();
|
||||
for (Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
f.set(this, f.get(r));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuffer buffer) {
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
buffer.get(bytes);
|
||||
decode(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream inputStream) throws IOException {
|
||||
decode(IOUtils.toByteArray(inputStream));
|
||||
}
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.GroupSizeEncodingDecoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class GroupSizeEncodingDecoder {
|
||||
public static final int ENCODED_LENGTH = 4;
|
||||
private DirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public GroupSizeEncodingDecoder wrap(final DirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public static int blockLengthNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int blockLengthMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int blockLengthMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public int blockLength() {
|
||||
return (buffer.getShort(offset + 0, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
public static int numInGroupNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int numInGroupMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int numInGroupMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public int numInGroup() {
|
||||
return (buffer.getShort(offset + 2, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
builder.append('(');
|
||||
//Token{signal=ENCODING, name='blockLength', description='Extra metadata bytes', id=-1, version=0, encodedLength=2, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=UINT16, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='UTF-8', epoch='null', timeUnit=null, semanticType='null'}}
|
||||
builder.append("blockLength=");
|
||||
builder.append(blockLength());
|
||||
builder.append('|');
|
||||
//Token{signal=ENCODING, name='numInGroup', description='Extra metadata bytes', id=-1, version=0, encodedLength=2, offset=2, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=UINT16, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='UTF-8', epoch='null', timeUnit=null, semanticType='null'}}
|
||||
builder.append("numInGroup=");
|
||||
builder.append(numInGroup());
|
||||
builder.append(')');
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.GroupSizeEncodingEncoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class GroupSizeEncodingEncoder {
|
||||
public static final int ENCODED_LENGTH = 4;
|
||||
private MutableDirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public GroupSizeEncodingEncoder wrap(final MutableDirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public static int blockLengthNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int blockLengthMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int blockLengthMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public GroupSizeEncodingEncoder blockLength(final int value) {
|
||||
buffer.putShort(offset + 0, (short) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static int numInGroupNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int numInGroupMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int numInGroupMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public GroupSizeEncodingEncoder numInGroup(final int value) {
|
||||
buffer.putShort(offset + 2, (short) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
GroupSizeEncodingDecoder writer = new GroupSizeEncodingDecoder();
|
||||
writer.wrap(buffer, offset);
|
||||
|
||||
return writer.appendTo(builder);
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.InitFieldsPresentDecoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class InitFieldsPresentDecoder {
|
||||
public static final int ENCODED_LENGTH = 1;
|
||||
private DirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public InitFieldsPresentDecoder wrap(final DirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public boolean softwareInfo() {
|
||||
return 0 != (buffer.getByte(offset) & (1 << 0));
|
||||
}
|
||||
|
||||
public boolean hardwareInfo() {
|
||||
return 0 != (buffer.getByte(offset) & (1 << 1));
|
||||
}
|
||||
|
||||
public boolean modelInfo() {
|
||||
return 0 != (buffer.getByte(offset) & (1 << 2));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
builder.append('{');
|
||||
boolean atLeastOne = false;
|
||||
if (softwareInfo()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("softwareInfo");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (hardwareInfo()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("hardwareInfo");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (modelInfo()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("modelInfo");
|
||||
atLeastOne = true;
|
||||
}
|
||||
builder.append('}');
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.InitFieldsPresentEncoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class InitFieldsPresentEncoder {
|
||||
public static final int ENCODED_LENGTH = 1;
|
||||
private MutableDirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public InitFieldsPresentEncoder wrap(final MutableDirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public InitFieldsPresentEncoder clear() {
|
||||
buffer.putByte(offset, (byte) (short) 0);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InitFieldsPresentEncoder softwareInfo(final boolean value) {
|
||||
byte bits = buffer.getByte(offset);
|
||||
bits = (byte) (value ? bits | (1 << 0) : bits & ~(1 << 0));
|
||||
buffer.putByte(offset, bits);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InitFieldsPresentEncoder hardwareInfo(final boolean value) {
|
||||
byte bits = buffer.getByte(offset);
|
||||
bits = (byte) (value ? bits | (1 << 1) : bits & ~(1 << 1));
|
||||
buffer.putByte(offset, bits);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InitFieldsPresentEncoder modelInfo(final boolean value) {
|
||||
byte bits = buffer.getByte(offset);
|
||||
bits = (byte) (value ? bits | (1 << 2) : bits & ~(1 << 2));
|
||||
buffer.putByte(offset, bits);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+60
@@ -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
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.ui.model.stats.sbe;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.MemoryType"})
|
||||
public enum MemoryType {
|
||||
JvmCurrent((short) 0), JvmMax((short) 1), OffHeapCurrent((short) 2), OffHeapMax((short) 3), DeviceCurrent(
|
||||
(short) 4), DeviceMax((short) 5), NULL_VAL((short) 255);
|
||||
|
||||
private final short value;
|
||||
|
||||
MemoryType(final short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public short value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static MemoryType get(final short value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return JvmCurrent;
|
||||
case 1:
|
||||
return JvmMax;
|
||||
case 2:
|
||||
return OffHeapCurrent;
|
||||
case 3:
|
||||
return OffHeapMax;
|
||||
case 4:
|
||||
return DeviceCurrent;
|
||||
case 5:
|
||||
return DeviceMax;
|
||||
}
|
||||
|
||||
if ((short) 255 == value) {
|
||||
return NULL_VAL;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown value: " + value);
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.MessageHeaderDecoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class MessageHeaderDecoder {
|
||||
public static final int ENCODED_LENGTH = 8;
|
||||
private DirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public MessageHeaderDecoder wrap(final DirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public static int blockLengthNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int blockLengthMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int blockLengthMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public int blockLength() {
|
||||
return (buffer.getShort(offset + 0, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
public static int templateIdNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int templateIdMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int templateIdMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public int templateId() {
|
||||
return (buffer.getShort(offset + 2, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
public static int schemaIdNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int schemaIdMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int schemaIdMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public int schemaId() {
|
||||
return (buffer.getShort(offset + 4, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF);
|
||||
}
|
||||
|
||||
|
||||
public static int versionNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int versionMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int versionMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public int version() {
|
||||
return (buffer.getShort(offset + 6, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF);
|
||||
}
|
||||
|
||||
}
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.MessageHeaderEncoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class MessageHeaderEncoder {
|
||||
public static final int ENCODED_LENGTH = 8;
|
||||
private MutableDirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public MessageHeaderEncoder wrap(final MutableDirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public static int blockLengthNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int blockLengthMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int blockLengthMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public MessageHeaderEncoder blockLength(final int value) {
|
||||
buffer.putShort(offset + 0, (short) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static int templateIdNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int templateIdMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int templateIdMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public MessageHeaderEncoder templateId(final int value) {
|
||||
buffer.putShort(offset + 2, (short) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static int schemaIdNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int schemaIdMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int schemaIdMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public MessageHeaderEncoder schemaId(final int value) {
|
||||
buffer.putShort(offset + 4, (short) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static int versionNullValue() {
|
||||
return 65535;
|
||||
}
|
||||
|
||||
public static int versionMinValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int versionMaxValue() {
|
||||
return 65534;
|
||||
}
|
||||
|
||||
public MessageHeaderEncoder version(final int value) {
|
||||
buffer.putShort(offset + 6, (short) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
+26
@@ -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
|
||||
* *****************************************************************************
|
||||
*/
|
||||
|
||||
package org.deeplearning4j.ui.model.stats.sbe;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.MetaAttribute"})
|
||||
public enum MetaAttribute {
|
||||
EPOCH, TIME_UNIT, SEMANTIC_TYPE
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
@javax.annotation.Generated(value = {"StatSource"})
|
||||
public enum StatSource {
|
||||
Parameters((short) 0), Updates((short) 1), Activations((short) 2), NULL_VAL((short) 255);
|
||||
|
||||
private final short value;
|
||||
|
||||
StatSource(final short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public short value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static StatSource get(final short value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return Parameters;
|
||||
case 1:
|
||||
return Updates;
|
||||
case 2:
|
||||
return Activations;
|
||||
}
|
||||
|
||||
if ((short) 255 == value) {
|
||||
return NULL_VAL;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown value: " + value);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
@javax.annotation.Generated(value = {"StatType"})
|
||||
public enum StatType {
|
||||
Mean((short) 0), Stdev((short) 1), MeanMagnitude((short) 2), NULL_VAL((short) 255);
|
||||
|
||||
private final short value;
|
||||
|
||||
StatType(final short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public short value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static StatType get(final short value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return Mean;
|
||||
case 1:
|
||||
return Stdev;
|
||||
case 2:
|
||||
return MeanMagnitude;
|
||||
}
|
||||
|
||||
if ((short) 255 == value) {
|
||||
return NULL_VAL;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown value: " + value);
|
||||
}
|
||||
}
|
||||
+2148
File diff suppressed because it is too large
Load Diff
+1853
File diff suppressed because it is too large
Load Diff
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.StatsType"})
|
||||
public enum StatsType {
|
||||
Parameters((short) 0), Gradients((short) 1), Updates((short) 2), Activations((short) 3), NULL_VAL((short) 255);
|
||||
|
||||
private final short value;
|
||||
|
||||
StatsType(final short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public short value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static StatsType get(final short value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return Parameters;
|
||||
case 1:
|
||||
return Gradients;
|
||||
case 2:
|
||||
return Updates;
|
||||
case 3:
|
||||
return Activations;
|
||||
}
|
||||
|
||||
if ((short) 255 == value) {
|
||||
return NULL_VAL;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown value: " + value);
|
||||
}
|
||||
}
|
||||
+659
@@ -0,0 +1,659 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.StorageMetaDataDecoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class StorageMetaDataDecoder {
|
||||
public static final int BLOCK_LENGTH = 8;
|
||||
public static final int TEMPLATE_ID = 3;
|
||||
public static final int SCHEMA_ID = 1;
|
||||
public static final int SCHEMA_VERSION = 0;
|
||||
|
||||
private final StorageMetaDataDecoder parentMessage = this;
|
||||
private DirectBuffer buffer;
|
||||
protected int offset;
|
||||
protected int limit;
|
||||
protected int actingBlockLength;
|
||||
protected int actingVersion;
|
||||
|
||||
public int sbeBlockLength() {
|
||||
return BLOCK_LENGTH;
|
||||
}
|
||||
|
||||
public int sbeTemplateId() {
|
||||
return TEMPLATE_ID;
|
||||
}
|
||||
|
||||
public int sbeSchemaId() {
|
||||
return SCHEMA_ID;
|
||||
}
|
||||
|
||||
public int sbeSchemaVersion() {
|
||||
return SCHEMA_VERSION;
|
||||
}
|
||||
|
||||
public String sbeSemanticType() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public int offset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public StorageMetaDataDecoder wrap(final DirectBuffer buffer, final int offset, final int actingBlockLength,
|
||||
final int actingVersion) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
this.actingBlockLength = actingBlockLength;
|
||||
this.actingVersion = actingVersion;
|
||||
limit(offset + actingBlockLength);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return limit - offset;
|
||||
}
|
||||
|
||||
public int limit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void limit(final int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public static int timeStampId() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public static String timeStampMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static long timeStampNullValue() {
|
||||
return -9223372036854775808L;
|
||||
}
|
||||
|
||||
public static long timeStampMinValue() {
|
||||
return -9223372036854775807L;
|
||||
}
|
||||
|
||||
public static long timeStampMaxValue() {
|
||||
return 9223372036854775807L;
|
||||
}
|
||||
|
||||
public long timeStamp() {
|
||||
return buffer.getLong(offset + 0, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
}
|
||||
|
||||
|
||||
private final ExtraMetaDataBytesDecoder extraMetaDataBytes = new ExtraMetaDataBytesDecoder();
|
||||
|
||||
public static long extraMetaDataBytesDecoderId() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public ExtraMetaDataBytesDecoder extraMetaDataBytes() {
|
||||
extraMetaDataBytes.wrap(parentMessage, buffer);
|
||||
return extraMetaDataBytes;
|
||||
}
|
||||
|
||||
public static class ExtraMetaDataBytesDecoder
|
||||
implements Iterable<ExtraMetaDataBytesDecoder>, java.util.Iterator<ExtraMetaDataBytesDecoder> {
|
||||
private static final int HEADER_SIZE = 4;
|
||||
private final GroupSizeEncodingDecoder dimensions = new GroupSizeEncodingDecoder();
|
||||
private StorageMetaDataDecoder parentMessage;
|
||||
private DirectBuffer buffer;
|
||||
private int blockLength;
|
||||
private int actingVersion;
|
||||
private int count;
|
||||
private int index;
|
||||
private int offset;
|
||||
|
||||
public void wrap(final StorageMetaDataDecoder parentMessage, final DirectBuffer buffer) {
|
||||
this.parentMessage = parentMessage;
|
||||
this.buffer = buffer;
|
||||
dimensions.wrap(buffer, parentMessage.limit());
|
||||
blockLength = dimensions.blockLength();
|
||||
count = dimensions.numInGroup();
|
||||
index = -1;
|
||||
parentMessage.limit(parentMessage.limit() + HEADER_SIZE);
|
||||
}
|
||||
|
||||
public static int sbeHeaderSize() {
|
||||
return HEADER_SIZE;
|
||||
}
|
||||
|
||||
public static int sbeBlockLength() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int actingBlockLength() {
|
||||
return blockLength;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return count;
|
||||
}
|
||||
|
||||
public java.util.Iterator<ExtraMetaDataBytesDecoder> iterator() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return (index + 1) < count;
|
||||
}
|
||||
|
||||
public ExtraMetaDataBytesDecoder next() {
|
||||
if (index + 1 >= count) {
|
||||
throw new java.util.NoSuchElementException();
|
||||
}
|
||||
|
||||
offset = parentMessage.limit();
|
||||
parentMessage.limit(offset + blockLength);
|
||||
++index;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static int bytesId() {
|
||||
return 3;
|
||||
}
|
||||
|
||||
public static String bytesMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static byte bytesNullValue() {
|
||||
return (byte) -128;
|
||||
}
|
||||
|
||||
public static byte bytesMinValue() {
|
||||
return (byte) -127;
|
||||
}
|
||||
|
||||
public static byte bytesMaxValue() {
|
||||
return (byte) 127;
|
||||
}
|
||||
|
||||
public byte bytes() {
|
||||
return buffer.getByte(offset + 0);
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
builder.append('(');
|
||||
//Token{signal=BEGIN_FIELD, name='bytes', description='null', id=3, version=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
//Token{signal=ENCODING, name='int8', description='null', id=-1, version=0, encodedLength=1, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT8, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("bytes=");
|
||||
builder.append(bytes());
|
||||
builder.append(')');
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
||||
public static int sessionIDId() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public static String sessionIDCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String sessionIDMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int sessionIDHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int sessionIDLength() {
|
||||
final int limit = parentMessage.limit();
|
||||
return (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
public int getSessionID(final MutableDirectBuffer dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public int getSessionID(final byte[] dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public String sessionID() {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
final byte[] tmp = new byte[dataLength];
|
||||
buffer.getBytes(limit + headerLength, tmp, 0, dataLength);
|
||||
|
||||
final String value;
|
||||
try {
|
||||
value = new String(tmp, "UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int typeIDId() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public static String typeIDCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String typeIDMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int typeIDHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int typeIDLength() {
|
||||
final int limit = parentMessage.limit();
|
||||
return (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
public int getTypeID(final MutableDirectBuffer dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public int getTypeID(final byte[] dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public String typeID() {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
final byte[] tmp = new byte[dataLength];
|
||||
buffer.getBytes(limit + headerLength, tmp, 0, dataLength);
|
||||
|
||||
final String value;
|
||||
try {
|
||||
value = new String(tmp, "UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int workerIDId() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
public static String workerIDCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String workerIDMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int workerIDHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int workerIDLength() {
|
||||
final int limit = parentMessage.limit();
|
||||
return (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
public int getWorkerID(final MutableDirectBuffer dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public int getWorkerID(final byte[] dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public String workerID() {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
final byte[] tmp = new byte[dataLength];
|
||||
buffer.getBytes(limit + headerLength, tmp, 0, dataLength);
|
||||
|
||||
final String value;
|
||||
try {
|
||||
value = new String(tmp, "UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int initTypeClassId() {
|
||||
return 7;
|
||||
}
|
||||
|
||||
public static String initTypeClassCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String initTypeClassMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int initTypeClassHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int initTypeClassLength() {
|
||||
final int limit = parentMessage.limit();
|
||||
return (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
public int getInitTypeClass(final MutableDirectBuffer dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public int getInitTypeClass(final byte[] dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public String initTypeClass() {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
final byte[] tmp = new byte[dataLength];
|
||||
buffer.getBytes(limit + headerLength, tmp, 0, dataLength);
|
||||
|
||||
final String value;
|
||||
try {
|
||||
value = new String(tmp, "UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int updateTypeClassId() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public static String updateTypeClassCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String updateTypeClassMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int updateTypeClassHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public int updateTypeClassLength() {
|
||||
final int limit = parentMessage.limit();
|
||||
return (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
public int getUpdateTypeClass(final MutableDirectBuffer dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public int getUpdateTypeClass(final byte[] dst, final int dstOffset, final int length) {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
final int bytesCopied = Math.min(length, dataLength);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
buffer.getBytes(limit + headerLength, dst, dstOffset, bytesCopied);
|
||||
|
||||
return bytesCopied;
|
||||
}
|
||||
|
||||
public String updateTypeClass() {
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
final int dataLength = (int) (buffer.getInt(limit, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
parentMessage.limit(limit + headerLength + dataLength);
|
||||
final byte[] tmp = new byte[dataLength];
|
||||
buffer.getBytes(limit + headerLength, tmp, 0, dataLength);
|
||||
|
||||
final String value;
|
||||
try {
|
||||
value = new String(tmp, "UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
final int originalLimit = limit();
|
||||
limit(offset + actingBlockLength);
|
||||
builder.append("[StorageMetaData](sbeTemplateId=");
|
||||
builder.append(TEMPLATE_ID);
|
||||
builder.append("|sbeSchemaId=");
|
||||
builder.append(SCHEMA_ID);
|
||||
builder.append("|sbeSchemaVersion=");
|
||||
if (actingVersion != SCHEMA_VERSION) {
|
||||
builder.append(actingVersion);
|
||||
builder.append('/');
|
||||
}
|
||||
builder.append(SCHEMA_VERSION);
|
||||
builder.append("|sbeBlockLength=");
|
||||
if (actingBlockLength != BLOCK_LENGTH) {
|
||||
builder.append(actingBlockLength);
|
||||
builder.append('/');
|
||||
}
|
||||
builder.append(BLOCK_LENGTH);
|
||||
builder.append("):");
|
||||
//Token{signal=BEGIN_FIELD, name='timeStamp', description='null', id=1, version=0, encodedLength=0, offset=0, componentTokenCount=3, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
//Token{signal=ENCODING, name='int64', description='null', id=-1, version=0, encodedLength=8, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=INT64, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("timeStamp=");
|
||||
builder.append(timeStamp());
|
||||
builder.append('|');
|
||||
//Token{signal=BEGIN_GROUP, name='extraMetaDataBytes', description='Extra metadata bytes', id=2, version=0, encodedLength=1, offset=8, componentTokenCount=9, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='null', timeUnit=null, semanticType='null'}}
|
||||
builder.append("extraMetaDataBytes=[");
|
||||
ExtraMetaDataBytesDecoder extraMetaDataBytes = extraMetaDataBytes();
|
||||
if (extraMetaDataBytes.count() > 0) {
|
||||
while (extraMetaDataBytes.hasNext()) {
|
||||
extraMetaDataBytes.next().appendTo(builder);
|
||||
builder.append(',');
|
||||
}
|
||||
builder.setLength(builder.length() - 1);
|
||||
}
|
||||
builder.append(']');
|
||||
builder.append('|');
|
||||
//Token{signal=BEGIN_VAR_DATA, name='sessionID', description='null', id=4, version=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("sessionID=");
|
||||
builder.append(sessionID());
|
||||
builder.append('|');
|
||||
//Token{signal=BEGIN_VAR_DATA, name='typeID', description='null', id=5, version=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("typeID=");
|
||||
builder.append(typeID());
|
||||
builder.append('|');
|
||||
//Token{signal=BEGIN_VAR_DATA, name='workerID', description='null', id=6, version=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("workerID=");
|
||||
builder.append(workerID());
|
||||
builder.append('|');
|
||||
//Token{signal=BEGIN_VAR_DATA, name='initTypeClass', description='null', id=7, version=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("initTypeClass=");
|
||||
builder.append(initTypeClass());
|
||||
builder.append('|');
|
||||
//Token{signal=BEGIN_VAR_DATA, name='updateTypeClass', description='null', id=8, version=0, encodedLength=0, offset=-1, componentTokenCount=6, encoding=Encoding{presence=REQUIRED, primitiveType=null, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='null', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("updateTypeClass=");
|
||||
builder.append(updateTypeClass());
|
||||
|
||||
limit(originalLimit);
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
+567
@@ -0,0 +1,567 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.StorageMetaDataEncoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class StorageMetaDataEncoder {
|
||||
public static final int BLOCK_LENGTH = 8;
|
||||
public static final int TEMPLATE_ID = 3;
|
||||
public static final int SCHEMA_ID = 1;
|
||||
public static final int SCHEMA_VERSION = 0;
|
||||
|
||||
private final StorageMetaDataEncoder parentMessage = this;
|
||||
private MutableDirectBuffer buffer;
|
||||
protected int offset;
|
||||
protected int limit;
|
||||
protected int actingBlockLength;
|
||||
protected int actingVersion;
|
||||
|
||||
public int sbeBlockLength() {
|
||||
return BLOCK_LENGTH;
|
||||
}
|
||||
|
||||
public int sbeTemplateId() {
|
||||
return TEMPLATE_ID;
|
||||
}
|
||||
|
||||
public int sbeSchemaId() {
|
||||
return SCHEMA_ID;
|
||||
}
|
||||
|
||||
public int sbeSchemaVersion() {
|
||||
return SCHEMA_VERSION;
|
||||
}
|
||||
|
||||
public String sbeSemanticType() {
|
||||
return "";
|
||||
}
|
||||
|
||||
public int offset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder wrap(final MutableDirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
limit(offset + BLOCK_LENGTH);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return limit - offset;
|
||||
}
|
||||
|
||||
public int limit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void limit(final int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public static long timeStampNullValue() {
|
||||
return -9223372036854775808L;
|
||||
}
|
||||
|
||||
public static long timeStampMinValue() {
|
||||
return -9223372036854775807L;
|
||||
}
|
||||
|
||||
public static long timeStampMaxValue() {
|
||||
return 9223372036854775807L;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder timeStamp(final long value) {
|
||||
buffer.putLong(offset + 0, value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private final ExtraMetaDataBytesEncoder extraMetaDataBytes = new ExtraMetaDataBytesEncoder();
|
||||
|
||||
public static long extraMetaDataBytesId() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public ExtraMetaDataBytesEncoder extraMetaDataBytesCount(final int count) {
|
||||
extraMetaDataBytes.wrap(parentMessage, buffer, count);
|
||||
return extraMetaDataBytes;
|
||||
}
|
||||
|
||||
public static class ExtraMetaDataBytesEncoder {
|
||||
private static final int HEADER_SIZE = 4;
|
||||
private final GroupSizeEncodingEncoder dimensions = new GroupSizeEncodingEncoder();
|
||||
private StorageMetaDataEncoder parentMessage;
|
||||
private MutableDirectBuffer buffer;
|
||||
private int blockLength;
|
||||
private int actingVersion;
|
||||
private int count;
|
||||
private int index;
|
||||
private int offset;
|
||||
|
||||
public void wrap(final StorageMetaDataEncoder parentMessage, final MutableDirectBuffer buffer,
|
||||
final int count) {
|
||||
if (count < 0 || count > 65534) {
|
||||
throw new IllegalArgumentException("count outside allowed range: count=" + count);
|
||||
}
|
||||
|
||||
this.parentMessage = parentMessage;
|
||||
this.buffer = buffer;
|
||||
actingVersion = SCHEMA_VERSION;
|
||||
dimensions.wrap(buffer, parentMessage.limit());
|
||||
dimensions.blockLength((int) 1);
|
||||
dimensions.numInGroup((int) count);
|
||||
index = -1;
|
||||
this.count = count;
|
||||
blockLength = 1;
|
||||
parentMessage.limit(parentMessage.limit() + HEADER_SIZE);
|
||||
}
|
||||
|
||||
public static int sbeHeaderSize() {
|
||||
return HEADER_SIZE;
|
||||
}
|
||||
|
||||
public static int sbeBlockLength() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public ExtraMetaDataBytesEncoder next() {
|
||||
if (index + 1 >= count) {
|
||||
throw new java.util.NoSuchElementException();
|
||||
}
|
||||
|
||||
offset = parentMessage.limit();
|
||||
parentMessage.limit(offset + blockLength);
|
||||
++index;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static byte bytesNullValue() {
|
||||
return (byte) -128;
|
||||
}
|
||||
|
||||
public static byte bytesMinValue() {
|
||||
return (byte) -127;
|
||||
}
|
||||
|
||||
public static byte bytesMaxValue() {
|
||||
return (byte) 127;
|
||||
}
|
||||
|
||||
public ExtraMetaDataBytesEncoder bytes(final byte value) {
|
||||
buffer.putByte(offset + 0, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static int sessionIDId() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public static String sessionIDCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String sessionIDMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int sessionIDHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putSessionID(final DirectBuffer src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putSessionID(final byte[] src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder sessionID(final String value) {
|
||||
final byte[] bytes;
|
||||
try {
|
||||
bytes = value.getBytes("UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
final int length = bytes.length;
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, bytes, 0, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static int typeIDId() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public static String typeIDCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String typeIDMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int typeIDHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putTypeID(final DirectBuffer src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putTypeID(final byte[] src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder typeID(final String value) {
|
||||
final byte[] bytes;
|
||||
try {
|
||||
bytes = value.getBytes("UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
final int length = bytes.length;
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, bytes, 0, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static int workerIDId() {
|
||||
return 6;
|
||||
}
|
||||
|
||||
public static String workerIDCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String workerIDMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int workerIDHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putWorkerID(final DirectBuffer src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putWorkerID(final byte[] src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder workerID(final String value) {
|
||||
final byte[] bytes;
|
||||
try {
|
||||
bytes = value.getBytes("UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
final int length = bytes.length;
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, bytes, 0, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static int initTypeClassId() {
|
||||
return 7;
|
||||
}
|
||||
|
||||
public static String initTypeClassCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String initTypeClassMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int initTypeClassHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putInitTypeClass(final DirectBuffer src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putInitTypeClass(final byte[] src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder initTypeClass(final String value) {
|
||||
final byte[] bytes;
|
||||
try {
|
||||
bytes = value.getBytes("UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
final int length = bytes.length;
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, bytes, 0, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public static int updateTypeClassId() {
|
||||
return 8;
|
||||
}
|
||||
|
||||
public static String updateTypeClassCharacterEncoding() {
|
||||
return "UTF-8";
|
||||
}
|
||||
|
||||
public static String updateTypeClassMetaAttribute(final MetaAttribute metaAttribute) {
|
||||
switch (metaAttribute) {
|
||||
case EPOCH:
|
||||
return "unix";
|
||||
case TIME_UNIT:
|
||||
return "nanosecond";
|
||||
case SEMANTIC_TYPE:
|
||||
return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
public static int updateTypeClassHeaderLength() {
|
||||
return 4;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putUpdateTypeClass(final DirectBuffer src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder putUpdateTypeClass(final byte[] src, final int srcOffset, final int length) {
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, src, srcOffset, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public StorageMetaDataEncoder updateTypeClass(final String value) {
|
||||
final byte[] bytes;
|
||||
try {
|
||||
bytes = value.getBytes("UTF-8");
|
||||
} catch (final java.io.UnsupportedEncodingException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
||||
final int length = bytes.length;
|
||||
if (length > 1073741824) {
|
||||
throw new IllegalArgumentException("length > max value for type: " + length);
|
||||
}
|
||||
|
||||
final int headerLength = 4;
|
||||
final int limit = parentMessage.limit();
|
||||
parentMessage.limit(limit + headerLength + length);
|
||||
buffer.putInt(limit, (int) length, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
buffer.putBytes(limit + headerLength, bytes, 0, length);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
StorageMetaDataDecoder writer = new StorageMetaDataDecoder();
|
||||
writer.wrap(buffer, offset, BLOCK_LENGTH, SCHEMA_VERSION);
|
||||
|
||||
return writer.appendTo(builder);
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.SummaryType"})
|
||||
public enum SummaryType {
|
||||
Mean((short) 0), Stdev((short) 1), MeanMagnitude((short) 2), NULL_VAL((short) 255);
|
||||
|
||||
private final short value;
|
||||
|
||||
SummaryType(final short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public short value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public static SummaryType get(final short value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return Mean;
|
||||
case 1:
|
||||
return Stdev;
|
||||
case 2:
|
||||
return MeanMagnitude;
|
||||
}
|
||||
|
||||
if ((short) 255 == value) {
|
||||
return NULL_VAL;
|
||||
}
|
||||
|
||||
throw new IllegalArgumentException("Unknown value: " + value);
|
||||
}
|
||||
}
|
||||
+2594
File diff suppressed because it is too large
Load Diff
+1667
File diff suppressed because it is too large
Load Diff
+296
@@ -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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.UpdateFieldsPresentDecoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class UpdateFieldsPresentDecoder {
|
||||
public static final int ENCODED_LENGTH = 4;
|
||||
private DirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public UpdateFieldsPresentDecoder wrap(final DirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public boolean score() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 0));
|
||||
}
|
||||
|
||||
public boolean memoryUse() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 1));
|
||||
}
|
||||
|
||||
public boolean performance() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 2));
|
||||
}
|
||||
|
||||
public boolean garbageCollection() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 3));
|
||||
}
|
||||
|
||||
public boolean histogramParameters() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 4));
|
||||
}
|
||||
|
||||
public boolean histogramGradients() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 5));
|
||||
}
|
||||
|
||||
public boolean histogramUpdates() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 6));
|
||||
}
|
||||
|
||||
public boolean histogramActivations() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 7));
|
||||
}
|
||||
|
||||
public boolean meanParameters() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 8));
|
||||
}
|
||||
|
||||
public boolean meanGradients() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 9));
|
||||
}
|
||||
|
||||
public boolean meanUpdates() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 10));
|
||||
}
|
||||
|
||||
public boolean meanActivations() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 11));
|
||||
}
|
||||
|
||||
public boolean stdevParameters() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 12));
|
||||
}
|
||||
|
||||
public boolean stdevGradients() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 13));
|
||||
}
|
||||
|
||||
public boolean stdevUpdates() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 14));
|
||||
}
|
||||
|
||||
public boolean stdevActivations() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 15));
|
||||
}
|
||||
|
||||
public boolean meanMagnitudeParameters() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 16));
|
||||
}
|
||||
|
||||
public boolean meanMagnitudeGradients() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 17));
|
||||
}
|
||||
|
||||
public boolean meanMagnitudeUpdates() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 18));
|
||||
}
|
||||
|
||||
public boolean meanMagnitudeActivations() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 19));
|
||||
}
|
||||
|
||||
public boolean learningRatesPresent() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 20));
|
||||
}
|
||||
|
||||
public boolean dataSetMetaDataPresent() {
|
||||
return 0 != (buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN) & (1 << 21));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
builder.append('{');
|
||||
boolean atLeastOne = false;
|
||||
if (score()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("score");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (memoryUse()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("memoryUse");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (performance()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("performance");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (garbageCollection()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("garbageCollection");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (histogramParameters()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("histogramParameters");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (histogramGradients()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("histogramGradients");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (histogramUpdates()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("histogramUpdates");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (histogramActivations()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("histogramActivations");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanParameters()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanParameters");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanGradients()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanGradients");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanUpdates()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanUpdates");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanActivations()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanActivations");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (stdevParameters()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("stdevParameters");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (stdevGradients()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("stdevGradients");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (stdevUpdates()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("stdevUpdates");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (stdevActivations()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("stdevActivations");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanMagnitudeParameters()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanMagnitudeParameters");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanMagnitudeGradients()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanMagnitudeGradients");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanMagnitudeUpdates()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanMagnitudeUpdates");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (meanMagnitudeActivations()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("meanMagnitudeActivations");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (learningRatesPresent()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("learningRatesPresent");
|
||||
atLeastOne = true;
|
||||
}
|
||||
if (dataSetMetaDataPresent()) {
|
||||
if (atLeastOne) {
|
||||
builder.append(',');
|
||||
}
|
||||
builder.append("dataSetMetaDataPresent");
|
||||
atLeastOne = true;
|
||||
}
|
||||
builder.append('}');
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.UpdateFieldsPresentEncoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class UpdateFieldsPresentEncoder {
|
||||
public static final int ENCODED_LENGTH = 4;
|
||||
private MutableDirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public UpdateFieldsPresentEncoder wrap(final MutableDirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder clear() {
|
||||
buffer.putInt(offset, (int) 0L, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder score(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 0) : bits & ~(1 << 0);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder memoryUse(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 1) : bits & ~(1 << 1);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder performance(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 2) : bits & ~(1 << 2);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder garbageCollection(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 3) : bits & ~(1 << 3);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder histogramParameters(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 4) : bits & ~(1 << 4);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder histogramGradients(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 5) : bits & ~(1 << 5);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder histogramUpdates(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 6) : bits & ~(1 << 6);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder histogramActivations(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 7) : bits & ~(1 << 7);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanParameters(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 8) : bits & ~(1 << 8);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanGradients(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 9) : bits & ~(1 << 9);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanUpdates(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 10) : bits & ~(1 << 10);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanActivations(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 11) : bits & ~(1 << 11);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder stdevParameters(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 12) : bits & ~(1 << 12);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder stdevGradients(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 13) : bits & ~(1 << 13);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder stdevUpdates(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 14) : bits & ~(1 << 14);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder stdevActivations(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 15) : bits & ~(1 << 15);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanMagnitudeParameters(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 16) : bits & ~(1 << 16);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanMagnitudeGradients(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 17) : bits & ~(1 << 17);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanMagnitudeUpdates(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 18) : bits & ~(1 << 18);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder meanMagnitudeActivations(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 19) : bits & ~(1 << 19);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder learningRatesPresent(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 20) : bits & ~(1 << 20);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
public UpdateFieldsPresentEncoder dataSetMetaDataPresent(final boolean value) {
|
||||
int bits = buffer.getInt(offset, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
bits = value ? bits | (1 << 21) : bits & ~(1 << 21);
|
||||
buffer.putInt(offset, bits, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.VarDataUTF8Decoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class VarDataUTF8Decoder {
|
||||
public static final int ENCODED_LENGTH = -1;
|
||||
private DirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public VarDataUTF8Decoder wrap(final DirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public static long lengthNullValue() {
|
||||
return 4294967294L;
|
||||
}
|
||||
|
||||
public static long lengthMinValue() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public static long lengthMaxValue() {
|
||||
return 1073741824L;
|
||||
}
|
||||
|
||||
public long length() {
|
||||
return (buffer.getInt(offset + 0, java.nio.ByteOrder.LITTLE_ENDIAN) & 0xFFFF_FFFFL);
|
||||
}
|
||||
|
||||
|
||||
public static short varDataNullValue() {
|
||||
return (short) 255;
|
||||
}
|
||||
|
||||
public static short varDataMinValue() {
|
||||
return (short) 0;
|
||||
}
|
||||
|
||||
public static short varDataMaxValue() {
|
||||
return (short) 254;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
builder.append('(');
|
||||
//Token{signal=ENCODING, name='length', description='null', id=-1, version=0, encodedLength=4, offset=0, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=UINT32, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=1073741824, nullValue=null, constValue=null, characterEncoding='UTF-8', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append("length=");
|
||||
builder.append(length());
|
||||
builder.append('|');
|
||||
//Token{signal=ENCODING, name='varData', description='null', id=-1, version=0, encodedLength=-1, offset=4, componentTokenCount=1, encoding=Encoding{presence=REQUIRED, primitiveType=UINT8, byteOrder=LITTLE_ENDIAN, minValue=null, maxValue=null, nullValue=null, constValue=null, characterEncoding='UTF-8', epoch='unix', timeUnit=nanosecond, semanticType='null'}}
|
||||
builder.append(')');
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.stats.sbe;
|
||||
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
|
||||
@javax.annotation.Generated(value = {"org.deeplearning4j.ui.stats.sbe.VarDataUTF8Encoder"})
|
||||
@SuppressWarnings("all")
|
||||
public class VarDataUTF8Encoder {
|
||||
public static final int ENCODED_LENGTH = -1;
|
||||
private MutableDirectBuffer buffer;
|
||||
private int offset;
|
||||
|
||||
public VarDataUTF8Encoder wrap(final MutableDirectBuffer buffer, final int offset) {
|
||||
this.buffer = buffer;
|
||||
this.offset = offset;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public int encodedLength() {
|
||||
return ENCODED_LENGTH;
|
||||
}
|
||||
|
||||
public static long lengthNullValue() {
|
||||
return 4294967294L;
|
||||
}
|
||||
|
||||
public static long lengthMinValue() {
|
||||
return 0L;
|
||||
}
|
||||
|
||||
public static long lengthMaxValue() {
|
||||
return 1073741824L;
|
||||
}
|
||||
|
||||
public VarDataUTF8Encoder length(final long value) {
|
||||
buffer.putInt(offset + 0, (int) value, java.nio.ByteOrder.LITTLE_ENDIAN);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public static short varDataNullValue() {
|
||||
return (short) 255;
|
||||
}
|
||||
|
||||
public static short varDataMinValue() {
|
||||
return (short) 0;
|
||||
}
|
||||
|
||||
public static short varDataMaxValue() {
|
||||
return (short) 254;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder(100)).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(final StringBuilder builder) {
|
||||
VarDataUTF8Decoder writer = new VarDataUTF8Decoder();
|
||||
writer.wrap(buffer, offset);
|
||||
|
||||
return writer.appendTo(builder);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage;
|
||||
|
||||
import org.agrona.DirectBuffer;
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
import org.deeplearning4j.core.storage.Persistable;
|
||||
|
||||
public interface AgronaPersistable extends Persistable {
|
||||
|
||||
void encode(MutableDirectBuffer buffer);
|
||||
|
||||
void decode(DirectBuffer buffer);
|
||||
|
||||
}
|
||||
+468
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.deeplearning4j.core.storage.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public abstract class BaseCollectionStatsStorage implements StatsStorage {
|
||||
|
||||
protected Set<String> sessionIDs;
|
||||
protected Map<SessionTypeId, StorageMetaData> storageMetaData;
|
||||
protected Map<SessionTypeWorkerId, Persistable> staticInfo;
|
||||
|
||||
protected Map<SessionTypeWorkerId, Map<Long, Persistable>> updates = new ConcurrentHashMap<>();
|
||||
|
||||
protected List<StatsStorageListener> listeners = new ArrayList<>();
|
||||
|
||||
protected BaseCollectionStatsStorage() {
|
||||
|
||||
}
|
||||
|
||||
protected abstract Map<Long, Persistable> getUpdateMap(String sessionID, String typeID, String workerID,
|
||||
boolean createIfRequired);
|
||||
|
||||
//Return any relevant storage events
|
||||
//We want to return these so they can be logged later. Can't be logged immediately, as this may case a race
|
||||
//condition with whatever is receiving the events: i.e., might get the event before the contents are actually
|
||||
//available in the DB
|
||||
protected List<StatsStorageEvent> checkStorageEvents(Persistable p) {
|
||||
if (listeners.isEmpty())
|
||||
return null;
|
||||
|
||||
int count = 0;
|
||||
StatsStorageEvent newSID = null;
|
||||
StatsStorageEvent newTID = null;
|
||||
StatsStorageEvent newWID = null;
|
||||
|
||||
//Is this a new session ID?
|
||||
if (!sessionIDs.contains(p.getSessionID())) {
|
||||
newSID = new StatsStorageEvent(this, StatsStorageListener.EventType.NewSessionID, p.getSessionID(),
|
||||
p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
count++;
|
||||
}
|
||||
|
||||
//Check for new type and worker IDs
|
||||
//TODO probably more efficient way to do this
|
||||
boolean foundTypeId = false;
|
||||
boolean foundWorkerId = false;
|
||||
String typeId = p.getTypeID();
|
||||
String wid = p.getWorkerID();
|
||||
for (SessionTypeId ts : storageMetaData.keySet()) {
|
||||
if (typeId.equals(ts.getTypeID())) {
|
||||
foundTypeId = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (SessionTypeWorkerId stw : staticInfo.keySet()) {
|
||||
if (!foundTypeId && typeId.equals(stw.getTypeID())) {
|
||||
foundTypeId = true;
|
||||
}
|
||||
if (!foundWorkerId && wid.equals(stw.getWorkerID())) {
|
||||
foundWorkerId = true;
|
||||
}
|
||||
if (foundTypeId && foundWorkerId)
|
||||
break;
|
||||
}
|
||||
if (!foundTypeId || !foundWorkerId) {
|
||||
for (SessionTypeWorkerId stw : updates.keySet()) {
|
||||
if (!foundTypeId && typeId.equals(stw.getTypeID())) {
|
||||
foundTypeId = true;
|
||||
}
|
||||
if (!foundWorkerId && wid.equals(stw.getWorkerID())) {
|
||||
foundWorkerId = true;
|
||||
}
|
||||
if (foundTypeId && foundWorkerId)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!foundTypeId) {
|
||||
//New type ID
|
||||
newTID = new StatsStorageEvent(this, StatsStorageListener.EventType.NewTypeID, p.getSessionID(),
|
||||
p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
count++;
|
||||
}
|
||||
if (!foundWorkerId) {
|
||||
//New worker ID
|
||||
newWID = new StatsStorageEvent(this, StatsStorageListener.EventType.NewWorkerID, p.getSessionID(),
|
||||
p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
count++;
|
||||
}
|
||||
if (count == 0)
|
||||
return null;
|
||||
List<StatsStorageEvent> sses = new ArrayList<>(count);
|
||||
if (newSID != null)
|
||||
sses.add(newSID);
|
||||
if (newTID != null)
|
||||
sses.add(newTID);
|
||||
if (newWID != null)
|
||||
sses.add(newWID);
|
||||
return sses;
|
||||
}
|
||||
|
||||
protected void notifyListeners(List<StatsStorageEvent> sses) {
|
||||
if (sses == null || sses.isEmpty() || listeners.isEmpty())
|
||||
return;
|
||||
for (StatsStorageListener l : listeners) {
|
||||
for (StatsStorageEvent e : sses) {
|
||||
l.notify(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listSessionIDs() {
|
||||
return new ArrayList<>(sessionIDs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sessionExists(String sessionID) {
|
||||
return sessionIDs.contains(sessionID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Persistable getStaticInfo(String sessionID, String typeID, String workerID) {
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
return staticInfo.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getAllStaticInfos(String sessionID, String typeID) {
|
||||
List<Persistable> out = new ArrayList<>();
|
||||
for (SessionTypeWorkerId key : staticInfo.keySet()) {
|
||||
if (sessionID.equals(key.getSessionID()) && typeID.equals(key.getTypeID())) {
|
||||
out.add(staticInfo.get(key));
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listTypeIDsForSession(String sessionID) {
|
||||
Set<String> typeIDs = new HashSet<>();
|
||||
for (SessionTypeId st : storageMetaData.keySet()) {
|
||||
if (!sessionID.equals(st.getSessionID()))
|
||||
continue;
|
||||
typeIDs.add(st.getTypeID());
|
||||
}
|
||||
|
||||
for (SessionTypeWorkerId stw : staticInfo.keySet()) {
|
||||
if (!sessionID.equals(stw.getSessionID()))
|
||||
continue;
|
||||
typeIDs.add(stw.getTypeID());
|
||||
}
|
||||
for (SessionTypeWorkerId stw : updates.keySet()) {
|
||||
if (!sessionID.equals(stw.getSessionID()))
|
||||
continue;
|
||||
typeIDs.add(stw.getTypeID());
|
||||
}
|
||||
|
||||
return new ArrayList<>(typeIDs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listWorkerIDsForSession(String sessionID) {
|
||||
List<String> out = new ArrayList<>();
|
||||
for (SessionTypeWorkerId ids : staticInfo.keySet()) {
|
||||
if (sessionID.equals(ids.getSessionID())) {
|
||||
out.add(ids.getWorkerID());
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listWorkerIDsForSessionAndType(String sessionID, String typeID) {
|
||||
List<String> out = new ArrayList<>();
|
||||
for (SessionTypeWorkerId ids : staticInfo.keySet()) {
|
||||
if (sessionID.equals(ids.getSessionID()) && typeID.equals(ids.getTypeID())) {
|
||||
out.add(ids.getWorkerID());
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumUpdateRecordsFor(String sessionID) {
|
||||
int count = 0;
|
||||
for (SessionTypeWorkerId id : updates.keySet()) {
|
||||
if (sessionID.equals(id.getSessionID())) {
|
||||
Map<Long, Persistable> map = updates.get(id);
|
||||
if (map != null)
|
||||
count += map.size();
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumUpdateRecordsFor(String sessionID, String typeID, String workerID) {
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
Map<Long, Persistable> map = updates.get(id);
|
||||
if (map != null)
|
||||
return map.size();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Persistable getLatestUpdate(String sessionID, String typeID, String workerID) {
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
Map<Long, Persistable> map = updates.get(id);
|
||||
if (map == null || map.isEmpty())
|
||||
return null;
|
||||
long maxTime = Long.MIN_VALUE;
|
||||
for (Long l : map.keySet()) {
|
||||
maxTime = Math.max(maxTime, l);
|
||||
}
|
||||
return map.get(maxTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Persistable getUpdate(String sessionID, String typeID, String workerID, long timestamp) {
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
Map<Long, Persistable> map = updates.get(id);
|
||||
if (map == null)
|
||||
return null;
|
||||
|
||||
return map.get(timestamp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getLatestUpdateAllWorkers(String sessionID, String typeID) {
|
||||
List<Persistable> list = new ArrayList<>();
|
||||
|
||||
for (SessionTypeWorkerId id : updates.keySet()) {
|
||||
if (sessionID.equals(id.getSessionID()) && typeID.equals(id.getTypeID())) {
|
||||
Persistable p = getLatestUpdate(sessionID, typeID, id.workerID);
|
||||
if (p != null) {
|
||||
list.add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getAllUpdatesAfter(String sessionID, String typeID, String workerID, long timestamp) {
|
||||
List<Persistable> list = new ArrayList<>();
|
||||
|
||||
Map<Long, Persistable> map = getUpdateMap(sessionID, typeID, workerID, false);
|
||||
if (map == null)
|
||||
return list;
|
||||
|
||||
for (Long time : map.keySet()) {
|
||||
if (time > timestamp) {
|
||||
list.add(map.get(time));
|
||||
}
|
||||
}
|
||||
|
||||
Collections.sort(list, new Comparator<Persistable>() {
|
||||
@Override
|
||||
public int compare(Persistable o1, Persistable o2) {
|
||||
return Long.compare(o1.getTimeStamp(), o2.getTimeStamp());
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getAllUpdatesAfter(String sessionID, String typeID, long timestamp) {
|
||||
List<Persistable> list = new ArrayList<>();
|
||||
|
||||
for (SessionTypeWorkerId stw : staticInfo.keySet()) {
|
||||
if (stw.getSessionID().equals(sessionID) && stw.getTypeID().equals(typeID)) {
|
||||
Map<Long, Persistable> u = updates.get(stw);
|
||||
if (u == null)
|
||||
continue;
|
||||
for (long l : u.keySet()) {
|
||||
if (l > timestamp) {
|
||||
list.add(u.get(l));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Sort by time stamp
|
||||
Collections.sort(list, new Comparator<Persistable>() {
|
||||
@Override
|
||||
public int compare(Persistable o1, Persistable o2) {
|
||||
return Long.compare(o1.getTimeStamp(), o2.getTimeStamp());
|
||||
}
|
||||
});
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageMetaData getStorageMetaData(String sessionID, String typeID) {
|
||||
return this.storageMetaData.get(new SessionTypeId(sessionID, typeID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getAllUpdateTimes(String sessionID, String typeID, String workerID) {
|
||||
SessionTypeWorkerId stw = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
Map<Long,Persistable> m = updates.get(stw);
|
||||
if(m == null){
|
||||
return new long[0];
|
||||
}
|
||||
|
||||
long[] ret = new long[m.size()];
|
||||
int i=0;
|
||||
for(Long l : m.keySet()){
|
||||
ret[i++] = l;
|
||||
if(i >= ret.length)
|
||||
break; //Map "m" can in principle be modified concurrently while iterating here - resulting in an array index exception
|
||||
}
|
||||
Arrays.sort(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getUpdates(String sessionID, String typeID, String workerID, long[] timestamps) {
|
||||
SessionTypeWorkerId stw = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
Map<Long,Persistable> m = updates.get(stw);
|
||||
if(m == null){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
List<Persistable> ret = new ArrayList<>(timestamps.length);
|
||||
for(long l : timestamps){
|
||||
Persistable p = m.get(l);
|
||||
if(p != null){
|
||||
ret.add(p);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ----- Store new info -----
|
||||
|
||||
@Override
|
||||
public abstract void putStaticInfo(Persistable staticInfo);
|
||||
|
||||
@Override
|
||||
public void putStaticInfo(Collection<? extends Persistable> staticInfo) {
|
||||
for (Persistable p : staticInfo) {
|
||||
putStaticInfo(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void putUpdate(Persistable update);
|
||||
|
||||
@Override
|
||||
public void putUpdate(Collection<? extends Persistable> updates) {
|
||||
for (Persistable p : updates) {
|
||||
putUpdate(p);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public abstract void putStorageMetaData(StorageMetaData storageMetaData);
|
||||
|
||||
@Override
|
||||
public void putStorageMetaData(Collection<? extends StorageMetaData> storageMetaData) {
|
||||
for (StorageMetaData m : storageMetaData) {
|
||||
putStorageMetaData(m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----- Listeners -----
|
||||
|
||||
@Override
|
||||
public void registerStatsStorageListener(StatsStorageListener listener) {
|
||||
if (!this.listeners.contains(listener)) {
|
||||
this.listeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterStatsStorageListener(StatsStorageListener listener) {
|
||||
this.listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllListeners() {
|
||||
this.listeners.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StatsStorageListener> getListeners() {
|
||||
return new ArrayList<>(listeners);
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class SessionTypeWorkerId implements Serializable, Comparable<SessionTypeWorkerId> {
|
||||
private final String sessionID;
|
||||
private final String typeID;
|
||||
private final String workerID;
|
||||
|
||||
public SessionTypeWorkerId(String sessionID, String typeID, String workerID) {
|
||||
this.sessionID = sessionID;
|
||||
this.typeID = typeID;
|
||||
this.workerID = workerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(SessionTypeWorkerId o) {
|
||||
int c = sessionID.compareTo(o.sessionID);
|
||||
if (c != 0)
|
||||
return c;
|
||||
c = typeID.compareTo(o.typeID);
|
||||
if (c != 0)
|
||||
return c;
|
||||
return workerID.compareTo(workerID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + sessionID + "," + typeID + "," + workerID + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public static class SessionTypeId implements Serializable, Comparable<SessionTypeId> {
|
||||
private final String sessionID;
|
||||
private final String typeID;
|
||||
|
||||
@Override
|
||||
public int compareTo(SessionTypeId o) {
|
||||
int c = sessionID.compareTo(o.sessionID);
|
||||
if (c != 0)
|
||||
return c;
|
||||
return typeID.compareTo(o.typeID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + sessionID + "," + typeID + ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage;
|
||||
|
||||
import org.deeplearning4j.ui.model.storage.mapdb.MapDBStatsStorage;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class FileStatsStorage extends MapDBStatsStorage {
|
||||
|
||||
private final File file;
|
||||
|
||||
public FileStatsStorage(File f) {
|
||||
super(f);
|
||||
this.file = f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FileStatsStorage(" + file.getPath() + ")";
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage;
|
||||
|
||||
import org.deeplearning4j.core.storage.Persistable;
|
||||
import org.deeplearning4j.core.storage.StatsStorageEvent;
|
||||
import org.deeplearning4j.core.storage.StatsStorageListener;
|
||||
import org.deeplearning4j.core.storage.StorageMetaData;
|
||||
import org.deeplearning4j.ui.model.storage.mapdb.MapDBStatsStorage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class InMemoryStatsStorage extends BaseCollectionStatsStorage {
|
||||
private final String uid;
|
||||
|
||||
public InMemoryStatsStorage() {
|
||||
super();
|
||||
String str = UUID.randomUUID().toString();
|
||||
uid = str.substring(0, Math.min(str.length(), 8));
|
||||
|
||||
sessionIDs = Collections.synchronizedSet(new HashSet<String>());
|
||||
storageMetaData = new ConcurrentHashMap<>();
|
||||
staticInfo = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected synchronized Map<Long, Persistable> getUpdateMap(String sessionID, String typeID, String workerID,
|
||||
boolean createIfRequired) {
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
if (updates.containsKey(id)) {
|
||||
return updates.get(id);
|
||||
}
|
||||
if (!createIfRequired) {
|
||||
return null;
|
||||
}
|
||||
Map<Long, Persistable> updateMap = new ConcurrentHashMap<>();
|
||||
updates.put(id, updateMap);
|
||||
return updateMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStaticInfo(Persistable staticInfo) {
|
||||
List<StatsStorageEvent> sses = checkStorageEvents(staticInfo);
|
||||
if (!sessionIDs.contains(staticInfo.getSessionID())) {
|
||||
sessionIDs.add(staticInfo.getSessionID());
|
||||
}
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(staticInfo.getSessionID(), staticInfo.getTypeID(),
|
||||
staticInfo.getWorkerID());
|
||||
|
||||
this.staticInfo.put(id, staticInfo);
|
||||
StatsStorageEvent sse = null;
|
||||
if (!listeners.isEmpty())
|
||||
sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostStaticInfo, staticInfo.getSessionID(),
|
||||
staticInfo.getTypeID(), staticInfo.getWorkerID(), staticInfo.getTimeStamp());
|
||||
for (StatsStorageListener l : listeners) {
|
||||
l.notify(sse);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putUpdate(Persistable update) {
|
||||
List<StatsStorageEvent> sses = checkStorageEvents(update);
|
||||
Map<Long, Persistable> updateMap =
|
||||
getUpdateMap(update.getSessionID(), update.getTypeID(), update.getWorkerID(), true);
|
||||
updateMap.put(update.getTimeStamp(), update);
|
||||
|
||||
StatsStorageEvent sse = null;
|
||||
if (!listeners.isEmpty())
|
||||
sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostUpdate, update.getSessionID(),
|
||||
update.getTypeID(), update.getWorkerID(), update.getTimeStamp());
|
||||
for (StatsStorageListener l : listeners) {
|
||||
l.notify(sse);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStorageMetaData(StorageMetaData storageMetaData) {
|
||||
List<StatsStorageEvent> sses = checkStorageEvents(storageMetaData);
|
||||
SessionTypeId id = new SessionTypeId(storageMetaData.getSessionID(), storageMetaData.getTypeID());
|
||||
this.storageMetaData.put(id, storageMetaData);
|
||||
|
||||
StatsStorageEvent sse = null;
|
||||
if (!listeners.isEmpty())
|
||||
sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostMetaData,
|
||||
storageMetaData.getSessionID(), storageMetaData.getTypeID(), storageMetaData.getWorkerID(),
|
||||
storageMetaData.getTimeStamp());
|
||||
for (StatsStorageListener l : listeners) {
|
||||
l.notify(sse);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
//No op
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "InMemoryStatsStorage(uid=" + uid + ")";
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage.impl;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.deeplearning4j.core.storage.StorageMetaData;
|
||||
import org.deeplearning4j.ui.model.stats.impl.SbeUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@Data
|
||||
public class JavaStorageMetaData implements StorageMetaData {
|
||||
|
||||
private long timeStamp;
|
||||
private String sessionID;
|
||||
private String typeID;
|
||||
private String workerID;
|
||||
private String initTypeClass;
|
||||
private String updateTypeClass;
|
||||
//Store serialized; saves class exceptions if we don't have the right class, and don't care about deserializing
|
||||
// on this machine, right now
|
||||
private byte[] extraMeta;
|
||||
|
||||
public JavaStorageMetaData() {
|
||||
//No arg constructor for serialization/deserialization
|
||||
}
|
||||
|
||||
public JavaStorageMetaData(long timeStamp, String sessionID, String typeID, String workerID, Class<?> initType,
|
||||
Class<?> updateType) {
|
||||
this(timeStamp, sessionID, typeID, workerID, (initType != null ? initType.getName() : null),
|
||||
(updateType != null ? updateType.getName() : null));
|
||||
}
|
||||
|
||||
public JavaStorageMetaData(long timeStamp, String sessionID, String typeID, String workerID, String initTypeClass,
|
||||
String updateTypeClass) {
|
||||
this(timeStamp, sessionID, typeID, workerID, initTypeClass, updateTypeClass, null);
|
||||
}
|
||||
|
||||
public JavaStorageMetaData(long timeStamp, String sessionID, String typeID, String workerID, String initTypeClass,
|
||||
String updateTypeClass, Serializable extraMetaData) {
|
||||
this.timeStamp = timeStamp;
|
||||
this.sessionID = sessionID;
|
||||
this.typeID = typeID;
|
||||
this.workerID = workerID;
|
||||
this.initTypeClass = initTypeClass;
|
||||
this.updateTypeClass = updateTypeClass;
|
||||
this.extraMeta = (extraMetaData == null ? null : SbeUtil.toBytesSerializable(extraMetaData));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int encodingLengthBytes() {
|
||||
//TODO - presumably a more efficient way to do this
|
||||
byte[] encoded = encode();
|
||||
return encoded.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(this);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer buffer) {
|
||||
buffer.put(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(OutputStream outputStream) throws IOException {
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(outputStream)) {
|
||||
oos.writeObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] decode) {
|
||||
JavaStorageMetaData r;
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(decode))) {
|
||||
r = (JavaStorageMetaData) ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
|
||||
Field[] fields = JavaStorageMetaData.class.getDeclaredFields();
|
||||
for (Field f : fields) {
|
||||
f.setAccessible(true);
|
||||
try {
|
||||
f.set(this, f.get(r));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e); //Should never happen
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuffer buffer) {
|
||||
byte[] bytes = new byte[buffer.remaining()];
|
||||
buffer.get(bytes);
|
||||
decode(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream inputStream) throws IOException {
|
||||
decode(IOUtils.toByteArray(inputStream));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Serializable getExtraMetaData() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.deeplearning4j.core.storage.StatsStorage;
|
||||
import org.deeplearning4j.core.storage.StatsStorageEvent;
|
||||
import org.deeplearning4j.core.storage.StatsStorageListener;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class QueuePairStatsStorageListener implements StatsStorageListener {
|
||||
|
||||
private final StatsStorage statsStorage;
|
||||
private final Queue<Pair<StatsStorage, StatsStorageEvent>> queue;
|
||||
|
||||
@Override
|
||||
public void notify(StatsStorageEvent event) {
|
||||
queue.add(new Pair<>(statsStorage, event));
|
||||
}
|
||||
}
|
||||
+38
@@ -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.model.storage.impl;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.deeplearning4j.core.storage.StatsStorageEvent;
|
||||
import org.deeplearning4j.core.storage.StatsStorageListener;
|
||||
|
||||
import java.util.Queue;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class QueueStatsStorageListener implements StatsStorageListener {
|
||||
|
||||
private final Queue<StatsStorageEvent> queue;
|
||||
|
||||
@Override
|
||||
public void notify(StatsStorageEvent event) {
|
||||
queue.add(event);
|
||||
}
|
||||
}
|
||||
+208
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage.impl;
|
||||
|
||||
import lombok.Data;
|
||||
import org.agrona.DirectBuffer;
|
||||
import org.agrona.MutableDirectBuffer;
|
||||
import org.agrona.concurrent.UnsafeBuffer;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.deeplearning4j.core.storage.StorageMetaData;
|
||||
import org.deeplearning4j.ui.model.stats.impl.SbeUtil;
|
||||
import org.deeplearning4j.ui.model.stats.sbe.MessageHeaderDecoder;
|
||||
import org.deeplearning4j.ui.model.stats.sbe.MessageHeaderEncoder;
|
||||
import org.deeplearning4j.ui.model.stats.sbe.StorageMetaDataDecoder;
|
||||
import org.deeplearning4j.ui.model.stats.sbe.StorageMetaDataEncoder;
|
||||
import org.deeplearning4j.ui.model.storage.AgronaPersistable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@Data
|
||||
public class SbeStorageMetaData implements StorageMetaData, AgronaPersistable {
|
||||
|
||||
|
||||
private long timeStamp;
|
||||
private String sessionID;
|
||||
private String typeID;
|
||||
private String workerID;
|
||||
private String initTypeClass;
|
||||
private String updateTypeClass;
|
||||
//Store serialized; saves class exceptions if we don't have the right class, and don't care about deserializing
|
||||
// on this machine, right now
|
||||
private byte[] extraMeta;
|
||||
|
||||
public SbeStorageMetaData() {
|
||||
//No arg constructor for serialization/deserialization
|
||||
}
|
||||
|
||||
public SbeStorageMetaData(long timeStamp, String sessionID, String typeID, String workerID, Class<?> initType,
|
||||
Class<?> updateType) {
|
||||
this(timeStamp, sessionID, typeID, workerID, (initType != null ? initType.getName() : null),
|
||||
(updateType != null ? updateType.getName() : null));
|
||||
}
|
||||
|
||||
public SbeStorageMetaData(long timeStamp, String sessionID, String typeID, String workerID, String initTypeClass,
|
||||
String updateTypeClass) {
|
||||
this(timeStamp, sessionID, typeID, workerID, initTypeClass, updateTypeClass, null);
|
||||
}
|
||||
|
||||
public SbeStorageMetaData(long timeStamp, String sessionID, String typeID, String workerID, String initTypeClass,
|
||||
String updateTypeClass, Serializable extraMetaData) {
|
||||
this.timeStamp = timeStamp;
|
||||
this.sessionID = sessionID;
|
||||
this.typeID = typeID;
|
||||
this.workerID = workerID;
|
||||
this.initTypeClass = initTypeClass;
|
||||
this.updateTypeClass = updateTypeClass;
|
||||
this.extraMeta = (extraMetaData == null ? null : SbeUtil.toBytesSerializable(extraMetaData));
|
||||
}
|
||||
|
||||
public Serializable getExtraMetaData() {
|
||||
return SbeUtil.fromBytesSerializable(extraMeta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int encodingLengthBytes() {
|
||||
//TODO store byte[]s so we don't end up calculating again in encode
|
||||
//SBE buffer is composed of:
|
||||
//(a) Header: 8 bytes (4x uint16 = 8 bytes)
|
||||
//(b) timestamp: fixed length long value (8 bytes)
|
||||
//(b) 5 variable length fields. 4 bytes header (each) + content = 20 bytes + content
|
||||
//(c) Variable length byte[]. 4 bytes header + content
|
||||
|
||||
int bufferSize = 8 + 8 + 20 + 4;
|
||||
byte[] bSessionID = SbeUtil.toBytes(true, sessionID);
|
||||
byte[] bTypeID = SbeUtil.toBytes(true, typeID);
|
||||
byte[] bWorkerID = SbeUtil.toBytes(true, workerID);
|
||||
byte[] bInitTypeClass = SbeUtil.toBytes(true, initTypeClass);
|
||||
byte[] bUpdateTypeClass = SbeUtil.toBytes(true, updateTypeClass);
|
||||
byte[] bExtraMetaData = SbeUtil.toBytesSerializable(extraMeta);
|
||||
|
||||
bufferSize += bSessionID.length + bTypeID.length + bWorkerID.length + bInitTypeClass.length
|
||||
+ bUpdateTypeClass.length + bExtraMetaData.length;
|
||||
|
||||
return bufferSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
byte[] bytes = new byte[encodingLengthBytes()];
|
||||
MutableDirectBuffer buffer = new UnsafeBuffer(bytes);
|
||||
encode(buffer);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer buffer) {
|
||||
encode(new UnsafeBuffer(buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(MutableDirectBuffer buffer) {
|
||||
MessageHeaderEncoder enc = new MessageHeaderEncoder();
|
||||
StorageMetaDataEncoder smde = new StorageMetaDataEncoder();
|
||||
|
||||
enc.wrap(buffer, 0).blockLength(smde.sbeBlockLength()).templateId(smde.sbeTemplateId())
|
||||
.schemaId(smde.sbeSchemaId()).version(smde.sbeSchemaVersion());
|
||||
|
||||
int offset = enc.encodedLength(); //Expect 8 bytes
|
||||
|
||||
byte[] bSessionID = SbeUtil.toBytes(true, sessionID);
|
||||
byte[] bTypeID = SbeUtil.toBytes(true, typeID);
|
||||
byte[] bWorkerID = SbeUtil.toBytes(true, workerID);
|
||||
byte[] bInitTypeClass = SbeUtil.toBytes(true, initTypeClass);
|
||||
byte[] bUpdateTypeClass = SbeUtil.toBytes(true, updateTypeClass);
|
||||
|
||||
smde.wrap(buffer, offset).timeStamp(timeStamp);
|
||||
|
||||
StorageMetaDataEncoder.ExtraMetaDataBytesEncoder ext =
|
||||
smde.extraMetaDataBytesCount(extraMeta == null ? 0 : extraMeta.length);
|
||||
if (extraMeta != null) {
|
||||
for (byte b : extraMeta) {
|
||||
ext.next().bytes(b);
|
||||
}
|
||||
}
|
||||
|
||||
smde.putSessionID(bSessionID, 0, bSessionID.length).putTypeID(bTypeID, 0, bTypeID.length)
|
||||
.putWorkerID(bWorkerID, 0, bWorkerID.length)
|
||||
.putInitTypeClass(bInitTypeClass, 0, bInitTypeClass.length)
|
||||
.putUpdateTypeClass(bUpdateTypeClass, 0, bUpdateTypeClass.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(OutputStream outputStream) throws IOException {
|
||||
//TODO there may be more efficient way of doing this
|
||||
outputStream.write(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] decode) {
|
||||
MutableDirectBuffer buffer = new UnsafeBuffer(decode);
|
||||
decode(buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuffer buffer) {
|
||||
decode(new UnsafeBuffer(buffer));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(DirectBuffer buffer) {
|
||||
|
||||
MessageHeaderDecoder dec = new MessageHeaderDecoder();
|
||||
dec.wrap(buffer, 0);
|
||||
final int blockLength = dec.blockLength();
|
||||
final int version = dec.version();
|
||||
final int headerLength = dec.encodedLength();
|
||||
|
||||
//TODO Validate header, version etc
|
||||
|
||||
StorageMetaDataDecoder smdd = new StorageMetaDataDecoder();
|
||||
smdd.wrap(buffer, headerLength, blockLength, version);
|
||||
timeStamp = smdd.timeStamp();
|
||||
|
||||
StorageMetaDataDecoder.ExtraMetaDataBytesDecoder ext = smdd.extraMetaDataBytes();
|
||||
int length = ext.count();
|
||||
if (length > 0) {
|
||||
extraMeta = new byte[length];
|
||||
int i = 0;
|
||||
for (StorageMetaDataDecoder.ExtraMetaDataBytesDecoder d : ext) {
|
||||
extraMeta[i++] = d.bytes();
|
||||
}
|
||||
}
|
||||
|
||||
sessionID = smdd.sessionID();
|
||||
typeID = smdd.typeID();
|
||||
workerID = smdd.workerID();
|
||||
initTypeClass = smdd.initTypeClass();
|
||||
updateTypeClass = smdd.updateTypeClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream inputStream) throws IOException {
|
||||
byte[] bytes = IOUtils.toByteArray(inputStream);
|
||||
decode(bytes);
|
||||
}
|
||||
}
|
||||
+344
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage.mapdb;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
import org.deeplearning4j.config.DL4JClassLoading;
|
||||
import org.deeplearning4j.core.storage.*;
|
||||
import org.deeplearning4j.ui.model.storage.BaseCollectionStatsStorage;
|
||||
import org.mapdb.*;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class MapDBStatsStorage extends BaseCollectionStatsStorage {
|
||||
|
||||
private static final String COMPOSITE_KEY_HEADER = "&&&";
|
||||
private static final String COMPOSITE_KEY_SEPARATOR = "@@@";
|
||||
|
||||
private boolean isClosed = false;
|
||||
private DB db;
|
||||
private Lock updateMapLock = new ReentrantLock(true);
|
||||
|
||||
private Map<String, Integer> classToInteger; //For storage
|
||||
private Map<Integer, String> integerToClass; //For storage
|
||||
private Atomic.Integer classCounter;
|
||||
|
||||
public MapDBStatsStorage() {
|
||||
this(new Builder());
|
||||
}
|
||||
|
||||
public MapDBStatsStorage(File f) {
|
||||
this(new Builder().file(f));
|
||||
}
|
||||
|
||||
private MapDBStatsStorage(Builder builder) {
|
||||
File f = builder.getFile();
|
||||
|
||||
if (f == null) {
|
||||
//In-Memory Stats Storage
|
||||
db = DBMaker.memoryDB().make();
|
||||
} else {
|
||||
db = DBMaker.fileDB(f).closeOnJvmShutdown().transactionEnable() //Default to Write Ahead Log - lower performance, but has crash protection
|
||||
.make();
|
||||
}
|
||||
|
||||
//Initialize/open the required maps/lists
|
||||
sessionIDs = db.hashSet("sessionIDs", Serializer.STRING).createOrOpen();
|
||||
storageMetaData = db.hashMap("storageMetaData").keySerializer(new SessionTypeIdSerializer())
|
||||
.valueSerializer(new PersistableSerializer<StorageMetaData>()).createOrOpen();
|
||||
staticInfo = db.hashMap("staticInfo").keySerializer(new SessionTypeWorkerIdSerializer())
|
||||
.valueSerializer(new PersistableSerializer<>()).createOrOpen();
|
||||
|
||||
classToInteger = db.hashMap("classToInteger").keySerializer(Serializer.STRING)
|
||||
.valueSerializer(Serializer.INTEGER).createOrOpen();
|
||||
|
||||
integerToClass = db.hashMap("integerToClass").keySerializer(Serializer.INTEGER)
|
||||
.valueSerializer(Serializer.STRING).createOrOpen();
|
||||
|
||||
classCounter = db.atomicInteger("classCounter").createOrOpen();
|
||||
|
||||
//Load up any saved update maps to the update map...
|
||||
for (String s : db.getAllNames()) {
|
||||
if (s.startsWith(COMPOSITE_KEY_HEADER)) {
|
||||
Map<Long, Persistable> m = db.hashMap(s).keySerializer(Serializer.LONG)
|
||||
.valueSerializer(new PersistableSerializer<>()).open();
|
||||
String[] arr = s.split(COMPOSITE_KEY_SEPARATOR);
|
||||
arr[0] = arr[0].substring(COMPOSITE_KEY_HEADER.length()); //Remove header...
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(arr[0], arr[1], arr[2]);
|
||||
updates.put(id, m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<Long, Persistable> getUpdateMap(String sessionID, String typeID, String workerID,
|
||||
boolean createIfRequired) {
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(sessionID, typeID, workerID);
|
||||
if (updates.containsKey(id)) {
|
||||
return updates.get(id);
|
||||
}
|
||||
if (!createIfRequired) {
|
||||
return null;
|
||||
}
|
||||
String compositeKey = COMPOSITE_KEY_HEADER + sessionID + COMPOSITE_KEY_SEPARATOR + typeID
|
||||
+ COMPOSITE_KEY_SEPARATOR + workerID;
|
||||
|
||||
Map<Long, Persistable> updateMap;
|
||||
updateMapLock.lock();
|
||||
try {
|
||||
//Try again, in case another thread created it before lock was acquired in this thread
|
||||
if (updates.containsKey(id)) {
|
||||
return updates.get(id);
|
||||
}
|
||||
updateMap = db.hashMap(compositeKey).keySerializer(Serializer.LONG)
|
||||
.valueSerializer(new PersistableSerializer<>()).createOrOpen();
|
||||
updates.put(id, updateMap);
|
||||
} finally {
|
||||
updateMapLock.unlock();
|
||||
}
|
||||
|
||||
return updateMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
db.commit(); //For write ahead log: need to ensure that we persist all data to disk...
|
||||
db.close();
|
||||
isClosed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
return isClosed;
|
||||
}
|
||||
|
||||
// ----- Store new info -----
|
||||
|
||||
@Override
|
||||
public void putStaticInfo(Persistable staticInfo) {
|
||||
List<StatsStorageEvent> sses = checkStorageEvents(staticInfo);
|
||||
if (!sessionIDs.contains(staticInfo.getSessionID())) {
|
||||
sessionIDs.add(staticInfo.getSessionID());
|
||||
}
|
||||
SessionTypeWorkerId id = new SessionTypeWorkerId(staticInfo.getSessionID(), staticInfo.getTypeID(),
|
||||
staticInfo.getWorkerID());
|
||||
|
||||
this.staticInfo.put(id, staticInfo);
|
||||
db.commit(); //For write ahead log: need to ensure that we persist all data to disk...
|
||||
StatsStorageEvent sse = null;
|
||||
if (!listeners.isEmpty())
|
||||
sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostStaticInfo, staticInfo.getSessionID(),
|
||||
staticInfo.getTypeID(), staticInfo.getWorkerID(), staticInfo.getTimeStamp());
|
||||
for (StatsStorageListener l : listeners) {
|
||||
l.notify(sse);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putUpdate(Persistable update) {
|
||||
List<StatsStorageEvent> sses = checkStorageEvents(update);
|
||||
Map<Long, Persistable> updateMap =
|
||||
getUpdateMap(update.getSessionID(), update.getTypeID(), update.getWorkerID(), true);
|
||||
updateMap.put(update.getTimeStamp(), update);
|
||||
db.commit(); //For write ahead log: need to ensure that we persist all data to disk...
|
||||
|
||||
StatsStorageEvent sse = null;
|
||||
if (!listeners.isEmpty())
|
||||
sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostUpdate, update.getSessionID(),
|
||||
update.getTypeID(), update.getWorkerID(), update.getTimeStamp());
|
||||
for (StatsStorageListener l : listeners) {
|
||||
l.notify(sse);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStorageMetaData(StorageMetaData storageMetaData) {
|
||||
List<StatsStorageEvent> sses = checkStorageEvents(storageMetaData);
|
||||
SessionTypeId id = new SessionTypeId(storageMetaData.getSessionID(), storageMetaData.getTypeID());
|
||||
this.storageMetaData.put(id, storageMetaData);
|
||||
db.commit(); //For write ahead log: need to ensure that we persist all data to disk...
|
||||
|
||||
StatsStorageEvent sse = null;
|
||||
if (!listeners.isEmpty())
|
||||
sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostMetaData,
|
||||
storageMetaData.getSessionID(), storageMetaData.getTypeID(), storageMetaData.getWorkerID(),
|
||||
storageMetaData.getTimeStamp());
|
||||
for (StatsStorageListener l : listeners) {
|
||||
l.notify(sse);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
public static class Builder {
|
||||
|
||||
private File file;
|
||||
private boolean useWriteAheadLog = true;
|
||||
|
||||
public Builder() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public Builder(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public Builder file(File file) {
|
||||
this.file = file;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder useWriteAheadLog(boolean useWriteAheadLog) {
|
||||
this.useWriteAheadLog = useWriteAheadLog;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MapDBStatsStorage build() {
|
||||
return new MapDBStatsStorage(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private int getIntForClass(Class<?> c) {
|
||||
String str = c.getName();
|
||||
if (classToInteger.containsKey(str)) {
|
||||
return classToInteger.get(str);
|
||||
}
|
||||
int idx = classCounter.getAndIncrement();
|
||||
classToInteger.put(str, idx);
|
||||
integerToClass.put(idx, str);
|
||||
db.commit();
|
||||
return idx;
|
||||
}
|
||||
|
||||
private String getClassForInt(int integer) {
|
||||
String c = integerToClass.get(integer);
|
||||
if (c == null)
|
||||
throw new RuntimeException("Unknown class index: " + integer); //Should never happen
|
||||
return c;
|
||||
}
|
||||
|
||||
//Simple serializer, based on MapDB's SerializerJava
|
||||
private static class SessionTypeWorkerIdSerializer implements Serializer<SessionTypeWorkerId> {
|
||||
@Override
|
||||
public void serialize(@NonNull DataOutput2 out, @NonNull SessionTypeWorkerId value) throws IOException {
|
||||
ObjectOutputStream out2 = new ObjectOutputStream(out);
|
||||
out2.writeObject(value);
|
||||
out2.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionTypeWorkerId deserialize(@NonNull DataInput2 in, int available) throws IOException {
|
||||
try {
|
||||
ObjectInputStream in2 = new ObjectInputStream(new DataInput2.DataInputToStream(in));
|
||||
return (SessionTypeWorkerId) in2.readObject();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(SessionTypeWorkerId w1, SessionTypeWorkerId w2) {
|
||||
return w1.compareTo(w2);
|
||||
}
|
||||
}
|
||||
|
||||
//Simple serializer, based on MapDB's SerializerJava
|
||||
private static class SessionTypeIdSerializer implements Serializer<SessionTypeId> {
|
||||
@Override
|
||||
public void serialize(@NonNull DataOutput2 out, @NonNull SessionTypeId value) throws IOException {
|
||||
ObjectOutputStream out2 = new ObjectOutputStream(out);
|
||||
out2.writeObject(value);
|
||||
out2.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SessionTypeId deserialize(@NonNull DataInput2 in, int available) throws IOException {
|
||||
try {
|
||||
ObjectInputStream in2 = new ObjectInputStream(new DataInput2.DataInputToStream(in));
|
||||
return (SessionTypeId) in2.readObject();
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(SessionTypeId w1, SessionTypeId w2) {
|
||||
return w1.compareTo(w2);
|
||||
}
|
||||
}
|
||||
|
||||
private class PersistableSerializer<T extends Persistable> implements Serializer<T> {
|
||||
|
||||
@Override
|
||||
public void serialize(@NonNull DataOutput2 out, @NonNull Persistable value) throws IOException {
|
||||
//Persistable values can't be decoded in isolation, i.e., without knowing the type
|
||||
//So, we'll first write an integer representing the class name, so we can decode it later...
|
||||
int classIdx = getIntForClass(value.getClass());
|
||||
out.writeInt(classIdx);
|
||||
value.encode(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T deserialize(@NonNull DataInput2 input, int available) throws IOException {
|
||||
int classIdx = input.readInt();
|
||||
String className = getClassForInt(classIdx);
|
||||
|
||||
Persistable persistable = DL4JClassLoading.createNewInstance(className);
|
||||
|
||||
int remainingLength = available - 4; // -4 for int class index
|
||||
byte[] temp = new byte[remainingLength];
|
||||
input.readFully(temp);
|
||||
persistable.decode(temp);
|
||||
return (T) persistable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(Persistable p1, Persistable p2) {
|
||||
int c = p1.getSessionID().compareTo(p2.getSessionID());
|
||||
if (c != 0)
|
||||
return c;
|
||||
c = p1.getTypeID().compareTo(p2.getTypeID());
|
||||
if (c != 0)
|
||||
return c;
|
||||
return p1.getWorkerID().compareTo(p2.getWorkerID());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+673
@@ -0,0 +1,673 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.storage.sqlite;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
import lombok.NonNull;
|
||||
import org.deeplearning4j.core.storage.*;
|
||||
import org.deeplearning4j.ui.model.storage.FileStatsStorage;
|
||||
import org.nd4j.common.primitives.Pair;
|
||||
|
||||
import java.io.*;
|
||||
import java.sql.*;
|
||||
import java.util.*;
|
||||
|
||||
public class J7FileStatsStorage implements StatsStorage {
|
||||
|
||||
private static final String TABLE_NAME_METADATA = "StorageMetaData";
|
||||
private static final String TABLE_NAME_STATIC_INFO = "StaticInfo";
|
||||
private static final String TABLE_NAME_UPDATES = "Updates";
|
||||
|
||||
private static final String INSERT_META_SQL = "INSERT OR REPLACE INTO " + TABLE_NAME_METADATA
|
||||
+ " (SessionID, TypeID, ObjectClass, ObjectBytes) VALUES ( ?, ?, ?, ? );";
|
||||
private static final String INSERT_STATIC_SQL = "INSERT OR REPLACE INTO " + TABLE_NAME_STATIC_INFO
|
||||
+ " (SessionID, TypeID, WorkerID, ObjectClass, ObjectBytes) VALUES ( ?, ?, ?, ?, ? );";
|
||||
private static final String INSERT_UPDATE_SQL = "INSERT OR REPLACE INTO " + TABLE_NAME_UPDATES
|
||||
+ " (SessionID, TypeID, WorkerID, Timestamp, ObjectClass, ObjectBytes) VALUES ( ?, ?, ?, ?, ?, ? );";
|
||||
|
||||
private final File file;
|
||||
private final Connection connection;
|
||||
private List<StatsStorageListener> listeners = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* @param file Storage location for the stats
|
||||
*/
|
||||
public J7FileStatsStorage(@NonNull File file) {
|
||||
this.file = file;
|
||||
|
||||
try {
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + file.getAbsolutePath());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error ninializing J7FileStatsStorage instance", e);
|
||||
}
|
||||
|
||||
try {
|
||||
initializeTables();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeTables() throws SQLException {
|
||||
|
||||
//Need tables for:
|
||||
//(a) Metadata -> session ID and type ID; class; StorageMetaData as a binary BLOB
|
||||
//(b) Static info -> session ID, type ID, worker ID, persistable class, persistable bytes
|
||||
//(c) Update info -> session ID, type ID, worker ID, timestamp, update class, update bytes
|
||||
|
||||
//First: check if tables exist
|
||||
DatabaseMetaData meta = connection.getMetaData();
|
||||
ResultSet rs = meta.getTables(null, null, "%", null);
|
||||
boolean hasStorageMetaDataTable = false;
|
||||
boolean hasStaticInfoTable = false;
|
||||
boolean hasUpdatesTable = false;
|
||||
while (rs.next()) {
|
||||
//3rd value: table name - http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getTables%28java.lang.String,%20java.lang.String,%20java.lang.String,%20java.lang.String[]%29
|
||||
String name = rs.getString(3);
|
||||
if (TABLE_NAME_METADATA.equals(name))
|
||||
hasStorageMetaDataTable = true;
|
||||
else if (TABLE_NAME_STATIC_INFO.equals(name))
|
||||
hasStaticInfoTable = true;
|
||||
else if (TABLE_NAME_UPDATES.equals(name))
|
||||
hasUpdatesTable = true;
|
||||
}
|
||||
|
||||
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
if (!hasStorageMetaDataTable) {
|
||||
statement.executeUpdate("CREATE TABLE " + TABLE_NAME_METADATA + " (" + "SessionID TEXT NOT NULL, "
|
||||
+ "TypeID TEXT NOT NULL, " + "ObjectClass TEXT NOT NULL, " + "ObjectBytes BLOB NOT NULL, "
|
||||
+ "PRIMARY KEY ( SessionID, TypeID )" + ");");
|
||||
}
|
||||
|
||||
if (!hasStaticInfoTable) {
|
||||
statement.executeUpdate("CREATE TABLE " + TABLE_NAME_STATIC_INFO + " (" + "SessionID TEXT NOT NULL, "
|
||||
+ "TypeID TEXT NOT NULL, " + "WorkerID TEXT NOT NULL, " + "ObjectClass TEXT NOT NULL, "
|
||||
+ "ObjectBytes BLOB NOT NULL, " + "PRIMARY KEY ( SessionID, TypeID, WorkerID )" + ");");
|
||||
}
|
||||
|
||||
if (!hasUpdatesTable) {
|
||||
statement.executeUpdate("CREATE TABLE " + TABLE_NAME_UPDATES + " (" + "SessionID TEXT NOT NULL, "
|
||||
+ "TypeID TEXT NOT NULL, " + "WorkerID TEXT NOT NULL, " + "Timestamp INTEGER NOT NULL, "
|
||||
+ "ObjectClass TEXT NOT NULL, " + "ObjectBytes BLOB NOT NULL, "
|
||||
+ "PRIMARY KEY ( SessionID, TypeID, WorkerID, Timestamp )" + ");");
|
||||
}
|
||||
|
||||
statement.close();
|
||||
|
||||
}
|
||||
|
||||
private static Pair<String, byte[]> serializeForDB(Object object) {
|
||||
String classStr = object.getClass().getName();
|
||||
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(object);
|
||||
oos.close();
|
||||
byte[] bytes = baos.toByteArray();
|
||||
return new Pair<>(classStr, bytes);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Error serializing object for storage", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T deserialize(byte[] bytes) {
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes))) {
|
||||
return (T) ois.readObject();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> T queryAndGet(String sql, int columnIndex) {
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(sql);
|
||||
if (!rs.next())
|
||||
return null;
|
||||
byte[] bytes = rs.getBytes(columnIndex);
|
||||
return deserialize(bytes);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> selectDistinct(String columnName, boolean queryMeta, boolean queryStatic, boolean queryUpdates,
|
||||
String conditionColumn, String conditionValue) {
|
||||
Set<String> unique = new HashSet<>();
|
||||
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
if (queryMeta) {
|
||||
queryHelper(statement, querySqlHelper(columnName, TABLE_NAME_METADATA, conditionColumn, conditionValue),
|
||||
unique);
|
||||
}
|
||||
|
||||
if (queryStatic) {
|
||||
queryHelper(statement,
|
||||
querySqlHelper(columnName, TABLE_NAME_STATIC_INFO, conditionColumn, conditionValue),
|
||||
unique);
|
||||
}
|
||||
|
||||
if (queryUpdates) {
|
||||
queryHelper(statement, querySqlHelper(columnName, TABLE_NAME_UPDATES, conditionColumn, conditionValue),
|
||||
unique);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return new ArrayList<>(unique);
|
||||
}
|
||||
|
||||
private String querySqlHelper(String columnName, String table, String conditionColumn, String conditionValue) {
|
||||
String unique = "SELECT DISTINCT " + columnName + " FROM " + table;
|
||||
if (conditionColumn != null) {
|
||||
unique += " WHERE " + conditionColumn + " = '" + conditionValue + "'";
|
||||
}
|
||||
unique += ";";
|
||||
return unique;
|
||||
}
|
||||
|
||||
private void queryHelper(Statement statement, String q, Set<String> unique) throws SQLException {
|
||||
ResultSet rs = statement.executeQuery(q);
|
||||
while (rs.next()) {
|
||||
String str = rs.getString(1);
|
||||
unique.add(str);
|
||||
}
|
||||
}
|
||||
|
||||
protected List<StatsStorageEvent> checkStorageEvents(Persistable p) {
|
||||
if (listeners.isEmpty())
|
||||
return null;
|
||||
|
||||
StatsStorageEvent newSID = null;
|
||||
StatsStorageEvent newTID = null;
|
||||
StatsStorageEvent newWID = null;
|
||||
|
||||
String sid = p.getSessionID();
|
||||
String tid = p.getTypeID();
|
||||
String wid = p.getWorkerID();
|
||||
|
||||
//Is this a new session ID? type ID? worker ID?
|
||||
|
||||
//This is not the most efficient approach
|
||||
boolean isNewSID = false;
|
||||
boolean isNewTID = false;
|
||||
boolean isNewWID = false;
|
||||
if (!listSessionIDs().contains(sid)) {
|
||||
isNewSID = true;
|
||||
isNewTID = true;
|
||||
isNewWID = true;
|
||||
}
|
||||
|
||||
if (!isNewTID && !listTypeIDsForSession(sid).contains(tid)) {
|
||||
isNewTID = true;
|
||||
}
|
||||
|
||||
if (!isNewWID && !listWorkerIDsForSessionAndType(sid, tid).contains(wid)) {
|
||||
isNewWID = true;
|
||||
}
|
||||
|
||||
if (isNewSID) {
|
||||
newSID = new StatsStorageEvent(this, StatsStorageListener.EventType.NewSessionID, p.getSessionID(),
|
||||
p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
}
|
||||
if (isNewTID) {
|
||||
newTID = new StatsStorageEvent(this, StatsStorageListener.EventType.NewTypeID, p.getSessionID(),
|
||||
p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
}
|
||||
if (isNewWID) {
|
||||
newWID = new StatsStorageEvent(this, StatsStorageListener.EventType.NewWorkerID, p.getSessionID(),
|
||||
p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
}
|
||||
|
||||
if (!isNewSID && !isNewTID && !isNewWID)
|
||||
return null;
|
||||
List<StatsStorageEvent> sses = new ArrayList<>(3);
|
||||
if (newSID != null)
|
||||
sses.add(newSID);
|
||||
if (newTID != null)
|
||||
sses.add(newTID);
|
||||
if (newWID != null)
|
||||
sses.add(newWID);
|
||||
return sses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStorageMetaData(StorageMetaData storageMetaData) {
|
||||
putStorageMetaData(Collections.singletonList(storageMetaData));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStorageMetaData(Collection<? extends StorageMetaData> collection) {
|
||||
List<StatsStorageEvent> sses = null;
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement(INSERT_META_SQL);
|
||||
|
||||
for (StorageMetaData storageMetaData : collection) {
|
||||
List<StatsStorageEvent> ssesTemp = checkStorageEvents(storageMetaData);
|
||||
if (ssesTemp != null) {
|
||||
if (sses == null)
|
||||
sses = ssesTemp;
|
||||
else
|
||||
sses.addAll(ssesTemp);
|
||||
}
|
||||
|
||||
if (!listeners.isEmpty()) {
|
||||
StatsStorageEvent sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostMetaData,
|
||||
storageMetaData.getSessionID(), storageMetaData.getTypeID(),
|
||||
storageMetaData.getWorkerID(), storageMetaData.getTimeStamp());
|
||||
if (sses == null)
|
||||
sses = new ArrayList<>();
|
||||
sses.add(sse);
|
||||
}
|
||||
|
||||
|
||||
//Normally we'd batch these... sqlite has an autocommit feature that messes up batching with .addBatch() and .executeUpdate()
|
||||
Pair<String, byte[]> p = serializeForDB(storageMetaData);
|
||||
|
||||
ps.setString(1, storageMetaData.getSessionID());
|
||||
ps.setString(2, storageMetaData.getTypeID());
|
||||
ps.setString(3, p.getFirst());
|
||||
ps.setObject(4, p.getSecond());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStaticInfo(Persistable staticInfo) {
|
||||
putStaticInfo(Collections.singletonList(staticInfo));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putStaticInfo(Collection<? extends Persistable> collection) {
|
||||
List<StatsStorageEvent> sses = null;
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement(INSERT_STATIC_SQL);
|
||||
|
||||
for (Persistable p : collection) {
|
||||
List<StatsStorageEvent> ssesTemp = checkStorageEvents(p);
|
||||
if (ssesTemp != null) {
|
||||
if (sses == null)
|
||||
sses = ssesTemp;
|
||||
else
|
||||
sses.addAll(ssesTemp);
|
||||
}
|
||||
|
||||
if (!listeners.isEmpty()) {
|
||||
StatsStorageEvent sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostStaticInfo,
|
||||
p.getSessionID(), p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
if (sses == null)
|
||||
sses = new ArrayList<>();
|
||||
sses.add(sse);
|
||||
}
|
||||
|
||||
//Normally we'd batch these... sqlite has an autocommit feature that messes up batching with .addBatch() and .executeUpdate()
|
||||
Pair<String, byte[]> pair = serializeForDB(p);
|
||||
|
||||
ps.setString(1, p.getSessionID());
|
||||
ps.setString(2, p.getTypeID());
|
||||
ps.setString(3, p.getWorkerID());
|
||||
ps.setString(4, pair.getFirst());
|
||||
ps.setBytes(5, pair.getSecond());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putUpdate(Persistable update) {
|
||||
putUpdate(Collections.singletonList(update));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putUpdate(Collection<? extends Persistable> collection) {
|
||||
List<StatsStorageEvent> sses = null;
|
||||
|
||||
try {
|
||||
PreparedStatement ps = connection.prepareStatement(INSERT_UPDATE_SQL);
|
||||
|
||||
for (Persistable p : collection) {
|
||||
List<StatsStorageEvent> ssesTemp = checkStorageEvents(p);
|
||||
if (ssesTemp != null) {
|
||||
if (sses == null)
|
||||
sses = ssesTemp;
|
||||
else
|
||||
sses.addAll(ssesTemp);
|
||||
}
|
||||
|
||||
if (!listeners.isEmpty()) {
|
||||
StatsStorageEvent sse = new StatsStorageEvent(this, StatsStorageListener.EventType.PostUpdate,
|
||||
p.getSessionID(), p.getTypeID(), p.getWorkerID(), p.getTimeStamp());
|
||||
if (sses == null)
|
||||
sses = new ArrayList<>();
|
||||
sses.add(sse);
|
||||
}
|
||||
|
||||
//Normally we'd batch these... sqlite has an autocommit feature that messes up batching with .addBatch() and .executeUpdate()
|
||||
Pair<String, byte[]> pair = serializeForDB(p);
|
||||
|
||||
ps.setString(1, p.getSessionID());
|
||||
ps.setString(2, p.getTypeID());
|
||||
ps.setString(3, p.getWorkerID());
|
||||
ps.setLong(4, p.getTimeStamp());
|
||||
ps.setString(5, pair.getFirst());
|
||||
ps.setObject(6, pair.getSecond());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
notifyListeners(sses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
try {
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClosed() {
|
||||
try {
|
||||
return connection.isClosed();
|
||||
} catch (Exception e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listSessionIDs() {
|
||||
return selectDistinct("SessionID", true, true, false, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sessionExists(String sessionID) {
|
||||
String existsMetaSQL = "SELECT 1 FROM " + TABLE_NAME_METADATA + " WHERE SessionID = '" + sessionID + "';";
|
||||
String existsStaticSQL = "SELECT 1 FROM " + TABLE_NAME_STATIC_INFO + " WHERE SessionID = '" + sessionID + "';";
|
||||
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(existsMetaSQL);
|
||||
if (rs.next()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
rs = statement.executeQuery(existsStaticSQL);
|
||||
return rs.next();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Persistable getStaticInfo(String sessionID, String typeID, String workerID) {
|
||||
String selectStaticSQL = "SELECT ObjectBytes FROM " + TABLE_NAME_STATIC_INFO + " WHERE SessionID = '"
|
||||
+ sessionID + "' AND TypeID = '" + typeID + "' AND WorkerID = '" + workerID + "';";
|
||||
return queryAndGet(selectStaticSQL, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getAllStaticInfos(String sessionID, String typeID) {
|
||||
String selectStaticSQL = "SELECT * FROM " + TABLE_NAME_STATIC_INFO + " WHERE SessionID = '" + sessionID
|
||||
+ "' AND TypeID = '" + typeID + "';";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(selectStaticSQL);
|
||||
List<Persistable> out = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
byte[] bytes = rs.getBytes(5);
|
||||
out.add((Persistable) deserialize(bytes));
|
||||
}
|
||||
return out;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listTypeIDsForSession(String sessionID) {
|
||||
return selectDistinct("TypeID", true, true, true, "SessionID", sessionID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listWorkerIDsForSession(String sessionID) {
|
||||
return selectDistinct("WorkerID", false, true, true, "SessionID", sessionID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listWorkerIDsForSessionAndType(String sessionID, String typeID) {
|
||||
String uniqueStatic = "SELECT DISTINCT WorkerID FROM " + TABLE_NAME_STATIC_INFO + " WHERE SessionID = '"
|
||||
+ sessionID + "' AND TypeID = '" + typeID + "';";
|
||||
String uniqueUpdates = "SELECT DISTINCT WorkerID FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '"
|
||||
+ sessionID + "' AND TypeID = '" + typeID + "';";
|
||||
|
||||
Set<String> unique = new HashSet<>();
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(uniqueStatic);
|
||||
while (rs.next()) {
|
||||
String str = rs.getString(1);
|
||||
unique.add(str);
|
||||
}
|
||||
|
||||
rs = statement.executeQuery(uniqueUpdates);
|
||||
while (rs.next()) {
|
||||
String str = rs.getString(1);
|
||||
unique.add(str);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return new ArrayList<>(unique);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumUpdateRecordsFor(String sessionID) {
|
||||
String sql = "SELECT COUNT(*) FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID + "';";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
return statement.executeQuery(sql).getInt(1);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNumUpdateRecordsFor(String sessionID, String typeID, String workerID) {
|
||||
String sql = "SELECT COUNT(*) FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID
|
||||
+ "' AND TypeID = '" + typeID + "' AND WorkerID = '" + workerID + "';";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
return statement.executeQuery(sql).getInt(1);
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Persistable getLatestUpdate(String sessionID, String typeID, String workerID) {
|
||||
String sql = "SELECT ObjectBytes FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID
|
||||
+ "' AND TypeID = '" + typeID + "' AND WorkerID = '" + workerID
|
||||
+ "' ORDER BY Timestamp DESC LIMIT 1;";
|
||||
return queryAndGet(sql, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Persistable getUpdate(String sessionID, String typeId, String workerID, long timestamp) {
|
||||
String sql = "SELECT ObjectBytes FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID
|
||||
+ "' AND TypeID = '" + typeId + "' AND WorkerID = '" + workerID + "' AND Timestamp = '"
|
||||
+ timestamp + "';";
|
||||
return queryAndGet(sql, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getLatestUpdateAllWorkers(String sessionID, String typeID) {
|
||||
String sql = "SELECT workerId, MAX(Timestamp) FROM " + TABLE_NAME_UPDATES + " WHERE SessionID ='"
|
||||
+ sessionID + "' AND " + "TypeID = '" + typeID + "' GROUP BY workerId";
|
||||
|
||||
Map<String,Long> m = new HashMap<>();
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(sql);
|
||||
while (rs.next()) {
|
||||
String wid = rs.getString(1);
|
||||
long ts = rs.getLong(2);
|
||||
m.put(wid, ts);
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
List<Persistable> out = new ArrayList<>();
|
||||
for(String s : m.keySet()){
|
||||
out.add(getUpdate(sessionID, typeID, s, m.get(s)));
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getAllUpdatesAfter(String sessionID, String typeID, String workerID, long timestamp) {
|
||||
String sql = "SELECT * FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID + "' AND TypeID = '"
|
||||
+ typeID + "' AND workerId = '" + workerID + "' AND Timestamp > " + timestamp + ";";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(sql);
|
||||
List<Persistable> out = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
byte[] bytes = rs.getBytes(6);
|
||||
out.add((Persistable) deserialize(bytes));
|
||||
}
|
||||
return out;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getAllUpdatesAfter(String sessionID, String typeID, long timestamp) {
|
||||
String sql = "SELECT ObjectBytes FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID + "' "
|
||||
+ "AND TypeID = '" + typeID + "' AND Timestamp > " + timestamp + ";";
|
||||
return queryUpdates(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long[] getAllUpdateTimes(String sessionID, String typeID, String workerID) {
|
||||
String sql = "SELECT Timestamp FROM " + TABLE_NAME_UPDATES + " WHERE SessionID = '" + sessionID + "' "
|
||||
+ "AND TypeID = '" + typeID + "' AND workerID = '" + workerID + "';";
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(sql);
|
||||
LongArrayList list = new LongArrayList();
|
||||
while (rs.next()) {
|
||||
list.add(rs.getLong(1));
|
||||
}
|
||||
return list.toLongArray();
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Persistable> getUpdates(String sessionID, String typeID, String workerID, long[] timestamps) {
|
||||
if(timestamps == null || timestamps.length == 0){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("SELECT ObjectBytes FROM ").append(TABLE_NAME_UPDATES).append(" WHERE SessionID = '").append(sessionID)
|
||||
.append("' AND TypeID = '").append(typeID).append("' AND workerID='").append(workerID)
|
||||
.append("' AND Timestamp IN (");
|
||||
|
||||
for( int i=0; i<timestamps.length; i++ ){
|
||||
if(i > 0){
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(timestamps[i]);
|
||||
}
|
||||
sb.append(");");
|
||||
|
||||
String sql = sb.toString();
|
||||
return queryUpdates(sql);
|
||||
}
|
||||
|
||||
private List<Persistable> queryUpdates(String sql){
|
||||
try (Statement statement = connection.createStatement()) {
|
||||
ResultSet rs = statement.executeQuery(sql);
|
||||
List<Persistable> out = new ArrayList<>();
|
||||
while (rs.next()) {
|
||||
byte[] bytes = rs.getBytes(1);
|
||||
out.add((Persistable) deserialize(bytes));
|
||||
}
|
||||
return out;
|
||||
} catch (SQLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageMetaData getStorageMetaData(String sessionID, String typeID) {
|
||||
String sql = "SELECT ObjectBytes FROM " + TABLE_NAME_METADATA + " WHERE SessionID = '" + sessionID
|
||||
+ "' AND TypeID = '" + typeID + "' LIMIT 1;";
|
||||
return queryAndGet(sql, 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerStatsStorageListener(StatsStorageListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deregisterStatsStorageListener(StatsStorageListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAllListeners() {
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StatsStorageListener> getListeners() {
|
||||
return new ArrayList<>(listeners);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "J7FileStatsStorage(file=" + file + ")";
|
||||
}
|
||||
|
||||
protected void notifyListeners(List<StatsStorageEvent> sses) {
|
||||
if (sses == null || sses.isEmpty() || listeners.isEmpty())
|
||||
return;
|
||||
for (StatsStorageListener l : listeners) {
|
||||
for (StatsStorageEvent e : sses) {
|
||||
l.notify(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.weights;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.deeplearning4j.core.storage.Persistable;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class ConvolutionListenerPersistable implements Persistable {
|
||||
|
||||
private static final String TYPE_ID = "ConvolutionalListener";
|
||||
|
||||
private String sessionID;
|
||||
private String workerID;
|
||||
private long timestamp;
|
||||
private transient BufferedImage img;
|
||||
|
||||
public ConvolutionListenerPersistable() {}
|
||||
|
||||
@Override
|
||||
public String getSessionID() {
|
||||
return sessionID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTypeID() {
|
||||
return TYPE_ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWorkerID() {
|
||||
return workerID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimeStamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int encodingLengthBytes() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] encode() {
|
||||
//Not the most efficient: but it's easy to implement...
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
|
||||
oos.writeObject(this);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e); //Shouldn't normally happen
|
||||
}
|
||||
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(ByteBuffer buffer) {
|
||||
buffer.put(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(OutputStream outputStream) throws IOException {
|
||||
outputStream.write(encode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(byte[] decode) {
|
||||
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(decode))) {
|
||||
ConvolutionListenerPersistable p = (ConvolutionListenerPersistable) ois.readObject();
|
||||
this.sessionID = p.sessionID;
|
||||
this.workerID = p.workerID;
|
||||
this.timestamp = p.getTimeStamp();
|
||||
this.img = p.img;
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
throw new RuntimeException(e); //Shouldn't normally happen
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(ByteBuffer buffer) {
|
||||
byte[] arr = new byte[buffer.remaining()];
|
||||
buffer.get(arr);
|
||||
decode(arr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void decode(InputStream inputStream) throws IOException {
|
||||
byte[] b = IOUtils.toByteArray(inputStream);
|
||||
decode(b);
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream oos) throws IOException {
|
||||
oos.defaultWriteObject();
|
||||
ImageIO.write(img, "png", oos);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
img = ImageIO.read(ois);
|
||||
}
|
||||
}
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.weights;
|
||||
|
||||
import lombok.Data;
|
||||
import org.nd4j.linalg.api.ndarray.INDArray;
|
||||
import org.nd4j.linalg.factory.Nd4j;
|
||||
import org.nd4j.shade.jackson.annotation.JsonIgnore;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Data
|
||||
public class HistogramBin implements Serializable {
|
||||
private transient INDArray sourceArray;
|
||||
private int numberOfBins;
|
||||
private int rounds;
|
||||
private transient INDArray bins;
|
||||
private double max;
|
||||
private double min;
|
||||
private Map<BigDecimal, AtomicInteger> data = new LinkedHashMap<>();
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(HistogramBin.class);
|
||||
|
||||
/**
|
||||
* No-Args constructor should be used only for serialization/deserialization purposes.
|
||||
* In all other cases please use Histogram.Builder()
|
||||
*/
|
||||
public HistogramBin() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds histogram bin for specified array
|
||||
* @param array
|
||||
*/
|
||||
public HistogramBin(INDArray array) {
|
||||
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
private synchronized void calcHistogram() {
|
||||
max = sourceArray.maxNumber().doubleValue();
|
||||
min = sourceArray.minNumber().doubleValue();
|
||||
|
||||
// TODO: there's probably better way to get around of possible NaNs in max/min
|
||||
if (Double.isInfinite(max))
|
||||
max = Float.MAX_VALUE;
|
||||
|
||||
if (Double.isNaN(max))
|
||||
max = Float.MIN_VALUE;
|
||||
|
||||
if (Double.isInfinite(min))
|
||||
min = Float.MAX_VALUE;
|
||||
|
||||
if (Double.isNaN(min))
|
||||
min = Float.MIN_VALUE;
|
||||
|
||||
bins = Nd4j.create(numberOfBins);
|
||||
final double binSize = (max - min) / (numberOfBins - 1);
|
||||
|
||||
|
||||
data = new LinkedHashMap<>();
|
||||
BigDecimal[] keys = new BigDecimal[numberOfBins];
|
||||
|
||||
for (int x = 0; x < numberOfBins; x++) {
|
||||
BigDecimal pos = new BigDecimal((min + (x * binSize))).setScale(rounds, BigDecimal.ROUND_CEILING);
|
||||
data.put(pos, new AtomicInteger(0));
|
||||
keys[x] = pos;
|
||||
}
|
||||
|
||||
for (int x = 0; x < sourceArray.length(); x++) {
|
||||
double d = sourceArray.getDouble(x);
|
||||
int bin = (int) ((d - min) / binSize);
|
||||
|
||||
if (bin < 0) {
|
||||
bins.putScalar(0, bins.getDouble(0) + 1);
|
||||
data.get(keys[0]).incrementAndGet();
|
||||
} else if (bin >= numberOfBins) {
|
||||
bins.putScalar(numberOfBins - 1, bins.getDouble(numberOfBins - 1) + 1);
|
||||
data.get(keys[numberOfBins - 1]).incrementAndGet();
|
||||
} else {
|
||||
bins.putScalar(bin, bins.getDouble(bin) + 1);
|
||||
data.get(keys[bin]).incrementAndGet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private INDArray source;
|
||||
private int binCount;
|
||||
private int rounds = 2;
|
||||
|
||||
/**
|
||||
* Build Histogram Builder instance for specified array
|
||||
* @param array
|
||||
*/
|
||||
public Builder(INDArray array) {
|
||||
this.source = array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets number of numbers behind decimal part
|
||||
*
|
||||
* @param rounds
|
||||
* @return
|
||||
*/
|
||||
public Builder setRounding(int rounds) {
|
||||
this.rounds = rounds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies number of bins for output histogram
|
||||
*
|
||||
* @param bins
|
||||
* @return
|
||||
*/
|
||||
public Builder setBinCount(int bins) {
|
||||
this.binCount = bins;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns ready-to-use Histogram instance
|
||||
* @return
|
||||
*/
|
||||
public HistogramBin build() {
|
||||
HistogramBin histogram = new HistogramBin();
|
||||
histogram.sourceArray = this.source;
|
||||
histogram.numberOfBins = this.binCount;
|
||||
histogram.rounds = this.rounds;
|
||||
|
||||
histogram.calcHistogram();
|
||||
|
||||
return histogram;
|
||||
}
|
||||
}
|
||||
}
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* ******************************************************************************
|
||||
* *
|
||||
* *
|
||||
* * 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.model.weights.beans;
|
||||
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Slightly modified version of ModelAndGradient, with binned params/gradients, suitable for fast network transfers for HistogramIterationListener
|
||||
*
|
||||
* @author Adam Gibson
|
||||
*/
|
||||
|
||||
public class CompactModelAndGradient implements Serializable {
|
||||
private long lastUpdateTime = -1L;
|
||||
private Map<String, Map> parameters;
|
||||
private Map<String, Map> gradients;
|
||||
private double score;
|
||||
private List<Double> scores = new ArrayList<>();
|
||||
private List<Map<String, List<Double>>> updateMagnitudes = new ArrayList<>();
|
||||
private List<Map<String, List<Double>>> paramMagnitudes = new ArrayList<>();
|
||||
private List<String> layerNames = new ArrayList<>();
|
||||
private String path;
|
||||
|
||||
|
||||
public CompactModelAndGradient() {
|
||||
parameters = new HashMap<>();
|
||||
gradients = new HashMap<>();
|
||||
}
|
||||
|
||||
|
||||
public void setLastUpdateTime(long lastUpdateTime) {
|
||||
this.lastUpdateTime = lastUpdateTime;
|
||||
}
|
||||
|
||||
public long getLastUpdateTime() {
|
||||
return lastUpdateTime;
|
||||
}
|
||||
|
||||
public double getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(double score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Map> getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public void setParameters(Map<String, Map> parameters) {
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Map> getGradients() {
|
||||
return gradients;
|
||||
}
|
||||
|
||||
public void setGradients(Map<String, Map> gradients) {
|
||||
this.gradients = gradients;
|
||||
}
|
||||
|
||||
public void setScores(List<Double> scores) {
|
||||
this.scores = scores;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
public List<Double> getScores() {
|
||||
return scores;
|
||||
}
|
||||
|
||||
public void setUpdateMagnitudes(List<Map<String, List<Double>>> updateMagnitudes) {
|
||||
this.updateMagnitudes = updateMagnitudes;
|
||||
}
|
||||
|
||||
public List<Map<String, List<Double>>> getUpdateMagnitudes() {
|
||||
return updateMagnitudes;
|
||||
}
|
||||
|
||||
public void setParamMagnitudes(List<Map<String, List<Double>>> paramMagnitudes) {
|
||||
this.paramMagnitudes = paramMagnitudes;
|
||||
}
|
||||
|
||||
public List<Map<String, List<Double>>> getParamMagnitudes() {
|
||||
return paramMagnitudes;
|
||||
}
|
||||
|
||||
public void setLayerNames(List<String> layerNames) {
|
||||
this.layerNames = layerNames;
|
||||
}
|
||||
|
||||
public List<String> getLayerNames() {
|
||||
return layerNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (o == null || getClass() != o.getClass())
|
||||
return false;
|
||||
|
||||
CompactModelAndGradient that = (CompactModelAndGradient) o;
|
||||
|
||||
if (Double.compare(that.score, score) != 0)
|
||||
return false;
|
||||
if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null)
|
||||
return false;
|
||||
return !(gradients != null ? !gradients.equals(that.gradients) : that.gradients != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result;
|
||||
long temp;
|
||||
result = parameters != null ? parameters.hashCode() : 0;
|
||||
result = 31 * result + (gradients != null ? gradients.hashCode() : 0);
|
||||
temp = Double.doubleToLongBits(score);
|
||||
result = 31 * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<!--
|
||||
~ /* ******************************************************************************
|
||||
~ *
|
||||
~ *
|
||||
~ * 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
|
||||
~ ******************************************************************************/
|
||||
-->
|
||||
|
||||
<sbe:messageSchema xmlns:sbe="http://fixprotocol.io/2016/sbe"
|
||||
package="org.deeplearning4j.ui.stats.sbe"
|
||||
id="1"
|
||||
version="0"
|
||||
semanticVersion="0.6.1"
|
||||
description="Deeplearning4j Stats Listener: Static Information and Updates"
|
||||
byteOrder="littleEndian">
|
||||
<!--
|
||||
Schemas for encoding information for the stats listener using SBE - Simple Binary Encoding.
|
||||
Two schemas are defined here:
|
||||
(a) StaticInfo - once-off information, passed once upon initialization
|
||||
(b) Update - posted periodically
|
||||
(c) Meta data - type information, for use with the Java SbeStorageMetaData class
|
||||
|
||||
SBE uses code generation to create high-performance binary encoding/decoding classes. These are generated directly
|
||||
from this XML data schema (for Java or C++), using the SBE Java tool.
|
||||
The generated code files are then used in the project, as normal Java files (requires only Agrona as a dependency)
|
||||
|
||||
To build the encoder/decoder files:
|
||||
1. Download sbe-all-1.5.1.jar (later versions should be fine) - http://repo1.maven.org/maven2/uk/co/real-logic/sbe-all/1.5.1/
|
||||
2. Change directory to the directory containing the above jar
|
||||
3. Run the following:
|
||||
java -Dsbe.output.dir=<path>/deeplearning4j-ui-parent/deeplearning4j-ui-model/src/main/java/ -jar sbe-all-1.5.1.jar <path>/deeplearning4j-ui-parent/deeplearning4j-ui-model/src/main/resources/StatsListenerSchemas.xml
|
||||
Where <path> is the path to the DL4J project root directory
|
||||
The "package" property above (org.deeplearning4j...) defines the rest of the output path relative to the output directory
|
||||
|
||||
Some key points to note with SBE:
|
||||
- There are specific rules regarding the formats and ordering for the Schema. You need to understand these before
|
||||
messing with this file, or generating new SBE formats
|
||||
- Encoding and decoding MUST follow the order defined in the schema exactly. Not doing this can result in corrupted
|
||||
data being read. Consequently, to decode any part of the message, you must decode everything that came before it.
|
||||
|
||||
+++ References +++
|
||||
Overview, performance: http://mechanical-sympathy.blogspot.com/2014/05/simple-binary-encoding.html
|
||||
Wiki: https://github.com/real-logic/simple-binary-encoding/wiki
|
||||
SBE tool: https://github.com/real-logic/simple-binary-encoding/wiki/Sbe-Tool-Guide
|
||||
SBE tool via Maven: https://github.com/real-logic/simple-binary-encoding/wiki/Sbe-Tool-Maven
|
||||
Schema: https://github.com/real-logic/simple-binary-encoding/wiki/FIX-SBE-XML-Primer
|
||||
Using the generated code: https://github.com/real-logic/simple-binary-encoding/wiki/Java-Users-Guide
|
||||
Example: https://github.com/real-logic/simple-binary-encoding/blob/master/sbe-samples/src/main/java/uk/co/real_logic/sbe/examples/ExampleUsingGeneratedStub.java
|
||||
|
||||
Author: Alex Black
|
||||
-->
|
||||
<types>
|
||||
<composite name="messageHeader" description="Message identifiers and length of message root">
|
||||
<type name="blockLength" primitiveType="uint16"/>
|
||||
<type name="templateId" primitiveType="uint16"/>
|
||||
<type name="schemaId" primitiveType="uint16"/>
|
||||
<type name="version" primitiveType="uint16"/>
|
||||
</composite>
|
||||
<composite name="VarDataUTF8">
|
||||
<type name="length" primitiveType="uint32" maxValue="1073741824"/>
|
||||
<type name="varData" primitiveType="uint8" length="0" characterEncoding="UTF-8"/>
|
||||
</composite>
|
||||
<composite name="groupSizeEncoding" description="Repeating group dimensions">
|
||||
<type name="blockLength" primitiveType="uint16"/>
|
||||
<type name="numInGroup" primitiveType="uint16"/>
|
||||
</composite>
|
||||
</types>
|
||||
<types>
|
||||
<!-- Initialization: Set for encoding presence/absence of software, hardware and model information -->
|
||||
<set name="InitFieldsPresent" encodingType="uint8" semanticType="FieldsPresent">
|
||||
<choice name="softwareInfo">0</choice>
|
||||
<choice name="hardwareInfo">1</choice>
|
||||
<choice name="modelInfo">2</choice>
|
||||
</set>
|
||||
|
||||
<!-- Updates: Set for encoding present/absence of various entries -->
|
||||
<set name="UpdateFieldsPresent" encodingType="uint32" semanticType="UpdateFieldsPresent">
|
||||
<choice name="score">0</choice>
|
||||
<choice name="memoryUse">1</choice>
|
||||
<choice name="performance">2</choice>
|
||||
<choice name="garbageCollection">3</choice>
|
||||
<choice name="histogramParameters">4</choice>
|
||||
<choice name="histogramGradients">5</choice>
|
||||
<choice name="histogramUpdates">6</choice>
|
||||
<choice name="histogramActivations">7</choice>
|
||||
<choice name="meanParameters">8</choice>
|
||||
<choice name="meanGradients">9</choice>
|
||||
<choice name="meanUpdates">10</choice>
|
||||
<choice name="meanActivations">11</choice>
|
||||
<choice name="stdevParameters">12</choice>
|
||||
<choice name="stdevGradients">13</choice>
|
||||
<choice name="stdevUpdates">14</choice>
|
||||
<choice name="stdevActivations">15</choice>
|
||||
<choice name="meanMagnitudeParameters">16</choice>
|
||||
<choice name="meanMagnitudeGradients">17</choice>
|
||||
<choice name="meanMagnitudeUpdates">18</choice>
|
||||
<choice name="meanMagnitudeActivations">19</choice>
|
||||
<choice name="learningRatesPresent">20</choice>
|
||||
<choice name="dataSetMetaDataPresent">21</choice>
|
||||
</set>
|
||||
<enum name="MemoryType" encodingType="uint8">
|
||||
<validValue name="JvmCurrent">0</validValue>
|
||||
<validValue name="JvmMax">1</validValue>
|
||||
<validValue name="OffHeapCurrent">2</validValue>
|
||||
<validValue name="OffHeapMax">3</validValue>
|
||||
<validValue name="DeviceCurrent">4</validValue>
|
||||
<validValue name="DeviceMax">5</validValue>
|
||||
</enum>
|
||||
|
||||
<enum name="StatsType" encodingType="uint8">
|
||||
<validValue name="Parameters">0</validValue>
|
||||
<validValue name="Gradients">1</validValue>
|
||||
<validValue name="Updates">2</validValue>
|
||||
<validValue name="Activations">3</validValue>
|
||||
</enum>
|
||||
<enum name="SummaryType" encodingType="uint8">
|
||||
<validValue name="Mean">0</validValue>
|
||||
<validValue name="Stdev">1</validValue>
|
||||
<validValue name="MeanMagnitude">2</validValue>
|
||||
</enum>
|
||||
</types>
|
||||
|
||||
<!-- Message 1: Static information -->
|
||||
<sbe:message name="StaticInfo" id="1" description="Static information for hardware, software, and model">
|
||||
<!-- Fixed length fields. These always appear first in SBE -->
|
||||
<field name="time" id="1" type="int64"/>
|
||||
<field name="fieldsPresent" id="2" type="InitFieldsPresent"/>
|
||||
<field name="hwJvmProcessors" id="3" type="uint16"/>
|
||||
<field name="hwNumDevices" id="4" type="uint8"/>
|
||||
<field name="hwJvmMaxMemory" id="5" type="int64"/>
|
||||
<field name="hwOffheapMaxMemory" id="6" type="int64"/>
|
||||
<field name="modelNumLayers" id="7" type="int32"/>
|
||||
<field name="modelNumParams" id="8" type="int64"/>
|
||||
<!-- Groups - always second in SBE. Two groups here: GPU/Device info, and model param names -->
|
||||
<group name="hwDeviceInfoGroup" id="9" dimensionType="groupSizeEncoding">
|
||||
<field name="deviceMemoryMax" id="10" type="int64"/>
|
||||
<data name="deviceDescription" id="50" type="VarDataUTF8"/> <!-- Variable length: last field in a group; must be encoded at end -->
|
||||
</group>
|
||||
<group name="swEnvironmentInfo" id="12" dimensionType="groupSizeEncoding">
|
||||
<data name="envKey" id="51" type="VarDataUTF8"/>
|
||||
<data name="envValue" id="52" type="VarDataUTF8"/>
|
||||
</group>
|
||||
<group name="modelParamNames" id="11" dimensionType="groupSizeEncoding">
|
||||
<data name="modelParamNames" id="53" type="VarDataUTF8"/>
|
||||
</group>
|
||||
<!-- Variable Length Data. By SBE design, all variable length fields must be encoded after fields and groups.
|
||||
Also can't have variable length in composite types, hence separate data fields instead of grouped by sw/hw/model -->
|
||||
<data name="sessionID" id="100" type="VarDataUTF8"/>
|
||||
<data name="typeID" id="101" type="VarDataUTF8"/>
|
||||
<data name="workerID" id="102" type="VarDataUTF8"/>
|
||||
<data name="swArch" id="201" type="VarDataUTF8"/>
|
||||
<data name="swOsName" id="202" type="VarDataUTF8"/>
|
||||
<data name="swJvmName" id="203" type="VarDataUTF8"/>
|
||||
<data name="swJvmVersion" id="204" type="VarDataUTF8"/>
|
||||
<data name="swJvmSpecVersion" id="205" type="VarDataUTF8"/>
|
||||
<data name="swNd4jBackendClass" id="206" type="VarDataUTF8"/>
|
||||
<data name="swNd4jDataTypeName" id="207" type="VarDataUTF8"/>
|
||||
<data name="swHostName" id="208" type="VarDataUTF8"/>
|
||||
<data name="swJvmUID" id="209" type="VarDataUTF8"/>
|
||||
<data name="hwHardwareUID" id="300" type="VarDataUTF8"/>
|
||||
<data name="modelConfigClassName" id="400" type="VarDataUTF8"/>
|
||||
<data name="modelConfigJson" id="401" type="VarDataUTF8"/>
|
||||
</sbe:message>
|
||||
|
||||
<!-- Message 2: Updates -->
|
||||
<sbe:message name="Update" id="2" description="Model status update">
|
||||
<!-- Fixed length fields. These always appear first in SBE -->
|
||||
<field name="time" id="1" type="int64"/>
|
||||
<field name="deltaTime" id="2" type="int32"/> <!-- Time since last report, MS -->
|
||||
<field name="iterationCount" id="3" type="int32"/>
|
||||
<field name="fieldsPresent" id="4" type="UpdateFieldsPresent"/>
|
||||
<field name="statsCollectionDuration" id="5" type="int32"/>
|
||||
<field name="score" id="6" type="double"/>
|
||||
|
||||
<!-- Groups - always second in SBE -->
|
||||
<group name="memoryUse" id="100" dimensionType="groupSizeEncoding">
|
||||
<field name="memoryType" id="101" type="MemoryType"/>
|
||||
<field name="memoryBytes" id="102" type="int64"/>
|
||||
</group>
|
||||
<group name="performance" id="200" dimensionType="groupSizeEncoding">
|
||||
<field name="totalRuntimeMs" id="201" type="int64"/>
|
||||
<field name="totalExamples" id="202" type="int64"/>
|
||||
<field name="totalMinibatches" id="203" type="int64"/>
|
||||
<field name="examplesPerSecond" id="204" type="float"/>
|
||||
<field name="minibatchesPerSecond" id="205" type="float"/>
|
||||
</group>
|
||||
<group name="gcStats" id="300" dimensionType="groupSizeEncoding">
|
||||
<field name="deltaGCCount" id="301" type="int32"/>
|
||||
<field name="deltaGCTimeMs" id="302" type="int32"/>
|
||||
<data name="gcName" id="1000" type="VarDataUTF8"/>
|
||||
</group>
|
||||
<group name="paramNames" id="350" dimensionType="groupSizeEncoding">
|
||||
<data name="paramName" id="1100" type="VarDataUTF8"/>
|
||||
</group>
|
||||
<group name="layerNames" id="351" dimensionType="groupSizeEncoding">
|
||||
<data name="layerName" id="1101" type="VarDataUTF8"/>
|
||||
</group>
|
||||
<!-- Per parameter and per stats: summary and histograms. mean/stdev/meanMag for each of params/gradients/updates/activations;
|
||||
histograms for params/gradients/updates/activations. Assumption here is that per param stats are encoded first, followed by
|
||||
per layer stats-->
|
||||
<group name="perParameterStats" id="400" dimensionType="groupSizeEncoding">
|
||||
<field name="learningRate" id="401" type="float"/>
|
||||
<group name="summaryStat" id="402" dimensionType="groupSizeEncoding">
|
||||
<field name="statType" id="403" type="StatsType"/> <!-- Parameters, Gradients, Updates, Activations -->
|
||||
<field name="summaryType" id="404" type="SummaryType"/> <!-- Mean, stdev, mean magnitude -->
|
||||
<field name="value" id="405" type="double"/>
|
||||
</group>
|
||||
<group name="histograms" id="406" dimensionType="groupSizeEncoding">
|
||||
<field name="statType" id="407" type="StatsType"/> <!-- Parameters, Gradients, Updates, Activations -->
|
||||
<field name="minValue" id="408" type="double"/>
|
||||
<field name="maxValue" id="409" type="double"/>
|
||||
<field name="nBins" id="410" type="int32"/>
|
||||
<group name="histogramCounts" id="411" dimensionType="groupSizeEncoding">
|
||||
<field name="binCount" id="412" type="uint32"/>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
<group name="dataSetMetaDataBytes" id="500" dimensionType="groupSizeEncoding">
|
||||
<group name="metaDataBytes" id="501" dimensionType="groupSizeEncoding">
|
||||
<field name="bytes" id="502" type="int8"/>
|
||||
</group>
|
||||
</group>
|
||||
<!-- Variable Length Data. By SBE design, all variable length fields must be encoded after fields and groups-->
|
||||
<data name="sessionID" id="1200" type="VarDataUTF8"/>
|
||||
<data name="typeID" id="1201" type="VarDataUTF8"/>
|
||||
<data name="workerID" id="1202" type="VarDataUTF8"/>
|
||||
<data name="dataSetMetaDataClassName" id="1300" type="VarDataUTF8"/>
|
||||
</sbe:message>
|
||||
|
||||
<!-- Message 3: Simple MetaData for class for SbeStorageMetaData -->
|
||||
<sbe:message name="StorageMetaData" id="3" description="StorageMetaData">
|
||||
<!-- Fixed length fields: only timestamp -->
|
||||
<field name="timeStamp" id="1" type="int64"/>
|
||||
<!-- Groups: only 1 group - ExtraMetaDataBytes -->
|
||||
<group name="extraMetaDataBytes" id="2" description="Extra metadata bytes">
|
||||
<field name="bytes" id="3" type="int8"/>
|
||||
</group>
|
||||
<!-- Variable length data -->
|
||||
<data name="sessionID" id="4" type="VarDataUTF8"/>
|
||||
<data name="typeID" id="5" type="VarDataUTF8"/>
|
||||
<data name="workerID" id="6" type="VarDataUTF8"/>
|
||||
<data name="initTypeClass" id="7" type="VarDataUTF8"/>
|
||||
<data name="updateTypeClass" id="8" type="VarDataUTF8"/>
|
||||
</sbe:message>
|
||||
</sbe:messageSchema>
|
||||
+36
@@ -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
|
||||
# ******************************************************************************/
|
||||
#
|
||||
|
||||
log4j.rootLogger=ERROR, Console
|
||||
log4j.appender.Console=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE} %-5p ~ %m%n
|
||||
|
||||
log4j.appender.org.springframework=DEBUG
|
||||
log4j.appender.org.deeplearning4j=DEBUG
|
||||
log4j.appender.org.nd4j=DEBUG
|
||||
log4j.appender.org.eclipse.jetty=OFF
|
||||
|
||||
log4j.logger.org.springframework=INFO
|
||||
log4j.logger.org.deeplearning4j=DEBUG
|
||||
log4j.logger.org.nd4j=DEBUG
|
||||
log4j.logger.org.eclipse.jetty=OFF
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
<!--
|
||||
~ /* ******************************************************************************
|
||||
~ *
|
||||
~ *
|
||||
~ * 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
|
||||
~ ******************************************************************************/
|
||||
-->
|
||||
|
||||
<configuration>
|
||||
|
||||
|
||||
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>logs/application.log</file>
|
||||
<encoder>
|
||||
<pattern> %logger{15} - %message%n%xException{5}
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern> %logger{15} - %message%n%xException{5}
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.apache.catalina.core" level="DEBUG" />
|
||||
<logger name="org.springframework" level="DEBUG" />
|
||||
<logger name="org.deeplearning4j" level="DEBUG" />
|
||||
<logger name="org.nd4j" level="DEBUG" />
|
||||
<logger name="org.eclipse.jetty" level="INFO" />
|
||||
|
||||
<logger name="opennlp.uima.util" level="OFF" />
|
||||
<logger name="org.apache.uima" level="OFF" />
|
||||
<logger name="org.cleartk" level="OFF" />
|
||||
|
||||
|
||||
|
||||
<root level="ERROR">
|
||||
<appender-ref ref="STDOUT" />
|
||||
<appender-ref ref="FILE" />
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
Reference in New Issue
Block a user