Comparar commits

..

75 Commits

Autor SHA1 Mensagem Data
Brian Broll 1578886584 v0.14.0 2016-08-22 07:04:42 -05:00
Brian Broll 0927c2c270 Added npm install instructions 2016-08-20 15:08:45 -05:00
Brian Broll bd329bdfe3 Forwarded stdin to subprocess. Fixes #737 (#738)
WIP #737 Added stdin forwarding

WIP #737 Fixed rnn installation

WIP #737 Updated tests
2016-08-20 11:25:49 -05:00
Brian Broll e3a499f409 Improved error handling on torch install. Fixes #705 (#736)
WIP #705

WIP #705 Fixed error detection on torch install

WIP #705 Changed to Q promises

WIP #705 Updated tests
2016-08-20 08:45:52 -05:00
Brian Broll 63c78426d3 Downgraded nvd3 to v1.8.2. Fixes #593 (#735) 2016-08-19 16:05:27 -05:00
Brian Broll 6ec2f69268 Set y axis precision to 2 places. Fixes #674 (#734) 2016-08-19 15:38:33 -05:00
Brian Broll 1ccd193ddd Hide lines w/ no points. Fixes #732 (#733) 2016-08-19 15:07:28 -05:00
Brian Broll a5d52dce33 Added exec abbreviations when multiple selected in index. Fixes #675 (#731)
WIP #675 Added execIds to executions in ExecIndex

WIP #675 Updated line name if multi execs showing

WIP #675 show execution abbreviation if needed

WIP #675 Fixed code climate issues
2016-08-19 14:51:46 -05:00
Brian Broll ca358ae7b9 Added custom layers to the nn import mock. Fixes #729 (#730) 2016-08-19 11:43:21 -05:00
Brian Broll 0a1177c299 Created tag after execution saved. Fixes #727 (#728) 2016-08-19 11:42:14 -05:00
Brian Broll 46bf346c5c Added symlink to node_modules. Fixes #724 (#725) 2016-08-19 09:55:50 -05:00
Brian Broll 8a94496e01 Added "worker.dir" to config. Fixes #721 (#723) 2016-08-19 08:58:16 -05:00
Brian Broll d3cf339856 Created new directory for each worker. Fixes #720 (#722) 2016-08-19 08:47:20 -05:00
Brian Broll 5c0c58c3be Debounced execution widget updates. Fixes #713 (#719) 2016-08-18 15:10:45 -05:00
Brian Broll ef607e0e76 Removed forever-monitor from cli. Fixes #714 (#717)
WIP #714 Updated tests
2016-08-18 13:47:11 -05:00
Brian Broll 305503ac7a Changed title rename to single click. Fixes #715 (#716) 2016-08-18 12:41:55 -05:00
Brian Broll c76e62b976 Updated creation fn to use places promise. Fixes #710 (#711) 2016-08-17 16:03:14 -05:00
Brian Broll 554065ee11 Updated DeepForge.places to use promises. Fixes #681 (#709)
WIP #681 Added comments for work to be done and some place loading support

WIP #681 changed places to use promises

WIP #681 Updated MainView to use places promises
2016-08-17 15:27:32 -05:00
Brian Broll 7fba52ad97 Added shift-enter to restart jobs/execs/etc. Fixes #641 (#708)
WIP #641 Added key listener for floating action button

WIP #641 Ignored shift+enter in code editor

WIP #641 Fixed shift-enter to restart job

WIP #641 Added shift-enter for execution view

WIP #641 Fixed code climate issues
2016-08-17 13:33:43 -05:00
Brian Broll c56de24e7d Added ctrl-alt-pagedown/up to jump to EOF/beginning in logs. Fixes #667 (#707) 2016-08-17 09:45:53 -05:00
Brian Broll 6e16087fc3 Set the ArtifactLoader name to target in execution view. Fixes #574 (#706)
WIP #574 Added comments for modification locations

WIP #574 Added ArtifactLoader check

WIP #574 Set ArtifactLoader name to the pointer value
2016-08-16 16:07:54 -05:00
Brian Broll 8133acbb46 Added execution duration to ExecIndex. Fixes #628 (#704)
WIP #628 Added execution time support

WIP #628 Removed endTime on execution start

WIP #628 Added startTime, endTime to execution

WIP #628 updated pipeline lib
2016-08-16 11:14:24 -05:00
Brian Broll d974cb8215 Added margin to bottom of log viewer. Fixes #696 (#702)
WIP #696 Added 5 lines to bottom of log file

WIP #696 Set scroll margin to 75px (from bottom)
2016-08-16 10:02:25 -05:00
Brian Broll 68021c1903 Removed \u0000 from stdout logs. Fixes #700 (#701) 2016-08-16 09:55:27 -05:00
Brian Broll 7178b89578 Added better error handling for ops w/ old refs. Fixes #698 (#699) 2016-08-16 09:01:58 -05:00
Brian Broll 0935abe858 Added operation attributes to jobs in ExecutionView. Fixes #686 (#697)
WIP #686 Added opAttributes

WIP #686 Added readonly pointer, attr to job
2016-08-16 07:54:55 -05:00
Brian Broll 22225922e5 Added support for \r in job logs. Fixes #298 (#695)
WIP #298 Adding progress bar support...

WIP #298 Updated stdout logs for \r support
2016-08-15 15:25:12 -05:00
Brian Broll 343f2ffa61 Updated breadcrumb header. Fixes #662 (#694)
WIP #662 Set cachePrefix for path storage

WIP #662 Updated breadcrumbheader version
2016-08-15 12:40:42 -05:00
Brian Broll 477d38d313 Added unknown ref type error and setting. Fixes #690 (#692)
WIP #690 Added viz feedback about unknown type

WIP #690 Starting to add ref type setting

WIP #690 Added click fn-ality. still has bad error tooltip

WIP #690 Replaced baseName tooltip on ref set

WIP #690 Fixed code climate issues
2016-08-15 12:08:42 -05:00
Brian Broll 84e5377b8a Changed template settings to defaults. Fixes #691 (#693) 2016-08-15 12:08:36 -05:00
Brian Broll 1abbecc54c v0.13.0 2016-08-15 10:07:40 -05:00
Brian Broll af2f34545b Added basic table literal support. Fixes #652 (#689) 2016-08-12 17:05:03 -05:00
Brian Broll f7499c4599 Added more robust layer parsing to LayerEditor. Fixes #670 (#688)
WIP #670 Added most LayerParser fn-ality

WIP Fixed error w/ changing arch editors

WIP #670 Added pointer, setter support in layer editor

WIP #670 Updated for layer-as-args

WIP #670 Fixed ctor_arg_order setting

WIP #670 Removed unused fn
2016-08-12 15:59:10 -05:00
Brian Broll ad52fe7d70 Removed containing dir info from stack trace. Fixes #668 (#687) 2016-08-12 15:30:16 -05:00
Brian Broll 5ddeb6f331 Added layers-as-arguments. Fixes #654 (#684)
WIP #654 Added LayerDecorator

WIP #654

WIP #654 Added support for adding/removing layers

WIP #654 Fixed the text for the layers

WIP #654 Refactored content text

WIP #654 Only delete target if it's a child

WIP #654 Updated for layers-as-args

WIP #654 Made a better name for layer args

WIP #654 Added explicit arg types

WIP #654 Changed argindex -> ctor_arg_order

WIP #654 Added support for layers-as-args in GenArch

WIP #654 Added import fn-ality

WIP #654 Updated visualizers for layer support

WIP #654 Fixed code climate issues

WIP #654 Fixed setter detection

WIP #654 Updated tests

WIP #654 Updated tests
2016-08-12 14:28:54 -05:00
Brian Broll 7cd3d961cf Added naming executions. Fixes #683 (#685)
WIP #683 Removed issue from merge w/ master

WIP #683 Updated googlenet test
2016-08-12 13:43:26 -05:00
Brian Broll c38b38b4a1 Added more logging to better debug failures in the future. Fixes #660 (#680)
WIP #660 Added more logs

WIP #660 Added more logs during execution creation

WIP #660 Added more logging for starting executions
2016-08-12 09:54:13 -05:00
Brian Broll 6ae73ece70 Added edit icon for custom layers. Fixes #678 (#679) 2016-08-11 21:33:16 -05:00
Brian Broll b5512d8228 Added better error handling when blob changed. Fixes #659 (#677) 2016-08-11 17:03:48 -05:00
Brian Broll 89c871412a Remove territory ui on ExecIndex destroy. Fixes #673 (#676) 2016-08-11 16:42:13 -05:00
JimnyCricket 33e28aa3f1 Filter non-numbers before graphing. Fixes #671 (#672)
WIP #671 Fixed code climate issues
2016-08-11 16:16:07 -05:00
Brian Broll 3899c3cb16 Added attr type inference in parser. Fixes #655 (#669)
WIP #655 Added type inference based on defaults

WIP #655 removed extra console.log

WIP #655 Inferring type from assertions

WIP #655 Fixed some parsing bugs

WIP #655 Added better type inference

WIP #655 Using types in metamodel creation

WIP #655 Added types

WIP #655 Updated nn library

WIP #655 Fixed code climate issues
2016-08-11 13:22:06 -05:00
Brian Broll eb4f97e9b5 Added check for points before graphing. Fixes #663 (#665)
WIP #663 Removed empty point text
2016-08-11 12:29:14 -05:00
JimnyCricket 16e37043f4 Added type checking for x,y in graph. Fixes #664 (#666)
Changed to single assertion with more info

