Skip to content

Commit

Permalink
Added 'deepforge.image(<name>, <tensor>)' support. Fixes #519 (#575)
Browse files Browse the repository at this point in the history
WIP #519 Added saving image file on worker

WIP #519 Added wrapper for the intermediate data results

WIP #519 filename->name and silenced blobClient logs

WIP #519 Removed old debug log

WIP #519 Added Image metadata creation

WIP #519 Added ImageViewer

WIP #519 Added zoom fn-ality

WIP #519 Added 'Image' node

WIP #519 Updated pipeline libraries

WIP #519 Added 'image' to deepforge autocomplete

WIP #519 Added no-image image

WIP #519 Fixed image updating

WIP #519 Added better origin url detection

WIP #519 Fixed code climate issues

WIP #519 fixed code climate issues
  • Loading branch information
brollb authored Jul 30, 2016
1 parent 98c64fc commit 70fe60a
Show file tree
Hide file tree
Showing 17 changed files with 524 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/common/Constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ define({

// DeepForge metadata creation in dist execution
START_CMD: 'deepforge-cmd',

IMAGE: 'IMG',

GRAPH_CREATE: 'GRAPH',
GRAPH_PLOT: 'PLOT',
GRAPH_CREATE_LINE: 'LINE'
Expand Down
73 changes: 57 additions & 16 deletions src/plugins/ExecuteJob/ExecuteJob.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ define([
name,
id,
idsToDelete = [],
type,
base,
child;

this.lastAppliedCmd[nodeId] = 0;
Expand All @@ -142,9 +144,16 @@ define([
if (this.isMetaTypeOf(child, this.META.Metadata)) {
id = this.core.getPath(child);
name = this.core.getAttribute(child, 'name');
base = this.core.getBase(child);
type = this.core.getAttribute(base, 'name');

this._markForDeletion[nodeId][id] = child;
this._oldMetadataByName[nodeId][name] = id;
// namespace by metadata type
if (!this._oldMetadataByName[nodeId][type]) {
this._oldMetadataByName[nodeId][type] = {};
}

this._oldMetadataByName[nodeId][type][name] = id;

// children of metadata nodes get deleted
idsToDelete = idsToDelete
Expand Down Expand Up @@ -314,13 +323,13 @@ define([
);

config = {
cmd: 'bash',
args: ['run.sh'],
cmd: 'node',
args: ['start.js'],
outputInterval: OUTPUT_INTERVAL,
resultArtifacts: outputs
};
files['executor_config.json'] = JSON.stringify(config, null, 4);
files['run.sh'] = Templates.BASH;
files['start.js'] = _.template(Templates.START)(CONSTANTS);

// Save the artifact
// Remove empty hashes
Expand Down Expand Up @@ -879,23 +888,14 @@ define([
ExecuteJob.prototype[CONSTANTS.GRAPH_CREATE] = function (job, id) {
var graph,
name = Array.prototype.slice.call(arguments, 2).join(' '),
jobId = this.core.getPath(job),
oldMetadata = this._oldMetadataByName[jobId],
oldId;
jobId = this.core.getPath(job);

id = jobId + '/' + id;
this.logger.info(`Creating graph ${id} named ${name}`);

// Check if the graph already exists
if (oldMetadata && oldMetadata[name]) {
oldId = oldMetadata[name];
graph = this._markForDeletion[jobId][oldId];

// Reset points
this.core.setAttribute(graph, 'points', '');

delete this._markForDeletion[jobId][oldId];
} else { // create new graph
graph = this._getExistingMetadata(jobId, 'Graph', name);
if (!graph) {
graph = this.core.createNode({
base: this.META.Graph,
parent: job
Expand Down Expand Up @@ -948,5 +948,46 @@ define([
this._metadata[jobId + '/' + id] = line;
};

ExecuteJob.prototype[CONSTANTS.IMAGE] = function (job, hash) {
var jobId = this.core.getPath(job),
name = Array.prototype.slice.call(arguments, 2).join(' '),
id = jobId + '/IMAGE/' + name,
imageNode = this._metadata[id]; // Look for the metadata imageNode

id = jobId + '/' + id;
this.logger.info(`Creating graph ${id} named ${name}`);

if (!imageNode) {

// Check if the imageNode already exists
imageNode = this._getExistingMetadata(jobId, 'Image', name);
if (!imageNode) {
imageNode = this.core.createNode({
base: this.META.Image,
parent: job
});
this.core.setAttribute(imageNode, 'name', name);
}
this._metadata[id] = imageNode;
}

this.core.setAttribute(imageNode, 'data', hash);
};

ExecuteJob.prototype._getExistingMetadata = function (jobId, type, name) {
var oldMetadata = this._oldMetadataByName[jobId] &&
this._oldMetadataByName[jobId][type],
node,
id;

if (oldMetadata && oldMetadata[name]) {
id = oldMetadata[name];
node = this._markForDeletion[jobId][id];
delete this._markForDeletion[jobId][id];
}

return node || null;
};

return ExecuteJob;
});
18 changes: 18 additions & 0 deletions src/plugins/ExecuteJob/templates/deepforge.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function deepforge._cmd(...)
print(cmd)
end

-- Graph support
Graph = torch.class('deepforge.Graph')

function Graph:__init(name)
Expand All @@ -43,4 +44,21 @@ function Graph:line(name, opts)
return deepforge._Line(self.id, name, opts)
end

-- Image support
function deepforge.image(name, tensor)
require 'image'
require 'paths'

-- save it in the tmp directory
local filename = name .. '.png'
local path = paths.concat('metadata', filename)

if paths.dir('metadata') == nil then
paths.mkdir('metadata')
end

image.save(path, tensor)
deepforge._cmd("<%= IMAGE %>", name)
end

return deepforge
5 changes: 3 additions & 2 deletions src/plugins/ExecuteJob/templates/index.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
/*globals define*/
define([
'text!./start.ejs',
'text!./entry.ejs',
'text!./main.ejs',
'text!./deepforge.ejs',
'text!./serialize.ejs',
'text!./deserialize.ejs'
], function(
START,
ENTRY,
MAIN,
DEEPFORGE,
SERIALIZE,
DESERIALIZE
) {

var BASH = 'th init.lua 2>&1';
return {
BASH,
START,
ENTRY,
MAIN,
SERIALIZE,
Expand Down
81 changes: 81 additions & 0 deletions src/plugins/ExecuteJob/templates/start.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// A wrapper for the torch script which:
// - merges stdout, stderr
// - receives some commands and uploads intermediate data
var spawn = require('child_process').spawn,
fs = require('fs'),
log = console.error,
logger = {};

// Create the stderr only logger
['error', 'warn', 'info', 'log', 'debug'].forEach(method => logger[method] = log);

// Get the BlobClient...
var COMMAND_PREFIX = '<%= START_CMD %>',
IMAGE = '<%= IMAGE %>',
requirejs = require('webgme').requirejs;

requirejs([
'blob/BlobClient'
], function(
BlobClient
) {
var url = process.env.ORIGIN_URL || 'http://127.0.0.1:8888',
protocol = url.split('://').shift(),
address,
port = (url.split(':') || ['80']).pop();

address = url.replace(protocol + '://', '')
.replace(':' + port, '');

var blobClient = new BlobClient({
server: address,
httpsecure: protocol === 'https',
serverPort: port,
logger: logger
});

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/
fs.readFile(filename, (err, content) => {
if (err) {
console.error(`Could not read ${filename}: ${err}`);
return;
}

// Add hash to the image command
blobClient.putFile(filename, content)
.then(hash => {
args.splice(2, 0, hash);
console.log(args.join(' '));
})
.fail(err => console.error(`${filename} upload failed: ${err}`));
});
};

var onStdout = function(data) {
var lines = data.toString().split('\n'),
result = [],
cmdStart;

// Check for commands...
for (var i = 0; i < lines.length; i++) {
cmdStart = lines[i].indexOf(COMMAND_PREFIX);
if (cmdStart !== -1 && lines[i].indexOf(IMAGE) !== -1) {
uploadImage(lines[i]);
} else {
result.push(lines[i]);
}
}

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));
});
Binary file modified src/seeds/cifar10/cifar10.webgmex
Binary file not shown.
Binary file modified src/seeds/pipeline/pipeline.webgmex
Binary file not shown.
Binary file modified src/seeds/project/project.webgmex
Binary file not shown.
Binary file modified src/seeds/xor/xor.webgmex
Binary file not shown.
6 changes: 6 additions & 0 deletions src/visualizers/Visualizers.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,11 @@
"title": "LineGraph",
"panel": "panels/LineGraph/LineGraphPanel",
"DEBUG_ONLY": false
},
{
"id": "ImageViewer",
"title": "ImageViewer",
"panel": "panels/ImageViewer/ImageViewerPanel",
"DEBUG_ONLY": false
}
]
Loading

0 comments on commit 70fe60a

Please sign in to comment.