Skip to content

Commit

Permalink
Added custom layer editing. Fixes #156
Browse files Browse the repository at this point in the history
WIP #156 Updated rootviz component config

WIP #156 Added template creation from parent if no code

WIP #156 Added root viz panel. Changed ordering

WIP #156 Added some support for 'create layer' button

WIP #156 Fixed create custom layer type button

WIP #156 Fixed bug with checking node for attribute

WIP #156. Added support for updating meta from constructor args

WIP #156

WIP #156 Added seeds

WIP #156 Added attr inheritance in layer def
  • Loading branch information
brollb committed Jun 17, 2016
1 parent 1beac9a commit 98b289d
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 105 deletions.
16 changes: 11 additions & 5 deletions config/components.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,29 @@
"description": "Pipelines compose operations together to effectively train, test and/or ensemble models."
},
{
"nodeName": "MyArtifacts",
"icon": "view_quilt",
"nodeName": "MyLayers",
"icon": "clear_all",
"rank": 4,
"color": "blue-grey",
"description": "Custom torch layers can be created and stored here for use in neural network architectures."
},
{
"nodeName": "MyArtifacts",
"icon": "view_quilt",
"rank": 5,
"description": "Artifacts from pipeline executions are stored here."
},
{
"nodeName": "MyExecutions",
"icon": "list",
"rank": 5,
"rank": 6,
"color": "blue-grey",
"description": "Executions are read-only snapshots of pipelines that have been executed. Past and current executing pipelines are stored here."
},
{
"nodeName": "MyDataTypes",
"icon": "settings",
"rank": 6,
"color": "blue-grey",
"rank": 7,
"description": "Custom defined data types are stored here."
}
]
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/ExecutePipeline/ExecutePipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,12 @@ define([

// add the given files
return this.createEntryFile(node, files)
// Add the custom layer definitions
// (with an init.lua file)
// TODO
.then(() => this.createInputs(node, files))
// Update the main file
// TODO
.then(() => this.createInputs(node, files))
.then(() => this.createOutputs(node, files))
.then(() => this.createMainFile(node, files))
Expand Down
Binary file modified src/seeds/nn/nn.webgmex
Binary file not shown.
Binary file modified src/seeds/project/project.webgmex
Binary file not shown.
14 changes: 1 addition & 13 deletions src/visualizers/Visualizers.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,12 @@
"panel": "panels/AutoViz/AutoVizPanel",
"DEBUG_ONLY": false
},
{
"id": "EasyDAG",
"title": "EasyDAG",
"panel": "panels/EasyDAG/EasyDAGPanel",
"DEBUG_ONLY": false
},
{
"id": "ArchEditor",
"title": "ArchEditor",
"panel": "panels/ArchEditor/ArchEditorPanel",
"DEBUG_ONLY": false
},
{
"id": "TextEditor",
"title": "TextEditor",
"panel": "panels/TextEditor/TextEditorPanel",
"DEBUG_ONLY": false
},
{
"id": "OperationEditor",
"title": "OperationEditor",
Expand Down Expand Up @@ -101,4 +89,4 @@
"panel": "panels/LayerEditor/LayerEditorPanel",
"DEBUG_ONLY": false
}
]
]
123 changes: 49 additions & 74 deletions src/visualizers/panels/ForgeActionButton/Actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@
// These are actions defined for specific meta types. They are evaluated from
// the context of the ForgeActionButton
define([
'js/RegistryKeys',
'js/Panels/MetaEditor/MetaEditorConstants',
'js/Constants'
'js/RegistryKeys'
], function(
REGISTRY_KEYS,
META_CONSTANTS,
CONSTANTS
REGISTRY_KEYS
) {
var instances = [
'Architecture',
Expand All @@ -20,88 +16,29 @@ define([
],
create = {};

var getUniqueName = function(parentId, basename) {
var pNode = this.client.getNode(parentId),
children = pNode.getChildrenIds().map(id => this.client.getNode(id)),
name = basename,
exists = {},
i = 2;

children.forEach(child => exists[child.getAttribute('name')] = true);

while (exists[name]) {
name = basename + '_' + i;
i++;
}

return name;
};

var createNew = function(type, metasheetName) {
// Create CNN node in the current dir
// Get CNN node type
var parentId = this._currentNodeId,
newId,
baseId;
var newId,
baseId,
msg = `Created new ${type + (metasheetName ? ' prototype' : '')}`;

baseId = this.client.getAllMetaNodes()
.find(node => node.getAttribute('name') === type)
.getId();

this.client.startTransaction('Created new operation prototype');
newId = this.client.createChild({parentId, baseId});
this.client.startTransaction(msg);
newId = this.createNamedNode(baseId, !!metasheetName);

// Name the new node
var basename = 'New' + this.client.getNode(baseId).getAttribute('name'),
newName = getUniqueName.call(this, parentId, basename);

// If instance, make the first char lowercase
if (!metasheetName) {
newName = newName.substring(0, 1).toLowerCase() + newName.substring(1);
if (metasheetName) {
this.addToMetaSheet(newId, metasheetName);
}

this.client.setAttributes(newId, 'name', newName);
if (metasheetName) { // Add to metasheet
var root = this.client.getNode(CONSTANTS.PROJECT_ROOT_ID),
metatabs = root.getRegistry(REGISTRY_KEYS.META_SHEETS),
metatab = metatabs.find(tab => tab.title === metasheetName) || metatabs[0],
metatabId = metatab.SetID;

// Add to the general meta
this.client.addMember(
CONSTANTS.PROJECT_ROOT_ID,
newId,
META_CONSTANTS.META_ASPECT_SET_NAME
);
this.client.setMemberRegistry(
CONSTANTS.PROJECT_ROOT_ID,
newId,
META_CONSTANTS.META_ASPECT_SET_NAME,
REGISTRY_KEYS.POSITION,
{
x: 100,
y: 100
}
);

// Add to the specific sheet
this.client.addMember(CONSTANTS.PROJECT_ROOT_ID, newId, metatabId);
this.client.setMemberRegistry(
CONSTANTS.PROJECT_ROOT_ID,
newId,
metatabId,
REGISTRY_KEYS.POSITION,
{
x: 100,
y: 100
}
);
}
this.client.completeTransaction();

WebGMEGlobal.State.registerActiveObject(newId);
return newId;
};


instances.forEach(type => {
create[type] = function() {
return createNew.call(this, type);
Expand All @@ -114,6 +51,37 @@ define([
};
});

var createLayer = function() {
// Prompt the base type
this.promptLayerType().then(selected => {
var baseId = selected.node.id,
typeName = this.client.getNode(baseId).getAttribute('name'),
metanodes = this.client.getAllMetaNodes(),
msg = `Created new custom ${typeName} layer`,
newId,
customLayerId,
name;

for (var i = metanodes.length; i--;) {
name = metanodes[i].getAttribute('name');
if (name === 'CustomLayer') {
customLayerId = metanodes[i].getId();
break;
}
}

this.client.startTransaction(msg);

newId = this.createNamedNode(baseId, true);
this.addToMetaSheet(newId, 'CustomLayers');
this.client.addMixin(newId, customLayerId);
this.client.setRegistry(newId, REGISTRY_KEYS.IS_ABSTRACT, false);

this.client.completeTransaction();

WebGMEGlobal.State.registerActiveObject(newId);
});
};
////////////// Downloading files //////////////
var downloadAttrs = [
'data',
Expand Down Expand Up @@ -216,6 +184,13 @@ define([
action: create.Data
}
],
MyLayers_META: [
{
name: 'Create new layer',
icon: 'queue',
action: createLayer
}
],
MyOperations_META: [
{
name: 'Create new operation',
Expand Down
125 changes: 125 additions & 0 deletions src/visualizers/panels/ForgeActionButton/ForgeActionButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,20 @@ define([
'panel/FloatingActionButton/FloatingActionButton',
'deepforge/viz/PipelineControl',
'./Actions',
'widgets/EasyDAG/AddNodeDialog',
'js/RegistryKeys',
'js/Panels/MetaEditor/MetaEditorConstants',
'q',
'text!./PluginConfig.json'
], function (
CONSTANTS,
PluginButton,
PipelineControl,
ACTIONS,
AddNodeDialog,
REGISTRY_KEYS,
META_CONSTANTS,
Q,
PluginConfig
) {
'use strict';
Expand Down Expand Up @@ -75,5 +83,122 @@ define([
this.update();
};

// Helper functions
ForgeActionButton.prototype.addToMetaSheet = function(nodeId, metasheetName) {
var root = this.client.getNode(CONSTANTS.PROJECT_ROOT_ID),
metatabs = root.getRegistry(REGISTRY_KEYS.META_SHEETS),
metatab = metatabs.find(tab => tab.title === metasheetName) || metatabs[0],
metatabId = metatab.SetID;

// Add to the general meta
this.client.addMember(
CONSTANTS.PROJECT_ROOT_ID,
nodeId,
META_CONSTANTS.META_ASPECT_SET_NAME
);
this.client.setMemberRegistry(
CONSTANTS.PROJECT_ROOT_ID,
nodeId,
META_CONSTANTS.META_ASPECT_SET_NAME,
REGISTRY_KEYS.POSITION,
{
x: 100,
y: 100
}
);

// Add to the specific sheet
this.client.addMember(CONSTANTS.PROJECT_ROOT_ID, nodeId, metatabId);
this.client.setMemberRegistry(
CONSTANTS.PROJECT_ROOT_ID,
nodeId,
metatabId,
REGISTRY_KEYS.POSITION,
{
x: 100,
y: 100
}
);
};

ForgeActionButton.prototype.createNamedNode = function(baseId, isMeta) {
var parentId = this._currentNodeId,
newId = this.client.createChild({parentId, baseId}),
basename = 'New' + this.client.getNode(baseId).getAttribute('name'),
newName = this.getUniqueName(parentId, basename);

// If instance, make the first char lowercase
if (!isMeta) {
newName = newName.substring(0, 1).toLowerCase() + newName.substring(1);
}
this.client.setAttributes(newId, 'name', newName);
return newId;
};

ForgeActionButton.prototype.getUniqueName = function(parentId, basename) {
var pNode = this.client.getNode(parentId),
children = pNode.getChildrenIds().map(id => this.client.getNode(id)),
name = basename,
exists = {},
i = 2;

children.forEach(child => exists[child.getAttribute('name')] = true);

while (exists[name]) {
name = basename + '_' + i;
i++;
}

return name;
};

ForgeActionButton.prototype.getLayerTypeDesc = function(node) {
var decManager = this.client.decoratorManager,
desc = {};

desc.id = node.getId();
desc.name = node.getAttribute('name');
desc.baseName = desc.name;
desc.attributes = {};
desc.pointers = {};

// Get the decorator
desc.Decorator = decManager.getDecoratorForWidget('EllipseDecorator', 'EasyDAG');

// Set the color
desc.color = '#9e9e9e';
// TODO
return desc;
};

ForgeActionButton.prototype.promptLayerType = function() {
// Prompt for the new custom layer's base type
var deferred = Q.defer(),
metanodes = this.client.getAllMetaNodes(),
baseLayerId = metanodes.find(n => n.getAttribute('name') === 'Layer').getId(),
layerType,
types;

// PoA:
// - Get the layer type ids
// - Create the descriptors
// - Get the color for the given types
// - Move colors to a constants dir?

// Get the layer type ids
layerType = metanodes
.filter(node => node.getBaseId() === baseLayerId);

// - Create the descriptors
types = layerType.map(node => {
return {
node: this.getLayerTypeDesc(node)
};
});

AddNodeDialog.prompt(types, deferred.resolve);
return deferred.promise;
};

return ForgeActionButton;
});
Loading

0 comments on commit 98b289d

Please sign in to comment.