WIP #664 "Expected" -> "expected"
2016-08-11 11:45:32 -05:00
Brian Broll 261ffd1eba Update README.md (#657) 2016-08-10 15:20:10 -05:00
Brian Broll 9167b33e18 Added configurable worker.cache.dir and worker.cache.useBlob. Fixes #638 (#653)
WIP #638 Added config schema

WIP #638 Added default cache location

WIP #638 Added useBlob fn-ality

WIP #638 Added type checking

WIP #638 Fixed config merge issue

WIP #638 Create worker cache parent dir if needed
2016-08-10 08:23:44 -05:00
Brian Broll 6f7f0d01e5 Added check for undefined value. Fixes #650 (#651) 2016-08-09 16:39:20 -05:00
Brian Broll c11b1fe812 Added blob.dir configuration. Fixes #639 (#649)
WIP #639 Added config schema

WIP #639 Added blob.dir config value
2016-08-09 14:57:32 -05:00
Brian Broll 306425cae1 Added implicit require 'nn' to ImportTorch. Fixes #644 (#647)
WIP #644 Added test
2016-08-09 14:14:04 -05:00
Brian Broll 6d70728b54 Added recurrent layers. Fixes #477 (#645)
WIP #477 Added skipArgs and rnn parsing support

WIP #477 Added update script and updated CreateTorchMeta

WIP #477 Run update script after nn-parser

WIP #477 Simplified nn-parser usage (just 'rnn' or 'nn')

WIP #477 Added 'all' option

WIP #477 Updated the nn project

WIP #477 `require 'rnn'` => nop in importer

WIP #477 Updated gen arch

WIP #477 Updated update --torch

WIP #477 Added rnn installation to torch install

WIP #477 Fixed code climate issues
2016-08-09 13:50:19 -05:00
Brian Broll fadb654883 Create worker dir if doesn't exist. Fixes #643 (#646) 2016-08-09 13:49:13 -05:00
Brian Broll 6528bbdbc6 Clearing output viewer territory on destroy. Fixes #622 (#642) 2016-08-09 07:50:19 -05:00
Brian Broll 23852de607 Set the cache to blob in 'local' mode. Fixes #637 (#640) 2016-08-08 12:43:37 -05:00
Brian Broll 9cf66a0e02 Added caching support to workers. Fixes #616 (#636)
WIP #616 Added cache dir if doesn't exist

WIP #616 Removed data from execution files

WIP #616 Added pointer files to data download

WIP #616 Fixed symlink creation
2016-08-08 12:16:30 -05:00
Brian Broll ad19e0fb57 v0.12.0 2016-08-08 08:30:01 -05:00
Brian Broll 14f222bf6f Merge branch '624-large-files-fail-exec' 2016-08-04 15:23:00 -05:00
Brian Broll 95141d1a42 Added image counter for uploading. Fixes #625 (#632) 2016-08-04 15:14:26 -05:00
Brian Broll 93aaf72372 Added explicit data download on worker. Fixes #624
WIP #624 Missing parens
2016-08-04 15:11:02 -05:00
Brian Broll 47a6612ed0 Added anchor detection on output type click. Fixes #626 (#631) 2016-08-04 14:37:15 -05:00
Brian Broll fe48af8bf4 Created unique worker config and cleanup on close. Fixes #618 (#623) 2016-08-04 10:55:06 -05:00
Brian Broll 78ca4f8762 Added error logs for more complex errors. Fixes #620 (#621)
WIP #620 Added error message to stdout

WIP #620 Added colors and console message
2016-08-04 10:01:36 -05:00
Brian Broll a7e08aa279 Update attributes on cancel job. Fixes #617 (#619)
WIP #617 moved client edits out of promise

WIP #617 Made 'isRunning' more robust

WIP #617 Fixed client calls
2016-08-04 08:37:09 -05:00
Brian Broll e2980d616f Filter out all non-alphanumeric or _ chars in execution. Fixes #612 (#614) 2016-08-03 16:55:02 -05:00
Brian Broll 96f2090d9e Removed long error message on failed exec. Fixes #608 (#611) 2016-08-03 15:55:04 -05:00
Brian Broll 8a86a114db Updated Materialize to explicit require (~global). Fixes #607 (#610) 2016-08-03 15:44:31 -05:00
Brian Broll cb757da118 Added torch config dir check before update. Fixes #606 (#609) 2016-08-03 15:36:43 -05:00
Brian Broll 31711e079a Enabled autoMerge. Fixes #332 Fixes #346 (#605) 2016-08-03 14:02:11 -05:00
Brian Broll 16ebb83ae6 Hiding restart button when running. Fixes #597 (#604) 2016-08-03 13:49:17 -05:00
Brian Broll 65304b2645 Changed SNAPSHOT->DEBUG. Fixes #601 (#603) 2016-08-03 13:18:41 -05:00
Brian Broll b44c6a104b Added execution canceling. Fixes #481 (#602)
WIP #481 Added buttons and jobId, secret setting

WIP #481 Added 'jobId', 'secret' to Job

WIP #481 Canceling job exec support

WIP #481 Added canceling executing pipelines

WIP #481 Fixed canceling pipelines

WIP #481 Improved result messages from executions

WIP #481 Updated decorator and status setting for ExecJob

WIP #481 Updated job colors in lists

WIP #481 Updated pipeline library

WIP #481 Fixed code climate issues
2016-08-03 12:42:55 -05:00
Brian Broll a8e5876f83 Updated fab icon colors. Fixes #588 (#599) 2016-08-03 08:41:24 -05:00
Brian Broll 2d9d1e71c0 Added "complete" notification if exec forked. Fixes #596 (#598)
WIP #596 Added quotes around job, exec, branch for consistency
2016-08-03 08:37:24 -05:00
Brian Broll 475bdfed50 Added notification on fork to ExecuteJob. Fixes #591 (#595)
WIP #591 Added notification on fork to ExecuteJob

WIP #591 Fixed fork name creation
2016-08-03 08:16:04 -05:00
Brian Broll c36f12ccb2 Added Execution dashboard. Fixes #587 (#594)
WIP #587 Added toggling embedded viz

WIP #587 Added ExecutionIndex

WIP #587 Added exec table and rows

WIP #587 Added status colors

WIP #587 Added color coded by status

WIP #587 Retrieved graphs for each execution

WIP #587 Added lineGraph object in right split

WIP #587 Fixed lineGraph resize and added multiple lines

WIP #587 Fixed line updates/removal

WIP #587 Added execution selection

WIP #587 Added execution toggling

WIP #587 Fixed untoggle-able after update

WIP #587 Fixed exec status color updates

WIP #578 Exec name click -> navigate to the given execution

WIP #587 Added pipeline names

WIP #587 Added default 'checking' and pipeline name updates

WIP #587 Fixed the deselection of running execs

WIP #587 Fixed initial pipeline names

WIP #587 Added toggling visualizers

WIP #587 Fixed positioning

WIP #587 Added more logs and fixed pipeline name finding

WIP #587 Fixed project switching and obj changed

WIP #587 Improved perf of chart
2016-08-02 16:42:28 -05:00
Brian Broll 0b8b5b8adf Added decimal to number chars in graph plotting. Fixes #589 (#590) 2016-08-02 11:56:50 -05:00
112 arquivos alterados com 8836 adições e 19947 exclusões
+8
Ver Arquivo
@@ -16,10 +16,18 @@ Simply run the following command to install deepforge with its dependencies:
curl -o- https://raw.githubusercontent.com/dfst/deepforge/master/install.sh | bash
```
Or, if you already have NodeJS (v6) installed, simply run
```
npm install -g deepforge
```
Next, start deepforge with `deepforge start`!
Finally, navigate to [http://localhost:8888](http://localhost:8888) to start using DeepForge! For more, detailed instructions, check out the [wiki](https://github.com/dfst/deepforge/wiki/Installation-Guide).
Also, be sure to check out the other available features of the `deepforge` cli; it can be used to update, manage your torch installation, uninstall deepforge and run individual components!
## Interested in contributing?
Contributions are welcome! Either fork the project and submit some PR's or shoot me an email about getting more involved!
+10
Ver Arquivo
@@ -2,6 +2,16 @@
"torch": {
"dir": "~/.deepforge/torch"
},
"blob": {
"dir": "~/.deepforge/blob"
},
"worker": {
"cache": {
"useBlob": true,
"dir": "~/.deepforge/worker/cache"
},
"dir": "~/.deepforge/worker"
},
"mongo": {
"dir": "~/.deepforge/data"
}
+167 -112
Ver Arquivo
@@ -3,15 +3,15 @@
var Command = require('commander').Command,
program = new Command(),
childProcess = require('child_process'),
spawn = childProcess.spawn,
rawSpawn = childProcess.spawn,
Q = require('q'),
execSync = childProcess.execSync,
path = require('path'),
fs = require('fs'),
version = require('../package.json').version,
exists = require('exists-file'),
forever = require('forever-monitor'),
DEFAULT_CONFIG = require('./config.json'),
assign = require('lodash.assign'),
merge = require('lodash.merge'),
config,
configDir = path.join(process.env.HOME, '.deepforge'),
@@ -20,7 +20,12 @@ var Command = require('commander').Command,
localConfig,
rm_rf = require('rimraf'),
p = dir => dir.replace(/^~/, process.env.HOME); // resolve '~' to '$HOME'
p = dir => {
if (typeof dir === 'string') {
return dir.replace(/^~/, process.env.HOME); // resolve '~' to '$HOME'
}
return dir;
};
// Check for any commands
if (process.argv.length === 2) {
@@ -39,17 +44,17 @@ if (!exists.sync(configPath)) {
}
localConfig = require(configPath);
config = assign(DEFAULT_CONFIG, require(configPath));
config = merge({}, DEFAULT_CONFIG, localConfig);
var getConfigValue = function(id) {
var getConfigValue = function(id, srcConfig) {
var keys = id.split('.'),
value = config;
value = srcConfig || config;
for (var i = 0; i < keys.length; i++) {
value = value[keys[i]];
if (!value) {
if (!value.hasOwnProperty(keys[i])) {
return null;
}
value = value[keys[i]];
}
return value;
};
@@ -59,7 +64,8 @@ var storeConfig = function(id, value) {
var keys = id.split('.').filter(k => k),
lastKey = keys.pop(),
currentObj = localConfig,
current = getConfigValue(id);
current = getConfigValue(id),
expType = typeof getConfigValue(id, DEFAULT_CONFIG);
// Check if it is a valid key
if (current === null) {
@@ -73,25 +79,39 @@ var storeConfig = function(id, value) {
currentObj = currentObj[keys[i]];
}
if (expType !== 'string') {
try { // try to downcast
value = JSON.parse(value);
} catch (e) {
console.log(`Invalid value: "${value}" (expected ${expType})`);
return;
}
}
currentObj[lastKey] = value;
fs.writeFileSync(configPath, JSON.stringify(localConfig, null, 2));
return true;
};
(function() { // Load config to env
var envToConf = require('./envConfig.json');
Object.keys(envToConf).forEach(env => {
var cKey = envToConf[env];
process.env[env] = process.env[env] || p(getConfigValue(cKey));
});
// Special cases
if (process.env.DEEPFORGE_WORKER_USE_BLOB === 'true' &&
exists.sync(process.env.DEEPFORGE_BLOB_DIR)) {
process.env.DEEPFORGE_WORKER_CACHE = process.env.DEEPFORGE_BLOB_DIR + '/wg-content';
}
})();
program
.version('v' + version)
.description('Command line interface for managing deepforge');
// start
var start = function(main, opts) {
var child = new forever.Monitor(main, opts);
child.on('exit', function () {
console.log('Exited after 3 failed restarts');
});
child.start();
};
var isLocalUri = function(protocol, uri) {
return uri.indexOf(protocol + '://localhost') === 0 ||
uri.indexOf(protocol + '://127.0.0.1') === 0;
@@ -115,7 +135,7 @@ var checkMongo = function(args) {
};
var startMongo = function(args, silent) {
var job = spawn('mongod', ['--dbpath', p(config.mongo.dir)], {
var job = rawSpawn('mongod', ['--dbpath', p(config.mongo.dir)], {
cwd: process.env.HOME
});
if (!silent) {
@@ -147,63 +167,95 @@ var startMongo = function(args, silent) {
}
});
};
var checkTorch = function() {
return new Promise(_checkTorch)
.catch(() => 'Torch installation failed');
var hasTorch = function() {
var result = childProcess.spawnSync('th', ['--help']);
return !result.error;
};
var _checkTorch = function(resolve, reject) {
var result = childProcess.spawnSync('th', ['--help']),
tgtDir = p(config.torch.dir),
gcl = `git clone https://github.com/torch/distro.git ${tgtDir} --recursive`;
var installTorchExtras = function() {
// Check if rnn is installed
var result = childProcess.spawnSync('luarocks', ['list', '--porcelain']),
pkgs = result.stdout.toString().split('\n')
.map(line => line.match(/^[a-zA-Z0-9]+/g))
.map(m => m && m[0]);
if (result.error) {
if (pkgs.indexOf('rnn') === -1) {
return spawn('luarocks', ['install', 'rnn']);
} else {
return Q();
}
};
var installTorch = function() {
var tgtDir = p(config.torch.dir),
args;
if (!hasTorch()) {
// Try to install torch
console.log(`Torch7 not found. Installing to ${tgtDir}...`);
args = `clone https://github.com/torch/distro.git ${tgtDir} --recursive`.split(' ');
spawnMany([gcl],
() => {
process.chdir(tgtDir);
spawnMany([
'bash install-deps',
'./install.sh'
], () => {
storeConfig('torch.dir', tgtDir);
resolve(true);
}, reject);
},
reject
);
return spawn('git', args)
.then(code => {
if (code !== 0) {
if (code === 128) {
console.error(`${tgtDir} is not empty. ` +
'Please empty it or change the torch directory:\n' +
'\n deepforge config torch.dir NEW/TORCH/PATH\n');
}
throw `Torch install Failed with exit code ${code}`;
} else { // continue installation
process.chdir(tgtDir);
return spawn('bash', ['install-deps'])
.then(() => spawn('bash', ['install.sh'], true))
.then(() => {
storeConfig('torch.dir', tgtDir);
console.log('Installed torch. Please close and ' +
're-open your terminal to use DeepForge w/ ' +
'torch support!');
process.exit(0);
});
}
});
} else {
resolve(false);
return Q();
}
};
var spawnMany = function(cmds, succ, err) {
var rawCmd,
cmd,
args,
job;
var spawn = function(cmd, args, opts) {
var deferred = Q.defer(),
job,
spawnOpts = typeof opts === 'object' ? opts : null,
forwardStdin = opts === true,
isOpen = true,
err;
if (cmds.length === 0) {
return succ();
}
rawCmd = cmds.shift();
args = rawCmd.split(' ');
cmd = args.shift();
job = spawn(cmd, args);
args = args || [];
job = spawnOpts ? rawSpawn(cmd, args, spawnOpts) : rawSpawn(cmd, args);
job.stdout.on('data', data => process.stdout.write(data));
job.stderr.on('data', data => process.stderr.write(data));
job.on('close', code => {
if (code) {
console.log(`${rawCmd} failed w/ error code ${code}`);
err(code, rawCmd);
isOpen = false;
if (err) {
deferred.reject(err, code);
} else {
spawnMany(cmds, succ, err);
deferred.resolve(code);
}
});
job.on('error', e => err = e);
if (forwardStdin) {
process.stdin.on('data', data => {
if (isOpen) {
job.stdin.write(data);
}
});
}
return deferred.promise;
};
program.command('start')
@@ -213,34 +265,31 @@ program.command('start')
.option('-w, --worker [url]', 'start a worker and connect to given url. Defaults to local deepforge')
.option('-m, --mongo', 'start MongoDB')
.action(args => {
var main = path.join(__dirname, 'start-local.js'),
opts;
opts = {
max: 3,
args: []
};
var main = path.join(__dirname, 'start-local.js');
if (args.port) {
opts.env = {
PORT: args.port
};
process.env.PORT = args.port;
}
if (args.server) {
checkMongo(args);
main = path.join(__dirname, '..', 'app.js');
start(main, opts);
spawn('node', [main]);
}
if (args.worker) {
checkTorch().then(() => {
main = path.join(__dirname, 'start-worker.js');
if (args.worker !== true) {
opts.args.push(args.worker);
}
start(main, opts);
});
if (hasTorch()) {
installTorchExtras().then(() => {
main = path.join(__dirname, 'start-worker.js');
if (args.worker !== true) {
spawn('node', [main, args.worker]);
} else {
spawn('node', [main]);
}
});
} else {
installTorch();
}
}
if (args.mongo) {
@@ -250,7 +299,11 @@ program.command('start')
if (!args.server && !args.worker && !args.mongo) {
// Starting everything
checkMongo(args);
checkTorch().then(() => start(main, opts));
if (hasTorch()) {
installTorchExtras().then(() => spawn('node', [main]));
} else {
installTorch();
}
}
});
@@ -264,7 +317,6 @@ program
.option('-s, --server', 'update deepforge')
.action(args => {
var pkg = 'deepforge',
job,
latestVersion;
// Install the project
@@ -287,38 +339,43 @@ program
}
}
job = spawn('npm', ['install', '-g', pkg]);
job.stdout.on('data', data => process.stdout.write(data.toString()));
job.stderr.on('data', data => process.stderr.write(data.toString()));
job.on('close', code => {
if (!code) {
spawn('npm', ['install', '-g', pkg])
.then(() => {
console.log('Upgrade successful!');
} else {
console.log('Upgrade failed w/ error code: ' + code);
}
});
})
.catch(code => console.log('Upgrade failed w/ error code: ' + code));
}
if (args.torch || !args.server) {
// Update torch
checkTorch().then(justInstalled => {
if (!justInstalled) {
// Upgrade torch
console.log('Upgrading torch...');
job = spawn('bash', ['./update.sh'], {
cwd: p(config.torch.dir)
});
job.stdout.on('data', data => process.stdout.write(data.toString()));
job.stderr.on('data', data => process.stderr.write(data.toString()));
job.on('close', code => {
if (!code) {
console.log('Upgrade successful!');
} else {
console.log('Upgrade failed w/ error code: ' + code);
}
});
if (hasTorch()) {
// Upgrade torch
console.log('Upgrading torch...');
console.log(`Checking for torch in ${config.torch.dir}`);
// Verify that torch is installed in the config's location
if (!exists.sync(path.join(config.torch.dir, 'update.sh'))) {
// config is incorrect!
console.log('Could not find torch installation. Please update the deepforge config with:');
console.log('');
console.log(' deepforge config torch.dir ~/path/to/torch/install');
console.log('');
return;
}
});
spawn('bash', ['./update.sh'], {cwd: p(config.torch.dir)})
.catch(err => console.log('Upgrade failed w/ error code: ' + err.code))
.then(() => {
console.log('About to update rnn package...');
// Update rnn
return spawn('luarocks', ['install', 'rnn']);
})
.then(() => {
console.log('Upgrade successful!');
})
.catch(code => console.log('Upgrade failed w/ error code: ' + code));
} else {
installTorch();
}
}
});
@@ -343,11 +400,9 @@ program
}
if (!opts.torch || opts.clean) { // uninstall deepforge
spawnMany(
['npm uninstall -g deepforge'],
() => console.log('deepforge has been uninstalled!'),
() => console.log('uninstall failed')
);
spawn('npm', ['uninstall', '-g', 'deepforge'])
.then(() => console.log('deepforge has been uninstalled!'))
.catch(() => console.log('uninstall failed'));
}
});
@@ -383,8 +438,8 @@ program
module.exports = function(cmd) {
var cmds = cmd.split(/\s+/).filter(w => !!w);
cmds.unshift('node');
cmds.unshift('./bin/deepforge');
cmds.unshift('node');
program.parse(cmds);
};
+6
Ver Arquivo
@@ -0,0 +1,6 @@
{
"DEEPFORGE_BLOB_DIR": "blob.dir",
"DEEPFORGE_WORKER_CACHE": "worker.cache.dir",
"DEEPFORGE_WORKER_DIR": "worker.dir",
"DEEPFORGE_WORKER_USE_BLOB": "worker.cache.useBlob"
}
+7 -1
Ver Arquivo
@@ -4,7 +4,13 @@ var spawn = require('child_process').spawn,
execJob,
path = require('path'),
env = {cwd: path.join(__dirname, '..')},
workerJob = null;
workerJob = null,
gmeConfig = require(__dirname + '/../config');
// Set the cache to the blob
if (gmeConfig.blob.type === 'FS') {
process.env.DEEPFORGE_WORKER_CACHE = path.resolve(gmeConfig.blob.fsDir + '/wg-content');
}
process.env.NODE_ENV = 'local';
execJob = spawn('npm', [
+36 -2
Ver Arquivo
@@ -4,15 +4,42 @@ var path = require('path'),
fs = require('fs'),
childProcess = require('child_process'),
spawn = childProcess.spawn,
rm_rf = require('rimraf'),
projectConfig = require(__dirname + '/../config'),
executorSrc = path.join(__dirname, '..', 'node_modules', 'webgme', 'src',
'server', 'middleware', 'executor', 'worker'),
workerPath = path.join(__dirname, '..', 'src', 'worker'),
id = Date.now(),
workerRootPath = process.env.DEEPFORGE_WORKER_DIR || path.join(__dirname, '..', 'src', 'worker'),
workerPath = path.join(workerRootPath, `worker_${id}`),
workerConfigPath = path.join(workerPath, 'config.json'),
workerTmp = path.join(workerPath, 'tmp'),
address,
config = {};
var createDir = function(dir) {
try {
fs.statSync(dir);
} catch (e) {
// Create dir
fs.mkdirSync(dir);
return true;
}
return false;
};
createDir(workerRootPath);
createDir(workerPath);
createDir(workerTmp);
// Create sym link to the node_modules
var modules = path.join(workerRootPath, 'node_modules');
try {
fs.statSync(modules);
} catch (e) {
// Create dir
childProcess.spawnSync('ln', ['-s', `${__dirname}/../node_modules`, modules]);
return true;
}
// Check torch support
var result = childProcess.spawnSync('th', ['--help']);
if (result.error) {
@@ -22,7 +49,15 @@ if (result.error) {
process.exit(1);
}
var cleanUp = function() {
console.log('removing worker directory ', workerPath);
rm_rf.sync(workerPath);
};
var startExecutor = function() {
process.on('SIGINT', cleanUp);
process.on('uncaughtException', cleanUp);
// Start the executor
var execJob = spawn('node', [
'node_worker.js',
@@ -42,7 +77,6 @@ var createConfigJson = function() {
}
config[address] = {};
// TODO: Check if the config already exists
fs.writeFile(workerConfigPath, JSON.stringify(config), startExecutor);
};
+2 -1
Ver Arquivo
@@ -12,7 +12,8 @@
"LayerColors": {}
},
"BreadcrumbHeader": {
"pathRule": "history"
"pathRule": "history",
"cachePrefix": "deepforge-header"
},
"FloatingActionButton": {
"hideOnEmpty": true
+4
Ver Arquivo
@@ -9,6 +9,8 @@ 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;
config.blob.fsDir = process.env.DEEPFORGE_BLOB_DIR || config.blob.fsDir;
config.requirejsPaths.deepforge = './src/common';
config.requirejsPaths.ace = './src/visualizers/widgets/TextEditor/lib/ace';
config.seedProjects.defaultProject = 'project';
@@ -21,5 +23,7 @@ config.executor.clearOldDataAtStartUp = true;
config.visualization.extraCss.push('deepforge/styles/global.css');
config.storage.autoMerge.enable = true;
validateConfig(config);
module.exports = config;
+5 -6
Ver Arquivo
@@ -12,23 +12,22 @@
"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.11.0",
"version": "0.14.0",
"dependencies": {
"commander": "^2.9.0",
"dotenv": "^2.0.0",
"exists-file": "^2.1.0",
"forever-monitor": "^1.7.0",
"lodash.assign": "^4.0.9",
"lodash.difference": "^4.1.2",
"lodash.merge": "^4.5.1",
"nodemon": "^1.9.2",
"rimraf": "^2.4.0",
"webgme": "^2.0.0",
"webgme-autoviz": "dfst/webgme-autoviz",
"webgme-breadcrumbheader": "^2.1.0",
"webgme-breadcrumbheader": "^2.1.1",
"webgme-chflayout": "^2.0.0",
"webgme-easydag": "dfst/webgme-easydag",
"webgme-fab": "dfst/webgme-fab",
"webgme-simple-nodes": "^2.0.0",
"rimraf": "^2.4.0"
"webgme-simple-nodes": "^2.1.0"
},
"devDependencies": {
"chai": "^3.0.0",
+4 -1
Ver Arquivo
@@ -9,5 +9,8 @@ define({
GRAPH_CREATE: 'GRAPH',
GRAPH_PLOT: 'PLOT',
GRAPH_CREATE_LINE: 'LINE'
GRAPH_CREATE_LINE: 'LINE',
// Code Generation Constants
CTOR_ARGS_ATTR: 'ctor_arg_order'
});
+129 -25
Ver Arquivo
@@ -83,20 +83,6 @@
//////////////////////// Setters END ////////////////////////
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;
if(params.length === 0 && block.func.varargs){
params[0] = 'params';
}
}
});
return params;
};
var isInitFn = function(node, className) {
if (node.type === 'stat.method' && node.self.val === className) {
return node.key.val === '__init';
@@ -154,7 +140,7 @@
curr.left.type === 'variable' && curr.right.type.indexOf('const') !== -1) {
varName = curr.left.val;
if (varUsageCnt[varName] === 1) {
value = curr.right.type === 'const.nil' ? null : curr.right.val;
value = curr.right.type === 'const.nil' ? null : curr.right;
dict[varName] = value;
}
}
@@ -163,18 +149,124 @@
return dict;
};
var copyAttrs = function(attrs, from, to) {
var copyNodeValues = function(attrs, from, to) {
var value;
for (var i = attrs.length; i--;) {
to[attrs[i]] = from[attrs[i]];
value = from[attrs[i]] || null;
if (value) {
value = (value && value.hasOwnProperty('val')) ? value.val : value;
to[attrs[i]] = value;
}
}
return to;
};
var getTypeCheckInfo = function(cond) {
var caller,
method,
target,
expType;
// Check for torch.isTypeOf:
if (cond.type === 'expr.call' && cond.func.type === 'expr.index') {
caller = cond.func.self.val;
method = cond.func.key.val;
if (cond.type === 'expr.call' && caller === 'torch') {
target = cond.args[0].val;
if (method === 'isTypeOf' && target) {
expType = cond.args[1].val;
return {
target,
type: expType
};
}
}
} else if (cond.type === 'expr.op') { // torch.type() === ''
// Check right side, too!
var sides = [cond.left, cond.right],
side,
otherSide;
for (var i = sides.length; i--;) {
side = sides[i];
otherSide = sides[(i+1)%2];
if (side.type === 'expr.call' && side.func.type === 'expr.index') {
// Is it torch?
caller = side.func.self.val;
method = side.func.key.val;
if (caller === 'torch' && method === 'type') {
if (side.args[0].type === 'variable') {
target = side.args[0].val;
if (otherSide.type === 'const.string') {
expType = otherSide.val;
return {
target: target,
type: expType
};
}
}
}
}
}
return null;
}
};
var isError = function(stat) {
var fn;
if (stat.type === 'stat.expr' && stat.expr.type === 'expr.call') {
fn = stat.expr.func.val;
return fn === 'error';
}
return false;
};
var inferParamTypes = function(node, paramDefs) {
var types = {},
check,
cond;
// Infer from assertions
luajs.codegen.traverse(curr => {
// check for 'assert's that check type
if (curr.type === 'expr.call' && curr.func.val === 'assert') {
cond = curr.args[0];
check = getTypeCheckInfo(cond);
if (check) {
types[check.target] = check.type;
}
} else if (curr.type === 'stat.if' && curr.cond.op === 'uop.not') {
// if statements throwing errors on type mismatch
cond = curr.cond.operand; // non-negated version
// Check that it throws an error on true
if (curr.tblock.stats.some(isError)) {
check = getTypeCheckInfo(cond);
if (check) {
types[check.target] = check.type;
}
}
}
})(node);
// Infer from defaults
Object.keys(paramDefs).forEach(param => {
var val = paramDefs[param];
if (val) { // initialized to 'null' doesn't help us...
types[param] = val.type.replace('const.', '');
}
});
return types;
};
var findTorchClass = function(ast){
var torchClassArgs, // args for `torch.class(...)`
name = '',
baseType,
params = [],
params,
setters = {},
defaults = {},
paramDefs,
@@ -191,7 +283,6 @@
name = torchClassArgs[0];
if(name !== ''){
name = name.replace('nn.', '');
params = findInitParams(ast);
if (torchClassArgs.length > 1) {
baseType = torchClassArgs[1].replace('nn.', '');
}
@@ -200,9 +291,10 @@
});
}
// Get the setters and defaults
// Get the setters, defaults and type info (inferred)
var setterNames,
schema,
types,
values;
luajs.codegen.traverse((curr, parent) => {
@@ -227,19 +319,26 @@
} else if (isInitFn(curr, name)) { // Record the defaults
paramDefs = getAttrsAndVals(curr);
attrDefs = getClassAttrDefs(curr);
types = inferParamTypes(curr, paramDefs);
// get ctor args
params = curr.func.args;
if(params.length === 0 && curr.func.varargs){
params.push('params');
}
}
})(ast);
// Get the defaults for the params from defs
if (paramDefs) {
copyAttrs(params, paramDefs, defaults);
if (paramDefs && params) {
copyNodeValues(params, paramDefs, defaults);
}
// Get the defaults for the setters from attrDefs
if (attrDefs) {
setterNames = Object.keys(setters);
copyAttrs(setterNames, attrDefs, defaults);
copyNodeValues(setterNames, attrDefs, defaults);
}
// Remove any const setters w/ only one value and no default
@@ -263,13 +362,18 @@
baseType,
params,
setters,
types,
defaults
};
};
LayerParser.parse = function(text) {
var ast = luajs.parser.parse(text);
return findTorchClass(ast);
try {
var ast = luajs.parser.parse(text);
return findTorchClass(ast);
} catch (e) {
return null;
}
};
return LayerParser;
+54 -23
Ver Arquivo
@@ -1,13 +1,17 @@
/* globals Materialize, WebGMEGlobal, define*/
/* globals WebGMEGlobal, define*/
// This file creates the DeepForge namespace and defines basic actions
define([
'panel/FloatingActionButton/styles/Materialize',
'js/RegistryKeys',
'js/Panels/MetaEditor/MetaEditorConstants',
'js/Constants'
'js/Constants',
'q'
], function(
Materialize,
REGISTRY_KEYS,
META_CONSTANTS,
CONSTANTS
CONSTANTS,
Q
) {
var DeepForge = {},
placesTerritoryId,
@@ -90,6 +94,7 @@ define([
};
//////////////////// DeepForge places detection ////////////////////
DeepForge.places = {};
var TYPE_TO_CONTAINER = {
Architecture: 'MyArchitectures',
@@ -105,10 +110,29 @@ define([
PLACE_NAMES = Object.keys(TYPE_TO_CONTAINER).map(key => TYPE_TO_CONTAINER[key]);
// Add DeepForge directories
var placePromises = {},
setPlaceId = {},
firstProject = true;
var getPlace = function(name) {
return placePromises[name];
};
var initializePlaces = function() {
PLACE_NAMES.forEach(name => {
var deferred = Q.defer();
placePromises[name] = deferred.promise;
setPlaceId[name] = deferred.resolve;
});
};
var updateDeepForgeNamespace = function() {
var territory = {};
DeepForge.places = {};
if (!firstProject) {
initializePlaces();
}
firstProject = false;
// Create a territory
if (placesTerritoryId) {
@@ -135,13 +159,16 @@ define([
nodes.forEach(node =>
nodeIdsByName[node.getAttribute('name')] = node.getId());
PLACE_NAMES.forEach(name => DeepForge.places[name] = nodeIdsByName[name]);
PLACE_NAMES.forEach(name => setPlaceId[name](nodeIdsByName[name]));
// Remove the territory
client.removeUI(placesTerritoryId);
placesTerritoryId = null;
};
initializePlaces();
PLACE_NAMES.forEach(name => DeepForge.places[name] = getPlace.bind(null, name));
//////////////////// DeepForge creation actions ////////////////////
var instances = [
'Architecture',
@@ -154,8 +181,7 @@ define([
];
var createNew = function(type, metasheetName) {
var parentId,
placeName = TYPE_TO_CONTAINER[type],
var placeName = TYPE_TO_CONTAINER[type],
newId,
baseId,
msg = `Created new ${type + (metasheetName ? ' prototype' : '')}`;
@@ -165,19 +191,20 @@ define([
.getId();
// Look up the parent container
parentId = DeepForge.places[placeName];
DeepForge.places[placeName]().then(parentId => {
client.startTransaction(msg);
newId = createNamedNode(baseId, parentId, !!metasheetName);
client.startTransaction(msg);
newId = createNamedNode(baseId, parentId, !!metasheetName);
if (metasheetName) {
addToMetaSheet(newId, metasheetName);
}
if (metasheetName) {
addToMetaSheet(newId, metasheetName);
}
client.completeTransaction();
client.completeTransaction();
WebGMEGlobal.State.registerActiveObject(newId);
return newId;
WebGMEGlobal.State.registerActiveObject(newId);
return newId;
});
};
var createCustomLayer = function(typeName) {
@@ -198,16 +225,20 @@ define([
}
}
client.startTransaction(msg);
return DeepForge.places.MyLayers()
.then(id => {
newId = createNamedNode(baseId, DeepForge.places.MyLayers, true);
addToMetaSheet(newId, 'CustomLayers');
client.addMixin(newId, customLayerId);
client.setRegistry(newId, REGISTRY_KEYS.IS_ABSTRACT, false);
client.startTransaction(msg);
client.completeTransaction();
newId = createNamedNode(baseId, id, true);
addToMetaSheet(newId, 'CustomLayers');
client.addMixin(newId, customLayerId);
client.setRegistry(newId, REGISTRY_KEYS.IS_ABSTRACT, false);
WebGMEGlobal.State.registerActiveObject(newId);
client.completeTransaction();
WebGMEGlobal.State.registerActiveObject(newId);
});
};
// Creating Artifacts
+20 -15
Ver Arquivo
@@ -1,6 +1,8 @@
/* globals define*/
define([
'deepforge/Constants'
], function(
Constants
) {
'use strict';
@@ -15,36 +17,39 @@ define([
return result;
};
var isArgument = function(arg) {
return arg.hasOwnProperty('argindex');
};
var isSetter = function(arg) {
return arg.hasOwnProperty('setterType');
};
var sortByIndex = function(a, b) {
return a.argindex > b.argindex;
};
var createLayerDict = function(core, meta) {
var node,
names = Object.keys(meta),
layers = {},
setters,
ctorData,
ctorArgs,
attrs;
for (var i = names.length; i--;) {
node = meta[names[i]];
attrs = core.getValidAttributeNames(node)
.map(attr => prepAttribute(core, node, attr));
ctorData = core.getAttribute(node, Constants.CTOR_ARGS_ATTR);
attrs = core.getValidAttributeNames(node);
layers[names[i]] = {};
layers[names[i]].args = attrs
.filter(isArgument)
.sort(sortByIndex);
if (ctorData) {
ctorArgs = ctorData.split(',')
.map(attr => prepAttribute(core, node, attr));
// Get the constructor args
layers[names[i]].args = ctorArgs;
} else {
layers[names[i]].args = [];
}
layers[names[i]].setters = {};
setters = attrs.filter(isSetter);
setters = attrs
.map(attr => prepAttribute(core, node, attr))
.filter(isSetter);
for (var j = setters.length; j--;) {
layers[names[i]].setters[setters[j].name] = setters[j];
}
@@ -54,7 +59,7 @@ define([
};
// When provided with the META, create the given LayerDict object
// - Sort (and filter) by argindex
// - Filter out the ctor args (in order)
// - add name attribute to schema
// - store this array under the META name
+4
Ver Arquivo
@@ -22,3 +22,7 @@
.create-node text {
font-style: italic;
}
.job-canceled {
background-color: #ffe0b2;
}
+58
Ver Arquivo
@@ -0,0 +1,58 @@
/* globals define*/
define([
], function(
) {
var isBoolean = txt => {
return typeof txt === 'boolean' || (txt === 'false' || txt === 'true');
};
var getSetterSchema = function(name, setters, defaults) {
var values,
schema = setters[name];
if (defaults.hasOwnProperty(name)) {
schema.default = defaults[name];
}
schema.type = 'string';
if (schema.setterType === 'const') {
values = Object.keys(schema.setterFn);
schema.isEnum = true;
schema.enumValues = values;
if (values.every(isBoolean)) {
if (!defaults.hasOwnProperty(name) && values.length === 1) {
// there is only a method to toggle the flag to true/false,
// then the default must be the other one
schema.default = values[0] === 'true' ? false : true;
}
if (isBoolean(schema.default)) {
schema.type = 'boolean';
}
}
}
return schema;
};
var abbrWord = function(word) { // camelcase
word = word.substring(0, 1).toUpperCase() + word.substring(1);
return word.split(/[a-z]+/g).join('').toLowerCase();
};
var abbrPhrase = function(words) { // dashes, spaces, underscores, etc
return words.map(word => word[0]).join('');
};
var abbr = function(phrase) {
var words = phrase.split(/[^a-zA-Z0-9]+/g);
if (words.length === 1) {
return abbrWord(phrase);
} else {
return abbrPhrase(words);
}
};
return {
getSetterSchema: getSetterSchema,
abbr: abbr
};
});
+102
Ver Arquivo
@@ -0,0 +1,102 @@
/* globals define, WebGMEGlobal */
// Mixin for executing jobs and pipelines
define([
'executor/ExecutorClient',
'panel/FloatingActionButton/styles/Materialize'
], function(
ExecutorClient,
Materialize
) {
var Execute = function(client, logger) {
this.client = this.client || client;
this.logger = this.logger || logger;
this._executor = new ExecutorClient({
logger: this.logger.fork('ExecutorClient'),
serverPort: WebGMEGlobal.gmeConfig.server.port,
httpsecure: window.location.protocol === 'https:'
});
};
Execute.prototype.executeJob = function(node) {
return this.runExecutionPlugin('ExecuteJob', {node: node});
};
Execute.prototype.executePipeline = function(node) {
return this.runExecutionPlugin('ExecutePipeline', {node: node});
};
Execute.prototype.runExecutionPlugin = function(pluginId, opts) {
var context = this.client.getCurrentPluginContext(pluginId),
node = opts.node || this.client.getNode(this._currentNodeId),
name = node.getAttribute('name'),
method;
// Set the activeNode
context.managerConfig.namespace = 'pipeline';
context.managerConfig.activeNode = node.getId();
method = opts.useSecondary ? 'runBrowserPlugin' : 'runServerPlugin';
this.client[method](pluginId, context, (err, result) => {
var msg = err ? `${name} failed!` : `${name} executed successfully!`,
duration = err ? 4000 : 2000;
// Check if it was canceled - if so, show that type of message
if (result) {
msg = result.messages[0].message;
duration = 4000;
}
Materialize.toast(msg, duration);
});
};
Execute.prototype.isRunning = function(node) {
var baseId,
base,
type;
node = node || this.client.getNode(this._currentNodeId);
baseId = node.getBaseId();
base = this.client.getNode(baseId);
type = base.getAttribute('name');
if (type === 'Execution') {
return node.getAttribute('status') === 'running';
} else if (type === 'Job') {
return this.isRunningJob(node);
}
return false;
};
Execute.prototype.isRunningJob = function(job) {
var status = job.getAttribute('status');
return (status === 'running' || status === 'pending') &&
job.getAttribute('secret') && job.getAttribute('jobId');
};
Execute.prototype.stopJob = function(job) {
var jobHash,
jobId,
secret;
job = job || this.client.getNode(this._currentNodeId);
jobId = job.getId();
jobHash = job.getAttribute('jobId');
secret = job.getAttribute('secret');
if (!jobHash || !secret) {
this.logger.error('Cannot stop job. Missing jobHash or secret');
return;
}
this.client.delAttributes(jobId, 'jobId');
this.client.delAttributes(jobId, 'secret');
this.client.setAttributes(jobId, 'status', 'canceled');
return this._executor.cancelJob(jobHash, secret)
.then(() => this.logger.info(`${jobHash} has been cancelled!`))
.fail(err => this.logger.error(`Job cancel failed: ${err}`));
};
return Execute;
});
+1 -1
Ver Arquivo
@@ -21,7 +21,7 @@ define([
RenameablePanel.OPTIONS = PanelBaseWithHeader.OPTIONS;
RenameablePanel.prototype.initializeRenameable = function () {
this.$panelHeaderTitle.on('dblclick', this.editTitle.bind(this));
this.$panelHeaderTitle.on('click', this.editTitle.bind(this));
};
RenameablePanel.prototype.currentNodeId = function () {
+19
Ver Arquivo
@@ -0,0 +1,19 @@
/* globals define*/
define({
getDisplayTime: timestamp => {
var today = new Date().toLocaleDateString(),
date = new Date(timestamp).toLocaleDateString();
if (date === today) {
date = `Today (${new Date(timestamp).toLocaleTimeString()})`;
}
return date;
},
ClassForJobStatus: {
success: 'success',
canceled: 'job-canceled',
failed: 'danger',
pending: '',
running: 'warning'
}
});
@@ -0,0 +1,17 @@
/*globals define*/
define([
'decorators/EllipseDecorator/EasyDAG/AttributeField'
], function(
BaseAttributeField
) {
var AttributeField = function() {
BaseAttributeField.apply(this, arguments);
};
AttributeField.prototype = Object.create(BaseAttributeField.prototype);
AttributeField.prototype.onClick = function() {
};
return AttributeField;
});
@@ -1,15 +1,15 @@
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
/**
* @author brollb / https://github.com/brollb
*/
define([
'decorators/EllipseDecorator/EasyDAG/EllipseDecorator.EasyDAGWidget',
'./PointerField.RO',
'./AttributeField.RO',
'css!./JobDecorator.EasyDAGWidget.css'
], function (
EllipseDecorator
EllipseDecorator,
PointerField,
AttributeField
) {
'use strict';
@@ -20,6 +20,7 @@ define([
pending: '#9e9e9e',
queued: '#cfd8dc',
running: '#fff59d',
canceled: '#ffcc80',
success: '#66bb6a',
fail: '#e57373'
};
@@ -35,6 +36,8 @@ define([
status: true,
execFiles: true,
stdout: true,
secret: true,
jobId: true,
debug: true
};
EllipseDecorator.call(this, options);
@@ -43,18 +46,46 @@ define([
_.extend(JobDecorator.prototype, EllipseDecorator.prototype);
JobDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
JobDecorator.prototype.AttributeField = AttributeField;
JobDecorator.prototype.PointerField = PointerField;
JobDecorator.prototype.isArtifactLoader = function() {
return this._node.name === 'ArtifactLoader';
};
JobDecorator.prototype.getDisplayName = function() {
if (this.isArtifactLoader()) {
var id = this._node.pointers.artifact;
// Try to look up the pointer name
return this.nameFor[id] || this._node.name;
}
return this._node.name;
};
JobDecorator.prototype.setAttributes = function() {
EllipseDecorator.prototype.setAttributes.call(this);
var attrs = this._node.attributes,
status = attrs.status && attrs.status.value;
status = attrs.status && attrs.status.value,
opAttrs = Object.keys(this._node.opAttributes);
// Update the color based on the 'status' attr
this.color = COLORS[status] || COLORS.fail;
// Set _attributes from opAttributes
for (var i = opAttrs.length; i--;) {
this._attributes[opAttrs[i]] = this._node.opAttributes[opAttrs[i]];
}
};
JobDecorator.prototype.updateTargetName = function() {
EllipseDecorator.prototype.updateTargetName.apply(this, arguments);
var name = this.getDisplayName();
if (name !== this.name) {
this.name = name;
this.onResize();
}
};
return JobDecorator;
@@ -0,0 +1,22 @@
/*globals define*/
define([
'decorators/EllipseDecorator/EasyDAG/PointerField'
], function(
BasePointerField
) {
var PointerField = function() {
BasePointerField.apply(this, arguments);
};
PointerField.prototype = Object.create(BasePointerField.prototype);
PointerField.prototype.onClick = function() {
};
// Remove the delete icon and adjust the text location
PointerField.prototype.hasIcon = function() {
return false;
};
return PointerField;
});
@@ -0,0 +1,110 @@
/*globals define, _, WebGMEGlobal*/
/*jshint browser: true, camelcase: false*/
define([
'decorators/EllipseDecorator/EasyDAG/EllipseDecorator.EasyDAGWidget',
'deepforge/Constants',
'./LayerField'
], function (
EllipseDecorator,
Constants,
LayerField
) {
'use strict';
var LayerDecorator,
DECORATOR_ID = 'LayerDecorator';
// Layer nodes need to be able to...
// - show their ports
// - highlight ports
// - unhighlight ports
// - report the location of specific ports
LayerDecorator = function (options) {
options.skipAttributes = {name: true};
options.skipAttributes[Constants.CTOR_ARGS_ATTR] = true;
EllipseDecorator.call(this, options);
};
_.extend(LayerDecorator.prototype, EllipseDecorator.prototype);
LayerDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
LayerDecorator.prototype.PointerField = LayerField;
LayerDecorator.prototype.getDisplayName = function() {
return this._node.name;
};
// Create the pointer fields and change the event handlers
LayerDecorator.prototype.createPointerFields = function() {
var i = this.fields.length,
y,
ptr;
// Get the fields
y = EllipseDecorator.prototype.createPointerFields.apply(this, arguments);
while (i < this.fields.length) {
// Update the event handlers
ptr = this.fields[i].name;
// TODO: This should be changed in EasyDAG
this.fields[i].selectTarget = this.getValidNestedLayers.bind(this, ptr);
i++;
}
return y;
};
LayerDecorator.prototype.getValidNestedLayers = function(ptr) {
var tgtId = this._node.pointers[ptr];
if (tgtId) {
WebGMEGlobal.State.registerActiveObject(tgtId);
} else {
this.createLayerArg(ptr);
}
};
LayerDecorator.prototype.createLayerArg = function(ptr) {
// Find the Architecture node type
var metanodes = this.client.getAllMetaNodes(),
base = metanodes.find(node => node.getAttribute('name') === 'Architecture'),
baseId,
msg = `Creating layers for "${ptr}" of ${this._node.name}`,
tgtId;
if (!base) {
return this.logger.error('Could not find "Architecture" type!');
}
// Create a nested "architecture" node and set the ptr target to it
baseId = base.getId();
this.client.startTransaction(msg);
tgtId = this.client.createChild({
parentId: this._node.id,
baseId: baseId
});
this.client.setAttributes(tgtId, 'name', `${ptr} (${this._node.name})`);
this.savePointer(ptr, tgtId);
this.client.completeTransaction();
WebGMEGlobal.State.registerActiveObject(tgtId);
};
LayerDecorator.prototype.savePointer = function(ptr, to) {
if (!to) { // delete the current target
var currentId = this._node.pointers[ptr],
name = this._node.name;
// If the target is contained in the current node, delete it!
if (currentId.indexOf(this._node.id) === 0) {
this.client.startTransaction(`Removing layer for ${ptr} of ${name}`);
this.client.delMoreNodes([currentId]);
this.client.completeTransaction();
this.logger.info(`Removed ${ptr} and deleted target (${currentId})`);
} else {
this.logger.info(`Removed ${ptr} (external architecture)`);
}
} else { // create and set the node
EllipseDecorator.prototype.savePointer.apply(this, arguments);
}
};
return LayerDecorator;
});
@@ -0,0 +1,29 @@
/* globals define, _ */
define([
'decorators/EllipseDecorator/EasyDAG/PointerField'
], function(
PointerField
) {
// The LayerField behaves the same as PointerFields but it shows "click to view"
// if it has a value
var LayerField = function() {
PointerField.apply(this, arguments);
};
_.extend(LayerField.prototype, PointerField.prototype);
LayerField.prototype.getContent = function(content) {
return content && 'click to view';
};
LayerField.prototype.createContent = function(w, y, content) {
PointerField.prototype.createContent.call(this, w, y, this.getContent(content));
this.$content.attr('font-style', 'italic');
};
LayerField.prototype.setValue = function(content) {
PointerField.prototype.setValue.call(this, this.getContent(content));
};
return LayerField;
});
@@ -0,0 +1,39 @@
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
define([
'js/Decorators/DecoratorBase',
'./EasyDAG/LayerDecorator.EasyDAGWidget'
], function (
DecoratorBase,
LayerDecoratorEasyDAGWidget
) {
'use strict';
var LayerDecorator,
__parent__ = DecoratorBase,
__parent_proto__ = DecoratorBase.prototype,
DECORATOR_ID = 'LayerDecorator';
LayerDecorator = function (params) {
var opts = _.extend({loggerName: this.DECORATORID}, params);
__parent__.apply(this, [opts]);
this.logger.debug('LayerDecorator ctor');
};
_.extend(LayerDecorator.prototype, __parent_proto__);
LayerDecorator.prototype.DECORATORID = DECORATOR_ID;
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
LayerDecorator.prototype.initializeSupportedWidgetMap = function () {
this.supportedWidgetMap = {
EasyDAG: LayerDecoratorEasyDAGWidget
};
};
return LayerDecorator;
});
@@ -1,4 +1,4 @@
/*globals define, $,_*/
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
/**
+37 -11
Ver Arquivo
@@ -79,7 +79,11 @@ define([
};
CreateExecution.prototype.createExecution = function (node) {
var name = this.core.getAttribute(node, 'name');
// Get the user supplied name
var name = this.core.getAttribute(node, 'name'),
config = this.getCurrentConfig(),
basename = config.name || (name + '_execution');
// Given a pipeline, copy all the operations to a custom job
// - Copy the operations
@@ -89,38 +93,46 @@ define([
// - 'console' show console output (future feature)
// - Update the references
var tgtNode,
execName,
copies,
opTuples, // [[op, index], [op, index], ...]
dataMapping = {};
return this.getExecutionDir()
.then(execDir => {
var execDirId = this.core.getPath(execDir),
execTypeId = this.core.getPath(this.META.Execution);
this.logger.debug(`Creating execution node in ${execDirId} (type is ${execTypeId})`);
tgtNode = this.core.createNode({
base: this.META.Execution,
parent: execDir
});
// Get a unique name
return this.getUniqueExecName(name + '_execution');
this.logger.debug(`About to get a unique name starting w/ ${basename}`);
return this.getUniqueExecName(basename);
})
.then(execName => {
var isSnapshot = !this.getCurrentConfig().debug;
.then(_execName => {
var isSnapshot = !this.getCurrentConfig().debug,
originName = this.core.getAttribute(this.activeNode, 'name'),
oId = this.core.getPath(this.activeNode),
tgtId = this.core.getPath(tgtNode);
this.logger.debug(`Creating execution ${execName}`);
execName = _execName;
this.logger.debug(`Configuring execution attributes (${execName})`);
// Set all the metadata for the new execution
this.core.setAttribute(tgtNode, 'name', execName);
this.core.setAttribute(tgtNode, 'snapshot', isSnapshot);
this.core.setAttribute(tgtNode, 'tagname', execName);
this.core.setAttribute(tgtNode, 'createdAt', Date.now());
this.logger.debug(`Setting origin pipeline to ${originName} (${oId})`);
this.core.setPointer(tgtNode, 'origin', this.activeNode);
this.logger.debug(`Adding ${tgtId} to execution list of ${originName} (${oId})`);
this.core.addMember(this.activeNode, 'executions', tgtNode);
return this.project.createTag(
execName.replace(/[ -]/g, '_'),
this.currentHash
);
this.logger.debug(`Creating tag "${execName}"`);
})
.then(() => this.core.loadChildren(node))
.then(children => {
@@ -128,6 +140,7 @@ define([
this.logger.warn('No children in pipeline. Will proceed anyway');
}
this.logger.debug(`Copying operations to "${execName}"`);
return this.copyOperations(children, tgtNode);
})
.then(copiedPairs => {
@@ -138,6 +151,7 @@ define([
.filter(pair => this.core.isTypeOf(pair[0], this.META.Operation));
// Create a mapping of old names to new names
this.logger.debug('Creating mapping of old->new');
return Q.all(opTuples.map(pair =>
// Add the input/output mappings to the dataMapping
this.addDataToMap(originals[pair[1]], pair[0], dataMapping)
@@ -145,22 +159,30 @@ define([
);
})
.then(() => { // datamapping is set!
this.logger.debug('Updating references...');
this.updateReferences(copies, dataMapping);
this.logger.debug('Placing operations in Job containers');
this.boxOperations(opTuples.map(o => o[0]), tgtNode);
this.logger.debug('Finished! Saving...');
return this.save(`Created execution from ${name}`);
})
.then(() => this.project.createTag(execName, this.currentHash))
.then(() => tgtNode); // return tgtNode
};
CreateExecution.prototype.getUniqueExecName = function (basename) {
var name = basename,
taken = {},
var taken = {},
name,
i = 2;
basename = basename.replace(/[^\da-zA-Z_]/g, '_');
name = basename;
// Get a unique name wrt the tags and the other executions
return this.project.getTags()
.then(tags => {
Object.keys(tags).forEach(name => taken[name] = true);
this.logger.debug(`Existing tags are ${Object.keys(tags).join(',')}`);
// Get the other executions
return this.getExecutionDir();
@@ -171,11 +193,13 @@ define([
})
.then(execs => {
var names = execs.map(exec => this.core.getAttribute(exec, 'name'));
this.logger.debug(`Existing names are ${names.join(',')}`);
names.forEach(name => taken[name] = true);
while (taken[name]) {
name = basename + '_' + (i++);
}
this.logger.debug(`Unique name is "${name}"`);
return name;
});
};
@@ -184,6 +208,7 @@ define([
var snapshot = !this.getCurrentConfig().debug;
if (snapshot) {
this.logger.debug('Execution is a snapshot -> severing the inheritance');
return Q.all(nodes.map(node => {
if (this.isLocalOperation(node) ||
this.isMetaTypeOf(node, this.META.Transporter)) {
@@ -198,6 +223,7 @@ define([
);
} else if (nodes.length) {
this.logger.debug('Execution is not a snapshot -> doing a simple copy');
var copies = this.core.copyNodes(nodes, dst);
return nodes.map((node, i) => [node, copies[i]]);
}
+150 -144
Ver Arquivo
@@ -4,18 +4,22 @@
define([
'plugin/PluginBase',
'common/util/guid',
'deepforge/Constants',
'deepforge/utils',
'js/RegistryKeys',
'js/Panels/MetaEditor/MetaEditorConstants',
'underscore',
'text!deepforge/layers.json',
'./schemas/index',
'text!./metadata.json'
], function (
PluginBase,
generateGuid,
Constants,
utils,
REGISTRY_KEYS,
META_CONSTANTS,
_,
DEFAULT_LAYERS,
Schemas,
metadata
) {
'use strict';
@@ -51,110 +55,102 @@ define([
* @param {function(string, plugin.PluginResult)} callback - the result callback
*/
CreateTorchMeta.prototype.main = function (callback) {
// Use self to access core, project, result, logger etc from PluginBase.
// These are all instantiated at this point.
var self = this;
if (!this.META.Language) {
return callback('"Language" container required to run plugin', this.result);
}
// Extra layer names
this.getJsonLayers((err, text) => {
if (err) {
return callback(err, this.result);
// The format is...
// - (Abstract) CategoryLayerTypes
// - LayerName
// - Attributes (if exists)
var layers,
content = {},
categories,
config = this.getCurrentConfig(),
nodes = {};
try {
layers = this.getJsonLayers();
} catch (e) {
return callback('JSON parse error: ' + e, this.result);
}
layers.forEach(layer => {
if (!content[layer.type]) {
content[layer.type] = [];
}
// The format is...
// - (Abstract) CategoryLayerTypes
// - LayerName
// - Attributes (if exists)
var content = {},
categories,
config = this.getCurrentConfig(),
nodes = {},
layers;
try {
layers = JSON.parse(text);
} catch (e) {
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) {
this.META.Layer = this.createMetaNode('Layer', this.META.FCO);
}
// Create the category nodes
categories
.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.setBase(layer, 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(layer => {
var name = layer.name;
nodes[name] = this.createMetaNode(name, nodes[cat], cat, layer);
// Make the node non-abstract
this.core.setRegistry(nodes[name], 'isAbstract', false);
});
});
self.save('CreateTorchMeta updated model.', function (err) {
if (err) {
callback(err, self.result);
return;
}
self.result.setSuccess(true);
callback(null, self.result);
});
content[layer.type].push(layer);
});
categories = Object.keys(content);
// Create the base class, if needed
if (!this.META.Layer) {
this.META.Layer = this.createMetaNode('Layer', this.META.FCO);
}
// Create the category nodes
categories
.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.setBase(layer, 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(layer => {
var name = layer.name,
node;
node = this.createMetaNode(name, nodes[cat], cat, layer);
// Make the node non-abstract
if (node) {
this.core.setRegistry(node, 'isAbstract', false);
nodes[name] = node;
}
});
});
this.save('CreateTorchMeta updated model.')
.then(() => {
this.result.setSuccess(true);
callback(null, this.result);
})
.fail(err => callback(err, this.result));
};
CreateTorchMeta.prototype.removeFromMeta = function (nodeId) {
@@ -196,26 +192,27 @@ define([
return sheet.SetID;
};
CreateTorchMeta.prototype.getJsonLayers = function (callback) {
var config = this.getCurrentConfig();
CreateTorchMeta.prototype.getJsonLayers = function () {
var config = this.getCurrentConfig(),
schema = config.layerSchema;
if (config.layerNameHash) {
this.blobClient.getObject(config.layerNameHash, (err, buffer) => {
if (err) {
return callback(err, this.result);
}
var text = String.fromCharCode.apply(null, new Uint8Array(buffer));
return callback(null, text);
});
} else {
return callback(null, DEFAULT_LAYERS);
if (schema === 'all') {
return Object.keys(Schemas).map(key => JSON.parse(Schemas[key]))
.reduce((l1, l2) => l1.concat(l2), []);
}
return JSON.parse(Schemas[schema]);
};
var isBoolean = txt => {
return typeof txt === 'boolean' || (txt === 'false' || txt === 'true');
// Some helper methods w/ attribute handling
var LUA_TO_GME = {
boolean: 'boolean',
number: 'float',
string: 'string'
};
var isLayerAttribute = type => type && type.substring(0, 3) === 'nn.';
CreateTorchMeta.prototype.createMetaNode = function (name, base, tabName, layer) {
var node = this.META[name],
nodeId = node && this.core.getPath(node),
@@ -223,6 +220,8 @@ define([
position = this.getPositionFor(name, tabName),
setters = {},
defaults = {},
types = {},
type,
attrs,
desc;
@@ -230,6 +229,7 @@ define([
attrs = layer.params;
setters = layer.setters;
defaults = layer.defaults;
types = layer.types || types;
}
if (!tabId) {
this.logger.error(`No meta sheet for ${tabName}`);
@@ -273,15 +273,15 @@ define([
// Remove attributes not in the given list
var currentAttrs = this.core.getValidAttributeNames(node),
defVal,
rmAttrs;
rmAttrs,
simpleAttrs,
rmPtrs;
rmAttrs = _.difference(currentAttrs, attrs) // old attribute names
simpleAttrs = attrs.filter(name => !isLayerAttribute(types[name]));
rmAttrs = _.difference(currentAttrs, simpleAttrs) // old attribute names
.filter(attr => attr !== 'name')
.filter(attr => !setters[attr]);
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) {
@@ -289,35 +289,37 @@ define([
}
});
attrs.forEach((name, index) => {
// Remove all old pointers
rmPtrs = _.difference(this.core.getPointerNames(node), currentAttrs)
.filter(ptr => ptr !== 'base');
if (rmPtrs.length + rmAttrs.length) {
this.logger.debug(`Removing ${rmPtrs.concat(rmAttrs).join(', ')} from ${name}`);
}
rmPtrs.forEach(ptr => this.core.delPointerMeta(node, ptr));
attrs.forEach(name => {
desc = {};
desc.argindex = index;
defVal = defaults.hasOwnProperty(name) ? defaults[name] : '';
this.addAttribute(name, node, desc, defVal);
type = LUA_TO_GME[types[name]];
if (type) {
desc.type = type;
}
if (isLayerAttribute(types[name])) { // Check if it is an nn layer type
// If so, create a pointer rather than attribute
this.addLayerAttribute(name, node);
this.logger.debug(`${name} is a layer type attribute`);
} else {
this.addAttribute(name, node, desc, defVal);
}
});
this.core.setAttribute(node, Constants.CTOR_ARGS_ATTR, attrs.join(','));
// Add the setters to the meta
Object.keys(setters).forEach(name => {
var values;
desc = setters[name];
defVal = defaults.hasOwnProperty(name) ? defaults[name] : '';
if (desc.setterType === 'const') {
values = Object.keys(desc.setterFn);
desc.isEnum = true;
desc.enumValues = values;
if (values.every(isBoolean)) {
if (!defaults.hasOwnProperty(name) && values.length === 1) {
// there is only a method to toggle the flag to true/false,
// then the default must be the other one
defVal = values[0] === 'true' ? false : true;
}
if (isBoolean(defVal)) {
this.logger.debug(`setting ${name} to boolean`);
desc.type = 'boolean';
}
}
}
desc = utils.getSetterSchema(name, setters, defaults);
defVal = desc.default;
delete desc.default;
this.addAttribute(name, node, desc, defVal);
});
}
@@ -353,6 +355,13 @@ define([
};
};
CreateTorchMeta.prototype.addLayerAttribute = function (name, node) {
// No default value support for now...
// Create a pointer of the given type on the node
this.core.setPointerMetaTarget(node, name, this.META.Architecture, 1, 1);
this.core.setPointerMetaLimits(node, name, 1, 1);
};
CreateTorchMeta.prototype.addAttribute = function (name, node, schema, defVal) {
schema.type = schema.type || 'string';
if (schema.type === 'list') { // FIXME: add support for lists
@@ -368,9 +377,6 @@ define([
schema.max = +schema.max;
}
// Add the argindex flag
schema.argindex = schema.argindex;
// Create the attribute and set the schema
this.core.setAttributeMeta(node, name, schema);
+23 -18
Ver Arquivo
@@ -7,24 +7,29 @@
"src": "",
"class": "glyphicon glyphicon-ok-circle"
},
"disableServerSideExecution": false,
"disableServerSideExecution": true,
"disableBrowserSideExecution": false,
"configStructure": [
{
"name": "layerNameHash",
"displayName": "Torch Layers",
"description": "Yaml file of torch layer descriptors (optional)",
"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
}
{
"name": "layerSchema",
"displayName": "Torch Libraries",
"description": "Torch nn libraries to create layers from",
"value": "all",
"valueItems": [
"nn",
"rnn",
"all"
],
"valueType": "string",
"readOnly": false
},
{
"name": "removeOldLayers",
"displayName": "Delete old layers",
"description": "Delete all layers not in the current description",
"value": true,
"valueType": "boolean",
"readOnly": false
}
]
}
}
+13
Ver Arquivo
@@ -0,0 +1,13 @@
/*globals define*/
define([
'text!./nn.json',
'text!./rnn.json'
], function(
nn,
rnn
) {
return {
nn: nn,
rnn: rnn
};
});
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+178
Ver Arquivo
@@ -0,0 +1,178 @@
[
{
"name": "CopyGrad",
"baseType": "Identity",
"setters": {},
"defaults": {},
"type": "RNN"
},
{
"name": "FastLSTM",
"baseType": "LSTM",
"params": [
"inputSize",
"outputSize",
"rho",
"eps",
"momentum",
"affine"
],
"setters": {},
"types": {
"eps": "number",
"momentum": "number"
},
"defaults": {
"momentum": 0.1,
"eps": 0.1
},
"type": "RNN"
},
{
"name": "LSTM",
"baseType": "AbstractRecurrent",
"params": [
"inputSize",
"outputSize",
"rho",
"cell2gate"
],
"setters": {},
"types": {
"rho": "number"
},
"defaults": {
"rho": 9999
},
"type": "RNN"
},
{
"name": "LinearNoBias",
"baseType": "Linear",
"params": [
"inputSize",
"outputSize"
],
"setters": {},
"types": {},
"defaults": {},
"type": "Simple"
},
{
"name": "LookupTableMaskZero",
"baseType": "LookupTable",
"params": [
"nIndex",
"nOutput"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
},
{
"name": "NormStabilizer",
"baseType": "AbstractRecurrent",
"params": [
"beta"
],
"setters": {},
"defaults": {},
"type": "RNN"
},
{
"name": "Recurrent",
"baseType": "AbstractRecurrent",
"params": [
"start",
"input",
"feedback",
"transfer",
"rho",
"merge"
],
"setters": {},
"types": {
"start": "nn.Module",
"transfer": "nn.Module",
"feedback": "nn.Module",
"input": "nn.Module"
},
"defaults": {},
"type": "RNN"
},
{
"name": "SAdd",
"baseType": "Module",
"params": [
"addend",
"negate"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
},
{
"name": "SeqBRNN",
"baseType": "Container",
"params": [
"inputDim",
"hiddenDim",
"batchFirst"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
},
{
"name": "SeqGRU",
"baseType": "Module",
"params": [
"inputSize",
"outputSize"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
},
{
"name": "SeqLSTM",
"baseType": "Module",
"params": [
"inputsize",
"hiddensize",
"outputsize"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
},
{
"name": "SeqLSTMP",
"baseType": "SeqLSTM",
"params": [
"inputsize",
"hiddensize",
"outputsize"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
},
{
"name": "SeqReverseSequence",
"baseType": "Module",
"params": [
"dim"
],
"setters": {},
"types": {},
"defaults": {},
"type": "RNN"
}
]
@@ -0,0 +1,37 @@
/* eslint-disable no-console */
// Update the metadata and schemas/index based on the new schemas in schemas/
// Update metadata
var fs = require('fs'),
path = require('path'),
schemas,
metadata = require('./metadata.json'),
schemaList;
schemas = fs.readdirSync(__dirname + '/schemas/')
.filter(name => path.extname(name) === '.json')
.map(name => name.replace(/\.json$/, ''));
console.log('Discovered schemas: ' + schemas.join(', '));
schemaList = metadata.configStructure.find(struct => struct.name === 'layerSchema');
schemaList.valueItems = schemas.concat('all');
console.log('Updating metadata...');
fs.writeFileSync(__dirname + '/metadata.json', JSON.stringify(metadata, null, 2));
// Update index.js
var index =
`/*globals define*/
define([
${schemas.map(s => `'text!./${s}.json'`).join(',\n ')}
], function(
${schemas.map(s => s).join(',\n ')}
) {
return {
${schemas.map(s => s + ': ' + s).join(',\n ')}
};
});`;
console.log('Updating index.js...');
fs.writeFileSync(__dirname + '/schemas/index.js', index);
+204 -45
Ver Arquivo
@@ -2,6 +2,7 @@
/*jshint node:true, browser:true*/
define([
'common/storage/constants',
'text!./metadata.json',
'executor/ExecutorClient',
'plugin/PluginBase',
@@ -12,6 +13,7 @@ define([
'q',
'underscore'
], function (
STORAGE_CONSTANTS,
pluginMetadata,
ExecutorClient,
PluginBase,
@@ -46,6 +48,7 @@ define([
this._markForDeletion = {}; // id -> node
this._oldMetadataByName = {}; // name -> id
this.lastAppliedCmd = {};
this.canceled = false;
};
/**
@@ -79,10 +82,43 @@ define([
}
this._callback = callback;
this.currentForkName = null;
this.prepare()
.then(() => this.executeJob(this.activeNode));
};
ExecuteJob.prototype.updateForkName = function (basename) {
basename = basename + '_fork';
basename = basename.replace(/[- ]/g, '_');
return this.project.getBranches().then(branches => {
var names = Object.keys(branches),
name = basename,
i = 2;
while (names.indexOf(name) !== -1) {
name = basename + '_' + i;
i++;
}
this.forkName = name;
});
};
// Override 'save' to notify the user on fork
ExecuteJob.prototype.save = function (msg) {
var name = this.core.getAttribute(this.activeNode, 'name');
return this.updateForkName(name)
.then(() => PluginBase.prototype.save.call(this, msg))
.then(result => {
var msg;
if (result.status === STORAGE_CONSTANTS.FORKED) {
msg = `"${name}" execution has forked to "${result.forkName}"`;
this.currentForkName = result.forkName;
this.sendNotification(msg);
}
});
};
ExecuteJob.prototype.getConnections = function (nodes) {
var conns = [];
for (var i = nodes.length; i--;) {
@@ -177,6 +213,24 @@ define([
}
delete this.lastAppliedCmd[nodeId];
delete this._markForDeletion[nodeId];
this.core.delAttribute(job, 'jobId');
this.core.delAttribute(job, 'secret');
};
ExecuteJob.prototype.resultMsg = function(msg) {
this.sendNotification(msg);
this.createMessage(null, msg);
};
ExecuteJob.prototype.onOperationCanceled = function(op) {
var job = this.core.getParent(op),
name = this.core.getAttribute(op, 'name'),
msg = `"${name}" canceled!`;
this.core.setAttribute(job, 'status', 'canceled');
this.resultMsg(msg);
this.onComplete(op, null);
};
ExecuteJob.prototype.onOperationFail =
@@ -186,8 +240,8 @@ define([
exec = this.core.getParent(job),
name = this.core.getAttribute(job, 'name'),
jobId = this.core.getPath(job),
status = err ? 'fail' : 'success',
msg = err ? `${name} execution failed: ${err}` :
status = err ? 'fail' : (this.canceled ? 'canceled' : 'success'),
msg = err ? `${name} execution failed!` :
`${name} executed successfully!`,
promise = Q();
@@ -195,8 +249,16 @@ define([
this.logger.info(`Setting ${name} (${jobId}) status to ${status}`);
this.clearOldMetadata(job);
if (this.currentForkName) {
// notify client that the job has completed
this.sendNotification(`"${name}" execution completed on branch "${this.currentForkName}"`);
}
if (err) {
this.logger.warn(`${name} failed: ${err}`);
this.core.setAttribute(exec, 'status', 'failed');
} else if (this.canceled) {
// Should I set this to 'canceled'?
this.core.setAttribute(exec, 'status', 'canceled');
} else {
// Check if all the other jobs are successful. If so, set the
// execution status to 'success'
@@ -222,6 +284,7 @@ define([
});
}
this.createMessage(null, msg);
promise
.then(() => this.save(msg))
.then(() => {
@@ -239,6 +302,24 @@ define([
children.find(child => this.isMetaTypeOf(child, this.META.Operation)));
};
ExecuteJob.prototype.onBlobRetrievalFail = function (node, input, err) {
var job = this.core.getParent(node),
e = `Failed to retrieve "${input}" (${err})`,
consoleErr = `Failed to execute operation: ${e}`;
consoleErr += [
'\n\nA couple things to check out:\n',
'- Has the location of DeepForge\'s blob changed?',
' (Configurable using "blob.dir" in the deepforge config' +
' or setting the DEEPFORGE_BLOB_DIR environment variable)\n',
'- Was this project created using a different blob location?'
].join('\n ');
this.core.setAttribute(job, 'stdout', consoleErr);
this.onOperationFail(node, `Blob retrieval failed for "${name}": ${e}`);
};
ExecuteJob.prototype.executeJob = function (job) {
return this.getOperation(job).then(node => {
var jobId = this.core.getPath(job),
@@ -272,37 +353,46 @@ define([
var hash = files.inputAssets[input];
// data asset for "input"
return this.blobClient.getMetadata(hash);
return this.blobClient.getMetadata(hash)
.fail(err => this.onBlobRetrievalFail(job, input, err));
})
);
})
.then(mds => {
// get (input, filename) tuples
// Record the large files
var inputData = {};
mds.forEach((metadata, i) => {
// add the hashes for each input
var input = inputs[i],
name = metadata.name,
hash = files.inputAssets[input];
data['inputs/' + input + '/' + name] = hash;
inputData['inputs/' + input + '/data'] = {
req: hash,
cache: metadata.content
};
});
delete files.inputAssets;
files['input-data.json'] = JSON.stringify(inputData, null, 2);
// Add pointer assets
Object.keys(files.ptrAssets)
.forEach(path => data[path] = files.ptrAssets[path]);
delete files.ptrAssets;
// Add the executor config
return this.getOutputs(node);
})
.then(outputArgs => {
var config,
outputs,
fileList,
ptrFiles = Object.keys(files.ptrAssets),
file;
files['start.js'] = _.template(Templates.START)(CONSTANTS);
delete files.ptrAssets;
fileList = Object.keys(files).concat(ptrFiles);
outputs = outputArgs.map(pair => pair[0])
.map(name => {
return {
@@ -318,7 +408,7 @@ define([
},
{
name: name + '-all-files',
resultPatterns: []
resultPatterns: fileList
}
);
@@ -329,7 +419,6 @@ define([
resultArtifacts: outputs
};
files['executor_config.json'] = JSON.stringify(config, null, 4);
files['start.js'] = _.template(Templates.START)(CONSTANTS);
// Save the artifact
// Remove empty hashes
@@ -382,7 +471,13 @@ define([
this.logger.debug(`Making a commit from ${this.currentHash}`);
this.save(`Queued "${name}" operation in ${this.pipelineName}`)
.then(() => executor.createJob({hash}))
.then(() => this.watchOperation(executor, hash, opNode, job))
.then(info => {
this.core.setAttribute(job, 'jobId', info.hash);
if (info.secret) { // o.w. it is a cached job!
this.core.setAttribute(job, 'secret', info.secret);
}
return this.watchOperation(executor, hash, opNode, job);
})
.catch(err => this.logger.error(`Could not execute "${name}": ${err}`));
};
@@ -570,12 +665,18 @@ define([
})
.then(_tplContents => {
tplContents = _tplContents;
var hashes = inputs
// storing the hash for now...
.map(pair =>
files.inputAssets[pair[0]] = this.core.getAttribute(pair[2], 'data')
);
return Q.all(hashes.map(h => this.blobClient.getMetadata(h)));
var hashes = inputs.map(pair => {
var hash = this.core.getAttribute(pair[2], 'data');
files.inputAssets[pair[0]] = hash;
return {
hash: hash,
name: pair[0]
};
});
return Q.all(hashes.map(pair =>
this.blobClient.getMetadata(pair.hash)
.fail(err => this.onBlobRetrievalFail(node, pair.name, err))));
})
.then(metadatas => {
// Create the deserializer
@@ -703,7 +804,19 @@ define([
var jobId = this.core.getPath(job),
opId = this.core.getPath(op),
info,
name;
secret,
name = this.core.getAttribute(job, 'name');
// If canceled, stop the operation
if (this.canceled) {
secret = this.core.getAttribute(job, 'secret');
if (secret) {
executor.cancelJob(hash, secret);
this.core.delAttribute(job, 'secret');
this.canceled = true;
return this.onOperationCanceled(op);
}
}
return executor.getInfo(hash)
.then(_info => { // Update the job's stdout
@@ -718,15 +831,21 @@ define([
.then(outputLines => {
var stdout = this.core.getAttribute(job, 'stdout'),
output = outputLines.map(o => o.output).join(''),
jobName = this.core.getAttribute(job, 'name');
last = stdout.lastIndexOf('\n'),
lastLine;
// parse deepforge commands
output = this.parseForMetadataCmds(job, output);
if (last !== -1) {
stdout = stdout.substring(0, last+1);
lastLine = stdout.substring(last+1);
output = lastLine + output;
}
output = this.processStdout(job, output, true);
if (output) {
stdout += output;
this.core.setAttribute(job, 'stdout', stdout);
return this.save(`Received stdout for ${jobName}`);
return this.save(`Received stdout for ${name}`);
}
});
}
@@ -736,7 +855,6 @@ define([
if (info.status === 'RUNNING' &&
this.core.getAttribute(job, 'status') !== 'running') {
name = this.core.getAttribute(job, 'name');
this.core.setAttribute(job, 'status', 'running');
this.save(`Started "${name}" operation in ${this.pipelineName}`);
}
@@ -748,26 +866,40 @@ define([
return;
}
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 => {
// Parse the remaining code
stdout = this.parseForMetadataCmds(job, stdout, true);
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.onOperationFail(op, `Operation "${opId}" failed! ${JSON.stringify(info)}`);
} else {
this.onDistOperationComplete(op, info);
}
});
if (info.status === 'CANCELED') {
// If it was cancelled, the pipeline has been stopped
this.logger.debug(`"${name}" has been CANCELED!`);
this.canceled = true;
return this.onOperationCanceled(op);
}
if (info.status === 'SUCCESS' || info.status === 'FAILED_TO_EXECUTE') {
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 => {
// Parse the remaining code
stdout = this.processStdout(job, 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.onOperationFail(op, `Operation "${opId}" failed! ${JSON.stringify(info)}`);
} else {
this.onDistOperationComplete(op, info);
}
});
} else { // something bad happened...
var err = `Failed to execute operation "${opId}": ${info.status}`,
consoleErr = `Failed to execute operation: ${info.status}`;
this.core.setAttribute(job, 'stdout', consoleErr);
this.logger.error(err);
this.onOperationFail(op, err);
}
})
.catch(err => this.logger.error(`Could not get op info for ${opId}: ${err}`));
};
@@ -853,10 +985,37 @@ define([
LocalExecutor.prototype
);
ExecuteJob.prototype.processStdout = function (job, text, continued) {
// resolve \r
var lines,
chars,
result,
i = 0;
text = text.replace(/\u0000/g, '');
lines = text.split('\n');
for (var l = lines.length-1; l >= 0; l--) {
i = 0;
chars = lines[l].split('');
result = [];
for (var c = 0; c < chars.length; c++) {
if (chars[c] === '\r') {
i = 0;
}
result[i] = chars[c];
i++;
}
lines[l] = result.join('');
}
// ... and metadata commands
return this.parseForMetadataCmds(job, lines, !continued);
};
//////////////////////////// Metadata ////////////////////////////
ExecuteJob.prototype.parseForMetadataCmds = function (job, text, skip) {
ExecuteJob.prototype.parseForMetadataCmds = function (job, lines, skip) {
var jobId = this.core.getPath(job),
lines = text.split('\n'),
args,
result = [],
cmdCnt = 0,
@@ -911,7 +1070,7 @@ define([
ExecuteJob.prototype[CONSTANTS.GRAPH_PLOT] = function (job, id, x, y) {
var jobId = this.core.getPath(job),
nonNum = /[^\d]*/g,
nonNum = /[^\d\.]*/g,
graph,
points;
@@ -37,6 +37,7 @@ function _Line:__init(graphId, name, opts)
end
function _Line:add(x, y)
assert(type(x) == "number" and type(y) == "number", "adding point (" .. tostring(x) .. ", " .. tostring(y) .. ") to " .. self.name .. " failed: expected (number, number)")
deepforge._cmd('<%= GRAPH_PLOT %>', self.id, x, y)
end
@@ -1,6 +1,6 @@
require 'paths'
local path = 'inputs/<%= name %>/<%= filename %>'
local abs_path = paths.concat('inputs', '<%= name %>', '<%= filename %>')
local path = 'inputs/<%= name %>/data'
local abs_path = paths.concat('inputs', '<%= name %>', 'data')
<%= code %>
+150 -8
Ver Arquivo
@@ -3,6 +3,7 @@
// - receives some commands and uploads intermediate data
var spawn = require('child_process').spawn,
fs = require('fs'),
path = require('path'),
log = console.error,
logger = {};
@@ -12,14 +13,19 @@ var spawn = require('child_process').spawn,
// Get the BlobClient...
var COMMAND_PREFIX = '<%= START_CMD %>',
IMAGE = '<%= IMAGE %>',
requirejs = require('webgme').requirejs;
requirejs = require('webgme').requirejs,
remainingImageCount = 0,
exitCode = null;
requirejs([
'q',
'blob/BlobClient'
], function(
Q,
BlobClient
) {
var url = process.env.ORIGIN_URL || 'http://127.0.0.1:8888',
CACHE_DIR = process.env.DEEPFORGE_WORKER_CACHE || './worker-cache',
protocol = url.split('://').shift(),
address,
port = (url.split(':') || ['80']).pop();
@@ -27,6 +33,37 @@ requirejs([
address = url.replace(protocol + '://', '')
.replace(':' + port, '');
// Create CACHE_DIR if it doesn't exist
var prepareCache = function() {
var dirs = CACHE_DIR.replace(/\/$/, '').split('/'),
cacheParent;
dirs.pop();
cacheParent = dirs.join('/');
return makeIfNeeded(cacheParent).then(() => makeIfNeeded(CACHE_DIR));
};
var makeIfNeeded = function(dir) {
var deferred = Q.defer(),
job;
log(`makeIfNeeded: ${JSON.stringify(dir)}`);
fs.lstat(dir, (err, stat) => {
if (err || !stat.isDirectory()) {
fs.mkdir(dir, err => {
if (err) {
return deferred.reject(err);
}
deferred.resolve();
});
} else {
deferred.resolve();
}
});
return deferred.promise;
};
var blobClient = new BlobClient({
server: address,
httpsecure: protocol === 'https',
@@ -34,28 +71,47 @@ requirejs([
logger: logger
});
var checkFinished = () => {
if (exitCode !== null && remainingImageCount === 0) {
log('finished!');
process.exit(exitCode);
}
};
var uploadImage = function(line) {
var args = line.split(/\s+/),
name = args.slice(2).join(' ').replace(/\s+$/, ''),
filename = 'metadata/' + name + '.png';
// Upload the image from metadata/
remainingImageCount++;
fs.readFile(filename, (err, content) => {
if (err) {
console.error(`Could not read ${filename}: ${err}`);
logger.error(`Could not read ${filename}: ${err}`);
return;
}
// Add hash to the image command
log('about to putFile', filename);
blobClient.putFile(filename, content)
.then(hash => {
args.splice(2, 0, hash);
console.log(args.join(' '));
log('printing cmd:', args.join(' '));
--remainingImageCount;
log('finished uploading ' + filename + ' ' + remainingImageCount + ' remain');
checkFinished();
})
.fail(err => console.error(`${filename} upload failed: ${err}`));
.fail(err => logger.error(`${filename} upload failed: ${err}`));
});
};
var onStderr = function(data) {
var text = data.toString();
// Filter out directory label from stack traces
process.stdout.write(text.replace(/\.\.\.\/.*\/(main|deepforge|init).lua/g, '$1'));
};
var onStdout = function(data) {
var lines = data.toString().split('\n'),
result = [],
@@ -74,9 +130,95 @@ requirejs([
process.stdout.write(result.join('\n'));
};
// Run 'th init.lua' and merge the stdout, stderr
var job = spawn('th', ['init.lua']);
job.stdout.on('data', onStdout);
job.stderr.on('data', data => process.stdout.write(data));
job.on('close', code => process.exit(code));
var createCacheDir = function(hash) {
var dir = hash.substring(0, 2);
return makeIfNeeded(CACHE_DIR + '/' + dir);
};
var dataCachePath = function(hash) {
var dir = hash.substring(0, 2),
filename = hash.substring(2),
cachePath = `${CACHE_DIR}/${dir}/${filename}`;
// Get the path for data in the cache
return cachePath;
};
var makeSymLink = function(target, src) {
var deferred = Q.defer(),
job;
src = path.resolve(src);
target = path.resolve(target);
fs.stat(src, err => {
if (err.code === 'ENOENT') {
logger.debug(`creating symlink "ln -s ${target} ${src}"`);
job = spawn('ln', ['-s', target, src || '.']);
job.on('exit', code => {
if (code) {
deferred.reject(`Could not create symlink ${target} -> ${src||'.'}`);
return;
}
deferred.resolve();
});
}
deferred.resolve();
});
return deferred.promise;
};
var getData = function(ipath, hashes) {
// Download the data and put it in the given path
var deferred = Q.defer(),
inputName = ipath.split('/')[1],
cachePath = dataCachePath(hashes.cache);
logger.debug(`retrieving ${ipath}`);
fs.lstat(cachePath, (err, cacheStats) => {
// Check if the data exists in the cache
if (!err && cacheStats.isFile()) {
logger.info(`${inputName} already cached. Skipping retrieval from blob`);
return makeSymLink(cachePath, ipath).then(deferred.resolve);
}
createCacheDir(hashes.cache)
.then(() => blobClient.getObject(hashes.req))
.then(buffer => fs.writeFile(cachePath, buffer, (err, result) => {
if (err) {
logger.error('Retrieving ' + ipath + ' failed!');
return deferred.reject(`Could not write to ${ipath}: ${err}`);
}
// Create the symlink
logger.info('Retrieved ' + ipath);
return makeSymLink(cachePath, ipath).then(deferred.resolve);
}))
.fail(err => deferred.reject(`Could not retrieve "${inputName}" (${err})`));
});
return deferred.promise;
};
// Download the large files
var inputData = JSON.parse(fs.readFileSync('./input-data.json')),
inputPaths = Object.keys(inputData);
// Request the data from the blob
prepareCache()
.then(() => Q.all(inputPaths.map(ipath => getData(ipath, inputData[ipath]))))
.then(() => {
// Run 'th init.lua' and merge the stdout, stderr
var job = spawn('th', ['init.lua']);
job.stdout.on('data', onStdout);
job.stderr.on('data', onStderr);
job.on('close', code => {
exitCode = code;
log('script finished w/ exit code:', code);
checkFinished();
});
})
.fail(err => {
console.log(`Data retrieval failed: ${err}`);
process.exit(1);
});
});
+42 -22
Ver Arquivo
@@ -74,6 +74,7 @@ define([
// - keep track if the pipeline has errored
// - if so, don't start any more jobs
this.pipelineError = null;
this.canceled = false;
this.runningJobs = 0;
// metadata records
@@ -103,15 +104,18 @@ define([
// If starting with a pipeline, we will create an Execution first
startPromise = this.createExecution(this.activeNode)
.then(execNode => {
this.logger.debug(`Finished creating execution "${this.core.getAttribute(execNode, 'name')}"`);
this.activeNode = execNode;
});
} else if (this.core.isTypeOf(this.activeNode, this.META.Execution)) {
this.logger.debug('Restarting execution');
startPromise = Q();
} else {
return callback('Current node is not a Pipeline or Execution!', this.result);
}
this._callback = callback;
this.currentForkName = null;
startPromise
.then(() => this.core.loadSubTree(this.activeNode))
@@ -120,41 +124,29 @@ define([
.filter(n => this.core.getParent(n) === this.activeNode);
this.pipelineName = this.core.getAttribute(this.activeNode, 'name');
this.logger.debug(`Loaded subtree of ${this.pipelineName}. About to build cache`);
this.buildCache(subtree);
this.logger.debug('Parsing execution for job inter-dependencies');
this.parsePipeline(children); // record deps, etc
this.logger.debug('Clearing old results');
return this.clearResults();
})
.then(() => this.executePipeline())
.fail(e => this.logger.error(e));
};
ExecutePipeline.prototype.updateForkName = function () {
var basename = this.pipelineName + '_fork';
return this.project.getBranches().then(branches => {
var names = Object.keys(branches),
name = basename,
i = 2;
while (names.indexOf(name) !== -1) {
name = basename + '_' + i;
i++;
}
this.forkName = name;
});
};
// 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(() => this.updateForkName())
.then(() => this.updateForkName(this.pipelineName))
.then(() => CreateExecution.prototype.save.call(this, msg))
.then(result => {
var msg;
if (result.status === STORAGE_CONSTANTS.FORKED) {
this.currentForkName = result.forkName;
msg = `"${this.pipelineName}" execution has forked to "${result.forkName}"`;
this.sendNotification(msg);
}
@@ -189,6 +181,8 @@ define([
this.core.setAttribute(this.activeNode, 'status', 'running');
this.logger.info('Setting all jobs status to "pending"');
this.logger.debug(`Making a commit from ${this.currentHash}`);
this.core.setAttribute(this.activeNode, 'startTime', Date.now());
this.core.delAttribute(this.activeNode, 'endTime');
return this.save(`Initializing ${this.pipelineName} for execution`);
};
@@ -287,8 +281,17 @@ define([
this.onPipelineComplete(err);
};
ExecutePipeline.prototype.onOperationCanceled = function(op) {
var job = this.core.getParent(op);
this.core.setAttribute(job, 'status', 'canceled');
this.runningJobs--;
this.logger.debug(`${this.core.getAttribute(job, 'name')} has been canceled`);
this.onPipelineComplete();
};
ExecutePipeline.prototype.onPipelineComplete = function(err) {
var name = this.core.getAttribute(this.activeNode, 'name');
var name = this.core.getAttribute(this.activeNode, 'name'),
msg = `"${this.pipelineName}" `;
if (err) {
this.runningJobs--;
@@ -296,17 +299,34 @@ define([
this.pipelineError = this.pipelineError || err;
if (this.pipelineError && this.runningJobs > 0) {
this.logger.info('Pipeline errored but is waiting for the running ' +
this.logger.debug(`${this.runningJobs} remaining jobs`);
if ((this.pipelineError || this.canceled) && this.runningJobs > 0) {
var action = this.pipelineError ? 'error' : 'cancel';
this.logger.info(`Pipeline ${action}ed but is waiting for the running ` +
'jobs to finish');
return;
}
if (this.currentForkName) {
// notify client that the job has completed
this.sendNotification(`"${this.pipelineName}" execution completed on branch "${this.currentForkName}"`);
}
if (this.pipelineError) {
msg += 'failed!';
} else if (this.canceled) {
msg += 'canceled!';
} else {
msg += 'finished!';
}
this.logger.debug(`Pipeline "${name}" complete!`);
this.core.setAttribute(this.activeNode, 'endTime', Date.now());
this.core.setAttribute(this.activeNode, 'status',
(!this.pipelineError ? 'success' : 'failed'));
(this.pipelineError ? 'failed' : (this.canceled ? 'canceled' : 'success')));
this._finished = true;
this.resultMsg(msg);
this.save('Pipeline execution finished')
.then(() => {
this.result.setSuccess(!this.pipelineError);
@@ -323,7 +343,7 @@ define([
this.logger.info(`About to execute ${readyOps.length} operations`);
// If the pipeline has errored don't start any more jobs
if (this.pipelineError) {
if (this.pipelineError || this.canceled) {
if (this.runningJobs === 0) {
this.onPipelineComplete();
}
+8
Ver Arquivo
@@ -10,6 +10,14 @@
"disableServerSideExecution": false,
"disableBrowserSideExecution": true,
"configStructure": [
{
"name": "name",
"displayName": "Execution name",
"description": "Optional name for this execution instance",
"value": "",
"valueType": "string",
"readOnly": false
},
{
"name": "debug",
"displayName": "Debug Mode",
@@ -5,12 +5,14 @@ define([
'SimpleNodes/SimpleNodes',
'SimpleNodes/Constants',
'deepforge/layer-args',
'deepforge/utils',
'underscore',
'text!./metadata.json'
], function (
PluginBase,
Constants,
createLayerDict,
utils,
_,
metadata
) {
@@ -36,11 +38,15 @@ define([
GenerateArchitecture.prototype = Object.create(PluginBase.prototype);
GenerateArchitecture.prototype.constructor = GenerateArchitecture;
GenerateArchitecture.prototype.getTemplateSettings = function () {
return null;
};
GenerateArchitecture.prototype.main = function () {
this.addCustomLayersToMeta();
this.LayerDict = createLayerDict(this.core, this.META);
this.uniqueId = 2;
this._oldTemplateSettings = _.templateSettings;
this.varnames = {};
return PluginBase.prototype.main.apply(this, arguments);
};
@@ -54,25 +60,36 @@ define([
.forEach(node => this.META[this.core.getAttribute(node, 'name')] = node);
};
GenerateArchitecture.prototype.hoist = function (code) {
this.definitions.push(code);
};
GenerateArchitecture.prototype.createOutputFiles = function (tree) {
var layers = tree[Constants.CHILDREN],
//initialLayers,
result = {},
code = 'require \'nn\'\n';
code = '';
this.definitions = [
'require \'nn\'',
'require \'rnn\''
];
//initialLayers = layers.filter(layer => layer[Constants.PREV].length === 0);
// Add an index to each layer
layers.forEach((l, index) => l[INDEX] = index);
// Define custom layers
if (this.getCurrentConfig().standalone) {
this.logger.debug('Generating layer definitions');
code += this.genLayerDefinitions(layers);
}
this.logger.debug('Generating architecture code...');
code += this.genArchCode(layers);
this.logger.debug('Prepending hoisted code...');
code = this.definitions.join('\n') + '\n' + code;
result[tree.name + '.lua'] = code;
_.templateSettings = this._oldTemplateSettings; // FIXME: Fix this in SimpleNodes
this.logger.debug(`Finished generating ${tree.name}.lua`);
return result;
};
@@ -83,10 +100,38 @@ define([
].join('\n');
};
GenerateArchitecture.prototype.genRawArchCode = function (layers, name) {
var result = '';
if (layers.length > 1) {
return this.createSequential(layers[0], name).code;
} else if (name) {
result = `\nlocal ${name} = `;
}
result += this.createLayer(layers[0]);
return result;
};
GenerateArchitecture.prototype.getVarName = function (base) {
// Check "this.varnames"
var name = base,
i = 2;
while (this.varnames[name]) {
name = base + '_' + (i++);
}
this.varnames[name] = true;
return name;
};
GenerateArchitecture.prototype.createLayer = function (layer) {
var args = this.createArgString(layer);
return `nn.${layer.name}${args}`;
};
GenerateArchitecture.prototype.createSequential = function (layer, name) {
var next = layer[Constants.NEXT][0],
args,
template,
snippet,
snippets,
code = `\nlocal ${name} = nn.Sequential()`,
@@ -101,10 +146,8 @@ define([
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;
snippet = this.createLayer(layer);
code += `\n${name}:add(${snippet})`;
}
@@ -113,7 +156,7 @@ define([
this.logger.debug(`detected fork of size ${layer[Constants.NEXT].length}`);
snippets = layer[Constants.NEXT].map(nlayer =>
this.createSequential(nlayer, 'net_'+(this.uniqueId++)));
this.createSequential(nlayer, this.getVarName('net')));
code += '\n' + snippets.map(snippet => snippet.code).join('\n');
// Make sure all snippets end at the same concat node
@@ -151,7 +194,7 @@ define([
// merge the elements in the group
if (snippets.length) { // prepare next iteration
result = this.createSequential(next, 'net_'+(this.uniqueId++));
result = this.createSequential(next, this.getVarName('net'));
code += result.code;
group = [result];
this.logger.debug('updating group ('+ snippets.length+ ' left)');
@@ -171,6 +214,33 @@ define([
};
};
GenerateArchitecture.prototype.getValue = function (arg, layer) {
var content = layer[arg];
if (typeof content === 'object') { // layer as arg
if (content[Constants.CHILDREN].length) {
// Generate the code for the children of layer[arg]
var name = this.getVarName(utils.abbr(arg)),
layers;
this.logger.debug(`Adding layer arg for ${arg} (${layer.name})`);
try {
layers = this.genRawArchCode(layer[arg][Constants.CHILDREN], name);
} catch (e) {
this.logger.error(`Layer arg creation failed: ${e}`);
return null;
}
// hoist layer definitions to the top of the file
this.hoist(layers);
return name;
} else {
return null;
}
}
return content;
};
GenerateArchitecture.prototype.createArgString = function (layer) {
var setters = this.LayerDict[layer.name].setters,
setterNames = Object.keys(this.LayerDict[layer.name].setters),
@@ -179,8 +249,9 @@ define([
fn,
layerCode;
this.logger.debug(`Creating arg string for ${layer.name}`);
layerCode = '(' + this.LayerDict[layer.name].args
.map(arg => layer[arg.name])
.map(arg => this.getValue(arg.name, layer))
.filter(GenerateArchitecture.isSet)
.join(', ') + ')';
@@ -194,12 +265,13 @@ define([
fn = desc.setterFn[layer[setterNames[i]]];
layerCode += `:${fn}()`;
}
} else if (layer[setterNames[i]] !== null) {
} else if (layer[setterNames[i]] !== null && layer[setterNames[i]] !== undefined) {
fn = desc.setterFn;
layerCode += `:${fn}(${layer[setterNames[i]]})`;
}
}
this.logger.debug(`Created nn.${layer.name}${layerCode}`);
return layerCode;
};
+21 -9
Ver Arquivo
@@ -49,6 +49,8 @@ define([
return callback('Torch code not provided.', this.result);
}
this.addCustomLayersToMeta();
this.blobClient.getMetadata(srcHash)
.then(mdata => { // Create the new model
// If the current node is an architecture, assume we are just extending it
@@ -72,11 +74,10 @@ define([
this.loadNNMock();
// Cross compile to js and run
src = 'require \'nn\'\n' + src; // guarantee it loads nn
this.bin = this.context.loadString(src);
this.bin();
this.afterExecution();
return this.save('ImportTorch updated model.');
})
.then(() => { // changes saved successfully
@@ -91,6 +92,22 @@ define([
);
};
ImportTorch.prototype.addCustomLayersToMeta = function () {
// Add custom layers to the metamodel
var metanodes = this.core.getAllMetaNodes(this.rootNode),
name;
Object.keys(metanodes).map(id => metanodes[id])
.filter(node => this.core.isTypeOf(node, this.META.Layer))
.forEach(layer => {
name = this.core.getAttribute(layer, 'name');
if (!this.META[name]) {
this.logger.debug(`Adding ${name} to the meta`);
this.META[name] = layer;
}
});
};
// Create the 'nn' shim and add it to the global context
ImportTorch.prototype.loadNNMock = function () {
// This needs a refactor...
@@ -101,15 +118,10 @@ define([
this.context._G.get('package').set('searchers', [function(name) {
if (name === 'nn') {
return lib;
} else {
return () => {};
}
}]);
// Some scripts don't include `require 'nn'`. I may have to add the
// "nn" package to the global scope...
};
ImportTorch.prototype.afterExecution = function () {
// TODO
};
return ImportTorch;
+90 -15
Ver Arquivo
@@ -7,7 +7,7 @@ define([
], function(
createLayerDict,
assert,
luajs
lua
) {
'use strict';
@@ -19,7 +19,8 @@ define([
LayerDict = createLayerDict(core, META),
helpers = context.__helpers,
oldSet = helpers.__set,
isSetting = false;
isSetting = false,
connsFrom = {};
// Override the helper's '__set' method to detect
// if the code is in the middle of a "set".
@@ -29,24 +30,68 @@ define([
isSetting = false;
};
var stringify = function(table) {
var strings = table.array.map(val => {
if (val instanceof lua.types.LuaTable) {
return stringify(val);
} else {
return val;
}
});
return '{' + strings.join(', ') + '}';
};
var allConnectedTo = function(current) {
var connectedIds = {},
node,
id;
while (current.length) {
node = current.shift();
id = core.getGuid(node);
if (connectedIds[id]) {
continue;
}
connectedIds[id] = node;
if (connsFrom[id]) {
current = current.concat(connsFrom[id]);
}
}
// Return an array of all things connected to the
// given node
return Object.keys(connectedIds).map(key => connectedIds[key]);
};
var connect = function(src, dst) {
var conn = core.createNode({
var conn,
id;
conn = core.createNode({
parent: parent,
base: META.Connection
});
core.setPointer(conn, 'src', src);
core.setPointer(conn, 'dst', dst);
// Record this
id = core.getGuid(src);
if (!connsFrom[id]) {
connsFrom[id] = [];
}
connsFrom[id].push(conn, dst);
};
// nn drawing library
var Layer = function(base, attrs, args) {
this._base = base;
this._attrs = attrs;
for (var i = 0; i < attrs.length; i++) {
this[attrs[i].name] = args[i];
}
// inputs/outputs used for being added to containers
this._values = args;
this._cachedNode = null;
this._inputs = [this._node()];
this._outputs = [this._node()];
@@ -55,6 +100,10 @@ define([
Layer.prototype._node = function() {
var name,
node,
nodes,
cntr,
layer,
cntrName,
value;
if (this._cachedNode) {
@@ -70,16 +119,42 @@ define([
for (var i = this._attrs.length; i--;) {
name = this._attrs[i].name;
value = this[name];
if ((typeof value) === 'object') {
// special lua.js object
value = value.valueOf();
}
value = this._values[i];
// TODO: Update this to check if inferred and the value matches
// our inferred value. If so, skip it
if (value !== undefined/*&& !this._attrs[i].infer*/) {
core.setAttribute(node, name, value);
if (value instanceof lua.types.LuaTable) {
layer = value.get('_node');
if (layer) { // layer arg!
// add all the inputs, outputs (and connected elements) to
// be in an "Architecture" node in the current node
cntr = core.createNode({
base: META.Architecture,
parent: node
});
cntrName = `${name} (${this._base})`;
logger.debug(`Naming layer arg ${cntrName}`);
core.setAttribute(cntr, 'name', cntrName);
// Move all connecting elements of the value to
// the cntr
nodes = allConnectedTo(layer._inputs.concat(layer._outputs));
for (var j = nodes.length; j--;) {
core.moveNode(nodes[j], cntr);
}
core.setPointer(node, name, cntr);
logger.debug(`Moving ${nodes.length} to ${name}(${this._base})`);
} else { // Something like {1, 2, 3}
value = stringify(value);
logger.debug(`Setting ${name} to ${value} (${this._base})`);
core.setAttribute(node, name, value);
}
} else { // attribute value
if ((typeof value) === 'object') {
// special lua.js object
value = value.valueOf();
}
if (value !== undefined) {
logger.debug(`Setting ${name} to ${value} (${this._base})`);
core.setAttribute(node, name, value);
}
}
}
@@ -197,9 +272,9 @@ define([
};
var CreateLayer = function(type) {
var res = luajs.newContext()._G,
var res = lua.newContext()._G,
attrs = [].slice.call(arguments, 1),
ltGet = luajs.types.LuaTable.prototype.get,
ltGet = lua.types.LuaTable.prototype.get,
setters = [],
args = [],
node;
@@ -253,7 +328,7 @@ define([
}
// TODO: Create the nn object
var nn = luajs.newContext()._G,
var nn = lua.newContext()._G,
names = Object.keys(LayerDict);
for (var i = names.length; i--;) {
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.
+6
Ver Arquivo
@@ -94,5 +94,11 @@
"title": "ImageViewer",
"panel": "panels/ImageViewer/ImageViewerPanel",
"DEBUG_ONLY": false
},
{
"id": "ExecutionIndex",
"title": "ExecutionIndex",
"panel": "panels/ExecutionIndex/ExecutionIndexPanel",
"DEBUG_ONLY": false
}
]
@@ -2,12 +2,14 @@
/*jshint browser: true*/
define([
'deepforge/Constants',
'deepforge/globals',
'panels/EasyDAG/EasyDAGControl',
'js/NodePropertyNames',
'js/Utils/ComponentSettings',
'underscore'
], function (
Constants,
DeepForge,
EasyDAGControl,
nodePropertyNames,
@@ -38,6 +40,7 @@ define([
_.extend(ArchEditorControl.prototype, EasyDAGControl.prototype);
ArchEditorControl.prototype.TERRITORY_RULE = {children: 1};
ArchEditorControl.prototype.DEFAULT_DECORATOR = 'LayerDecorator';
ArchEditorControl.prototype.getComponentId = function() {
return 'ArchEditor';
};
@@ -59,13 +62,24 @@ define([
if (!desc.isConnection) {
var allAttrs = desc.attributes,
names = Object.keys(allAttrs),
schema;
ctorInfo = desc.attributes[Constants.CTOR_ARGS_ATTR],
ctorAttrs = ctorInfo ? ctorInfo.value.split(','): [],
schema,
i;
desc.attributes = {};
for (var i = names.length; i--;) {
// add ctor attributes
for (i = 0; i < ctorAttrs.length; i++) {
if (allAttrs[ctorAttrs[i]]) { // (not a ref to a layer)
desc.attributes[ctorAttrs[i]] = allAttrs[ctorAttrs[i]];
}
}
for (i = names.length; i--;) {
// check if it is a setter
schema = this._client.getAttributeSchema(id, names[i]);
if (names[i] === 'name' || schema.hasOwnProperty('argindex') ||
schema.setterType) {
if (names[i] === 'name' || schema.setterType) {
desc.attributes[names[i]] = allAttrs[names[i]];
}
}
@@ -164,7 +178,7 @@ define([
ArchEditorControl.prototype.getCreateNewDecorator = function() {
return this._client.decoratorManager.getDecoratorForWidget(
'EllipseDecorator',
'LayerDecorator',
'EasyDAG'
);
};
@@ -0,0 +1,377 @@
/*globals define, WebGMEGlobal*/
/*jshint browser: true*/
define([
'js/Constants',
'deepforge/utils'
], function (
CONSTANTS,
utils
) {
'use strict';
var ExecutionIndexControl;
ExecutionIndexControl = function (options) {
this._logger = options.logger.fork('Control');
this._client = options.client;
this._embedded = options.embedded;
// Initialize core collections and variables
this._widget = options.widget;
this._currentNodeId = null;
this.displayedExecutions = {};
this._linesForExecution = {};
this._lineToExec = {};
this._pipelineNames = {};
this.abbrToId = {};
this.abbrFor = {};
this._initWidgetEventHandlers();
this._logger.debug('ctor finished');
};
ExecutionIndexControl.prototype._initWidgetEventHandlers = function () {
this._widget.setExecutionDisplayed = this.setExecutionDisplayed.bind(this);
};
ExecutionIndexControl.prototype.setExecutionDisplayed = function (id, bool) {
var lines = this._linesForExecution[id] || [],
otherLines,
wasMultiLine = this.displayedExecCount() > 1,
isMultiLine;
this._logger.info(`setting execution ${id} to ${bool ? 'displayed' : 'hidden'}`);
this.displayedExecutions[id] = bool;
// If we just crossed the multi line threshold, then update all the lines
isMultiLine = this.displayedExecCount() > 1;
if (isMultiLine !== wasMultiLine) {
// Refresh the other lines visible
otherLines = Object.keys(this.displayedExecutions)
.filter(eId => this.displayedExecutions[eId] && (eId !== id))
.map(id => this._linesForExecution[id])
.reduce((l1, l2) => l1.concat(l2), []);
this._updateLines(otherLines, false);
this._updateLines(otherLines, true);
}
this._updateLines(lines, bool);
};
ExecutionIndexControl.prototype._updateLines = function (lines, added) {
var action = added ? 'addNode' : 'removeNode';
// If removing, just get the ids
lines = !added ? lines : lines.map(line => this._getObjectDescriptor(line));
// update the given lines
for (var i = lines.length; i--;) {
this._widget[action](lines[i]);
}
};
ExecutionIndexControl.prototype.clearTerritory = function () {
if (this._territoryId) {
this._client.removeUI(this._territoryId);
this._territoryId = null;
}
};
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
ExecutionIndexControl.prototype.selectedObjectChanged = function (nodeId) {
var self = this;
self._logger.debug('activeObject nodeId \'' + nodeId + '\'');
// Remove current territory patterns
self.clearTerritory();
self._currentNodeId = nodeId;
if (typeof self._currentNodeId === 'string') {
// Create a territory for the executions
self._selfPatterns = {};
self._territoryId = self._client.addUI(self, function (events) {
self._eventCallback(events);
});
// Update the territory
self._selfPatterns[nodeId] = {children: 4};
self._client.updateTerritory(self._territoryId, self._selfPatterns);
}
};
ExecutionIndexControl.prototype.getUniqAbbreviation = function(desc) {
// Get a unique abbreviation for the given execution
var base = utils.abbr(desc.name).toLowerCase(),
abbr = base,
oldAbbr = this.abbrFor[desc.id],
i = 2;
// Make sure it is unique!
while (this.abbrToId[abbr] && this.abbrToId[abbr] !== desc.id) {
abbr = base + i;
i++;
}
if (oldAbbr !== undefined) { // updating abbr
delete this.abbrToId[oldAbbr];
}
this.abbrToId[abbr] = desc.id;
this.abbrFor[desc.id] = abbr;
return abbr;
};
// This next function retrieves the relevant node information for the widget
ExecutionIndexControl.prototype._getObjectDescriptor = function (nodeId) {
var node = this._client.getNode(nodeId),
childIds,
desc,
base,
type;
if (node) {
base = this._client.getNode(node.getBaseId());
type = base.getAttribute('name');
desc = {
id: node.getId(),
type: type,
name: node.getAttribute('name')
};
if (type === 'Execution') {
desc.status = node.getAttribute('status');
desc.originTime = node.getAttribute('createdAt');
desc.originId = node.getPointer('origin').to;
desc.pipelineName = this._pipelineNames[desc.originId];
desc.startTime = node.getAttribute('startTime');
desc.endTime = node.getAttribute('endTime');
this._logger.debug(`Looking up pipeline name for ${desc.name}: ${desc.pipelineName}`);
// Add the (unique) abbreviation of the execution!
desc.abbr = this.getUniqAbbreviation(desc);
// Create a territory for this origin and update it!
this._selfPatterns[desc.originId] = {children: 0};
setTimeout(() => this._client.updateTerritory(this._territoryId, this._selfPatterns), 0);
} else if (type === 'Line') {
desc = this.getLineDesc(node);
} else if (type === 'Pipeline') {
desc.execs = node.getMemberIds('executions');
this._pipelineNames[desc.id] = desc.name;
} else if (type === 'Graph') {
childIds = node.getChildrenIds();
desc.lines = childIds.map(id => {
var n = this._client.getNode(id);
return this.getLineDesc(n);
});
}
}
return desc;
};
ExecutionIndexControl.prototype.getLineDesc = function (node) {
var id = node.getId(),
graphId = node.getParentId(),
jobId = this._client.getNode(graphId).getParentId(),
execId = this._client.getNode(jobId).getParentId(),
points,
desc;
points = node.getAttribute('points').split(';')
.filter(data => !!data) // remove any ''
.map(pair => {
var nums = pair.split(',').map(num => parseFloat(num));
return {
x: nums[0],
y: nums[1]
};
});
desc = {
id: id,
execId: execId,
lineName: node.getAttribute('name'),
name: node.getAttribute('name'),
type: 'line',
points: points
};
if (!this._lineToExec[id]) {
// Update records
if (!this._linesForExecution[execId]) {
this._linesForExecution[execId] = [];
}
this._linesForExecution[execId].push(id);
this._lineToExec[id] = execId;
}
// If there are multiple executions, add the exec's abbr
var displayedCnt = this.displayedExecCount(),
execAbbr;
if (displayedCnt > 1) {
execAbbr = this.abbrFor[execId] || this._getObjectDescriptor(execId).abbr;
desc.name = `${desc.name} (${execAbbr})`;
}
return desc;
};
/* * * * * * * * Node Event Handling * * * * * * * */
ExecutionIndexControl.prototype._eventCallback = function (events) {
var event;
events = events.filter(event => event.eid !== this._currentNodeId);
this._logger.debug('received \'' + events.length + '\' events');
for (var i = events.length; i--;) {
event = events[i];
switch (event.etype) {
case CONSTANTS.TERRITORY_EVENT_LOAD:
this._onLoad(event.eid);
break;
case CONSTANTS.TERRITORY_EVENT_UPDATE:
this._onUpdate(event.eid);
break;
case CONSTANTS.TERRITORY_EVENT_UNLOAD:
this._onUnload(event.eid);
break;
default:
break;
}
}
this._logger.debug('finished processing events!');
};
ExecutionIndexControl.prototype._onLoad = function (gmeId) {
var desc = this._getObjectDescriptor(gmeId);
this._logger.debug(`Loading node of type ${desc.type}`);
if (desc.type === 'Execution') {
this._logger.debug('Adding node to widget...');
this._logger.debug('desc:', desc);
this._widget.addNode(desc);
} else if (desc.type === 'line' && this.isLineDisplayed(desc)) {
this._widget.addNode(desc);
} else if (desc.type === 'Pipeline') {
this.updatePipelineNames(desc);
}
};
ExecutionIndexControl.prototype._onUpdate = function (gmeId) {
var desc = this._getObjectDescriptor(gmeId);
if (desc.type === 'Execution') {
this._widget.updateNode(desc);
} else if (desc.type === 'line' && this.isLineDisplayed(desc)) {
this._widget.updateNode(desc);
} else if (desc.type === 'Pipeline') {
this.updatePipelineNames(desc);
}
};
ExecutionIndexControl.prototype.updatePipelineNames = function (desc) {
// Get all associated executions and update their pipeline name
this._logger.debug('updating pipeline name for ' + desc.execs.join(', '));
for (var i = desc.execs.length; i--;) {
this._widget.updatePipelineName(desc.execs[i], desc.name);
}
if (desc.execs.length === 0) {
// Executions have been deleted - no longer relevant
this._logger.debug('pipeline has 0 executions... removing it', desc.id);
delete this._selfPatterns[desc.id];
delete this._pipelineNames[desc.id];
}
};
ExecutionIndexControl.prototype._onUnload = function (id) {
var execId = this._lineToExec[id],
abbr;
if (execId) { // it is a line
delete this._lineToExec[id];
for (var k = this._linesForExecution[execId].length; k--;) {
if (this._linesForExecution[execId][k] === id) {
this._linesForExecution[execId].splice(k, 1);
break;
}
}
}
if (this.abbrFor[id]) {
abbr = this.abbrFor[id];
delete this.abbrFor[id];
delete this.abbrToId[abbr];
}
this._widget.removeNode(id);
};
ExecutionIndexControl.prototype.isLineDisplayed = function (line) {
// lines are only displayed if their execution is checked
return this.displayedExecutions[line.execId];
};
ExecutionIndexControl.prototype.displayedExecCount = function () {
return Object.keys(this.displayedExecutions)
.map(id => this.displayedExecutions[id])
.filter(shown => shown).length;
};
ExecutionIndexControl.prototype._stateActiveObjectChanged = function (model, activeObjectId) {
if (this._currentNodeId === activeObjectId) {
// The same node selected as before - do not trigger
} else {
this.selectedObjectChanged(activeObjectId);
}
};
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
ExecutionIndexControl.prototype.destroy = function () {
this._detachClientEventListeners();
this.clearTerritory();
};
ExecutionIndexControl.prototype._attachClientEventListeners = function () {
this._detachClientEventListeners();
if (!this._embedded) {
WebGMEGlobal.State.on('change:' + CONSTANTS.STATE_ACTIVE_OBJECT,
this._stateActiveObjectChanged, this);
}
};
ExecutionIndexControl.prototype._detachClientEventListeners = function () {
if (!this._embedded) {
WebGMEGlobal.State.off('change:' + CONSTANTS.STATE_ACTIVE_OBJECT,
this._stateActiveObjectChanged);
}
};
ExecutionIndexControl.prototype.onActivate = function () {
this._attachClientEventListeners();
if (typeof this._currentNodeId === 'string') {
WebGMEGlobal.State.registerSuppressVisualizerFromNode(true);
WebGMEGlobal.State.registerActiveObject(this._currentNodeId);
WebGMEGlobal.State.registerSuppressVisualizerFromNode(false);
}
};
ExecutionIndexControl.prototype.onDeactivate = function () {
this._detachClientEventListeners();
};
return ExecutionIndexControl;
});
@@ -0,0 +1,93 @@
/*globals define, _, WebGMEGlobal*/
/*jshint browser: true*/
define([
'js/PanelBase/PanelBase',
'js/PanelManager/IActivePanel',
'widgets/ExecutionIndex/ExecutionIndexWidget',
'./ExecutionIndexControl'
], function (
PanelBase,
IActivePanel,
ExecutionIndexWidget,
ExecutionIndexControl
) {
'use strict';
var ExecutionIndexPanel;
ExecutionIndexPanel = function (layoutManager, params) {
var options = {};
//set properties from options
options[PanelBase.OPTIONS.LOGGER_INSTANCE_NAME] = 'ExecutionIndexPanel';
options[PanelBase.OPTIONS.FLOATING_TITLE] = true;
//call parent's constructor
PanelBase.apply(this, [options, layoutManager]);
this._client = params.client;
this._embedded = params.embedded;
//initialize UI
this._initialize();
this.logger.debug('ctor finished');
};
//inherit from PanelBase
_.extend(ExecutionIndexPanel.prototype, PanelBase.prototype);
_.extend(ExecutionIndexPanel.prototype, IActivePanel.prototype);
ExecutionIndexPanel.prototype._initialize = function () {
//set Widget title
this.widget = new ExecutionIndexWidget(this.logger, this.$el);
this.control = new ExecutionIndexControl({
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 */
ExecutionIndexPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
//apply parent's onReadOnlyChanged
PanelBase.prototype.onReadOnlyChanged.call(this, isReadOnly);
};
ExecutionIndexPanel.prototype.onResize = function (width, height) {
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
this.widget.onWidgetContainerResize(width, height);
};
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
ExecutionIndexPanel.prototype.destroy = function () {
this.control.destroy();
this.widget.destroy();
PanelBase.prototype.destroy.call(this);
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
};
ExecutionIndexPanel.prototype.onActivate = function () {
this.widget.onActivate();
this.control.onActivate();
WebGMEGlobal.KeyboardManager.setListener(this.widget);
WebGMEGlobal.Toolbar.refresh();
};
ExecutionIndexPanel.prototype.onDeactivate = function () {
this.widget.onDeactivate();
this.control.onDeactivate();
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
};
return ExecutionIndexPanel;
});
@@ -1,15 +1,14 @@
/*globals define, WebGMEGlobal */
/*jshint browser: true*/
/**
* Generated by VisualizerGenerator 1.7.0 from webgme on Tue May 24 2016 10:15:19 GMT-0500 (CDT).
*/
define([
'js/Constants',
'deepforge/Constants',
'panels/EasyDAG/EasyDAGControl',
'deepforge/viz/PipelineControl',
'underscore'
], function (
GME_CONSTANTS,
CONSTANTS,
EasyDAGControl,
PipelineControl,
@@ -62,7 +61,7 @@ define([
return;
}
if (event.etype === CONSTANTS.TERRITORY_EVENT_UNLOAD) {
if (event.etype === GME_CONSTANTS.TERRITORY_EVENT_UNLOAD) {
this.originId = null;
this._widget.onOriginDeleted();
} else {
@@ -90,6 +89,65 @@ define([
};
};
ExecutionViewControl.prototype._getObjectDescriptor = function(id) {
var desc = PipelineControl.prototype._getObjectDescriptor.call(this, id),
childrenIds,
node,
opId;
// If it is a job, add the operation attributes
if (this.hasMetaName(id, 'Job')) {
node = this._client.getNode(id);
childrenIds = node.getChildrenIds();
opId = childrenIds.find(id => this.hasMetaName(id, 'Operation'));
desc.opAttributes = {};
if (opId) {
var opNode = this._client.getNode(opId),
attrs,
allAttrs = {},
hiddenAttrs = [
CONSTANTS.LINE_OFFSET,
'code',
'name'
],
i;
opNode.getValidAttributeNames().concat(opNode.getAttributeNames())
.forEach(attr => allAttrs[attr] = true);
// Remove skip values
hiddenAttrs.forEach(attr => delete allAttrs[attr]);
attrs = Object.keys(allAttrs);
for (i = attrs.length; i--;) {
desc.opAttributes[attrs[i]] = {
name: attrs[i],
value: opNode.getAttribute(attrs[i]),
type: 'string'
};
}
// Pointers
var allPtrs = {},
ptrs;
opNode.getValidPointerNames().concat(opNode.getPointerNames())
.filter(ptr => ptr !== 'base')
.forEach(ptr => allPtrs[ptr] = true);
ptrs = Object.keys(allPtrs);
for (i = ptrs.length; i--;) {
desc.pointers[ptrs[i]] = opNode.getPointer(ptrs[i]).to;
}
} else {
this.logger.error(`Job "${desc.name}" (${id}) is missing an operation!`);
}
}
return desc;
};
ExecutionViewControl.prototype._onLoad = function(id) {
var desc = this._getObjectDescriptor(id);
@@ -1,13 +1,16 @@
/*globals DeepForge, define, $, Materialize, WebGMEGlobal*/
/*globals define, $, WebGMEGlobal*/
// These are actions defined for specific meta types. They are evaluated from
// the context of the ForgeActionButton
define([
'panel/FloatingActionButton/styles/Materialize',
'q',
'js/RegistryKeys',
'deepforge/globals'
], function(
Materialize,
Q,
REGISTRY_KEYS
REGISTRY_KEYS,
DeepForge
) {
var FILE_UPLOAD_INPUT = $('<input type="file" />');
@@ -103,6 +106,7 @@ define([
name: `Return to ${fromType}`,
icon: 'input',
priority: 2,
color: 'teal',
filter: () => {
return DeepForge.last[fromType];
},
@@ -112,6 +116,7 @@ define([
name: `Delete ${type} Definition`,
icon: 'delete',
priority: 1,
color: 'red',
action: function() {
// Delete and go to the last pipeline?
var node = this.client.getNode(this._currentNodeId),
@@ -134,13 +139,19 @@ define([
}
];
var makeRestartButton = function(name, pluginId) {
var makeRestartButton = function(name, pluginId, hotkeys) {
return {
name: 'Restart ' + name,
icon: 'replay',
priority: 1000,
color: 'red',
hotkey: hotkeys && 'shift enter',
filter: function() {
// Only show if stopped!
return !this.isRunning();
},
action: function(event) {
this.runExecutionPlugin(pluginId, event.shiftKey);
this.runExecutionPlugin(pluginId, {useSecondary: event.shiftKey});
}
};
};
@@ -215,9 +226,47 @@ define([
icon: 'play_for_work',
priority: 1,
href: download.execFiles
},
// Stop execution button
{
name: 'Stop Current Job',
icon: 'stop',
priority: 1001,
filter: function() {
return this.isRunning();
},
action: function() {
this.stopJob();
}
}
],
Execution: [
makeRestartButton('Execution', 'ExecutePipeline', true),
// Stop execution button
{
name: 'Stop Running Execution',
icon: 'stop',
priority: 1001,
hotkey: 'shift enter',
filter: function() {
return this.isRunning();
},
action: function() {
// Stop every running job
var execNode = this.client.getNode(this._currentNodeId),
jobIds = execNode.getChildrenIds(),
msg = `Canceling ${execNode.getAttribute('name')} execution`;
this.client.startTransaction(msg);
jobIds.map(id => this.client.getNode(id))
.filter(job => this.isRunning(job)) // get running jobs
.forEach(job => this.stopJob(job)); // stop them
this.client.setAttributes(execNode.getId(), 'status', 'canceled');
this.client.completeTransaction();
}
}
],
Execution: [makeRestartButton('Execution', 'ExecutePipeline')],
Pipeline: [
{
name: 'Create new node',
@@ -1,4 +1,4 @@
/*globals DeepForge, $, Materialize, define, _ */
/*globals $, window, define, _ */
/*jshint browser: true*/
define([
@@ -7,6 +7,7 @@ define([
'panel/FloatingActionButton/FloatingActionButton',
'deepforge/viz/PipelineControl',
'deepforge/viz/NodePrompter',
'deepforge/viz/Execute',
'./Actions',
'widgets/EasyDAG/AddNodeDialog',
'js/RegistryKeys',
@@ -20,12 +21,14 @@ define([
PluginButton,
PipelineControl,
NodePrompter,
Execute,
ACTIONS,
AddNodeDialog,
REGISTRY_KEYS,
META_CONSTANTS,
Q,
PluginConfig
PluginConfig,
DeepForge
) {
'use strict';
@@ -39,6 +42,8 @@ define([
logger: this.logger.fork('BlobClient')
});
Execute.call(this, this.client, this.logger);
this.initializeKeyListener();
this.logger.debug('ctor finished');
};
@@ -46,9 +51,46 @@ define([
_.extend(
ForgeActionButton.prototype,
PluginButton.prototype,
Execute.prototype,
PipelineControl.prototype
);
ForgeActionButton.prototype.initializeKeyListener = function() {
// add key listener to parent?
this.oldOnKeyDown = document.body.onkeydown;
document.onkeydown = event => {
var keys = String.fromCharCode(event.which) || '',
names = Object.keys(this.buttons),
btn,
name;
// Simple button detection
if (event.which === 13) {
keys = 'enter';
}
if (event.shiftKey) {
keys = 'shift ' + keys;
}
for (var i = names.length; i--;) {
name = names[i];
btn = this.buttons[name];
if (btn.hotkey && btn.hotkey === keys) {
btn.action.call(this, event);
}
}
if (this.oldOnKeyDown) {
this.oldOnKeyDown(event);
}
};
};
ForgeActionButton.prototype.destroy = function() {
PluginButton.prototype.destroy.call(this);
PipelineControl.prototype.destroy.call(this);
document.body.onclick = this.oldOnKeyDown;
};
ForgeActionButton.prototype.findActionsFor = function(nodeId) {
var node = this.client.getNode(nodeId),
base = this.client.getNode(node.getMetaTypeId()),
@@ -60,7 +102,7 @@ define([
if (!base) { // must be ROOT or FCO
basename = node.getAttribute('name') || 'ROOT_NODE';
actions = (ACTIONS[basename] || [])
.filter(action => !action.filter || action.filter());
.filter(action => !action.filter || action.filter.call(this));
return actions;
}
@@ -69,7 +111,7 @@ define([
base = this.client.getNode(base.getBaseId());
actions = ACTIONS[basename];
if (actions) {
actions = actions.filter(action => !action.filter || action.filter());
actions = actions.filter(action => !action.filter || action.filter.call(this));
}
}
@@ -321,21 +363,5 @@ define([
}
};
ForgeActionButton.prototype.runExecutionPlugin = function(pluginId, useSecondary) {
var context = this.client.getCurrentPluginContext(pluginId),
name = this.client.getNode(this._currentNodeId).getAttribute('name'),
method;
context.managerConfig.namespace = 'pipeline';
method = useSecondary ? 'runBrowserPlugin' : 'runServerPlugin';
this.client[method](pluginId, context, err => {
if (err) {
return Materialize.toast(`${name} failed!`, 4000);
}
Materialize.toast(`${name} executed successfully!`, 2000);
});
};
return ForgeActionButton;
});
@@ -1,10 +1,13 @@
{
"GenerateArchitecture": {
"icon": "description",
"hotkey": "shift enter",
"priority": -1
},
"ExecutePipeline": {
"icon": "play_arrow",
"hotkey": "shift enter",
"color": "green",
"priority": 1
},
"ImportTorch": {
@@ -68,6 +68,9 @@ define([
// The OperationCodeEditor should receive the
if (!this.readOnly) {
// Pass a reference to the panel
this._panels[0].control.currentJobId = nodeId;
// Get the operation base node id and pass it to OpCodeEditor selObjChanged
if (this._territoryId) {
this._client.removeUI(this._territoryId);
@@ -2,9 +2,15 @@
/*jshint browser: true*/
define([
'panels/TextEditor/TextEditorControl'
'panels/TextEditor/TextEditorControl',
'deepforge/LayerParser',
'deepforge/utils',
'deepforge/Constants'
], function (
TextEditorControl
TextEditorControl,
LayerParser,
utils,
Constants
) {
'use strict';
@@ -50,62 +56,120 @@ define([
};
LayerEditorControl.prototype.saveTextFor = function (id, text) {
var r = /:__init\((.*)\)/,
match = text.match(r),
textMatch = match && match[1],
node = this._client.getNode(id),
var node = this._client.getNode(id),
currentAttrs = node.getValidAttributeNames(),
attributes = [],
msg = `Updating layer definition for ${node.getAttribute('name')}`;
types,
ctorAttrs = [],
setterNames,
schema,
currentPtrs = {base: true},
type,
ptr,
msg = `Updating layer definition for ${node.getAttribute('name')}`,
i;
// 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!
// Parse the ctorAttrs and update the node!
var layerSchema = LayerParser.parse(text);
if (!layerSchema) {
return TextEditorControl.prototype.saveTextFor.call(this, id, text);
}
if (layerSchema.params) {
ctorAttrs = layerSchema.params;
} else { // inheriting __init
attributes = this.getInheritedAttrs(text);
ctorAttrs = this.getInheritedAttrs(layerSchema);
}
this._client.startTransaction(msg);
TextEditorControl.prototype.saveTextFor.call(this, id, text);
this._client.setAttributes(id, 'name', layerSchema.name);
this._logger.debug(`Setting ctor args to ${ctorAttrs.join(',')}`);
this._client.setAttributes(id, Constants.CTOR_ARGS_ATTR, ctorAttrs.join(','));
types = layerSchema.types || {};
schema = this.getPointerMeta();
// Handle pointer types
for (i = ctorAttrs.length; i--;) {
type = types[ctorAttrs[i]];
if (type && type.substring(0, 3) === 'nn.') {
ptr = ctorAttrs.splice(i, 1)[0];
this._client.setPointerMeta(id, ptr, schema);
currentPtrs[ptr] = true;
}
}
// Remove old pointers
node.getPointerNames().filter(ptr => !currentPtrs[ptr])
.forEach(ptr => this._client.deleteMetaPointer(id, ptr));
// Remove old attributes
_.difference(currentAttrs, attributes)
setterNames = Object.keys(layerSchema.setters);
_.difference(currentAttrs, ctorAttrs, setterNames)
.forEach(attr => this._client.removeAttributeSchema(id, attr));
attributes.forEach((attr, i) =>
this._client.setAttributeSchema(id, attr, {type: 'string', argindex: i}));
// Add setters
for (i = setterNames.length; i--;) {
schema = utils.getSetterSchema(setterNames[i], layerSchema.setters, layerSchema.defaults);
// Get setter attr schema
if (schema.hasOwnProperty('default')) {
this._client.setAttributes(id, setterNames[i], schema.default);
delete schema.default;
}
if (types[setterNames[i]]) {
schema.type = types[setterNames[i]];
}
this._client.setAttributeSchema(id, setterNames[i], schema);
}
ctorAttrs.forEach(attr =>
this._client.setAttributeSchema(id, attr, {
type: types[attr] || 'string'
})
);
this._client.completeTransaction();
};
LayerEditorControl.prototype.getInheritedAttrs = function (code) {
LayerEditorControl.prototype.getPointerMeta = function () {
var archNode = this._client.getAllMetaNodes()
.find(node => node.getAttribute('name') === 'Architecture');
if (!archNode) {
throw 'Could not find the "Architecture" node!';
}
return {
min: 1,
max: 1,
items: [
{
id: archNode.getId(),
max: 1
}
]
};
};
LayerEditorControl.prototype.getInheritedAttrs = function (layerSchema) {
// Get the base class
var r = /torch.class\((.*)\)/,
match = code.match(r),
baseType,
metanode,
textMatch = match && match[1];
var metanode;
if (textMatch) {
baseType = textMatch.split(',')[1]
.replace(/^\s*['"]nn\./, '')
.replace(/['"]\s*$/, '');
this._logger.debug(`inheriting the attributes from ${baseType}`);
if (layerSchema.baseType) {
this._logger.debug(`inheriting the attributes from ${layerSchema.baseType}`);
// Get the meta node and valid attribute names
metanode = this._client.getAllMetaNodes()
.find(node => node.getAttribute('name') === baseType);
.find(node => node.getAttribute('name') === layerSchema.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 []`);
this._logger.warn(`Unknown base type ${layerSchema.baseType}. Assuming attributes are []`);
}
}
return [];
@@ -83,17 +83,20 @@ define([
// Check if it is a line
if (desc.id !== this._currentNodeId) {
var points = (node.getAttribute('points') || '').split(';')
.map(pair => {
var nums = pair.split(','),
x = parseFloat(nums[0]),
y = parseFloat(nums[1]);
var rawPoints = node.getAttribute('points') || '',
points = rawPoints.split(';')
.filter(data => !!data) // remove any ''
.map(pair => {
var nums = pair.split(','),
x = parseFloat(nums[0]),
y = parseFloat(nums[1]);
return {
x: x,
y:y
};
});
return {
x: x,
y:y
};
});
desc.type = 'line';
desc.points = points;
}
@@ -65,6 +65,8 @@ define([
return null;
}
};
this._widget.toggleEmbeddedPanel = () => this.toggleEmbeddedPanel();
};
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
@@ -92,9 +94,11 @@ define([
// Update the territory
this.territory[type] = {};
this.territory[type][DeepForge.places[dirname]] = {children: 1};
this.ui[type] = this._client.addUI(this, this.handleEvents.bind(this, type));
this._client.updateTerritory(this.ui[type], this.territory[type]);
DeepForge.places[dirname]().then(id => {
this.territory[type][id] = {children: 1};
this.ui[type] = this._client.addUI(this, this.handleEvents.bind(this, type));
this._client.updateTerritory(this.ui[type], this.territory[type]);
});
});
}
};
+49 -10
Ver Arquivo
@@ -9,6 +9,7 @@ define([
'widgets/MainView/MainViewWidget',
'./MainViewControl',
'panels/PipelineIndex/PipelineIndexPanel',
'panels/ExecutionIndex/ExecutionIndexPanel',
'deepforge/globals'
], function (
PanelBaseWithHeader,
@@ -16,6 +17,7 @@ define([
MainViewWidget,
MainViewControl,
PipelineIndexPanel,
ExecutionIndexPanel,
DeepForge
) {
'use strict';
@@ -38,12 +40,14 @@ define([
this.$nav = $('<div>', {id: 'nav-container'});
this.$el.css({padding: 0});
this.embeddedPanel = new PipelineIndexPanel(layoutManager, params);
this.$embedded = this.embeddedPanel.$el;
this.$embedded.addClass('embedded');
this.$el.append(this.$nav, this.$embedded);
this.embeddedPanels = [
PipelineIndexPanel,
ExecutionIndexPanel
];
this.nextPanelIndex = 0;
this._lm = layoutManager;
this._params = params;
this.$el.append(this.$nav);
this._initialize();
this.logger.debug('ctor finished');
@@ -66,15 +70,48 @@ define([
widget: this.widget
});
var controlObjectChanged = this.control.selectedObjectChanged;
this.control.selectedObjectChanged = nodeId => {
this.embeddedPanel.control.selectedObjectChanged(DeepForge.places.MyPipelines);
return controlObjectChanged.call(this.control, nodeId);
this.control.toggleEmbeddedPanel = this.toggleEmbeddedPanel.bind(this);
var selectedObjectChanged = this.control.selectedObjectChanged;
this.control.selectedObjectChanged = id => {
this.getEmbeddedNode().then(nodeId =>
this.embeddedPanel.control.selectedObjectChanged(nodeId));
selectedObjectChanged.call(this.control, id);
};
this.toggleEmbeddedPanel(true);
this.onActivate();
};
MainViewPanel.prototype.getEmbeddedNode = function() {
if (this.nextPanelIndex === 1) {
return DeepForge.places.MyPipelines();
} else {
return DeepForge.places.MyExecutions();
}
};
MainViewPanel.prototype.toggleEmbeddedPanel = function (silent) {
var Panel = this.embeddedPanels[this.nextPanelIndex];
this.nextPanelIndex = (this.nextPanelIndex + 1) % this.embeddedPanels.length;
if (this.embeddedPanel) { // Remove current
this.embeddedPanel.destroy();
this.$embedded.remove();
}
this.embeddedPanel = new Panel(this._lm, this._params);
this.$embedded = this.embeddedPanel.$el;
this.$embedded.addClass('main-view-embedded');
this.$el.append(this.$embedded);
// Call on Resize and selectedObjectChanged
this.onResize(this.width, this.height);
if (!silent) {
this.getEmbeddedNode().then(nodeId =>
this.embeddedPanel.control.selectedObjectChanged(nodeId));
}
};
/* OVERRIDE FROM WIDGET-WITH-HEADER */
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
MainViewPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
@@ -98,6 +135,8 @@ define([
margin: 'inherit'
});
this.embeddedPanel.onResize(embeddedWidth, height);
this.width = width;
this.height = height;
};
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
@@ -4,11 +4,13 @@
define([
'panels/TextEditor/TextEditorControl',
'deepforge/viz/OperationControl',
'deepforge/viz/Execute',
'deepforge/Constants',
'underscore'
], function (
TextEditorControl,
OperationControl,
Execute,
CONSTANTS,
_
) {
@@ -20,17 +22,21 @@ define([
OperationCodeEditorControl = function (options) {
options.attributeName = 'code';
TextEditorControl.call(this, options);
Execute.call(this, this._client, this._logger);
this.currentJobId = null;
};
_.extend(
OperationCodeEditorControl.prototype,
OperationControl.prototype,
TextEditorControl.prototype
TextEditorControl.prototype,
Execute.prototype
);
OperationCodeEditorControl.prototype._initWidgetEventHandlers = function () {
TextEditorControl.prototype._initWidgetEventHandlers.call(this);
this._widget.getOperationAttributes = this.getOperationAttributes.bind(this);
this._widget.executeOrStopJob = this.executeOrStopJob.bind(this);
};
OperationCodeEditorControl.prototype.TERRITORY_RULE = {children: 3};
@@ -78,6 +84,19 @@ define([
return attrs;
};
OperationCodeEditorControl.prototype.executeOrStopJob = function () {
var job;
if (this.currentJobId) { // Only if nested in a job
job = this._client.getNode(this.currentJobId);
if (this.isRunning(job)) {
this.stopJob(job);
} else {
this.executeJob(job);
}
}
};
// Line offset handling
OperationCodeEditorControl.prototype.offsetNodeChanged = function (id) {
// Create a territory for this node
@@ -9,6 +9,7 @@ define([
this._widget.allDataTypeIds = this.allDataTypeIds.bind(this);
this._widget.allValidReferences = this.allValidReferences.bind(this);
this._widget.addRefTo = this.addRefTo.bind(this);
this._widget.setRefType = this.setRefType.bind(this);
this._widget.changePtrName = this.changePtrName.bind(this);
this._widget.removePtr = this.removePtr.bind(this);
this._widget.getCreationNode = this.getCreationNode.bind(this);
@@ -138,6 +139,29 @@ define([
this._client.completeTransaction();
};
OperationInterfaceEditorEvents.prototype.setRefType = function(ref, targetId) {
var meta = this._client.getPointerMeta(this._currentNodeId, ref),
msg = `Setting ${ref} reference type to ${targetId}`;
if (!meta) {
this.logger.debug(`No meta found for ${ref}. Creating a new reference to ${targetId}`);
meta = {
min: 1,
max: 1,
items: []
};
}
meta.items.push({
id: targetId,
max: 1
});
this._client.startTransaction(msg);
this._client.setPointerMeta(this._currentNodeId, ref, meta);
this._client.completeTransaction();
};
OperationInterfaceEditorEvents.prototype.changePtrName = function(from, to) {
var opNode = this._client.getNode(this._currentNodeId),
name = opNode.getAttribute('name'),
@@ -255,13 +255,23 @@ define([
};
OperationInterfaceEditorControl.prototype.getPtrDescriptor = function(name) {
var targetId = this._client.getPointerMeta(this._currentNodeId, name)
.items[0].id,
target = this._client.getNode(targetId),
decManager = this._client.decoratorManager,
Decorator = decManager.getDecoratorForWidget('OpIntPtrDecorator', 'EasyDAG'),
var Decorator = this._client.decoratorManager.getDecoratorForWidget('OpIntPtrDecorator', 'EasyDAG'),
id = 'ptr_'+name,
used = this.isUsedInput(name);
used = this.isUsedInput(name),
ptrMeta = this._client.getPointerMeta(this._currentNodeId, name),
targetId,
target,
baseName;
if (!ptrMeta || ptrMeta.items.length === 0) {
// No known type
this._logger.error(`No known target type for "${name}" reference`);
baseName = null;
} else {
targetId = ptrMeta.items[0].id;
target = this._client.getNode(targetId);
baseName = target.getAttribute('name');
}
if (used === null) {
used = this._usage[id] !== undefined ? this._usage[id] : true;
@@ -270,7 +280,8 @@ define([
return {
id: id,
isPointer: true,
baseName: target.getAttribute('name'),
baseName: baseName,
isUnknown: !baseName,
Decorator: Decorator,
used: used,
attributes: {},
@@ -92,13 +92,18 @@ define([
OutputViewerPanel.prototype.selectOutput = function (element) {
if (this.$selected !== element) {
// Update the panel
var dataId = element.data('id');
while (element.prop('tagName').toLowerCase() !== 'a' && element.length) {
element = element.parent();
}
dataId = element.data('id');
this.$selected.parent().removeClass('active');
element.parent().addClass('active');
this.$selected = element;
// Update the panel
var dataId = element.data('id');
if (dataId) {
this.loadOutputFor(dataId);
} else { // Set the logviewer
@@ -300,6 +305,7 @@ define([
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
OutputViewerPanel.prototype.destroy = function () {
this.activePanel.destroy();
this.clearTerritory();
PanelBaseWithHeader.prototype.destroy.call(this);
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
@@ -62,7 +62,7 @@ define(['js/PanelBase/PanelBaseWithHeader',
});
// Editable pipeline name
this.$panelHeaderTitle.on('dblclick', () => this.editTitle());
this.$panelHeaderTitle.on('click', () => this.editTitle());
this.onActivate();
};
@@ -5,6 +5,7 @@ define([
'deepforge/globals',
'widgets/EasyDAG/EasyDAGWidget',
'widgets/EasyDAG/AddNodeDialog',
'./SelectionManager',
'./Layer',
'q',
'underscore',
@@ -13,6 +14,7 @@ define([
DeepForge,
EasyDAGWidget,
AddNodeDialog,
SelectionManager,
Layer,
Q,
_
@@ -31,6 +33,7 @@ define([
_.extend(ArchEditorWidget.prototype, EasyDAGWidget.prototype);
ArchEditorWidget.prototype.ItemClass = Layer;
ArchEditorWidget.prototype.SelectionManager = SelectionManager;
ArchEditorWidget.prototype.onCreateInitialNode = function() {
var nodes = this.getValidInitialNodes();
@@ -0,0 +1,52 @@
/* globals _, WebGMEGlobal, define*/
define([
'widgets/EasyDAG/SelectionManager',
'deepforge/viz/Buttons'
], function(
ManagerBase,
Buttons
) {
var client = WebGMEGlobal.Client;
var SelectionManager = function() {
ManagerBase.apply(this, arguments);
};
_.extend(SelectionManager.prototype, ManagerBase.prototype);
SelectionManager.prototype.createActionButtons = function(width, height) {
var disabled,
btn;
ManagerBase.prototype.createActionButtons.call(this, width, height);
if (!this.selectedItem.isConnection) {
disabled = !this._isCustomLayer();
// Check that the base type
btn = new Buttons.GoToBase({
$pEl: this.$selection,
context: this._widget,
item: this.selectedItem,
disabled: disabled,
x: width,
y: 0
});
}
return btn;
};
SelectionManager.prototype._isCustomLayer = function() {
var node = client.getNode(this.selectedItem.id),
attrNames;
if (node) {
attrNames = node.getAttributeNames();
return attrNames.indexOf('code') !== -1;
}
return false;
};
return SelectionManager;
});
@@ -0,0 +1,13 @@
<table class="table">
<thead>
<tr>
<td></td>
<td>Name</td>
<td>Creation Date</td>
<td>Origin Pipeline</td>
<td>Duration</td>
</tr>
</thead>
<tbody class="execs-content">
</tbody>
</table>
@@ -0,0 +1,325 @@
/*globals define, WebGMEGlobal, $*/
/*jshint browser: true*/
define([
'deepforge/viz/Utils',
'widgets/LineGraph/LineGraphWidget',
'text!./ExecTable.html',
'css!./styles/ExecutionIndexWidget.css'
], function (
Utils,
LineGraphWidget,
TableHtml
) {
'use strict';
var ExecutionIndexWidget,
WIDGET_CLASS = 'execution-index';
ExecutionIndexWidget = function (logger, container) {
this._logger = logger.fork('Widget');
this.$el = container;
this.nodes = {};
this.graphs = {};
this.checkedIds = [];
this._initialize();
this._logger.debug('ctor finished');
};
ExecutionIndexWidget.prototype._initialize = function () {
// set widget class
this.$el.addClass(WIDGET_CLASS);
// Create split screen
this.$left = $('<div>', {class: 'left'});
this.$right = $('<div>', {class: 'right'});
this.$el.append(this.$left, this.$right);
// Create the table
this.$table = $(TableHtml);
this.$table.on('click', '.exec-row', event => this.onExecutionClicked(event));
this.$table.on('click', '.node-nav', event => this.navToNode(event));
this.$left.append(this.$table);
this.$execList = this.$table.find('.execs-content');
// Create the graph in the right half
this.lineGraph = new LineGraphWidget(this._logger, this.$right);
this.defaultSelection = null;
this.hasRunning = false;
};
ExecutionIndexWidget.prototype.navToNode = function (event) {
var id = event.target.getAttribute('data-id');
if (typeof id === 'string') {
WebGMEGlobal.State.registerActiveObject(id);
event.stopPropagation();
}
this._logger.warn('No node id found for node-nav!');
};
ExecutionIndexWidget.prototype.onExecutionClicked = function (event) {
var target = event.target,
checked,
id;
while (!target.getAttribute('data-id')) {
if (!target.parentNode) {
this._logger.error('could not find execution id for ' + event);
return;
}
target = target.parentNode;
}
id = target.getAttribute('data-id');
checked = this.nodes[id].$checkbox.checked;
if (event.target.tagName.toLowerCase() !== 'input') {
this.setSelect(id, !checked);
} else {
this.setExecutionDisplayed(id, checked);
}
};
ExecutionIndexWidget.prototype.onWidgetContainerResize = function (width, height) {
this.$left.css({
width: width/2,
height: height
});
this.$right.css({
left: width/2,
width: width/2,
height: height
});
this.lineGraph.onWidgetContainerResize(width/2, height);
this._logger.debug('Widget is resizing...');
};
// Adding/Removing/Updating items
ExecutionIndexWidget.prototype.addNode = function (desc) {
var isFirstNode = Object.keys(this.nodes).length === 0;
if (desc.type === 'Execution') {
// Add node to a table of nodes
this.addExecLine(desc);
this.updateSelected(desc);
} else if (desc.type === 'line') {
desc.type = 'line';
this.lineGraph.addNode(desc);
}
if (isFirstNode) {
this.updateTimes();
}
};
ExecutionIndexWidget.prototype.updatePipelineName = function (execId, name) {
if (this.nodes[execId]) {
this.nodes[execId].$pipeline.text(name);
}
};
ExecutionIndexWidget.prototype.addExecLine = function (desc) {
var row = $('<tr>', {class: 'exec-row', 'data-id': desc.id}),
checkBox = $('<input>', {type: 'checkbox'}),
statusClass = Utils.ClassForJobStatus[desc.status],
fields,
pipeline,
name,
duration = $('<div>'),
td;
pipeline = $('<a>', {
class: 'node-nav',
'data-id': desc.originId
}).text(desc.pipelineName || 'view pipeline');
name = $('<a>', {class: 'node-nav', 'data-id': desc.id})
.text(desc.name);
fields = [
checkBox,
name,
Utils.getDisplayTime(desc.originTime),
pipeline,
duration
];
for (var i = 0; i < fields.length; i++) {
td = $('<td>');
if ((typeof fields[i]) === 'string') {
td.text(fields[i]);
} else {
td.append(fields[i]);
}
row.append(td);
}
this._logger.debug(`Adding execution ${desc.name} (${desc.id}) to list`);
this.$execList.append(row);
row.addClass(statusClass);
this.nodes[desc.id] = {
statusClass: statusClass,
desc: desc,
$el: row,
$checkbox: checkBox[0],
$pipeline: pipeline,
$duration: duration,
$name: name
};
this.updateTime(desc.id, true);
};
ExecutionIndexWidget.prototype.getDurationText = function (duration) {
var hours,
min,
sec;
sec = duration/1000;
hours = Math.floor(sec/3600);
sec = sec%3600;
min = Math.floor(sec/60);
sec = Math.floor(sec%60);
return `${hours}:${min}:${sec}`;
};
ExecutionIndexWidget.prototype.updateTime = function (id, force) {
var desc = this.nodes[id].desc,
duration = 'unknown';
if (desc.status === 'running') {
if (desc.startTime) {
duration = this.getDurationText(Date.now() - desc.startTime);
}
this.nodes[id].$duration.text(duration);
return true;
} else if (force) {
if (desc.endTime && desc.startTime) {
duration = this.getDurationText(desc.endTime - desc.startTime);
}
this.nodes[id].$duration.text(duration);
return true;
}
return false;
};
ExecutionIndexWidget.prototype.updateTimes = function () {
var nodeIds = Object.keys(this.nodes),
updated = false;
for (var i = nodeIds.length; i--;) {
updated = this.updateTime(nodeIds[i]) || updated;
}
if (updated) { // if there are still nodes, call again!
setTimeout(this.updateTimes.bind(this), 1000);
}
};
ExecutionIndexWidget.prototype.removeNode = function (id) {
if (this.nodes[id]) {
this.nodes[id].$el.remove();
} else if (this.graphs[id]) {
delete this.graphs[id];
}
delete this.nodes[id];
this.lineGraph.removeNode(id); // 'nop' if node is not line
};
ExecutionIndexWidget.prototype.updateSelected = function (desc) {
// If the running pipeline has been unselected, don't reselect it!
if (desc.status === 'running') {
this.hasRunning = true;
this.setSelect(desc.id, true);
if (this.defaultSelection) {
this.setSelect(this.defaultSelection, false);
}
} else if (!this.hasRunning && !this.defaultSelection) {
this.defaultSelection = desc.id;
this.setSelect(desc.id, true);
}
};
ExecutionIndexWidget.prototype.toggleAbbreviations = function (show, ids) {
var node,
desc,
name;
ids = ids || this.checkedIds;
for (var i = ids.length; i--;) {
node = this.nodes[ids[i]];
desc = node.desc;
name = show ? `${desc.name} (${desc.abbr})` : desc.name;
node.$name.text(name);
}
};
ExecutionIndexWidget.prototype.setSelect = function (id, checked) {
var wasChecked = this.checkedIds.length > 1,
isChecked;
this.nodes[id].$checkbox.checked = checked;
// If multiple are checked, display the abbreviation
if (checked) {
this.checkedIds.push(id);
} else {
var k = this.checkedIds.indexOf(id);
if (k !== -1) {
this.checkedIds.splice(k, 1);
}
}
isChecked = this.checkedIds.length > 1;
if (isChecked !== wasChecked) {
this.toggleAbbreviations(isChecked);
}
// Update the given node
if (!checked || isChecked) {
this.toggleAbbreviations(checked, [id]);
}
this.setExecutionDisplayed(id, checked);
};
ExecutionIndexWidget.prototype.updateNode = function (desc) {
var node = this.nodes[desc.id];
if (node) {
node.$name.text(desc.name);
node.$el.removeClass(node.statusClass);
node.$el.addClass(Utils.ClassForJobStatus[desc.status]);
if (Utils.ClassForJobStatus[desc.status] !== node.statusClass) {
// Only update the selection if the status has changed.
// ie, it has started running
this.updateSelected(desc);
}
this._logger.debug(`setting execution ${desc.id} to ${desc.status}`);
node.statusClass = Utils.ClassForJobStatus[desc.status];
node.desc = desc;
} else if (desc.type === 'line') {
this.lineGraph.updateNode(desc);
}
};
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
ExecutionIndexWidget.prototype.destroy = function () {
};
ExecutionIndexWidget.prototype.onActivate = function () {
this._logger.debug('ExecutionIndexWidget has been activated');
};
ExecutionIndexWidget.prototype.onDeactivate = function () {
this._logger.debug('ExecutionIndexWidget has been deactivated');
};
return ExecutionIndexWidget;
});
@@ -0,0 +1,21 @@
/**
* 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
*/
.execution-index.panel-body {
padding: 0;
}
.execution-index .left {
position: absolute;
background-color: #eee;
}
.execution-index .right {
position: absolute;
background-color: #eee;
}
@@ -0,0 +1,7 @@
/**
* This file is for any scss that you may want for this visualizer.
*/
.execution-index {
outline: none;
}
@@ -48,8 +48,8 @@ define([
var title = nodeName === undefined ? this._currentTitle : nodeName;
this._currentTitle = title;
if (this.isSnapshot) {
title += ' (SNAPSHOT)';
if (!this.isSnapshot) {
title += ' (DEBUG)';
}
this._setTitle(title);
@@ -1,4 +1,4 @@
/*globals define, d3, nv */
/*globals define, d3, nv, _ */
/*jshint browser: true*/
define([
@@ -35,7 +35,6 @@ define([
this.$chart = d3.select(this.$el[0]).append('svg');
nv.addGraph(() => {
var chart = nv.models.lineChart()
//.margin({left: 100})
.useInteractiveGuideline(true)
.showLegend(true)
.showYAxis(true)
@@ -49,6 +48,7 @@ define([
.axisLabel(this.options.xAxis);
}
chart.yAxis.tickFormat(d3.format('.02f'));
if (this.options.yAxis) {
chart.yAxis
.axisLabel(this.options.yAxis);
@@ -69,7 +69,9 @@ define([
};
LineGraphWidget.prototype.getData = function () {
return Object.keys(this.lineData).map(id => this.lineData[id]);
return Object.keys(this.lineData)
.map(id => this.lineData[id])
.filter(data => data.values.length !== 0); // hide empty lines
};
// Adding/Removing/Updating items
@@ -82,20 +84,20 @@ define([
values: desc.points
};
}
this.updateChartData();
this.refreshChart();
}
};
LineGraphWidget.prototype.removeNode = function (id) {
delete this.lineData[id];
this.updateChartData();
this.refreshChart();
};
LineGraphWidget.prototype.updateNode = function (desc) {
if (desc && this.lineData[desc.id]) {
this.lineData[desc.id].values = desc.points;
this.lineData[desc.id].key = desc.name;
this.updateChartData();
this.refreshChart();
}
};
@@ -115,6 +117,9 @@ define([
}
};
LineGraphWidget.prototype.refreshChart =
_.debounce(LineGraphWidget.prototype.updateChartData, 50);
LineGraphWidget.prototype.updateChart = function () {
if (this.chart) {
this.chart.update();
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
@@ -1 +0,0 @@
{"version":3,"sources":["build/nv.d3.css"],"names":[],"mappings":"AAqBA,oBAfA,oBAgBI,KAAM,KAmXN,gBAAiB,WAhFrB,kBA+DA,uBAnWA,oBAfA,oBAmYI,gBAAiB,WAmErB,UAAW,UAJX,mBAvcA,eAsbA,uBA8BA,uCACI,eAAgB,KA+DpB,WA7QA,aAoRI,QAAS,MAST,sBAAuB,KAEvB,mBAAoB,KAtiBxB,eAEI,QAAS,EAuCb,2BA4JA,0DACI,QAAS,EAjMb,oBAEI,OAAQ,KACR,eAAgB,IAIpB,2BACI,eAAgB,IAGpB,gCACI,eAAgB,EAGpB,oBAEI,OAAQ,QAIZ,0BACI,0BACA,eAAgB,IAGpB,mCACI,YAAa,IAGjB,sCACA,uCACA,uCACI,YAAa,OAOjB,oBACI,aAAc,IAEd,WAAY,aAAa,MAAM,OAC/B,gBAAiB,aAAa,MAAM,OACpC,mBAAoB,aAAa,MAAM,OAG3C,0BACI,aAAc,EAGlB,2BACI,KAAM,QAGV,oBACI,KAAM,YAGV,2BACI,KAAM,cAKV,sCAFA,mCACA,6CAEI,eAAgB,EAEhB,WAAY,aAAa,MAAM,OAC/B,gBAAiB,aAAa,MAAM,OACpC,mBAAoB,aAAa,MAAM,OAK3C,8CACA,4CAHA,yCACA,mDAGI,aAAc,EAGlB,sCACA,6CACI,YAAa,IACb,KAAM,cACN,OAAQ,YAIZ,yBACE,aAAc,GAGhB,+BAIA,6BAHE,aAAc,EAOhB,6BACE,OAAQ,KAGV,uBACE,aAAc,MAGhB,gBAAkB,KAAM,KAAK,WAC7B,4BAA8B,aAAc,GAC5C,kCAAoC,aAAc,EAClD,2BAA6B,OAAQ,KAAM,aAAc,IACzD,mCAAqC,OAAQ,KAAM,KAAM,KAAM,aAAc,MAC7E,+BAAiC,OAAQ,KAAM,aAAc,MAC7D,8BAAgC,OAAQ,KAAM,aAAc,KAC5D,gCAAkC,KAAM,KACxC,gCAAkC,KAAM,KACxC,gCAAkC,KAAM,KACxC,0BAA4B,UAAW,KAAM,YAAa,IAC1D,6BAA+B,KAAM,KAGrC,0BACI,KAAM,QACN,aAAc,GAElB,gCACI,aAAc,GAGlB,2CACI,aAAc,IAGlB,iDACI,aAAc,IAGlB,yDACI,OAAQ,QACR,KAAM,QAGV,yDACI,OAAQ,QACR,KAAM,QAGV,wDACI,WAAY,aAAa,MAAM,OAAQ,eAAe,MAAM,OAC5D,gBAAiB,aAAa,MAAM,OAAQ,eAAe,MAAM,OACjE,mBAAoB,aAAa,MAAM,OAAQ,eAAe,MAAM,OAIxE,uCACI,OAAQ,KAIZ,eACE,OAAQ,KACR,aAAc,MAEhB,eACE,OAAQ,KACR,eAAgB,GAElB,oBACE,aAAc,EAOhB,4BACI,aAAa,EACb,aAAa,EAGjB,8BACI,aAAa,EACb,aAAa,EAGjB,qDACI,aAAa,EACb,eAAe,EAQnB,kCACI,aAAc,IAGlB,wCACI,aAAc,EAElB,8BACI,KAAM,KAGV,8BACI,OAAQ,KAGZ,oDACI,aAAc,EACd,eAAgB,EAGpB,sDACI,aAAc,aACd,eAAgB,aAIpB,6CACI,WAAY,aAAa,MAAM,OAAQ,eAAe,MAAM,OAC5D,gBAAiB,aAAa,MAAM,OAAQ,eAAe,MAAM,OACjE,mBAAoB,aAAa,MAAM,OAAQ,eAAe,MAAM,OAKxE,iCADA,4CAEI,aAAc,IACd,aAAc,cACd,eAAgB,cAIpB,2BACI,OAAQ,KACR,eAAgB,EAChB,KAAM,KACN,aAAc,EAKlB,oBACI,OAAQ,UAUZ,aAEI,oBAAqB,KAErB,gBAAiB,KACjB,iBAAkB,KAClB,YAAa,KAEb,MAAM,KACN,OAAO,KAMX,0BAA2B,2BACvB,gBAAiB,EAAE,IAAI,KAAK,eAC5B,mBAAoB,EAAE,IAAI,KAAK,eAC/B,WAAY,EAAE,IAAI,KAAK,eAEvB,sBAAuB,IACvB,mBAAoB,IACpB,cAAe,IAInB,WACI,KAAM,IAAO,KAAK,MAGtB,aACI,KAAM,IAAK,KAAK,MAGpB,qBACI,KAAM,KACN,aAAc,EAGlB,gBACI,UAAW,KACX,YAAa,IAQjB,kBACI,aAAc,KAIlB,uBACI,KAAM,KACN,OAAQ,KAQZ,4BACI,OAAQ,QAGZ,qCACI,aAAc,EAIlB,wBACI,aAAc,YAGlB,+BACI,OAAQ,KACR,aAAc,GACd,KAAM,KACN,aAAc,GAOlB,aACE,WACE,aAAc,EACd,aAAc,GAIlB,oCACI,aAAc,IAGlB,0CACI,aAAc,IAGlB,6CACI,OAAQ,QAGZ,6CACI,OAAQ,QAIZ,uBACI,KAAM,KACN,OAAQ,KACR,eAAgB,GAIpB,uBACI,KAAM,KACN,eAAgB,GAGpB,4CAEI,KAAM,KACN,aAAc,GACd,OAAQ,KACR,gBAAiB,WAGrB,qCACI,aAAc,EACjB,aAAc,IAIf,8BACE,KAAM,KACN,OAAQ,KACR,aAAc,EACd,eAAgB,EAChB,iBAAkB,EAAG,EAUvB,2BACI,UAAW,KACX,KAAM,qBAGV,4BACI,OAAQ,KACR,aAAc,EAGlB,kBAhBI,WAAY,aAAa,MAAM,OAAQ,aAAa,MAAM,OAAQ,eAAe,MAAM,OACvF,gBAAiB,aAAa,MAAM,OAAQ,aAAa,MAAM,OAAQ,eAAe,MAAM,OAC5F,mBAAoB,aAAa,MAAM,OAAQ,aAAa,MAAM,OAAQ,eAAe,MAAM,OAe/F,OAAQ,KACR,aAAc,IACd,eAAgB,EAIhB,aAAc,GAElB,yBACI,aAAc,EAKlB,4BACI,aAAc,EACd,eAAgB,EAIpB,iCACI,aAAc,KACd,eAAgB,GAGpB,kCACI,aAAc,EAWlB,wBACI,KAAM,KAOV,2CACI,OAAQ,KACR,aAAc,MAGlB,uBACA,yBACI,eAAgB,IA4LpB,+BAvIA,WAwII,eAAe,KA1LnB,oBACI,aAAc,EACd,eAAgB,EAGpB,kCACA,kCACI,aAAc,EACd,UAAW,KACX,YAAa,IAGjB,kCACI,OAAQ,KAGZ,oCACI,OAAQ,QACR,KAAM,QAGV,oCACI,OAAQ,QACR,KAAM,QAGV,wCACI,YAAa,IACb,UAAW,MAsEf,cAsCA,wBACI,YAAa,IA1GjB,kCACI,aAAc,GACd,eAAgB,EAChB,WAAY,aAAa,MAAM,OAAQ,eAAe,MAAM,OAC5D,gBAAiB,aAAa,MAAM,OAAQ,eAAe,MAAM,OACjE,mBAAoB,aAAa,MAAM,OAAQ,eAAe,MAAM,OAGxE,wCACI,aAAc,GAIlB,0CACI,eAAgB,EAChB,aAAc,EAIlB,WACI,SAAU,SAEV,MAAO,cACP,QAAS,IAET,QAAS,MAGT,YAAa,MACb,UAAW,KACX,WAAY,KAGZ,YAAa,OAGb,oBAAqB,KAErB,iBAAkB,KAClB,gBAAiB,KACjB,YAAa,KAIb,WAAY,qBACZ,OAAQ,IAAI,MAAM,eAClB,cAAe,IAqBnB,cAgBA,aACI,OAAQ,EAER,WAAY,OAlChB,4BAA6B,6BACzB,WAAY,QAAQ,KAAK,OACzB,gBAAiB,QAAQ,KAAK,OAC9B,mBAAoB,QAAQ,KAAK,OAEjC,iBAAkB,MAClB,sBAAuB,MACvB,yBAA0B,MAG9B,uBACA,uBACI,QAAS,IAGb,cAEI,QAAS,IAAI,KACb,YAAa,KAEb,iBAAkB,sBAClB,MAAO,cAGP,cAAe,IAAI,MAAM,QAEzB,sBAAuB,IAAI,IAAI,EAAE,EACjC,mBAAoB,IAAI,IAAI,EAAE,EAC9B,cAAe,IAAI,IAAI,EAAE,EAG7B,aAEI,QAAS,IAAI,KAIjB,gBACI,QAAS,aACT,OAAQ,IAAI,EAGhB,iBACI,OAAQ,IACR,eAAe,EAInB,oBACI,QAAS,IAAI,IAAI,IAAI,EACrB,eAAgB,OAMpB,8BACI,YAAa,IAEjB,0BACI,WAAY,MACZ,YAAa,IAGjB,4BACI,MAAO,QAGX,iCACI,QAAS,IAAI,IAAI,IAAI,EACrB,oBAAqB,MACrB,oBAAqB,IACrB,iBAAkB,MAClB,iBAAkB,IAGtB,2CAGI,eAAgB,OAIhB,MAAO,KACP,OAAQ,KACR,OAAQ,IAAI,MAAM,KAGtB,mBACI,QAAS,IACT,WAAY,OAGhB,2BACI,eAAgB,KAChB,QAAS,KAUb,wBACI,OAAQ"}
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
Diff do arquivo suprimido porque uma ou mais linhas são muito longas
@@ -27,6 +27,8 @@ define([
this._el.addClass('log-viewer');
this.editor.setTheme('ace/theme/twilight');
this.editor.setShowPrintMargin(false);
this.editor.renderer.setScrollMargin(0, 75);
this.addKeyListeners();
// Override the textlayer to add support for ansi colors
this.customizeAce();
@@ -34,6 +36,24 @@ define([
_.extend(LogViewerWidget.prototype, TextEditorWidget.prototype);
LogViewerWidget.prototype.addKeyListeners = function() {
// Need to add key listeners to the container itself since ace is in read-only mode
this._el.on('keydown', event => {
// ctrl-alt-pagedown -> EOF
if (event.key === 'PageDown' && event.altKey && (event.ctrlKey || event.metaKey)) {
this.editor.gotoLine(Infinity);
event.stopPropagation();
event.preventDefault();
}
// ctrl-alt-pagedown -> beginning of file
if (event.key === 'PageUp' && event.altKey && (event.ctrlKey || event.metaKey)) {
this.editor.gotoLine(0);
event.stopPropagation();
event.preventDefault();
}
});
};
LogViewerWidget.prototype.getHeader = function(desc) {
return `Console logging for Operation "${desc.name}":\n`;
};
@@ -17,12 +17,17 @@ define([
var MainViewWidget,
WIDGET_CLASS = 'main-view',
CreateListItem = _.template(ListItem);
CreateListItem = _.template(ListItem),
ToggleLabels = [
'Executions',
'Pipelines'
];
MainViewWidget = function (logger, container) {
this._logger = logger.fork('Widget');
this.$el = container;
this.$el.addClass(WIDGET_CLASS);
this.toggleIndex = 0;
this.initialize();
this._logger.debug('ctor finished');
};
@@ -32,6 +37,19 @@ define([
this.$nav = $(NavBarHTML);
this.$el.append(this.$nav);
// Execution support
this.$toggle = this.$nav.find('#toggle-main');
this.$toggleLabel = this.$nav.find('.toggle-label');
this.$toggle.on('click', () => {
if (this._closed) { // shouldn't be clicked when closed (but it is possible)
return;
}
this.toggleEmbeddedPanel();
// Update the toggle name
this.toggleIndex = (this.toggleIndex + 1) % 2;
this.$toggleLabel.text(ToggleLabels[this.toggleIndex]);
});
this.$archlist = this.$nav.find('#arch-list-content');
this.$artifacts = this.$nav.find('#artifact-list-content');
@@ -1,6 +1,13 @@
<nav class="side-nav fixed closed hide-list">
<li class="pull-right side-nav-control">
<span class="glyphicon glyphicon-menu-hamburger" aria-hidden="true"></span>
</li >
<li class="no-padding" id="toggle-main">
<ul>
<li class="no-padding">
<a class="toggle-label">Executions</a>
</li>
</ul>
</li>
<li class="no-padding">
<ul class="collapsible" data-collapsible="accordion">
@@ -1,3 +1,7 @@
.main-view-embedded {
position: absolute;
}
.main-view .side-nav-control {
padding-right: 1em;
padding-top: 1em;
@@ -17,6 +17,15 @@ define([
OperationCodeEditorWidget = function (logger, container) {
TextEditorWidget.call(this, logger, container);
this.lineOffset = 0;
// Add the shift-enter command
this.editor.commands.addCommand({
name: 'executeOrStopJob',
bindKey: {
mac: 'Shift-Enter',
win: 'Shift-Enter'
},
exec: () => this.executeOrStopJob()
});
};
_.extend(OperationCodeEditorWidget.prototype, TextEditorWidget.prototype);
@@ -1,4 +1,4 @@
/*globals define */
/*globals define*/
define([
'widgets/EasyDAG/DAGItem',
'underscore'
@@ -13,6 +13,7 @@ define([
// Show the warnings
this.$warning = null;
this.updateWarnings();
};
_.extend(Item.prototype, DAGItem.prototype);
@@ -29,38 +30,55 @@ define([
if (this.desc.used === false) {
this.warn(msg, isInput ? 'bottom' : 'top');
} else {
this.clearWarning();
this.clearNotification('$warning');
}
if (this.desc.isUnknown) { // ptrs only
this.error('Unknown type! Click to set', 'bottom');
} else if (this.$error) {
// Set the baseName tooltip, if needed
this.clearNotification('$error');
this.decorator.enableTooltip(this.desc.baseName, 'dark');
}
};
Item.prototype.warn = function(message, tipJoint) {
// Create a temporary div over the given svg element
if (this.$warning) {
this.clearWarning();
}
this.notify(message, '$warning', '#ffeb3b', 'standard', tipJoint);
};
this.decorator.highlight('#ffeb3b');
this.$warning = this.createTooltip(message, {
Item.prototype.error = function(message, tipJoint) {
this.notify(message, '$error', '#ef5350', 'alert', tipJoint);
};
Item.prototype.notify = function(message, varname, color, style, tipJoint) {
this.clearNotification(varname);
this.decorator.highlight(color);
this[varname] = this.createTooltip(message, {
showIf: () => !this.isSelected(),
tipJoint: tipJoint,
style: 'standard'
style: style
});
};
Item.prototype.clearWarning = function() {
if (this.$warning) {
this.destroyTooltip(this.$warning);
this.$warning = null;
Item.prototype.clearNotification = function(varname) {
if (this[varname]) {
this.destroyTooltip(this[varname]);
this[varname] = null;
}
this.decorator.unHighlight();
};
Item.prototype.onSelect = function() {
DAGItem.prototype.onSelect.call(this);
if (this.$warning) {
this.$warning.hide();
}
// Add click listener to set type
if (this.desc.isUnknown) {
this.onSetRefClicked(this.desc.name);
}
};
Item.prototype.setupDecoratorCallbacks = function() {
@@ -37,7 +37,7 @@ define([
EasyDAG.prototype.setupItemCallbacks.call(this);
// Add ptr rename callback
this.ItemClass.prototype.changePtrName = (from, to) => this.changePtrName(from, to);
this.ItemClass.prototype.onSetRefClicked = OperationInterfaceEditorWidget.prototype.onSetRefClicked.bind(this);
};
OperationInterfaceEditorWidget.prototype.onAddItemSelected = function(selected, isInput) {
@@ -77,6 +77,25 @@ define([
this.active = true; // keep refreshing the screen -> it is always visible
};
OperationInterfaceEditorWidget.prototype.onSetRefClicked = function(name) {
var refs = this.allValidReferences();
// Get all valid references
if (refs.length > 1) {
// Create the modal view with all possible subsequent nodes
var dialog = new AddNodeDialog();
dialog.show(null, refs);
dialog.onSelect = selected => {
if (selected) {
this.setRefType(name, selected.node.id);
}
};
} else if (refs[0]) {
this.setRefType(name, refs[0].node.id);
}
};
OperationInterfaceEditorWidget.prototype.onAddRefClicked = function() {
var refs = this.allValidReferences();
@@ -1,14 +1,11 @@
/*globals WebGMEGlobal, $, define*/
/*jshint browser: true*/
/**
* Generated by VisualizerGenerator 1.7.0 from webgme on Thu May 19 2016 14:04:47 GMT-0500 (CDT).
*/
define([
'widgets/EasyDAG/AddNodeDialog',
'widgets/EasyDAG/EasyDAGWidget',
'deepforge/viz/PipelineControl',
'deepforge/viz/Utils',
'deepforge/globals',
'./OperationNode',
'./Connection',
@@ -19,6 +16,7 @@ define([
AddNodeDialog,
EasyDAGWidget,
PipelineControl,
Utils,
DeepForge,
OperationNode,
Connection,
@@ -35,12 +33,7 @@ define([
DEFAULT: 'default',
CONNECTING: 'connecting'
},
UPLOAD_ARTIFACT_ID = '__UPLOAD_ARTIFACT__',
STATUS_TO_CLASS = {
running: 'warning',
success: 'success',
failed: 'danger'
};
UPLOAD_ARTIFACT_ID = '__UPLOAD_ARTIFACT__';
PipelineEditorWidget = function (logger, container, execCntr) {
EasyDAGWidget.call(this, logger, container);
@@ -51,6 +44,7 @@ define([
this._connForPort = {};
this._itemsShowingPorts = [];
this.updateExecutions = _.debounce(this._updateExecutions, 50);
this.initExecs(execCntr);
};
@@ -290,7 +284,7 @@ define([
this.updateExecutions();
};
PipelineEditorWidget.prototype.updateExecutions = function() {
PipelineEditorWidget.prototype._updateExecutions = function() {
var keys = Object.keys(this.executions),
hasExecutions = !!keys.length,
msg = `${keys.length || 'No'} Associated Execution` +
@@ -321,14 +315,10 @@ define([
var row = $('<tr>'),
title = $('<td>', {class: 'execution-name'}),
timestamp = $('<td>'),
className = STATUS_TO_CLASS[exec.status] || '',
today = new Date().toLocaleDateString(),
date = new Date(exec.createdAt).toLocaleDateString(),
className = Utils.ClassForJobStatus[exec.status] || '',
date = Utils.getDisplayTime(exec.createdAt),
rmIcon = $(REMOVE_ICON);
if (date === today) {
date = `Today (${new Date(exec.createdAt).toLocaleTimeString()})`;
}
timestamp.text(date);
title.append($('<a>').text(exec.name));
@@ -44,7 +44,7 @@ define([
this.deletePipeline(id);
});
this.$el.on('dblclick', '.pipeline-name', event => {
this.$el.on('click', '.pipeline-name', event => {
var html = $(event.target),
id = html.data('id');
@@ -111,7 +111,8 @@ define([
return;
}
text = this.editor.getValue().replace(this.currentHeader + '\n', '');
text = this.editor.getValue()
.replace(this.currentHeader + '\n', '');
if (typeof this.activeNode === 'string') {
this.saveTextFor(this.activeNode, text);
} else {
-1
Ver Arquivo
@@ -1 +0,0 @@
{"http://localhost:8888":{}}
+38 -28
Ver Arquivo
@@ -12,8 +12,7 @@ var callRegister = {
var mocks = {
childProcess: {},
rimraf: {},
forever: {}
rimraf: {}
};
var childProcess = {
@@ -23,6 +22,14 @@ var childProcess = {
return mocks.childProcess.execSync.apply(this, arguments);
}
},
spawnSync: function(cmd) {
if (cmd === 'luarocks') {
return {
stdout: 'rnn'
};
}
return {};
},
spawn: function() {
if (mocks.childProcess.spawn) {
mocks.childProcess.spawn.apply(this, arguments);
@@ -38,16 +45,6 @@ var childProcess = {
};
}
};
var forever = {};
forever.Monitor = function() {
var res = {};
res.on = nop;
res.start = nop;
if (mocks.forever.Monitor) {
mocks.forever.Monitor.apply(this, arguments);
}
return res;
};
var rimraf = {};
rimraf.sync = function() {
if (mocks.rimraf.sync) {
@@ -63,8 +60,9 @@ describe('cli', function() {
warnOnUnregistered: false
});
mockery.registerMock('child_process', childProcess);
mockery.registerMock('forever-monitor', forever);
mockery.registerMock('rimraf', rimraf);
// Clear node's cache
delete require.cache[require.resolve('../../bin/deepforge')];
cli = require('../../bin/deepforge');
});
@@ -75,10 +73,11 @@ describe('cli', function() {
describe('start', function() {
afterEach(function() {
callRegister.childProcess.execSync = [];
mocks.childProcess.execSync = nop;
mocks.childProcess.spawn = nop;
mocks.forever.Monitor = nop;
mocks.childProcess.execSync = () => '123';
mocks.rimraf.sync = nop;
delete require.cache[require.resolve('../../bin/deepforge')];
cli = require('../../bin/deepforge');
});
it('should check for running mongo', function() {
@@ -113,21 +112,29 @@ describe('cli', function() {
cli('start --mongo');
});
it('should start local deepforge by default', function() {
mocks.forever.Monitor = main =>
assert.notEqual(main.indexOf('start-local.js'), -1);
it('should start local deepforge by default', function(done) {
mocks.childProcess.spawn = (main, args) => {
if (main === 'node') {
assert.notEqual(args[0].indexOf('start-local.js'), -1);
done();
}
};
cli('start');
});
it('should start normal deepforge if --server set', function() {
mocks.forever.Monitor = main =>
assert.notEqual(main.indexOf('app.js'), -1);
it('should start normal deepforge if --server set', function(done) {
mocks.childProcess.spawn = (main, args) => {
if (main === 'node') {
assert.notEqual(args[0].indexOf('app.js'), -1);
done();
}
};
cli('start --server');
});
it('should start worker if --worker set', function(done) {
mocks.forever.Monitor = main => {
if (main.indexOf('start-worker.js') !== -1) {
mocks.childProcess.spawn = (main, args) => {
if (args[0].indexOf('start-worker.js') !== -1) {
done();
}
};
@@ -163,17 +170,20 @@ describe('cli', function() {
describe('update', function() {
it('should update deepforge w/ npm', function() {
mocks.childProcess.spawn = (cmd, args) => {
assert.equal(cmd, 'npm');
assert.equal(args[0], 'install');
assert.notEqual(args.indexOf('deepforge'), -1);
assert.notEqual(args.indexOf('-g'), -1);
if (cmd === 'npm') {
assert.equal(args[0], 'install');
assert.notEqual(args.indexOf('deepforge'), -1);
assert.notEqual(args.indexOf('-g'), -1);
}
};
cli('update');
});
it('should update deepforge from git if --git set w/ npm', function() {
mocks.childProcess.spawn = (cmd, args) => {
assert.notEqual(args.indexOf('dfst/deepforge'), -1);
if (cmd === 'npm') {
assert.notEqual(args.indexOf('dfst/deepforge'), -1);
}
};
cli('update --git');
});
+68 -55
Ver Arquivo
@@ -1,7 +1,4 @@
/*jshint node:true, mocha:true*/
/**
* Generated by PluginGenerator 0.14.0 from webgme on Thu Mar 10 2016 04:16:02 GMT-0600 (CST).
*/
'use strict';
var testFixture = require('../../globals'),
@@ -63,7 +60,7 @@ describe('ImportTorch', function () {
checker = new GraphChecker({
core: core,
ignore: {
attributes: []
attributes: ['ctor_arg_order']
}
});
return project.createBranch('test', commitHash);
@@ -103,60 +100,16 @@ describe('ImportTorch', function () {
});
var runTest = function(name, done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {},
context = {
namespace: 'nn',
project: project,
branchName: 'test',
activeNode: ''
},
data = fs.readFileSync(path.join(TEST_CASE_DIR, name), 'utf8'),
var data = fs.readFileSync(path.join(TEST_CASE_DIR, name), 'utf8'),
ymlFile = path.join(YAML_DIR, name.replace(/lua$/, 'yml')),
yml = fs.readFileSync(ymlFile, 'utf8'),
initModels;
yml = fs.readFileSync(ymlFile, 'utf8');
// Load the children from the head of the 'test' branch
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) {
return core.loadChildren(root);
})
.then(children => {
initModels = children.map(core.getPath);
return blobClient.putFile(name, data); // upload the file
})
.then(hash => {
pluginConfig.srcHash = hash;
return Q.nfcall(
manager.executePlugin.bind(manager),
pluginName,
pluginConfig,
context
);
})
.then(pluginResult => {
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
return project.getBranchHash('test');
})
importTorch(name, data)
// Use the check-model object to check the result models!
.then(function (branchHash) {
return Q.ninvoke(project, 'loadObject', branchHash);
})
.then(function (commitObject) {
return Q.ninvoke(core, 'loadRoot', commitObject.root);
})
.then(function (root) {
return core.loadChildren(root);
})
.then(children => {
var newModel = children.find(model =>
.then(groups => {
var children = groups[1],
initModels = groups[0],
newModel = children.find(model =>
initModels.indexOf(core.getPath(model)) === -1);
expect(initModels.length+1).to.equal(children.length);
@@ -176,6 +129,56 @@ describe('ImportTorch', function () {
.nodeify(done);
};
var importTorch = function(name, code) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {},
context = {
namespace: 'nn',
project: project,
branchName: 'test',
activeNode: ''
},
initModels;
// Load the children from the head of the 'test' branch
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 (root) {
return core.loadChildren(root);
})
.then(children => {
initModels = children.map(core.getPath);
return blobClient.putFile(name, code); // upload the file
})
.then(hash => {
pluginConfig.srcHash = hash;
return Q.nfcall(
manager.executePlugin.bind(manager),
pluginName,
pluginConfig,
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(root => core.loadChildren(root))
.then(children => [initModels, children]);
};
describe('run test cases', function() {
var cases = fs.readdirSync(TEST_CASE_DIR)
.filter(name => path.extname(name) === '.lua')
@@ -186,4 +189,14 @@ describe('ImportTorch', function () {
// one test for each test name
cases.forEach(name => it(`should run test "${name}"`, runTest.bind(this, name)));
});
it('should support "require \'rnn\'"', function(done) {
importTorch('test', 'require \'nn\'\nrequire \'rnn\'')
.nodeify(done);
});
it('should not need require \'nn\'', function(done) {
importTorch('test', 'nn.Sequential():add(nn.Linear(100, 50))')
.nodeify(done);
});
});
+5
Ver Arquivo
@@ -0,0 +1,5 @@
local net = nn.Sequential()
net:add(nn.Transpose({ 1, 2 }))
net:add(nn.Transpose({ {1, 2}, {3, 4} }))
return net;
+177 -176
Ver Arquivo
@@ -1,340 +1,341 @@
require 'nn'
require 'rnn'
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, 0, 0))
net:add(nn.SpatialConvolution(64, 64, 1, 1, 0))
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, 0, 0))
net:add(nn.SpatialMaxPooling(3, 3, 2, 2))
local net = nn.Sequential()
net:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialConvolution(96, 96, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
local net_2 = nn.Sequential()
net_2:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1, 0))
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.SpatialConvolution(192, 64, 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, 0))
net_3:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1))
net_3:add(nn.ReLU(true))
net_3:add(nn.SpatialConvolution(64, 64, 3, 3, 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, 0))
net_4:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_4:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_4:add(nn.SpatialConvolution(192, 32, 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, 0, 0))
net_5:add(nn.SpatialConvolution(192, 32, 1, 1, 1, 1, 0))
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)
concat_24:add(net)
net:add(concat_24)
local net_5 = nn.Sequential()
net_5:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
net_5:add(nn.ReLU(true))
local net_6 = nn.Sequential()
net_6:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1, 0))
net_6:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
net_6:add(nn.ReLU(true))
net_6:add(nn.SpatialConvolution(64, 96, 3, 3, 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, 0))
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))
net_7:add(nn.SpatialConvolution(96, 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, 0))
net_8:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_8:add(nn.SpatialAveragePooling(3, 3, 1, 1))
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, 0, 0))
net_9:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1, 0))
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)
concat_41:add(net_5)
net:add(concat_41)
local net_9 = nn.Sequential()
net_9:add(nn.SpatialConvolution(320, 128, 1, 1, 1, 1))
net_9:add(nn.ReLU(true))
net_9:add(nn.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
net_9:add(nn.ReLU(true))
local net_10 = nn.Sequential()
net_10:add(nn.SpatialConvolution(320, 128, 1, 1, 1, 1, 0))
net_10:add(nn.SpatialConvolution(320, 64, 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.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
net_10:add(nn.ReLU(true))
net_10:add(nn.SpatialConvolution(96, 96, 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, 0))
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, 0, 0))
net_11:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_11: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)
concat_54:add(net_9)
net:add(concat_54)
net:add(nn.SpatialConvolution(576, 576, 2, 2, 2, 2, 0))
net:add(nn.SpatialConvolution(576, 576, 2, 2, 2, 2))
local net_12 = nn.Sequential()
net_12:add(nn.SpatialConvolution(576, 224, 1, 1, 1, 1))
net_12:add(nn.ReLU(true))
local net_13 = nn.Sequential()
net_13:add(nn.SpatialConvolution(576, 224, 1, 1, 1, 1, 0))
net_13:add(nn.SpatialConvolution(576, 64, 1, 1, 1, 1))
net_13:add(nn.ReLU(true))
net_13:add(nn.SpatialConvolution(64, 96, 3, 3, 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, 0))
net_14:add(nn.SpatialConvolution(576, 96, 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.SpatialConvolution(96, 128, 3, 3, 1, 1, 1, 1))
net_14:add(nn.ReLU(true))
net_14:add(nn.SpatialConvolution(128, 128, 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, 0))
net_15:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_15:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_15:add(nn.SpatialConvolution(576, 128, 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, 0, 0))
net_16:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1, 0))
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)
concat_72:add(net_12)
net:add(concat_72)
local net_16 = nn.Sequential()
net_16:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1))
net_16:add(nn.ReLU(true))
local net_17 = nn.Sequential()
net_17:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1, 0))
net_17:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_17:add(nn.ReLU(true))
net_17:add(nn.SpatialConvolution(96, 128, 3, 3, 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, 0))
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))
net_18:add(nn.SpatialConvolution(128, 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, 0))
net_19:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_19:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_19:add(nn.SpatialConvolution(576, 128, 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, 0, 0))
net_20:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1, 0))
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)
concat_89:add(net_16)
net:add(concat_89)
local net_20 = nn.Sequential()
net_20:add(nn.SpatialConvolution(576, 160, 1, 1, 1, 1))
net_20:add(nn.ReLU(true))
local net_21 = nn.Sequential()
net_21:add(nn.SpatialConvolution(576, 160, 1, 1, 1, 1, 0))
net_21:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_21:add(nn.ReLU(true))
net_21:add(nn.SpatialConvolution(128, 160, 3, 3, 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, 0))
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))
net_22:add(nn.SpatialConvolution(160, 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, 0))
net_23:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_23:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_23:add(nn.SpatialConvolution(576, 96, 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, 0, 0))
net_24:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1, 0))
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)
concat_106:add(net_20)
net:add(concat_106)
local net_24 = nn.Sequential()
net_24:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_24:add(nn.ReLU(true))
local net_25 = nn.Sequential()
net_25:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1, 0))
net_25:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_25:add(nn.ReLU(true))
net_25:add(nn.SpatialConvolution(128, 192, 3, 3, 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, 0))
net_26:add(nn.SpatialConvolution(576, 160, 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.SpatialConvolution(160, 192, 3, 3, 1, 1, 1, 1))
net_26:add(nn.ReLU(true))
net_26:add(nn.SpatialConvolution(192, 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, 0))
net_27:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_27:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_27:add(nn.SpatialConvolution(576, 96, 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, 0, 0))
net_28:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1, 0))
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)
concat_123:add(net_24)
net:add(concat_123)
local net_28 = nn.Sequential()
net_28:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1))
net_28:add(nn.ReLU(true))
net_28:add(nn.SpatialConvolution(192, 256, 3, 3, 1, 1, 1, 1))
net_28:add(nn.ReLU(true))
net_28:add(nn.SpatialConvolution(256, 256, 3, 3, 1, 1, 1, 1))
net_28:add(nn.ReLU(true))
local net_29 = nn.Sequential()
net_29:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1, 0))
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))
net_29:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_29:add(nn.SpatialMaxPooling(3, 3, 1, 1))
local net_30 = nn.Sequential()
net_30:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_30:add(nn.SpatialMaxPooling(3, 3, 1, 1, 0, 0))
net_30:add(nn.SpatialAveragePooling(5, 5, 3, 3))
net_30:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_30:add(nn.View())
net_30:add(nn.Linear(2048, 768))
net_30:add(nn.ReLU())
net_30:add(nn.Linear(768, 4))
net_30:add(nn.LogSoftMax())
local net_31 = nn.Sequential()
net_31:add(nn.SpatialAveragePooling(5, 5, 3, 3, 0, 0))
net_31:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1, 0))
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())
net_31:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_31:add(nn.ReLU(true))
net_31:add(nn.SpatialConvolution(128, 192, 3, 3, 1, 1, 1, 1))
net_31:add(nn.ReLU(true))
local concat_143 = nn.Concat(2)
concat_143:add(net_31)
concat_143:add(net_29)
concat_143:add(net_28)
net:add(concat_143)
local net_32 = nn.Sequential()
net_32:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1, 0))
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))
net_32:add(nn.SpatialConvolution(1024, 1024, 2, 2, 2, 2))
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, 0))
net_33:add(nn.SpatialConvolution(1024, 352, 1, 1, 1, 1))
net_33:add(nn.ReLU(true))
local net_34 = nn.Sequential()
net_34:add(nn.SpatialConvolution(1024, 352, 1, 1, 1, 1, 0))
net_34:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
net_34:add(nn.ReLU(true))
net_34:add(nn.SpatialConvolution(192, 320, 3, 3, 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, 0))
net_35:add(nn.SpatialConvolution(1024, 160, 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.SpatialConvolution(160, 224, 3, 3, 1, 1, 1, 1))
net_35:add(nn.ReLU(true))
net_35:add(nn.SpatialConvolution(224, 224, 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, 0))
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.SpatialZeroPadding(1, 1, 1, 1))
net_36:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_36:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1))
net_36:add(nn.ReLU(true))
local concat_161 = nn.Concat(2)
concat_161:add(net_36)
concat_161:add(net_35)
concat_161:add(net_34)
concat_161:add(net_33)
net_32:add(concat_161)
local net_37 = nn.Sequential()
net_37:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_37:add(nn.SpatialAveragePooling(3, 3, 1, 1, 0, 0))
net_37:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1, 0))
net_37:add(nn.SpatialConvolution(1024, 352, 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, 0))
net_38:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
net_38:add(nn.ReLU(true))
net_38:add(nn.SpatialConvolution(192, 320, 3, 3, 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, 0))
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.SpatialConvolution(192, 224, 3, 3, 1, 1, 1, 1))
net_39:add(nn.ReLU(true))
net_39:add(nn.SpatialConvolution(224, 224, 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, 0))
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.SpatialZeroPadding(1, 1, 1, 1))
net_40:add(nn.SpatialMaxPooling(3, 3, 1, 1))
net_40:add(nn.SpatialConvolution(1024, 128, 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, 0, 0))
net_41:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1, 0))
net_41:add(nn.ReLU(true))
local concat_178 = nn.Concat(2)
concat_178:add(net_40)
concat_178:add(net_39)
concat_178:add(net_38)
concat_178:add(net_37)
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, 0, 0))
net_33:add(nn.View())
net_33:add(nn.Linear(1024, 4))
net_33:add(nn.LogSoftMax())
net_32:add(concat_178)
net_32:add(nn.SpatialAveragePooling(7, 7, 1, 1))
net_32:add(nn.View())
net_32:add(nn.Linear(1024, 4))
net_32:add(nn.LogSoftMax())
local concat_183 = nn.Concat(2)
concat_183:add(net_33)
concat_183:add(net_31)
concat_183:add(net_32)
concat_183:add(net_30)
net:add(concat_183)
+6 -5
Ver Arquivo
@@ -1,19 +1,20 @@
require 'nn'
require 'rnn'
local net = nn.Sequential()
net:add(nn.SpatialConvolution(3, 96, 11, 11, 4, 4, 0))
net:add(nn.SpatialConvolution(3, 96, 11, 11, 4, 4))
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2, 0, 0))
net:add(nn.SpatialConvolution(96, 256, 5, 5, 1, 1, 0))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.SpatialConvolution(96, 256, 5, 5, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2, 0, 0))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
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, 0, 0))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.View())
net:add(nn.Dropout(0.5))
net:add(nn.Linear(25600, 3072))
+156 -138
Ver Arquivo
@@ -1,8 +1,30 @@
- type: SpatialConvolution
id: /P/0
- type: ReLU
id: /b/6
next:
- /P/2
- /b/oG
attributes:
p: ''
ctor_arg_order: p
- type: ReLU
id: /b/7
next:
- /b/u4
attributes:
p: ''
ctor_arg_order: p
- type: ReLU
id: /b/9
next:
- /b/X
attributes:
ctor_arg_order: p
p: true
- type: SpatialConvolution
id: /b/I8
next:
- /b/9
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 1
padW: 1
dH: 1
@@ -12,32 +34,46 @@
nOutputPlane: 384
nInputPlane: 192
- type: ReLU
id: /P/2
id: /b/K
next:
- /P/fX
- /b/w
attributes:
ctor_arg_order: p
p: true
- type: Dropout
id: /P/6
- type: ReLU
id: /b/N
next:
- /P/C
- /b/s
attributes:
v1: ''
inplace: ''
p: 0.5
- type: Linear
id: /P/8p
ctor_arg_order: p
p: true
- type: SpatialMaxPooling
id: /b/U
next:
- /P/S8
- /b/W
attributes:
padW: ''
padH: ''
ctor_arg_order: 'kW,kH,dW,dH,padW,padH'
dH: 2
dW: 2
kH: 3
kW: 3
- type: Linear
id: /b/V
next:
- /b/7
attributes:
bias: ''
outputSize: 5
inputSize: 4096
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 4096
inputSize: 9216
- type: SpatialConvolution
id: /P/A
id: /b/W
next:
- /P/j
- /b/N
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 2
padW: 2
dH: 1
@@ -46,108 +82,12 @@
kW: 5
nOutputPlane: 192
nInputPlane: 64
- type: Linear
id: /P/C
next:
- /P/mQ
attributes:
bias: ''
outputSize: 4096
inputSize: 9216
- type: ReLU
id: /P/F
next:
- /P/R
attributes:
p: true
- type: Linear
id: /P/H
next:
- /P/e
attributes:
bias: ''
outputSize: 4096
inputSize: 4096
- type: SpatialMaxPooling
id: /P/J
next:
- /P/A
attributes:
padW: 0
padH: 0
ceil_mode: false
dH: 2
dW: 2
kH: 3
kW: 3
- type: Dropout
id: /P/L
next:
- /P/H
attributes:
v1: ''
inplace: ''
p: 0.5
- type: View
id: /P/M
next:
- /P/6
attributes:
numInputDims: null
params: 9216
- type: SpatialConvolution
id: /P/R
id: /b/X
next:
- /P/i
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 256
nInputPlane: 256
- type: LogSoftMax
id: /P/S8
next: []
attributes: {}
- type: SpatialMaxPooling
id: /P/c
next:
- /P/0
attributes:
padW: 0
padH: 0
ceil_mode: false
dH: 2
dW: 2
kH: 3
kW: 3
- type: SpatialConvolution
id: /P/d
next:
- /P/q
attributes:
padH: 2
padW: 2
dH: 4
dW: 4
kH: 11
kW: 11
nOutputPlane: 64
nInputPlane: 3
- type: ReLU
id: /P/e
next:
- /P/8p
attributes:
p: ''
- type: SpatialConvolution
id: /P/fX
next:
- /P/F
- /b/o
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 1
padW: 1
dH: 1
@@ -156,39 +96,117 @@
kW: 3
nOutputPlane: 256
nInputPlane: 384
- type: ReLU
id: /P/i
- type: SpatialConvolution
id: /b/b
next:
- /P/n5
- /b/K
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 256
nInputPlane: 256
- type: View
id: /b/c
next:
- /b/v
attributes:
ctor_arg_order: params
params: 9216
- type: SpatialConvolution
id: /b/d
next:
- /b/q
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 2
padW: 2
dH: 4
dW: 4
kH: 11
kW: 11
nOutputPlane: 64
nInputPlane: 3
- type: LogSoftMax
id: /b/iW
next: []
attributes:
ctor_arg_order: ''
- type: ReLU
id: /b/o
next:
- /b/b
attributes:
ctor_arg_order: p
p: true
- type: ReLU
id: /P/j
- type: Linear
id: /b/oG
next:
- /P/c
- /b/iW
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 5
inputSize: 4096
- type: ReLU
id: /b/q
next:
- /b/U
attributes:
ctor_arg_order: p
p: true
- type: ReLU
id: /P/mQ
next:
- /P/L
attributes:
p: ''
- type: SpatialMaxPooling
id: /P/n5
id: /b/s
next:
- /P/M
- /b/I8
attributes:
padW: 0
padH: 0
ceil_mode: false
padW: ''
padH: ''
ctor_arg_order: 'kW,kH,dW,dH,padW,padH'
dH: 2
dW: 2
kH: 3
kW: 3
- type: ReLU
id: /P/q
- type: Dropout
id: /b/u4
next:
- /P/J
- /b/x
attributes:
p: true
v1: ''
inplace: ''
ctor_arg_order: 'p,v1,inplace'
p: 0.5
- type: Dropout
id: /b/v
next:
- /b/V
attributes:
v1: ''
inplace: ''
ctor_arg_order: 'p,v1,inplace'
p: 0.5
- type: SpatialMaxPooling
id: /b/w
next:
- /b/c
attributes:
padW: ''
padH: ''
ctor_arg_order: 'kW,kH,dW,dH,padW,padH'
dH: 2
dW: 2
kH: 3
kW: 3
- type: Linear
id: /b/x
next:
- /b/6
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 4096
inputSize: 4096
+217 -192
Ver Arquivo
@@ -1,8 +1,46 @@
- type: SpatialConvolution
id: /A/0
- type: ReLU
id: /V/1
next:
- /A/w
- /V/M
attributes:
ctor_arg_order: p
p: true
- type: Linear
id: /V/29
next:
- /V/s
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 10
inputSize: 4096
- type: Dropout
id: /V/3
next:
- /V/Q
attributes:
v1: ''
inplace: ''
ctor_arg_order: 'p,v1,inplace'
p: 0.5
- type: SpatialMaxPooling
id: /V/4
next:
- /V/o
attributes:
padW: ''
padH: ''
ctor_arg_order: 'kW,kH,dW,dH,padW,padH'
dH: 2
dW: 2
kH: 3
kW: 3
- type: SpatialConvolution
id: /V/6
next:
- /V/Z
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 1
padW: 1
dH: 1
@@ -11,171 +49,67 @@
kW: 3
nOutputPlane: 384
nInputPlane: 192
- type: LogSoftMax
id: /A/2
next: []
attributes: {}
- type: ReLU
id: /A/3
- type: SpatialBatchNormalization
id: /V/8
next:
- /A/H
- /V/R
attributes:
p: ''
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 64
- type: ReLU
id: /A/6
id: /V/F
next:
- /A/NJ
- /V/a
attributes:
ctor_arg_order: p
p: true
- type: SpatialMaxPooling
id: /A/7
- type: SpatialBatchNormalization
id: /V/G
next:
- /A/G
- /V/O
attributes:
padW: 0
padH: 0
ceil_mode: false
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 192
- type: ReLU
id: /V/H
next:
- /V/N
attributes:
ctor_arg_order: p
p: true
- type: Dropout
id: /V/Im
next:
- /V/iP
attributes:
v1: ''
inplace: ''
ctor_arg_order: 'p,v1,inplace'
p: 0.5
- type: SpatialMaxPooling
id: /V/M
next:
- /V/xK
attributes:
padW: ''
padH: ''
ctor_arg_order: 'kW,kH,dW,dH,padW,padH'
dH: 2
dW: 2
kH: 3
kW: 3
- type: BatchNormalization
id: /A/A
next:
- /A/r7
attributes:
momentum: ''
affine: ''
eps: 0.001
nOutput: 4096
- type: BatchNormalization
id: /A/B
next:
- /A/3
attributes:
momentum: ''
affine: ''
eps: 0.001
nOutput: 4096
- type: ReLU
id: /A/F
next:
- /A/q
attributes:
p: true
- type: View
id: /A/G
next:
- /A/a
attributes:
numInputDims: null
params: 9216
- type: Dropout
id: /A/H
next:
- /A/i
attributes:
v1: ''
inplace: ''
p: 0.5
- type: SpatialBatchNormalization
id: /A/I
next:
- /A/t
attributes:
momentum: ''
affine: ''
eps: 0.001
nOutput: 192
- type: Linear
id: /A/M
next:
- /A/B
attributes:
bias: ''
outputSize: 4096
inputSize: 9216
- type: SpatialConvolution
id: /A/NJ
id: /V/N
next:
- /A/PF
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 256
nInputPlane: 256
- type: SpatialBatchNormalization
id: /A/PF
next:
- /A/X
attributes:
momentum: ''
affine: ''
eps: 0.001
nOutput: 256
- type: ReLU
id: /A/X
next:
- /A/7
attributes:
p: true
- type: Dropout
id: /A/a
next:
- /A/M
attributes:
v1: ''
inplace: ''
p: 0.5
- type: ReLU
id: /A/d
next:
- /A/n
attributes:
p: true
- type: Linear
id: /A/h
next:
- /A/2
attributes:
bias: ''
outputSize: 10
inputSize: 4096
- type: Linear
id: /A/i
next:
- /A/A
attributes:
bias: ''
outputSize: 4096
inputSize: 4096
- type: SpatialBatchNormalization
id: /A/k
next:
- /A/6
attributes:
momentum: ''
affine: ''
eps: 0.001
nOutput: 256
- type: SpatialBatchNormalization
id: /A/l
next:
- /A/F
attributes:
momentum: ''
affine: ''
eps: 0.001
nOutput: 64
- type: SpatialConvolution
id: /A/n
next:
- /A/k
- /V/g
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 1
padW: 1
dH: 1
@@ -184,35 +118,19 @@
kW: 3
nOutputPlane: 256
nInputPlane: 384
- type: SpatialMaxPooling
id: /A/nm
- type: ReLU
id: /V/O
next:
- /A/0
- /V/k
attributes:
padW: 0
padH: 0
ceil_mode: false
dH: 2
dW: 2
kH: 3
kW: 3
- type: SpatialMaxPooling
id: /A/q
next:
- /A/y
attributes:
padW: 0
padH: 0
ceil_mode: false
dH: 2
dW: 2
kH: 3
kW: 3
ctor_arg_order: p
p: true
- type: SpatialConvolution
id: /A/r
id: /V/P
next:
- /A/l
- /V/8
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 2
padW: 2
dH: 4
@@ -221,32 +139,103 @@
kW: 11
nOutputPlane: 64
nInputPlane: 3
- type: ReLU
id: /A/r7
- type: Linear
id: /V/Q
next:
- /A/h
- /V/Qm
attributes:
p: ''
- type: ReLU
id: /A/t
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 4096
inputSize: 4096
- type: BatchNormalization
id: /V/Qm
next:
- /A/nm
attributes:
p: true
- type: SpatialBatchNormalization
id: /A/w
next:
- /A/d
- /V/t7
attributes:
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 4096
- type: ReLU
id: /V/R
next:
- /V/4
attributes:
ctor_arg_order: p
p: true
- type: SpatialBatchNormalization
id: /V/Z
next:
- /V/H
attributes:
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 384
- type: SpatialConvolution
id: /A/y
id: /V/a
next:
- /A/I
- /V/z
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 256
nInputPlane: 256
- type: BatchNormalization
id: /V/b
next:
- /V/t
attributes:
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 4096
- type: SpatialBatchNormalization
id: /V/g
next:
- /V/F
attributes:
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 256
- type: Linear
id: /V/iP
next:
- /V/b
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 4096
inputSize: 9216
- type: SpatialMaxPooling
id: /V/k
next:
- /V/6
attributes:
padW: ''
padH: ''
ctor_arg_order: 'kW,kH,dW,dH,padW,padH'
dH: 2
dW: 2
kH: 3
kW: 3
- type: SpatialConvolution
id: /V/o
next:
- /V/G
attributes:
ctor_arg_order: 'nInputPlane,nOutputPlane,kW,kH,dW,dH,padW,padH'
padH: 2
padW: 2
dH: 1
@@ -255,3 +244,39 @@
kW: 5
nOutputPlane: 192
nInputPlane: 64
- type: LogSoftMax
id: /V/s
next: []
attributes:
ctor_arg_order: ''
- type: ReLU
id: /V/t
next:
- /V/3
attributes:
p: ''
ctor_arg_order: p
- type: ReLU
id: /V/t7
next:
- /V/29
attributes:
p: ''
ctor_arg_order: p
- type: View
id: /V/xK
next:
- /V/Im
attributes:
ctor_arg_order: params
params: 9216
- type: SpatialBatchNormalization
id: /V/z
next:
- /V/1
attributes:
momentum: ''
affine: ''
ctor_arg_order: 'nOutput,eps,momentum,affine'
eps: 0.001
nOutput: 256
+63 -52
Ver Arquivo
@@ -1,76 +1,87 @@
- type: Reshape
id: /J/1
next:
- /J/5
attributes:
params: 100
- type: Linear
id: /J/5
id: /k/5
next:
- /J/x
- /k/a
attributes:
bias: ''
outputSize: 300
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 100
inputSize: 100
- type: Sigmoid
id: /J/F
next:
- /J/z
attributes: {}
- type: ReLU
id: /J/G
next:
- /J/q
attributes:
p: ''
- type: SoftMax
id: /J/Y
next: []
attributes: {}
- type: LeakyReLU
id: /J/c
next:
- /J/m
attributes:
negval: ''
ip: false
- type: Linear
id: /J/d
id: /k/6
next:
- /J/G
- /k/Y
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 100
inputSize: 300
- type: SoftMax
id: /k/O
next: []
attributes:
ctor_arg_order: ''
- type: Linear
id: /J/m
id: /k/S
next:
- /J/Y
- /k/y
attributes:
bias: ''
outputSize: 5
inputSize: 120
- type: Linear
id: /J/q
next:
- /J/F
attributes:
bias: ''
outputSize: 100
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 120
inputSize: 100
- type: RReLU
id: /J/x
- type: Linear
id: /k/V
next:
- /J/d
- /k/i
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 300
inputSize: 100
- type: ReLU
id: /k/Y
next:
- /k/5
attributes:
p: ''
ctor_arg_order: p
- type: Sigmoid
id: /k/a
next:
- /k/S
attributes:
ctor_arg_order: ''
- type: RReLU
id: /k/i
next:
- /k/6
attributes:
l: ''
u: ''
ip: false
ip: ''
ctor_arg_order: 'l,u,ip'
- type: Linear
id: /J/z
id: /k/p
next:
- /J/c
- /k/O
attributes:
bias: ''
outputSize: 120
inputSize: 100
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 5
inputSize: 120
- type: Reshape
id: /k/q
next:
- /k/V
attributes:
ctor_arg_order: params
params: 100
- type: LeakyReLU
id: /k/y
next:
- /k/p
attributes:
negval: ''
ip: ''
ctor_arg_order: 'negval,ip'
+15 -12
Ver Arquivo
@@ -1,29 +1,32 @@
- type: Reshape
id: /x/3
next:
- /x/K
attributes:
params: 100
- type: Linear
id: /x/K
id: /Q/E
next:
- /x/e
- /Q/e
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 300
inputSize: 100
- type: Linear
id: /x/N
id: /Q/Q
next: []
attributes:
bias: ''
ctor_arg_order: 'inputSize,outputSize,bias'
outputSize: 10
inputSize: 300
- type: HardTanh
id: /x/e
id: /Q/e
next:
- /x/N
- /Q/Q
attributes:
min_value: ''
max_value: 1
inplace: ''
ctor_arg_order: 'min_value,max_value'
- type: Reshape
id: /Q/j
next:
- /Q/E
attributes:
ctor_arg_order: params
params: 100
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff

Alguns arquivos não foram exibidos porque demasiados arquivos foram alterados neste diff Mostrar Mais