Comparar commits

...

24 Commits

Autor SHA1 Mensagem Data
Brian Broll 3676d4c340 WIP Added istanbul 2016-10-02 09:04:17 -05:00
Brian Broll 16668468f4 Added boolean type check for attributes. Fixes #832 (#834) 2016-09-28 21:31:51 -05:00
Brian Broll ffae88a168 Set the exec status to 'running' on job restart. Fixes #831 (#833) 2016-09-28 21:27:45 -05:00
Brian Broll 25f5759c17 Cancel job if the exec has been canceled. Fixes #820 (#830)
* Cancel job if the exec has been canceled. Fixes #820

* WIP #820 Added test for stopping watching on cancel

* WIP #820 Increased the timeout for import torch
2016-09-27 19:28:57 -05:00
Brian Broll 7a0eae386f Added run.sh script to execution files. Fixes #818 (#829)
* WIP Added basic run.sh script creation

* WIP #818. Added baseURL... still needs work

* WIP #818 Added prompt for DEEPFORGE_URL and fixed wget issue
2016-09-27 15:01:51 -05:00
Brian Broll af5d74483a Added read-only tier of changes being applied. Fixes #826 (#827)
* Added read-only tier of changes being applied. Fixes #826

WIP #826 Updated currentChanges name. Added debugging

WIP #826 Added get/setAttr test for ExecJob

WIP #826 Added get/set attr tests

WIP #826 Added logs to try to figure out what on earth is going wrong

WIP #826 Fixed typo in test

WIP #826 Removed debugging logging

WIP #826 Enabled all tests

* WIP #826 Fixed code climate issue
2016-09-26 19:18:20 -05:00
Brian Broll 9bf7632aba Update README.md 2016-09-24 15:24:43 -05:00
Brian Broll d7f3544bb3 v0.16.0 2016-09-19 17:48:51 -05:00
Brian Broll 19a7b2a8fa Apply node creation/deletion before save. Fixes #824 (#825)
* WIP #824 Added extra logs

* WIP #824 Moved creation events to the local diff strategy

* WIP #824 Added deletion event to the local stored changes to apply

* WIP #824 Fixed variable name

* WIP #824 Fixed apply dependent creation changes

* WIP #824 Update local operation setAttr, getAttr

* WIP #824 Updated execpipeline save method

* WIP #824 Fixed code climate issue

I will probably remove all ArtifactFinder fn-ality

* WIP #824 Removed unused var

