Comparar commits
74 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 7eb2c1a404 | |||
| 69cfc4dd77 | |||
| e88500df33 | |||
| 64ae1da03e | |||
| e24bf3171d | |||
| f301e9312f | |||
| 0b95219c2a | |||
| b05f96e77a | |||
| 063aac8730 | |||
| edeb783547 | |||
| b65c0b740a | |||
| 55d8b72e05 | |||
| 1d4469d2b9 | |||
| fda5be793d | |||
| a8666959c0 | |||
| f95125ab04 | |||
| a5cbfb2c89 | |||
| b43a580683 | |||
| 1f0f615fc4 | |||
| 3842439112 | |||
| 8229495b34 | |||
| b0135100ed | |||
| a628256682 | |||
| ddd6431d55 | |||
| a63287df92 | |||
| 3721257559 | |||
| dba9c4a25b | |||
| 11f7751843 | |||
| c05d7bb433 | |||
| 8e6bdfbeff | |||
| b4829adbc3 | |||
| a3cfa9f8e3 | |||
| 62a80d1f9f | |||
| b0ad46c66b | |||
| 7e2b83b5cc | |||
| 5193bbd931 | |||
| b513bcbec4 | |||
| 408ee8e0f4 | |||
| dd92726044 | |||
| 5d2098e6e1 | |||
| 341497323c | |||
| 1f71b254b5 | |||
| db97a492e1 | |||
| f863fc2638 | |||
| 3d6c654028 | |||
| 64f64ecd2a | |||
| 09b33792d9 | |||
| ab932c1a52 | |||
| 206f4ce6fc | |||
| 1618460984 | |||
| 41cfdfb007 | |||
| 57a60d6919 | |||
| ab3ba50886 | |||
| cc21727a7b | |||
| 1dbbf8a302 | |||
| 6f6ab1af1e | |||
| 09a51dd518 | |||
| 3e0b1c0e50 | |||
| 628c636129 | |||
| d2173bd9f3 | |||
| 2baf4a72bf | |||
| de1ca7a2d2 | |||
| 2b75f16b9a | |||
| 20618ddb40 | |||
| be97f4806e | |||
| cb97a14e59 | |||
| 6faa7d444a | |||
| 806780bd1f | |||
| 2e0ddfaeb9 | |||
| c83d4ecbc5 | |||
| a467e67524 | |||
| 271f237eac | |||
| 857be35efa | |||
| 87f73359ab |
@@ -2,3 +2,4 @@ src/common/lua.js
|
||||
src/visualizers/widgets/TextEditor/lib/*
|
||||
src/common/js-yaml.min.js
|
||||
src/visualizers/Visualizers.json
|
||||
config/config.webgme.js
|
||||
|
||||
+5
-4
@@ -1,18 +1,19 @@
|
||||
env:
|
||||
browser: true
|
||||
node: true
|
||||
mocha: true
|
||||
es6: true
|
||||
extends: 'eslint:recommended'
|
||||
rules:
|
||||
indent:
|
||||
- error
|
||||
- 2
|
||||
- 4
|
||||
linebreak-style:
|
||||
- error
|
||||
- 2
|
||||
- unix
|
||||
quotes:
|
||||
- error
|
||||
- 2
|
||||
- single
|
||||
semi:
|
||||
- error
|
||||
- 2
|
||||
- always
|
||||
|
||||
+1
-1
@@ -1 +1 @@
|
||||
*.webgmex filter=lfs diff=lfs merge=lfs -text
|
||||
|
||||
|
||||
+7
-5
@@ -1,4 +1,4 @@
|
||||
[](https://img.shields.io/badge/state-pre--alpha-red.svg)
|
||||
[](https://img.shields.io/badge/state-alpha-orange.svg)
|
||||
[](./LICENSE)
|
||||
[](https://travis-ci.org/dfst/deepforge)
|
||||
[](https://gitter.im/dfst/deepforge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
@@ -6,14 +6,16 @@
|
||||
# DeepForge
|
||||
DeepForge is an open-source visual development environment for deep learning. Currently, it supports Convolutional Neural Networks but we are planning on supporting additional deep learning classifiers such as RNNs and LSTMs. Additional features include real-time collaborative editing and version control.
|
||||
|
||||
## Quick Setup
|
||||
After cloning the repo, run
|
||||
## Quick Start
|
||||
Simply run the following command to install deepforge with its dependencies:
|
||||
|
||||
```
|
||||
npm install && npm start
|
||||
curl -o- https://raw.githubusercontent.com/dfst/deepforge/master/install.sh | bash
|
||||
```
|
||||
|
||||
Now, navigate to `localhost:8888` in a browser and create a new project. Select `nn` as the seed and start creating your neural nets!
|
||||
Next, follow the postinstall instructions to start MongoDB and DeepForge!
|
||||
|
||||
Finally, navigate to [http://localhost:8888](http://localhost:8888) to start using DeepForge! For more, detailed instructions,check out our [wiki](https://github.com/dfst/deepforge/wiki/Installation-Guide).
|
||||
|
||||
## Caffe Support?
|
||||
DeepForge uses Torch to perform the actual training and testing of the models. If you are interested in DeepForge using Caffe for actual training and testing, check out [DeepForge-Caffe](https://github.com/dfst/deepforge-caffe).
|
||||
|
||||
@@ -4,6 +4,7 @@ var spawn = require('child_process').spawn,
|
||||
execJob,
|
||||
workerJob = null;
|
||||
|
||||
process.env.NODE_ENV = 'local';
|
||||
execJob = spawn('npm', [
|
||||
'start'
|
||||
]);
|
||||
|
||||
+13
-3
@@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
/*globals process, __dirname, require*/
|
||||
|
||||
var path = require('path'),
|
||||
fs = require('fs'),
|
||||
spawn = require('child_process').spawn,
|
||||
childProcess = require('child_process'),
|
||||
spawn = childProcess.spawn,
|
||||
projectConfig = require(__dirname + '/../config'),
|
||||
executorSrc = path.join(__dirname, '..', 'node_modules', 'webgme', 'src',
|
||||
'server', 'middleware', 'executor', 'worker'),
|
||||
@@ -12,13 +13,22 @@ var path = require('path'),
|
||||
address,
|
||||
config = {};
|
||||
|
||||
// Check torch support
|
||||
var result = childProcess.spawnSync('th', ['--help']);
|
||||
if (result.error) {
|
||||
console.error('Checking Torch7 dependency failed. Do you have Torch7 installed ' +
|
||||
'and in your PATH?\n\nFor Torch7 installation instructions, check out ' +
|
||||
'http://torch.ch/docs/getting-started.html');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
var startExecutor = function() {
|
||||
// Start the executor
|
||||
var execJob = spawn('node', [
|
||||
'node_worker.js',
|
||||
workerConfigPath,
|
||||
workerTmp
|
||||
]);
|
||||
]);
|
||||
execJob.stdout.pipe(process.stdout);
|
||||
execJob.stderr.pipe(process.stderr);
|
||||
};
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
"hotkeys": "none",
|
||||
"LayerColors": {}
|
||||
},
|
||||
"FloatingActionButton": {
|
||||
"hideOnEmpty": true
|
||||
},
|
||||
"GenericUIProjectNavigatorController": {
|
||||
"rootMenuClass": "deepforge-logo",
|
||||
"rootDisplayName": "DeepForge"
|
||||
},
|
||||
"CHFLayout": {
|
||||
"panels": [
|
||||
{
|
||||
@@ -13,7 +20,7 @@
|
||||
},
|
||||
{
|
||||
"id": "Footer",
|
||||
"panel": "FooterControls/FooterControlsPanel",
|
||||
"panel": "Footer/FooterPanel",
|
||||
"container": "footer",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
@@ -36,26 +43,47 @@
|
||||
"nodes": [
|
||||
{
|
||||
"nodeName": "MyArchitectures",
|
||||
"icon": "shuffle",
|
||||
"rank": 1,
|
||||
"description": "Neural network architectures are stored here and can be used in pipelines."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyExecutions",
|
||||
"description": "Executions are read-only snapshots of pipelines that have been executed. Past and current executing pipelines are stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyPipelines",
|
||||
"description": "Pipelines are used for training, testing and ensembling models."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyOperations",
|
||||
"icon": "mode_edit",
|
||||
"rank": 2,
|
||||
"color": "blue-grey",
|
||||
"description": "Operations are the building blocks of pipelines. Custom operations can be created and stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyPipelines",
|
||||
"icon": "input",
|
||||
"rank": 3,
|
||||
"description": "Pipelines compose operations together to effectively train, test and/or ensemble models."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyLayers",
|
||||
"icon": "clear_all",
|
||||
"rank": 4,
|
||||
"color": "blue-grey",
|
||||
"description": "Custom torch layers can be created and stored here for use in neural network architectures."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyArtifacts",
|
||||
"icon": "view_quilt",
|
||||
"rank": 5,
|
||||
"description": "Artifacts from pipeline executions are stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyExecutions",
|
||||
"icon": "list",
|
||||
"rank": 6,
|
||||
"color": "blue-grey",
|
||||
"description": "Executions are read-only snapshots of pipelines that have been executed. Past and current executing pipelines are stored here."
|
||||
},
|
||||
{
|
||||
"nodeName": "MyDataTypes",
|
||||
"icon": "settings",
|
||||
"rank": 7,
|
||||
"description": "Custom defined data types are stored here."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
var config = require('./config.webgme'),
|
||||
validateConfig = require('webgme/config/validator');
|
||||
|
||||
require('dotenv').load();
|
||||
require('dotenv').load({silent: true});
|
||||
|
||||
// Add/overwrite any additional settings here
|
||||
config.server.port = process.env.PORT || config.server.port;
|
||||
config.mongo.uri = process.env.MONGO_URI || config.mongo.uri;
|
||||
@@ -16,5 +17,7 @@ config.plugin.allowServerExecution = true;
|
||||
|
||||
config.executor.enable = true;
|
||||
|
||||
config.visualization.extraCss.push('deepforge/styles/global.css');
|
||||
|
||||
validateConfig(config);
|
||||
module.exports = config;
|
||||
|
||||
@@ -9,8 +9,7 @@ var config = require('./config.base'),
|
||||
// config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_my_app';
|
||||
|
||||
// Seeds for development are prefixed with 'dev'
|
||||
config.seedProjects.basePaths = config.seedProjects.basePaths
|
||||
.filter(path => path.indexOf('dev') === -1);
|
||||
config.seedProjects.basePaths = ['src/seeds/project'];
|
||||
|
||||
validateConfig(config);
|
||||
module.exports = config;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// Config for running deepforge w/ one local worker
|
||||
// jshint node: true
|
||||
'use strict';
|
||||
|
||||
var config = require('./config.default'),
|
||||
validateConfig = require('webgme/config/validator');
|
||||
|
||||
// Turn up the worker polling rate
|
||||
config.executor.workerRefreshInterval = 150;
|
||||
config.executor.clearOldDataAtStartUp = true,
|
||||
|
||||
validateConfig(config);
|
||||
module.exports = config;
|
||||
@@ -15,7 +15,6 @@ config.visualization.decoratorPaths.push('src/decorators');
|
||||
config.visualization.decoratorPaths.push('node_modules/webgme-easydag/src/decorators');
|
||||
config.seedProjects.basePaths.push('src/seeds/nn');
|
||||
config.seedProjects.basePaths.push('src/seeds/devTests');
|
||||
config.seedProjects.basePaths.push('src/seeds/devMinimal');
|
||||
config.seedProjects.basePaths.push('src/seeds/devUtilTests');
|
||||
config.seedProjects.basePaths.push('src/seeds/pipeline');
|
||||
config.seedProjects.basePaths.push('src/seeds/devPipelineTests');
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#!/usr/bin/env bash
|
||||
# Things to install:
|
||||
# - nvm
|
||||
|
||||
command -v git >/dev/null 2>&1 || { echo >&2 "I require git but it's not installed. Aborting."; exit 1; }
|
||||
|
||||
echo >&2 "Checking DeepForge dependencies...";
|
||||
command -v th >/dev/null 2>&1 || {
|
||||
# No torch!
|
||||
echo >&2 "Torch is not found. Installing...";
|
||||
git clone https://github.com/torch/distro.git ~/torch --recursive;
|
||||
cd ~/torch; bash install-deps;
|
||||
./install.sh;
|
||||
}
|
||||
|
||||
# profile (bash, zsh, profile, etc) borrowed from nvm's installer
|
||||
detect_profile() {
|
||||
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
|
||||
echo "$PROFILE"
|
||||
return
|
||||
fi
|
||||
|
||||
DETECTED_PROFILE=''
|
||||
local SHELLTYPE
|
||||
SHELLTYPE="$(basename "/$SHELL")"
|
||||
|
||||
if [ "$SHELLTYPE" = "bash" ]; then
|
||||
if [ -f "$HOME/.bashrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bashrc"
|
||||
elif [ -f "$HOME/.bash_profile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bash_profile"
|
||||
fi
|
||||
elif [ "$SHELLTYPE" = "zsh" ]; then
|
||||
DETECTED_PROFILE="$HOME/.zshrc"
|
||||
fi
|
||||
|
||||
if [ -z "$DETECTED_PROFILE" ]; then
|
||||
if [ -f "$HOME/.profile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.profile"
|
||||
elif [ -f "$HOME/.bashrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bashrc"
|
||||
elif [ -f "$HOME/.bash_profile" ]; then
|
||||
DETECTED_PROFILE="$HOME/.bash_profile"
|
||||
elif [ -f "$HOME/.zshrc" ]; then
|
||||
DETECTED_PROFILE="$HOME/.zshrc"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
detect_profile
|
||||
|
||||
command -v node >/dev/null 2>&1 || {
|
||||
# No node! Install nvm
|
||||
echo >&2 "NodeJS is not found. Installing (using nvm)...";
|
||||
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash;
|
||||
source $DETECTED_PROFILE
|
||||
|
||||
# Install nodejs v6.2.0
|
||||
echo "Installing nodejs v6.2.0"
|
||||
nvm install v6.2.0
|
||||
nvm alias default v6.2.0
|
||||
|
||||
# Install npm@2
|
||||
npm install npm@2 -g
|
||||
|
||||
}
|
||||
|
||||
command -v node >/dev/null 2>&1 || {
|
||||
# No mongod!
|
||||
echo >&2 "MongoDB is not found. Installing...";
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
brew install mongodb
|
||||
fi
|
||||
}
|
||||
|
||||
echo >&2 "Installing DeepForge...";
|
||||
|
||||
# Clone deepforge into ~/deepforge
|
||||
git clone https://github.com/dfst/deepforge ~/deepforge
|
||||
cd ~/deepforge
|
||||
npm install
|
||||
|
||||
mkdir ~/deepforge/data 2> /dev/null
|
||||
echo "DeepForge is installed! To run it:"
|
||||
echo " 1) make sure MongoDB is running locally"
|
||||
echo " (start mongo w/ \"mongod --dbpath ~/deepforge/data\")"
|
||||
echo " 2) Run \"npm run local\" from ~/deepforge"
|
||||
+7
-4
@@ -3,20 +3,23 @@
|
||||
"scripts": {
|
||||
"start": "node app.js",
|
||||
"start-dev": "NODE_ENV=dev node app.js",
|
||||
"worker": "node ./bin/start-worker.js",
|
||||
"local": "node ./bin/start-local.js",
|
||||
"test": "node ./node_modules/mocha/bin/mocha --recursive test"
|
||||
"worker": "node ./bin/start-worker.js",
|
||||
"test": "node ./node_modules/mocha/bin/mocha --recursive test",
|
||||
"watch-test": "./node_modules/nodemon/bin/nodemon.js --exec 'node ./node_modules/mocha/bin/mocha --recursive test'",
|
||||
"build-nn": "node ./utils/nn-parser.js"
|
||||
},
|
||||
"version": "0.4.0",
|
||||
"version": "0.6.0",
|
||||
"dependencies": {
|
||||
"dotenv": "^2.0.0",
|
||||
"lodash.difference": "^4.1.2",
|
||||
"nodemon": "^1.9.2",
|
||||
"webgme": "^2.0.0",
|
||||
"webgme-autoviz": "^2.0.3",
|
||||
"webgme-breadcrumbheader": "^2.0.0",
|
||||
"webgme-chflayout": "^2.0.0",
|
||||
"webgme-easydag": "dfst/webgme-easydag",
|
||||
"webgme-fab": "^2.0.2",
|
||||
"webgme-fab": "dfst/webgme-fab",
|
||||
"webgme-simple-nodes": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,48 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
define([
|
||||
'q'
|
||||
], function(
|
||||
Q
|
||||
) {
|
||||
var PtrCodeGen = function() {
|
||||
};
|
||||
|
||||
PtrCodeGen.prototype.getPtrCodeHash = function(ptrId) {
|
||||
return this.core.loadByPath(this.rootNode, ptrId)
|
||||
.then(ptrNode => {
|
||||
// Look up the plugin to use
|
||||
var metanode = this.core.getMetaType(ptrNode),
|
||||
pluginId;
|
||||
|
||||
pluginId = this.core.getRegistry(ptrNode, 'validPlugins').split(' ').shift();
|
||||
this.logger.info(`generating code for ${this.core.getAttribute(ptrNode, 'name')} using ${pluginId}`);
|
||||
|
||||
var context = WebGMEGlobal.Client.getCurrentPluginContext(pluginId);
|
||||
|
||||
context.managerConfig.namespace = this.core.getNamespace(metanode);
|
||||
context.managerConfig.activeNode = this.core.getPath(ptrNode);
|
||||
|
||||
// Load and run the plugin
|
||||
return Q.nfcall(this.executePlugin.bind(this), pluginId, context);
|
||||
})
|
||||
.then(hashes => hashes[0]); // Grab the first asset for now
|
||||
};
|
||||
|
||||
PtrCodeGen.prototype.executePlugin = function(pluginId, config, callback) {
|
||||
// Call the Interpreter manager in a Q.ninvoke friendly way
|
||||
// I need to create a custom context for the given plugin:
|
||||
// - Set the activeNode to the given referenced node
|
||||
// - If the activeNode is namespaced, set META to the given namespace
|
||||
//
|
||||
// FIXME: Check if it is running in the browser or on the server
|
||||
WebGMEGlobal.Client.runBrowserPlugin(pluginId, config, (err, result) => {
|
||||
if (!result.success) {
|
||||
return callback(result.getError());
|
||||
}
|
||||
this.logger.info('Finished calling ' + pluginId);
|
||||
callback(null, result.artifacts);
|
||||
});
|
||||
};
|
||||
|
||||
return PtrCodeGen;
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Audiowide';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Audiowide'), local('Audiowide-Regular'), url(https://fonts.gstatic.com/s/audiowide/v4/7pSgz2MbVvTCvvm7vukSHxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
|
||||
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Audiowide';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: local('Audiowide'), local('Audiowide-Regular'), url(https://fonts.gstatic.com/s/audiowide/v4/8XtYtNKEyyZh481XVWfVOltXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
|
||||
}
|
||||
|
||||
.deepforge-logo .item-label {
|
||||
font-family: 'Audiowide', cursive;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/ArtifactOpDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
ArtifactOpDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var ArtifactOpDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'ArtifactOpDecorator';
|
||||
|
||||
ArtifactOpDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('ArtifactOpDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(ArtifactOpDecorator.prototype, __parent_proto__);
|
||||
ArtifactOpDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
ArtifactOpDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: ArtifactOpDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return ArtifactOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.artifactop-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.artifactop-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.artifactop-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.artifactop-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.artifactop-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.artifactop-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.artifactop-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .artifactop-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,102 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'decorators/DcOpDecorator/EasyDAG/DcOpDecorator.EasyDAGWidget',
|
||||
'css!./ArtifactOpDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var ArtifactOpDecorator,
|
||||
DECORATOR_ID = 'ArtifactOpDecorator',
|
||||
CAST_OPTS = {
|
||||
ArtifactLoader: {
|
||||
ptr: 'artifact',
|
||||
metaTgt: false
|
||||
},
|
||||
ArtifactFinder: {
|
||||
ptr: 'type',
|
||||
metaTgt: true
|
||||
}
|
||||
};
|
||||
|
||||
// ArtifactOp nodes need to be able to...
|
||||
// - dynamically change their outputs (downcast)
|
||||
ArtifactOpDecorator = function (options) {
|
||||
options.color = options.color || '#b0bec5';
|
||||
DecoratorBase.call(this, options);
|
||||
// set the opts...
|
||||
this.castOpts = CAST_OPTS[this._node.baseName];
|
||||
};
|
||||
|
||||
_.extend(ArtifactOpDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
ArtifactOpDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
|
||||
ArtifactOpDecorator.prototype.getTargetFilterFnFor = function() {
|
||||
return id => {
|
||||
var node = this.client.getNode(id),
|
||||
isMetaTgt = node.getId() === node.getMetaTypeId();
|
||||
return isMetaTgt === this.castOpts.metaTgt;
|
||||
};
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.savePointer = function(name, to) {
|
||||
// When the 'artifact' pointer is changed, we should change the base
|
||||
// of the data output node to the target type
|
||||
if (name === this.castOpts.ptr && (typeof to === 'string')) {
|
||||
this.client.startTransaction(`Setting output of ${this.name} to ${to}`);
|
||||
this.castOutputType(to);
|
||||
this.client.makePointer(this._node.id, name, to);
|
||||
this.client.completeTransaction();
|
||||
} else {
|
||||
DecoratorBase.prototype.savePointer.call(this, name, to);
|
||||
}
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.getDisplayName = function() {
|
||||
var ptrName = this._node.baseName === 'ArtifactLoader' ? 'artifact' : 'type',
|
||||
id = this._node.pointers[ptrName],
|
||||
name = this.nameFor[id] || this._node.name;
|
||||
return name;
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.updateDisplayName = function() {
|
||||
var newName = this.getDisplayName();
|
||||
if (this.name !== newName) {
|
||||
this.name = newName;
|
||||
this.nameWidth = null;
|
||||
}
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.updateTargetName = function(id, name) {
|
||||
DecoratorBase.prototype.updateTargetName.apply(this, arguments);
|
||||
// Update name
|
||||
var ptrName = this._node.baseName === 'ArtifactLoader' ? 'artifact' : 'type';
|
||||
if (this._node.pointers[ptrName] === id) {
|
||||
this._name = name;
|
||||
this.onResize();
|
||||
}
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.expand = function() {
|
||||
this.updateDisplayName();
|
||||
DecoratorBase.prototype.expand.call(this);
|
||||
};
|
||||
|
||||
ArtifactOpDecorator.prototype.condense = function() {
|
||||
this.updateDisplayName();
|
||||
DecoratorBase.prototype.condense.call(this);
|
||||
};
|
||||
|
||||
return ArtifactOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Decorators/DecoratorBase',
|
||||
'./EasyDAG/DcOpDecorator.EasyDAGWidget'
|
||||
], function (
|
||||
DecoratorBase,
|
||||
DcOpDecoratorEasyDAGWidget
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var DcOpDecorator,
|
||||
__parent__ = DecoratorBase,
|
||||
__parent_proto__ = DecoratorBase.prototype,
|
||||
DECORATOR_ID = 'DcOpDecorator';
|
||||
|
||||
DcOpDecorator = function (params) {
|
||||
var opts = _.extend({loggerName: this.DECORATORID}, params);
|
||||
|
||||
__parent__.apply(this, [opts]);
|
||||
|
||||
this.logger.debug('DcOpDecorator ctor');
|
||||
};
|
||||
|
||||
_.extend(DcOpDecorator.prototype, __parent_proto__);
|
||||
DcOpDecorator.prototype.DECORATORID = DECORATOR_ID;
|
||||
|
||||
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
|
||||
|
||||
DcOpDecorator.prototype.initializeSupportedWidgetMap = function () {
|
||||
this.supportedWidgetMap = {
|
||||
EasyDAG: DcOpDecoratorEasyDAGWidget
|
||||
};
|
||||
};
|
||||
|
||||
return DcOpDecorator;
|
||||
});
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
.dcop-decorator {
|
||||
min-width: 65px;
|
||||
height: 40px;
|
||||
border: 1px solid black;
|
||||
background-color: #dedede;
|
||||
padding: 3px;
|
||||
text-align: center; }
|
||||
.dcop-decorator .attr-title {
|
||||
font-style: italic;
|
||||
}
|
||||
.dcop-decorator .name {
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
|
||||
text-align: center; }
|
||||
.dcop-decorator .connector {
|
||||
background-color: #fefefe;
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
border: 1px solid blue;
|
||||
z-index: 10;
|
||||
margin-left: -6px;
|
||||
left: 50%; }
|
||||
.dcop-decorator .connector:hover {
|
||||
border-color: rgba(82, 168, 236, 0.8);
|
||||
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
|
||||
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
|
||||
.dcop-decorator .connector.top {
|
||||
top: -6px; }
|
||||
.dcop-decorator .connector.bottom {
|
||||
bottom: -6px; }
|
||||
|
||||
.selected .dcop-decorator {
|
||||
border: 1px solid #52a8ec;
|
||||
background-color: #dbeafc; }
|
||||
@@ -0,0 +1,79 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
* @author brollb / https://github.com/brollb
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'decorators/OperationDecorator/EasyDAG/OperationDecorator.EasyDAGWidget',
|
||||
'css!./DcOpDecorator.EasyDAGWidget.css'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
DecoratorBase
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var DcOpDecorator,
|
||||
DECORATOR_ID = 'DcOpDecorator';
|
||||
|
||||
// DcOp nodes need to be able to...
|
||||
// - dynamically change their outputs (downcast)
|
||||
DcOpDecorator = function (options) {
|
||||
options.color = options.color || '#78909c';
|
||||
DecoratorBase.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(DcOpDecorator.prototype, DecoratorBase.prototype);
|
||||
|
||||
DcOpDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
|
||||
|
||||
DcOpDecorator.prototype.getTargetFilterFnFor = function() {
|
||||
return id => {
|
||||
var node = this.client.getNode(id);
|
||||
return node.getId() !== node.getMetaTypeId(); // not meta node
|
||||
};
|
||||
};
|
||||
|
||||
DcOpDecorator.prototype.castOutputType = function(targetId) {
|
||||
var target = this.client.getNode(targetId),
|
||||
baseId = target.getBaseId(),
|
||||
outputId = this._node.outputs[0] && this._node.outputs[0].id,
|
||||
hash;
|
||||
|
||||
if (!outputId) {
|
||||
// create the outputId node
|
||||
outputId = this._createOutputNode(baseId);
|
||||
} else {
|
||||
this.client.makePointer(outputId, CONSTANTS.POINTER_BASE, baseId);
|
||||
}
|
||||
// Copy the data content to the output node
|
||||
hash = target.getAttribute('data');
|
||||
this.client.setAttributes(outputId, 'data', hash);
|
||||
};
|
||||
|
||||
DcOpDecorator.prototype._createOutputNode = function(baseId) {
|
||||
var n = this.client.getNode(this._node.id),
|
||||
outputCntrId;
|
||||
|
||||
outputCntrId = n.getChildrenIds().find(id => {
|
||||
var metaTypeId = this.client.getNode(id).getMetaTypeId(),
|
||||
metaType = this.client.getNode(metaTypeId);
|
||||
|
||||
if (!metaType) {
|
||||
this.logger.error(`Could not check the type of ${id}!`);
|
||||
return false;
|
||||
}
|
||||
return metaType.getAttribute('name') === 'Outputs';
|
||||
});
|
||||
|
||||
return this.client.createChild({
|
||||
baseId: baseId,
|
||||
parentId: outputCntrId
|
||||
});
|
||||
};
|
||||
|
||||
return DcOpDecorator;
|
||||
});
|
||||
@@ -29,6 +29,13 @@ define([
|
||||
// - unhighlight ports
|
||||
// - report the location of specific ports
|
||||
JobDecorator = function (options) {
|
||||
options.skipAttributes = {
|
||||
name: true,
|
||||
status: true,
|
||||
execFiles: true,
|
||||
stdout: true,
|
||||
debug: true
|
||||
};
|
||||
EllipseDecorator.call(this, options);
|
||||
};
|
||||
|
||||
@@ -42,7 +49,8 @@ define([
|
||||
|
||||
JobDecorator.prototype.setAttributes = function() {
|
||||
EllipseDecorator.prototype.setAttributes.call(this);
|
||||
var status = this._attributes.status && this._attributes.status.value;
|
||||
var attrs = this._node.attributes,
|
||||
status = attrs.status && attrs.status.value;
|
||||
|
||||
// Update the color based on the 'status' attr
|
||||
this.color = COLORS[status] || COLORS.fail;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*globals define, _*/
|
||||
/*globals define, _, Opentip*/
|
||||
/*jshint browser: true, camelcase: false*/
|
||||
|
||||
/**
|
||||
@@ -16,7 +16,12 @@ define([
|
||||
|
||||
var OperationDecorator,
|
||||
NAME_MARGIN = 25,
|
||||
DECORATOR_ID = 'OperationDecorator';
|
||||
DECORATOR_ID = 'OperationDecorator',
|
||||
PORT_TOOLTIP_OPTS = {
|
||||
tipJoint: 'left',
|
||||
removeElementsOnHide: true,
|
||||
style: 'dark'
|
||||
};
|
||||
|
||||
// Operation nodes need to be able to...
|
||||
// - show their ports
|
||||
@@ -30,6 +35,7 @@ define([
|
||||
this.id = this._node.id;
|
||||
this.$ports = this.$el.append('g')
|
||||
.attr('id', 'ports');
|
||||
this.$portTooltips = {};
|
||||
};
|
||||
|
||||
_.extend(OperationDecorator.prototype, DecoratorBase.prototype);
|
||||
@@ -91,7 +97,8 @@ define([
|
||||
|
||||
OperationDecorator.prototype.renderPort = function(port, x, y, isInput) {
|
||||
var color = this.PORT_COLOR.OPEN,
|
||||
portIcon = this.$ports.append('g');
|
||||
portIcon = this.$ports.append('g'),
|
||||
tooltip;
|
||||
|
||||
// If the port is incoming and occupied, render it differently
|
||||
if (isInput && port.connection) {
|
||||
@@ -115,14 +122,26 @@ define([
|
||||
portIcon.on('click', this.onPortClick.bind(this, this.id, port.id, !isInput));
|
||||
|
||||
// Add tooltip with whole name
|
||||
// TODO
|
||||
if (this.$portTooltips[port.id]) {
|
||||
this.$portTooltips[port.id].hide();
|
||||
}
|
||||
tooltip = new Opentip(portIcon[0][0], PORT_TOOLTIP_OPTS);
|
||||
tooltip.setContent(port.name);
|
||||
portIcon.on('mouseenter', () => tooltip.show());
|
||||
portIcon.on('mouseout', () => tooltip.hide());
|
||||
this.$portTooltips[port.id] = tooltip;
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.hidePorts = function() {
|
||||
var visiblePortIds = Object.keys(this.$portTooltips);
|
||||
this.logger.info(`hiding ports for ${this.name} (${this.id})`);
|
||||
this.$ports.remove();
|
||||
this.$ports = this.$el.append('g')
|
||||
.attr('id', 'ports');
|
||||
|
||||
for (var i = visiblePortIds.length; i--;) {
|
||||
this.$portTooltips[visiblePortIds[i]].hide();
|
||||
}
|
||||
};
|
||||
|
||||
OperationDecorator.prototype.getPortLocation = function(id, isInput) {
|
||||
|
||||
@@ -9,12 +9,22 @@ define([
|
||||
'plugin/PluginConfig',
|
||||
'plugin/PluginBase',
|
||||
'deepforge/js-yaml.min',
|
||||
'text!deepforge/layers.yml',
|
||||
'common/util/guid',
|
||||
'js/RegistryKeys',
|
||||
'js/Constants',
|
||||
'js/Panels/MetaEditor/MetaEditorConstants',
|
||||
'underscore',
|
||||
'text!deepforge/layers.json',
|
||||
'text!./metadata.json'
|
||||
], function (
|
||||
PluginConfig,
|
||||
PluginBase,
|
||||
yaml,
|
||||
generateGuid,
|
||||
REGISTRY_KEYS,
|
||||
CONSTANTS,
|
||||
META_CONSTANTS,
|
||||
_,
|
||||
DEFAULT_LAYERS,
|
||||
metadata
|
||||
) {
|
||||
@@ -31,6 +41,8 @@ define([
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = CreateTorchMeta.metadata;
|
||||
this.metaSheets = {};
|
||||
this.sheetCounts = {};
|
||||
};
|
||||
|
||||
CreateTorchMeta.metadata = JSON.parse(metadata);
|
||||
@@ -58,7 +70,7 @@ define([
|
||||
}
|
||||
|
||||
// Extra layer names
|
||||
this.getYamlText((err, text) => {
|
||||
this.getJsonLayers((err, text) => {
|
||||
if (err) {
|
||||
return callback(err, this.result);
|
||||
}
|
||||
@@ -67,15 +79,25 @@ define([
|
||||
// - (Abstract) CategoryLayerTypes
|
||||
// - LayerName
|
||||
// - Attributes (if exists)
|
||||
var content,
|
||||
var content = {},
|
||||
categories,
|
||||
nodes = {};
|
||||
config = this.getCurrentConfig(),
|
||||
nodes = {},
|
||||
layers;
|
||||
|
||||
try {
|
||||
content = yaml.load(text);
|
||||
layers = JSON.parse(text)
|
||||
.filter(layer => layer.type !== 'Criterion');
|
||||
} catch (e) {
|
||||
return callback('YAML parse error: ' + e, this.result);
|
||||
return callback('JSON parse error: ' + e, this.result);
|
||||
}
|
||||
layers.forEach(layer => {
|
||||
if (!content[layer.type]) {
|
||||
content[layer.type] = [];
|
||||
}
|
||||
content[layer.type].push(layer);
|
||||
});
|
||||
|
||||
categories = Object.keys(content);
|
||||
// Create the base class, if needed
|
||||
if (!this.META.Layer) {
|
||||
@@ -84,23 +106,52 @@ define([
|
||||
|
||||
// Create the category nodes
|
||||
categories
|
||||
.forEach(name => nodes[name] = this.createMetaNode(name, this.META.Layer));
|
||||
.forEach(name => {
|
||||
// Create a tab for each
|
||||
this.metaSheets[name] = this.createMetaSheetTab(name);
|
||||
this.sheetCounts[name] = 0;
|
||||
nodes[name] = this.createMetaNode(name, this.META.Layer, name);
|
||||
});
|
||||
|
||||
// Make them abstract
|
||||
categories
|
||||
.forEach(name => this.core.setRegistry(nodes[name], 'isAbstract', true));
|
||||
|
||||
|
||||
if (config.removeOldLayers) {
|
||||
var isNewLayer = {},
|
||||
newLayers = layers.map(layer => layer.name),
|
||||
oldLayers,
|
||||
oldNames;
|
||||
|
||||
newLayers = newLayers.concat(categories); // add the category nodes
|
||||
newLayers.forEach(name => isNewLayer[name] = true);
|
||||
|
||||
// Set the newLayer nodes 'base' to 'Layer' so we don't accidentally
|
||||
// delete them
|
||||
newLayers
|
||||
.map(name => this.META[name])
|
||||
.filter(layer => !!layer)
|
||||
.forEach(layer => this.core.setPointer(layer, 'base', this.META.Layer));
|
||||
|
||||
oldLayers = Object.keys(this.META)
|
||||
.filter(name => name !== 'Layer')
|
||||
.map(name => this.META[name])
|
||||
.filter(node => this.isMetaTypeOf(node, this.META.Layer))
|
||||
.filter(node => !isNewLayer[this.core.getAttribute(node, 'name')]);
|
||||
|
||||
oldNames = oldLayers.map(l => this.core.getAttribute(l, 'name'));
|
||||
// Get the old layer names
|
||||
this.logger.debug(`Removing layers: ${oldNames.join(', ')}`);
|
||||
oldLayers.forEach(layer => this.core.deleteNode(layer));
|
||||
}
|
||||
|
||||
// Create the actual nodes
|
||||
categories.forEach(cat => {
|
||||
content[cat]
|
||||
.forEach(name => {
|
||||
var attrs = null;
|
||||
if (typeof name !== 'string') {
|
||||
attrs = name[Object.keys(name)[0]];
|
||||
name = Object.keys(name)[0];
|
||||
}
|
||||
nodes[name] = this.createMetaNode(name, nodes[cat], attrs);
|
||||
.forEach(layer => {
|
||||
var attrs = layer.params,
|
||||
name = layer.name;
|
||||
nodes[name] = this.createMetaNode(name, nodes[cat], cat, attrs);
|
||||
// Make the node non-abstract
|
||||
this.core.setRegistry(nodes[name], 'isAbstract', false);
|
||||
});
|
||||
@@ -115,11 +166,48 @@ define([
|
||||
callback(null, self.result);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.getYamlText = function (callback) {
|
||||
CreateTorchMeta.prototype.removeFromMeta = function (nodeId) {
|
||||
var sheets = this.core.getRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS),
|
||||
sheet;
|
||||
|
||||
// Remove from meta
|
||||
this.core.delMember(this.rootNode, META_CONSTANTS.META_ASPECT_SET_NAME, nodeId);
|
||||
|
||||
// Remove from the given meta sheet
|
||||
sheet = sheets.find(sheet => {
|
||||
var paths = this.core.getMemberPaths(this.rootNode, sheet.SetID);
|
||||
return paths.indexOf(nodeId) > -1;
|
||||
});
|
||||
|
||||
if (sheet) {
|
||||
this.core.delMember(this.rootNode, sheet.SetID, nodeId);
|
||||
}
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.createMetaSheetTab = function (name) {
|
||||
var sheets = this.core.getRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS),
|
||||
id = META_CONSTANTS.META_ASPECT_SHEET_NAME_PREFIX + generateGuid(),
|
||||
sheet,
|
||||
desc = {
|
||||
SetID: id,
|
||||
order: sheets.length,
|
||||
title: name
|
||||
};
|
||||
|
||||
sheet = sheets.find(sheet => sheet.title === name);
|
||||
if (!sheet) {
|
||||
sheet = desc;
|
||||
this.logger.debug(`creating meta sheet "${name}"`);
|
||||
this.core.createSet(this.rootNode, sheet.SetID);
|
||||
sheets.push(sheet);
|
||||
this.core.setRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS, sheets);
|
||||
}
|
||||
return sheet.SetID;
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.getJsonLayers = function (callback) {
|
||||
var config = this.getCurrentConfig();
|
||||
|
||||
if (config.layerNameHash) {
|
||||
@@ -135,41 +223,72 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.createMetaNode = function (name, base, attrs) {
|
||||
var node;
|
||||
CreateTorchMeta.prototype.createMetaNode = function (name, base, tabName, attrs) {
|
||||
var node = this.META[name],
|
||||
nodeId = node && this.core.getPath(node),
|
||||
tabId = this.metaSheets[tabName],
|
||||
position = this.getPositionFor(name, tabName);
|
||||
|
||||
if (this.META[name]) {
|
||||
this.logger.warn('"' + name + '" already exists. skipping...');
|
||||
return this.META[name];
|
||||
if (!tabId) {
|
||||
this.logger.error(`No meta sheet for ${tabName}`);
|
||||
}
|
||||
|
||||
// Create a node
|
||||
node = this.core.createNode({
|
||||
parent: this.META.Language,
|
||||
base: base
|
||||
});
|
||||
this.core.setAttribute(node, 'name', name);
|
||||
if (!node) {
|
||||
// Create a node
|
||||
node = this.core.createNode({
|
||||
parent: this.META.Language,
|
||||
base: base
|
||||
});
|
||||
this.core.setAttribute(node, 'name', name);
|
||||
|
||||
nodeId = this.core.getPath(node);
|
||||
} else {
|
||||
// Remove from meta
|
||||
this.removeFromMeta(nodeId);
|
||||
this.core.setPointer(node, 'base', base);
|
||||
}
|
||||
|
||||
// Add it to the meta sheet
|
||||
this.core.addMember(this.rootNode, 'MetaAspectSet', node);
|
||||
this.core.addMember(this.rootNode, META_CONSTANTS.META_ASPECT_SET_NAME, node);
|
||||
this.core.addMember(this.rootNode, tabId, node);
|
||||
|
||||
// Add it to a tab of the meta sheet
|
||||
var set = this.core.getSetNames(this.rootNode)
|
||||
.find(name => name !== 'MetaAspectSet');
|
||||
|
||||
this.core.addMember(this.rootNode, set, node);
|
||||
// TODO: Position the nodes on the META
|
||||
// TODO: Put each group of nodes on their own META sheet
|
||||
this.core.setMemberRegistry(
|
||||
this.rootNode,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME,
|
||||
nodeId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
position
|
||||
);
|
||||
this.core.setMemberRegistry(
|
||||
this.rootNode,
|
||||
tabId,
|
||||
nodeId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
position
|
||||
);
|
||||
|
||||
if (attrs) { // Add the attributes
|
||||
attrs.forEach((name, index) => {
|
||||
var desc = null;
|
||||
if (typeof name !== 'string') {
|
||||
desc = name[Object.keys(name)[0]];
|
||||
name = Object.keys(name)[0];
|
||||
// Remove attributes not in the given list
|
||||
var currentAttrs = this.core.getValidAttributeNames(node),
|
||||
rmAttrs;
|
||||
|
||||
rmAttrs = _.difference(currentAttrs, attrs) // old attribute names
|
||||
.filter(attr => attr !== 'name');
|
||||
|
||||
if (rmAttrs.length) {
|
||||
this.logger.debug(`Removing ${rmAttrs.join(', ')} from ${name}`);
|
||||
}
|
||||
rmAttrs.forEach(attr => {
|
||||
this.core.delAttributeMeta(node, attr);
|
||||
if (this.core.getOwnAttribute(node, attr) !== undefined) {
|
||||
this.core.delAttribute(node, attr);
|
||||
}
|
||||
desc = desc || {};
|
||||
});
|
||||
|
||||
attrs.forEach((name, index) => {
|
||||
var desc = {};
|
||||
desc.argindex = index;
|
||||
desc.default = '';
|
||||
this.addAttribute(name, node, desc);
|
||||
});
|
||||
}
|
||||
@@ -178,11 +297,38 @@ define([
|
||||
return node;
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.getPositionFor = function(name, tabName) {
|
||||
var index = this.sheetCounts[tabName],
|
||||
dx = 140,
|
||||
dy = 100,
|
||||
MAX_WIDTH = 1200,
|
||||
x;
|
||||
|
||||
if (tabName === 'Convolution') {
|
||||
dx *= 1.3;
|
||||
dy *= 1.5;
|
||||
}
|
||||
|
||||
this.sheetCounts[tabName]++;
|
||||
if (index === 0) {
|
||||
return {
|
||||
x: MAX_WIDTH/2,
|
||||
y: 50
|
||||
};
|
||||
}
|
||||
|
||||
x = dx*index;
|
||||
return {
|
||||
x: x%MAX_WIDTH,
|
||||
y: Math.floor(x/MAX_WIDTH+1)*dy + 50
|
||||
};
|
||||
};
|
||||
|
||||
CreateTorchMeta.prototype.addAttribute = function (name, node, def) {
|
||||
var initial,
|
||||
schema = {};
|
||||
|
||||
schema.type = def.type || 'integer';
|
||||
schema.type = def.type || 'string';
|
||||
if (schema.type === 'list') { // FIXME: add support for lists
|
||||
schema.type = 'string';
|
||||
}
|
||||
@@ -212,9 +358,7 @@ define([
|
||||
if (schema.type === 'boolean') {
|
||||
initial = initial !== null ? initial : false;
|
||||
}
|
||||
if (initial !== null) { // optional attribute - set default value
|
||||
this.core.setAttribute(node, name, initial);
|
||||
}
|
||||
this.core.setAttribute(node, name, initial);
|
||||
};
|
||||
|
||||
return CreateTorchMeta;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"id": "CreateTorchMeta",
|
||||
"name": "Create Torch Meta",
|
||||
"name": "Update nn meta",
|
||||
"version": "0.1.0",
|
||||
"description": "Create metamodel from Torch yaml",
|
||||
"icon": {
|
||||
@@ -17,6 +17,14 @@
|
||||
"value": "",
|
||||
"valueType": "asset",
|
||||
"readOnly": false
|
||||
},
|
||||
{
|
||||
"name": "removeOldLayers",
|
||||
"displayName": "Delete old layers",
|
||||
"description": "Delete all layers not in the current description",
|
||||
"value": true,
|
||||
"valueType": "boolean",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
/*globals define */
|
||||
/*jshint node:true, browser:true, esversion: 6*/
|
||||
|
||||
define([
|
||||
'plugin/CreateExecution/CreateExecution/CreateExecution',
|
||||
'deepforge/plugin/PtrCodeGen',
|
||||
'common/core/constants',
|
||||
'q',
|
||||
'text!./metadata.json',
|
||||
'./Templates/index',
|
||||
'./templates/index',
|
||||
'./LocalExecutor',
|
||||
'executor/ExecutorClient',
|
||||
'jszip',
|
||||
'underscore'
|
||||
], function (
|
||||
CreateExecution,
|
||||
PtrCodeGen,
|
||||
CONSTANTS,
|
||||
Q,
|
||||
pluginMetadata,
|
||||
Templates,
|
||||
LocalExecutor, // DeepForge operation primitives
|
||||
ExecutorClient,
|
||||
JsZip,
|
||||
_
|
||||
) {
|
||||
'use strict';
|
||||
@@ -32,24 +32,15 @@ define([
|
||||
* @classdesc This class represents the plugin ExecutePipeline.
|
||||
* @constructor
|
||||
*/
|
||||
var OUTPUT_INTERVAL = 1500,
|
||||
STDOUT_FILE = 'job_stdout.txt';
|
||||
var ExecutePipeline = function () {
|
||||
// Call base class' constructor.
|
||||
CreateExecution.call(this);
|
||||
this.pluginMetadata = pluginMetadata;
|
||||
|
||||
// Cache
|
||||
this.nodes = {};
|
||||
|
||||
// Record keeping for running operations
|
||||
this.opFor = {};
|
||||
this.incomingCounts = {};
|
||||
this.outputsOf = {};
|
||||
this.inputPortsFor = {};
|
||||
this.inputs = {};
|
||||
|
||||
this.finished = {};
|
||||
this.completedCount = 0;
|
||||
this.totalCount = 0;
|
||||
this._currentSave = Q();
|
||||
this.initRun();
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -64,6 +55,23 @@ define([
|
||||
ExecutePipeline.prototype = Object.create(CreateExecution.prototype);
|
||||
ExecutePipeline.prototype.constructor = ExecutePipeline;
|
||||
|
||||
ExecutePipeline.prototype.initRun = function () {
|
||||
// Cache
|
||||
this.nodes = {};
|
||||
|
||||
// Record keeping for running operations
|
||||
this.opFor = {};
|
||||
this.incomingCounts = {};
|
||||
this.outputsOf = {};
|
||||
this.inputPortsFor = {};
|
||||
this.inputs = {};
|
||||
|
||||
this.finished = {};
|
||||
this.completedCount = 0;
|
||||
this.totalCount = 0;
|
||||
this.outputLineCount = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
@@ -78,6 +86,8 @@ define([
|
||||
// inputs for the next operation cannot be created until the inputs have
|
||||
// been generated
|
||||
|
||||
this.initRun();
|
||||
this.pipelineName = this.core.getAttribute(this.activeNode, 'name');
|
||||
var startPromise;
|
||||
if (this.core.isTypeOf(this.activeNode, this.META.Pipeline)) {
|
||||
// If starting with a pipeline, we will create an Execution first
|
||||
@@ -103,34 +113,49 @@ define([
|
||||
this.buildCache(subtree);
|
||||
this.parsePipeline(children); // record deps, etc
|
||||
|
||||
//if (this.getCurrentConfig().reset) {
|
||||
this.clearResults();
|
||||
//}
|
||||
|
||||
// Execute the operations in the proper order
|
||||
this.executePipeline();
|
||||
return this.clearResults();
|
||||
})
|
||||
.then(() => this.executePipeline())
|
||||
.fail(e => this.logger.error(e));
|
||||
};
|
||||
|
||||
// Override 'save' to prevent race conditions while saving
|
||||
ExecutePipeline.prototype.save = function (msg) {
|
||||
// When 'save' is called, it should still finish any current save op
|
||||
// before continuing
|
||||
this._currentSave = this._currentSave
|
||||
.then(() => CreateExecution.prototype.save.call(this, msg));
|
||||
|
||||
return this._currentSave;
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.isInputData = function (node) {
|
||||
var prnt = this.core.getParent(node);
|
||||
return this.core.isTypeOf(prnt, this.META.Inputs);
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.clearResults = function () {
|
||||
var nodes = Object.keys(this.nodes).map(id => this.nodes[id]);
|
||||
// Clear the pipeline's results
|
||||
this.logger.info('Clearing all intermediate execution results');
|
||||
|
||||
nodes.filter(node => this.core.isTypeOf(node, this.META.Data))
|
||||
// Only input data nodes should be cleared. Outputs will be overwritten
|
||||
.filter(node => this.isInputData(node))
|
||||
.forEach(conn => this.core.delAttribute(conn, 'data'));
|
||||
|
||||
// Set the status for each job to 'pending'
|
||||
nodes.filter(node => this.core.isTypeOf(node, this.META.Job))
|
||||
.forEach(node => this.core.setAttribute(node, 'status', 'pending'));
|
||||
|
||||
this.logger.info('Setting all jobs status to "pending"');
|
||||
this.logger.debug(`Making a commit from ${this.currentHash}`);
|
||||
return this.save(`Initializing ${this.pipelineName} for execution`);
|
||||
};
|
||||
|
||||
//////////////////////////// Operation Preparation/Execution ////////////////////////////
|
||||
ExecutePipeline.prototype.buildCache = function (nodes) {
|
||||
// Cache all nodes
|
||||
// Do I need to cache the data inputs? TODO
|
||||
// Probably not - I should be able to look them up as needed
|
||||
nodes.forEach(node => this.nodes[this.core.getPath(node)] = node);
|
||||
};
|
||||
|
||||
@@ -235,8 +260,10 @@ define([
|
||||
// Execute all ready operations
|
||||
readyOps.forEach(jobId => {
|
||||
delete this.incomingCounts[jobId];
|
||||
this.executeOperation(jobId);
|
||||
});
|
||||
readyOps.reduce((prev, jobId) => {
|
||||
return prev.then(() => this.executeOperation(jobId));
|
||||
}, Q());
|
||||
return readyOps.length;
|
||||
};
|
||||
|
||||
@@ -259,11 +286,12 @@ define([
|
||||
inputs;
|
||||
|
||||
// Execute any special operation types here - not on an executor
|
||||
this.logger.debug(`Executing operation "${name}"`);
|
||||
if (localTypeId !== null) {
|
||||
this.executeLocalOperation(localTypeId, node);
|
||||
return this.executeLocalOperation(localTypeId, node);
|
||||
} else {
|
||||
// Generate all execution files
|
||||
this.createOperationFiles(node).then(results => {
|
||||
return this.createOperationFiles(node).then(results => {
|
||||
files = results;
|
||||
artifactName = `${name}_${jobId.replace(/\//g, '_')}-execution-files`;
|
||||
artifact = this.blobClient.createArtifact(artifactName);
|
||||
@@ -306,8 +334,8 @@ define([
|
||||
})
|
||||
.then(outputArgs => {
|
||||
var config,
|
||||
args = ['init.lua'],
|
||||
outputs;
|
||||
outputs,
|
||||
file;
|
||||
|
||||
outputs = outputArgs.map(pair => pair[0])
|
||||
.map(name => {
|
||||
@@ -317,8 +345,12 @@ define([
|
||||
};
|
||||
});
|
||||
|
||||
outputs.push({
|
||||
name: 'stdout',
|
||||
resultPatterns: [STDOUT_FILE]
|
||||
});
|
||||
|
||||
if (this.debug) {
|
||||
args.push('#' + Date.now());
|
||||
outputs.push({
|
||||
name: name + '-all-files',
|
||||
resultPatterns: []
|
||||
@@ -326,13 +358,22 @@ define([
|
||||
}
|
||||
|
||||
config = {
|
||||
cmd: 'th',
|
||||
args: args,
|
||||
cmd: 'bash',
|
||||
args: ['run.sh'],
|
||||
outputInterval: OUTPUT_INTERVAL,
|
||||
resultArtifacts: outputs
|
||||
};
|
||||
files['executor_config.json'] = JSON.stringify(config, null, 4);
|
||||
files['run.sh'] = Templates.BASH;
|
||||
|
||||
// Save the artifact
|
||||
// Remove empty hashes
|
||||
for (file in data) {
|
||||
if (!data[file]) {
|
||||
this.logger.warn(`Empty data hash has been found for file "${file}". Removing it...`);
|
||||
delete data[file];
|
||||
}
|
||||
}
|
||||
return artifact.addObjectHashes(data);
|
||||
})
|
||||
.then(() => {
|
||||
@@ -350,6 +391,7 @@ define([
|
||||
})
|
||||
.fail(e => {
|
||||
this.core.setAttribute(this.nodes[jobId], 'status', 'fail');
|
||||
this.logger.info(`Setting ${jobId} status to "fail"`);
|
||||
this.onPipelineComplete(`Distributed operation "${name}" failed ${e}`);
|
||||
});
|
||||
}
|
||||
@@ -365,21 +407,48 @@ define([
|
||||
|
||||
this.logger.info(`Executing operation "${name}"`);
|
||||
|
||||
this.outputLineCount[jobId] = 0;
|
||||
// Set the job status to 'running'
|
||||
this.core.setAttribute(this.nodes[jobId], 'status', 'running');
|
||||
|
||||
// Run the operation on an executor
|
||||
executor.createJob({hash})
|
||||
this.core.setAttribute(this.nodes[jobId], 'stdout', '');
|
||||
this.logger.info(`Setting ${jobId} status to "running" (${this.currentHash})`);
|
||||
this.logger.debug(`Making a commit from ${this.currentHash}`);
|
||||
this.save(`Started "${name}" operation in ${this.pipelineName}`)
|
||||
.then(() => executor.createJob({hash}))
|
||||
.then(() => this.watchOperation(executor, hash, opId, jobId))
|
||||
.catch(err => this.logger.error(`Could not execute "${name}": ${err}`));
|
||||
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.watchOperation = function (executor, hash, opId, jobId) {
|
||||
var name;
|
||||
var job = this.nodes[jobId],
|
||||
info,
|
||||
name;
|
||||
|
||||
return executor.getInfo(hash)
|
||||
.then(info => {
|
||||
.then(_info => { // Update the job's stdout
|
||||
var actualLine, // on executing job
|
||||
currentLine = this.outputLineCount[jobId];
|
||||
|
||||
info = _info;
|
||||
actualLine = info.outputNumber;
|
||||
if (actualLine !== null && actualLine >= currentLine) {
|
||||
this.outputLineCount[jobId] = actualLine + 1;
|
||||
return executor.getOutput(hash, currentLine, actualLine+1)
|
||||
.then(outputLines => {
|
||||
var stdout = this.core.getAttribute(job, 'stdout'),
|
||||
output = outputLines.map(o => o.output).join(''),
|
||||
jobName = this.core.getAttribute(job, 'name');
|
||||
|
||||
// Handle the \b
|
||||
// TODO
|
||||
stdout += output;
|
||||
this.core.setAttribute(job, 'stdout', stdout);
|
||||
return this.save(`Received stdout for ${jobName}`);
|
||||
});
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
if (info.status === 'CREATED' || info.status === 'RUNNING') {
|
||||
setTimeout(
|
||||
this.watchOperation.bind(this, executor, hash, opId, jobId),
|
||||
@@ -388,20 +457,29 @@ define([
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.status !== 'SUCCESS') {
|
||||
name = this.core.getAttribute(this.nodes[opId], 'name');
|
||||
// Download all files
|
||||
this.result.addArtifact(info.resultHashes[name + '-all-files']);
|
||||
// Set the job to failed! Store the error
|
||||
this.core.setAttribute(this.nodes[jobId], 'status', 'fail');
|
||||
this.onPipelineComplete(`Operation "${opId}" failed! ${JSON.stringify(info)}`); // Failed
|
||||
} else {
|
||||
name = this.core.getAttribute(this.nodes[opId], 'name');
|
||||
if (this.debug) {
|
||||
this.result.addArtifact(info.resultHashes[name + '-all-files']);
|
||||
}
|
||||
this.onDistOperationComplete(opId, info);
|
||||
}
|
||||
name = this.core.getAttribute(job, 'name');
|
||||
this.core.setAttribute(job, 'execFiles', info.resultHashes[name + '-all-files']);
|
||||
return this.blobClient.getArtifact(info.resultHashes.stdout)
|
||||
.then(artifact => {
|
||||
var stdoutHash = artifact.descriptor.content[STDOUT_FILE].content;
|
||||
return this.blobClient.getObjectAsString(stdoutHash);
|
||||
})
|
||||
.then(stdout => {
|
||||
this.core.setAttribute(job, 'stdout', stdout);
|
||||
if (info.status !== 'SUCCESS') {
|
||||
// Download all files
|
||||
this.result.addArtifact(info.resultHashes[name + '-all-files']);
|
||||
// Set the job to failed! Store the error
|
||||
this.core.setAttribute(this.nodes[jobId], 'status', 'fail');
|
||||
this.logger.info(`Setting ${jobId} status to "fail"`);
|
||||
this.onPipelineComplete(`Operation "${opId}" failed! ${JSON.stringify(info)}`); // Failed
|
||||
} else {
|
||||
if (this.debug) {
|
||||
this.result.addArtifact(info.resultHashes[name + '-all-files']);
|
||||
}
|
||||
this.onDistOperationComplete(opId, info);
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch(err => this.logger.error(`Could not get op info for ${opId}: ${err}`));
|
||||
};
|
||||
@@ -433,6 +511,7 @@ define([
|
||||
hash = artifact.descriptor.content[`outputs/${name}`].content;
|
||||
|
||||
this.core.setAttribute(outputMap[name], 'data', hash);
|
||||
this.logger.info(`Setting ${nodeId} data to ${hash}`);
|
||||
});
|
||||
|
||||
return this.onOperationComplete(node);
|
||||
@@ -445,45 +524,53 @@ define([
|
||||
nextPortIds = this.getOperationOutputIds(opNode),
|
||||
jNode = this.core.getParent(opNode),
|
||||
resultPorts,
|
||||
jobId = this.core.getPath(jNode),
|
||||
hasReadyOps;
|
||||
|
||||
// Set the operation to 'success'!
|
||||
this.core.setAttribute(jNode, 'status', 'success');
|
||||
this.logger.info(`Setting ${jobId} status to "success"`);
|
||||
this.logger.debug(`Making a commit from ${this.currentHash}`);
|
||||
this.save(`Operation "${name}" in ${this.pipelineName} completed successfully`)
|
||||
.then(() => {
|
||||
|
||||
// Transport the data from the outputs to any connected inputs
|
||||
// - Get all the connections from each outputId
|
||||
// - Get the corresponding dst outputs
|
||||
// - Use these new ids for checking 'hasReadyOps'
|
||||
resultPorts = nextPortIds.map(id => this.inputPortsFor[id])
|
||||
.reduce((l1, l2) => l1.concat(l2), []);
|
||||
// Transport the data from the outputs to any connected inputs
|
||||
// - Get all the connections from each outputId
|
||||
// - Get the corresponding dst outputs
|
||||
// - Use these new ids for checking 'hasReadyOps'
|
||||
resultPorts = nextPortIds.map(id => this.inputPortsFor[id])
|
||||
.reduce((l1, l2) => l1.concat(l2), []);
|
||||
|
||||
resultPorts.map((id, i) => [this.nodes[id], this.nodes[nextPortIds[i]]])
|
||||
.forEach(pair => { // [ resultPort, nextPort ]
|
||||
var result = pair[0],
|
||||
next = pair[1],
|
||||
hash = this.core.getAttribute(result, 'data');
|
||||
|
||||
this.logger.info(`forwarding data (${hash}) from ${this.core.getPath(result)} ` +
|
||||
`to ${this.core.getPath(next)}`);
|
||||
this.core.setAttribute(next, 'data', hash);
|
||||
resultPorts
|
||||
.map((id, i) => [this.nodes[id], this.nodes[nextPortIds[i]]])
|
||||
.forEach(pair => { // [ resultPort, nextPort ]
|
||||
var result = pair[0],
|
||||
next = pair[1],
|
||||
hash = this.core.getAttribute(result, 'data');
|
||||
|
||||
this.logger.info(`forwarding data (${hash}) from ${this.core.getPath(result)} ` +
|
||||
`to ${this.core.getPath(next)}`);
|
||||
this.core.setAttribute(next, 'data', hash);
|
||||
this.logger.info(`Setting ${jobId} data to ${hash}`);
|
||||
});
|
||||
|
||||
// For all the nextPortIds, decrement the corresponding operation's incoming counts
|
||||
hasReadyOps = nextPortIds.map(id => this.getSiblingIdContaining(id))
|
||||
.reduce((l1, l2) => l1.concat(l2), [])
|
||||
|
||||
// decrement the incoming counts for each operation id
|
||||
.map(opId => --this.incomingCounts[opId])
|
||||
.indexOf(0) > -1;
|
||||
|
||||
this.completedCount++;
|
||||
this.logger.debug(`Operation "${name}" completed. ` +
|
||||
`${this.totalCount - this.completedCount} remaining.`);
|
||||
if (hasReadyOps) {
|
||||
this.executeReadyOperations();
|
||||
} else if (this.completedCount === this.totalCount) {
|
||||
this.onPipelineComplete();
|
||||
}
|
||||
});
|
||||
|
||||
// For all the nextPortIds, decrement the corresponding operation's incoming counts
|
||||
hasReadyOps = resultPorts.map(id => this.opFor[id])
|
||||
.reduce((l1, l2) => l1.concat(l2), [])
|
||||
|
||||
// decrement the incoming counts for each operation id
|
||||
.map(opId => --this.incomingCounts[opId])
|
||||
.indexOf(0) > -1;
|
||||
|
||||
this.completedCount++;
|
||||
this.logger.info(`Operation "${name}" completed. ` +
|
||||
`${this.totalCount - this.completedCount} remaining.`);
|
||||
if (hasReadyOps) {
|
||||
this.executeReadyOperations();
|
||||
} else if (this.completedCount === this.totalCount) {
|
||||
this.onPipelineComplete();
|
||||
}
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.getOperationOutputIds = function(node) {
|
||||
@@ -511,6 +598,7 @@ define([
|
||||
|
||||
// add the given files
|
||||
return this.createEntryFile(node, files)
|
||||
.then(() => this.createCustomLayers(node, files))
|
||||
.then(() => this.createInputs(node, files))
|
||||
.then(() => this.createOutputs(node, files))
|
||||
.then(() => this.createMainFile(node, files))
|
||||
@@ -520,20 +608,45 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.createCustomLayers = function (node, files) {
|
||||
var isCustomLayer = {},
|
||||
metaDict = this.core.getAllMetaNodes(this.rootNode),
|
||||
metanodes,
|
||||
customLayers,
|
||||
code;
|
||||
|
||||
metanodes = Object.keys(metaDict).map(id => metaDict[id]);
|
||||
// Get all the custom layers
|
||||
metanodes.forEach(node => {
|
||||
if (this.core.getAttribute(node, 'name') === 'CustomLayer') {
|
||||
isCustomLayer[this.core.getPath(node)] = true;
|
||||
}
|
||||
});
|
||||
customLayers = metanodes.filter(node =>
|
||||
this.core.getMixinPaths(node).some(id => isCustomLayer[id]));
|
||||
|
||||
// Get the code definitions for each
|
||||
code = 'require \'nn\'\n\n' + customLayers
|
||||
.map(node => this.core.getAttribute(node, 'code')).join('\n');
|
||||
|
||||
// Create the custom layers file
|
||||
files['custom-layers.lua'] = code;
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.createInputs = function (node, files) {
|
||||
var tplContents;
|
||||
return this.getInputs(node)
|
||||
.then(inputs => {
|
||||
// For each input, match the connection with the input name
|
||||
// [ name, type ] => [ name, type, node ]
|
||||
if (inputs.length > 1) {
|
||||
this.logger.warn('multiple inputs not yet fully supported!');
|
||||
}
|
||||
|
||||
//
|
||||
// For each input,
|
||||
// - create the deserializer
|
||||
// - put it in inputs/<name>/init.lua
|
||||
// - copy the data asset to /inputs/<name>/init.lua
|
||||
inputs = inputs
|
||||
.filter(pair => !!this.core.getAttribute(pair[2], 'data')); // remove empty inputs
|
||||
|
||||
files.inputAssets = {}; // data assets
|
||||
tplContents = inputs.map(pair => {
|
||||
var name = pair[0],
|
||||
@@ -544,10 +657,11 @@ define([
|
||||
code: this.core.getAttribute(node, 'deserialize')
|
||||
};
|
||||
});
|
||||
var hashes = inputs.map(pair =>
|
||||
var hashes = inputs
|
||||
// storing the hash for now...
|
||||
files.inputAssets[pair[0]] = this.core.getAttribute(pair[2], 'data')
|
||||
);
|
||||
.map(pair =>
|
||||
files.inputAssets[pair[0]] = this.core.getAttribute(pair[2], 'data')
|
||||
);
|
||||
return Q.all(hashes.map(h => this.blobClient.getMetadata(h)));
|
||||
})
|
||||
.then(metadatas => {
|
||||
@@ -562,57 +676,23 @@ define([
|
||||
};
|
||||
|
||||
ExecutePipeline.prototype.createPointers = function (node, files, cb) {
|
||||
var pointers = this.core.getPointerNames(node).filter(name => name !== 'base'),
|
||||
nIds = pointers.map(p => this.core.getPointerPath(node, p));
|
||||
var pointers,
|
||||
nIds;
|
||||
|
||||
pointers = this.core.getPointerNames(node)
|
||||
.filter(name => name !== 'base')
|
||||
.filter(id => this.core.getPointerPath(node, id) !== null);
|
||||
|
||||
nIds = pointers.map(p => this.core.getPointerPath(node, p));
|
||||
files.ptrAssets = {};
|
||||
Q.all(
|
||||
nIds.map(nId => this.core.loadByPath(this.rootNode, nId))
|
||||
nIds.map(nId => this.getPtrCodeHash(nId))
|
||||
)
|
||||
.then(nodes => {
|
||||
|
||||
var executePlugin = (pluginId, config, callback) => {
|
||||
// Call the Interpreter manager in a Q.ninvoke friendly way
|
||||
// I need to create a custom context for the given plugin:
|
||||
// - Set the activeNode to the given referenced node
|
||||
// - If the activeNode is namespaced, set META to the given namespace
|
||||
//
|
||||
// FIXME: Check if it is running in the browser or on the server
|
||||
WebGMEGlobal.Client.runBrowserPlugin(pluginId, config, (err, result) => {
|
||||
if (!result.success) {
|
||||
return callback(result.getError());
|
||||
}
|
||||
this.logger.info('Finished calling ' + pluginId);
|
||||
callback(null, result.artifacts);
|
||||
});
|
||||
};
|
||||
|
||||
return Q.all(
|
||||
nodes.map(ptrNode => {
|
||||
// Look up the plugin to use
|
||||
var metanode = this.core.getMetaType(ptrNode),
|
||||
pluginId;
|
||||
|
||||
pluginId = this.core.getRegistry(ptrNode, 'validPlugins').split(' ').shift();
|
||||
this.logger.info(`generating code for ${this.core.getAttribute(ptrNode, 'name')} using ${pluginId}`);
|
||||
|
||||
var context = WebGMEGlobal.Client.getCurrentPluginContext(pluginId);
|
||||
|
||||
context.managerConfig.namespace = this.core.getNamespace(metanode);
|
||||
context.managerConfig.activeNode = this.core.getPath(ptrNode);
|
||||
|
||||
// Load and run the plugin
|
||||
return Q.nfcall(executePlugin, pluginId, context);
|
||||
})
|
||||
);
|
||||
})
|
||||
.then(resultHashes => {
|
||||
var name = this.core.getAttribute(node, 'name');
|
||||
this.logger.info(`Pointer generation for ${name} FINISHED!`);
|
||||
resultHashes.forEach((hashes, index) => {
|
||||
// Grab the first asset for now
|
||||
// FIXME
|
||||
files.ptrAssets[`pointers/${pointers[index]}/init.lua`] = hashes[0];
|
||||
resultHashes.forEach((hash, index) => {
|
||||
files.ptrAssets[`pointers/${pointers[index]}/init.lua`] = hash;
|
||||
});
|
||||
return cb(null, files);
|
||||
})
|
||||
@@ -694,10 +774,12 @@ define([
|
||||
};
|
||||
|
||||
// Get input data arguments
|
||||
content.inputs = inputs;
|
||||
content.inputs = inputs
|
||||
.map(pair => [pair[0], !this.core.getAttribute(pair[2], 'data')]); // remove empty inputs
|
||||
|
||||
// Defined variables for each pointers
|
||||
content.pointers = pointers;
|
||||
content.pointers = pointers
|
||||
.map(id => [id, this.core.getPointerPath(node, id) === null]);
|
||||
|
||||
// Add remaining code
|
||||
content.code = code;
|
||||
@@ -745,7 +827,11 @@ define([
|
||||
return this[type](node);
|
||||
};
|
||||
|
||||
_.extend(ExecutePipeline.prototype, LocalExecutor.prototype);
|
||||
_.extend(
|
||||
ExecutePipeline.prototype,
|
||||
LocalExecutor.prototype,
|
||||
PtrCodeGen.prototype
|
||||
);
|
||||
|
||||
return ExecutePipeline;
|
||||
});
|
||||
|
||||
@@ -9,9 +9,24 @@ define([
|
||||
};
|
||||
|
||||
// Should these be in lua?
|
||||
LocalExecutor.prototype.BlobLoader = function(node) {
|
||||
var hash = this.core.getAttribute(node, 'data');
|
||||
return this.getOutputs(node)
|
||||
LocalExecutor.prototype.ArtifactLoader = function(node) {
|
||||
// Get the hash from the output node
|
||||
var hash;
|
||||
return this.core.loadChildren(node)
|
||||
.then(cntrs => {
|
||||
// Get the output container and load it's children
|
||||
var output = cntrs
|
||||
.find(cntr => {
|
||||
var metaNode = this.core.getMetaType(cntr),
|
||||
metaName = this.core.getAttribute(metaNode, 'name');
|
||||
return metaName === 'Outputs';
|
||||
});
|
||||
return this.core.loadChildren(output);
|
||||
})
|
||||
.then(dataNodes => {
|
||||
hash = this.core.getAttribute(dataNodes[0], 'data');
|
||||
return this.getOutputs(node);
|
||||
})
|
||||
.then(outputTuples => {
|
||||
var outputs = outputTuples.map(tuple => tuple[2]),
|
||||
paths;
|
||||
@@ -21,12 +36,52 @@ define([
|
||||
this.logger.info(`Loading blob data (${hash}) to ${paths.map(p => `"${p}"`)}`);
|
||||
outputs.forEach(output => this.core.setAttribute(output, 'data', hash));
|
||||
|
||||
// Set the metadata as appropriate
|
||||
// TODO
|
||||
this.onOperationComplete(node);
|
||||
});
|
||||
};
|
||||
|
||||
LocalExecutor.prototype.ArtifactFinder = function(node) {
|
||||
// Check the save dir for a node with the given name
|
||||
// that has the given type
|
||||
var hash,
|
||||
typeId = this.core.getPointerPath(node, 'type'),
|
||||
type,
|
||||
artifactName = this.core.getAttribute(node, 'artifactName');
|
||||
|
||||
return this.core.loadByPath(this.rootNode, typeId)
|
||||
.then(_type => {
|
||||
type = _type;
|
||||
return this._getSaveDir();
|
||||
})
|
||||
.then(saveDir => this.core.loadChildren(saveDir))
|
||||
.then(artifacts => {
|
||||
return artifacts.find(artifact =>
|
||||
this.core.getAttribute(artifact, 'name') === artifactName &&
|
||||
this.isMetaTypeOf(artifact, type));
|
||||
})
|
||||
.then(matchingArtifact => {
|
||||
hash = matchingArtifact && this.core.getAttribute(matchingArtifact, 'data');
|
||||
// If no hash, just
|
||||
if (!hash) {
|
||||
return this.onOperationComplete(node);
|
||||
} else {
|
||||
return this.getOutputs(node)
|
||||
.then(outputTuples => {
|
||||
var outputs = outputTuples.map(tuple => tuple[2]),
|
||||
paths;
|
||||
|
||||
paths = outputs.map(output => this.core.getPath(output));
|
||||
// Get the 'data' hash and store it in the output data ports
|
||||
this.logger.info(`Loading blob data (${hash}) to ${paths.map(p => `"${p}"`)}`);
|
||||
|
||||
outputs.forEach(output => this.core.setAttribute(output, 'data', hash));
|
||||
|
||||
this.onOperationComplete(node);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
LocalExecutor.prototype._getSaveDir = function () {
|
||||
return this.core.loadChildren(this.rootNode)
|
||||
.then(children => {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
require 'paths'
|
||||
|
||||
local path = 'inputs/<%= name %>/<%= filename %>'
|
||||
local abs_path = paths.concat('inputs', '<%= name %>', '<%= filename %>')
|
||||
|
||||
<%= code %>
|
||||
|
||||
@@ -11,7 +11,9 @@ define([
|
||||
DESERIALIZE
|
||||
) {
|
||||
|
||||
var BASH = 'th init.lua 2>&1';
|
||||
return {
|
||||
BASH,
|
||||
ENTRY,
|
||||
MAIN,
|
||||
SERIALIZE,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
-- input data
|
||||
<% inputs.forEach(function(pair) { var input = pair[0]%>
|
||||
<%= input %> = require './inputs/<%= input %>'
|
||||
<% }); %>
|
||||
-- load custom layers
|
||||
require './custom-layers'
|
||||
|
||||
-- load references
|
||||
<% pointers.forEach(function(pointer) { %><%= pointer %> = require './pointers/<%= pointer %>'
|
||||
<% }); %>
|
||||
-- input data<% inputs.forEach(function(pair) { var input = pair[0], isNil = pair[1];%>
|
||||
<%= isNil ? 'local ' : ''%><%= input %> = <% if (isNil) { %>nil<% } else { %>require './inputs/<%= input %>'<%}}); %>
|
||||
|
||||
-- load references<% pointers.forEach(function(pair) { var pointer = pair[0], isNil = pair[1];%>
|
||||
<%= isNil ? 'local ' : ''%><%= pointer %> = <% if (isNil) { %>nil<% } else { %>require './pointers/<%= pointer %>'<%}}); %>
|
||||
attributes = require './attributes'
|
||||
|
||||
-- main operation code for <%= name %>
|
||||
|
||||
@@ -29,6 +29,7 @@ define([
|
||||
* @classdesc This class represents the plugin GenerateArchitecture.
|
||||
* @constructor
|
||||
*/
|
||||
var INDEX = '__index__';
|
||||
var GenerateArchitecture = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
@@ -42,57 +43,166 @@ define([
|
||||
GenerateArchitecture.prototype.constructor = GenerateArchitecture;
|
||||
|
||||
GenerateArchitecture.prototype.main = function () {
|
||||
this.addCustomLayersToMeta();
|
||||
this.LayerDict = createLayerDict(this.core, this.META);
|
||||
this.uniqueId = 2;
|
||||
this._oldTemplateSettings = _.templateSettings;
|
||||
return PluginBase.prototype.main.apply(this, arguments);
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.addCustomLayersToMeta = function () {
|
||||
var metaDict = this.core.getAllMetaNodes(this.rootNode);
|
||||
|
||||
Object.keys(metaDict).map(id => metaDict[id])
|
||||
// Get all custom layers
|
||||
.filter(node => this.core.isTypeOf(node, this.META.Layer))
|
||||
// Add them to the meta
|
||||
.forEach(node => this.META[this.core.getAttribute(node, 'name')] = node);
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createOutputFiles = function (tree) {
|
||||
var layers = tree[Constants.CHILDREN],
|
||||
//initialLayers,
|
||||
result = {},
|
||||
template,
|
||||
snippet,
|
||||
code,
|
||||
args;
|
||||
code = 'require \'nn\'\n';
|
||||
|
||||
code = [
|
||||
'require \'nn\'',
|
||||
'',
|
||||
'local net = nn.Sequential()'
|
||||
].join('\n');
|
||||
//initialLayers = layers.filter(layer => layer[Constants.PREV].length === 0);
|
||||
// Add an index to each layer
|
||||
layers.forEach((l, index) => l[INDEX] = index);
|
||||
|
||||
// Start with sequential (just one input)
|
||||
for (var i = 0; i < layers.length; i++) {
|
||||
if (layers[i][Constants.NEXT].length > 1) {
|
||||
// no support for
|
||||
this.logger.error('No support for parallel layers... yet');
|
||||
break;
|
||||
} else {
|
||||
// args
|
||||
args = this.createArgString(layers[i]);
|
||||
template = _.template('net:add(nn.{{= name }}' + args + ')');
|
||||
snippet = template(layers[i]);
|
||||
code += '\n' + snippet;
|
||||
}
|
||||
// Define custom layers
|
||||
if (this.getCurrentConfig().standalone) {
|
||||
code += this.genLayerDefinitions(layers);
|
||||
}
|
||||
|
||||
code += '\n\nreturn net';
|
||||
code += this.genArchCode(layers);
|
||||
|
||||
result[tree.name + '.lua'] = code;
|
||||
_.templateSettings = this._oldTemplateSettings; // FIXME: Fix this in SimpleNodes
|
||||
return result;
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createArgString = function (layer) {
|
||||
return '(' + this.LayerDict[layer.name].map(arg => {
|
||||
var value = layer[arg.name];
|
||||
// Infer if value is unset and infer.dimensionality is set
|
||||
if (!value && arg.infer === 'dimensionality') {
|
||||
value = dimensionality(layer[Constants.PREV][0]);
|
||||
}
|
||||
return value;
|
||||
}).join(', ') + ')';
|
||||
GenerateArchitecture.prototype.genArchCode = function (layers) {
|
||||
return [
|
||||
this.createSequential(layers[0], 'net').code,
|
||||
'\nreturn net'
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createSequential = function (layer, name) {
|
||||
var next = layer[Constants.NEXT][0],
|
||||
args,
|
||||
template,
|
||||
snippet,
|
||||
snippets,
|
||||
code = `\nlocal ${name} = nn.Sequential()`,
|
||||
|
||||
group,
|
||||
i,
|
||||
result;
|
||||
|
||||
while (layer) {
|
||||
// if there is only one successor, just add the given layer
|
||||
if (layer[Constants.PREV].length > 1) { // sequential layers are over
|
||||
next = layer; // the given layer will be added by the caller
|
||||
break;
|
||||
} else { // add the given layer
|
||||
args = this.createArgString(layer);
|
||||
template = _.template(name + ':add(nn.{{= name }}' + args + ')');
|
||||
snippet = template(layer);
|
||||
code += '\n' + snippet;
|
||||
|
||||
}
|
||||
|
||||
while (layer && layer[Constants.NEXT].length > 1) { // concat/parallel
|
||||
// if there is a fork, recurse and add a concat layer
|
||||
|
||||
this.logger.debug(`detected fork of size ${layer[Constants.NEXT].length}`);
|
||||
snippets = layer[Constants.NEXT].map(nlayer =>
|
||||
this.createSequential(nlayer, 'net_'+(this.uniqueId++)));
|
||||
code += '\n' + snippets.map(snippet => snippet.code).join('\n');
|
||||
|
||||
// Make sure all snippets end at the same concat node
|
||||
|
||||
// Until all snippets end at the same concat node
|
||||
snippets.sort((a, b) => a.endIndex < b.endIndex ? -1 : 1);
|
||||
group = [];
|
||||
while (snippets.length > 0) {
|
||||
// Add snippets to the group
|
||||
i = 0;
|
||||
while (i < snippets.length &&
|
||||
snippets[0].endIndex === snippets[i].endIndex) {
|
||||
|
||||
group.push(snippets[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
// Add concat layer
|
||||
layer = group[0].next;
|
||||
if (layer) {
|
||||
args = this.createArgString(layer);
|
||||
code += `\n\nlocal concat_${layer[INDEX]} = nn.Concat${args}\n` +
|
||||
group.map(snippet =>
|
||||
`concat_${layer[INDEX]}:add(${snippet.name})`)
|
||||
.join('\n') + `\n\n${name}:add(concat_${layer[INDEX]})`;
|
||||
|
||||
next = layer[Constants.NEXT][0];
|
||||
} else {
|
||||
next = null; // no next layers
|
||||
}
|
||||
|
||||
// Remove the updated snippets
|
||||
this.logger.debug('removing ' + i + ' snippet(s)');
|
||||
snippets.splice(0, i);
|
||||
|
||||
// merge the elements in the group
|
||||
if (snippets.length) { // prepare next iteration
|
||||
result = this.createSequential(next, 'net_'+(this.uniqueId++));
|
||||
code += result.code;
|
||||
group = [result];
|
||||
this.logger.debug('updating group ('+ snippets.length+ ' left)');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layer = next;
|
||||
next = layer && layer[Constants.NEXT][0];
|
||||
}
|
||||
|
||||
return {
|
||||
code: code,
|
||||
name: name,
|
||||
endIndex: next ? next[INDEX] : Infinity,
|
||||
next: next
|
||||
};
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.createArgString = function (layer) {
|
||||
return '(' + this.LayerDict[layer.name]
|
||||
.map(arg => layer[arg.name])
|
||||
.filter(GenerateArchitecture.isSet)
|
||||
.join(', ') + ')';
|
||||
};
|
||||
|
||||
GenerateArchitecture.isSet = function (value) {
|
||||
return !(value === undefined || value === null || value === '');
|
||||
};
|
||||
|
||||
GenerateArchitecture.prototype.genLayerDefinitions = function(layers) {
|
||||
var code = '',
|
||||
customLayerId = this.core.getPath(this.META.CustomLayer),
|
||||
customLayers = layers.filter(layer => { // Get the custom layers
|
||||
var node = this.META[layer.name];
|
||||
return this.core.getMixinPaths(node).indexOf(customLayerId) !== -1;
|
||||
});
|
||||
|
||||
if (customLayers.length) {
|
||||
code += '\n-------------- Custom Layer Definitions --------------\n\n';
|
||||
code += customLayers.map(layer => layer.code).join('\n');
|
||||
code += '\n\n-------------- Network --------------\n';
|
||||
}
|
||||
|
||||
return code;
|
||||
};
|
||||
return GenerateArchitecture;
|
||||
});
|
||||
|
||||
@@ -9,5 +9,14 @@
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"configStructure": []
|
||||
"configStructure": [
|
||||
{
|
||||
"name": "standalone",
|
||||
"displayName": "Standalone",
|
||||
"description": "Prepend custom layer definitions",
|
||||
"value": false,
|
||||
"valueType": "boolean",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,344 @@
|
||||
/*globals define, _*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Sat Jun 04 2016 18:01:54 GMT-0500 (CDT).
|
||||
* A plugin that inherits from the PluginBase. To see source code documentation about available
|
||||
* properties and methods visit %host%/docs/source/PluginBase.html.
|
||||
*/
|
||||
|
||||
define([
|
||||
'text!./metadata.json',
|
||||
'plugin/PluginBase',
|
||||
'deepforge/plugin/PtrCodeGen',
|
||||
'q'
|
||||
], function (
|
||||
pluginMetadata,
|
||||
PluginBase,
|
||||
PtrCodeGen,
|
||||
Q
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
pluginMetadata = JSON.parse(pluginMetadata);
|
||||
var HEADER_LENGTH = 60;
|
||||
|
||||
/**
|
||||
* Initializes a new instance of GenerateExecFile.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin GenerateExecFile.
|
||||
* @constructor
|
||||
*/
|
||||
var GenerateExecFile = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = pluginMetadata;
|
||||
|
||||
this._srcIdFor = {}; // input path -> output data node path
|
||||
|
||||
this._nameFor = {}; // input path -> opname
|
||||
this._dataNameFor = {};
|
||||
this._opNames = {};
|
||||
|
||||
// topo sort stuff
|
||||
this._nextOps = {};
|
||||
this._incomingCnts = {};
|
||||
|
||||
this._operations = {};
|
||||
this.activeNodeId = null;
|
||||
this.activeNodeDepth = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
|
||||
* This is also available at the instance at this.pluginMetadata.
|
||||
* @type {object}
|
||||
*/
|
||||
GenerateExecFile.metadata = pluginMetadata;
|
||||
|
||||
// Prototypical inheritance from PluginBase.
|
||||
GenerateExecFile.prototype = Object.create(PluginBase.prototype);
|
||||
GenerateExecFile.prototype.constructor = GenerateExecFile;
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
GenerateExecFile.prototype.main = function (callback) {
|
||||
// Get all the children and call generate exec file
|
||||
this.activeNodeId = this.core.getPath(this.activeNode);
|
||||
this.activeNodeDepth = this.activeNodeId.split('/').length + 1;
|
||||
|
||||
if (this.isMetaTypeOf(this.activeNode, this.META.Execution)) {
|
||||
this.activeNodeDepth++;
|
||||
}
|
||||
|
||||
return this.core.loadChildren(this.activeNode)
|
||||
.then(nodes => this.createExecFile(nodes))
|
||||
.then(code => this.blobClient.putFile('init.lua', code))
|
||||
.then(hash => {
|
||||
this.result.addArtifact(hash);
|
||||
this.result.setSuccess(true);
|
||||
callback(null, this.result);
|
||||
})
|
||||
.fail(err => callback(err));
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.createExecFile = function (children) {
|
||||
// Convert opNodes' jobs to the nested operations
|
||||
var opNodes,
|
||||
nodes;
|
||||
|
||||
return this.unpackJobs(children)
|
||||
.then(_nodes => {
|
||||
nodes = _nodes;
|
||||
opNodes = nodes
|
||||
.filter(node => this.isMetaTypeOf(node, this.META.Operation));
|
||||
return Q.all(nodes.map(node => this.registerNameAndData(node)));
|
||||
})
|
||||
.then(() => Q.all(opNodes.map(node => this.createOperation(node))))
|
||||
.then(operations => {
|
||||
var nextIds = opNodes.map(n => this.core.getPath(n))
|
||||
.filter(id => !this._incomingCnts[id]);
|
||||
|
||||
operations.forEach(op => this._operations[op.id] = op);
|
||||
|
||||
// Toposort and concat!
|
||||
return this.combineOpNodes(nextIds);
|
||||
})
|
||||
.fail(err => this.logger.error(err));
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.unpackJobs = function (nodes) {
|
||||
return Q.all(
|
||||
nodes.map(node => {
|
||||
if (!this.isMetaTypeOf(node, this.META.Job)) {
|
||||
return node;
|
||||
}
|
||||
return this.core.loadChildren(node)
|
||||
.then(children =>
|
||||
children.find(c => this.isMetaTypeOf(c, this.META.Operation))
|
||||
);
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.combineOpNodes = function (opIds) {
|
||||
var nextIds = [],
|
||||
dstIds,
|
||||
code,
|
||||
id;
|
||||
|
||||
// Combine all nodes with incoming cnts of 0
|
||||
code = opIds.map(id => this._operations[id].code).join('\n');
|
||||
|
||||
// Decrement all next ops
|
||||
dstIds = opIds.map(id => this._nextOps[id])
|
||||
.reduce((l1, l2) => l1.concat(l2), []);
|
||||
for (var i = dstIds.length; i--;) {
|
||||
id = dstIds[i];
|
||||
if (--this._incomingCnts[id] === 0) {
|
||||
nextIds.push(id);
|
||||
}
|
||||
}
|
||||
|
||||
// append
|
||||
return [
|
||||
code,
|
||||
nextIds.length ? this.combineOpNodes(nextIds) : ''
|
||||
].join('\n');
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.registerNameAndData = function (node) {
|
||||
var name = this.core.getAttribute(node, 'name'),
|
||||
id = this.core.getPath(node),
|
||||
basename = name,
|
||||
i = 2;
|
||||
|
||||
if (this.isMetaTypeOf(node, this.META.Operation)) {
|
||||
|
||||
// Get a unique operation name
|
||||
while (this._opNames[name]) {
|
||||
name = basename + '_' + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
// register the unique name
|
||||
this._opNames[name] = true;
|
||||
this._nameFor[id] = name;
|
||||
|
||||
// For operations, register all output data node names by path
|
||||
return this.core.loadChildren(node)
|
||||
.then(cntrs => {
|
||||
var cntr = cntrs.find(n => this.isMetaTypeOf(n, this.META.Outputs));
|
||||
return this.core.loadChildren(cntr);
|
||||
})
|
||||
.then(outputs => {
|
||||
outputs.forEach(output => {
|
||||
var dataId = this.core.getPath(output);
|
||||
|
||||
name = this.core.getAttribute(output, 'name');
|
||||
this._dataNameFor[dataId] = name;
|
||||
});
|
||||
});
|
||||
|
||||
// For each input data node, register the associated output id
|
||||
} else if (this.isMetaTypeOf(node, this.META.Transporter)) {
|
||||
var outputData = this.core.getPointerPath(node, 'src'),
|
||||
inputData = this.core.getPointerPath(node, 'dst'),
|
||||
srcOpId = this.getOpIdFor(outputData),
|
||||
dstOpId = this.getOpIdFor(inputData);
|
||||
|
||||
this._srcIdFor[inputData] = outputData;
|
||||
|
||||
// Store the next operation ids for the op id
|
||||
if (!this._nextOps[srcOpId]) {
|
||||
this._nextOps[srcOpId] = [];
|
||||
}
|
||||
this._nextOps[srcOpId].push(dstOpId);
|
||||
|
||||
// Increment the incoming counts for each dst op
|
||||
this._incomingCnts[dstOpId] = this._incomingCnts[dstOpId] || 0;
|
||||
this._incomingCnts[dstOpId]++;
|
||||
}
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.getOpIdFor = function (dataId) {
|
||||
var ids = dataId.split('/'),
|
||||
depth = ids.length;
|
||||
|
||||
ids.splice(this.activeNodeDepth - depth);
|
||||
return ids.join('/');
|
||||
};
|
||||
|
||||
// For each operation...
|
||||
// - unpack the inputs from prev ops
|
||||
// - add the attributes table (if used)
|
||||
// - check for '\<attributes\>' in code
|
||||
// - add the references
|
||||
// - generate the code
|
||||
// - replace the `return <thing>` w/ `<ref-name> = <thing>`
|
||||
GenerateExecFile.prototype.createOperation = function (node) {
|
||||
var id = this.core.getPath(node),
|
||||
operation = {};
|
||||
|
||||
operation.name = this._nameFor[id];
|
||||
operation.id = id;
|
||||
operation.code = this.core.getAttribute(node, 'code');
|
||||
|
||||
// Update the 'code' attribute
|
||||
// Change the last return statement to assign the results to a table
|
||||
operation.code = this.assignResultToVar(operation.code,
|
||||
`${operation.name}_results`);
|
||||
|
||||
// Get all the input names (and sources)
|
||||
return this.core.loadChildren(node)
|
||||
.then(containers => {
|
||||
var inputs;
|
||||
|
||||
inputs = containers
|
||||
.find(cntr => this.isMetaTypeOf(cntr, this.META.Inputs));
|
||||
|
||||
this.logger.info(`${name} has ${containers.length} cntrs`);
|
||||
return this.core.loadChildren(inputs);
|
||||
})
|
||||
.then(data => {
|
||||
// Get the input names and sources
|
||||
var inputNames = data.map(d => this.core.getAttribute(d, 'name')),
|
||||
ids = data.map(d => this.core.getPath(d)),
|
||||
srcIds = ids.map(id => this._srcIdFor[id]);
|
||||
|
||||
operation.inputs = inputNames.map((name, i) => {
|
||||
var id = srcIds[i],
|
||||
srcDataName = this._dataNameFor[id],
|
||||
srcOpId = this.getOpIdFor(id),
|
||||
srcOpName = this._nameFor[srcOpId];
|
||||
|
||||
return `local ${name} = ${srcOpName}_results.${srcDataName}`;
|
||||
});
|
||||
|
||||
return operation;
|
||||
|
||||
})
|
||||
.then(operation => {
|
||||
|
||||
// For each reference, run the plugin and retrieve the generated code
|
||||
operation.refNames = this.core.getPointerNames(node)
|
||||
.filter(name => name !== 'base');
|
||||
|
||||
var refs = operation.refNames
|
||||
.map(ref => [ref, this.core.getPointerPath(node, ref)]);
|
||||
|
||||
return Q.all(
|
||||
refs.map(pair => this.genPtrSnippet.apply(this, pair))
|
||||
);
|
||||
})
|
||||
.then(codeFiles => {
|
||||
operation.refs = codeFiles;
|
||||
this.genOperationCode(operation);
|
||||
return operation;
|
||||
});
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.genPtrSnippet = function (ptrName, pId) {
|
||||
return this.getPtrCodeHash(pId)
|
||||
.then(hash => this.blobClient.getObjectAsString(hash))
|
||||
.then(code => this.createHeader(`creating ${ptrName}`, 40) + '\n' +
|
||||
this.assignResultToVar(code, ptrName));
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.createHeader = function (title, length) {
|
||||
var len;
|
||||
title = ` ${title} `;
|
||||
length = length || HEADER_LENGTH;
|
||||
|
||||
len = Math.max(
|
||||
Math.floor((length - title.length)/2),
|
||||
2
|
||||
);
|
||||
|
||||
return [
|
||||
'',
|
||||
title,
|
||||
''
|
||||
].join(new Array(len+1).join('-')) + '\n';
|
||||
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.genOperationCode = function (operation) {
|
||||
var header = this.createHeader(`"${operation.name}" Operation`),
|
||||
codeParts = [];
|
||||
|
||||
codeParts.push(header);
|
||||
|
||||
if (operation.inputs.length) {
|
||||
codeParts.push(operation.inputs.join('\n'));
|
||||
}
|
||||
|
||||
if (operation.refs.length) {
|
||||
codeParts.push(operation.refs.join('\n'));
|
||||
}
|
||||
|
||||
codeParts.push(operation.code);
|
||||
codeParts.push('');
|
||||
operation.code = codeParts.join('\n');
|
||||
return operation;
|
||||
};
|
||||
|
||||
GenerateExecFile.prototype.assignResultToVar = function (code, name) {
|
||||
var i = code.lastIndexOf('return');
|
||||
return code.substring(0, i) +
|
||||
code.substring(i)
|
||||
.replace('return', `local ${name} = `);
|
||||
};
|
||||
|
||||
_.extend(GenerateExecFile.prototype, PtrCodeGen.prototype);
|
||||
|
||||
return GenerateExecFile;
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"id": "GenerateExecFile",
|
||||
"name": "Generate Execution File",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"icon": {
|
||||
"class": "glyphicon glyphicon-cog",
|
||||
"src": ""
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"writeAccessRequired": false,
|
||||
"configStructure": []
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*globals define*/
|
||||
/*jshint node:true, browser:true*/
|
||||
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Tue Jun 07 2016 11:25:09 GMT-0500 (CDT).
|
||||
* A plugin that inherits from the PluginBase. To see source code documentation about available
|
||||
* properties and methods visit %host%/docs/source/PluginBase.html.
|
||||
*/
|
||||
|
||||
define([
|
||||
'text!./metadata.json',
|
||||
'plugin/PluginBase',
|
||||
'q'
|
||||
], function (
|
||||
pluginMetadata,
|
||||
PluginBase,
|
||||
Q
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
pluginMetadata = JSON.parse(pluginMetadata);
|
||||
|
||||
/**
|
||||
* Initializes a new instance of ImportArtifact.
|
||||
* @class
|
||||
* @augments {PluginBase}
|
||||
* @classdesc This class represents the plugin ImportArtifact.
|
||||
* @constructor
|
||||
*/
|
||||
var ImportArtifact = function () {
|
||||
// Call base class' constructor.
|
||||
PluginBase.call(this);
|
||||
this.pluginMetadata = pluginMetadata;
|
||||
};
|
||||
|
||||
/**
|
||||
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
|
||||
* This is also available at the instance at this.pluginMetadata.
|
||||
* @type {object}
|
||||
*/
|
||||
ImportArtifact.metadata = pluginMetadata;
|
||||
|
||||
// Prototypical inheritance from PluginBase.
|
||||
ImportArtifact.prototype = Object.create(PluginBase.prototype);
|
||||
ImportArtifact.prototype.constructor = ImportArtifact;
|
||||
|
||||
/**
|
||||
* Main function for the plugin to execute. This will perform the execution.
|
||||
* Notes:
|
||||
* - Always log with the provided logger.[error,warning,info,debug].
|
||||
* - Do NOT put any user interaction logic UI, etc. inside this method.
|
||||
* - callback always has to be called even if error happened.
|
||||
*
|
||||
* @param {function(string, plugin.PluginResult)} callback - the result callback
|
||||
*/
|
||||
ImportArtifact.prototype.main = function (callback) {
|
||||
var self = this,
|
||||
config = this.getCurrentConfig(),
|
||||
hash = config.dataHash,
|
||||
baseName = config.dataTypeId,
|
||||
name,
|
||||
baseType,
|
||||
dataNode,
|
||||
|
||||
metaDict,
|
||||
metanodes;
|
||||
|
||||
// Create node of type "typeId" in the activeNode and set the hash, name
|
||||
metaDict = this.core.getAllMetaNodes(this.activeNode);
|
||||
metanodes = Object.keys(metaDict).map(id => metaDict[id]);
|
||||
baseType = metanodes.find(node =>
|
||||
this.core.getAttribute(node, 'name') === baseName
|
||||
);
|
||||
|
||||
if (!baseType) {
|
||||
callback(`Could not find data type "${baseName}"`, this.result);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the base node
|
||||
dataNode = this.core.createNode({
|
||||
base: baseType,
|
||||
parent: this.activeNode
|
||||
});
|
||||
|
||||
this.core.setAttribute(dataNode, 'data', hash);
|
||||
baseName = this.core.getAttribute(baseType, 'name');
|
||||
|
||||
var getName;
|
||||
if (config.name) {
|
||||
getName = Q().then(() => config.name);
|
||||
} else {
|
||||
getName = this.blobClient.getMetadata(hash)
|
||||
.then(md => {
|
||||
name = baseName[0].toLowerCase() + baseName.substring(1);
|
||||
if (md) {
|
||||
name = md.name.replace(/\.[^\.]*?$/, '');
|
||||
}
|
||||
return name;
|
||||
});
|
||||
}
|
||||
|
||||
getName.then(name => this.core.setAttribute(dataNode, 'name', name))
|
||||
.then(() => this.save(`Uploaded "${name}" data`))
|
||||
.then(function () {
|
||||
self.result.setSuccess(true);
|
||||
callback(null, self.result);
|
||||
})
|
||||
.fail(function (err) {
|
||||
callback(err, self.result);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
return ImportArtifact;
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"id": "ImportArtifact",
|
||||
"name": "ImportArtifact",
|
||||
"version": "0.1.0",
|
||||
"description": "",
|
||||
"icon": {
|
||||
"class": "glyphicon glyphicon-cog",
|
||||
"src": ""
|
||||
},
|
||||
"disableServerSideExecution": false,
|
||||
"disableBrowserSideExecution": false,
|
||||
"writeAccessRequired": true,
|
||||
"configStructure": [
|
||||
{
|
||||
"name": "name",
|
||||
"displayName": "Data name",
|
||||
"description": "Optional name for artifact",
|
||||
"value": "",
|
||||
"valueType": "string",
|
||||
"readOnly": false
|
||||
},
|
||||
{
|
||||
"name": "dataHash",
|
||||
"displayName": "Data to upload",
|
||||
"description": "",
|
||||
"value": "",
|
||||
"valueType": "asset",
|
||||
"readOnly": false
|
||||
}
|
||||
]
|
||||
}
|
||||
Arquivo binário não exibido.
@@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0f7228f775590d69e1215d25afc299809755a6e820fbd5cfdcd1e9bb3abdaf3a
|
||||
size 23753
|
||||
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -5,24 +5,12 @@
|
||||
"panel": "panels/AutoViz/AutoVizPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "EasyDAG",
|
||||
"title": "EasyDAG",
|
||||
"panel": "panels/EasyDAG/EasyDAGPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "ArchEditor",
|
||||
"title": "ArchEditor",
|
||||
"panel": "panels/ArchEditor/ArchEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "TextEditor",
|
||||
"title": "TextEditor",
|
||||
"panel": "panels/TextEditor/TextEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "OperationEditor",
|
||||
"title": "OperationEditor",
|
||||
@@ -82,5 +70,23 @@
|
||||
"title": "DeserializeEditor",
|
||||
"panel": "panels/DeserializeEditor/DeserializeEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "Footer",
|
||||
"title": "Footer",
|
||||
"panel": "panels/Footer/FooterPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "LogViewer",
|
||||
"title": "LogViewer",
|
||||
"panel": "panels/LogViewer/LogViewerPanel",
|
||||
"DEBUG_ONLY": false
|
||||
},
|
||||
{
|
||||
"id": "LayerEditor",
|
||||
"title": "LayerEditor",
|
||||
"panel": "panels/LayerEditor/LayerEditorPanel",
|
||||
"DEBUG_ONLY": false
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
@@ -23,12 +23,10 @@ define([
|
||||
DefaultColor: '#ffb74d',
|
||||
LayerColors: {
|
||||
Containers: '#ffb74d',
|
||||
Module: '#ba68c8',
|
||||
ConvLayer: '#2196f3',
|
||||
SimpleLayer: '#ff9100',
|
||||
TransferLayer: '#80deea',
|
||||
MiscLayers: '#ce93d8',
|
||||
Criterion: '#7e57c2'
|
||||
Convolution: '#2196f3',
|
||||
Simple: '#ff9100',
|
||||
Transfer: '#80deea',
|
||||
Misc: '#ce93d8'
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*globals define, _, WebGMEGlobal, $ */
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* @author rkereskenyi / https://github.com/rkereskenyi
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBase',
|
||||
'js/Widgets/NetworkStatus/NetworkStatusWidget',
|
||||
'js/Widgets/BranchStatus/BranchStatusWidget',
|
||||
'js/Widgets/BranchSelector/BranchSelectorWidget',
|
||||
'js/Widgets/KeyboardManager/KeyboardManagerWidget',
|
||||
'js/Widgets/Notification/NotificationWidget'
|
||||
], function (PanelBase,
|
||||
NetworkStatusWidget,
|
||||
BranchStatusWidget,
|
||||
BranchSelectorWidget,
|
||||
KeyboardManagerWidget,
|
||||
NotificationWidget) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var FooterPanel,
|
||||
__parent__ = PanelBase;
|
||||
|
||||
FooterPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBase.OPTIONS.LOGGER_INSTANCE_NAME] = 'FooterPanel';
|
||||
|
||||
//call parent's constructor
|
||||
__parent__.apply(this, [options]);
|
||||
|
||||
this._client = params.client;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('FooterPanel ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(FooterPanel.prototype, __parent__.prototype);
|
||||
|
||||
FooterPanel.prototype._initialize = function () {
|
||||
//main container
|
||||
var navBar = $('<div/>', {class: 'navbar navbar-inverse navbar-fixed-bottom'}),
|
||||
navBarInner = $('<div/>', {class: 'navbar-inner'}),
|
||||
separator = $('<div class="spacer pull-right"></div>'),
|
||||
widgetPlaceHolder = $('<div class="pull-right"></div>'),
|
||||
keyBoardManagerEl,
|
||||
networkStatusEl,
|
||||
branchStatusEl,
|
||||
notificationEl;
|
||||
|
||||
navBar.append(navBarInner);
|
||||
this.$el.append(navBar);
|
||||
|
||||
//padding from screen right edge
|
||||
navBarInner.append(separator.clone());
|
||||
|
||||
//keyboard enable/disbale widget (NOTE: only on non touch device)
|
||||
if (WebGMEGlobal.SUPPORTS_TOUCH !== true) {
|
||||
keyBoardManagerEl = widgetPlaceHolder.clone();
|
||||
new KeyboardManagerWidget(keyBoardManagerEl);
|
||||
navBarInner.append(keyBoardManagerEl).append(separator.clone());
|
||||
}
|
||||
|
||||
networkStatusEl = widgetPlaceHolder.clone();
|
||||
new NetworkStatusWidget(networkStatusEl, this._client);
|
||||
navBarInner.append(networkStatusEl).append(separator.clone());
|
||||
|
||||
notificationEl = widgetPlaceHolder.clone();
|
||||
new NotificationWidget(notificationEl, this._client);
|
||||
navBarInner.append(notificationEl).append(separator.clone());
|
||||
|
||||
branchStatusEl = widgetPlaceHolder.clone();
|
||||
new BranchStatusWidget(branchStatusEl, this._client);
|
||||
navBarInner.append(branchStatusEl).append(separator.clone());
|
||||
};
|
||||
|
||||
return FooterPanel;
|
||||
});
|
||||
@@ -1,14 +1,10 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
/*globals define, Materialize, WebGMEGlobal*/
|
||||
// These are actions defined for specific meta types. They are evaluated from
|
||||
// the context of the ForgeActionButton
|
||||
define([
|
||||
'js/RegistryKeys',
|
||||
'js/Panels/MetaEditor/MetaEditorConstants',
|
||||
'js/Constants'
|
||||
'js/RegistryKeys'
|
||||
], function(
|
||||
REGISTRY_KEYS,
|
||||
META_CONSTANTS,
|
||||
CONSTANTS
|
||||
REGISTRY_KEYS
|
||||
) {
|
||||
var instances = [
|
||||
'Architecture',
|
||||
@@ -20,88 +16,29 @@ define([
|
||||
],
|
||||
create = {};
|
||||
|
||||
var getUniqueName = function(parentId, basename) {
|
||||
var pNode = this.client.getNode(parentId),
|
||||
children = pNode.getChildrenIds().map(id => this.client.getNode(id)),
|
||||
name = basename,
|
||||
exists = {},
|
||||
i = 2;
|
||||
|
||||
children.forEach(child => exists[child.getAttribute('name')] = true);
|
||||
|
||||
while (exists[name]) {
|
||||
name = basename + '_' + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
var createNew = function(type, metasheetName) {
|
||||
// Create CNN node in the current dir
|
||||
// Get CNN node type
|
||||
var parentId = this._currentNodeId,
|
||||
newId,
|
||||
baseId;
|
||||
var newId,
|
||||
baseId,
|
||||
msg = `Created new ${type + (metasheetName ? ' prototype' : '')}`;
|
||||
|
||||
baseId = this.client.getAllMetaNodes()
|
||||
.find(node => node.getAttribute('name') === type)
|
||||
.getId();
|
||||
|
||||
this.client.startTransaction('Created new operation prototype');
|
||||
newId = this.client.createChild({parentId, baseId});
|
||||
this.client.startTransaction(msg);
|
||||
newId = this.createNamedNode(baseId, !!metasheetName);
|
||||
|
||||
// Name the new node
|
||||
var basename = 'New' + this.client.getNode(baseId).getAttribute('name'),
|
||||
newName = getUniqueName.call(this, parentId, basename);
|
||||
|
||||
// If instance, make the first char lowercase
|
||||
if (!metasheetName) {
|
||||
newName = newName.substring(0, 1).toLowerCase() + newName.substring(1);
|
||||
if (metasheetName) {
|
||||
this.addToMetaSheet(newId, metasheetName);
|
||||
}
|
||||
|
||||
this.client.setAttributes(newId, 'name', newName);
|
||||
if (metasheetName) { // Add to metasheet
|
||||
var root = this.client.getNode(CONSTANTS.PROJECT_ROOT_ID),
|
||||
metatabs = root.getRegistry(REGISTRY_KEYS.META_SHEETS),
|
||||
metatab = metatabs.find(tab => tab.title === metasheetName) || metatabs[0],
|
||||
metatabId = metatab.SetID;
|
||||
|
||||
// Add to the general meta
|
||||
this.client.addMember(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
newId,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME
|
||||
);
|
||||
this.client.setMemberRegistry(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
newId,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
{
|
||||
x: 100,
|
||||
y: 100
|
||||
}
|
||||
);
|
||||
|
||||
// Add to the specific sheet
|
||||
this.client.addMember(CONSTANTS.PROJECT_ROOT_ID, newId, metatabId);
|
||||
this.client.setMemberRegistry(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
newId,
|
||||
metatabId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
{
|
||||
x: 100,
|
||||
y: 100
|
||||
}
|
||||
);
|
||||
}
|
||||
this.client.completeTransaction();
|
||||
|
||||
WebGMEGlobal.State.registerActiveObject(newId);
|
||||
return newId;
|
||||
};
|
||||
|
||||
|
||||
instances.forEach(type => {
|
||||
create[type] = function() {
|
||||
return createNew.call(this, type);
|
||||
@@ -114,11 +51,55 @@ define([
|
||||
};
|
||||
});
|
||||
|
||||
var createLayer = function() {
|
||||
// Prompt the base type
|
||||
this.promptLayerType().then(selected => {
|
||||
var baseId = selected.node.id,
|
||||
typeName = this.client.getNode(baseId).getAttribute('name'),
|
||||
metanodes = this.client.getAllMetaNodes(),
|
||||
msg = `Created new custom ${typeName} layer`,
|
||||
newId,
|
||||
customLayerId,
|
||||
name;
|
||||
|
||||
for (var i = metanodes.length; i--;) {
|
||||
name = metanodes[i].getAttribute('name');
|
||||
if (name === 'CustomLayer') {
|
||||
customLayerId = metanodes[i].getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.client.startTransaction(msg);
|
||||
|
||||
newId = this.createNamedNode(baseId, true);
|
||||
this.addToMetaSheet(newId, 'CustomLayers');
|
||||
this.client.addMixin(newId, customLayerId);
|
||||
this.client.setRegistry(newId, REGISTRY_KEYS.IS_ABSTRACT, false);
|
||||
|
||||
this.client.completeTransaction();
|
||||
|
||||
WebGMEGlobal.State.registerActiveObject(newId);
|
||||
});
|
||||
};
|
||||
////////////// Downloading files //////////////
|
||||
var downloadAttrs = [
|
||||
'data',
|
||||
'execFiles'
|
||||
],
|
||||
download = {};
|
||||
|
||||
downloadAttrs.forEach(attr => {
|
||||
download[attr] = function() {
|
||||
return downloadButton.call(this, attr);
|
||||
};
|
||||
});
|
||||
|
||||
// Add download model button
|
||||
var downloadButton = function() {
|
||||
var downloadButton = function(attr) {
|
||||
var id = this._currentNodeId,
|
||||
node = this.client.getNode(id),
|
||||
hash = node.getAttribute('data');
|
||||
hash = node.getAttribute(attr);
|
||||
|
||||
if (hash) {
|
||||
return '/rest/blob/download/' + hash;
|
||||
@@ -126,15 +107,62 @@ define([
|
||||
return null;
|
||||
};
|
||||
|
||||
return {
|
||||
Data: [
|
||||
{
|
||||
name: 'Download',
|
||||
icon: 'play_for_work',
|
||||
href: downloadButton // function to create href url
|
||||
}
|
||||
],
|
||||
var UPLOAD_PLUGIN = 'ImportArtifact',
|
||||
DATA_TYPE_CONFIG = {
|
||||
name: 'dataTypeId',
|
||||
displayName: 'Data Type Id',
|
||||
valueType: 'string',
|
||||
valueItems: []
|
||||
};
|
||||
var uploadArtifact = function() {
|
||||
// Get the data types
|
||||
var dataBase,
|
||||
dataBaseId,
|
||||
metanodes = this.client.getAllMetaNodes(),
|
||||
dataTypes = []; // TODO
|
||||
|
||||
dataBase = metanodes.find(n => n.getAttribute('name') === 'Data');
|
||||
|
||||
if (!dataBase) {
|
||||
this.logger.error('Could not find the base Data node!');
|
||||
return;
|
||||
}
|
||||
|
||||
dataBaseId = dataBase.getId();
|
||||
dataTypes = metanodes.filter(n => this.client.isTypeOf(n.getId(), dataBaseId))
|
||||
.map(node => node.getAttribute('name'));
|
||||
|
||||
this.logger.info(`Found ${dataTypes.length} data types`);
|
||||
|
||||
// Add the target type to the pluginMetadata... hacky :/
|
||||
// FIXME: this should create it's own plugin dialog which allows
|
||||
// users to select the data type
|
||||
var metadata = WebGMEGlobal.allPluginsMetadata[UPLOAD_PLUGIN],
|
||||
config = metadata.configStructure
|
||||
.find(opt => opt.name === DATA_TYPE_CONFIG.name);
|
||||
|
||||
if (!config) {
|
||||
config = DATA_TYPE_CONFIG;
|
||||
WebGMEGlobal.allPluginsMetadata[UPLOAD_PLUGIN].configStructure.push(config);
|
||||
}
|
||||
|
||||
config.valueItems = dataTypes;
|
||||
config.value = dataTypes[0];
|
||||
|
||||
WebGMEGlobal.InterpreterManager.configureAndRun(metadata, (result) => {
|
||||
if (!result) {
|
||||
Materialize.toast('Artifact upload failed!', 2000);
|
||||
return;
|
||||
}
|
||||
this.logger.info('Finished uploading ' + UPLOAD_PLUGIN);
|
||||
Materialize.toast('Artifact upload complete!', 2000);
|
||||
});
|
||||
};
|
||||
|
||||
var returnToLastPipeline = () =>
|
||||
WebGMEGlobal.State.registerActiveObject(window.DeepForge.lastPipeline);
|
||||
return {
|
||||
// Meta nodes
|
||||
MyPipelines_META: [
|
||||
{
|
||||
name: 'Create new pipeline',
|
||||
@@ -156,6 +184,13 @@ define([
|
||||
action: create.Data
|
||||
}
|
||||
],
|
||||
MyLayers_META: [
|
||||
{
|
||||
name: 'Create new layer',
|
||||
icon: 'queue',
|
||||
action: createLayer
|
||||
}
|
||||
],
|
||||
MyOperations_META: [
|
||||
{
|
||||
name: 'Create new operation',
|
||||
@@ -163,6 +198,37 @@ define([
|
||||
action: create.Operation
|
||||
}
|
||||
],
|
||||
MyArtifacts_META: [
|
||||
{
|
||||
name: 'Upload artifact',
|
||||
icon: 'swap_vert',
|
||||
action: uploadArtifact
|
||||
}
|
||||
],
|
||||
Operation_META: [
|
||||
{
|
||||
name: 'Return to Pipeline',
|
||||
icon: 'input',
|
||||
filter: () => window.DeepForge && window.DeepForge.lastPipeline,
|
||||
action: returnToLastPipeline
|
||||
}
|
||||
],
|
||||
|
||||
// Instances
|
||||
Data: [
|
||||
{
|
||||
name: 'Download',
|
||||
icon: 'play_for_work',
|
||||
href: download.data // function to create href url
|
||||
}
|
||||
],
|
||||
Job: [
|
||||
{
|
||||
name: 'Download Execution Files',
|
||||
icon: 'play_for_work',
|
||||
href: download.execFiles
|
||||
}
|
||||
],
|
||||
Pipeline: [
|
||||
{
|
||||
name: 'Create new node',
|
||||
|
||||
@@ -6,12 +6,20 @@ define([
|
||||
'panel/FloatingActionButton/FloatingActionButton',
|
||||
'deepforge/viz/PipelineControl',
|
||||
'./Actions',
|
||||
'widgets/EasyDAG/AddNodeDialog',
|
||||
'js/RegistryKeys',
|
||||
'js/Panels/MetaEditor/MetaEditorConstants',
|
||||
'q',
|
||||
'text!./PluginConfig.json'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
PluginButton,
|
||||
PipelineControl,
|
||||
ACTIONS,
|
||||
AddNodeDialog,
|
||||
REGISTRY_KEYS,
|
||||
META_CONSTANTS,
|
||||
Q,
|
||||
PluginConfig
|
||||
) {
|
||||
'use strict';
|
||||
@@ -37,14 +45,19 @@ define([
|
||||
base = this.client.getNode(node.getMetaTypeId()),
|
||||
isMeta = base && base.getId() === node.getId(),
|
||||
suffix = isMeta ? '_META' : '',
|
||||
actions,
|
||||
basename;
|
||||
|
||||
while (base && !ACTIONS[basename]) {
|
||||
while (base && !(actions && actions.length)) {
|
||||
basename = base.getAttribute('name') + suffix;
|
||||
base = this.client.getNode(base.getBaseId());
|
||||
actions = ACTIONS[basename];
|
||||
if (actions) {
|
||||
actions = actions.filter(action => !action.filter || action.filter());
|
||||
}
|
||||
}
|
||||
|
||||
return ACTIONS[basename] || [];
|
||||
return actions || [];
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.onNodeLoad = function(nodeId) {
|
||||
@@ -70,5 +83,121 @@ define([
|
||||
this.update();
|
||||
};
|
||||
|
||||
// Helper functions
|
||||
ForgeActionButton.prototype.addToMetaSheet = function(nodeId, metasheetName) {
|
||||
var root = this.client.getNode(CONSTANTS.PROJECT_ROOT_ID),
|
||||
metatabs = root.getRegistry(REGISTRY_KEYS.META_SHEETS),
|
||||
metatab = metatabs.find(tab => tab.title === metasheetName) || metatabs[0],
|
||||
metatabId = metatab.SetID;
|
||||
|
||||
// Add to the general meta
|
||||
this.client.addMember(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
nodeId,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME
|
||||
);
|
||||
this.client.setMemberRegistry(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
nodeId,
|
||||
META_CONSTANTS.META_ASPECT_SET_NAME,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
{
|
||||
x: 100,
|
||||
y: 100
|
||||
}
|
||||
);
|
||||
|
||||
// Add to the specific sheet
|
||||
this.client.addMember(CONSTANTS.PROJECT_ROOT_ID, nodeId, metatabId);
|
||||
this.client.setMemberRegistry(
|
||||
CONSTANTS.PROJECT_ROOT_ID,
|
||||
nodeId,
|
||||
metatabId,
|
||||
REGISTRY_KEYS.POSITION,
|
||||
{
|
||||
x: 100,
|
||||
y: 100
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.createNamedNode = function(baseId, isMeta) {
|
||||
var parentId = this._currentNodeId,
|
||||
newId = this.client.createChild({parentId, baseId}),
|
||||
basename = 'New' + this.client.getNode(baseId).getAttribute('name'),
|
||||
newName = this.getUniqueName(parentId, basename);
|
||||
|
||||
// If instance, make the first char lowercase
|
||||
if (!isMeta) {
|
||||
newName = newName.substring(0, 1).toLowerCase() + newName.substring(1);
|
||||
}
|
||||
this.client.setAttributes(newId, 'name', newName);
|
||||
return newId;
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.getUniqueName = function(parentId, basename) {
|
||||
var pNode = this.client.getNode(parentId),
|
||||
children = pNode.getChildrenIds().map(id => this.client.getNode(id)),
|
||||
name = basename,
|
||||
exists = {},
|
||||
i = 2;
|
||||
|
||||
children.forEach(child => exists[child.getAttribute('name')] = true);
|
||||
|
||||
while (exists[name]) {
|
||||
name = basename + '_' + i;
|
||||
i++;
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.getLayerTypeDesc = function(node) {
|
||||
var decManager = this.client.decoratorManager,
|
||||
desc = {};
|
||||
|
||||
desc.id = node.getId();
|
||||
desc.name = node.getAttribute('name');
|
||||
desc.baseName = desc.name;
|
||||
desc.attributes = {};
|
||||
desc.pointers = {};
|
||||
|
||||
// Get the decorator
|
||||
desc.Decorator = decManager.getDecoratorForWidget('EllipseDecorator', 'EasyDAG');
|
||||
|
||||
// Set the color
|
||||
desc.color = '#9e9e9e';
|
||||
return desc;
|
||||
};
|
||||
|
||||
ForgeActionButton.prototype.promptLayerType = function() {
|
||||
// Prompt for the new custom layer's base type
|
||||
var deferred = Q.defer(),
|
||||
metanodes = this.client.getAllMetaNodes(),
|
||||
baseLayerId = metanodes.find(n => n.getAttribute('name') === 'Layer').getId(),
|
||||
layerType,
|
||||
types;
|
||||
|
||||
// PoA:
|
||||
// - Get the layer type ids
|
||||
// - Create the descriptors
|
||||
// - Get the color for the given types
|
||||
// - Move colors to a constants dir?
|
||||
|
||||
// Get the layer type ids
|
||||
layerType = metanodes
|
||||
.filter(node => node.getBaseId() === baseLayerId);
|
||||
|
||||
// - Create the descriptors
|
||||
types = layerType.map(node => {
|
||||
return {
|
||||
node: this.getLayerTypeDesc(node)
|
||||
};
|
||||
});
|
||||
|
||||
AddNodeDialog.prompt(types, deferred.resolve);
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return ForgeActionButton;
|
||||
});
|
||||
|
||||
@@ -10,5 +10,9 @@
|
||||
"ImportTorch": {
|
||||
"icon": "import_export",
|
||||
"priority": -1
|
||||
},
|
||||
"GenerateExecFile": {
|
||||
"icon": "play_for_work",
|
||||
"priority": -1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl'
|
||||
], function (
|
||||
TextEditorControl
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var NO_CODE_MESSAGE = '-- <%= name %> is not an editable layer!',
|
||||
LayerEditorControl;
|
||||
|
||||
LayerEditorControl = function (options) {
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(LayerEditorControl.prototype, TextEditorControl.prototype);
|
||||
|
||||
LayerEditorControl.prototype.loadMetaNodes = function () {
|
||||
return this._client.getAllMetaNodes();
|
||||
};
|
||||
|
||||
// This next function retrieves the relevant node information for the widget
|
||||
LayerEditorControl.prototype._getObjectDescriptor = function (nodeId) {
|
||||
var desc = TextEditorControl.prototype._getObjectDescriptor.call(this, nodeId),
|
||||
node = this._client.getNode(nodeId),
|
||||
hasCode = node.getValidAttributeNames().indexOf('code') > -1,
|
||||
template;
|
||||
|
||||
// Get own attribute, if set. Otherwise, set the text to the parent's populated
|
||||
// template
|
||||
this.loadMetaNodes();
|
||||
if (hasCode) { // is a custom layer
|
||||
if (!node.getOwnAttribute('code')) {
|
||||
// Retrieve the template from the mixin
|
||||
template = node.getMixinPaths()
|
||||
.map(id => this._client.getNode(id).getAttribute('code'))
|
||||
.find(code => !!code) || NO_CODE_MESSAGE;
|
||||
}
|
||||
} else {
|
||||
template = NO_CODE_MESSAGE;
|
||||
}
|
||||
|
||||
if (template) {
|
||||
desc.text = _.template(template)(desc);
|
||||
}
|
||||
return desc;
|
||||
};
|
||||
|
||||
LayerEditorControl.prototype.saveTextFor = function (id, text) {
|
||||
var r = /:__init\((.*)\)/,
|
||||
match = text.match(r),
|
||||
textMatch = match && match[1],
|
||||
node = this._client.getNode(id),
|
||||
currentAttrs = node.getValidAttributeNames(),
|
||||
attributes = [],
|
||||
msg = `Updating layer definition for ${node.getAttribute('name')}`;
|
||||
|
||||
// Parse the attributes and update the node!
|
||||
if (textMatch) {
|
||||
attributes = textMatch.split(',')
|
||||
.map(arg => arg.replace(/\s+/g, '')) // trim white space
|
||||
.filter(arg => !!arg); // no empty strings!
|
||||
} else { // inheriting __init
|
||||
attributes = this.getInheritedAttrs(text);
|
||||
}
|
||||
|
||||
this._client.startTransaction(msg);
|
||||
|
||||
TextEditorControl.prototype.saveTextFor.call(this, id, text);
|
||||
|
||||
// Remove old attributes
|
||||
_.difference(currentAttrs, attributes)
|
||||
.forEach(attr => this._client.removeAttributeSchema(id, attr));
|
||||
|
||||
attributes.forEach((attr, i) =>
|
||||
this._client.setAttributeSchema(id, attr, {type: 'string', argindex: i}));
|
||||
|
||||
this._client.completeTransaction();
|
||||
};
|
||||
|
||||
LayerEditorControl.prototype.getInheritedAttrs = function (code) {
|
||||
// Get the base class
|
||||
var r = /torch.class\((.*)\)/,
|
||||
match = code.match(r),
|
||||
baseType,
|
||||
metanode,
|
||||
textMatch = match && match[1];
|
||||
|
||||
if (textMatch) {
|
||||
baseType = textMatch.split(',')[1]
|
||||
.replace(/^\s*['"]nn\./, '')
|
||||
.replace(/['"]\s*$/, '');
|
||||
|
||||
this._logger.debug(`inheriting the attributes from ${baseType}`);
|
||||
|
||||
// Get the meta node and valid attribute names
|
||||
metanode = this._client.getAllMetaNodes()
|
||||
.find(node => node.getAttribute('name') === baseType);
|
||||
|
||||
if (metanode) {
|
||||
return metanode.getValidAttributeNames()
|
||||
.filter(attr => attr !== 'name');
|
||||
} else {
|
||||
// Check if the type is known by torch
|
||||
this._logger.warn(`Unknown base type ${baseType}. Assuming attributes are []`);
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
return LayerEditorControl;
|
||||
});
|
||||
@@ -0,0 +1,101 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/TextEditor/TextEditorWidget',
|
||||
'./LayerEditorControl'
|
||||
], function (
|
||||
PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
TextEditorWidget,
|
||||
LayerEditorControl
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var LayerEditorPanel;
|
||||
|
||||
LayerEditorPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'LayerEditorPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(LayerEditorPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(LayerEditorPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
LayerEditorPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new TextEditorWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new LayerEditorControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
LayerEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
LayerEditorPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
LayerEditorPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LayerEditorPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LayerEditorPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return LayerEditorPanel;
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
// This is a read-only view of the 'stdout' attribute for a Job node
|
||||
define([
|
||||
'panels/TextEditor/TextEditorControl'
|
||||
], function (
|
||||
TextEditorControl
|
||||
) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var LogViewerControl;
|
||||
|
||||
LogViewerControl = function (options) {
|
||||
options.attributeName = 'stdout';
|
||||
TextEditorControl.call(this, options);
|
||||
};
|
||||
|
||||
_.extend(LogViewerControl.prototype, TextEditorControl.prototype);
|
||||
|
||||
LogViewerControl.prototype._onUpdate = function (id) {
|
||||
if (id === this._currentNodeId) {
|
||||
TextEditorControl.prototype._onUpdate.call(this, id);
|
||||
}
|
||||
};
|
||||
|
||||
return LogViewerControl;
|
||||
});
|
||||
@@ -0,0 +1,104 @@
|
||||
/*globals define, _, WebGMEGlobal*/
|
||||
/*jshint browser: true*/
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed Jun 15 2016 14:06:10 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/LogViewer/LogViewerWidget',
|
||||
'./LogViewerControl'
|
||||
], function (
|
||||
PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
LogViewerWidget,
|
||||
LogViewerControl
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var LogViewerPanel;
|
||||
|
||||
LogViewerPanel = function (layoutManager, params) {
|
||||
var options = {};
|
||||
//set properties from options
|
||||
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'LogViewerPanel';
|
||||
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
|
||||
|
||||
//call parent's constructor
|
||||
PanelBaseWithHeader.apply(this, [options, layoutManager]);
|
||||
|
||||
this._client = params.client;
|
||||
this._embedded = params.embedded;
|
||||
|
||||
//initialize UI
|
||||
this._initialize();
|
||||
|
||||
this.logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
//inherit from PanelBaseWithHeader
|
||||
_.extend(LogViewerPanel.prototype, PanelBaseWithHeader.prototype);
|
||||
_.extend(LogViewerPanel.prototype, IActivePanel.prototype);
|
||||
|
||||
LogViewerPanel.prototype._initialize = function () {
|
||||
var self = this;
|
||||
|
||||
//set Widget title
|
||||
this.setTitle('');
|
||||
|
||||
this.widget = new LogViewerWidget(this.logger, this.$el);
|
||||
|
||||
this.widget.setTitle = function (title) {
|
||||
self.setTitle(title);
|
||||
};
|
||||
|
||||
this.control = new LogViewerControl({
|
||||
logger: this.logger,
|
||||
client: this._client,
|
||||
embedded: this._embedded,
|
||||
widget: this.widget
|
||||
});
|
||||
|
||||
this.onActivate();
|
||||
};
|
||||
|
||||
/* OVERRIDE FROM WIDGET-WITH-HEADER */
|
||||
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
|
||||
LogViewerPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
};
|
||||
|
||||
LogViewerPanel.prototype.onResize = function (width, height) {
|
||||
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
|
||||
this.widget.onWidgetContainerResize(width, height);
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
LogViewerPanel.prototype.destroy = function () {
|
||||
this.control.destroy();
|
||||
this.widget.destroy();
|
||||
|
||||
PanelBaseWithHeader.prototype.destroy.call(this);
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LogViewerPanel.prototype.onActivate = function () {
|
||||
this.widget.onActivate();
|
||||
this.control.onActivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(this.widget);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
LogViewerPanel.prototype.onDeactivate = function () {
|
||||
this.widget.onDeactivate();
|
||||
this.control.onDeactivate();
|
||||
WebGMEGlobal.KeyboardManager.setListener(undefined);
|
||||
WebGMEGlobal.Toolbar.refresh();
|
||||
};
|
||||
|
||||
return LogViewerPanel;
|
||||
});
|
||||
@@ -2,6 +2,7 @@
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'js/Constants',
|
||||
'panels/EasyDAG/EasyDAGControl',
|
||||
'deepforge/viz/PipelineControl',
|
||||
'common/core/coreQ',
|
||||
@@ -9,6 +10,7 @@ define([
|
||||
'q',
|
||||
'underscore'
|
||||
], function (
|
||||
CONSTANTS,
|
||||
EasyDAGControl,
|
||||
PipelineControl,
|
||||
Core,
|
||||
@@ -23,7 +25,12 @@ define([
|
||||
CONN = {
|
||||
SRC: 'src',
|
||||
DST: 'dst'
|
||||
};
|
||||
},
|
||||
DECORATORS = {
|
||||
ArtifactLoader: 'ArtifactOpDecorator',
|
||||
ArtifactFinder: 'ArtifactOpDecorator'
|
||||
},
|
||||
WIDGET_NAME = 'EasyDAG';
|
||||
|
||||
PipelineEditorControl = function (options) {
|
||||
EasyDAGControl.call(this, options);
|
||||
@@ -94,6 +101,11 @@ define([
|
||||
// Add a rule for them
|
||||
.forEach(opId => this._territories[opId] = this.TERRITORY_RULE);
|
||||
|
||||
// Add arch/artifact dir to the territory
|
||||
// loading more than necessary.... can restrict it in the future
|
||||
// if perf is a problem
|
||||
this._territories[CONSTANTS.PROJECT_ROOT_ID] = {children: 2};
|
||||
|
||||
this._client.updateTerritory(this._territoryId, this._territories);
|
||||
};
|
||||
|
||||
@@ -116,7 +128,8 @@ define([
|
||||
if (desc.parentId === this._currentNodeId) {
|
||||
this.addedIds[desc.id] = true;
|
||||
return EasyDAGControl.prototype._onLoad.call(this, gmeId);
|
||||
} else if (this.isContainedInActive(desc.parentId) && desc.isDataPort) {
|
||||
} else if (desc.parentId !== null &&
|
||||
this.isContainedInActive(desc.parentId) && desc.isDataPort) {
|
||||
// port added!
|
||||
this.addedIds[desc.id] = true;
|
||||
this._widget.addPort(desc);
|
||||
@@ -142,6 +155,19 @@ define([
|
||||
} // Ignore any other updates - ie, Inputs/Outputs containers
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getNodeDecorator = function (nodeObj) {
|
||||
var decoratorManager = this._client.decoratorManager,
|
||||
decorator,
|
||||
decoratorClass;
|
||||
|
||||
var base = this._client.getNode(nodeObj.getMetaTypeId()),
|
||||
baseName = base && base.getAttribute('name');
|
||||
|
||||
decorator = DECORATORS[baseName] || this.DEFAULT_DECORATOR;
|
||||
decoratorClass = decoratorManager.getDecoratorForWidget(decorator, WIDGET_NAME);
|
||||
return decoratorClass;
|
||||
};
|
||||
|
||||
// Override the getSuccessors method to look up successors by operations
|
||||
// with input nodes of the selected node's output type (prioritize the
|
||||
// valid nodes that are using an unused output type, if one exists, ow
|
||||
@@ -418,5 +444,27 @@ define([
|
||||
}
|
||||
};
|
||||
|
||||
PipelineEditorControl.prototype._getTargetDirs = function (typeIds) {
|
||||
// Find the directories containing these types
|
||||
return this._client.getNode(CONSTANTS.PROJECT_ROOT_ID).getChildrenIds()
|
||||
// No referencing data meta types
|
||||
.filter(id => {
|
||||
var cMeta = this._client.getChildrenMeta(id),
|
||||
validChildIds;
|
||||
|
||||
if (!cMeta) {
|
||||
return false;
|
||||
}
|
||||
|
||||
validChildIds = cMeta.items.map(item => item.id);
|
||||
for (var i = typeIds.length; i--;) {
|
||||
if (validChildIds.indexOf(typeIds[i]) !== -1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
return PipelineEditorControl;
|
||||
});
|
||||
|
||||
@@ -39,10 +39,9 @@ define([
|
||||
};
|
||||
|
||||
TextEditorControl.prototype._initWidgetEventHandlers = function () {
|
||||
// TODO: Add a way to navigate out of the current widget...
|
||||
this._widget.saveTextFor = (id, text) => {
|
||||
if (this._currentNodeHasAttr) {
|
||||
this._client.setAttributes(id, this.ATTRIBUTE_NAME, text);
|
||||
this.saveTextFor(id, text);
|
||||
} else {
|
||||
this._logger.warn(`Cannot save attribute ${this.ATTRIBUTE_NAME} ` +
|
||||
`for ${id} - node doesn't have the given attribute!`);
|
||||
@@ -50,10 +49,10 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
|
||||
// One major concept here is with managing the territory. The territory
|
||||
// defines the parts of the project that the visualizer is interested in
|
||||
// (this allows the browser to then only load those relevant parts).
|
||||
TextEditorControl.prototype.saveTextFor = function (id, text) {
|
||||
this._client.setAttributes(id, this.ATTRIBUTE_NAME, text);
|
||||
};
|
||||
|
||||
TextEditorControl.prototype.TERRITORY_RULE = {children: 0};
|
||||
TextEditorControl.prototype.selectedObjectChanged = function (nodeId) {
|
||||
var self = this;
|
||||
@@ -67,8 +66,7 @@ define([
|
||||
|
||||
self._currentNodeId = nodeId;
|
||||
self._currentNodeParentId = undefined;
|
||||
self._currentNodeHasAttr = (typeof self._client.getNode(self._currentNodeId)
|
||||
.getAttribute(self.ATTRIBUTE_NAME)) === 'string';
|
||||
self._currentNodeHasAttr = self._client.getNode(self._currentNodeId).getValidAttributeNames().indexOf(self.ATTRIBUTE_NAME) > -1;
|
||||
|
||||
if (typeof self._currentNodeId === 'string') {
|
||||
var parentId = this._getParentId(nodeId);
|
||||
|
||||
@@ -4,14 +4,17 @@
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 08:58:20 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define(['js/PanelBase/PanelBaseWithHeader',
|
||||
define([
|
||||
'js/PanelBase/PanelBaseWithHeader',
|
||||
'js/PanelManager/IActivePanel',
|
||||
'widgets/TextEditor/TextEditorWidget',
|
||||
'./TextEditorControl'
|
||||
], function (PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
TextEditorWidget,
|
||||
TextEditorControl) {
|
||||
], function (
|
||||
PanelBaseWithHeader,
|
||||
IActivePanel,
|
||||
TextEditorWidget,
|
||||
TextEditorControl
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var TextEditorPanel;
|
||||
@@ -65,7 +68,7 @@ define(['js/PanelBase/PanelBaseWithHeader',
|
||||
TextEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
|
||||
//apply parent's onReadOnlyChanged
|
||||
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
|
||||
|
||||
this.widget.setReadOnly(isReadOnly);
|
||||
};
|
||||
|
||||
TextEditorPanel.prototype.onResize = function (width, height) {
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
|
||||
define([
|
||||
'widgets/EasyDAG/SelectionManager',
|
||||
'widgets/EasyDAG/Buttons',
|
||||
'underscore'
|
||||
], function(
|
||||
EasyDAGSelectionManager,
|
||||
Buttons,
|
||||
_
|
||||
) {
|
||||
'use strict';
|
||||
@@ -15,9 +17,16 @@ define([
|
||||
|
||||
_.extend(SelectionManager.prototype, EasyDAGSelectionManager.prototype);
|
||||
|
||||
SelectionManager.prototype.createActionButtons = function(/*width, height*/) {
|
||||
// Add restart btn, etc
|
||||
SelectionManager.prototype.createActionButtons = function(width/*, height*/) {
|
||||
// Add 'watch' and 'jumpToDef' buttons
|
||||
// TODO
|
||||
new Buttons.Enter({
|
||||
context: this._widget,
|
||||
$pEl: this.$selection,
|
||||
item: this.selectedItem,
|
||||
x: width,
|
||||
y: 0
|
||||
});
|
||||
};
|
||||
|
||||
return SelectionManager;
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
/*globals define, _*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
define([
|
||||
'widgets/TextEditor/TextEditorWidget',
|
||||
'css!./styles/LogViewerWidget.css'
|
||||
], function (
|
||||
TextEditorWidget
|
||||
) {
|
||||
'use strict';
|
||||
|
||||
var LogViewerWidget,
|
||||
ANSI_COLORS = [
|
||||
'black',
|
||||
'red',
|
||||
'green',
|
||||
'yellow',
|
||||
'blue',
|
||||
'magenta',
|
||||
'cyan',
|
||||
'gray'
|
||||
];
|
||||
|
||||
LogViewerWidget = function () {
|
||||
this.readOnly = true;
|
||||
TextEditorWidget.apply(this, arguments);
|
||||
this._el.addClass('log-viewer');
|
||||
this.editor.setTheme('ace/theme/twilight');
|
||||
this.editor.setShowPrintMargin(false);
|
||||
|
||||
// Override the textlayer to add support for ansi colors
|
||||
this.customizeAce();
|
||||
};
|
||||
|
||||
_.extend(LogViewerWidget.prototype, TextEditorWidget.prototype);
|
||||
|
||||
LogViewerWidget.prototype.getHeader = function(desc) {
|
||||
return `Console logging for Operation "${desc.name}":\n`;
|
||||
};
|
||||
|
||||
LogViewerWidget.prototype.customizeAce = function() {
|
||||
var textLayer = this.editor.renderer.$textLayer,
|
||||
renderToken = textLayer.$renderToken;
|
||||
|
||||
textLayer.$renderToken = function(builder, col, token, value) {
|
||||
// check for ansi color
|
||||
var ansiBuilder = LogViewerWidget.renderAnsiFromText(value),
|
||||
newToken;
|
||||
|
||||
for (var i = 1; i < ansiBuilder.length; i+= 3) {
|
||||
builder.push(ansiBuilder[i-1]);
|
||||
value = ansiBuilder[i];
|
||||
newToken = {
|
||||
type: token.type,
|
||||
value: value
|
||||
};
|
||||
col = renderToken.call(this, builder, col, newToken, value);
|
||||
builder.push(ansiBuilder[i+1]);
|
||||
}
|
||||
|
||||
return col;
|
||||
};
|
||||
};
|
||||
|
||||
// Get the editor text and update wrt ansi colors
|
||||
LogViewerWidget.renderAnsiFromText = function(remaining) {
|
||||
var r = /\[0(;3([0-7]))?m/,
|
||||
match,
|
||||
ansiCode,
|
||||
text,
|
||||
color,
|
||||
nextColor = 'default',
|
||||
builder = [];
|
||||
|
||||
color = color || nextColor;
|
||||
while (remaining) {
|
||||
match = remaining.match(r);
|
||||
if (match) {
|
||||
ansiCode = match[0];
|
||||
nextColor = ANSI_COLORS[match[2]] || null;
|
||||
text = remaining.substring(0, match.index);
|
||||
remaining = remaining.substring(match.index+ansiCode.length);
|
||||
} else {
|
||||
text = remaining;
|
||||
remaining = '';
|
||||
}
|
||||
|
||||
// Add a "span" node w/ the appropriate color class
|
||||
builder.push(`<span class='ansi-${color}'>`, text, '</span>');
|
||||
|
||||
color = nextColor;
|
||||
nextColor = 'default';
|
||||
}
|
||||
return builder;
|
||||
};
|
||||
|
||||
LogViewerWidget.prototype.getSessionOptions = function() {
|
||||
return {
|
||||
firstLineNumber: -1
|
||||
};
|
||||
};
|
||||
|
||||
LogViewerWidget.prototype.getEditorOptions = function() {
|
||||
return {
|
||||
fontSize: '10pt'
|
||||
};
|
||||
};
|
||||
|
||||
return LogViewerWidget;
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* This file is for any css that you may want for this visualizer.
|
||||
*
|
||||
* Ideally, you would use the scss file also provided in this directory
|
||||
* and then generate this file automatically from that. However, you can
|
||||
* simply write css if you prefer
|
||||
*/
|
||||
|
||||
.log-viewer {
|
||||
outline: none;
|
||||
}
|
||||
.log-viewer .ansi-black {
|
||||
color: #000000;
|
||||
}
|
||||
.log-viewer .ansi-red {
|
||||
color: rgb(194, 54, 33);
|
||||
}
|
||||
.log-viewer .ansi-green {
|
||||
color: rgb(37, 188, 36);
|
||||
}
|
||||
.log-viewer .ansi-yellow {
|
||||
color: rgb(173, 173, 39);
|
||||
}
|
||||
.log-viewer .ansi-blue {
|
||||
color: rgb(73, 46, 225);
|
||||
}
|
||||
.log-viewer .ansi-magenta {
|
||||
color: rgb(211, 56, 211);
|
||||
}
|
||||
.log-viewer .ansi-cyan {
|
||||
color: rgb(51, 187, 200);
|
||||
}
|
||||
.log-viewer .ansi-gray {
|
||||
color: rgb(203, 204, 205);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* This file is for any scss that you may want for this visualizer.
|
||||
*/
|
||||
|
||||
.log-viewer {
|
||||
outline: none;
|
||||
}
|
||||
@@ -113,10 +113,25 @@ define([
|
||||
|
||||
};
|
||||
|
||||
var Delete = function(params) {
|
||||
EasyDAGButtons.DeleteOne.call(this, params);
|
||||
};
|
||||
|
||||
_.extend(Delete.prototype, EasyDAGButtons.DeleteOne.prototype);
|
||||
|
||||
Delete.prototype._onClick = function(item) {
|
||||
// Check if it is a pointer or
|
||||
if (item.desc.isPointer) {
|
||||
this.removePtr(item.name);
|
||||
} else {
|
||||
this.deleteNode(item.id);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
AddOutput: AddOutput,
|
||||
AddInput: AddInput,
|
||||
AddRef: AddRef,
|
||||
Delete: EasyDAGButtons.Delete
|
||||
Delete: Delete
|
||||
};
|
||||
});
|
||||
|
||||
@@ -91,13 +91,5 @@ define([
|
||||
this.addRefTo(target.node.id);
|
||||
};
|
||||
|
||||
OperationInterfaceEditorWidget.prototype.removeItem = function(item) {
|
||||
if (item.desc.isPointer) {
|
||||
this.removePtr(item.name);
|
||||
} else {
|
||||
this.removeSubtreeAt(item.id);
|
||||
}
|
||||
};
|
||||
|
||||
return OperationInterfaceEditorWidget;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*globals define, WebGMEGlobal*/
|
||||
define([
|
||||
'widgets/EasyDAG/Buttons'
|
||||
], function(
|
||||
EasyDAGButtons
|
||||
) {
|
||||
|
||||
// Create a GoToBase button
|
||||
var client = WebGMEGlobal.Client,
|
||||
LocalOps = {
|
||||
ArtifactLoader: true,
|
||||
Save: true
|
||||
};
|
||||
|
||||
var GoToBase = function(params) {
|
||||
// Check if it should be disabled
|
||||
var baseId = this._getBaseId(params.item),
|
||||
base = client.getNode(baseId);
|
||||
|
||||
params.disabled = base ? base.isLibraryElement() : false;
|
||||
EasyDAGButtons.ButtonBase.call(this, params);
|
||||
};
|
||||
|
||||
GoToBase.SIZE = 10;
|
||||
GoToBase.BORDER = 5;
|
||||
GoToBase.prototype.BTN_CLASS = 'add';
|
||||
GoToBase.prototype = new EasyDAGButtons.ButtonBase();
|
||||
|
||||
GoToBase.prototype._render = function() {
|
||||
var lineRadius = GoToBase.SIZE - GoToBase.BORDER,
|
||||
btnColor = '#90caf9',
|
||||
lineColor = '#7986cb';
|
||||
|
||||
if (this.disabled) {
|
||||
btnColor = '#e0e0e0';
|
||||
lineColor = '#9e9e9e';
|
||||
}
|
||||
|
||||
this.$el
|
||||
.append('circle')
|
||||
.attr('r', GoToBase.SIZE)
|
||||
.attr('fill', btnColor);
|
||||
|
||||
this.$el
|
||||
.append('circle')
|
||||
//.attr('cx', -)
|
||||
//.attr('cy', 0)
|
||||
.attr('r', GoToBase.SIZE/3)
|
||||
.attr('stroke-width', 3)
|
||||
.attr('stroke', lineColor);
|
||||
|
||||
this.$el
|
||||
.append('line')
|
||||
.attr('y1', 0)
|
||||
.attr('y2', 0)
|
||||
.attr('x1', -lineRadius)
|
||||
.attr('x2', lineRadius)
|
||||
.attr('stroke-width', 3)
|
||||
.attr('stroke', lineColor);
|
||||
|
||||
};
|
||||
|
||||
GoToBase.prototype._onClick = function(item) {
|
||||
var node = client.getNode(item.id),
|
||||
baseId = node.getBaseId();
|
||||
|
||||
window.DeepForge = window.DeepForge || {};
|
||||
window.DeepForge.lastPipeline = item.desc.parentId;
|
||||
|
||||
WebGMEGlobal.State.registerActiveObject(baseId);
|
||||
};
|
||||
|
||||
GoToBase.prototype._getBaseId = function(item) {
|
||||
var n = client.getNode(item.id);
|
||||
return n.getBaseId();
|
||||
};
|
||||
|
||||
return {
|
||||
DeleteOne: EasyDAGButtons.DeleteOne,
|
||||
GoToBase: GoToBase
|
||||
};
|
||||
});
|
||||
@@ -60,6 +60,20 @@ define([
|
||||
this._visiblePorts = null;
|
||||
};
|
||||
|
||||
OperationNode.prototype.removePort = function(id) {
|
||||
// Find the given port and remove it
|
||||
[this.inputs, this.outputs] // Look for the port in both lists
|
||||
.forEach(ports => {
|
||||
var port = ports.find(p => p.id === id),
|
||||
i;
|
||||
|
||||
if (port) {
|
||||
i = ports.indexOf(port);
|
||||
ports.splice(i, 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
OperationNode.prototype.updatePort = function(/*desc*/) {
|
||||
// TODO
|
||||
};
|
||||
@@ -78,5 +92,13 @@ define([
|
||||
this.hidePorts();
|
||||
};
|
||||
|
||||
OperationNode.prototype.update = function() {
|
||||
DAGItem.prototype.update.apply(this, arguments);
|
||||
if (this._visiblePorts) {
|
||||
var areInputs = this._visiblePorts[1];
|
||||
this.showPorts.call(this, null, areInputs);
|
||||
}
|
||||
};
|
||||
|
||||
return OperationNode;
|
||||
});
|
||||
|
||||
@@ -35,6 +35,7 @@ define([
|
||||
this.$el.addClass(WIDGET_CLASS);
|
||||
this.portIdToNode = {};
|
||||
this.PORT_STATE = STATE.DEFAULT;
|
||||
this.srcPortToConnectArgs = null;
|
||||
this._connForPort = {};
|
||||
this._itemsShowingPorts = [];
|
||||
};
|
||||
@@ -88,6 +89,12 @@ define([
|
||||
// Update the item's ports
|
||||
item.refreshPorts();
|
||||
}
|
||||
|
||||
// If in a "connecting-port" state, refresh the port
|
||||
if (this.PORT_STATE === STATE.CONNECTING) {
|
||||
this.PORT_STATE = STATE.DEFAULT;
|
||||
this.connectPort.apply(this, this.srcPortToConnectArgs);
|
||||
}
|
||||
};
|
||||
|
||||
PipelineEditorWidget.prototype._removeConnection = function(id) {
|
||||
@@ -139,6 +146,7 @@ define([
|
||||
PipelineEditorWidget.prototype.connectPort = function(nodeId, id, isOutput) {
|
||||
this._logger.info('port ' + id + ' has been clicked! (', isOutput, ')');
|
||||
if (this.PORT_STATE === STATE.DEFAULT) {
|
||||
this.srcPortToConnectArgs = arguments;
|
||||
this.startPortConnection(nodeId, id, isOutput);
|
||||
} else if (this._selectedPort !== id) {
|
||||
this._logger.info('connecting ' + this._selectedPort + ' to ' + id);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
define([
|
||||
'widgets/EasyDAG/SelectionManager',
|
||||
'widgets/EasyDAG/Buttons',
|
||||
'./Buttons',
|
||||
'underscore'
|
||||
], function(
|
||||
EasyDAGSelectionManager,
|
||||
@@ -17,7 +17,7 @@ define([
|
||||
|
||||
_.extend(SelectionManager.prototype, EasyDAGSelectionManager.prototype);
|
||||
|
||||
SelectionManager.prototype.createActionButtons = function(/*width, height*/) {
|
||||
SelectionManager.prototype.createActionButtons = function(width/*, height*/) {
|
||||
// move the 'x' to the top left
|
||||
new Buttons.DeleteOne({
|
||||
context: this._widget,
|
||||
@@ -26,6 +26,15 @@ define([
|
||||
x: 0,
|
||||
y: 0
|
||||
});
|
||||
// If the operation has a user-defined base type,
|
||||
// show a button for jumping to the base def
|
||||
new Buttons.GoToBase({
|
||||
context: this._widget,
|
||||
$pEl: this.$selection,
|
||||
item: this.selectedItem,
|
||||
x: width,
|
||||
y: 0
|
||||
});
|
||||
};
|
||||
|
||||
SelectionManager.prototype.deselect = function() {
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<div class="col s2 m4">
|
||||
<div class="card blue lighten-2">
|
||||
<div class="col s2 m4" id="card-node<%= htmlId %>" data-rank="<%= rank %>">
|
||||
<div class="card <%= color %> <%= shade %>">
|
||||
<div class="card-content">
|
||||
<% if (typeof icon !== 'undefined') {%>
|
||||
<div><i class="large material-icons"><%=icon%></i></div>
|
||||
<%}%>
|
||||
<span class="card-title"><%= title %></span>
|
||||
<div
|
||||
<p><%= description %></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -30,6 +30,10 @@ define([
|
||||
|
||||
// Load the component settings
|
||||
this._config = {
|
||||
defaults: {
|
||||
color: 'blue',
|
||||
shade: 'lighten-2'
|
||||
},
|
||||
nodes:[]
|
||||
};
|
||||
ComponentSettings.resolveWithWebGMEGlobal(this._config, this.getComponentId());
|
||||
@@ -69,7 +73,7 @@ define([
|
||||
node = this.validNodes[desc[attr]];
|
||||
|
||||
if (node) {
|
||||
_.extend(desc, node);
|
||||
_.extend(desc, this._config.defaults, node);
|
||||
desc.title = desc.title || desc.name;
|
||||
this.addPanel(desc);
|
||||
}
|
||||
@@ -77,15 +81,40 @@ define([
|
||||
};
|
||||
|
||||
RootVizWidget.prototype.addPanel = function (desc) {
|
||||
var html = $(NodeTpl(desc));
|
||||
var html;
|
||||
|
||||
// Create the html from template
|
||||
if (this.nodes[desc.id]) {
|
||||
if (this.nodes[desc.id]) { // refresh, if already exists
|
||||
this.removeNode(desc.id);
|
||||
}
|
||||
|
||||
// Create the html from template
|
||||
this.$container.append(html);
|
||||
desc.htmlId = desc.id.replace('/', '-');
|
||||
html = $(NodeTpl(desc));
|
||||
|
||||
// Find the child just before the given one
|
||||
var children = this.$container.children(),
|
||||
rank = -Infinity,
|
||||
id;
|
||||
|
||||
desc.rank = +desc.rank;
|
||||
if (children.length) { // Add it in order
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
rank = +children[i].getAttribute('data-rank');
|
||||
if (rank > desc.rank) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < children.length) {
|
||||
id = children[i].getAttribute('id');
|
||||
this.$container.find('#' + id).before(html);
|
||||
} else {
|
||||
this.$container.append(html);
|
||||
}
|
||||
} else {
|
||||
this.$container.append(html);
|
||||
}
|
||||
|
||||
html.on('click', () => {
|
||||
this.onNodeClick(desc.id);
|
||||
event.stopPropagation();
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
/*globals define*/
|
||||
/*globals $, define*/
|
||||
/*jshint browser: true*/
|
||||
|
||||
/**
|
||||
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 08:58:20 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
define([
|
||||
'./lib/ace',
|
||||
'underscore',
|
||||
@@ -23,19 +19,22 @@ define([
|
||||
|
||||
this._el = container;
|
||||
this._el.css({height: '100%'});
|
||||
this.editor = ace.edit(this._el[0]);
|
||||
this.editor.getSession().setMode('ace/mode/lua');
|
||||
this.$editor = $('<div/>');
|
||||
this.$editor.css({height: '100%'});
|
||||
this._el.append(this.$editor[0]);
|
||||
|
||||
this.readOnly = this.readOnly || false;
|
||||
this.editor = ace.edit(this.$editor[0]);
|
||||
|
||||
// Get the config from component settings for themes
|
||||
// TODO
|
||||
this.editor.setOptions({
|
||||
fontSize: '12pt'
|
||||
});
|
||||
this.editor.getSession().setOptions(this.getSessionOptions());
|
||||
this.editor.setOptions(this.getEditorOptions());
|
||||
this.editor.$blockScrolling = Infinity;
|
||||
this.DELAY = 750;
|
||||
// this.editor.setTheme('ace/theme/monokai');
|
||||
|
||||
this.editor.on('input', _.debounce(this.saveText.bind(this), this.DELAY));
|
||||
this.setReadOnly(this.readOnly);
|
||||
this.currentHeader = '';
|
||||
this.activeNode = null;
|
||||
this._initialize();
|
||||
@@ -43,6 +42,20 @@ define([
|
||||
this._logger.debug('ctor finished');
|
||||
};
|
||||
|
||||
TextEditorWidget.prototype.getEditorOptions = function () {
|
||||
return {
|
||||
fontSize: '12pt'
|
||||
};
|
||||
};
|
||||
|
||||
TextEditorWidget.prototype.getSessionOptions = function () {
|
||||
return {
|
||||
mode: 'ace/mode/lua',
|
||||
tabSize: 3,
|
||||
useSoftTabs: true
|
||||
};
|
||||
};
|
||||
|
||||
TextEditorWidget.prototype._initialize = function () {
|
||||
// set widget class
|
||||
this._el.addClass(WIDGET_CLASS);
|
||||
@@ -68,7 +81,13 @@ define([
|
||||
};
|
||||
|
||||
TextEditorWidget.prototype.saveText = function () {
|
||||
var text = this.editor.getValue().replace(this.currentHeader + '\n', '');
|
||||
var text;
|
||||
|
||||
if (this.readOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
text = this.editor.getValue().replace(this.currentHeader + '\n', '');
|
||||
if (this.activeNode) {
|
||||
this.saveTextFor(this.activeNode, text);
|
||||
} else {
|
||||
@@ -85,7 +104,9 @@ define([
|
||||
|
||||
TextEditorWidget.prototype.updateNode = function (desc) {
|
||||
// Check for header changes
|
||||
if (this.activeNode === desc.id &&
|
||||
if (this.readOnly) {
|
||||
this.addNode(desc);
|
||||
} else if (this.activeNode === desc.id &&
|
||||
this.getHeader(desc) !== this.currentHeader) {
|
||||
this.addNode(desc);
|
||||
}
|
||||
@@ -100,6 +121,7 @@ define([
|
||||
|
||||
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
|
||||
TextEditorWidget.prototype.destroy = function () {
|
||||
this.editor.destroy();
|
||||
};
|
||||
|
||||
TextEditorWidget.prototype.onActivate = function () {
|
||||
@@ -110,5 +132,10 @@ define([
|
||||
this._logger.debug('TextEditorWidget has been deactivated');
|
||||
};
|
||||
|
||||
TextEditorWidget.prototype.setReadOnly = function (isReadOnly) {
|
||||
this.readOnly = isReadOnly;
|
||||
this.editor.setReadOnly(isReadOnly);
|
||||
};
|
||||
|
||||
return TextEditorWidget;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
define("ace/theme/twilight",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
|
||||
|
||||
exports.isDark = true;
|
||||
exports.cssClass = "ace-twilight";
|
||||
exports.cssText = ".ace-twilight .ace_gutter {\
|
||||
background: #232323;\
|
||||
color: #E2E2E2\
|
||||
}\
|
||||
.ace-twilight .ace_print-margin {\
|
||||
width: 1px;\
|
||||
background: #232323\
|
||||
}\
|
||||
.ace-twilight {\
|
||||
background-color: #141414;\
|
||||
color: #F8F8F8\
|
||||
}\
|
||||
.ace-twilight .ace_cursor {\
|
||||
color: #A7A7A7\
|
||||
}\
|
||||
.ace-twilight .ace_marker-layer .ace_selection {\
|
||||
background: rgba(221, 240, 255, 0.20)\
|
||||
}\
|
||||
.ace-twilight.ace_multiselect .ace_selection.ace_start {\
|
||||
box-shadow: 0 0 3px 0px #141414;\
|
||||
}\
|
||||
.ace-twilight .ace_marker-layer .ace_step {\
|
||||
background: rgb(102, 82, 0)\
|
||||
}\
|
||||
.ace-twilight .ace_marker-layer .ace_bracket {\
|
||||
margin: -1px 0 0 -1px;\
|
||||
border: 1px solid rgba(255, 255, 255, 0.25)\
|
||||
}\
|
||||
.ace-twilight .ace_marker-layer .ace_active-line {\
|
||||
background: rgba(255, 255, 255, 0.031)\
|
||||
}\
|
||||
.ace-twilight .ace_gutter-active-line {\
|
||||
background-color: rgba(255, 255, 255, 0.031)\
|
||||
}\
|
||||
.ace-twilight .ace_marker-layer .ace_selected-word {\
|
||||
border: 1px solid rgba(221, 240, 255, 0.20)\
|
||||
}\
|
||||
.ace-twilight .ace_invisible {\
|
||||
color: rgba(255, 255, 255, 0.25)\
|
||||
}\
|
||||
.ace-twilight .ace_keyword,\
|
||||
.ace-twilight .ace_meta {\
|
||||
color: #CDA869\
|
||||
}\
|
||||
.ace-twilight .ace_constant,\
|
||||
.ace-twilight .ace_constant.ace_character,\
|
||||
.ace-twilight .ace_constant.ace_character.ace_escape,\
|
||||
.ace-twilight .ace_constant.ace_other,\
|
||||
.ace-twilight .ace_heading,\
|
||||
.ace-twilight .ace_markup.ace_heading,\
|
||||
.ace-twilight .ace_support.ace_constant {\
|
||||
color: #CF6A4C\
|
||||
}\
|
||||
.ace-twilight .ace_invalid.ace_illegal {\
|
||||
color: #F8F8F8;\
|
||||
background-color: rgba(86, 45, 86, 0.75)\
|
||||
}\
|
||||
.ace-twilight .ace_invalid.ace_deprecated {\
|
||||
text-decoration: underline;\
|
||||
font-style: italic;\
|
||||
color: #D2A8A1\
|
||||
}\
|
||||
.ace-twilight .ace_support {\
|
||||
color: #9B859D\
|
||||
}\
|
||||
.ace-twilight .ace_fold {\
|
||||
background-color: #AC885B;\
|
||||
border-color: #F8F8F8\
|
||||
}\
|
||||
.ace-twilight .ace_support.ace_function {\
|
||||
color: #DAD085\
|
||||
}\
|
||||
.ace-twilight .ace_list,\
|
||||
.ace-twilight .ace_markup.ace_list,\
|
||||
.ace-twilight .ace_storage {\
|
||||
color: #F9EE98\
|
||||
}\
|
||||
.ace-twilight .ace_entity.ace_name.ace_function,\
|
||||
.ace-twilight .ace_meta.ace_tag,\
|
||||
.ace-twilight .ace_variable {\
|
||||
color: #AC885B\
|
||||
}\
|
||||
.ace-twilight .ace_string {\
|
||||
color: #8F9D6A\
|
||||
}\
|
||||
.ace-twilight .ace_string.ace_regexp {\
|
||||
color: #E9C062\
|
||||
}\
|
||||
.ace-twilight .ace_comment {\
|
||||
font-style: italic;\
|
||||
color: #5F5A60\
|
||||
}\
|
||||
.ace-twilight .ace_variable {\
|
||||
color: #7587A6\
|
||||
}\
|
||||
.ace-twilight .ace_xml-pe {\
|
||||
color: #494949\
|
||||
}\
|
||||
.ace-twilight .ace_indent-guide {\
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\
|
||||
}";
|
||||
|
||||
var dom = require("../lib/dom");
|
||||
dom.importCssString(exports.cssText, exports.cssClass);
|
||||
});
|
||||
@@ -8,5 +8,6 @@
|
||||
|
||||
.text-editor {
|
||||
outline: none;
|
||||
padding: 0px;
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../../globals'),
|
||||
SEED_DIR = testFixture.path.join(testFixture.DF_SEED_DIR, 'devMinimal'),
|
||||
SEED_DIR = testFixture.path.join(testFixture.DF_SEED_DIR, 'nn'),
|
||||
assert = require('assert');
|
||||
|
||||
describe('CreateTorchMeta', function () {
|
||||
@@ -20,9 +20,14 @@ describe('CreateTorchMeta', function () {
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
ORIG_META = {},
|
||||
META = {},
|
||||
origRoot,
|
||||
root,
|
||||
commitHash;
|
||||
|
||||
before(function (done) {
|
||||
this.timeout(5000);
|
||||
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
|
||||
.then(function (gmeAuth_) {
|
||||
gmeAuth = gmeAuth_;
|
||||
@@ -32,7 +37,7 @@ describe('CreateTorchMeta', function () {
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: testFixture.path.join(SEED_DIR, 'devMinimal.webgmex'),
|
||||
projectSeed: testFixture.path.join(SEED_DIR, 'nn.webgmex'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
@@ -45,8 +50,56 @@ describe('CreateTorchMeta', function () {
|
||||
project = importResult.project;
|
||||
core = importResult.core;
|
||||
commitHash = importResult.commitHash;
|
||||
origRoot = importResult.rootNode;
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
// Run the plugin
|
||||
.then(() => {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
metaDict = core.getAllMetaNodes(origRoot),
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211'
|
||||
};
|
||||
|
||||
|
||||
// Populate the META object
|
||||
Object.keys(metaDict)
|
||||
.map(id => metaDict[id])
|
||||
.forEach(node => ORIG_META[core.getAttribute(node, 'name')] = node);
|
||||
|
||||
return Q.ninvoke(
|
||||
manager,
|
||||
'executePlugin',
|
||||
pluginName,
|
||||
{removeOldLayers: true},
|
||||
context
|
||||
);
|
||||
})
|
||||
.then(pluginResult => {
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
|
||||
return project.getBranchHash('test');
|
||||
})
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (rootNode) {
|
||||
var metaDict = core.getAllMetaNodes(rootNode);
|
||||
root = rootNode;
|
||||
|
||||
// Populate the META object
|
||||
Object.keys(metaDict)
|
||||
.map(id => metaDict[id])
|
||||
.forEach(node => META[core.getAttribute(node, 'name')] = node);
|
||||
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
@@ -128,122 +181,42 @@ describe('CreateTorchMeta', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('should place the nodes in the Language node', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211'
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal(null);
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (rootNode) {
|
||||
var metaDict = core.getAllMetaNodes(rootNode),
|
||||
metaNodes,
|
||||
nodes,
|
||||
langNode;
|
||||
|
||||
metaNodes = Object.keys(metaDict)
|
||||
.map(id => metaDict[id]);
|
||||
|
||||
langNode = metaNodes
|
||||
.find(node => core.getAttribute(node, 'name') === 'Language' );
|
||||
|
||||
nodes = metaNodes
|
||||
.filter(node => core.getAttribute(node, 'name') !== 'FCO' &&
|
||||
core.getAttribute(node, 'name') !== 'Language' );
|
||||
|
||||
nodes.forEach(node => assert.equal(core.getParent(node), langNode));
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
it('should update existing layers', function () {
|
||||
var scGuid = core.getGuid(ORIG_META.SpatialConvolution);
|
||||
// Check the guid of spatial convolution
|
||||
expect(scGuid).to.equal(core.getGuid(META.SpatialConvolution));
|
||||
});
|
||||
|
||||
// Attributes
|
||||
describe('attributes', function() {
|
||||
var rootNode,
|
||||
META = {};
|
||||
it('should add attributes', function () {
|
||||
// check that "Linear" has multiple attrs
|
||||
var attrs = core.getAttributeNames(META.Linear);
|
||||
assert.notEqual(attrs.length, 1, `missing attributes! ${attrs}`);
|
||||
});
|
||||
|
||||
before(function(done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211'
|
||||
};
|
||||
it('should create string attributes', function () {
|
||||
// check that "Linear" has an attribute called "output"
|
||||
var attr = core.getAttributeMeta(META.Add, 'scalar');
|
||||
assert.equal(attr.type, 'string');
|
||||
});
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal(null);
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
return Q.ninvoke(project, 'loadObject', branchHash);
|
||||
})
|
||||
.then(function (commitObject) {
|
||||
return Q.ninvoke(core, 'loadRoot', commitObject.root);
|
||||
})
|
||||
.then(function (root) {
|
||||
rootNode = root;
|
||||
var metaDict = core.getAllMetaNodes(rootNode);
|
||||
it('should place the nodes in the Language node', function () {
|
||||
var metaDict = core.getAllMetaNodes(root),
|
||||
metaNodes,
|
||||
nodes,
|
||||
langNode;
|
||||
|
||||
// Populate the META object
|
||||
Object.keys(metaDict)
|
||||
.map(id => metaDict[id])
|
||||
.forEach(node => META[core.getAttribute(node, 'name')] = node);
|
||||
metaNodes = Object.keys(metaDict)
|
||||
.map(id => metaDict[id]);
|
||||
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
langNode = metaNodes
|
||||
.find(node => core.getAttribute(node, 'name') === 'Language' );
|
||||
|
||||
it('should add attributes', function () {
|
||||
// check that "Linear" has multiple attrs
|
||||
var attrs = core.getAttributeNames(META.Linear);
|
||||
assert.notEqual(attrs.length, 1, `missing attributes! ${attrs}`);
|
||||
});
|
||||
nodes = metaNodes
|
||||
.filter(node => core.getAttribute(node, 'name') !== 'FCO' &&
|
||||
core.getAttribute(node, 'name') !== 'Language' );
|
||||
|
||||
it('should support custom types', function () {
|
||||
// check that "Add" has a boolean attribute called 'isScalar'
|
||||
var attr = core.getAttributeMeta(META.Add, 'isScalar');
|
||||
assert.equal(attr.type, 'boolean');
|
||||
});
|
||||
|
||||
it('should create integer type if none specified', function () {
|
||||
// check that "Linear" has an attribute called "output"
|
||||
var attr = core.getAttributeMeta(META.Linear, 'output');
|
||||
assert.notEqual(attr, -1);
|
||||
assert.equal(attr.type, 'integer');
|
||||
});
|
||||
|
||||
it('should set "min" when specified', function () {
|
||||
var attr = core.getAttributeMeta(META.Linear, 'output');
|
||||
assert.equal(attr.min, 1);
|
||||
});
|
||||
|
||||
it('should ignore "ignore" attributes', function () {
|
||||
// check that "Linear" doesn't have an attribute called "input"
|
||||
var attrs = core.getAttributeNames(META.Linear);
|
||||
assert.equal(attrs.indexOf('input'), -1);
|
||||
});
|
||||
nodes.forEach(node => assert.equal(core.getParent(node), langNode));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -58,7 +58,7 @@ describe('GenerateArchitecture', function () {
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should run plugin and not update the branch', function (done) {
|
||||
it.skip('should run plugin and not update the branch', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
@@ -85,12 +85,12 @@ describe('GenerateArchitecture', function () {
|
||||
|
||||
describe('test cases', function() {
|
||||
var cases = [
|
||||
['/4', 'basic.lua'],
|
||||
['/T', 'basic-transfers.lua'],
|
||||
['/W', 'overfeat.lua']
|
||||
// TODO: Add more tests
|
||||
// Need a concat test
|
||||
// TODO
|
||||
// Need to update the input args for Reshape!
|
||||
//['/o', 'basic.lua'],
|
||||
//['/8', 'basic-transfers.lua'],
|
||||
//['/M', 'concat-parallel.lua'],
|
||||
['/e', 'googlenet.lua'],
|
||||
['/X', 'overfeat.lua']
|
||||
];
|
||||
|
||||
var runTest = function(pair, done) {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*jshint node:true, mocha:true*/
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Sat Jun 04 2016 18:01:54 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../../globals');
|
||||
|
||||
describe.skip('GenerateExecFile', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
expect = testFixture.expect,
|
||||
logger = testFixture.logger.fork('GenerateExecFile'),
|
||||
PluginCliManager = testFixture.WebGME.PluginCliManager,
|
||||
projectName = 'testProject',
|
||||
pluginName = 'GenerateExecFile',
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
commitHash;
|
||||
|
||||
before(function (done) {
|
||||
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
|
||||
.then(function (gmeAuth_) {
|
||||
gmeAuth = gmeAuth_;
|
||||
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
|
||||
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
|
||||
return storage.openDatabase();
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'EmptyProject.webgmex'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
gmeConfig: gmeConfig
|
||||
};
|
||||
|
||||
return testFixture.importProject(storage, importParam);
|
||||
})
|
||||
.then(function (importResult) {
|
||||
project = importResult.project;
|
||||
commitHash = importResult.commitHash;
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
storage.closeDatabase()
|
||||
.then(function () {
|
||||
return gmeAuth.unload();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should run plugin and update the branch', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211',
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal(null);
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
expect(branchHash).to.not.equal(commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -8,7 +8,7 @@ var testFixture = require('../../globals'),
|
||||
path = testFixture.path,
|
||||
BASE_DIR = testFixture.DF_SEED_DIR;
|
||||
|
||||
describe('GenerateYaml', function () {
|
||||
describe.skip('GenerateYaml', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
expect = testFixture.expect,
|
||||
logger = testFixture.logger.fork('GenerateYaml'),
|
||||
@@ -64,7 +64,7 @@ describe('GenerateYaml', function () {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/4'
|
||||
activeNode: ''
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*jshint node:true, mocha:true*/
|
||||
/**
|
||||
* Generated by PluginGenerator 1.7.0 from webgme on Tue Jun 07 2016 11:25:09 GMT-0500 (CDT).
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
var testFixture = require('../../globals');
|
||||
|
||||
describe.skip('ImportArtifact', function () {
|
||||
var gmeConfig = testFixture.getGmeConfig(),
|
||||
expect = testFixture.expect,
|
||||
logger = testFixture.logger.fork('ImportArtifact'),
|
||||
PluginCliManager = testFixture.WebGME.PluginCliManager,
|
||||
projectName = 'testProject',
|
||||
pluginName = 'ImportArtifact',
|
||||
project,
|
||||
gmeAuth,
|
||||
storage,
|
||||
commitHash;
|
||||
|
||||
before(function (done) {
|
||||
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
|
||||
.then(function (gmeAuth_) {
|
||||
gmeAuth = gmeAuth_;
|
||||
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
|
||||
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
|
||||
return storage.openDatabase();
|
||||
})
|
||||
.then(function () {
|
||||
var importParam = {
|
||||
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'EmptyProject.webgmex'),
|
||||
projectName: projectName,
|
||||
branchName: 'master',
|
||||
logger: logger,
|
||||
gmeConfig: gmeConfig
|
||||
};
|
||||
|
||||
return testFixture.importProject(storage, importParam);
|
||||
})
|
||||
.then(function (importResult) {
|
||||
project = importResult.project;
|
||||
commitHash = importResult.commitHash;
|
||||
return project.createBranch('test', commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
after(function (done) {
|
||||
storage.closeDatabase()
|
||||
.then(function () {
|
||||
return gmeAuth.unload();
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
|
||||
it('should run plugin and update the branch', function (done) {
|
||||
var manager = new PluginCliManager(null, logger, gmeConfig),
|
||||
pluginConfig = {
|
||||
},
|
||||
context = {
|
||||
project: project,
|
||||
commitHash: commitHash,
|
||||
branchName: 'test',
|
||||
activeNode: '/960660211',
|
||||
};
|
||||
|
||||
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
|
||||
expect(err).to.equal(null);
|
||||
expect(typeof pluginResult).to.equal('object');
|
||||
expect(pluginResult.success).to.equal(true);
|
||||
|
||||
project.getBranchHash('test')
|
||||
.then(function (branchHash) {
|
||||
expect(branchHash).to.not.equal(commitHash);
|
||||
})
|
||||
.nodeify(done);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -19,6 +19,7 @@ var testFixture = require('../../globals'),
|
||||
'basic4.lua'
|
||||
],
|
||||
ONLY_TESTS = [
|
||||
'vgg.lua'
|
||||
];
|
||||
|
||||
describe('ImportTorch', function () {
|
||||
|
||||
@@ -54,7 +54,7 @@ describe('ImportYaml', function () {
|
||||
checker = new GraphChecker({
|
||||
core: core,
|
||||
ignore: {
|
||||
attributes: ['calculateDimensionality', 'dimensionalityTransform']
|
||||
attributes: []
|
||||
}
|
||||
});
|
||||
return project.createBranch('test', commitHash);
|
||||
@@ -167,7 +167,7 @@ describe('ImportYaml', function () {
|
||||
};
|
||||
|
||||
describe('run test cases', function() {
|
||||
var cases = fs.readdirSync(YAML_DIR)
|
||||
var cases = ['vgg.yml'] // fs.readdirSync(YAML_DIR)
|
||||
.filter(name => path.extname(name) === '.yml');
|
||||
|
||||
// one test for each test name
|
||||
|
||||
@@ -24,9 +24,9 @@ concat:add(conv3xx)
|
||||
local pool = nn.Sequential()
|
||||
pool:add(nn.SpatialZeroPadding(1,1,1,1)) -- remove after getting nn R2 into fbcode
|
||||
if config[4][1] == 'max' then
|
||||
pool:add(nn.SpatialMaxPooling(3,3,1,1):ceil())
|
||||
pool:add(nn.SpatialMaxPooling(3,3,1,1))
|
||||
elseif config[4][1] == 'avg' then
|
||||
pool:add(nn.SpatialAveragePooling(3,3,1,1):ceil())
|
||||
pool:add(nn.SpatialAveragePooling(3,3,1,1))
|
||||
else
|
||||
error('Unknown pooling')
|
||||
end
|
||||
@@ -40,10 +40,10 @@ end
|
||||
|
||||
local features = nn.Sequential()
|
||||
features:add(nn.SpatialConvolution(3,64,7,7,2,2,3,3)):add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2):ceil())
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2))
|
||||
features:add(nn.SpatialConvolution(64,64,1,1)):add(nn.ReLU(true))
|
||||
features:add(nn.SpatialConvolution(64,192,3,3,1,1,1,1)):add(nn.ReLU(true))
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2):ceil())
|
||||
features:add(nn.SpatialMaxPooling(3,3,2,2))
|
||||
features:add(inception( 192, {{ 64},{ 64, 64},{ 64, 96},{'avg', 32}})) -- 3(a)
|
||||
features:add(inception( 256, {{ 64},{ 64, 96},{ 64, 96},{'avg', 64}})) -- 3(b)
|
||||
features:add(inception( 320, {{ 0},{128,160},{ 64, 96},{'max', 0}})) -- 3(c)
|
||||
@@ -59,15 +59,15 @@ main_branch:add(nn.SpatialConvolution(1024,1024,2,2,2,2))
|
||||
main_branch:add(inception(1024, {{352},{192,320},{160,224},{'avg',128}})) -- 5(a)
|
||||
main_branch:add(inception(1024, {{352},{192,320},{192,224},{'max',128}})) -- 5(b)
|
||||
main_branch:add(nn.SpatialAveragePooling(7,7,1,1))
|
||||
main_branch:add(nn.View(1024):setNumInputDims(3))
|
||||
main_branch:add(nn.View(1024))
|
||||
main_branch:add(nn.Linear(1024,nClasses))
|
||||
main_branch:add(nn.LogSoftMax())
|
||||
|
||||
-- add auxillary classifier here (thanks to Christian Szegedy for the details)
|
||||
local aux_classifier = nn.Sequential()
|
||||
aux_classifier:add(nn.SpatialAveragePooling(5,5,3,3):ceil())
|
||||
aux_classifier:add(nn.SpatialAveragePooling(5,5,3,3))
|
||||
aux_classifier:add(nn.SpatialConvolution(576,128,1,1,1,1))
|
||||
aux_classifier:add(nn.View(128*4*4):setNumInputDims(3))
|
||||
aux_classifier:add(nn.View(128*4*4))
|
||||
aux_classifier:add(nn.Linear(128*4*4,768))
|
||||
aux_classifier:add(nn.ReLU())
|
||||
aux_classifier:add(nn.Linear(768,nClasses))
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
require 'nn'
|
||||
|
||||
local net = nn.Sequential()
|
||||
net:add(nn.Reshape(100))
|
||||
|
||||
local net_2 = nn.Sequential()
|
||||
net_2:add(nn.Linear(100, 150))
|
||||
net_2:add(nn.Tanh())
|
||||
net_2:add(nn.Linear(150, 50))
|
||||
|
||||
local net_3 = nn.Sequential()
|
||||
net_3:add(nn.Linear(100, 150))
|
||||
net_3:add(nn.Tanh())
|
||||
net_3:add(nn.Linear(150, 30))
|
||||
|
||||
local concat_7 = nn.Concat(1)
|
||||
concat_7:add(net_3)
|
||||
concat_7:add(net_2)
|
||||
|
||||
net:add(concat_7)
|
||||
net:add(nn.Tanh())
|
||||
net:add(nn.Linear(80, 7))
|
||||
|
||||
return net
|
||||
@@ -0,0 +1,341 @@
|
||||
require 'nn'
|
||||
|
||||
local net = nn.Sequential()
|
||||
net:add(nn.SpatialConvolution(3, 64, 7, 7, 2, 2, 3, 3))
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialMaxPooling(3, 3, 2, 2))
|
||||
net:add(nn.SpatialConvolution(64, 64, 1, 1))
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialConvolution(64, 192, 3, 3, 1, 1, 1, 1))
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialMaxPooling(3, 3, 2, 2))
|
||||
|
||||
local net_2 = nn.Sequential()
|
||||
net_2:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1))
|
||||
net_2:add(nn.ReLU(true))
|
||||
net_2:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_2:add(nn.ReLU(true))
|
||||
net_2:add(nn.SpatialConvolution(96, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_2:add(nn.ReLU(true))
|
||||
|
||||
local net_3 = nn.Sequential()
|
||||
net_3:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1))
|
||||
net_3:add(nn.ReLU(true))
|
||||
|
||||
local net_4 = nn.Sequential()
|
||||
net_4:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1))
|
||||
net_4:add(nn.ReLU(true))
|
||||
net_4:add(nn.SpatialConvolution(64, 64, 3, 3, 1, 1, 1, 1))
|
||||
net_4:add(nn.ReLU(true))
|
||||
|
||||
local net_5 = nn.Sequential()
|
||||
net_5:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_5:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_5:add(nn.SpatialConvolution(192, 32, 1, 1, 1, 1))
|
||||
net_5:add(nn.ReLU(true))
|
||||
|
||||
local concat_24 = nn.Concat(2)
|
||||
concat_24:add(net_5)
|
||||
concat_24:add(net_4)
|
||||
concat_24:add(net_3)
|
||||
concat_24:add(net_2)
|
||||
|
||||
net:add(concat_24)
|
||||
|
||||
local net_6 = nn.Sequential()
|
||||
net_6:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
|
||||
net_6:add(nn.ReLU(true))
|
||||
|
||||
local net_7 = nn.Sequential()
|
||||
net_7:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
|
||||
net_7:add(nn.ReLU(true))
|
||||
net_7:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_7:add(nn.ReLU(true))
|
||||
|
||||
local net_8 = nn.Sequential()
|
||||
net_8:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
|
||||
net_8:add(nn.ReLU(true))
|
||||
net_8:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_8:add(nn.ReLU(true))
|
||||
net_8:add(nn.SpatialConvolution(96, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_8:add(nn.ReLU(true))
|
||||
|
||||
local net_9 = nn.Sequential()
|
||||
net_9:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_9:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_9:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
|
||||
net_9:add(nn.ReLU(true))
|
||||
|
||||
local concat_41 = nn.Concat(2)
|
||||
concat_41:add(net_9)
|
||||
concat_41:add(net_8)
|
||||
concat_41:add(net_7)
|
||||
concat_41:add(net_6)
|
||||
|
||||
net:add(concat_41)
|
||||
|
||||
local net_10 = nn.Sequential()
|
||||
net_10:add(nn.SpatialConvolution(320, 128, 1, 1, 1, 1))
|
||||
net_10:add(nn.ReLU(true))
|
||||
net_10:add(nn.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
|
||||
net_10:add(nn.ReLU(true))
|
||||
|
||||
local net_11 = nn.Sequential()
|
||||
net_11:add(nn.SpatialConvolution(320, 64, 1, 1, 1, 1))
|
||||
net_11:add(nn.ReLU(true))
|
||||
net_11:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_11:add(nn.ReLU(true))
|
||||
net_11:add(nn.SpatialConvolution(96, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_11:add(nn.ReLU(true))
|
||||
|
||||
local net_12 = nn.Sequential()
|
||||
net_12:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_12:add(nn.SpatialMaxPooling(3, 3, 1, 1))
|
||||
|
||||
local concat_54 = nn.Concat(2)
|
||||
concat_54:add(net_12)
|
||||
concat_54:add(net_11)
|
||||
concat_54:add(net_10)
|
||||
|
||||
net:add(concat_54)
|
||||
net:add(nn.SpatialConvolution(576, 576, 2, 2, 2, 2))
|
||||
|
||||
local net_13 = nn.Sequential()
|
||||
net_13:add(nn.SpatialConvolution(576, 224, 1, 1, 1, 1))
|
||||
net_13:add(nn.ReLU(true))
|
||||
|
||||
local net_14 = nn.Sequential()
|
||||
net_14:add(nn.SpatialConvolution(576, 64, 1, 1, 1, 1))
|
||||
net_14:add(nn.ReLU(true))
|
||||
net_14:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
|
||||
net_14:add(nn.ReLU(true))
|
||||
|
||||
local net_15 = nn.Sequential()
|
||||
net_15:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
|
||||
net_15:add(nn.ReLU(true))
|
||||
net_15:add(nn.SpatialConvolution(96, 128, 3, 3, 1, 1, 1, 1))
|
||||
net_15:add(nn.ReLU(true))
|
||||
net_15:add(nn.SpatialConvolution(128, 128, 3, 3, 1, 1, 1, 1))
|
||||
net_15:add(nn.ReLU(true))
|
||||
|
||||
local net_16 = nn.Sequential()
|
||||
net_16:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_16:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_16:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_16:add(nn.ReLU(true))
|
||||
|
||||
local concat_72 = nn.Concat(2)
|
||||
concat_72:add(net_16)
|
||||
concat_72:add(net_15)
|
||||
concat_72:add(net_14)
|
||||
concat_72:add(net_13)
|
||||
|
||||
net:add(concat_72)
|
||||
|
||||
local net_17 = nn.Sequential()
|
||||
net_17:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1))
|
||||
net_17:add(nn.ReLU(true))
|
||||
|
||||
local net_18 = nn.Sequential()
|
||||
net_18:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
|
||||
net_18:add(nn.ReLU(true))
|
||||
net_18:add(nn.SpatialConvolution(96, 128, 3, 3, 1, 1, 1, 1))
|
||||
net_18:add(nn.ReLU(true))
|
||||
|
||||
local net_19 = nn.Sequential()
|
||||
net_19:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
|
||||
net_19:add(nn.ReLU(true))
|
||||
net_19:add(nn.SpatialConvolution(96, 128, 3, 3, 1, 1, 1, 1))
|
||||
net_19:add(nn.ReLU(true))
|
||||
net_19:add(nn.SpatialConvolution(128, 128, 3, 3, 1, 1, 1, 1))
|
||||
net_19:add(nn.ReLU(true))
|
||||
|
||||
local net_20 = nn.Sequential()
|
||||
net_20:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_20:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_20:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_20:add(nn.ReLU(true))
|
||||
|
||||
local concat_89 = nn.Concat(2)
|
||||
concat_89:add(net_20)
|
||||
concat_89:add(net_19)
|
||||
concat_89:add(net_18)
|
||||
concat_89:add(net_17)
|
||||
|
||||
net:add(concat_89)
|
||||
|
||||
local net_21 = nn.Sequential()
|
||||
net_21:add(nn.SpatialConvolution(576, 160, 1, 1, 1, 1))
|
||||
net_21:add(nn.ReLU(true))
|
||||
|
||||
local net_22 = nn.Sequential()
|
||||
net_22:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_22:add(nn.ReLU(true))
|
||||
net_22:add(nn.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
|
||||
net_22:add(nn.ReLU(true))
|
||||
|
||||
local net_23 = nn.Sequential()
|
||||
net_23:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_23:add(nn.ReLU(true))
|
||||
net_23:add(nn.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
|
||||
net_23:add(nn.ReLU(true))
|
||||
net_23:add(nn.SpatialConvolution(160, 160, 3, 3, 1, 1, 1, 1))
|
||||
net_23:add(nn.ReLU(true))
|
||||
|
||||
local net_24 = nn.Sequential()
|
||||
net_24:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_24:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_24:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
|
||||
net_24:add(nn.ReLU(true))
|
||||
|
||||
local concat_106 = nn.Concat(2)
|
||||
concat_106:add(net_24)
|
||||
concat_106:add(net_23)
|
||||
concat_106:add(net_22)
|
||||
concat_106:add(net_21)
|
||||
|
||||
net:add(concat_106)
|
||||
|
||||
local net_25 = nn.Sequential()
|
||||
net_25:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
|
||||
net_25:add(nn.ReLU(true))
|
||||
|
||||
local net_26 = nn.Sequential()
|
||||
net_26:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_26:add(nn.ReLU(true))
|
||||
net_26:add(nn.SpatialConvolution(128, 192, 3, 3, 1, 1, 1, 1))
|
||||
net_26:add(nn.ReLU(true))
|
||||
|
||||
local net_27 = nn.Sequential()
|
||||
net_27:add(nn.SpatialConvolution(576, 160, 1, 1, 1, 1))
|
||||
net_27:add(nn.ReLU(true))
|
||||
net_27:add(nn.SpatialConvolution(160, 192, 3, 3, 1, 1, 1, 1))
|
||||
net_27:add(nn.ReLU(true))
|
||||
net_27:add(nn.SpatialConvolution(192, 192, 3, 3, 1, 1, 1, 1))
|
||||
net_27:add(nn.ReLU(true))
|
||||
|
||||
local net_28 = nn.Sequential()
|
||||
net_28:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_28:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_28:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
|
||||
net_28:add(nn.ReLU(true))
|
||||
|
||||
local concat_123 = nn.Concat(2)
|
||||
concat_123:add(net_28)
|
||||
concat_123:add(net_27)
|
||||
concat_123:add(net_26)
|
||||
concat_123:add(net_25)
|
||||
|
||||
net:add(concat_123)
|
||||
|
||||
local net_29 = nn.Sequential()
|
||||
net_29:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1))
|
||||
net_29:add(nn.ReLU(true))
|
||||
net_29:add(nn.SpatialConvolution(192, 256, 3, 3, 1, 1, 1, 1))
|
||||
net_29:add(nn.ReLU(true))
|
||||
net_29:add(nn.SpatialConvolution(256, 256, 3, 3, 1, 1, 1, 1))
|
||||
net_29:add(nn.ReLU(true))
|
||||
|
||||
local net_30 = nn.Sequential()
|
||||
net_30:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_30:add(nn.SpatialMaxPooling(3, 3, 1, 1))
|
||||
|
||||
local net_31 = nn.Sequential()
|
||||
net_31:add(nn.SpatialAveragePooling(5, 5, 3, 3))
|
||||
net_31:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_31:add(nn.View())
|
||||
net_31:add(nn.Linear(2048, 768))
|
||||
net_31:add(nn.ReLU())
|
||||
net_31:add(nn.Linear(768, 4))
|
||||
net_31:add(nn.LogSoftMax())
|
||||
|
||||
local net_32 = nn.Sequential()
|
||||
net_32:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
|
||||
net_32:add(nn.ReLU(true))
|
||||
net_32:add(nn.SpatialConvolution(128, 192, 3, 3, 1, 1, 1, 1))
|
||||
net_32:add(nn.ReLU(true))
|
||||
|
||||
local concat_136 = nn.Concat(2)
|
||||
concat_136:add(net_32)
|
||||
concat_136:add(net_30)
|
||||
concat_136:add(net_29)
|
||||
|
||||
net:add(concat_136)
|
||||
local net_33 = nn.Sequential()
|
||||
net_33:add(nn.SpatialConvolution(1024, 1024, 2, 2, 2, 2))
|
||||
|
||||
local net_34 = nn.Sequential()
|
||||
net_34:add(nn.SpatialConvolution(1024, 352, 1, 1, 1, 1))
|
||||
net_34:add(nn.ReLU(true))
|
||||
|
||||
local net_35 = nn.Sequential()
|
||||
net_35:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
|
||||
net_35:add(nn.ReLU(true))
|
||||
net_35:add(nn.SpatialConvolution(192, 320, 3, 3, 1, 1, 1, 1))
|
||||
net_35:add(nn.ReLU(true))
|
||||
|
||||
local net_36 = nn.Sequential()
|
||||
net_36:add(nn.SpatialConvolution(1024, 160, 1, 1, 1, 1))
|
||||
net_36:add(nn.ReLU(true))
|
||||
net_36:add(nn.SpatialConvolution(160, 224, 3, 3, 1, 1, 1, 1))
|
||||
net_36:add(nn.ReLU(true))
|
||||
net_36:add(nn.SpatialConvolution(224, 224, 3, 3, 1, 1, 1, 1))
|
||||
net_36:add(nn.ReLU(true))
|
||||
|
||||
local net_37 = nn.Sequential()
|
||||
net_37:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_37:add(nn.SpatialAveragePooling(3, 3, 1, 1))
|
||||
net_37:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1))
|
||||
net_37:add(nn.ReLU(true))
|
||||
|
||||
local concat_154 = nn.Concat(2)
|
||||
concat_154:add(net_37)
|
||||
concat_154:add(net_36)
|
||||
concat_154:add(net_35)
|
||||
concat_154:add(net_34)
|
||||
|
||||
net_33:add(concat_154)
|
||||
|
||||
local net_38 = nn.Sequential()
|
||||
net_38:add(nn.SpatialConvolution(1024, 352, 1, 1, 1, 1))
|
||||
net_38:add(nn.ReLU(true))
|
||||
|
||||
local net_39 = nn.Sequential()
|
||||
net_39:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
|
||||
net_39:add(nn.ReLU(true))
|
||||
net_39:add(nn.SpatialConvolution(192, 320, 3, 3, 1, 1, 1, 1))
|
||||
net_39:add(nn.ReLU(true))
|
||||
|
||||
local net_40 = nn.Sequential()
|
||||
net_40:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
|
||||
net_40:add(nn.ReLU(true))
|
||||
net_40:add(nn.SpatialConvolution(192, 224, 3, 3, 1, 1, 1, 1))
|
||||
net_40:add(nn.ReLU(true))
|
||||
net_40:add(nn.SpatialConvolution(224, 224, 3, 3, 1, 1, 1, 1))
|
||||
net_40:add(nn.ReLU(true))
|
||||
|
||||
local net_41 = nn.Sequential()
|
||||
net_41:add(nn.SpatialZeroPadding(1, 1, 1, 1))
|
||||
net_41:add(nn.SpatialMaxPooling(3, 3, 1, 1))
|
||||
net_41:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1))
|
||||
net_41:add(nn.ReLU(true))
|
||||
|
||||
local concat_171 = nn.Concat(2)
|
||||
concat_171:add(net_41)
|
||||
concat_171:add(net_40)
|
||||
concat_171:add(net_39)
|
||||
concat_171:add(net_38)
|
||||
|
||||
net_33:add(concat_171)
|
||||
net_33:add(nn.SpatialAveragePooling(7, 7, 1, 1))
|
||||
net_33:add(nn.View())
|
||||
net_33:add(nn.Linear(1024, 4))
|
||||
net_33:add(nn.LogSoftMax())
|
||||
|
||||
local concat_183 = nn.Concat(2)
|
||||
concat_183:add(net_33)
|
||||
concat_183:add(net_31)
|
||||
|
||||
net:add(concat_183)
|
||||
|
||||
return net
|
||||
@@ -2,25 +2,25 @@ require 'nn'
|
||||
|
||||
local net = nn.Sequential()
|
||||
net:add(nn.SpatialConvolution(3, 96, 11, 11, 4, 4))
|
||||
net:add(nn.ReLU())
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
|
||||
net:add(nn.SpatialConvolution(96, 256, 5, 5, 1, 1))
|
||||
net:add(nn.ReLU())
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
|
||||
net:add(nn.SpatialConvolution(256, 512, 3, 3, 1, 1))
|
||||
net:add(nn.ReLU())
|
||||
net:add(nn.SpatialConvolution(512, 1024, 3, 3, 1, 1))
|
||||
net:add(nn.ReLU())
|
||||
net:add(nn.SpatialConvolution(1024, 1024, 3, 3, 1, 1))
|
||||
net:add(nn.ReLU())
|
||||
net:add(nn.SpatialConvolution(256, 512, 3, 3, 1, 1, 1, 1))
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialConvolution(512, 1024, 3, 3, 1, 1, 1, 1))
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialConvolution(1024, 1024, 3, 3, 1, 1, 1, 1))
|
||||
net:add(nn.ReLU(true))
|
||||
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
|
||||
net:add(nn.View(25600))
|
||||
net:add(nn.View())
|
||||
net:add(nn.Dropout(0.5))
|
||||
net:add(nn.Linear(25600, 3072))
|
||||
net:add(nn.Threshold(0, 0.000001, false))
|
||||
net:add(nn.Threshold(0, 0.000001))
|
||||
net:add(nn.Dropout(0.5))
|
||||
net:add(nn.Linear(3072, 4096))
|
||||
net:add(nn.Threshold(0, 0.000001, false))
|
||||
net:add(nn.Threshold(0, 0.000001))
|
||||
net:add(nn.Linear(4096, 7))
|
||||
net:add(nn.LogSoftMax())
|
||||
|
||||
|
||||
+242
-262
@@ -1,292 +1,272 @@
|
||||
- type: Threshold
|
||||
id: /Y/1
|
||||
next:
|
||||
- /Y/C
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
inplace: false
|
||||
value: 0.000001
|
||||
threshold: 0
|
||||
- type: LogSoftMax
|
||||
id: /Y/19
|
||||
next: []
|
||||
attributes: {}
|
||||
- type: SpatialConvolution
|
||||
id: /Y/2
|
||||
id: /Y/3
|
||||
next:
|
||||
- /Y/hb
|
||||
attributes:
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 256
|
||||
- type: SpatialConvolution
|
||||
id: /Y/4
|
||||
next:
|
||||
- /Y/8
|
||||
attributes:
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 64
|
||||
nInputPlane: 3
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/6
|
||||
next:
|
||||
- /Y/IL
|
||||
attributes:
|
||||
padW: ''
|
||||
padH: ''
|
||||
dH: 2
|
||||
dW: 2
|
||||
kH: 2
|
||||
kW: 2
|
||||
- type: ReLU
|
||||
id: /Y/8
|
||||
next:
|
||||
- /Y/l
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: SpatialConvolution
|
||||
id: /Y/5
|
||||
next:
|
||||
- /Y/O
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 128
|
||||
- type: SpatialConvolution
|
||||
id: /Y/6
|
||||
next:
|
||||
- /Y/9k
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: Dropout
|
||||
id: /Y/8C
|
||||
next:
|
||||
- /Y/W
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
probability: 0.5
|
||||
- type: ReLU
|
||||
id: /Y/9k
|
||||
next:
|
||||
- /Y/T
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
- type: Dropout
|
||||
id: /Y/C
|
||||
next:
|
||||
- /Y/CC
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
probability: 0.5
|
||||
- type: Linear
|
||||
id: /Y/CC
|
||||
next:
|
||||
- /Y/qU
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
output: 4096
|
||||
input: 4096
|
||||
- type: ReLU
|
||||
id: /Y/D
|
||||
next:
|
||||
- /Y/X
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
- type: SpatialConvolution
|
||||
id: /Y/H
|
||||
next:
|
||||
- /Y/t
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 64
|
||||
nInputPlane: 3
|
||||
- type: ReLU
|
||||
id: /Y/J
|
||||
next:
|
||||
- /Y/2
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
p: true
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/K
|
||||
next:
|
||||
- /Y/h
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 2
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: ReLU
|
||||
id: /Y/M
|
||||
id: /Y/9
|
||||
next:
|
||||
- /Y/K
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
- type: ReLU
|
||||
id: /Y/O
|
||||
next:
|
||||
- /Y/Y
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
padW: ''
|
||||
padH: ''
|
||||
dH: 2
|
||||
dW: 2
|
||||
kH: 2
|
||||
kW: 2
|
||||
- type: SpatialConvolution
|
||||
id: /Y/T
|
||||
id: /Y/A
|
||||
next:
|
||||
- /Y/M
|
||||
- /Y/y
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: SpatialConvolution
|
||||
id: /Y/U
|
||||
next:
|
||||
- /Y/J
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 256
|
||||
- type: Linear
|
||||
id: /Y/W
|
||||
next:
|
||||
- /Y/xG
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
output: 10
|
||||
input: 4096
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/X
|
||||
next:
|
||||
- /Y/U
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 2
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: SpatialConvolution
|
||||
id: /Y/Y
|
||||
next:
|
||||
- /Y/D
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 256
|
||||
- type: SpatialConvolution
|
||||
id: /Y/a
|
||||
next:
|
||||
- /Y/v
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 1
|
||||
strideWidth: 1
|
||||
kernelHeight: 3
|
||||
kernelWidth: 3
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 128
|
||||
nInputPlane: 64
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/e
|
||||
next:
|
||||
- /Y/5
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 2
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: View
|
||||
id: /Y/h
|
||||
next:
|
||||
- /Y/zb
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
sizes: 25088
|
||||
- type: ReLU
|
||||
id: /Y/l
|
||||
- type: Threshold
|
||||
id: /Y/Cg
|
||||
next:
|
||||
- /Y/z
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
- type: Threshold
|
||||
id: /Y/qU
|
||||
ip: ''
|
||||
v: 0.000001
|
||||
th: 0
|
||||
- type: Linear
|
||||
id: /Y/D
|
||||
next:
|
||||
- /Y/8C
|
||||
- /Y/f4
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
inplace: false
|
||||
value: 0.000001
|
||||
threshold: 0
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/r
|
||||
next:
|
||||
- /Y/a
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 2
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
bias: ''
|
||||
outputSize: 4096
|
||||
inputSize: 25088
|
||||
- type: ReLU
|
||||
id: /Y/t
|
||||
id: /Y/EE
|
||||
next:
|
||||
- /Y/r
|
||||
- /Y/v
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
- type: ReLU
|
||||
id: /Y/v
|
||||
p: true
|
||||
- type: SpatialConvolution
|
||||
id: /Y/IL
|
||||
next:
|
||||
- /Y/e
|
||||
- /Y/EE
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
- type: LogSoftMax
|
||||
id: /Y/xG
|
||||
next: []
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: SpatialConvolution
|
||||
id: /Y/K
|
||||
next:
|
||||
- /Y/m
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 128
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/z
|
||||
id: /Y/M
|
||||
next:
|
||||
- /Y/a5
|
||||
attributes:
|
||||
padW: ''
|
||||
padH: ''
|
||||
dH: 2
|
||||
dW: 2
|
||||
kH: 2
|
||||
kW: 2
|
||||
- type: Linear
|
||||
id: /Y/Q
|
||||
next:
|
||||
- /Y/19
|
||||
attributes:
|
||||
bias: ''
|
||||
outputSize: 10
|
||||
inputSize: 4096
|
||||
- type: ReLU
|
||||
id: /Y/R
|
||||
next:
|
||||
- /Y/M
|
||||
attributes:
|
||||
p: true
|
||||
- type: ReLU
|
||||
id: /Y/T
|
||||
next:
|
||||
- /Y/6
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
strideHeight: 2
|
||||
strideWidth: 2
|
||||
kernelHeight: 2
|
||||
kernelWidth: 2
|
||||
- type: Linear
|
||||
id: /Y/zb
|
||||
p: true
|
||||
- type: Dropout
|
||||
id: /Y/U7
|
||||
next:
|
||||
- /Y/1
|
||||
- /Y/k
|
||||
attributes:
|
||||
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
|
||||
dimensionalityTransform: same
|
||||
output: 4096
|
||||
input: 25088
|
||||
v1: ''
|
||||
inplace: ''
|
||||
p: 0.5
|
||||
- type: View
|
||||
id: /Y/a5
|
||||
next:
|
||||
- /Y/D
|
||||
attributes: {}
|
||||
- type: Threshold
|
||||
id: /Y/f4
|
||||
next:
|
||||
- /Y/U7
|
||||
attributes:
|
||||
ip: ''
|
||||
v: 0.000001
|
||||
th: 0
|
||||
- type: ReLU
|
||||
id: /Y/h
|
||||
next:
|
||||
- /Y/j
|
||||
attributes:
|
||||
p: true
|
||||
- type: ReLU
|
||||
id: /Y/hb
|
||||
next:
|
||||
- /Y/l4
|
||||
attributes:
|
||||
p: true
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/j
|
||||
next:
|
||||
- /Y/3
|
||||
attributes:
|
||||
padW: ''
|
||||
padH: ''
|
||||
dH: 2
|
||||
dW: 2
|
||||
kH: 2
|
||||
kW: 2
|
||||
- type: Linear
|
||||
id: /Y/k
|
||||
next:
|
||||
- /Y/Cg
|
||||
attributes:
|
||||
bias: ''
|
||||
outputSize: 4096
|
||||
inputSize: 4096
|
||||
- type: SpatialMaxPooling
|
||||
id: /Y/l
|
||||
next:
|
||||
- /Y/A
|
||||
attributes:
|
||||
padW: ''
|
||||
padH: ''
|
||||
dH: 2
|
||||
dW: 2
|
||||
kH: 2
|
||||
kW: 2
|
||||
- type: SpatialConvolution
|
||||
id: /Y/l4
|
||||
next:
|
||||
- /Y/T
|
||||
attributes:
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: ReLU
|
||||
id: /Y/m
|
||||
next:
|
||||
- /Y/x
|
||||
attributes:
|
||||
p: true
|
||||
- type: SpatialConvolution
|
||||
id: /Y/v
|
||||
next:
|
||||
- /Y/R
|
||||
attributes:
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 512
|
||||
nInputPlane: 512
|
||||
- type: SpatialConvolution
|
||||
id: /Y/x
|
||||
next:
|
||||
- /Y/h
|
||||
attributes:
|
||||
padH: 1
|
||||
padW: 1
|
||||
dH: 1
|
||||
dW: 1
|
||||
kH: 3
|
||||
kW: 3
|
||||
nOutputPlane: 256
|
||||
nInputPlane: 256
|
||||
- type: ReLU
|
||||
id: /Y/y
|
||||
next:
|
||||
- /Y/9
|
||||
attributes:
|
||||
p: true
|
||||
- type: Dropout
|
||||
id: /Y/z
|
||||
next:
|
||||
- /Y/Q
|
||||
attributes:
|
||||
v1: ''
|
||||
inplace: ''
|
||||
p: 0.5
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
{
|
||||
"Convolution": [
|
||||
"TemporalConvolution",
|
||||
"TemporalMaxPooling",
|
||||
"TemporalSubSampling",
|
||||
"LookupTable",
|
||||
"SpatialConvolutionMM",
|
||||
"SpatialConvolution",
|
||||
"SpatialConvolutionMap",
|
||||
"SpatialFullConvolutionMap",
|
||||
"SpatialLPPooling",
|
||||
"SpatialMaxPooling",
|
||||
"SpatialAveragePooling",
|
||||
"SpatialAdaptiveMaxPooling",
|
||||
"SpatialSubSampling",
|
||||
"SpatialUpSamplingNearest",
|
||||
"SpatialZeroPadding",
|
||||
"SpatialReflectionPadding",
|
||||
"SpatialReplicationPadding",
|
||||
"SpatialSubtractiveNormalization",
|
||||
"SpatialCrossMapLRN",
|
||||
"SpatialConvolutionLocal",
|
||||
"SpatialDropout",
|
||||
"SpatialDilatedConvolution",
|
||||
"SpatialFractionalMaxPooling",
|
||||
"SpatialDivisiveNormalization",
|
||||
"SpatialContrastiveNormalization",
|
||||
"SpatialBatchNormalization",
|
||||
"SpatialFullConvolution",
|
||||
"SpatialMaxUnpooling",
|
||||
"VolumetricConvolution",
|
||||
"VolumetricMaxPooling",
|
||||
"VolumetricAveragePooling",
|
||||
"VolumetricBatchNormalization",
|
||||
"VolumetricDropout",
|
||||
|
||||
"VolumetricFullConvolution",
|
||||
"VolumetricMaxUnpooling"
|
||||
],
|
||||
"Containers": [
|
||||
"Concat"
|
||||
],
|
||||
"Criterion": [
|
||||
"BCECriterion",
|
||||
"WeightedMSECriterion",
|
||||
"SmoothL1Criterion",
|
||||
"MSECriterion",
|
||||
"AbsCriterion",
|
||||
"MultiCriterion",
|
||||
"DistKLDivCriterion",
|
||||
"HingeEmbeddingCriterion",
|
||||
"CriterionTable",
|
||||
"MultiMarginCriterion",
|
||||
"MultiLabelMarginCriterion",
|
||||
"L1HingeEmbeddingCriterion",
|
||||
"CosineEmbeddingCriterion",
|
||||
"MarginRankingCriterion",
|
||||
"CrossEntropyCriterion",
|
||||
"MarginCriterion",
|
||||
"ClassNLLCriterion",
|
||||
"ParallelCriterion",
|
||||
"SpatialClassNLLCriterion",
|
||||
"SoftMarginCriterion",
|
||||
"MultiLabelSoftMarginCriterion"
|
||||
],
|
||||
"Simple": [
|
||||
"Linear",
|
||||
"SparseLinear",
|
||||
"Dropout",
|
||||
"Abs",
|
||||
"Add",
|
||||
"Mul",
|
||||
"CMul",
|
||||
"Max",
|
||||
"Min",
|
||||
"Mean",
|
||||
"Sum",
|
||||
"Euclidean",
|
||||
"WeightedEuclidean",
|
||||
"Identity",
|
||||
"Copy",
|
||||
"Narrow",
|
||||
"Replicate",
|
||||
"Reshape",
|
||||
"View",
|
||||
"Select",
|
||||
"Exp",
|
||||
"Square",
|
||||
"Sqrt",
|
||||
"Power",
|
||||
"MM",
|
||||
"AddConstant",
|
||||
"MulConstant"
|
||||
],
|
||||
"Transfer": [
|
||||
"Threshold",
|
||||
"HardTanh",
|
||||
"HardShrink",
|
||||
"SoftShrink",
|
||||
"SoftMax",
|
||||
"SpatialSoftMax",
|
||||
"SoftMin",
|
||||
"SoftPlus",
|
||||
"SoftSign",
|
||||
"LogSigmoid",
|
||||
"LogSoftMax",
|
||||
"Sigmoid",
|
||||
"Tanh",
|
||||
"ReLU",
|
||||
"PReLU",
|
||||
"RReLU",
|
||||
"LeakyReLU"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var parser = require('../src/common/lua').parser;
|
||||
var torchPath = process.env.HOME + '/torch/extra/nn/';
|
||||
var SKIP_LAYERS = {};
|
||||
var skipLayerList = require('./skipLayers.json');
|
||||
skipLayerList.forEach(name => SKIP_LAYERS[name] = true);
|
||||
|
||||
var findInitParams = function(ast){
|
||||
// Find '__init' function
|
||||
var params;
|
||||
ast.block.stats.forEach(function(block){
|
||||
if(block.key && block.key.val == '__init' && block.func){
|
||||
params = block.func.args;
|
||||
}
|
||||
});
|
||||
return params;
|
||||
};
|
||||
|
||||
var findTorchClass = function(ast){
|
||||
var torchClassArgs, // args for `torch.class(...)`
|
||||
name = '',
|
||||
baseType,
|
||||
params = [];
|
||||
|
||||
if(ast.type == 'function'){
|
||||
ast.block.stats.forEach(function(func){
|
||||
if(func.type == 'stat.local' && func.right && func.right[0] &&
|
||||
func.right[0].func && func.right[0].func.self &&
|
||||
func.right[0].func.self.val == 'torch' &&
|
||||
func.right[0].func.key.val == 'class'){
|
||||
|
||||
torchClassArgs = func.right[0].args.map(arg => arg.val);
|
||||
name = torchClassArgs[0];
|
||||
if(name !== ''){
|
||||
name = name.replace('nn.', '');
|
||||
params = findInitParams(ast);
|
||||
if (torchClassArgs.length > 1) {
|
||||
baseType = torchClassArgs[1].replace('nn.', '');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
name,
|
||||
baseType,
|
||||
params
|
||||
};
|
||||
};
|
||||
|
||||
var categories = require('./categories.json');
|
||||
var catNames = Object.keys(categories);
|
||||
var layerToCategory = {};
|
||||
catNames.forEach(cat => // create layer -> category dictionary
|
||||
categories[cat].forEach(lname => layerToCategory[lname] = cat)
|
||||
);
|
||||
var lookupType = function(name){
|
||||
var layerType = layerToCategory[name];
|
||||
if (!layerType) { // try to infer
|
||||
layerType = name.indexOf('Criterion') > -1 && 'Criterion';
|
||||
}
|
||||
return layerType || 'Misc';
|
||||
};
|
||||
|
||||
fs.readdir(torchPath, function(err,files){
|
||||
if(err) throw err;
|
||||
var layers,
|
||||
layerByName = {};
|
||||
|
||||
layers = files.filter(filename => path.extname(filename) === '.lua')
|
||||
.map(filename => fs.readFileSync(torchPath + filename, 'utf8'))
|
||||
.map(code => parser.parse(code))
|
||||
.map(ast => findTorchClass(ast)) // create initial layers
|
||||
.filter(layer => !!layer && layer.name);
|
||||
|
||||
layers.forEach(layer => {
|
||||
layer.type = lookupType(layer.name);
|
||||
layerByName[layer.name] = layer;
|
||||
layer.setters = [];
|
||||
});
|
||||
|
||||
// handle inheritance
|
||||
layers.forEach(layer => {
|
||||
var iter = layer,
|
||||
params = layer.params;
|
||||
|
||||
while (iter && params === undefined) {
|
||||
params = iter.params;
|
||||
iter = layerByName[iter.baseType];
|
||||
}
|
||||
layer.params = params;
|
||||
});
|
||||
layers = layers.filter(layer => !SKIP_LAYERS[layer.name]);
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('Saved nn interface to src/common/layers.json');
|
||||
fs.writeFileSync('src/common/layers.json', JSON.stringify(layers, null, 2));
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
[
|
||||
"Sequential",
|
||||
"Container",
|
||||
"Criterion",
|
||||
"StochasticGradient",
|
||||
"Module"
|
||||
]
|
||||
+35
-3
@@ -28,6 +28,14 @@
|
||||
"CreateExecution": {
|
||||
"src": "src/plugins/CreateExecution",
|
||||
"test": "test/plugins/CreateExecution"
|
||||
},
|
||||
"GenerateExecFile": {
|
||||
"src": "src/plugins/GenerateExecFile",
|
||||
"test": "test/plugins/GenerateExecFile"
|
||||
},
|
||||
"ImportArtifact": {
|
||||
"src": "src/plugins/ImportArtifact",
|
||||
"test": "test/plugins/ImportArtifact"
|
||||
}
|
||||
},
|
||||
"layouts": {},
|
||||
@@ -122,6 +130,27 @@
|
||||
"panel": "src/visualizers/panels/DeserializeEditor",
|
||||
"secondary": false,
|
||||
"widget": "src/visualizers/widgets/DeserializeEditor"
|
||||
},
|
||||
"Footer": {
|
||||
"src": "panels/Footer/FooterPanel",
|
||||
"title": "Footer",
|
||||
"panel": "src/visualizers/panels/Footer",
|
||||
"secondary": false,
|
||||
"widget": "src/visualizers/widgets/Footer"
|
||||
},
|
||||
"LogViewer": {
|
||||
"src": "panels/LogViewer/LogViewerPanel",
|
||||
"title": "LogViewer",
|
||||
"panel": "src/visualizers/panels/LogViewer",
|
||||
"secondary": false,
|
||||
"widget": "src/visualizers/widgets/LogViewer"
|
||||
},
|
||||
"LayerEditor": {
|
||||
"src": "panels/LayerEditor/LayerEditorPanel",
|
||||
"title": "LayerEditor",
|
||||
"panel": "src/visualizers/panels/LayerEditor",
|
||||
"secondary": false,
|
||||
"widget": "src/visualizers/widgets/LayerEditor"
|
||||
}
|
||||
},
|
||||
"addons": {},
|
||||
@@ -137,6 +166,12 @@
|
||||
},
|
||||
"OpIntPtrDecorator": {
|
||||
"src": "src/decorators/OpIntPtrDecorator"
|
||||
},
|
||||
"DcOpDecorator": {
|
||||
"src": "src/decorators/DcOpDecorator"
|
||||
},
|
||||
"ArtifactOpDecorator": {
|
||||
"src": "src/decorators/ArtifactOpDecorator"
|
||||
}
|
||||
},
|
||||
"seeds": {
|
||||
@@ -146,9 +181,6 @@
|
||||
"devTests": {
|
||||
"src": "src/seeds/devTests"
|
||||
},
|
||||
"devMinimal": {
|
||||
"src": "src/seeds/devMinimal"
|
||||
},
|
||||
"devUtilTests": {
|
||||
"src": "src/seeds/devUtilTests"
|
||||
},
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário