136 lines
5.8 KiB
Plaintext
136 lines
5.8 KiB
Plaintext
|
/*******************************************************************************
|
||
|
* Copyright (c) 2015-2019 Skymind, Inc.
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
* 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
|
||
|
******************************************************************************/
|
||
|
|
||
|
include "array.fbs"; //For FlatArray
|
||
|
|
||
|
namespace nd4j.graph;
|
||
|
|
||
|
/*
|
||
|
An "Event" is any value that may occur multiple times (score vs. iteration, or accuracy for example)
|
||
|
All events have timestamps and iteration/epoch.
|
||
|
|
||
|
Design: Given given FlatBuffers doesn't support polymorphism, each "frame" in our log file will comprise a sequence of (Event,X) pairs
|
||
|
"Event" is common information/header for the frame (i.e., determines type that follows and allows decoding), and can also be used for filtering - i.e., can skip the next entry
|
||
|
|
||
|
Alternatives:
|
||
|
1. Have a large Event class, with all but 1 of the 'type specific' fields being null (inefficient, especially for things like scalars)
|
||
|
2. Use pair of (ubyte,X) and have duplicate fields in every event subtype
|
||
|
|
||
|
Types of entries that can follow an Event:
|
||
|
array:FlatArray; //Use standard/existing graph FlatArray class. Also used for scalars! (For types and also strings etc)
|
||
|
arrayList:[FlatArray]; //For TensorArray and the like
|
||
|
histogram:Histogram; //Histogram class
|
||
|
image:Image; //Could just use array/FlatArray, but idea is to store more efficiently here in compressed format
|
||
|
summaryStat:SummaryStatistics; //One class for holding stuff like min/mean/max/stdev etc - more efficiently than a whole lot of separate scalar entries...
|
||
|
opTiming:FlatTiming; //Timing/profiling information about a single op execution. Use existing FlatTiming, but maybe extend if required
|
||
|
hardwareState:HardwareState; //Information about hardware at a specific point in time: CPU/GPU utilization, etc
|
||
|
*/
|
||
|
|
||
|
|
||
|
enum UIEventType:byte {
|
||
|
ADD_NAME, //Used to register a name (essentialy, Map<Integer,String>.put(i,name)), so it can be referred to by index later. Saves us encoding really long names in every single frame...
|
||
|
SCALAR,
|
||
|
ARRAY,
|
||
|
ARRAY_LIST,
|
||
|
HISTOGRAM,
|
||
|
IMAGE, //To be added later
|
||
|
SUMMARY_STATISTICS,
|
||
|
OP_TIMING,
|
||
|
HARDWARE_STATE
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
UIEventSubtype relates to what the metric is about. This determines where the value should be presented in the UI
|
||
|
For example, we can have scalars for: evaluation, tuning (mean magnitudes), performance (op runtime) etc.
|
||
|
But these should be presented in different sections of the UI.
|
||
|
It can also be thought of as the "semantic type of event" whereas UIEventType is the "data type of event"
|
||
|
*/
|
||
|
enum UIEventSubtype:byte {
|
||
|
NONE, //Not applicable (for example, ADD_NAME event type)
|
||
|
EVALUATION, //Train/test accuracy, etc
|
||
|
LOSS, //Value of the loss function (or any sub-component there-of, such as L2)
|
||
|
LEARNING_RATE, //Learning rate
|
||
|
TUNING_METRIC, //Metrics like: parameter:update ratio, or parameter and gradient histograms, etc
|
||
|
PERFORMANCE, //Global performance metrics - batches/sec, epoch time, etc
|
||
|
PROFILING, //Op profiling/performance metrics - how long to run each op, etc
|
||
|
FEATURE_LABEL, //Feature/input - for visualization, debugging, etc
|
||
|
PREDICTION, //Network prediction/output
|
||
|
USER_CUSTOM //Custom, user-defined metric or value
|
||
|
}
|
||
|
|
||
|
table UIEvent {
|
||
|
eventType:UIEventType; //Type of the event that follows
|
||
|
eventSubType:UIEventSubtype;//Subtype of event that follows
|
||
|
nameIdx:int; //Integer representing the previously registered name of the event - for example, 0=="accuracy", 1=="score", 2=="weights" etc as previously registered
|
||
|
timestamp:long;
|
||
|
iteration:int;
|
||
|
epoch:int;
|
||
|
variableId:int16; //Number of the variable. Optional (-1 == not applicable)
|
||
|
frameIter:FrameIteration; //Optional - some events have a corresponding frame/iteration
|
||
|
plugin:uint16; //An ID number - what UI page/plugin should be used to render this information? (Allows for extensibility, separation of data for different UI components)
|
||
|
}
|
||
|
|
||
|
//Optional, often null. Used for events that have an associated frame/iteration (like array values in a loop)
|
||
|
table FrameIteration {
|
||
|
frame:string;
|
||
|
iteration:uint16;
|
||
|
}
|
||
|
|
||
|
//Used to register a name (essentialy, Map<Integer,String>.put(i,name)), so it can be referred to by index later. Saves us encoding really long names in every single frame...
|
||
|
table UIAddName {
|
||
|
nameIdx:int;
|
||
|
name:string;
|
||
|
}
|
||
|
|
||
|
//A simple list of arrays
|
||
|
table FlatArrayList {
|
||
|
list:[FlatArray];
|
||
|
}
|
||
|
|
||
|
enum UIHistogramType:byte {
|
||
|
DISCRETE,
|
||
|
EQUAL_SPACING, //use min/max + num bins to determine where
|
||
|
CUSTOM
|
||
|
}
|
||
|
|
||
|
table UIHistogram {
|
||
|
type:UIHistogramType;
|
||
|
numbins:uint32;
|
||
|
binranges:FlatArray; //Shape [2] for EQUAL_SPACING (min/max), or shape [2,numbins] for custom bin min/max values
|
||
|
y:FlatArray; //Shape [numbins] - could be integer or floating point, positive or negative
|
||
|
binlabels:[string]; //Optional - used for discrete histograms (essentially, bar chart) //TODO might want to register this value once + reuse?
|
||
|
}
|
||
|
|
||
|
table UISummaryStatistics {
|
||
|
bitmask:uint32; //Bit mask that represents which of the primitives are actually present (FB doesn't support null primitives AFAIK)
|
||
|
min:FlatArray; //Typed - but it would be more space efficient to use double...
|
||
|
max:FlatArray;
|
||
|
mean:double;
|
||
|
stdev:double;
|
||
|
countzero:long;
|
||
|
countpositive:long;
|
||
|
countnegative:long;
|
||
|
countnan:long;
|
||
|
countinf:long;
|
||
|
}
|
||
|
|
||
|
//Standard metrics related to current hardware status
|
||
|
table UIHardwareState {
|
||
|
//TODO - do we want CPU/GPU utilization statistics and the like?
|
||
|
gpuMemory:[long];
|
||
|
hostMemory:long;
|
||
|
}
|