Comparar commits
75 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 1578886584 | |||
| 0927c2c270 | |||
| bd329bdfe3 | |||
| e3a499f409 | |||
| 63c78426d3 | |||
| 6ec2f69268 | |||
| 1ccd193ddd | |||
| a5d52dce33 | |||
| ca358ae7b9 | |||
| 0a1177c299 | |||
| 46bf346c5c | |||
| 8a94496e01 | |||
| d3cf339856 | |||
| 5c0c58c3be | |||
| ef607e0e76 | |||
| 305503ac7a | |||
| c76e62b976 | |||
| 554065ee11 | |||
| 7fba52ad97 | |||
| c56de24e7d | |||
| 6e16087fc3 | |||
| 8133acbb46 | |||
| d974cb8215 | |||
| 68021c1903 | |||
| 7178b89578 | |||
| 0935abe858 | |||
| 22225922e5 | |||
| 343f2ffa61 | |||
| 477d38d313 | |||
| 84e5377b8a | |||
| 1abbecc54c | |||
| af2f34545b | |||
| f7499c4599 | |||
| ad52fe7d70 | |||
| 5ddeb6f331 | |||
| 7cd3d961cf | |||
| c38b38b4a1 | |||
| 6ae73ece70 | |||
| b5512d8228 | |||
| 89c871412a | |||
| 33e28aa3f1 | |||
| 3899c3cb16 | |||
| eb4f97e9b5 | |||
| 16e37043f4 | |||
| 261ffd1eba | |||
| 9167b33e18 | |||
| 6f7f0d01e5 | |||
| c11b1fe812 | |||
| 306425cae1 | |||
| 6d70728b54 | |||
| fadb654883 | |||
| 6528bbdbc6 | |||
| 23852de607 | |||
| 9cf66a0e02 | |||
| ad19e0fb57 | |||
| 14f222bf6f | |||
| 95141d1a42 | |||
| 93aaf72372 | |||
| 47a6612ed0 | |||
| fe48af8bf4 | |||
| 78ca4f8762 | |||
| a7e08aa279 | |||
| e2980d616f | |||
| 96f2090d9e | |||
| 8a86a114db | |||
| cb757da118 | |||
| 31711e079a | |||
| 16ebb83ae6 | |||
| 65304b2645 | |||
| b44c6a104b | |||
| a8e5876f83 | |||
| 2d9d1e71c0 | |||
| 475bdfed50 | |||
| c36f12ccb2 | |||
| 0b8b5b8adf |
@@ -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!
|
||||
|
||||
|
||||
@@ -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
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
"LayerColors": {}
|
||||
},
|
||||
"BreadcrumbHeader": {
|
||||
"pathRule": "history"
|
||||
"pathRule": "history",
|
||||
"cachePrefix": "deepforge-header"
|
||||
},
|
||||
"FloatingActionButton": {
|
||||
"hideOnEmpty": true
|
||||
|
||||
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -22,3 +22,7 @@
|
||||
.create-node text {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.job-canceled {
|
||||
background-color: #ffe0b2;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
});
|
||||
@@ -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;
|
||||
});
|
||||
@@ -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 () {
|
||||
|
||||
@@ -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*/
|
||||
|
||||
/**
|
||||
|
||||
@@ -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]]);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
@@ -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 = `[0;31mFailed to execute operation: ${e}[0m`;
|
||||
|
||||
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 = `[0;31mFailed to execute operation: ${info.status}[0m`;
|
||||
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 %>
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
@@ -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]);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
+24
@@ -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'),
|
||||
|
||||
+18
-7
@@ -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() {
|
||||
|
||||
+20
-1
@@ -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 +0,0 @@
|
||||
{"http://localhost:8888":{}}
|
||||
+38
-28
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
local net = nn.Sequential()
|
||||
net:add(nn.Transpose({ 1, 2 }))
|
||||
net:add(nn.Transpose({ {1, 2}, {3, 4} }))
|
||||
|
||||
return net;
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
+1574
-1406
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
Referência em uma Nova Issue
Bloquear um usuário