* WIP #824 update the meta on fast forward
2016-09-17 14:40:09 -05:00
Brian Broll aadd581189 Fixed regex for plotting negative numbers. Fixes #822 (#823) 2016-09-15 10:26:03 -05:00
Brian Broll a5d00efd39 Improved logo and icon legibility (#819)
WIP Changed logo font to "regular" for better legibility.

 WIP Changed node color on Icon

WIP CHANGED COLOR OF NODE TO MAKE MORE VISIBLE
2016-09-14 07:56:39 -05:00
Brian Broll a239c7bd44 Updated 'SGD' to graph error by default. Fixes #815 (#816) 2016-09-13 14:32:34 -05:00
Brian Broll 5871b5058e Better log-storage error handling on fork. Fixes #813 (#814)
WIP #813 Check if file exists before copy

WIP #813 Added test
2016-09-13 13:48:47 -05:00
Brian Broll 3a8108b321 Added deepforge.Image w/ update, title. Fixes #799 (#812)
WIP #799 Added deepforge.Image basics

WIP #799 deepforge.Image creates image

WIP #799 Fixed the image id creation

WIP #799 Don't reset zoom on image update

WIP #799 Added support for updating image names

WIP #799 Added id to deepforge.image

WIP #799 Fixed the simple image and log msg
2016-09-13 13:09:32 -05:00
Brian Broll b18a3b2747 Hide "monitor" button for Input/Outputs. Fixes #810 (#811) 2016-09-13 12:04:31 -05:00
Brian Broll 884ba2557f Delete executions w/ pipeline. Fixes #773 (#808)
WIP #773 Fixed deleting not loaded exec nodes
2016-09-13 11:23:23 -05:00
Brian Broll e2d3058de1 Added in-sync check for executions. Fixes #789 (#809) 2016-09-13 11:21:37 -05:00
Brian Broll 02739bfd62 Fixed saving race conditions in pipeline/job execution. Fixes #787 (#790)
* WIP #787 Fixing async race conditions in execs

* WIP #787 Fixed issues w/ the batched changes

* WIP #787 Added delAttribute
2016-09-13 10:18:38 -05:00
Brian Broll 89e2e387c7 Verified valid originIds before adding to territory. Fixes #753 (#807) 2016-09-13 08:28:45 -05:00
Brian Broll 0ac2b1b6ab Added deepforge.initialize(). Fixes #798 (#806)
WIP #798 Updated deepforge completer
2016-09-12 20:25:11 -05:00
Brian Broll a36e8df404 Added missing \n's to stdout. Fixes #804 (#805) 2016-09-11 20:26:01 -05:00
Brian Broll 93a89ddaa1 Fixed graph updating, express dependency Fixes #802 (#803)
WIP #802 Added express dependency

WIP #802 Added carriage return check to log-storage api

WIP #802 Fixed saving for graphs, images

Also fixed bug when using xlua progress bar w/ graphs
2016-09-11 13:33:51 -05:00
Brian Broll 7281dcefc6 Added log-storage for running jobs. Fixes #785 (#800)
WIP #785 Initial router commit

WIP #785 Added the log manager api

WIP #785 Added some comments for needed updates

WIP #785 Fixed typo in export

WIP #785 Added basic fn-ality to JobLogsClient

WIP #785 Added tests for the log router

WIP #785 uri encode project, branch. Updated viz to use the log-storage

WIP #785 Fixed updating on stdout update

WIP #785 Filtered out stdout update msgs from the notification widget

WIP #785 Added stdout save on canceled

WIP #785 Added tests for the joblogsclient

WIP #785 Moved job logs client to src/common

WIP #785 Added forking support to api

WIP #785 Added fork support for the job log client

WIP #785 Fixed flashing on canceled job

WIP #785 Fixed minor code climate issues

WIP #785 Create test-tmp on npm test
2016-09-10 17:34:36 -05:00
Brian Broll bfc1f08c7e Added 'net' to used var and fixed omitted vars. Fixes #795 (#796)
WIP #795 fixed the duplicate varnames

WIP #795 only omit last unset values

WIP #795 Replaced omitted, required values w/ nil

WIP #795 Updated tests
2016-09-09 16:47:42 -05:00
40 arquivos alterados com 2109 adições e 429 exclusões
+7 -1
Ver Arquivo
@@ -7,7 +7,13 @@
**Notice**: DeepForge is still a work in progress and is also lacking significant documentation! That being said, any contributions and/or feedback is greatly appreciated (and feel free to always ask any questions on the gitter)!
# DeepForge
DeepForge is an open-source visual development environment for deep learning. Currently, it supports Convolutional Neural Networks but we are planning on supporting additional deep learning classifiers such as RNNs and LSTMs. Additional features include real-time collaborative editing and version control.
DeepForge is an open-source visual development environment for deep learning. Currently, it supports Convolutional Neural Networks, RNNs and LSTMs as well as the creation of custom layers. Additional features include:
- Graphical architecture editor
- Training/testing pipeline creation
- Distributed pipeline execution
- Real-time pipeline feedback
- Collaborative editing
- Automatic version control.
## Quick Start
Simply run the following command to install deepforge with its dependencies:
+4 -2
Ver Arquivo
@@ -5,9 +5,11 @@
'use strict';
var config = require('./config.default');
var config = require('./config.default'),
path = require('path');
config.server.port = 9001;
config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_tests';
config.blob.fsDir = path.join(__dirname, '..', 'test-tmp', 'blob');
module.exports = config;
module.exports = config;
+22 -20
Ver Arquivo
@@ -6,33 +6,35 @@
var config = require('webgme/config/config.default'),
validateConfig = require('webgme/config/validator');
// The paths can be loaded from the webgme-setup.json
config.plugin.basePaths.push('src/plugins');
config.plugin.basePaths.push('node_modules/webgme-simple-nodes/src/plugins');
config.visualization.layout.basePaths.push('node_modules/webgme-chflayout/src/layouts');
config.visualization.decoratorPaths.push('src/decorators');
config.visualization.decoratorPaths.push('node_modules/webgme-easydag/src/decorators');
config.seedProjects.basePaths.push('src/seeds/nn');
config.seedProjects.basePaths.push('src/seeds/devTests');
config.seedProjects.basePaths.push('src/seeds/devUtilTests');
config.seedProjects.basePaths.push('src/seeds/pipeline');
config.seedProjects.basePaths.push('src/seeds/devPipelineTests');
config.seedProjects.basePaths.push('src/seeds/project');
config.seedProjects.basePaths.push('src/seeds/cifar10');
config.seedProjects.basePaths.push('src/seeds/xor');
config.plugin.basePaths.push(__dirname + '/../src/plugins');
config.plugin.basePaths.push(__dirname + '/../node_modules/webgme-simple-nodes/src/plugins');
config.visualization.layout.basePaths.push(__dirname + '/../node_modules/webgme-chflayout/src/layouts');
config.visualization.decoratorPaths.push(__dirname + '/../src/decorators');
config.visualization.decoratorPaths.push(__dirname + '/../node_modules/webgme-easydag/src/decorators');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/nn');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/devTests');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/devUtilTests');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/pipeline');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/devPipelineTests');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/project');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/cifar10');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/xor');
config.seedProjects.basePaths.push(__dirname + '/../src/seeds/devProject');
config.visualization.panelPaths.push('node_modules/webgme-fab/src/visualizers/panels');
config.visualization.panelPaths.push('node_modules/webgme-breadcrumbheader/src/visualizers/panels');
config.visualization.panelPaths.push('node_modules/webgme-autoviz/src/visualizers/panels');
config.visualization.panelPaths.push('node_modules/webgme-easydag/src/visualizers/panels');
config.visualization.panelPaths.push('src/visualizers/panels');
config.visualization.panelPaths.push(__dirname + '/../node_modules/webgme-fab/src/visualizers/panels');
config.visualization.panelPaths.push(__dirname + '/../node_modules/webgme-breadcrumbheader/src/visualizers/panels');
config.visualization.panelPaths.push(__dirname + '/../node_modules/webgme-autoviz/src/visualizers/panels');
config.visualization.panelPaths.push(__dirname + '/../node_modules/webgme-easydag/src/visualizers/panels');
config.visualization.panelPaths.push(__dirname + '/../src/visualizers/panels');
config.rest.components['execution/logs'] = __dirname + '/../src/routers/JobLogsAPI/JobLogsAPI.js';
// Visualizer descriptors
config.visualization.visualizerDescriptors.push('./src/visualizers/Visualizers.json');
config.visualization.visualizerDescriptors.push(__dirname + '/../src/visualizers/Visualizers.json');
// Add requirejs paths
config.requirejsPaths = {
'EllipseDecorator': 'node_modules/webgme-easydag/src/decorators/EllipseDecorator',
+5 -2
Ver Arquivo
@@ -8,15 +8,17 @@
"start-dev": "NODE_ENV=dev node app.js",
"local": "node ./bin/start-local.js",
"worker": "node ./bin/start-worker.js",
"test": "node ./node_modules/mocha/bin/mocha --recursive test",
"test": "mkdir ./test-tmp; node ./node_modules/mocha/bin/mocha --recursive test",
"test-cover": "node node_modules/istanbul/lib/cli.js --hook-run-in-context cover node_modules/mocha/bin/_mocha -- -R spec test/**/*",
"watch-test": "./node_modules/nodemon/bin/nodemon.js --exec 'node ./node_modules/mocha/bin/mocha --recursive test'",
"build-nn": "node ./utils/nn-parser.js"
},
"version": "0.15.0",
"version": "0.16.0",
"dependencies": {
"commander": "^2.9.0",
"dotenv": "^2.0.0",
"exists-file": "^2.1.0",
"express": "^4.14.0",
"lodash.difference": "^4.1.2",
"lodash.merge": "^4.5.1",
"nodemon": "^1.9.2",
@@ -34,6 +36,7 @@
"chai": "^3.0.0",
"jszip": "^2.5.0",
"mocha": "^2.2.5",
"istanbul": "^0.4.5",
"mockery": "^1.7.0"
}
}
+11 -2
Ver Arquivo
@@ -5,7 +5,13 @@ define({
// DeepForge metadata creation in dist execution
START_CMD: 'deepforge-cmd',
IMAGE: 'IMG',
IMAGE: { // all prefixed w/ 'IMG' for simple upload detection
PREFIX: 'IMG',
BASIC: 'IMG-B',
CREATE: 'IMG-C',
UPDATE: 'IMG-U',
NAME: 'IMAGE-N' // No upload required
},
GRAPH_CREATE: 'GRAPH',
GRAPH_PLOT: 'PLOT',
@@ -18,5 +24,8 @@ define({
OP: {
INPUT: 'Input',
OUTPUT: 'Output'
}
},
// Job stdout update
STDOUT_UPDATE: 'stdout_update'
});
+132
Ver Arquivo
@@ -0,0 +1,132 @@
/* globals define */
define([
'q',
'superagent'
], function(
Q,
superagent
) {
'use strict';
// Wrap the ability to read, update, and delete logs using the JobLogsAPI
var JobLogsClient = function(params) {
params = params || {};
this.logger = params.logger.fork('JobLogsClient');
// Get the server url
this.token = params.token;
this.origin = this._getServerUrl(params);
this.relativeUrl = '/execution/logs';
this.url = this.origin + this.relativeUrl;
this.logger.debug(`Setting url to ${this.url}`);
// Get the project, branch name
if (!(params.branchName && params.projectId)) {
throw Error('"branchName" and "projectId" required');
}
this.branch = params.branchName;
this.project = params.projectId;
this._modifiedJobs = [];
this.logger.debug(`Using <project>:<branch>: "${this.project}"/"${this.branch}"`);
this.logger.info('ctor finished');
};
JobLogsClient.prototype._getServerUrl = function(params) {
if (typeof window !== 'undefined') {
return window.location.origin;
}
// If not in browser, set using the params
var server = params.server || '127.0.0.1',
port = params.port || '80',
protocol = params.httpsecure ? 'https' : 'http'; // default is http
return params.origin || `${protocol}://${server}:${port}`;
};
// This method could be optimized - it could make a log of requests
JobLogsClient.prototype.fork = function(forkName) {
var jobIds = this._modifiedJobs,
deferred = Q.defer(),
url = [
this.url,
'migrate',
encodeURIComponent(this.project),
encodeURIComponent(this.branch),
encodeURIComponent(forkName)
].join('/'),
req = superagent.post(url);
this.logger.info(`migrating ${jobIds.length} jobs from ${this.branch} to ${forkName} in ${this.project}`);
if (this.token) {
req.set('Authorization', 'Bearer ' + this.token);
}
req.send({jobs: jobIds})
.end((err, res) => {
if (err || res.status > 399) {
return deferred.reject(err || res.status);
}
return deferred.resolve(res);
});
this.branch = forkName;
return deferred.promise;
};
JobLogsClient.prototype.getUrl = function(jobId) {
return [
this.url,
encodeURIComponent(this.project),
encodeURIComponent(this.branch),
encodeURIComponent(jobId)
].join('/');
};
JobLogsClient.prototype._logRequest = function(method, jobId, content) {
var deferred = Q.defer(),
req = superagent[method](this.getUrl(jobId));
this.logger.info(`sending ${method} request to ${this.getUrl(jobId)}`);
if (this.token) {
req.set('Authorization', 'Bearer ' + this.token);
}
if (content) {
req = req.send(content);
}
req.end((err, res) => {
if (err || res.status > 399) {
return deferred.reject(err || res.status);
}
return deferred.resolve(res);
});
return deferred.promise;
};
JobLogsClient.prototype.appendTo = function(jobId, text) {
this._modifiedJobs.push(jobId);
this.logger.info(`Appending logs to ${jobId}`);
return this._logRequest('patch', jobId, {patch: text});
};
JobLogsClient.prototype.getLog = function(jobId) {
this.logger.info(`Getting logs for ${jobId}`);
return this._logRequest('get', jobId)
.then(res => res.text);
};
JobLogsClient.prototype.deleteLog = function(jobId) {
this.logger.info(`Deleting logs for ${jobId}`);
return this._logRequest('delete', jobId);
};
return JobLogsClient;
});
+14 -19
Ver Arquivo
@@ -20,13 +20,13 @@ define([
var output = cntrs
.find(cntr => {
var metaNode = this.core.getMetaType(cntr),
metaName = this.core.getAttribute(metaNode, 'name');
metaName = this.getAttribute(metaNode, 'name');
return metaName === 'Outputs';
});
return this.core.loadChildren(output);
})
.then(dataNodes => {
hash = this.core.getAttribute(dataNodes[0], 'data');
hash = this.getAttribute(dataNodes[0], 'data');
return this.getOutputs(node);
})
.then(outputTuples => {
@@ -48,7 +48,7 @@ define([
var hash,
typeId = this.core.getPointerPath(node, 'type'),
type,
artifactName = this.core.getAttribute(node, 'artifactName');
artifactName = this.getAttribute(node, 'artifactName');
return this.core.loadByPath(this.rootNode, typeId)
.then(_type => {
@@ -58,25 +58,20 @@ define([
.then(saveDir => this.core.loadChildren(saveDir))
.then(artifacts => {
return artifacts.find(artifact =>
this.core.getAttribute(artifact, 'name') === artifactName &&
this.getAttribute(artifact, 'name') === artifactName &&
this.isMetaTypeOf(artifact, type));
})
.then(matchingArtifact => {
hash = matchingArtifact && this.core.getAttribute(matchingArtifact, 'data');
hash = matchingArtifact && this.getAttribute(matchingArtifact, 'data');
// If no hash, just continue (the subsequent ops will receive 'nil')
if (!hash) {
return this.onOperationComplete(node);
} else {
return this.getOutputs(node)
.then(outputPairs => {
var outputs = outputPairs.map(pair => pair[2]),
paths;
paths = outputs.map(output => this.core.getPath(output));
var outputs = outputPairs.map(pair => pair[2]);
// Get the 'data' hash and store it in the output data ports
this.logger.info(`Loading blob data (${hash}) to ${paths.map(p => `"${p}"`)}`);
outputs.forEach(output => this.core.setAttribute(output, 'data', hash));
outputs.forEach(output => this.setAttribute(output, 'data', hash));
this.onOperationComplete(node);
});
@@ -99,7 +94,7 @@ define([
if (containers.length > 1) {
saveDir = containers.find(c =>
this.core.getAttribute(c, 'name').toLowerCase().indexOf('artifacts') > -1
this.getAttribute(c, 'name').toLowerCase().indexOf('artifacts') > -1
) || containers[0];
}
@@ -121,8 +116,8 @@ define([
.then(artifacts => {
currNameHashPairs = artifacts
.map(node => [
this.core.getAttribute(node, 'name'),
this.core.getAttribute(node, 'data')
this.getAttribute(node, 'name'),
this.getAttribute(node, 'data')
]);
return this.getInputs(node);
})
@@ -142,9 +137,9 @@ define([
// Remove nodes that already exist
dataNodes = allDataNodes.filter(dataNode => {
var hash = this.core.getAttribute(dataNode, 'data'),
var hash = this.getAttribute(dataNode, 'data'),
name = this.core.getOwnAttribute(node, 'saveName') ||
this.core.getAttribute(dataNode, 'name');
this.getAttribute(dataNode, 'name');
return !(currNameHashPairs
.find(pair => pair[0] === name && pair[1] === hash));
@@ -156,10 +151,10 @@ define([
newName = this.core.getOwnAttribute(node, 'saveName');
if (newName) {
newNodes.forEach(node =>
this.core.setAttribute(node, 'name', newName)
this.setAttribute(node, 'name', newName)
);
}
var hashes = dataNodes.map(n => this.core.getAttribute(n, 'data'));
var hashes = dataNodes.map(n => this.getAttribute(n, 'data'));
this.logger.info(`saving hashes: ${hashes.map(h => `"${h}"`)}`);
} else if (allDataNodes.length === 0) {
this.logger.warn('No data nodes found!');
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 1.1 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 2.0 KiB

Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 3.1 KiB

Depois

Largura:  |  Altura:  |  Tamanho: 3.3 KiB

+39 -4
Ver Arquivo
@@ -1,7 +1,13 @@
/* globals define*/
define([
], function(
) {
(function(root, factory){
if(typeof define === 'function' && define.amd) {
define([], function(){
return (root.utils = factory());
});
} else if(typeof module === 'object' && module.exports) {
module.exports = (root.utils = factory());
}
}(this, function() {
var isBoolean = txt => {
return typeof txt === 'boolean' || (txt === 'false' || txt === 'true');
};
@@ -51,8 +57,37 @@ define([
}
};
// Resolving stdout
var resolveCarriageReturns = function(text) {
// 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('');
}
return lines;
};
return {
getSetterSchema: getSetterSchema,
resolveCarriageReturns: resolveCarriageReturns,
abbr: abbr
};
});
}));
+8
Ver Arquivo
@@ -38,6 +38,14 @@ define([
context.managerConfig.namespace = 'pipeline';
context.managerConfig.activeNode = node.getId();
method = opts.useSecondary ? 'runBrowserPlugin' : 'runServerPlugin';
if (method === 'runServerPlugin' &&
this.client.getBranchStatus() !== this.client.CONSTANTS.BRANCH_STATUS.SYNC) {
Materialize.toast('Cannot execute operations when client is out-of-sync', 2000);
return;
}
this.client[method](pluginId, context, (err, result) => {
var msg = err ? `${name} failed!` : `${name} executed successfully!`,
duration = err ? 4000 : 2000;
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+35 -3
Ver Arquivo
@@ -1,6 +1,13 @@
-- Instantiate the deepforge object
deepforge = {}
function deepforge.initialize()
require 'nn'
require 'rnn'
require './classes/init'
require './custom-layers'
end
function deepforge.id()
if __deepforge_id == nil then
__deepforge_id = 0
@@ -16,7 +23,7 @@ function deepforge._cmd(...)
for i=1,n do
cmd = cmd .. ' ' .. tostring(arg[i])
end
print(cmd)
print(cmd .. ' ') -- guarantee ends w/ space
end
-- Graph support
@@ -46,7 +53,7 @@ function Graph:line(name, opts)
end
-- Image support
function deepforge.image(name, tensor)
local function saveImage(name, tensor)
require 'image'
require 'paths'
@@ -59,7 +66,32 @@ function deepforge.image(name, tensor)
end
image.save(path, tensor)
deepforge._cmd("<%= IMAGE %>", name)
end
function deepforge.image(name, tensor)
saveImage(name, tensor)
deepforge._cmd("<%= IMAGE.BASIC %>", deepforge.id(), name)
end
Image = torch.class('deepforge.Image')
function Image:__init(name, tensor)
self.id = deepforge.id()
self.name = name
if tensor ~= nil then
saveImage(name, tensor)
deepforge._cmd('<%= IMAGE.CREATE %>', self.id, self.name)
end
end
function Image:update(tensor)
saveImage(self.name, tensor)
deepforge._cmd('<%= IMAGE.UPDATE %>', self.id, self.name)
end
function Image:title(name)
self.name = name
deepforge._cmd('<%= IMAGE.NAME %>', self.id, self.name)
end
return deepforge
+5 -8
Ver Arquivo
@@ -1,15 +1,12 @@
-- load custom layers
require './custom-layers'
-- load custom class definitions
require './classes'
-- load custom layers and classes
deepforge.initialize()
-- input data<% inputs.forEach(function(pair) { var input = pair[0], isNil = pair[1];%>
<%= isNil ? 'local ' : ''%><%= input %> = <% if (isNil) { %>nil<% } else { %>require './inputs/<%= input %>'<%}}); %>
local <%= input %> = <% if (isNil) { %>nil<% } else { %>require './inputs/<%= input %>'<%}}); %>
-- load references<% pointers.forEach(function(pair) { var pointer = pair[0], isNil = pair[1];%>
<%= isNil ? 'local ' : ''%><%= pointer %> = <% if (isNil) { %>nil<% } else { %>require './pointers/<%= pointer %>'<%}}); %>
attributes = require './attributes'
local <%= pointer %> = <% if (isNil) { %>nil<% } else { %>require './pointers/<%= pointer %>'<%}}); %>
local attributes = require './attributes'
-- main operation code for <%= name %>
<%= code %>
+2 -2
Ver Arquivo
@@ -12,7 +12,7 @@ var spawn = require('child_process').spawn,
// Get the BlobClient...
var COMMAND_PREFIX = '<%= START_CMD %>',
IMAGE = '<%= IMAGE %>',
IMAGE = '<%= IMAGE.PREFIX %>',
requirejs = require('webgme').requirejs,
remainingImageCount = 0,
exitCode = null;
@@ -80,7 +80,7 @@ requirejs([
var uploadImage = function(line) {
var args = line.split(/\s+/),
name = args.slice(2).join(' ').replace(/\s+$/, ''),
name = args.slice(3).join(' ').replace(/\s+$/, ''),
filename = 'metadata/' + name + '.png';
// Upload the image from metadata/
+36 -16
Ver Arquivo
@@ -4,6 +4,7 @@
define([
'plugin/CreateExecution/CreateExecution/CreateExecution',
'plugin/ExecuteJob/ExecuteJob/ExecuteJob',
'deepforge/JobLogsClient',
'common/storage/constants',
'common/core/constants',
'q',
@@ -12,6 +13,7 @@ define([
], function (
CreateExecution,
ExecuteJob,
JobLogsClient,
STORAGE_CONSTANTS,
CONSTANTS,
Q,
@@ -34,6 +36,11 @@ define([
this.pluginMetadata = pluginMetadata;
this._currentSave = Q();
this.changes = {};
this.currentChanges = {}; // read-only changes being applied
this.creations = {};
this.deletions = [];
this.createIdToMetadataId = {};
this.initRun();
};
@@ -101,7 +108,7 @@ 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.logger.debug(`Finished creating execution "${this.getAttribute(execNode, 'name')}"`);
this.activeNode = execNode;
});
} else if (this.core.isTypeOf(this.activeNode, this.META.Execution)) {
@@ -111,6 +118,13 @@ define([
return callback('Current node is not a Pipeline or Execution!', this.result);
}
// Get the gmeConfig...
this.logManager = new JobLogsClient({
logger: this.logger,
port: this.gmeConfig.server.port,
branchName: this.branchName,
projectId: this.projectId
});
this._callback = callback;
this.currentForkName = null;
@@ -120,7 +134,7 @@ define([
var children = subtree
.filter(n => this.core.getParent(n) === this.activeNode);
this.pipelineName = this.core.getAttribute(this.activeNode, 'name');
this.pipelineName = this.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');
@@ -139,11 +153,13 @@ define([
// before continuing
this._currentSave = this._currentSave
.then(() => this.updateForkName(this.pipelineName))
.then(() => this.applyModelChanges())
.then(() => CreateExecution.prototype.save.call(this, msg))
.then(result => {
var msg;
if (result.status === STORAGE_CONSTANTS.FORKED) {
this.currentForkName = result.forkName;
this.logManager.fork(result.forkName);
msg = `"${this.pipelineName}" execution has forked to "${result.forkName}"`;
this.sendNotification(msg);
} else if (result.status === STORAGE_CONSTANTS.MERGED) {
@@ -173,6 +189,10 @@ define([
});
};
ExecutePipeline.prototype.isExecutionCanceled = function () {
return this.getAttribute(this.activeNode, 'status') === 'canceled';
};
ExecutePipeline.prototype.isInputData = function (node) {
var prnt = this.core.getParent(node);
return this.core.isTypeOf(prnt, this.META.Inputs);
@@ -192,14 +212,14 @@ define([
nodes.filter(node => this.core.isTypeOf(node, this.META.Job))
.forEach(node => {
this.recordOldMetadata(node);
this.core.setAttribute(node, 'status', 'pending');
this.setAttribute(node, 'status', 'pending');
});
// Set the status of the execution to 'running'
this.core.setAttribute(this.activeNode, 'status', 'running');
this.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.setAttribute(this.activeNode, 'startTime', Date.now());
this.core.delAttribute(this.activeNode, 'endTime');
return this.save(`Initializing ${this.pipelineName} for execution`);
};
@@ -291,24 +311,24 @@ define([
ExecutePipeline.prototype.onOperationFail = function(node, err) {
var job = this.core.getParent(node),
id = this.core.getPath(node),
name = this.core.getAttribute(node, 'name');
name = this.getAttribute(node, 'name');
this.logger.debug(`Operation ${name} (${id}) failed: ${err}`);
this.core.setAttribute(job, 'status', 'fail');
this.setAttribute(job, 'status', 'fail');
this.clearOldMetadata(job);
this.onPipelineComplete(err);
};
ExecutePipeline.prototype.onOperationCanceled = function(op) {
var job = this.core.getParent(op);
this.core.setAttribute(job, 'status', 'canceled');
this.setAttribute(job, 'status', 'canceled');
this.runningJobs--;
this.logger.debug(`${this.core.getAttribute(job, 'name')} has been canceled`);
this.logger.debug(`${this.getAttribute(job, 'name')} has been canceled`);
this.onPipelineComplete();
};
ExecutePipeline.prototype.onPipelineComplete = function(err) {
var name = this.core.getAttribute(this.activeNode, 'name'),
var name = this.getAttribute(this.activeNode, 'name'),
msg = `"${this.pipelineName}" `;
if (err) {
@@ -342,8 +362,8 @@ define([
if (!isDeleted) {
this.logger.debug(`Pipeline "${name}" complete!`);
this.core.setAttribute(this.activeNode, 'endTime', Date.now());
this.core.setAttribute(this.activeNode, 'status',
this.setAttribute(this.activeNode, 'endTime', Date.now());
this.setAttribute(this.activeNode, 'status',
(this.pipelineError ? 'failed' :
(this.canceled ? 'canceled' : 'success')
)
@@ -420,7 +440,7 @@ define([
};
ExecutePipeline.prototype.onOperationComplete = function (opNode) {
var name = this.core.getAttribute(opNode, 'name'),
var name = this.getAttribute(opNode, 'name'),
nextPortIds = this.getOperationOutputIds(opNode),
jNode = this.core.getParent(opNode),
resultPorts,
@@ -430,7 +450,7 @@ define([
// Set the operation to 'success'!
this.clearOldMetadata(jNode);
this.runningJobs--;
this.core.setAttribute(jNode, 'status', 'success');
this.setAttribute(jNode, 'status', 'success');
this.logger.info(`Setting ${jobId} status to "success"`);
this.logger.info(`There are now ${this.runningJobs} running jobs`);
this.logger.debug(`Making a commit from ${this.currentHash}`);
@@ -449,11 +469,11 @@ define([
.forEach(pair => { // [ resultPort, nextPort ]
var result = pair[0],
next = pair[1],
hash = this.core.getAttribute(result, 'data');
hash = this.getAttribute(result, 'data');
this.logger.info(`forwarding data (${hash}) from ${this.core.getPath(result)} ` +
`to ${this.core.getPath(next)}`);
this.core.setAttribute(next, 'data', hash);
this.setAttribute(next, 'data', hash);
this.logger.info(`Setting ${jobId} data to ${hash}`);
});
@@ -46,7 +46,7 @@ define([
this.addCustomLayersToMeta();
this.LayerDict = createLayerDict(this.core, this.META);
this.uniqueId = 2;
this.varnames = {};
this.varnames = {net: true};
return PluginBase.prototype.main.apply(this, arguments);
};
@@ -247,17 +247,27 @@ define([
base = layer[Constants.BASE],
desc,
fn,
layerCode;
layerCode,
args,
i;
this.logger.debug(`Creating arg string for ${layer.name}`);
layerCode = '(' + this.LayerDict[layer.name].args
.map(arg => this.getValue(arg.name, layer))
.filter(GenerateArchitecture.isSet)
args = this.LayerDict[layer.name].args
.map(arg => this.getValue(arg.name, layer));
for (i = args.length; i--;) {
if (GenerateArchitecture.isSet(args[i])) {
break;
}
args.pop();
}
layerCode = '(' + args.map(arg => GenerateArchitecture.isSet(arg) ? arg : 'nil')
.join(', ') + ')';
// Add any setters
// For each setter, check if it has been changed (and needs to be set)
for (var i = setterNames.length; i--;) {
for (i = setterNames.length; i--;) {
desc = setters[setterNames[i]];
if (desc.setterType === 'const') {
// if the value is not the default, add the given fn
+149
Ver Arquivo
@@ -0,0 +1,149 @@
var path = require('path'),
Q = require('q'),
fs = require('fs'),
exists = require('exists-file'),
utils = require('../../common/utils'),
NO_LOG_FOUND = '';
var JobLogManager = function(logger, config) {
this.rootDir = path.join(config.blob.fsDir, 'log-storage');
this.logger = logger.fork('JobLogManager');
this._onCopyFinished = {};
};
JobLogManager.prototype._getFilePath = function(jInfo) {
this.logger.debug(`getting file path for ${jInfo.job} in ${jInfo.project} on ${jInfo.branch}`);
var jobId = jInfo.job.replace(/\//g, '_'),
filename = `${jobId}.txt`;
return path.join(this.rootDir, jInfo.project, jInfo.branch, filename);
};
JobLogManager.prototype.exists = function(jobInfo) {
var filename = this._getFilePath(jobInfo);
return Q.nfcall(exists, filename);
};
JobLogManager.prototype.mkdirIfNeeded = function(dir) {
return Q.nfcall(exists, dir).then(exist => {
if (!exist) {
this.logger.debug('making dir:', dir);
return Q.nfcall(fs.mkdir, dir)
.catch(() => this.logger.debug(`dir already created: ${dir}`));
}
});
};
JobLogManager.prototype._copyFile = function(src, dst) {
return Q.nfcall(exists, src).then(exists => {
if (!exists) {
this.logger.warn(`Cannot copy file from ${src}. File doesn't exist!`);
return;
}
return this.mkdirIfNeeded(path.dirname(dst)).then(() => {
var deferred = Q.defer(),
stream = fs.createReadStream(src).pipe(fs.createWriteStream(dst));
stream.on('error', deferred.reject);
stream.on('finish', deferred.resolve);
return deferred.promise;
});
});
};
// Copy one branch info to the next
// Could optimize this to symlink until data appended...
JobLogManager.prototype.migrate = function(migrationInfo, jobIds) {
// Recursively copy the srcBranch dir to the dstBranch dir
// Should probably use streams...
// Need to block appends to the given files so they are not written
// to until they have finished copying...
// TODO
var jobs,
src,
dst,
i;
for (i = jobIds.length; i--;) {
this._onCopyFinished[jobIds[i]] = [];
}
// Copy the job files and evaluate each of the finish functions
this.logger.info('migrating from ' + migrationInfo.srcBranch + ' to '+ migrationInfo.dstBranch);
return Q.all(jobIds.map(jobId => {
src = this._getFilePath({
project: migrationInfo.project,
branch: migrationInfo.srcBranch,
job: jobId
});
dst = this._getFilePath({
project: migrationInfo.project,
branch: migrationInfo.dstBranch,
job: jobId
});
return this._copyFile(src, dst).then(() => {
jobs = this._onCopyFinished[jobId];
for (var j = jobs.length; j--;) {
jobs[j]();
}
});
}));
};
JobLogManager.prototype._appendTo = function(filename, logs) {
return Q.nfcall(exists, filename).then(exists => {
var promise = Q().then(() => '');
if (exists) {
promise = Q.nfcall(fs.readFile, filename, 'utf8');
}
return promise.then(content => {
// This could be optimized to not re-read/write the whole file each time...
var lines = utils.resolveCarriageReturns(content + logs);
return Q.nfcall(fs.writeFile, filename, lines.join('\n'));
});
});
};
JobLogManager.prototype.appendTo = function(jobInfo, logs) {
var filename = this._getFilePath(jobInfo),
branchDirname = path.dirname(filename),
projDirname = path.dirname(branchDirname);
this.logger.info(`Appending content to ${filename}`);
// Make directory if needed
return this.mkdirIfNeeded(this.rootDir)
.then(() => this.mkdirIfNeeded(projDirname))
.then(() => this.mkdirIfNeeded(branchDirname))
.then(() => this._appendTo(filename, logs));
};
JobLogManager.prototype.getLog = function(jobInfo) {
var filename = this._getFilePath(jobInfo);
this.logger.info(`Getting log content from ${filename}`);
return this.exists(jobInfo)
.then(exists => {
if (exists) {
return Q.nfcall(fs.readFile, filename);
}
return NO_LOG_FOUND;
});
};
JobLogManager.prototype.delete = function(jobInfo) {
var filename = this._getFilePath(jobInfo);
return this.exists(jobInfo)
.then(exists => {
if (exists) {
this.logger.debug(`Removing file ${filename}`);
return Q.nfcall(fs.unlink, filename);
}
this.logger.info(`${filename} doesn't exist. No need to delete...`);
});
};
module.exports = JobLogManager;
+93
Ver Arquivo
@@ -0,0 +1,93 @@
/*jshint node:true*/
'use strict';
var express = require('express'),
JobLogManager = require('./JobLogManager'),
router = express.Router();
/**
* Called when the server is created but before it starts to listening to incoming requests.
* N.B. gmeAuth, safeStorage and workerManager are not ready to use until the start function is called.
* (However inside an incoming request they are all ensured to have been initialized.)
*
* @param {object} middlewareOpts - Passed by the webgme server.
* @param {GmeConfig} middlewareOpts.gmeConfig - GME config parameters.
* @param {GmeLogger} middlewareOpts.logger - logger
* @param {function} middlewareOpts.ensureAuthenticated - Ensures the user is authenticated.
* @param {function} middlewareOpts.getUserId - If authenticated retrieves the userId from the request.
* @param {object} middlewareOpts.gmeAuth - Authorization module.
* @param {object} middlewareOpts.safeStorage - Accesses the storage and emits events (PROJECT_CREATED, COMMIT..).
* @param {object} middlewareOpts.workerManager - Spawns and keeps track of "worker" sub-processes.
*/
function initialize(middlewareOpts) {
var logger = middlewareOpts.logger.fork('JobLogsAPI'),
ensureAuthenticated = middlewareOpts.ensureAuthenticated,
gmeConfig = middlewareOpts.gmeConfig,
logManager = new JobLogManager(logger, gmeConfig);
logger.debug('initializing ...');
// Ensure authenticated can be used only after this rule.
router.use('*', function (req, res, next) {
// This header ensures that any failures with authentication won't redirect.
res.setHeader('X-WebGME-Media-Type', 'webgme.v1');
next();
});
// Use ensureAuthenticated if the routes require authentication. (Can be set explicitly for each route.)
router.use('*', ensureAuthenticated);
router.get('/:project/:branch/:job', function (req, res/*, next*/) {
// Retrieve the job logs for the given job
logManager.getLog(req.params).then(log => {
res.set('Content-Type', 'text/plain');
res.send(log);
});
});
router.patch('/:project/:branch/:job', function (req, res/*, next*/) {
var logs = req.body.patch;
logger.info(`Received append request for ${req.params.job} in ${req.params.project}`);
logManager.appendTo(req.params, logs)
.then(() => res.send('Append successful'))
.catch(err => logger.error(`Append failed: ${err}`));
});
router.delete('/:project/:branch/:job', function (req, res/*, next*/) {
logManager.delete(req.params).then(() => res.send('delete successful'));
});
router.post('/migrate/:project/:srcBranch/:dstBranch', function (req, res/*, next*/) {
var jobs = req.body.jobs;
logManager.migrate(req.params, jobs)
.then(() => res.send('migration successful'))
.fail(err => logger.error(err));
});
logger.debug('ready');
}
/**
* Called before the server starts listening.
* @param {function} callback
*/
function start(callback) {
callback();
}
/**
* Called after the server stopped listening.
* @param {function} callback
*/
function stop(callback) {
callback();
}
module.exports = {
initialize: initialize,
router: router,
start: start,
stop: stop
};
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
@@ -161,7 +161,9 @@ define([
desc.abbr = this.getUniqAbbreviation(desc);
// Create a territory for this origin and update it!
this._selfPatterns[desc.originId] = {children: 0};
if (desc.originId) {
this._selfPatterns[desc.originId] = {children: 0};
}
setTimeout(() => this._client.updateTerritory(this._territoryId, this._selfPatterns), 0);
} else if (type === 'Line') {
desc = this.getLineDesc(node);
@@ -0,0 +1,28 @@
/* globals define */
// A notification widget which filters out stdout update notifications
define([
'deepforge/Constants',
'js/Widgets/Notification/NotificationWidget'
], function(
CONSTANTS,
GmeNotificationWidget
) {
var NotificationWidget = function() {
GmeNotificationWidget.apply(this, arguments);
};
NotificationWidget.prototype = Object.create(GmeNotificationWidget.prototype);
NotificationWidget.prototype.isUserNotication = function(data) {
return data.message.indexOf(CONSTANTS.STDOUT_UPDATE) === -1;
};
NotificationWidget.prototype._refreshNotifications = function(eventData) {
if (this.isUserNotication(eventData)) {
GmeNotificationWidget.prototype._refreshNotifications.call(this, eventData);
}
};
return NotificationWidget;
});
+9 -10
Ver Arquivo
@@ -1,8 +1,5 @@
/*globals define, _, WebGMEGlobal, $ */
/*jshint browser: true*/
/**
* @author rkereskenyi / https://github.com/rkereskenyi
*/
define([
'js/PanelBase/PanelBase',
@@ -10,13 +7,15 @@ define([
'js/Widgets/BranchStatus/BranchStatusWidget',
'js/Widgets/BranchSelector/BranchSelectorWidget',
'js/Widgets/KeyboardManager/KeyboardManagerWidget',
'js/Widgets/Notification/NotificationWidget'
], function (PanelBase,
NetworkStatusWidget,
BranchStatusWidget,
BranchSelectorWidget,
KeyboardManagerWidget,
NotificationWidget) {
'./FilteredNotificationWidget'
], function (
PanelBase,
NetworkStatusWidget,
BranchStatusWidget,
BranchSelectorWidget,
KeyboardManagerWidget,
NotificationWidget
) {
'use strict';
@@ -2,9 +2,18 @@
/*jshint browser: true*/
// This is a read-only view of the 'stdout' attribute for a Job node
// if the job is running, get the logs from the log-storage
define([
'q',
'deepforge/JobLogsClient',
'js/Constants',
'deepforge/Constants',
'panels/TextEditor/TextEditorControl'
], function (
Q,
JobLogsClient,
GME_CONSTANTS,
CONSTANTS,
TextEditorControl
) {
@@ -19,11 +28,68 @@ define([
_.extend(LogViewerControl.prototype, TextEditorControl.prototype);
LogViewerControl.prototype.getFullDescriptor = function (id) {
var desc = LogViewerControl.prototype._getObjectDescriptor.call(this, id);
return this._getRunningLogs(id).then(text => {
// Use attribute or running log if none
desc.text = desc.text || text;
return desc;
});
};
LogViewerControl.prototype.getUpdatedJobId = function (msg) {
// verify that it is the given notification type
if (msg.indexOf(CONSTANTS.STDOUT_UPDATE) !== -1) {
return msg.replace(/^[^\/]*\//, '');
}
};
LogViewerControl.prototype.selectedObjectChanged = function (id) {
TextEditorControl.prototype.selectedObjectChanged.call(this, id);
// Listen for notifications about updated logs
this.removeNotificationHandler();
this.notificationHandler = (sender, data) => {
var nodeId = this.getUpdatedJobId(data.message);
if (nodeId === id) {
this._onUpdate(id);
}
};
this._client.addEventListener(GME_CONSTANTS.CLIENT.NOTIFICATION, this.notificationHandler);
};
LogViewerControl.prototype.removeNotificationHandler = function () {
// Remove the notifications listener
if (this.notificationHandler) {
this._client.removeEventListener();
this.notificationHandler = null;
}
};
LogViewerControl.prototype.destroy = function () {
TextEditorControl.prototype.destroy.call(this);
this.removeNotificationHandler();
};
LogViewerControl.prototype._onLoad = function (id) {
this.getFullDescriptor(id).then(desc => this._widget.addNode(desc));
};
LogViewerControl.prototype._onUpdate = function (id) {
if (id === this._currentNodeId) {
TextEditorControl.prototype._onUpdate.call(this, id);
this.getFullDescriptor(id).then(desc => this._widget.updateNode(desc));
}
};
LogViewerControl.prototype._getRunningLogs = function (id) {
var logManager = new JobLogsClient({
logger: this._logger,
projectId: this._client.getActiveProjectId(),
branchName: this._client.getActiveBranchName()
});
return logManager.getLog(id);
};
return LogViewerControl;
});
@@ -33,12 +33,33 @@ define([
this._widget.deletePipeline = id => {
var node = this._client.getNode(id),
name = node.getAttribute('name'),
msg = `Deleting pipeline "${name}"`;
msg = `Deleting pipeline "${name}"`,
delTerritory = {},
delUI,
ids = [id];
// Change the current active object
this._client.startTransaction(msg);
this._client.delMoreNodes([id]);
this._client.completeTransaction();
// Delete all associated executions
ids = node.getMemberIds('executions');
for (var i = ids.length; i--;) {
delTerritory[ids[i]] = {children: 0};
}
delUI = this._client.addUI(this, events => {
var ids = [id];
for (i = events.length; i--;) {
if (events[i].eid && events[i].etype === CONSTANTS.TERRITORY_EVENT_LOAD) {
ids.push(events[i].eid);
}
}
this._client.startTransaction(msg);
this._client.delMoreNodes(ids);
this._client.completeTransaction();
this._client.removeUI(delUI);
});
this._client.updateTerritory(delUI, delTerritory);
};
this._widget.setName = (id, name) => {
@@ -3,10 +3,12 @@
define([
'widgets/EasyDAG/SelectionManager',
'widgets/EasyDAG/Buttons',
'deepforge/Constants',
'underscore'
], function(
EasyDAGSelectionManager,
Buttons,
CONSTANTS,
_
) {
'use strict';
@@ -18,16 +20,19 @@ define([
_.extend(SelectionManager.prototype, EasyDAGSelectionManager.prototype);
SelectionManager.prototype.createActionButtons = function(width/*, height*/) {
// Add 'watch' and 'jumpToDef' buttons
// TODO
new Buttons.Enter({
context: this._widget,
$pEl: this.$selection,
item: this.selectedItem,
icon: 'monitor',
x: width,
y: 0
});
var jobName = this.selectedItem.desc.name;
// Check if it is an Input or Output job
if (jobName !== CONSTANTS.OP.INPUT && jobName !== CONSTANTS.OP.OUTPUT) {
new Buttons.Enter({
context: this._widget,
$pEl: this.$selection,
item: this.selectedItem,
icon: 'monitor',
x: width,
y: 0
});
}
};
return SelectionManager;
@@ -82,7 +82,6 @@ define([
ImageViewerWidget.prototype.updateImage = function (url) {
url = url || NO_IMAGE_URL;
this.zoom = 1;
this.$image.attr('src', url);
};
@@ -1,6 +1,7 @@
{
"deepforge": [
"Graph",
"initialize",
"image"
],
"torch": [
+138
Ver Arquivo
@@ -0,0 +1,138 @@
var testFixture = require('../globals'),
expect = testFixture.expect,
assert = require('assert'),
path = testFixture.path,
gmeConfig = testFixture.getGmeConfig(),
blobDir = gmeConfig.blob.fsDir,
server = testFixture.WebGME.standaloneServer(gmeConfig),
Logger = require('webgme/src/server/logger'),
logger = Logger.createWithGmeConfig('gme', gmeConfig, true),
JobLogsClient = testFixture.requirejs('deepforge/JobLogsClient'),
rm_rf = require('rimraf'),
exists = require('exists-file');
describe('JobLogsClient', function() {
var logClient = new JobLogsClient({
logger: logger,
origin: server.getUrl(),
projectId: 'testProject',
branchName: 'master'
}),
jobId = '/4/q/l',
firstLog = 'hello world';
before(function(done) {
testFixture.mkdir(blobDir);
server.start(done);
});
after(function(done) {
rm_rf.sync(blobDir);
server.stop(done);
});
describe('appendTo', function() {
before(function(done) {
logClient.appendTo(jobId, firstLog)
.then(() => done())
.catch(err => done(err));
});
it('should create job-logs directory', function() {
assert(exists.sync(path.join(blobDir, 'log-storage')));
});
describe('getLog', function() {
it('should return the logs from the job', function(done) {
logClient.getLog(jobId).then(log => {
expect(log).to.contain(firstLog);
done();
});
});
it('should append additional logs to the file', function(done) {
var secondLog = 'goodbye world';
logClient.appendTo(jobId, secondLog)
.then(() => logClient.getLog(jobId))
.then(log => {
expect(log).to.contain(secondLog);
done();
});
});
});
});
describe('delete', function() {
var delJobId = '/4/8/l';
before(function(done) {
logClient.appendTo(delJobId, firstLog).then(() => done());
});
it('should delete the file from job-logs directory', function(done) {
logClient.deleteLog(delJobId)
.then(() => logClient.getLog(delJobId))
.then(log => {
expect(log).to.equal('');
done();
});
});
});
describe('migration', function() {
var client,
jId = '/asd/4/q',
logs = 'asdfasde',
newBranch = 'otherBranch';
before(function(done) {
client = new JobLogsClient({
logger: logger,
origin: server.getUrl(),
projectId: 'migTest',
branchName: 'master'
});
// Write logs to job
client.appendTo(jId, logs)
.then(() => client.fork(newBranch))
.catch(err => done(err))
.then(() => done());
});
it('should migrate the edited nodes to the new branch', function(done) {
client.getLog(jId).then(log => {
expect(log).to.equal(logs);
done();
});
});
describe('new logs', function() {
it('should not edit old job logs', function() {
var c2 = new JobLogsClient({
logger: logger,
origin: server.getUrl(),
projectId: 'migTest',
branchName: 'master'
});
c2.getLog(jId).then(log => {
expect(log).to.equal(logs);
done();
});
});
it('should write new logs', function() {
client.appendTo(jId, 'moreStuff')
.then(() => client.getLog(jId))
.then(log => {
expect(log).to.contain('moreStuff');
done();
});
});
});
// TODO: Test that, on a fork, the logClient will copy all the current jobs to
// the new fork name
});
});
+17
Ver Arquivo
@@ -7,6 +7,9 @@
'use strict';
var testFixture = require('webgme/test/_globals'),
path = require('path'),
fs = require('fs'),
exists = require('exists-file'),
WEBGME_CONFIG_PATH = '../config';
// This flag will make sure the config.test.js is being used
@@ -34,4 +37,18 @@ testFixture.requirejs.config({
testFixture.getGmeConfig = getGmeConfig;
testFixture.DF_SEED_DIR = testFixture.path.join(__dirname, '..', 'src', 'seeds');
testFixture.mkdir = function(dir) {
var dirs = path.resolve(dir).split(path.sep),
shortDir,
i = 1;
while (i++ < dirs.length) {
shortDir = dirs.slice(0,i).join(path.sep);
if (!exists.sync(shortDir)) {
fs.mkdirSync(shortDir);
}
}
};
module.exports = testFixture;
+285 -4
Ver Arquivo
@@ -10,12 +10,14 @@ describe('ExecuteJob', function () {
PluginCliManager = testFixture.WebGME.PluginCliManager,
projectName = 'testProject',
pluginName = 'ExecuteJob',
manager = new PluginCliManager(null, logger, gmeConfig),
project,
gmeAuth,
storage,
commitHash;
before(function (done) {
this.timeout(10000);
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
@@ -25,7 +27,7 @@ describe('ExecuteJob', function () {
})
.then(function () {
var importParam = {
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'EmptyProject.webgmex'),
projectSeed: testFixture.path.join(testFixture.DF_SEED_DIR, 'devProject', 'devProject.webgmex'),
projectName: projectName,
branchName: 'master',
logger: logger,
@@ -51,9 +53,7 @@ describe('ExecuteJob', function () {
});
it('should verify activeNode is "Job"', function (done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
var pluginConfig = {},
context = {
project: project,
commitHash: commitHash,
@@ -68,4 +68,285 @@ describe('ExecuteJob', function () {
done();
});
});
////////// Helper Functions //////////
var plugin,
node,
preparePlugin = function(done) {
var context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/K/R/p' // hello world job
};
return manager.initializePlugin(pluginName)
.then(plugin_ => {
plugin = plugin_;
return manager.configurePlugin(plugin, {}, context);
})
.then(() => node = plugin.activeNode)
.nodeify(done);
};
////////// END Helper Functions //////////
// Race condition checks w/ saving...
describe('get/set', function() {
beforeEach(preparePlugin);
it('should get correct attribute after set', function() {
plugin.setAttribute(node, 'status', 'queued');
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
});
it('should get correct attribute before updating nodes', function(done) {
// Run setAttribute on some node
plugin.setAttribute(node, 'status', 'queued');
// Check that the value is correct before applying node changes
var updateNodes = plugin.updateNodes;
plugin.updateNodes = function() {
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
return updateNodes.apply(this, arguments);
};
plugin.save().nodeify(done);
});
it('should get correct attribute (from new node) before updating nodes', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('pipeline.Graph', node),
newVal = 'testGraph',
id = 'testId';
// Get the
plugin.setAttribute(graphTmp, 'name', newVal);
plugin._metadata[id] = graphTmp;
plugin.createIdToMetadataId[graphTmp] = id;
// Check that the value is correct before applying node changes
var updateNodes = plugin.updateNodes;
plugin.updateNodes = function() {
var graph = plugin._metadata[id],
attrValue = plugin.getAttribute(graph, 'name');
expect(attrValue).to.equal(newVal);
return updateNodes.apply(this, arguments);
};
plugin.save().nodeify(done);
});
it('should get correct attribute after save', function(done) {
// Run setAttribute on some node
plugin.setAttribute(node, 'status', 'queued');
// Check that the value is correct before applying node changes
plugin.save()
.then(() => {
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
})
.nodeify(done);
});
it('should get correct attribute while applying node changes', function(done) {
// Run setAttribute on some node
plugin.setAttribute(node, 'status', 'queued');
// Check that the value is correct before applying node changes
var oldApplyChanges = plugin._applyNodeChanges;
plugin._applyNodeChanges = function() {
var attrValue = plugin.getAttribute(node, 'status');
expect(attrValue).to.equal('queued');
return oldApplyChanges.apply(this, arguments);
};
plugin.save().nodeify(done);
});
});
describe('createNode', function() {
beforeEach(preparePlugin);
it('should update _metadata after applying changes', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('pipeline.Graph', node),
id = 'testId';
plugin._metadata[id] = graphTmp;
plugin.createIdToMetadataId[graphTmp] = id;
// Check that the value is correct before applying node changes
var applyModelChanges = plugin.applyModelChanges;
plugin.applyModelChanges = function() {
return applyModelChanges.apply(this, arguments)
.then(() => {
var graph = plugin._metadata[id];
expect(graph).to.not.equal(graphTmp);
});
};
plugin.save().nodeify(done);
});
it('should update _metadata in updateNodes', function(done) {
var id = 'testId';
plugin._metadata[id] = node;
node.old = true;
plugin.updateNodes()
.then(() => {
var graph = plugin._metadata[id];
expect(graph.old).to.not.equal(true);
})
.nodeify(done);
});
// Check that it gets the correct value from a newly created node after
// it has been saved/created
it('should get changed attribute', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('pipeline.Graph', node),
id = 'testId';
plugin._metadata[id] = node;
plugin.createIdToMetadataId[graphTmp] = id;
plugin.setAttribute(graphTmp, 'name', 'firstName');
// Check that the value is correct before applying node changes
plugin.save()
.then(() => {
var graph = plugin._metadata[id],
val = plugin.getAttribute(graph, 'name');
expect(val).to.equal('firstName');
})
.nodeify(done);
});
it('should get inherited attribute', function(done) {
// Run setAttribute on some node
var graphTmp = plugin.createNode('pipeline.Graph', node),
id = 'testId',
val;
// Check that the value is correct before applying node changes
plugin._metadata[id] = node;
plugin.createIdToMetadataId[graphTmp] = id;
val = plugin.getAttribute(graphTmp, 'name');
expect(val).to.equal('Graph');
plugin.save()
.then(() => {
var graph = plugin._metadata[id];
val = plugin.getAttribute(graph, 'name');
expect(val).to.equal('Graph');
})
.nodeify(done);
});
});
// Canceling
describe('cancel', function() {
beforeEach(preparePlugin);
it('should stop the job if the execution is canceled', function(done) {
var job = node,
hash = 'abc123',
exec = {
cancelJob: jobHash => expect(jobHash).equal(hash)
};
plugin.setAttribute(node, 'secret', 'abc');
plugin.isExecutionCanceled = () => true;
plugin.onOperationCanceled = () => done();
plugin.watchOperation(exec, hash, job, job);
});
it('should stop the job if a job is canceled', function(done) {
var job = node,
hash = 'abc123',
exec = {
cancelJob: jobHash => expect(jobHash).equal(hash)
};
plugin.setAttribute(job, 'secret', 'abc');
plugin.canceled = true;
plugin.onOperationCanceled = () => done();
plugin.watchOperation(exec, hash, job, job);
});
it('should set exec to running', function(done) {
var job = node,
execNode = plugin.core.getParent(job);
// Set the execution to canceled
plugin.setAttribute(execNode, 'status', 'canceled');
plugin.prepare = () => {
var status = plugin.getAttribute(execNode, 'status');
expect(status).to.not.equal('canceled');
return {then: () => done()};
};
plugin.main();
});
});
describe('exec files', function() {
describe('attribute file', function() {
var boolString = /['"](true|false)['"]/g;
beforeEach(preparePlugin);
it('should not quote true (s) boolean values', function() {
var files = {},
content,
matches;
plugin.setAttribute(node, 'debug', 'true');
plugin.createAttributeFile(node, files);
content = files['attributes.lua'];
matches = content.match(boolString);
expect(matches).to.equal(null);
});
it('should not quote true boolean values', function() {
var files = {},
content,
matches;
plugin.setAttribute(node, 'debug', true);
plugin.createAttributeFile(node, files);
content = files['attributes.lua'];
matches = content.match(boolString);
expect(matches).to.equal(null);
});
it('should not quote false (s) boolean values', function() {
var files = {},
content,
matches;
plugin.setAttribute(node, 'debug', 'false');
plugin.createAttributeFile(node, files);
content = files['attributes.lua'];
matches = content.match(boolString);
expect(matches).to.equal(null);
});
it('should not quote false boolean values', function() {
var files = {},
content,
matches;
plugin.setAttribute(node, 'debug', false);
plugin.createAttributeFile(node, files);
content = files['attributes.lua'];
matches = content.match(boolString);
expect(matches).to.equal(null);
});
});
});
});
@@ -89,6 +89,7 @@ describe('GenerateArchitecture', function () {
//['/o', 'basic.lua'],
//['/8', 'basic-transfers.lua'],
//['/M', 'concat-parallel.lua'],
['/4', 'requiredOmitted.lua'],
['/e', 'googlenet.lua'],
['/X', 'overfeat.lua']
];
+1 -1
Ver Arquivo
@@ -14,7 +14,7 @@ var testFixture = require('../../globals'),
];
describe('ImportTorch', function () {
this.timeout(5000);
this.timeout(7500);
var gmeConfig = testFixture.getGmeConfig(),
Q = testFixture.Q,
GraphChecker = testFixture.requirejs('deepforge/GraphChecker'),
+211
Ver Arquivo
@@ -0,0 +1,211 @@
var testFixture = require('../globals'),
superagent = testFixture.superagent,
Q = testFixture.Q,
expect = testFixture.expect,
assert = require('assert'),
path = testFixture.path,
gmeConfig = testFixture.getGmeConfig(),
blobDir = gmeConfig.blob.fsDir,
server = testFixture.WebGME.standaloneServer(gmeConfig),
mntPt = 'execution/logs',
rm_rf = require('rimraf'),
exists = require('exists-file');
describe('JobLogsAPI', function() {
var project = 'testProject',
branch = 'master',
jobId = encodeURIComponent('/4/q/l'),
firstLog = 'hello world',
url = [
server.getUrl(),
mntPt,
project,
branch,
jobId
].join('/');
before(function(done) {
testFixture.mkdir(blobDir);
server.start(done);
});
after(function(done) {
rm_rf.sync(blobDir);
server.stop(done);
});
describe('appendTo', function() {
before(function(done) {
superagent.patch(url)
.send({patch: firstLog})
.end(function (err, res) {
expect(res.status).equal(200, err);
done();
});
});
it('should create job-logs directory', function() {
assert(exists.sync(path.join(blobDir, 'log-storage')));
});
describe('getLog', function() {
it('should return the logs from the job', function(done) {
superagent.get(url)
.end(function (err, res) {
expect(res.status).equal(200, err);
expect(res.text).to.contain(firstLog);
done();
});
});
it('should append additional logs to the file', function(done) {
var secondLog = 'goodbye world';
superagent.patch(url)
.send({patch: secondLog})
.end(function (err, res) {
expect(res.status).equal(200, err);
superagent.get(url)
.end(function (err, res) {
expect(res.status).equal(200, err);
expect(res.text).to.contain(secondLog);
done();
});
});
});
});
});
describe('delete', function() {
var delUrl = [
server.getUrl(),
mntPt,
'testProject',
'other',
encodeURIComponent('/4/8/l')
].join('/');
before(function(done) {
superagent.patch(delUrl)
.send({patch: firstLog})
.end(function (err, res) {
expect(res.status).equal(200, err);
done();
});
});
it('should delete the file from job-logs directory', function(done) {
superagent.delete(delUrl)
.end(function (err, res) {
expect(res.status).equal(200, err);
superagent.get(delUrl)
.end(function (err, res) {
expect(res.status).equal(200, err);
expect(res.text).to.equal('');
done();
});
});
});
});
function getUrl(project, branch, job) {
return [
server.getUrl(),
mntPt,
encodeURIComponent(project),
encodeURIComponent(branch),
encodeURIComponent(job)
].join('/');
}
function addLog(project, branch, job, log) {
var deferred = Q.defer();
console.log('adding log', log);
superagent.patch(getUrl(project, branch, job))
.send({patch: log})
.end(function (err, res) {
if (err) {
return deferred.reject(err + ' (' + job + ')');
}
return deferred.resolve(res);
});
return deferred.promise;
}
describe('migrate', function() {
var j1 = '/s/p/3',
j2 = '/1/d/4',
b1 = 'asdfmaster',
b2 = 'not-master',
proj = 'someProject',
j1log = 'I am ' + j1,
j2log = 'I am ' + j2,
url;
before(function(done) {
Q.all([
addLog(proj, b1, j1, j1log),
addLog(proj, b1, j2, j2log),
addLog(proj, b2, j2, 'otherStuff')
]).then(() => {
url = [
server.getUrl(),
mntPt + '/migrate',
encodeURIComponent(proj),
encodeURIComponent(b1),
encodeURIComponent(b2)
].join('/');
superagent.post(url)
.send({jobs: [j1]})
.end(err => done(err));
})
.catch(err => done(err));
});
it('should copy the log content to the new branch', function(done) {
url = getUrl(proj, b2, j1);
superagent.get(url)
.end((err, res) => {
expect(res.text).to.equal(j1log);
done(err);
});
});
it('should not copy other jobs', function(done) {
url = getUrl(proj, b2, j2);
superagent.get(url)
.end((err, res) => {
// This log shouldn't be updated
expect(res.text).to.not.equal(j2log);
done(err);
});
});
it('should not change original log', function(done) {
url = getUrl(proj, b1, j1);
superagent.get(url)
.end((err, res) => {
expect(res.text).to.equal(j1log);
done(err);
});
});
it('should not crash on bad request', function(done) {
url = [
server.getUrl(),
mntPt + '/migrate',
encodeURIComponent(proj),
encodeURIComponent('someBranch3'),
encodeURIComponent(b2)
].join('/');
superagent.post(url)
.send({jobs: [j1]})
.end(err => done(err));
});
});
});
+157 -157
Ver Arquivo
@@ -11,136 +11,130 @@ net:add(nn.SpatialConvolution(64, 192, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(3, 3, 2, 2))
local net = 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))
net_2:add(nn.ReLU(true))
net_2:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
net_2:add(nn.ReLU(true))
net_2:add(nn.SpatialConvolution(96, 96, 3, 3, 1, 1, 1, 1))
net_2:add(nn.ReLU(true))
local net_3 = nn.Sequential()
net_3:add(nn.SpatialConvolution(192, 64, 1, 1, 1, 1))
net_3:add(nn.ReLU(true))
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.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.SpatialConvolution(192, 64, 1, 1, 1, 1))
net_4:add(nn.ReLU(true))
net_4:add(nn.SpatialConvolution(64, 64, 3, 3, 1, 1, 1, 1))
net_4:add(nn.ReLU(true))
local net_5 = nn.Sequential()
net_5:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_5:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_5:add(nn.SpatialConvolution(192, 32, 1, 1, 1, 1))
net_5:add(nn.ReLU(true))
local concat_24 = nn.Concat(2)
concat_24:add(net_5)
concat_24:add(net_4)
concat_24:add(net_3)
concat_24:add(net_2)
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))
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))
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.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))
net_9:add(nn.SpatialConvolution(256, 64, 1, 1, 1, 1))
net_9:add(nn.ReLU(true))
local concat_41 = nn.Concat(2)
concat_41:add(net_9)
concat_41:add(net_8)
concat_41:add(net_7)
concat_41:add(net_6)
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, 64, 1, 1, 1, 1))
net_10:add(nn.SpatialConvolution(320, 128, 1, 1, 1, 1))
net_10:add(nn.ReLU(true))
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.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
net_10:add(nn.ReLU(true))
local net_11 = nn.Sequential()
net_11:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_11:add(nn.SpatialMaxPooling(3, 3, 1, 1))
net_11:add(nn.SpatialConvolution(320, 64, 1, 1, 1, 1))
net_11:add(nn.ReLU(true))
net_11:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
net_11:add(nn.ReLU(true))
net_11:add(nn.SpatialConvolution(96, 96, 3, 3, 1, 1, 1, 1))
net_11:add(nn.ReLU(true))
local net_12 = nn.Sequential()
net_12:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_12:add(nn.SpatialMaxPooling(3, 3, 1, 1))
local concat_54 = nn.Concat(2)
concat_54:add(net_12)
concat_54:add(net_11)
concat_54:add(net_10)
concat_54:add(net_9)
net:add(concat_54)
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, 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.SpatialConvolution(576, 224, 1, 1, 1, 1))
net_13:add(nn.ReLU(true))
local net_14 = nn.Sequential()
net_14:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_14:add(nn.SpatialConvolution(576, 64, 1, 1, 1, 1))
net_14:add(nn.ReLU(true))
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.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
net_14:add(nn.ReLU(true))
local net_15 = nn.Sequential()
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.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_15:add(nn.ReLU(true))
net_15:add(nn.SpatialConvolution(96, 128, 3, 3, 1, 1, 1, 1))
net_15:add(nn.ReLU(true))
net_15:add(nn.SpatialConvolution(128, 128, 3, 3, 1, 1, 1, 1))
net_15:add(nn.ReLU(true))
local net_16 = nn.Sequential()
net_16:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_16:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_16:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_16:add(nn.ReLU(true))
local concat_72 = nn.Concat(2)
concat_72:add(net_16)
concat_72:add(net_15)
concat_72:add(net_14)
concat_72:add(net_13)
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, 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.SpatialConvolution(576, 192, 1, 1, 1, 1))
net_17:add(nn.ReLU(true))
local net_18 = nn.Sequential()
@@ -148,31 +142,31 @@ 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.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.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_19:add(nn.ReLU(true))
net_19:add(nn.SpatialConvolution(96, 128, 3, 3, 1, 1, 1, 1))
net_19:add(nn.ReLU(true))
net_19:add(nn.SpatialConvolution(128, 128, 3, 3, 1, 1, 1, 1))
net_19:add(nn.ReLU(true))
local net_20 = nn.Sequential()
net_20:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_20:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_20:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_20:add(nn.ReLU(true))
local concat_89 = nn.Concat(2)
concat_89:add(net_20)
concat_89:add(net_19)
concat_89:add(net_18)
concat_89:add(net_17)
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, 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.SpatialConvolution(576, 160, 1, 1, 1, 1))
net_21:add(nn.ReLU(true))
local net_22 = nn.Sequential()
@@ -180,162 +174,168 @@ 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.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.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_23:add(nn.ReLU(true))
net_23:add(nn.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
net_23:add(nn.ReLU(true))
net_23:add(nn.SpatialConvolution(160, 160, 3, 3, 1, 1, 1, 1))
net_23:add(nn.ReLU(true))
local concat_106 = nn.Concat(2)
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.SpatialZeroPadding(1, 1, 1, 1))
net_24:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_24:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_24:add(nn.ReLU(true))
local concat_106 = nn.Concat(2)
concat_106:add(net_24)
concat_106:add(net_23)
concat_106:add(net_22)
concat_106:add(net_21)
net:add(concat_106)
local net_25 = nn.Sequential()
net_25:add(nn.SpatialConvolution(576, 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.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_25:add(nn.ReLU(true))
local net_26 = nn.Sequential()
net_26:add(nn.SpatialConvolution(576, 160, 1, 1, 1, 1))
net_26:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_26:add(nn.ReLU(true))
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.SpatialConvolution(128, 192, 3, 3, 1, 1, 1, 1))
net_26:add(nn.ReLU(true))
local net_27 = nn.Sequential()
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.SpatialConvolution(576, 160, 1, 1, 1, 1))
net_27:add(nn.ReLU(true))
net_27:add(nn.SpatialConvolution(160, 192, 3, 3, 1, 1, 1, 1))
net_27:add(nn.ReLU(true))
net_27:add(nn.SpatialConvolution(192, 192, 3, 3, 1, 1, 1, 1))
net_27:add(nn.ReLU(true))
local net_28 = nn.Sequential()
net_28:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_28:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_28:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
net_28:add(nn.ReLU(true))
local concat_123 = nn.Concat(2)
concat_123:add(net_28)
concat_123:add(net_27)
concat_123:add(net_26)
concat_123:add(net_25)
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.SpatialZeroPadding(1, 1, 1, 1))
net_29:add(nn.SpatialMaxPooling(3, 3, 1, 1))
net_29:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1))
net_29:add(nn.ReLU(true))
net_29:add(nn.SpatialConvolution(192, 256, 3, 3, 1, 1, 1, 1))
net_29:add(nn.ReLU(true))
net_29:add(nn.SpatialConvolution(256, 256, 3, 3, 1, 1, 1, 1))
net_29:add(nn.ReLU(true))
local net_30 = nn.Sequential()
net_30:add(nn.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())
net_30:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_30:add(nn.SpatialMaxPooling(3, 3, 1, 1))
local net_31 = nn.Sequential()
net_31:add(nn.SpatialAveragePooling(5, 5, 3, 3))
net_31:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_31:add(nn.ReLU(true))
net_31:add(nn.SpatialConvolution(128, 192, 3, 3, 1, 1, 1, 1))
net_31:add(nn.ReLU(true))
net_31:add(nn.View())
net_31:add(nn.Linear(2048, 768))
net_31:add(nn.ReLU())
net_31:add(nn.Linear(768, 4))
net_31:add(nn.LogSoftMax())
local net_32 = nn.Sequential()
net_32:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_32:add(nn.ReLU(true))
net_32:add(nn.SpatialConvolution(128, 192, 3, 3, 1, 1, 1, 1))
net_32:add(nn.ReLU(true))
local concat_143 = nn.Concat(2)
concat_143:add(net_31)
concat_143:add(net_32)
concat_143:add(net_30)
concat_143:add(net_29)
concat_143:add(net_28)
net:add(concat_143)
local net_32 = nn.Sequential()
net_32:add(nn.SpatialConvolution(1024, 1024, 2, 2, 2, 2))
local net_33 = nn.Sequential()
net_33:add(nn.SpatialConvolution(1024, 352, 1, 1, 1, 1))
net_33:add(nn.ReLU(true))
net_33:add(nn.SpatialConvolution(1024, 1024, 2, 2, 2, 2))
local net_34 = nn.Sequential()
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.SpatialConvolution(1024, 352, 1, 1, 1, 1))
net_34:add(nn.ReLU(true))
local net_35 = nn.Sequential()
net_35:add(nn.SpatialConvolution(1024, 160, 1, 1, 1, 1))
net_35:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
net_35:add(nn.ReLU(true))
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.SpatialConvolution(192, 320, 3, 3, 1, 1, 1, 1))
net_35:add(nn.ReLU(true))
local net_36 = nn.Sequential()
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.SpatialConvolution(1024, 160, 1, 1, 1, 1))
net_36:add(nn.ReLU(true))
net_36:add(nn.SpatialConvolution(160, 224, 3, 3, 1, 1, 1, 1))
net_36:add(nn.ReLU(true))
net_36:add(nn.SpatialConvolution(224, 224, 3, 3, 1, 1, 1, 1))
net_36:add(nn.ReLU(true))
local net_37 = nn.Sequential()
net_37:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_37:add(nn.SpatialAveragePooling(3, 3, 1, 1))
net_37:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1))
net_37:add(nn.ReLU(true))
local concat_161 = nn.Concat(2)
concat_161:add(net_37)
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.SpatialConvolution(1024, 352, 1, 1, 1, 1))
net_37:add(nn.ReLU(true))
net_33:add(concat_161)
local net_38 = nn.Sequential()
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.SpatialConvolution(1024, 352, 1, 1, 1, 1))
net_38:add(nn.ReLU(true))
local net_39 = nn.Sequential()
net_39:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
net_39:add(nn.ReLU(true))
net_39:add(nn.SpatialConvolution(192, 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.SpatialConvolution(192, 320, 3, 3, 1, 1, 1, 1))
net_39:add(nn.ReLU(true))
local net_40 = nn.Sequential()
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.SpatialConvolution(1024, 192, 1, 1, 1, 1))
net_40:add(nn.ReLU(true))
net_40:add(nn.SpatialConvolution(192, 224, 3, 3, 1, 1, 1, 1))
net_40:add(nn.ReLU(true))
net_40:add(nn.SpatialConvolution(224, 224, 3, 3, 1, 1, 1, 1))
net_40:add(nn.ReLU(true))
local net_41 = nn.Sequential()
net_41:add(nn.SpatialZeroPadding(1, 1, 1, 1))
net_41:add(nn.SpatialMaxPooling(3, 3, 1, 1))
net_41:add(nn.SpatialConvolution(1024, 128, 1, 1, 1, 1))
net_41:add(nn.ReLU(true))
local concat_178 = nn.Concat(2)
concat_178:add(net_41)
concat_178:add(net_40)
concat_178:add(net_39)
concat_178:add(net_38)
concat_178:add(net_37)
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())
net_33:add(concat_178)
net_33:add(nn.SpatialAveragePooling(7, 7, 1, 1))
net_33:add(nn.View())
net_33:add(nn.Linear(1024, 4))
net_33:add(nn.LogSoftMax())
local concat_183 = nn.Concat(2)
concat_183:add(net_32)
concat_183:add(net_30)
concat_183:add(net_33)
concat_183:add(net_31)
net:add(concat_183)
@@ -0,0 +1,7 @@
require 'nn'
require 'rnn'
local net = nn.Sequential()
net:add(nn.Add(nil, true))
return net
+11 -1
Ver Arquivo
@@ -280,6 +280,15 @@
},
"xor": {
"src": "src/seeds/xor"
},
"devProject": {
"src": "src/seeds/devProject"
}
},
"routers": {
"JobLogsAPI": {
"src": "src/routers/JobLogsAPI",
"mount": "execution/logs"
}
}
},
@@ -337,6 +346,7 @@
"path": "node_modules/webgme-easydag/src/decorators/EllipseDecorator"
}
},
"seeds": {}
"seeds": {},
"routers": {}
}
}