Comparar commits

..

74 Commits

Autor SHA1 Mensagem Data
Brian Broll 7eb2c1a404 v0.6.0 2016-06-20 16:22:47 -05:00
JimnyCricket 69cfc4dd77 Merge pull request #325 from dfst/324-artifact-loader-returns-nil
Updated downcast data setting. Fixes #324
2016-06-20 15:49:56 -04:00
Brian Broll e88500df33 Updated pipeline buttons. Fixes #326 (#327) 2016-06-20 12:01:22 -05:00
Brian Broll 64ae1da03e Updated downcast data setting. Fixes #324
WIP #324. Fixed data reset
2016-06-20 11:39:57 -05:00
Brian Broll e24bf3171d Added simple install script. Fixes #278 (#323)
WIP #278 added cloning deepforge repo

WIP #278 updated readme and added more installation logging

WIP #278 added FIXME when merging

WIP #278 Added curl to readme

WIP #278 Fixed var scope

WIP #278 Updated readme
2016-06-20 11:07:56 -05:00
JimnyCricket f301e9312f Merge pull request #320 from dfst/306-terminal-ansi-codes
Added ansi color support. Fixes #306
2016-06-20 10:51:19 -04:00
Brian Broll 0b95219c2a Removed extra seeds. Fixes #317 (#322) 2016-06-20 09:45:00 -05:00
Brian Broll b05f96e77a Fixed promise chaining issue in ExecutePipeline. Fixes #310 (#321) 2016-06-20 09:27:50 -05:00
Brian Broll 063aac8730 Added ansi color support. Fixes #306
WIP #306 Added basic ansi color support (flicker-y)

WIP #306 Fixed resize color update

WIP #306 Overrode the ace renderer to add support for ansi

WIP #306 Removed old TODO
2016-06-20 09:13:15 -05:00
Brian Broll edeb783547 Custom Layer Support (#315)
* Added basic custom layer editor. Fixes #1

* Added custom layer editing. Fixes #156

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

WIP #156 Removed extra TODO

* Added custom layer support to executions. Fixes #296

WIP #296 Fixed execution support

* Updated GenArch for custom layers. Fixes #157

WIP #157 Updated 'standalone' default to true

WIP #157 Fixed code-climate issues

WIP #157 Fixed bad default

WIP Removed outdated tests
2016-06-17 13:28:50 -05:00
Brian Broll b65c0b740a Revert "Added regex to remove console colors. Fixes #306 " (#311) 2016-06-16 15:07:18 -05:00
JimnyCricket 55d8b72e05 Added regex to remove console colors. Fixes #306 (#307) 2016-06-16 14:18:34 -05:00
JimnyCricket 1d4469d2b9 Merge pull request #309 from dfst/308-update-nn-seed
Updated project, nn, and minimal seeds. Fixes #308
2016-06-16 14:00:12 -05:00
Brian Broll fda5be793d Updated project, nn, and minimal seeds. Fixes #308 2016-06-16 11:15:49 -05:00
Brian Broll a8666959c0 Added download execFiles button. Fixes #295
WIP #295. updated seeds
2016-06-16 07:58:54 -05:00
Brian Broll f95125ab04 Removed ruler from LogViewer. Fixes #302 (#303) 2016-06-16 06:12:13 -05:00
Brian Broll a5cbfb2c89 Setting stdout from results on job finished. Fixes #300 (#301) 2016-06-16 06:06:23 -05:00
Brian Broll b43a580683 Added node updating to CreateTorchMeta. Fixes #290
WIP #290 Added attribute updating and meta sheet placement

WIP #290 Removing old layers and changing category support

WIP #290 Added update layer test

WIP #290 Updated ArchEditor layer type colors

WIP #290 Updated seeds

WIP #290 Fixed attribute not showing up bug

WIP #290 Fixed removal of old attribute names

WIP #290 Added more logs

WIP #290 Removed 'only' from tests
2016-06-15 21:10:27 -05:00
Brian Broll 1f0f615fc4 Added stdout viewer for jobs. Fixes #162 (#294)
WIP #162. Hid 'success' and 'debug' attrs

WIP #162 Added stdout logs to jobs

WIP #162 Added 'Enter' button on jobs

WIP #162 Added readonly, no syntax highlighting to LogViewer

WIP #162 Added theme

WIP #162. Removed extra new lines

WIP #162. redirected stderr to stdout

WIP #162 Updated seeds

WIP #162 Removed unnecessary comment
2016-06-15 20:39:27 -05:00
Brian Broll 3842439112 Added port update on node creation, port change. Fixes #258 (#282)
WIP #258 Works with artifact loader updates

WIP #258. Fixed reconnection for port update
2016-06-15 13:31:33 -05:00
Brian Broll 8229495b34 Changed downcasting to set base and copy content. Fixes #283 (#284) 2016-06-15 13:31:19 -05:00
Brian Broll b0135100ed Added parsing torch nn for nn visual lang. Fixes #85 (#291)
WIP 85 Added Parser

WIP #85 Fixed BatchNormalization bug and some styling

WIP #85 Added types and json conversion.

WIP #85 create nn layers from parsed library.

WIP #85 Skipping abstract torch layer types. Updated categories

WIP #85 Filtered out 'Criterion' type. Update category name for pos

WIP #85 Added 'baseType' to layer description

WIP #85 Added init params inheritance

WIP #85 Removed out-dated tests

WIP #85 Updated GenArch to omit unset values
2016-06-15 11:27:01 -05:00
Brian Broll a628256682 Set ArtifactLoader name to the target name. Fixes #288 (#289) 2016-06-14 14:03:52 -05:00
Brian Broll ddd6431d55 Added port name tooltips. Fixes #286 (#287) 2016-06-14 13:09:40 -05:00
Brian Broll a63287df92 Removed git lfs from readme; added links 2016-06-14 10:47:09 -05:00
Brian Broll 3721257559 Removed git lfs Fixes #153 (#285)
* WIP #153 Removed git lfs

* WIP #153 Added project seeds back to git
2016-06-14 10:42:57 -05:00
Brian Broll dba9c4a25b Added meta positioning for CreateTorchMeta. Fixes #41. Fixes #24 (#281) 2016-06-14 07:45:49 -05:00
Brian Broll 11f7751843 Destory editor on viz close. Fixes #184 (#280) 2016-06-13 18:30:05 -05:00
Brian Broll c05d7bb433 Added ArtifactFinder. Fixes #236 (#277)
WIP #236 Added ArtifactFinder support to ExecutePipeline

WIP #236 Updated UI for ArtifactFinder support

WIP #236 updated seeds
2016-06-13 13:09:10 -05:00
Brian Broll 8e6bdfbeff Added time limit for upload toast. Fixes #274 (#275) 2016-06-13 11:52:57 -05:00
Brian Broll b4829adbc3 v0.5.0
Updated state badge
2016-06-13 10:58:33 -05:00
Brian Broll a3cfa9f8e3 Added concat support to GenArch. Fixes #61 (#273)
WIP #61 Started w/ concat support

WIP #61 Added basic concat support

WIP #61 Added quick merge-fork fn-ality

WIP #64 Added nested concat support

WIP #61 Added concat tests

WIP #61 Added `npm run watch-test` cmd

WIP #61 Fixed lint errors. Removed debugger statement
2016-06-13 10:53:52 -05:00
Brian Broll 62a80d1f9f Set the logo font for just the item-label. Fixes #271 (#272) 2016-06-11 23:09:53 -05:00
Brian Broll b0ad46c66b Hide fab on no actions. Fixes #269 (#270) 2016-06-11 22:30:51 -05:00
Brian Broll 7e2b83b5cc Added font for deepforge logo. Fixes #267 (#268) 2016-06-11 18:29:47 -05:00
JimnyCricket 5193bbd931 Merge pull request #266 from dfst/259-deleting-input-to-operation
Added removePort to OperationNode. Fixes #259
2016-06-11 18:19:37 -05:00
Brian Broll b513bcbec4 Added removePort to OperationNode. Fixes #259 2016-06-11 18:08:32 -05:00
JimnyCricket 408ee8e0f4 Updated dist code gen to support nil inputs, refs Fixes #228 (#239)
WIP #228 Add nil return to deserialize fn

WIP #228 Removed empty object hashes

WIP #228 Added check for no filename

WIP #228 Updated dist code gen for pointers, inputs

WIP #228. Removed unnecessary template stuff and added warning

WIP #228. local nil var shadowing if no input/ptr
2016-06-11 13:53:49 -05:00
Brian Broll dd92726044 Added torch dep check on worker start. Fixes #255 (#265) 2016-06-11 12:45:48 -05:00
Brian Broll 5d2098e6e1 Removed webgme logo and text. Fixes #260 (#264) 2016-06-11 12:12:25 -05:00
Brian Broll 341497323c Removed default webgme footer. Fixes #262 (#263) 2016-06-11 12:12:22 -05:00
Brian Broll 1f71b254b5 Added require 'nn' to model deser. Fixes #252 (#253) 2016-06-10 13:15:46 -05:00
Brian Broll db97a492e1 Added sorted, colored, root cards w/ icons. Fixes #238 (#251)
WIP #238 Added root viz icons... Needs ranking

WIP #238 Fixed ordering

WIP #238 Added colors

WIP #238 Extended desc of pipelines to fix formatting
2016-06-10 09:48:58 -05:00
Brian Broll f863fc2638 Merge branch '249-multiple-outputs-exec' 2016-06-10 09:00:43 -05:00
JimnyCricket 3d6c654028 Merge pull request #248 from dfst/237-execution-forks
Provided a 'fork-free' save for pipeline execution. Fixes #237
2016-06-10 08:59:14 -05:00
Brian Broll 64f64ecd2a Fixed operation input double counting. Fixes #249 2016-06-10 08:57:48 -05:00
Brian Broll 09b33792d9 Provided a 'fork-free' save for pipeline execution. Fixes #237 2016-06-10 08:24:01 -05:00
Brian Broll ab932c1a52 Fixed case in dependency. Fixes #241 (#242) 2016-06-09 20:49:47 -05:00
Brian Broll 206f4ce6fc Added git-lfs to install instructions. Fixes #240
Also updated some style rules in eslint
2016-06-09 08:28:43 -05:00
JimnyCricket 1618460984 Merge pull request #234 from dfst/232-jump-to-op-def
Added pivoting btwn op defs and pipeline. Fixes #232
2016-06-08 22:34:58 -05:00
Brian Broll 41cfdfb007 Added ArtifactLoader. Fixes #166 (#235)
WIP #166 Added ArtifactLoader to seeds

WIP #166 Added OpIntDecorator

WIP #166 Filtered out the meta data nodes

WIP #166 Added node creation/base change on pointer set

WIP #166. Fixed output node creation

WIP #166 Added ArtifactLoader to LocalExecutor
2016-06-08 11:10:16 -05:00
Brian Broll 57a60d6919 Added pivoting btwn op defs and pipeline. Fixes #232
WIP #232 Added jump to op def button in selection

WIP #232 Added returning to pipeline
2016-06-08 10:29:05 -05:00
Brian Broll ab3ba50886 Added 'upload artifact' button. Fixes #225 (#227) 2016-06-07 14:32:48 -05:00
JimnyCricket cc21727a7b Update README.md
add npm
2016-06-07 12:43:46 -05:00
JimnyCricket 1dbbf8a302 Update README.md
Combining lines.
2016-06-07 12:41:24 -05:00
JimnyCricket 6f6ab1af1e Update README.md
collapse lines
2016-06-07 12:32:37 -05:00
JimnyCricket 09a51dd518 Update README.md
Don't start mongo in sudo.
2016-06-07 12:31:55 -05:00
JimnyCricket 3e0b1c0e50 Update README.md
Added Quick Setup
2016-06-07 12:26:17 -05:00
JimnyCricket 628c636129 Update README.md
Moved Torch installation to Installation Guide
2016-06-07 12:18:38 -05:00
JimnyCricket d2173bd9f3 Update README.md
Referenced the Installation Guide
2016-06-07 12:17:44 -05:00
JimnyCricket 2baf4a72bf Merge pull request #213 from dfst/207-del-op-ptr
207 del op ptr
2016-06-07 11:16:30 -05:00
Brian Broll de1ca7a2d2 Renamed ROOT -> HOME. Fixes #109 (#226) 2016-06-07 10:44:45 -05:00
Brian Broll 2b75f16b9a Added referencing architectures. Fixes #222 (#223) 2016-06-07 10:18:23 -05:00
Brian Broll 20618ddb40 Added intermittent commits to pipeline execution. Fixes #150 (#220)
WIP #150. Added commits...

WIP #150 cancelled commits...?

WIP #150 Creating jobs serially. Fixed cancelled commits

WIP #150 Removed unneeded comment
2016-06-06 11:22:53 -05:00
JimnyCricket be97f4806e Merge pull request #217 from dfst/205-slow-polling
Shortened worker refresh in 'local' mode. Fixes #205
2016-06-06 10:56:18 -05:00
JimnyCricket cb97a14e59 Merge pull request #210 from dfst/154-basic-torch-data-types
Added data types to project and added minimal seed. Yeah, I think having some connections to the blob might be good. We'll address these in another issue. Fixes #154
2016-06-06 10:49:18 -05:00
JimnyCricket 6faa7d444a Merge pull request #218 from dfst/214-code-editor-indents
set tab size to 3. Fixes #214
2016-06-06 10:38:29 -05:00
Brian Broll 806780bd1f Added single execution file generation. Fixes #138 (#219)
WIP #138 Added basic code generation for each op.

WIP #138 merged operation code blocks in topo ordering

WIP #138 Removed unused file and updated plugin name

WIP #138 Added support for references

WIP #138. Updated plugin for executions

WIP #138 Fixed ptr code generation

WIP #138 Updated pipeline seed
2016-06-06 09:56:59 -05:00
Brian Broll 2e0ddfaeb9 set tab size to 3. Fixes #214 2016-06-04 13:29:09 -05:00
Brian Broll c83d4ecbc5 Shortened worker refresh in 'local' mode. Fixes #205 2016-06-04 11:15:21 -05:00
Brian Broll a467e67524 Merge branch 'master' into 207-del-op-ptr 2016-06-04 09:45:10 -05:00
Brian Broll 271f237eac Merge branch 'master' into 154-basic-torch-data-types 2016-06-04 09:44:53 -05:00
Brian Broll 857be35efa Updated Delete button for ptrs. Fixes #207 2016-06-04 09:38:57 -05:00
Brian Broll 87f73359ab Added data types to project and added minimal seed. Fixes #154 2016-06-04 08:59:39 -05:00
89 arquivos alterados com 5573 adições e 827 exclusões
+1
Ver Arquivo
@@ -2,3 +2,4 @@ src/common/lua.js
src/visualizers/widgets/TextEditor/lib/*
src/common/js-yaml.min.js
src/visualizers/Visualizers.json
config/config.webgme.js
+5 -4
Ver Arquivo
@@ -1,18 +1,19 @@
env:
browser: true
node: true
mocha: true
es6: true
extends: 'eslint:recommended'
rules:
indent:
- error
- 2
- 4
linebreak-style:
- error
- 2
- unix
quotes:
- error
- 2
- single
semi:
- error
- 2
- always
+1 -1
Ver Arquivo
@@ -1 +1 @@
*.webgmex filter=lfs diff=lfs merge=lfs -text
+7 -5
Ver Arquivo
@@ -1,4 +1,4 @@
[![Release State](https://img.shields.io/badge/state-pre--alpha-red.svg)](https://img.shields.io/badge/state-pre--alpha-red.svg)
[![Release State](https://img.shields.io/badge/state-alpha-orange.svg)](https://img.shields.io/badge/state-alpha-orange.svg)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](./LICENSE)
[![Build Status](https://travis-ci.org/dfst/deepforge.svg?branch=master)](https://travis-ci.org/dfst/deepforge)
[![Join the chat at https://gitter.im/dfst/deepforge](https://badges.gitter.im/dfst/deepforge.svg)](https://gitter.im/dfst/deepforge?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
@@ -6,14 +6,16 @@
# 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.
## Quick Setup
After cloning the repo, run
## Quick Start
Simply run the following command to install deepforge with its dependencies:
```
npm install && npm start
curl -o- https://raw.githubusercontent.com/dfst/deepforge/master/install.sh | bash
```
Now, navigate to `localhost:8888` in a browser and create a new project. Select `nn` as the seed and start creating your neural nets!
Next, follow the postinstall instructions to start MongoDB and DeepForge!
Finally, navigate to [http://localhost:8888](http://localhost:8888) to start using DeepForge! For more, detailed instructions,check out our [wiki](https://github.com/dfst/deepforge/wiki/Installation-Guide).
## Caffe Support?
DeepForge uses Torch to perform the actual training and testing of the models. If you are interested in DeepForge using Caffe for actual training and testing, check out [DeepForge-Caffe](https://github.com/dfst/deepforge-caffe).
+1
Ver Arquivo
@@ -4,6 +4,7 @@ var spawn = require('child_process').spawn,
execJob,
workerJob = null;
process.env.NODE_ENV = 'local';
execJob = spawn('npm', [
'start'
]);
+13 -3
Ver Arquivo
@@ -1,8 +1,9 @@
'use strict';
/*globals process, __dirname, require*/
var path = require('path'),
fs = require('fs'),
spawn = require('child_process').spawn,
childProcess = require('child_process'),
spawn = childProcess.spawn,
projectConfig = require(__dirname + '/../config'),
executorSrc = path.join(__dirname, '..', 'node_modules', 'webgme', 'src',
'server', 'middleware', 'executor', 'worker'),
@@ -12,13 +13,22 @@ var path = require('path'),
address,
config = {};
// Check torch support
var result = childProcess.spawnSync('th', ['--help']);
if (result.error) {
console.error('Checking Torch7 dependency failed. Do you have Torch7 installed ' +
'and in your PATH?\n\nFor Torch7 installation instructions, check out ' +
'http://torch.ch/docs/getting-started.html');
process.exit(1);
}
var startExecutor = function() {
// Start the executor
var execJob = spawn('node', [
'node_worker.js',
workerConfigPath,
workerTmp
]);
]);
execJob.stdout.pipe(process.stdout);
execJob.stderr.pipe(process.stderr);
};
+37 -9
Ver Arquivo
@@ -3,6 +3,13 @@
"hotkeys": "none",
"LayerColors": {}
},
"FloatingActionButton": {
"hideOnEmpty": true
},
"GenericUIProjectNavigatorController": {
"rootMenuClass": "deepforge-logo",
"rootDisplayName": "DeepForge"
},
"CHFLayout": {
"panels": [
{
@@ -13,7 +20,7 @@
},
{
"id": "Footer",
"panel": "FooterControls/FooterControlsPanel",
"panel": "Footer/FooterPanel",
"container": "footer",
"DEBUG_ONLY": false
},
@@ -36,26 +43,47 @@
"nodes": [
{
"nodeName": "MyArchitectures",
"icon": "shuffle",
"rank": 1,
"description": "Neural network architectures are stored here and can be used in pipelines."
},
{
"nodeName": "MyExecutions",
"description": "Executions are read-only snapshots of pipelines that have been executed. Past and current executing pipelines are stored here."
},
{
"nodeName": "MyPipelines",
"description": "Pipelines are used for training, testing and ensembling models."
},
{
"nodeName": "MyOperations",
"icon": "mode_edit",
"rank": 2,
"color": "blue-grey",
"description": "Operations are the building blocks of pipelines. Custom operations can be created and stored here."
},
{
"nodeName": "MyPipelines",
"icon": "input",
"rank": 3,
"description": "Pipelines compose operations together to effectively train, test and/or ensemble models."
},
{
"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": 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": 7,
"description": "Custom defined data types are stored here."
}
]
+4 -1
Ver Arquivo
@@ -4,7 +4,8 @@
var config = require('./config.webgme'),
validateConfig = require('webgme/config/validator');
require('dotenv').load();
require('dotenv').load({silent: true});
// Add/overwrite any additional settings here
config.server.port = process.env.PORT || config.server.port;
config.mongo.uri = process.env.MONGO_URI || config.mongo.uri;
@@ -16,5 +17,7 @@ config.plugin.allowServerExecution = true;
config.executor.enable = true;
config.visualization.extraCss.push('deepforge/styles/global.css');
validateConfig(config);
module.exports = config;
+1 -2
Ver Arquivo
@@ -9,8 +9,7 @@ var config = require('./config.base'),
// config.mongo.uri = 'mongodb://127.0.0.1:27017/webgme_my_app';
// Seeds for development are prefixed with 'dev'
config.seedProjects.basePaths = config.seedProjects.basePaths
.filter(path => path.indexOf('dev') === -1);
config.seedProjects.basePaths = ['src/seeds/project'];
validateConfig(config);
module.exports = config;
+13
Ver Arquivo
@@ -0,0 +1,13 @@
// Config for running deepforge w/ one local worker
// jshint node: true
'use strict';
var config = require('./config.default'),
validateConfig = require('webgme/config/validator');
// Turn up the worker polling rate
config.executor.workerRefreshInterval = 150;
config.executor.clearOldDataAtStartUp = true,
validateConfig(config);
module.exports = config;
-1
Ver Arquivo
@@ -15,7 +15,6 @@ 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/devMinimal');
config.seedProjects.basePaths.push('src/seeds/devUtilTests');
config.seedProjects.basePaths.push('src/seeds/pipeline');
config.seedProjects.basePaths.push('src/seeds/devPipelineTests');
+86
Ver Arquivo
@@ -0,0 +1,86 @@
#!/usr/bin/env bash
# Things to install:
# - nvm
command -v git >/dev/null 2>&1 || { echo >&2 "I require git but it's not installed. Aborting."; exit 1; }
echo >&2 "Checking DeepForge dependencies...";
command -v th >/dev/null 2>&1 || {
# No torch!
echo >&2 "Torch is not found. Installing...";
git clone https://github.com/torch/distro.git ~/torch --recursive;
cd ~/torch; bash install-deps;
./install.sh;
}
# profile (bash, zsh, profile, etc) borrowed from nvm's installer
detect_profile() {
if [ -n "$PROFILE" -a -f "$PROFILE" ]; then
echo "$PROFILE"
return
fi
DETECTED_PROFILE=''
local SHELLTYPE
SHELLTYPE="$(basename "/$SHELL")"
if [ "$SHELLTYPE" = "bash" ]; then
if [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile"
fi
elif [ "$SHELLTYPE" = "zsh" ]; then
DETECTED_PROFILE="$HOME/.zshrc"
fi
if [ -z "$DETECTED_PROFILE" ]; then
if [ -f "$HOME/.profile" ]; then
DETECTED_PROFILE="$HOME/.profile"
elif [ -f "$HOME/.bashrc" ]; then
DETECTED_PROFILE="$HOME/.bashrc"
elif [ -f "$HOME/.bash_profile" ]; then
DETECTED_PROFILE="$HOME/.bash_profile"
elif [ -f "$HOME/.zshrc" ]; then
DETECTED_PROFILE="$HOME/.zshrc"
fi
fi
}
detect_profile
command -v node >/dev/null 2>&1 || {
# No node! Install nvm
echo >&2 "NodeJS is not found. Installing (using nvm)...";
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.31.1/install.sh | bash;
source $DETECTED_PROFILE
# Install nodejs v6.2.0
echo "Installing nodejs v6.2.0"
nvm install v6.2.0
nvm alias default v6.2.0
# Install npm@2
npm install npm@2 -g
}
command -v node >/dev/null 2>&1 || {
# No mongod!
echo >&2 "MongoDB is not found. Installing...";
if [[ `uname` == "Darwin" ]]; then
brew install mongodb
fi
}
echo >&2 "Installing DeepForge...";
# Clone deepforge into ~/deepforge
git clone https://github.com/dfst/deepforge ~/deepforge
cd ~/deepforge
npm install
mkdir ~/deepforge/data 2> /dev/null
echo "DeepForge is installed! To run it:"
echo " 1) make sure MongoDB is running locally"
echo " (start mongo w/ \"mongod --dbpath ~/deepforge/data\")"
echo " 2) Run \"npm run local\" from ~/deepforge"
+7 -4
Ver Arquivo
@@ -3,20 +3,23 @@
"scripts": {
"start": "node app.js",
"start-dev": "NODE_ENV=dev node app.js",
"worker": "node ./bin/start-worker.js",
"local": "node ./bin/start-local.js",
"test": "node ./node_modules/mocha/bin/mocha --recursive test"
"worker": "node ./bin/start-worker.js",
"test": "node ./node_modules/mocha/bin/mocha --recursive 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.4.0",
"version": "0.6.0",
"dependencies": {
"dotenv": "^2.0.0",
"lodash.difference": "^4.1.2",
"nodemon": "^1.9.2",
"webgme": "^2.0.0",
"webgme-autoviz": "^2.0.3",
"webgme-breadcrumbheader": "^2.0.0",
"webgme-chflayout": "^2.0.0",
"webgme-easydag": "dfst/webgme-easydag",
"webgme-fab": "^2.0.2",
"webgme-fab": "dfst/webgme-fab",
"webgme-simple-nodes": "^2.0.0"
},
"devDependencies": {
Diferenças do arquivo suprimidas por serem muito extensas Carregar Diff
+48
Ver Arquivo
@@ -0,0 +1,48 @@
/*globals define, WebGMEGlobal*/
define([
'q'
], function(
Q
) {
var PtrCodeGen = function() {
};
PtrCodeGen.prototype.getPtrCodeHash = function(ptrId) {
return this.core.loadByPath(this.rootNode, ptrId)
.then(ptrNode => {
// Look up the plugin to use
var metanode = this.core.getMetaType(ptrNode),
pluginId;
pluginId = this.core.getRegistry(ptrNode, 'validPlugins').split(' ').shift();
this.logger.info(`generating code for ${this.core.getAttribute(ptrNode, 'name')} using ${pluginId}`);
var context = WebGMEGlobal.Client.getCurrentPluginContext(pluginId);
context.managerConfig.namespace = this.core.getNamespace(metanode);
context.managerConfig.activeNode = this.core.getPath(ptrNode);
// Load and run the plugin
return Q.nfcall(this.executePlugin.bind(this), pluginId, context);
})
.then(hashes => hashes[0]); // Grab the first asset for now
};
PtrCodeGen.prototype.executePlugin = function(pluginId, config, callback) {
// Call the Interpreter manager in a Q.ninvoke friendly way
// I need to create a custom context for the given plugin:
// - Set the activeNode to the given referenced node
// - If the activeNode is namespaced, set META to the given namespace
//
// FIXME: Check if it is running in the browser or on the server
WebGMEGlobal.Client.runBrowserPlugin(pluginId, config, (err, result) => {
if (!result.success) {
return callback(result.getError());
}
this.logger.info('Finished calling ' + pluginId);
callback(null, result.artifacts);
});
};
return PtrCodeGen;
});
+20
Ver Arquivo
@@ -0,0 +1,20 @@
/* latin-ext */
@font-face {
font-family: 'Audiowide';
font-style: normal;
font-weight: 400;
src: local('Audiowide'), local('Audiowide-Regular'), url(https://fonts.gstatic.com/s/audiowide/v4/7pSgz2MbVvTCvvm7vukSHxJtnKITppOI_IvcXXDNrsc.woff2) format('woff2');
unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Audiowide';
font-style: normal;
font-weight: 400;
src: local('Audiowide'), local('Audiowide-Regular'), url(https://fonts.gstatic.com/s/audiowide/v4/8XtYtNKEyyZh481XVWfVOltXRa8TVwTICgirnJhmVJw.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000;
}
.deepforge-logo .item-label {
font-family: 'Audiowide', cursive;
}
@@ -0,0 +1,43 @@
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
/**
* @author brollb / https://github.com/brollb
*/
define([
'js/Decorators/DecoratorBase',
'./EasyDAG/ArtifactOpDecorator.EasyDAGWidget'
], function (
DecoratorBase,
ArtifactOpDecoratorEasyDAGWidget
) {
'use strict';
var ArtifactOpDecorator,
__parent__ = DecoratorBase,
__parent_proto__ = DecoratorBase.prototype,
DECORATOR_ID = 'ArtifactOpDecorator';
ArtifactOpDecorator = function (params) {
var opts = _.extend({loggerName: this.DECORATORID}, params);
__parent__.apply(this, [opts]);
this.logger.debug('ArtifactOpDecorator ctor');
};
_.extend(ArtifactOpDecorator.prototype, __parent_proto__);
ArtifactOpDecorator.prototype.DECORATORID = DECORATOR_ID;
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
ArtifactOpDecorator.prototype.initializeSupportedWidgetMap = function () {
this.supportedWidgetMap = {
EasyDAG: ArtifactOpDecoratorEasyDAGWidget
};
};
return ArtifactOpDecorator;
});
@@ -0,0 +1,43 @@
/**
* @author brollb / https://github.com/brollb
*/
.artifactop-decorator {
min-width: 65px;
height: 40px;
border: 1px solid black;
background-color: #dedede;
padding: 3px;
text-align: center; }
.artifactop-decorator .attr-title {
font-style: italic;
}
.artifactop-decorator .name {
margin-top: 10px;
white-space: nowrap;
font-size: 16px;
font-weight: bold;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
text-align: center; }
.artifactop-decorator .connector {
background-color: #fefefe;
height: 10px;
width: 10px;
position: absolute;
cursor: pointer;
border: 1px solid blue;
z-index: 10;
margin-left: -6px;
left: 50%; }
.artifactop-decorator .connector:hover {
border-color: rgba(82, 168, 236, 0.8);
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
.artifactop-decorator .connector.top {
top: -6px; }
.artifactop-decorator .connector.bottom {
bottom: -6px; }
.selected .artifactop-decorator {
border: 1px solid #52a8ec;
background-color: #dbeafc; }
@@ -0,0 +1,102 @@
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
/**
* @author brollb / https://github.com/brollb
*/
define([
'js/Constants',
'decorators/DcOpDecorator/EasyDAG/DcOpDecorator.EasyDAGWidget',
'css!./ArtifactOpDecorator.EasyDAGWidget.css'
], function (
CONSTANTS,
DecoratorBase
) {
'use strict';
var ArtifactOpDecorator,
DECORATOR_ID = 'ArtifactOpDecorator',
CAST_OPTS = {
ArtifactLoader: {
ptr: 'artifact',
metaTgt: false
},
ArtifactFinder: {
ptr: 'type',
metaTgt: true
}
};
// ArtifactOp nodes need to be able to...
// - dynamically change their outputs (downcast)
ArtifactOpDecorator = function (options) {
options.color = options.color || '#b0bec5';
DecoratorBase.call(this, options);
// set the opts...
this.castOpts = CAST_OPTS[this._node.baseName];
};
_.extend(ArtifactOpDecorator.prototype, DecoratorBase.prototype);
ArtifactOpDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
ArtifactOpDecorator.prototype.getTargetFilterFnFor = function() {
return id => {
var node = this.client.getNode(id),
isMetaTgt = node.getId() === node.getMetaTypeId();
return isMetaTgt === this.castOpts.metaTgt;
};
};
ArtifactOpDecorator.prototype.savePointer = function(name, to) {
// When the 'artifact' pointer is changed, we should change the base
// of the data output node to the target type
if (name === this.castOpts.ptr && (typeof to === 'string')) {
this.client.startTransaction(`Setting output of ${this.name} to ${to}`);
this.castOutputType(to);
this.client.makePointer(this._node.id, name, to);
this.client.completeTransaction();
} else {
DecoratorBase.prototype.savePointer.call(this, name, to);
}
};
ArtifactOpDecorator.prototype.getDisplayName = function() {
var ptrName = this._node.baseName === 'ArtifactLoader' ? 'artifact' : 'type',
id = this._node.pointers[ptrName],
name = this.nameFor[id] || this._node.name;
return name;
};
ArtifactOpDecorator.prototype.updateDisplayName = function() {
var newName = this.getDisplayName();
if (this.name !== newName) {
this.name = newName;
this.nameWidth = null;
}
};
ArtifactOpDecorator.prototype.updateTargetName = function(id, name) {
DecoratorBase.prototype.updateTargetName.apply(this, arguments);
// Update name
var ptrName = this._node.baseName === 'ArtifactLoader' ? 'artifact' : 'type';
if (this._node.pointers[ptrName] === id) {
this._name = name;
this.onResize();
}
};
ArtifactOpDecorator.prototype.expand = function() {
this.updateDisplayName();
DecoratorBase.prototype.expand.call(this);
};
ArtifactOpDecorator.prototype.condense = function() {
this.updateDisplayName();
DecoratorBase.prototype.condense.call(this);
};
return ArtifactOpDecorator;
});
@@ -0,0 +1,43 @@
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
/**
* @author brollb / https://github.com/brollb
*/
define([
'js/Decorators/DecoratorBase',
'./EasyDAG/DcOpDecorator.EasyDAGWidget'
], function (
DecoratorBase,
DcOpDecoratorEasyDAGWidget
) {
'use strict';
var DcOpDecorator,
__parent__ = DecoratorBase,
__parent_proto__ = DecoratorBase.prototype,
DECORATOR_ID = 'DcOpDecorator';
DcOpDecorator = function (params) {
var opts = _.extend({loggerName: this.DECORATORID}, params);
__parent__.apply(this, [opts]);
this.logger.debug('DcOpDecorator ctor');
};
_.extend(DcOpDecorator.prototype, __parent_proto__);
DcOpDecorator.prototype.DECORATORID = DECORATOR_ID;
/*********************** OVERRIDE DecoratorBase MEMBERS **************************/
DcOpDecorator.prototype.initializeSupportedWidgetMap = function () {
this.supportedWidgetMap = {
EasyDAG: DcOpDecoratorEasyDAGWidget
};
};
return DcOpDecorator;
});
@@ -0,0 +1,43 @@
/**
* @author brollb / https://github.com/brollb
*/
.dcop-decorator {
min-width: 65px;
height: 40px;
border: 1px solid black;
background-color: #dedede;
padding: 3px;
text-align: center; }
.dcop-decorator .attr-title {
font-style: italic;
}
.dcop-decorator .name {
margin-top: 10px;
white-space: nowrap;
font-size: 16px;
font-weight: bold;
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
text-align: center; }
.dcop-decorator .connector {
background-color: #fefefe;
height: 10px;
width: 10px;
position: absolute;
cursor: pointer;
border: 1px solid blue;
z-index: 10;
margin-left: -6px;
left: 50%; }
.dcop-decorator .connector:hover {
border-color: rgba(82, 168, 236, 0.8);
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
-moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); }
.dcop-decorator .connector.top {
top: -6px; }
.dcop-decorator .connector.bottom {
bottom: -6px; }
.selected .dcop-decorator {
border: 1px solid #52a8ec;
background-color: #dbeafc; }
@@ -0,0 +1,79 @@
/*globals define, _*/
/*jshint browser: true, camelcase: false*/
/**
* @author brollb / https://github.com/brollb
*/
define([
'js/Constants',
'decorators/OperationDecorator/EasyDAG/OperationDecorator.EasyDAGWidget',
'css!./DcOpDecorator.EasyDAGWidget.css'
], function (
CONSTANTS,
DecoratorBase
) {
'use strict';
var DcOpDecorator,
DECORATOR_ID = 'DcOpDecorator';
// DcOp nodes need to be able to...
// - dynamically change their outputs (downcast)
DcOpDecorator = function (options) {
options.color = options.color || '#78909c';
DecoratorBase.call(this, options);
};
_.extend(DcOpDecorator.prototype, DecoratorBase.prototype);
DcOpDecorator.prototype.DECORATOR_ID = DECORATOR_ID;
DcOpDecorator.prototype.getTargetFilterFnFor = function() {
return id => {
var node = this.client.getNode(id);
return node.getId() !== node.getMetaTypeId(); // not meta node
};
};
DcOpDecorator.prototype.castOutputType = function(targetId) {
var target = this.client.getNode(targetId),
baseId = target.getBaseId(),
outputId = this._node.outputs[0] && this._node.outputs[0].id,
hash;
if (!outputId) {
// create the outputId node
outputId = this._createOutputNode(baseId);
} else {
this.client.makePointer(outputId, CONSTANTS.POINTER_BASE, baseId);
}
// Copy the data content to the output node
hash = target.getAttribute('data');
this.client.setAttributes(outputId, 'data', hash);
};
DcOpDecorator.prototype._createOutputNode = function(baseId) {
var n = this.client.getNode(this._node.id),
outputCntrId;
outputCntrId = n.getChildrenIds().find(id => {
var metaTypeId = this.client.getNode(id).getMetaTypeId(),
metaType = this.client.getNode(metaTypeId);
if (!metaType) {
this.logger.error(`Could not check the type of ${id}!`);
return false;
}
return metaType.getAttribute('name') === 'Outputs';
});
return this.client.createChild({
baseId: baseId,
parentId: outputCntrId
});
};
return DcOpDecorator;
});
@@ -29,6 +29,13 @@ define([
// - unhighlight ports
// - report the location of specific ports
JobDecorator = function (options) {
options.skipAttributes = {
name: true,
status: true,
execFiles: true,
stdout: true,
debug: true
};
EllipseDecorator.call(this, options);
};
@@ -42,7 +49,8 @@ define([
JobDecorator.prototype.setAttributes = function() {
EllipseDecorator.prototype.setAttributes.call(this);
var status = this._attributes.status && this._attributes.status.value;
var attrs = this._node.attributes,
status = attrs.status && attrs.status.value;
// Update the color based on the 'status' attr
this.color = COLORS[status] || COLORS.fail;
@@ -1,4 +1,4 @@
/*globals define, _*/
/*globals define, _, Opentip*/
/*jshint browser: true, camelcase: false*/
/**
@@ -16,7 +16,12 @@ define([
var OperationDecorator,
NAME_MARGIN = 25,
DECORATOR_ID = 'OperationDecorator';
DECORATOR_ID = 'OperationDecorator',
PORT_TOOLTIP_OPTS = {
tipJoint: 'left',
removeElementsOnHide: true,
style: 'dark'
};
// Operation nodes need to be able to...
// - show their ports
@@ -30,6 +35,7 @@ define([
this.id = this._node.id;
this.$ports = this.$el.append('g')
.attr('id', 'ports');
this.$portTooltips = {};
};
_.extend(OperationDecorator.prototype, DecoratorBase.prototype);
@@ -91,7 +97,8 @@ define([
OperationDecorator.prototype.renderPort = function(port, x, y, isInput) {
var color = this.PORT_COLOR.OPEN,
portIcon = this.$ports.append('g');
portIcon = this.$ports.append('g'),
tooltip;
// If the port is incoming and occupied, render it differently
if (isInput && port.connection) {
@@ -115,14 +122,26 @@ define([
portIcon.on('click', this.onPortClick.bind(this, this.id, port.id, !isInput));
// Add tooltip with whole name
// TODO
if (this.$portTooltips[port.id]) {
this.$portTooltips[port.id].hide();
}
tooltip = new Opentip(portIcon[0][0], PORT_TOOLTIP_OPTS);
tooltip.setContent(port.name);
portIcon.on('mouseenter', () => tooltip.show());
portIcon.on('mouseout', () => tooltip.hide());
this.$portTooltips[port.id] = tooltip;
};
OperationDecorator.prototype.hidePorts = function() {
var visiblePortIds = Object.keys(this.$portTooltips);
this.logger.info(`hiding ports for ${this.name} (${this.id})`);
this.$ports.remove();
this.$ports = this.$el.append('g')
.attr('id', 'ports');
for (var i = visiblePortIds.length; i--;) {
this.$portTooltips[visiblePortIds[i]].hide();
}
};
OperationDecorator.prototype.getPortLocation = function(id, isInput) {
+191 -47
Ver Arquivo
@@ -9,12 +9,22 @@ define([
'plugin/PluginConfig',
'plugin/PluginBase',
'deepforge/js-yaml.min',
'text!deepforge/layers.yml',
'common/util/guid',
'js/RegistryKeys',
'js/Constants',
'js/Panels/MetaEditor/MetaEditorConstants',
'underscore',
'text!deepforge/layers.json',
'text!./metadata.json'
], function (
PluginConfig,
PluginBase,
yaml,
generateGuid,
REGISTRY_KEYS,
CONSTANTS,
META_CONSTANTS,
_,
DEFAULT_LAYERS,
metadata
) {
@@ -31,6 +41,8 @@ define([
// Call base class' constructor.
PluginBase.call(this);
this.pluginMetadata = CreateTorchMeta.metadata;
this.metaSheets = {};
this.sheetCounts = {};
};
CreateTorchMeta.metadata = JSON.parse(metadata);
@@ -58,7 +70,7 @@ define([
}
// Extra layer names
this.getYamlText((err, text) => {
this.getJsonLayers((err, text) => {
if (err) {
return callback(err, this.result);
}
@@ -67,15 +79,25 @@ define([
// - (Abstract) CategoryLayerTypes
// - LayerName
// - Attributes (if exists)
var content,
var content = {},
categories,
nodes = {};
config = this.getCurrentConfig(),
nodes = {},
layers;
try {
content = yaml.load(text);
layers = JSON.parse(text)
.filter(layer => layer.type !== 'Criterion');
} catch (e) {
return callback('YAML parse error: ' + e, this.result);
return callback('JSON parse error: ' + e, this.result);
}
layers.forEach(layer => {
if (!content[layer.type]) {
content[layer.type] = [];
}
content[layer.type].push(layer);
});
categories = Object.keys(content);
// Create the base class, if needed
if (!this.META.Layer) {
@@ -84,23 +106,52 @@ define([
// Create the category nodes
categories
.forEach(name => nodes[name] = this.createMetaNode(name, this.META.Layer));
.forEach(name => {
// Create a tab for each
this.metaSheets[name] = this.createMetaSheetTab(name);
this.sheetCounts[name] = 0;
nodes[name] = this.createMetaNode(name, this.META.Layer, name);
});
// Make them abstract
categories
.forEach(name => this.core.setRegistry(nodes[name], 'isAbstract', true));
if (config.removeOldLayers) {
var isNewLayer = {},
newLayers = layers.map(layer => layer.name),
oldLayers,
oldNames;
newLayers = newLayers.concat(categories); // add the category nodes
newLayers.forEach(name => isNewLayer[name] = true);
// Set the newLayer nodes 'base' to 'Layer' so we don't accidentally
// delete them
newLayers
.map(name => this.META[name])
.filter(layer => !!layer)
.forEach(layer => this.core.setPointer(layer, 'base', this.META.Layer));
oldLayers = Object.keys(this.META)
.filter(name => name !== 'Layer')
.map(name => this.META[name])
.filter(node => this.isMetaTypeOf(node, this.META.Layer))
.filter(node => !isNewLayer[this.core.getAttribute(node, 'name')]);
oldNames = oldLayers.map(l => this.core.getAttribute(l, 'name'));
// Get the old layer names
this.logger.debug(`Removing layers: ${oldNames.join(', ')}`);
oldLayers.forEach(layer => this.core.deleteNode(layer));
}
// Create the actual nodes
categories.forEach(cat => {
content[cat]
.forEach(name => {
var attrs = null;
if (typeof name !== 'string') {
attrs = name[Object.keys(name)[0]];
name = Object.keys(name)[0];
}
nodes[name] = this.createMetaNode(name, nodes[cat], attrs);
.forEach(layer => {
var attrs = layer.params,
name = layer.name;
nodes[name] = this.createMetaNode(name, nodes[cat], cat, attrs);
// Make the node non-abstract
this.core.setRegistry(nodes[name], 'isAbstract', false);
});
@@ -115,11 +166,48 @@ define([
callback(null, self.result);
});
});
};
CreateTorchMeta.prototype.getYamlText = function (callback) {
CreateTorchMeta.prototype.removeFromMeta = function (nodeId) {
var sheets = this.core.getRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS),
sheet;
// Remove from meta
this.core.delMember(this.rootNode, META_CONSTANTS.META_ASPECT_SET_NAME, nodeId);
// Remove from the given meta sheet
sheet = sheets.find(sheet => {
var paths = this.core.getMemberPaths(this.rootNode, sheet.SetID);
return paths.indexOf(nodeId) > -1;
});
if (sheet) {
this.core.delMember(this.rootNode, sheet.SetID, nodeId);
}
};
CreateTorchMeta.prototype.createMetaSheetTab = function (name) {
var sheets = this.core.getRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS),
id = META_CONSTANTS.META_ASPECT_SHEET_NAME_PREFIX + generateGuid(),
sheet,
desc = {
SetID: id,
order: sheets.length,
title: name
};
sheet = sheets.find(sheet => sheet.title === name);
if (!sheet) {
sheet = desc;
this.logger.debug(`creating meta sheet "${name}"`);
this.core.createSet(this.rootNode, sheet.SetID);
sheets.push(sheet);
this.core.setRegistry(this.rootNode, REGISTRY_KEYS.META_SHEETS, sheets);
}
return sheet.SetID;
};
CreateTorchMeta.prototype.getJsonLayers = function (callback) {
var config = this.getCurrentConfig();
if (config.layerNameHash) {
@@ -135,41 +223,72 @@ define([
}
};
CreateTorchMeta.prototype.createMetaNode = function (name, base, attrs) {
var node;
CreateTorchMeta.prototype.createMetaNode = function (name, base, tabName, attrs) {
var node = this.META[name],
nodeId = node && this.core.getPath(node),
tabId = this.metaSheets[tabName],
position = this.getPositionFor(name, tabName);
if (this.META[name]) {
this.logger.warn('"' + name + '" already exists. skipping...');
return this.META[name];
if (!tabId) {
this.logger.error(`No meta sheet for ${tabName}`);
}
// Create a node
node = this.core.createNode({
parent: this.META.Language,
base: base
});
this.core.setAttribute(node, 'name', name);
if (!node) {
// Create a node
node = this.core.createNode({
parent: this.META.Language,
base: base
});
this.core.setAttribute(node, 'name', name);
nodeId = this.core.getPath(node);
} else {
// Remove from meta
this.removeFromMeta(nodeId);
this.core.setPointer(node, 'base', base);
}
// Add it to the meta sheet
this.core.addMember(this.rootNode, 'MetaAspectSet', node);
this.core.addMember(this.rootNode, META_CONSTANTS.META_ASPECT_SET_NAME, node);
this.core.addMember(this.rootNode, tabId, node);
// Add it to a tab of the meta sheet
var set = this.core.getSetNames(this.rootNode)
.find(name => name !== 'MetaAspectSet');
this.core.addMember(this.rootNode, set, node);
// TODO: Position the nodes on the META
// TODO: Put each group of nodes on their own META sheet
this.core.setMemberRegistry(
this.rootNode,
META_CONSTANTS.META_ASPECT_SET_NAME,
nodeId,
REGISTRY_KEYS.POSITION,
position
);
this.core.setMemberRegistry(
this.rootNode,
tabId,
nodeId,
REGISTRY_KEYS.POSITION,
position
);
if (attrs) { // Add the attributes
attrs.forEach((name, index) => {
var desc = null;
if (typeof name !== 'string') {
desc = name[Object.keys(name)[0]];
name = Object.keys(name)[0];
// Remove attributes not in the given list
var currentAttrs = this.core.getValidAttributeNames(node),
rmAttrs;
rmAttrs = _.difference(currentAttrs, attrs) // old attribute names
.filter(attr => attr !== 'name');
if (rmAttrs.length) {
this.logger.debug(`Removing ${rmAttrs.join(', ')} from ${name}`);
}
rmAttrs.forEach(attr => {
this.core.delAttributeMeta(node, attr);
if (this.core.getOwnAttribute(node, attr) !== undefined) {
this.core.delAttribute(node, attr);
}
desc = desc || {};
});
attrs.forEach((name, index) => {
var desc = {};
desc.argindex = index;
desc.default = '';
this.addAttribute(name, node, desc);
});
}
@@ -178,11 +297,38 @@ define([
return node;
};
CreateTorchMeta.prototype.getPositionFor = function(name, tabName) {
var index = this.sheetCounts[tabName],
dx = 140,
dy = 100,
MAX_WIDTH = 1200,
x;
if (tabName === 'Convolution') {
dx *= 1.3;
dy *= 1.5;
}
this.sheetCounts[tabName]++;
if (index === 0) {
return {
x: MAX_WIDTH/2,
y: 50
};
}
x = dx*index;
return {
x: x%MAX_WIDTH,
y: Math.floor(x/MAX_WIDTH+1)*dy + 50
};
};
CreateTorchMeta.prototype.addAttribute = function (name, node, def) {
var initial,
schema = {};
schema.type = def.type || 'integer';
schema.type = def.type || 'string';
if (schema.type === 'list') { // FIXME: add support for lists
schema.type = 'string';
}
@@ -212,9 +358,7 @@ define([
if (schema.type === 'boolean') {
initial = initial !== null ? initial : false;
}
if (initial !== null) { // optional attribute - set default value
this.core.setAttribute(node, name, initial);
}
this.core.setAttribute(node, name, initial);
};
return CreateTorchMeta;
+9 -1
Ver Arquivo
@@ -1,6 +1,6 @@
{
"id": "CreateTorchMeta",
"name": "Create Torch Meta",
"name": "Update nn meta",
"version": "0.1.0",
"description": "Create metamodel from Torch yaml",
"icon": {
@@ -17,6 +17,14 @@
"value": "",
"valueType": "asset",
"readOnly": false
},
{
"name": "removeOldLayers",
"displayName": "Delete old layers",
"description": "Delete all layers not in the current description",
"value": true,
"valueType": "boolean",
"readOnly": false
}
]
}
+224 -138
Ver Arquivo
@@ -1,25 +1,25 @@
/*globals define, WebGMEGlobal*/
/*globals define */
/*jshint node:true, browser:true, esversion: 6*/
define([
'plugin/CreateExecution/CreateExecution/CreateExecution',
'deepforge/plugin/PtrCodeGen',
'common/core/constants',
'q',
'text!./metadata.json',
'./Templates/index',
'./templates/index',
'./LocalExecutor',
'executor/ExecutorClient',
'jszip',
'underscore'
], function (
CreateExecution,
PtrCodeGen,
CONSTANTS,
Q,
pluginMetadata,
Templates,
LocalExecutor, // DeepForge operation primitives
ExecutorClient,
JsZip,
_
) {
'use strict';
@@ -32,24 +32,15 @@ define([
* @classdesc This class represents the plugin ExecutePipeline.
* @constructor
*/
var OUTPUT_INTERVAL = 1500,
STDOUT_FILE = 'job_stdout.txt';
var ExecutePipeline = function () {
// Call base class' constructor.
CreateExecution.call(this);
this.pluginMetadata = pluginMetadata;
// Cache
this.nodes = {};
// Record keeping for running operations
this.opFor = {};
this.incomingCounts = {};
this.outputsOf = {};
this.inputPortsFor = {};
this.inputs = {};
this.finished = {};
this.completedCount = 0;
this.totalCount = 0;
this._currentSave = Q();
this.initRun();
};
/**
@@ -64,6 +55,23 @@ define([
ExecutePipeline.prototype = Object.create(CreateExecution.prototype);
ExecutePipeline.prototype.constructor = ExecutePipeline;
ExecutePipeline.prototype.initRun = function () {
// Cache
this.nodes = {};
// Record keeping for running operations
this.opFor = {};
this.incomingCounts = {};
this.outputsOf = {};
this.inputPortsFor = {};
this.inputs = {};
this.finished = {};
this.completedCount = 0;
this.totalCount = 0;
this.outputLineCount = {};
};
/**
* Main function for the plugin to execute. This will perform the execution.
* Notes:
@@ -78,6 +86,8 @@ define([
// inputs for the next operation cannot be created until the inputs have
// been generated
this.initRun();
this.pipelineName = this.core.getAttribute(this.activeNode, 'name');
var startPromise;
if (this.core.isTypeOf(this.activeNode, this.META.Pipeline)) {
// If starting with a pipeline, we will create an Execution first
@@ -103,34 +113,49 @@ define([
this.buildCache(subtree);
this.parsePipeline(children); // record deps, etc
//if (this.getCurrentConfig().reset) {
this.clearResults();
//}
// Execute the operations in the proper order
this.executePipeline();
return this.clearResults();
})
.then(() => this.executePipeline())
.fail(e => this.logger.error(e));
};
// Override 'save' to prevent race conditions while saving
ExecutePipeline.prototype.save = function (msg) {
// When 'save' is called, it should still finish any current save op
// before continuing
this._currentSave = this._currentSave
.then(() => CreateExecution.prototype.save.call(this, msg));
return this._currentSave;
};
ExecutePipeline.prototype.isInputData = function (node) {
var prnt = this.core.getParent(node);
return this.core.isTypeOf(prnt, this.META.Inputs);
};
ExecutePipeline.prototype.clearResults = function () {
var nodes = Object.keys(this.nodes).map(id => this.nodes[id]);
// Clear the pipeline's results
this.logger.info('Clearing all intermediate execution results');
nodes.filter(node => this.core.isTypeOf(node, this.META.Data))
// Only input data nodes should be cleared. Outputs will be overwritten
.filter(node => this.isInputData(node))
.forEach(conn => this.core.delAttribute(conn, 'data'));
// Set the status for each job to 'pending'
nodes.filter(node => this.core.isTypeOf(node, this.META.Job))
.forEach(node => this.core.setAttribute(node, 'status', 'pending'));
this.logger.info('Setting all jobs status to "pending"');
this.logger.debug(`Making a commit from ${this.currentHash}`);
return this.save(`Initializing ${this.pipelineName} for execution`);
};
//////////////////////////// Operation Preparation/Execution ////////////////////////////
ExecutePipeline.prototype.buildCache = function (nodes) {
// Cache all nodes
// Do I need to cache the data inputs? TODO
// Probably not - I should be able to look them up as needed
nodes.forEach(node => this.nodes[this.core.getPath(node)] = node);
};
@@ -235,8 +260,10 @@ define([
// Execute all ready operations
readyOps.forEach(jobId => {
delete this.incomingCounts[jobId];
this.executeOperation(jobId);
});
readyOps.reduce((prev, jobId) => {
return prev.then(() => this.executeOperation(jobId));
}, Q());
return readyOps.length;
};
@@ -259,11 +286,12 @@ define([
inputs;
// Execute any special operation types here - not on an executor
this.logger.debug(`Executing operation "${name}"`);
if (localTypeId !== null) {
this.executeLocalOperation(localTypeId, node);
return this.executeLocalOperation(localTypeId, node);
} else {
// Generate all execution files
this.createOperationFiles(node).then(results => {
return this.createOperationFiles(node).then(results => {
files = results;
artifactName = `${name}_${jobId.replace(/\//g, '_')}-execution-files`;
artifact = this.blobClient.createArtifact(artifactName);
@@ -306,8 +334,8 @@ define([
})
.then(outputArgs => {
var config,
args = ['init.lua'],
outputs;
outputs,
file;
outputs = outputArgs.map(pair => pair[0])
.map(name => {
@@ -317,8 +345,12 @@ define([
};
});
outputs.push({
name: 'stdout',
resultPatterns: [STDOUT_FILE]
});
if (this.debug) {
args.push('#' + Date.now());
outputs.push({
name: name + '-all-files',
resultPatterns: []
@@ -326,13 +358,22 @@ define([
}
config = {
cmd: 'th',
args: args,
cmd: 'bash',
args: ['run.sh'],
outputInterval: OUTPUT_INTERVAL,
resultArtifacts: outputs
};
files['executor_config.json'] = JSON.stringify(config, null, 4);
files['run.sh'] = Templates.BASH;
// Save the artifact
// Remove empty hashes
for (file in data) {
if (!data[file]) {
this.logger.warn(`Empty data hash has been found for file "${file}". Removing it...`);
delete data[file];
}
}
return artifact.addObjectHashes(data);
})
.then(() => {
@@ -350,6 +391,7 @@ define([
})
.fail(e => {
this.core.setAttribute(this.nodes[jobId], 'status', 'fail');
this.logger.info(`Setting ${jobId} status to "fail"`);
this.onPipelineComplete(`Distributed operation "${name}" failed ${e}`);
});
}
@@ -365,21 +407,48 @@ define([
this.logger.info(`Executing operation "${name}"`);
this.outputLineCount[jobId] = 0;
// Set the job status to 'running'
this.core.setAttribute(this.nodes[jobId], 'status', 'running');
// Run the operation on an executor
executor.createJob({hash})
this.core.setAttribute(this.nodes[jobId], 'stdout', '');
this.logger.info(`Setting ${jobId} status to "running" (${this.currentHash})`);
this.logger.debug(`Making a commit from ${this.currentHash}`);
this.save(`Started "${name}" operation in ${this.pipelineName}`)
.then(() => executor.createJob({hash}))
.then(() => this.watchOperation(executor, hash, opId, jobId))
.catch(err => this.logger.error(`Could not execute "${name}": ${err}`));
};
ExecutePipeline.prototype.watchOperation = function (executor, hash, opId, jobId) {
var name;
var job = this.nodes[jobId],
info,
name;
return executor.getInfo(hash)
.then(info => {
.then(_info => { // Update the job's stdout
var actualLine, // on executing job
currentLine = this.outputLineCount[jobId];
info = _info;
actualLine = info.outputNumber;
if (actualLine !== null && actualLine >= currentLine) {
this.outputLineCount[jobId] = actualLine + 1;
return executor.getOutput(hash, currentLine, actualLine+1)
.then(outputLines => {
var stdout = this.core.getAttribute(job, 'stdout'),
output = outputLines.map(o => o.output).join(''),
jobName = this.core.getAttribute(job, 'name');
// Handle the \b
// TODO
stdout += output;
this.core.setAttribute(job, 'stdout', stdout);
return this.save(`Received stdout for ${jobName}`);
});
}
})
.then(() => {
if (info.status === 'CREATED' || info.status === 'RUNNING') {
setTimeout(
this.watchOperation.bind(this, executor, hash, opId, jobId),
@@ -388,20 +457,29 @@ define([
return;
}
if (info.status !== 'SUCCESS') {
name = this.core.getAttribute(this.nodes[opId], 'name');
// Download all files
this.result.addArtifact(info.resultHashes[name + '-all-files']);
// Set the job to failed! Store the error
this.core.setAttribute(this.nodes[jobId], 'status', 'fail');
this.onPipelineComplete(`Operation "${opId}" failed! ${JSON.stringify(info)}`); // Failed
} else {
name = this.core.getAttribute(this.nodes[opId], 'name');
if (this.debug) {
this.result.addArtifact(info.resultHashes[name + '-all-files']);
}
this.onDistOperationComplete(opId, info);
}
name = this.core.getAttribute(job, 'name');
this.core.setAttribute(job, 'execFiles', info.resultHashes[name + '-all-files']);
return this.blobClient.getArtifact(info.resultHashes.stdout)
.then(artifact => {
var stdoutHash = artifact.descriptor.content[STDOUT_FILE].content;
return this.blobClient.getObjectAsString(stdoutHash);
})
.then(stdout => {
this.core.setAttribute(job, 'stdout', stdout);
if (info.status !== 'SUCCESS') {
// Download all files
this.result.addArtifact(info.resultHashes[name + '-all-files']);
// Set the job to failed! Store the error
this.core.setAttribute(this.nodes[jobId], 'status', 'fail');
this.logger.info(`Setting ${jobId} status to "fail"`);
this.onPipelineComplete(`Operation "${opId}" failed! ${JSON.stringify(info)}`); // Failed
} else {
if (this.debug) {
this.result.addArtifact(info.resultHashes[name + '-all-files']);
}
this.onDistOperationComplete(opId, info);
}
});
})
.catch(err => this.logger.error(`Could not get op info for ${opId}: ${err}`));
};
@@ -433,6 +511,7 @@ define([
hash = artifact.descriptor.content[`outputs/${name}`].content;
this.core.setAttribute(outputMap[name], 'data', hash);
this.logger.info(`Setting ${nodeId} data to ${hash}`);
});
return this.onOperationComplete(node);
@@ -445,45 +524,53 @@ define([
nextPortIds = this.getOperationOutputIds(opNode),
jNode = this.core.getParent(opNode),
resultPorts,
jobId = this.core.getPath(jNode),
hasReadyOps;
// Set the operation to 'success'!
this.core.setAttribute(jNode, 'status', 'success');
this.logger.info(`Setting ${jobId} status to "success"`);
this.logger.debug(`Making a commit from ${this.currentHash}`);
this.save(`Operation "${name}" in ${this.pipelineName} completed successfully`)
.then(() => {
// Transport the data from the outputs to any connected inputs
// - Get all the connections from each outputId
// - Get the corresponding dst outputs
// - Use these new ids for checking 'hasReadyOps'
resultPorts = nextPortIds.map(id => this.inputPortsFor[id])
.reduce((l1, l2) => l1.concat(l2), []);
// Transport the data from the outputs to any connected inputs
// - Get all the connections from each outputId
// - Get the corresponding dst outputs
// - Use these new ids for checking 'hasReadyOps'
resultPorts = nextPortIds.map(id => this.inputPortsFor[id])
.reduce((l1, l2) => l1.concat(l2), []);
resultPorts.map((id, i) => [this.nodes[id], this.nodes[nextPortIds[i]]])
.forEach(pair => { // [ resultPort, nextPort ]
var result = pair[0],
next = pair[1],
hash = this.core.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);
resultPorts
.map((id, i) => [this.nodes[id], this.nodes[nextPortIds[i]]])
.forEach(pair => { // [ resultPort, nextPort ]
var result = pair[0],
next = pair[1],
hash = this.core.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.logger.info(`Setting ${jobId} data to ${hash}`);
});
// For all the nextPortIds, decrement the corresponding operation's incoming counts
hasReadyOps = nextPortIds.map(id => this.getSiblingIdContaining(id))
.reduce((l1, l2) => l1.concat(l2), [])
// decrement the incoming counts for each operation id
.map(opId => --this.incomingCounts[opId])
.indexOf(0) > -1;
this.completedCount++;
this.logger.debug(`Operation "${name}" completed. ` +
`${this.totalCount - this.completedCount} remaining.`);
if (hasReadyOps) {
this.executeReadyOperations();
} else if (this.completedCount === this.totalCount) {
this.onPipelineComplete();
}
});
// For all the nextPortIds, decrement the corresponding operation's incoming counts
hasReadyOps = resultPorts.map(id => this.opFor[id])
.reduce((l1, l2) => l1.concat(l2), [])
// decrement the incoming counts for each operation id
.map(opId => --this.incomingCounts[opId])
.indexOf(0) > -1;
this.completedCount++;
this.logger.info(`Operation "${name}" completed. ` +
`${this.totalCount - this.completedCount} remaining.`);
if (hasReadyOps) {
this.executeReadyOperations();
} else if (this.completedCount === this.totalCount) {
this.onPipelineComplete();
}
};
ExecutePipeline.prototype.getOperationOutputIds = function(node) {
@@ -511,6 +598,7 @@ define([
// add the given files
return this.createEntryFile(node, files)
.then(() => this.createCustomLayers(node, files))
.then(() => this.createInputs(node, files))
.then(() => this.createOutputs(node, files))
.then(() => this.createMainFile(node, files))
@@ -520,20 +608,45 @@ define([
});
};
ExecutePipeline.prototype.createCustomLayers = function (node, files) {
var isCustomLayer = {},
metaDict = this.core.getAllMetaNodes(this.rootNode),
metanodes,
customLayers,
code;
metanodes = Object.keys(metaDict).map(id => metaDict[id]);
// Get all the custom layers
metanodes.forEach(node => {
if (this.core.getAttribute(node, 'name') === 'CustomLayer') {
isCustomLayer[this.core.getPath(node)] = true;
}
});
customLayers = metanodes.filter(node =>
this.core.getMixinPaths(node).some(id => isCustomLayer[id]));
// Get the code definitions for each
code = 'require \'nn\'\n\n' + customLayers
.map(node => this.core.getAttribute(node, 'code')).join('\n');
// Create the custom layers file
files['custom-layers.lua'] = code;
};
ExecutePipeline.prototype.createInputs = function (node, files) {
var tplContents;
return this.getInputs(node)
.then(inputs => {
// For each input, match the connection with the input name
// [ name, type ] => [ name, type, node ]
if (inputs.length > 1) {
this.logger.warn('multiple inputs not yet fully supported!');
}
//
// For each input,
// - create the deserializer
// - put it in inputs/<name>/init.lua
// - copy the data asset to /inputs/<name>/init.lua
inputs = inputs
.filter(pair => !!this.core.getAttribute(pair[2], 'data')); // remove empty inputs
files.inputAssets = {}; // data assets
tplContents = inputs.map(pair => {
var name = pair[0],
@@ -544,10 +657,11 @@ define([
code: this.core.getAttribute(node, 'deserialize')
};
});
var hashes = inputs.map(pair =>
var hashes = inputs
// storing the hash for now...
files.inputAssets[pair[0]] = this.core.getAttribute(pair[2], 'data')
);
.map(pair =>
files.inputAssets[pair[0]] = this.core.getAttribute(pair[2], 'data')
);
return Q.all(hashes.map(h => this.blobClient.getMetadata(h)));
})
.then(metadatas => {
@@ -562,57 +676,23 @@ define([
};
ExecutePipeline.prototype.createPointers = function (node, files, cb) {
var pointers = this.core.getPointerNames(node).filter(name => name !== 'base'),
nIds = pointers.map(p => this.core.getPointerPath(node, p));
var pointers,
nIds;
pointers = this.core.getPointerNames(node)
.filter(name => name !== 'base')
.filter(id => this.core.getPointerPath(node, id) !== null);
nIds = pointers.map(p => this.core.getPointerPath(node, p));
files.ptrAssets = {};
Q.all(
nIds.map(nId => this.core.loadByPath(this.rootNode, nId))
nIds.map(nId => this.getPtrCodeHash(nId))
)
.then(nodes => {
var executePlugin = (pluginId, config, callback) => {
// Call the Interpreter manager in a Q.ninvoke friendly way
// I need to create a custom context for the given plugin:
// - Set the activeNode to the given referenced node
// - If the activeNode is namespaced, set META to the given namespace
//
// FIXME: Check if it is running in the browser or on the server
WebGMEGlobal.Client.runBrowserPlugin(pluginId, config, (err, result) => {
if (!result.success) {
return callback(result.getError());
}
this.logger.info('Finished calling ' + pluginId);
callback(null, result.artifacts);
});
};
return Q.all(
nodes.map(ptrNode => {
// Look up the plugin to use
var metanode = this.core.getMetaType(ptrNode),
pluginId;
pluginId = this.core.getRegistry(ptrNode, 'validPlugins').split(' ').shift();
this.logger.info(`generating code for ${this.core.getAttribute(ptrNode, 'name')} using ${pluginId}`);
var context = WebGMEGlobal.Client.getCurrentPluginContext(pluginId);
context.managerConfig.namespace = this.core.getNamespace(metanode);
context.managerConfig.activeNode = this.core.getPath(ptrNode);
// Load and run the plugin
return Q.nfcall(executePlugin, pluginId, context);
})
);
})
.then(resultHashes => {
var name = this.core.getAttribute(node, 'name');
this.logger.info(`Pointer generation for ${name} FINISHED!`);
resultHashes.forEach((hashes, index) => {
// Grab the first asset for now
// FIXME
files.ptrAssets[`pointers/${pointers[index]}/init.lua`] = hashes[0];
resultHashes.forEach((hash, index) => {
files.ptrAssets[`pointers/${pointers[index]}/init.lua`] = hash;
});
return cb(null, files);
})
@@ -694,10 +774,12 @@ define([
};
// Get input data arguments
content.inputs = inputs;
content.inputs = inputs
.map(pair => [pair[0], !this.core.getAttribute(pair[2], 'data')]); // remove empty inputs
// Defined variables for each pointers
content.pointers = pointers;
content.pointers = pointers
.map(id => [id, this.core.getPointerPath(node, id) === null]);
// Add remaining code
content.code = code;
@@ -745,7 +827,11 @@ define([
return this[type](node);
};
_.extend(ExecutePipeline.prototype, LocalExecutor.prototype);
_.extend(
ExecutePipeline.prototype,
LocalExecutor.prototype,
PtrCodeGen.prototype
);
return ExecutePipeline;
});
+60 -5
Ver Arquivo
@@ -9,9 +9,24 @@ define([
};
// Should these be in lua?
LocalExecutor.prototype.BlobLoader = function(node) {
var hash = this.core.getAttribute(node, 'data');
return this.getOutputs(node)
LocalExecutor.prototype.ArtifactLoader = function(node) {
// Get the hash from the output node
var hash;
return this.core.loadChildren(node)
.then(cntrs => {
// Get the output container and load it's children
var output = cntrs
.find(cntr => {
var metaNode = this.core.getMetaType(cntr),
metaName = this.core.getAttribute(metaNode, 'name');
return metaName === 'Outputs';
});
return this.core.loadChildren(output);
})
.then(dataNodes => {
hash = this.core.getAttribute(dataNodes[0], 'data');
return this.getOutputs(node);
})
.then(outputTuples => {
var outputs = outputTuples.map(tuple => tuple[2]),
paths;
@@ -21,12 +36,52 @@ define([
this.logger.info(`Loading blob data (${hash}) to ${paths.map(p => `"${p}"`)}`);
outputs.forEach(output => this.core.setAttribute(output, 'data', hash));
// Set the metadata as appropriate
// TODO
this.onOperationComplete(node);
});
};
LocalExecutor.prototype.ArtifactFinder = function(node) {
// Check the save dir for a node with the given name
// that has the given type
var hash,
typeId = this.core.getPointerPath(node, 'type'),
type,
artifactName = this.core.getAttribute(node, 'artifactName');
return this.core.loadByPath(this.rootNode, typeId)
.then(_type => {
type = _type;
return this._getSaveDir();
})
.then(saveDir => this.core.loadChildren(saveDir))
.then(artifacts => {
return artifacts.find(artifact =>
this.core.getAttribute(artifact, 'name') === artifactName &&
this.isMetaTypeOf(artifact, type));
})
.then(matchingArtifact => {
hash = matchingArtifact && this.core.getAttribute(matchingArtifact, 'data');
// If no hash, just
if (!hash) {
return this.onOperationComplete(node);
} else {
return this.getOutputs(node)
.then(outputTuples => {
var outputs = outputTuples.map(tuple => tuple[2]),
paths;
paths = outputs.map(output => this.core.getPath(output));
// 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));
this.onOperationComplete(node);
});
}
});
};
LocalExecutor.prototype._getSaveDir = function () {
return this.core.loadChildren(this.rootNode)
.then(children => {
@@ -1,4 +1,6 @@
require 'paths'
local path = 'inputs/<%= name %>/<%= filename %>'
local abs_path = paths.concat('inputs', '<%= name %>', '<%= filename %>')
<%= code %>
@@ -11,7 +11,9 @@ define([
DESERIALIZE
) {
var BASH = 'th init.lua 2>&1';
return {
BASH,
ENTRY,
MAIN,
SERIALIZE,
+7 -7
Ver Arquivo
@@ -1,11 +1,11 @@
-- input data
<% inputs.forEach(function(pair) { var input = pair[0]%>
<%= input %> = require './inputs/<%= input %>'
<% }); %>
-- load custom layers
require './custom-layers'
-- load references
<% pointers.forEach(function(pointer) { %><%= pointer %> = require './pointers/<%= pointer %>'
<% }); %>
-- input data<% inputs.forEach(function(pair) { var input = pair[0], isNil = pair[1];%>
<%= isNil ? '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'
-- main operation code for <%= name %>
@@ -29,6 +29,7 @@ define([
* @classdesc This class represents the plugin GenerateArchitecture.
* @constructor
*/
var INDEX = '__index__';
var GenerateArchitecture = function () {
// Call base class' constructor.
PluginBase.call(this);
@@ -42,57 +43,166 @@ define([
GenerateArchitecture.prototype.constructor = GenerateArchitecture;
GenerateArchitecture.prototype.main = function () {
this.addCustomLayersToMeta();
this.LayerDict = createLayerDict(this.core, this.META);
this.uniqueId = 2;
this._oldTemplateSettings = _.templateSettings;
return PluginBase.prototype.main.apply(this, arguments);
};
GenerateArchitecture.prototype.addCustomLayersToMeta = function () {
var metaDict = this.core.getAllMetaNodes(this.rootNode);
Object.keys(metaDict).map(id => metaDict[id])
// Get all custom layers
.filter(node => this.core.isTypeOf(node, this.META.Layer))
// Add them to the meta
.forEach(node => this.META[this.core.getAttribute(node, 'name')] = node);
};
GenerateArchitecture.prototype.createOutputFiles = function (tree) {
var layers = tree[Constants.CHILDREN],
//initialLayers,
result = {},
template,
snippet,
code,
args;
code = 'require \'nn\'\n';
code = [
'require \'nn\'',
'',
'local net = nn.Sequential()'
].join('\n');
//initialLayers = layers.filter(layer => layer[Constants.PREV].length === 0);
// Add an index to each layer
layers.forEach((l, index) => l[INDEX] = index);
// Start with sequential (just one input)
for (var i = 0; i < layers.length; i++) {
if (layers[i][Constants.NEXT].length > 1) {
// no support for
this.logger.error('No support for parallel layers... yet');
break;
} else {
// args
args = this.createArgString(layers[i]);
template = _.template('net:add(nn.{{= name }}' + args + ')');
snippet = template(layers[i]);
code += '\n' + snippet;
}
// Define custom layers
if (this.getCurrentConfig().standalone) {
code += this.genLayerDefinitions(layers);
}
code += '\n\nreturn net';
code += this.genArchCode(layers);
result[tree.name + '.lua'] = code;
_.templateSettings = this._oldTemplateSettings; // FIXME: Fix this in SimpleNodes
return result;
};
GenerateArchitecture.prototype.createArgString = function (layer) {
return '(' + this.LayerDict[layer.name].map(arg => {
var value = layer[arg.name];
// Infer if value is unset and infer.dimensionality is set
if (!value && arg.infer === 'dimensionality') {
value = dimensionality(layer[Constants.PREV][0]);
}
return value;
}).join(', ') + ')';
GenerateArchitecture.prototype.genArchCode = function (layers) {
return [
this.createSequential(layers[0], 'net').code,
'\nreturn net'
].join('\n');
};
GenerateArchitecture.prototype.createSequential = function (layer, name) {
var next = layer[Constants.NEXT][0],
args,
template,
snippet,
snippets,
code = `\nlocal ${name} = nn.Sequential()`,
group,
i,
result;
while (layer) {
// if there is only one successor, just add the given layer
if (layer[Constants.PREV].length > 1) { // sequential layers are over
next = layer; // the given layer will be added by the caller
break;
} else { // add the given layer
args = this.createArgString(layer);
template = _.template(name + ':add(nn.{{= name }}' + args + ')');
snippet = template(layer);
code += '\n' + snippet;
}
while (layer && layer[Constants.NEXT].length > 1) { // concat/parallel
// if there is a fork, recurse and add a concat layer
this.logger.debug(`detected fork of size ${layer[Constants.NEXT].length}`);
snippets = layer[Constants.NEXT].map(nlayer =>
this.createSequential(nlayer, 'net_'+(this.uniqueId++)));
code += '\n' + snippets.map(snippet => snippet.code).join('\n');
// Make sure all snippets end at the same concat node
// Until all snippets end at the same concat node
snippets.sort((a, b) => a.endIndex < b.endIndex ? -1 : 1);
group = [];
while (snippets.length > 0) {
// Add snippets to the group
i = 0;
while (i < snippets.length &&
snippets[0].endIndex === snippets[i].endIndex) {
group.push(snippets[i]);
i++;
}
// Add concat layer
layer = group[0].next;
if (layer) {
args = this.createArgString(layer);
code += `\n\nlocal concat_${layer[INDEX]} = nn.Concat${args}\n` +
group.map(snippet =>
`concat_${layer[INDEX]}:add(${snippet.name})`)
.join('\n') + `\n\n${name}:add(concat_${layer[INDEX]})`;
next = layer[Constants.NEXT][0];
} else {
next = null; // no next layers
}
// Remove the updated snippets
this.logger.debug('removing ' + i + ' snippet(s)');
snippets.splice(0, i);
// merge the elements in the group
if (snippets.length) { // prepare next iteration
result = this.createSequential(next, 'net_'+(this.uniqueId++));
code += result.code;
group = [result];
this.logger.debug('updating group ('+ snippets.length+ ' left)');
}
}
}
layer = next;
next = layer && layer[Constants.NEXT][0];
}
return {
code: code,
name: name,
endIndex: next ? next[INDEX] : Infinity,
next: next
};
};
GenerateArchitecture.prototype.createArgString = function (layer) {
return '(' + this.LayerDict[layer.name]
.map(arg => layer[arg.name])
.filter(GenerateArchitecture.isSet)
.join(', ') + ')';
};
GenerateArchitecture.isSet = function (value) {
return !(value === undefined || value === null || value === '');
};
GenerateArchitecture.prototype.genLayerDefinitions = function(layers) {
var code = '',
customLayerId = this.core.getPath(this.META.CustomLayer),
customLayers = layers.filter(layer => { // Get the custom layers
var node = this.META[layer.name];
return this.core.getMixinPaths(node).indexOf(customLayerId) !== -1;
});
if (customLayers.length) {
code += '\n-------------- Custom Layer Definitions --------------\n\n';
code += customLayers.map(layer => layer.code).join('\n');
code += '\n\n-------------- Network --------------\n';
}
return code;
};
return GenerateArchitecture;
});
+10 -1
Ver Arquivo
@@ -9,5 +9,14 @@
},
"disableServerSideExecution": false,
"disableBrowserSideExecution": false,
"configStructure": []
"configStructure": [
{
"name": "standalone",
"displayName": "Standalone",
"description": "Prepend custom layer definitions",
"value": false,
"valueType": "boolean",
"readOnly": false
}
]
}
@@ -0,0 +1,344 @@
/*globals define, _*/
/*jshint node:true, browser:true*/
/**
* Generated by PluginGenerator 1.7.0 from webgme on Sat Jun 04 2016 18:01:54 GMT-0500 (CDT).
* A plugin that inherits from the PluginBase. To see source code documentation about available
* properties and methods visit %host%/docs/source/PluginBase.html.
*/
define([
'text!./metadata.json',
'plugin/PluginBase',
'deepforge/plugin/PtrCodeGen',
'q'
], function (
pluginMetadata,
PluginBase,
PtrCodeGen,
Q
) {
'use strict';
pluginMetadata = JSON.parse(pluginMetadata);
var HEADER_LENGTH = 60;
/**
* Initializes a new instance of GenerateExecFile.
* @class
* @augments {PluginBase}
* @classdesc This class represents the plugin GenerateExecFile.
* @constructor
*/
var GenerateExecFile = function () {
// Call base class' constructor.
PluginBase.call(this);
this.pluginMetadata = pluginMetadata;
this._srcIdFor = {}; // input path -> output data node path
this._nameFor = {}; // input path -> opname
this._dataNameFor = {};
this._opNames = {};
// topo sort stuff
this._nextOps = {};
this._incomingCnts = {};
this._operations = {};
this.activeNodeId = null;
this.activeNodeDepth = null;
};
/**
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
* This is also available at the instance at this.pluginMetadata.
* @type {object}
*/
GenerateExecFile.metadata = pluginMetadata;
// Prototypical inheritance from PluginBase.
GenerateExecFile.prototype = Object.create(PluginBase.prototype);
GenerateExecFile.prototype.constructor = GenerateExecFile;
/**
* Main function for the plugin to execute. This will perform the execution.
* Notes:
* - Always log with the provided logger.[error,warning,info,debug].
* - Do NOT put any user interaction logic UI, etc. inside this method.
* - callback always has to be called even if error happened.
*
* @param {function(string, plugin.PluginResult)} callback - the result callback
*/
GenerateExecFile.prototype.main = function (callback) {
// Get all the children and call generate exec file
this.activeNodeId = this.core.getPath(this.activeNode);
this.activeNodeDepth = this.activeNodeId.split('/').length + 1;
if (this.isMetaTypeOf(this.activeNode, this.META.Execution)) {
this.activeNodeDepth++;
}
return this.core.loadChildren(this.activeNode)
.then(nodes => this.createExecFile(nodes))
.then(code => this.blobClient.putFile('init.lua', code))
.then(hash => {
this.result.addArtifact(hash);
this.result.setSuccess(true);
callback(null, this.result);
})
.fail(err => callback(err));
};
GenerateExecFile.prototype.createExecFile = function (children) {
// Convert opNodes' jobs to the nested operations
var opNodes,
nodes;
return this.unpackJobs(children)
.then(_nodes => {
nodes = _nodes;
opNodes = nodes
.filter(node => this.isMetaTypeOf(node, this.META.Operation));
return Q.all(nodes.map(node => this.registerNameAndData(node)));
})
.then(() => Q.all(opNodes.map(node => this.createOperation(node))))
.then(operations => {
var nextIds = opNodes.map(n => this.core.getPath(n))
.filter(id => !this._incomingCnts[id]);
operations.forEach(op => this._operations[op.id] = op);
// Toposort and concat!
return this.combineOpNodes(nextIds);
})
.fail(err => this.logger.error(err));
};
GenerateExecFile.prototype.unpackJobs = function (nodes) {
return Q.all(
nodes.map(node => {
if (!this.isMetaTypeOf(node, this.META.Job)) {
return node;
}
return this.core.loadChildren(node)
.then(children =>
children.find(c => this.isMetaTypeOf(c, this.META.Operation))
);
})
);
};
GenerateExecFile.prototype.combineOpNodes = function (opIds) {
var nextIds = [],
dstIds,
code,
id;
// Combine all nodes with incoming cnts of 0
code = opIds.map(id => this._operations[id].code).join('\n');
// Decrement all next ops
dstIds = opIds.map(id => this._nextOps[id])
.reduce((l1, l2) => l1.concat(l2), []);
for (var i = dstIds.length; i--;) {
id = dstIds[i];
if (--this._incomingCnts[id] === 0) {
nextIds.push(id);
}
}
// append
return [
code,
nextIds.length ? this.combineOpNodes(nextIds) : ''
].join('\n');
};
GenerateExecFile.prototype.registerNameAndData = function (node) {
var name = this.core.getAttribute(node, 'name'),
id = this.core.getPath(node),
basename = name,
i = 2;
if (this.isMetaTypeOf(node, this.META.Operation)) {
// Get a unique operation name
while (this._opNames[name]) {
name = basename + '_' + i;
i++;
}
// register the unique name
this._opNames[name] = true;
this._nameFor[id] = name;
// For operations, register all output data node names by path
return this.core.loadChildren(node)
.then(cntrs => {
var cntr = cntrs.find(n => this.isMetaTypeOf(n, this.META.Outputs));
return this.core.loadChildren(cntr);
})
.then(outputs => {
outputs.forEach(output => {
var dataId = this.core.getPath(output);
name = this.core.getAttribute(output, 'name');
this._dataNameFor[dataId] = name;
});
});
// For each input data node, register the associated output id
} else if (this.isMetaTypeOf(node, this.META.Transporter)) {
var outputData = this.core.getPointerPath(node, 'src'),
inputData = this.core.getPointerPath(node, 'dst'),
srcOpId = this.getOpIdFor(outputData),
dstOpId = this.getOpIdFor(inputData);
this._srcIdFor[inputData] = outputData;
// Store the next operation ids for the op id
if (!this._nextOps[srcOpId]) {
this._nextOps[srcOpId] = [];
}
this._nextOps[srcOpId].push(dstOpId);
// Increment the incoming counts for each dst op
this._incomingCnts[dstOpId] = this._incomingCnts[dstOpId] || 0;
this._incomingCnts[dstOpId]++;
}
};
GenerateExecFile.prototype.getOpIdFor = function (dataId) {
var ids = dataId.split('/'),
depth = ids.length;
ids.splice(this.activeNodeDepth - depth);
return ids.join('/');
};
// For each operation...
// - unpack the inputs from prev ops
// - add the attributes table (if used)
// - check for '\<attributes\>' in code
// - add the references
// - generate the code
// - replace the `return <thing>` w/ `<ref-name> = <thing>`
GenerateExecFile.prototype.createOperation = function (node) {
var id = this.core.getPath(node),
operation = {};
operation.name = this._nameFor[id];
operation.id = id;
operation.code = this.core.getAttribute(node, 'code');
// Update the 'code' attribute
// Change the last return statement to assign the results to a table
operation.code = this.assignResultToVar(operation.code,
`${operation.name}_results`);
// Get all the input names (and sources)
return this.core.loadChildren(node)
.then(containers => {
var inputs;
inputs = containers
.find(cntr => this.isMetaTypeOf(cntr, this.META.Inputs));
this.logger.info(`${name} has ${containers.length} cntrs`);
return this.core.loadChildren(inputs);
})
.then(data => {
// Get the input names and sources
var inputNames = data.map(d => this.core.getAttribute(d, 'name')),
ids = data.map(d => this.core.getPath(d)),
srcIds = ids.map(id => this._srcIdFor[id]);
operation.inputs = inputNames.map((name, i) => {
var id = srcIds[i],
srcDataName = this._dataNameFor[id],
srcOpId = this.getOpIdFor(id),
srcOpName = this._nameFor[srcOpId];
return `local ${name} = ${srcOpName}_results.${srcDataName}`;
});
return operation;
})
.then(operation => {
// For each reference, run the plugin and retrieve the generated code
operation.refNames = this.core.getPointerNames(node)
.filter(name => name !== 'base');
var refs = operation.refNames
.map(ref => [ref, this.core.getPointerPath(node, ref)]);
return Q.all(
refs.map(pair => this.genPtrSnippet.apply(this, pair))
);
})
.then(codeFiles => {
operation.refs = codeFiles;
this.genOperationCode(operation);
return operation;
});
};
GenerateExecFile.prototype.genPtrSnippet = function (ptrName, pId) {
return this.getPtrCodeHash(pId)
.then(hash => this.blobClient.getObjectAsString(hash))
.then(code => this.createHeader(`creating ${ptrName}`, 40) + '\n' +
this.assignResultToVar(code, ptrName));
};
GenerateExecFile.prototype.createHeader = function (title, length) {
var len;
title = ` ${title} `;
length = length || HEADER_LENGTH;
len = Math.max(
Math.floor((length - title.length)/2),
2
);
return [
'',
title,
''
].join(new Array(len+1).join('-')) + '\n';
};
GenerateExecFile.prototype.genOperationCode = function (operation) {
var header = this.createHeader(`"${operation.name}" Operation`),
codeParts = [];
codeParts.push(header);
if (operation.inputs.length) {
codeParts.push(operation.inputs.join('\n'));
}
if (operation.refs.length) {
codeParts.push(operation.refs.join('\n'));
}
codeParts.push(operation.code);
codeParts.push('');
operation.code = codeParts.join('\n');
return operation;
};
GenerateExecFile.prototype.assignResultToVar = function (code, name) {
var i = code.lastIndexOf('return');
return code.substring(0, i) +
code.substring(i)
.replace('return', `local ${name} = `);
};
_.extend(GenerateExecFile.prototype, PtrCodeGen.prototype);
return GenerateExecFile;
});
+14
Ver Arquivo
@@ -0,0 +1,14 @@
{
"id": "GenerateExecFile",
"name": "Generate Execution File",
"version": "0.1.0",
"description": "",
"icon": {
"class": "glyphicon glyphicon-cog",
"src": ""
},
"disableServerSideExecution": false,
"disableBrowserSideExecution": false,
"writeAccessRequired": false,
"configStructure": []
}
+116
Ver Arquivo
@@ -0,0 +1,116 @@
/*globals define*/
/*jshint node:true, browser:true*/
/**
* Generated by PluginGenerator 1.7.0 from webgme on Tue Jun 07 2016 11:25:09 GMT-0500 (CDT).
* A plugin that inherits from the PluginBase. To see source code documentation about available
* properties and methods visit %host%/docs/source/PluginBase.html.
*/
define([
'text!./metadata.json',
'plugin/PluginBase',
'q'
], function (
pluginMetadata,
PluginBase,
Q
) {
'use strict';
pluginMetadata = JSON.parse(pluginMetadata);
/**
* Initializes a new instance of ImportArtifact.
* @class
* @augments {PluginBase}
* @classdesc This class represents the plugin ImportArtifact.
* @constructor
*/
var ImportArtifact = function () {
// Call base class' constructor.
PluginBase.call(this);
this.pluginMetadata = pluginMetadata;
};
/**
* Metadata associated with the plugin. Contains id, name, version, description, icon, configStructue etc.
* This is also available at the instance at this.pluginMetadata.
* @type {object}
*/
ImportArtifact.metadata = pluginMetadata;
// Prototypical inheritance from PluginBase.
ImportArtifact.prototype = Object.create(PluginBase.prototype);
ImportArtifact.prototype.constructor = ImportArtifact;
/**
* Main function for the plugin to execute. This will perform the execution.
* Notes:
* - Always log with the provided logger.[error,warning,info,debug].
* - Do NOT put any user interaction logic UI, etc. inside this method.
* - callback always has to be called even if error happened.
*
* @param {function(string, plugin.PluginResult)} callback - the result callback
*/
ImportArtifact.prototype.main = function (callback) {
var self = this,
config = this.getCurrentConfig(),
hash = config.dataHash,
baseName = config.dataTypeId,
name,
baseType,
dataNode,
metaDict,
metanodes;
// Create node of type "typeId" in the activeNode and set the hash, name
metaDict = this.core.getAllMetaNodes(this.activeNode);
metanodes = Object.keys(metaDict).map(id => metaDict[id]);
baseType = metanodes.find(node =>
this.core.getAttribute(node, 'name') === baseName
);
if (!baseType) {
callback(`Could not find data type "${baseName}"`, this.result);
return;
}
// Get the base node
dataNode = this.core.createNode({
base: baseType,
parent: this.activeNode
});
this.core.setAttribute(dataNode, 'data', hash);
baseName = this.core.getAttribute(baseType, 'name');
var getName;
if (config.name) {
getName = Q().then(() => config.name);
} else {
getName = this.blobClient.getMetadata(hash)
.then(md => {
name = baseName[0].toLowerCase() + baseName.substring(1);
if (md) {
name = md.name.replace(/\.[^\.]*?$/, '');
}
return name;
});
}
getName.then(name => this.core.setAttribute(dataNode, 'name', name))
.then(() => this.save(`Uploaded "${name}" data`))
.then(function () {
self.result.setSuccess(true);
callback(null, self.result);
})
.fail(function (err) {
callback(err, self.result);
});
};
return ImportArtifact;
});
+31
Ver Arquivo
@@ -0,0 +1,31 @@
{
"id": "ImportArtifact",
"name": "ImportArtifact",
"version": "0.1.0",
"description": "",
"icon": {
"class": "glyphicon glyphicon-cog",
"src": ""
},
"disableServerSideExecution": false,
"disableBrowserSideExecution": false,
"writeAccessRequired": true,
"configStructure": [
{
"name": "name",
"displayName": "Data name",
"description": "Optional name for artifact",
"value": "",
"valueType": "string",
"readOnly": false
},
{
"name": "dataHash",
"displayName": "Data to upload",
"description": "",
"value": "",
"valueType": "asset",
"readOnly": false
}
]
}
Arquivo binário não exibido.
-3
Ver Arquivo
@@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0f7228f775590d69e1215d25afc299809755a6e820fbd5cfdcd1e9bb3abdaf3a
size 23753
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
Arquivo binário não exibido.
+19 -13
Ver Arquivo
@@ -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",
@@ -82,5 +70,23 @@
"title": "DeserializeEditor",
"panel": "panels/DeserializeEditor/DeserializeEditorPanel",
"DEBUG_ONLY": false
},
{
"id": "Footer",
"title": "Footer",
"panel": "panels/Footer/FooterPanel",
"DEBUG_ONLY": false
},
{
"id": "LogViewer",
"title": "LogViewer",
"panel": "panels/LogViewer/LogViewerPanel",
"DEBUG_ONLY": false
},
{
"id": "LayerEditor",
"title": "LayerEditor",
"panel": "panels/LayerEditor/LayerEditorPanel",
"DEBUG_ONLY": false
}
]
]
@@ -23,12 +23,10 @@ define([
DefaultColor: '#ffb74d',
LayerColors: {
Containers: '#ffb74d',
Module: '#ba68c8',
ConvLayer: '#2196f3',
SimpleLayer: '#ff9100',
TransferLayer: '#80deea',
MiscLayers: '#ce93d8',
Criterion: '#7e57c2'
Convolution: '#2196f3',
Simple: '#ff9100',
Transfer: '#80deea',
Misc: '#ce93d8'
}
};
+83
Ver Arquivo
@@ -0,0 +1,83 @@
/*globals define, _, WebGMEGlobal, $ */
/*jshint browser: true*/
/**
* @author rkereskenyi / https://github.com/rkereskenyi
*/
define([
'js/PanelBase/PanelBase',
'js/Widgets/NetworkStatus/NetworkStatusWidget',
'js/Widgets/BranchStatus/BranchStatusWidget',
'js/Widgets/BranchSelector/BranchSelectorWidget',
'js/Widgets/KeyboardManager/KeyboardManagerWidget',
'js/Widgets/Notification/NotificationWidget'
], function (PanelBase,
NetworkStatusWidget,
BranchStatusWidget,
BranchSelectorWidget,
KeyboardManagerWidget,
NotificationWidget) {
'use strict';
var FooterPanel,
__parent__ = PanelBase;
FooterPanel = function (layoutManager, params) {
var options = {};
//set properties from options
options[PanelBase.OPTIONS.LOGGER_INSTANCE_NAME] = 'FooterPanel';
//call parent's constructor
__parent__.apply(this, [options]);
this._client = params.client;
//initialize UI
this._initialize();
this.logger.debug('FooterPanel ctor finished');
};
//inherit from PanelBaseWithHeader
_.extend(FooterPanel.prototype, __parent__.prototype);
FooterPanel.prototype._initialize = function () {
//main container
var navBar = $('<div/>', {class: 'navbar navbar-inverse navbar-fixed-bottom'}),
navBarInner = $('<div/>', {class: 'navbar-inner'}),
separator = $('<div class="spacer pull-right"></div>'),
widgetPlaceHolder = $('<div class="pull-right"></div>'),
keyBoardManagerEl,
networkStatusEl,
branchStatusEl,
notificationEl;
navBar.append(navBarInner);
this.$el.append(navBar);
//padding from screen right edge
navBarInner.append(separator.clone());
//keyboard enable/disbale widget (NOTE: only on non touch device)
if (WebGMEGlobal.SUPPORTS_TOUCH !== true) {
keyBoardManagerEl = widgetPlaceHolder.clone();
new KeyboardManagerWidget(keyBoardManagerEl);
navBarInner.append(keyBoardManagerEl).append(separator.clone());
}
networkStatusEl = widgetPlaceHolder.clone();
new NetworkStatusWidget(networkStatusEl, this._client);
navBarInner.append(networkStatusEl).append(separator.clone());
notificationEl = widgetPlaceHolder.clone();
new NotificationWidget(notificationEl, this._client);
navBarInner.append(notificationEl).append(separator.clone());
branchStatusEl = widgetPlaceHolder.clone();
new BranchStatusWidget(branchStatusEl, this._client);
navBarInner.append(branchStatusEl).append(separator.clone());
};
return FooterPanel;
});
+151 -85
Ver Arquivo
@@ -1,14 +1,10 @@
/*globals define, WebGMEGlobal*/
/*globals define, Materialize, WebGMEGlobal*/
// 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',
@@ -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);
@@ -114,11 +51,55 @@ 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',
'execFiles'
],
download = {};
downloadAttrs.forEach(attr => {
download[attr] = function() {
return downloadButton.call(this, attr);
};
});
// Add download model button
var downloadButton = function() {
var downloadButton = function(attr) {
var id = this._currentNodeId,
node = this.client.getNode(id),
hash = node.getAttribute('data');
hash = node.getAttribute(attr);
if (hash) {
return '/rest/blob/download/' + hash;
@@ -126,15 +107,62 @@ define([
return null;
};
return {
Data: [
{
name: 'Download',
icon: 'play_for_work',
href: downloadButton // function to create href url
}
],
var UPLOAD_PLUGIN = 'ImportArtifact',
DATA_TYPE_CONFIG = {
name: 'dataTypeId',
displayName: 'Data Type Id',
valueType: 'string',
valueItems: []
};
var uploadArtifact = function() {
// Get the data types
var dataBase,
dataBaseId,
metanodes = this.client.getAllMetaNodes(),
dataTypes = []; // TODO
dataBase = metanodes.find(n => n.getAttribute('name') === 'Data');
if (!dataBase) {
this.logger.error('Could not find the base Data node!');
return;
}
dataBaseId = dataBase.getId();
dataTypes = metanodes.filter(n => this.client.isTypeOf(n.getId(), dataBaseId))
.map(node => node.getAttribute('name'));
this.logger.info(`Found ${dataTypes.length} data types`);
// Add the target type to the pluginMetadata... hacky :/
// FIXME: this should create it's own plugin dialog which allows
// users to select the data type
var metadata = WebGMEGlobal.allPluginsMetadata[UPLOAD_PLUGIN],
config = metadata.configStructure
.find(opt => opt.name === DATA_TYPE_CONFIG.name);
if (!config) {
config = DATA_TYPE_CONFIG;
WebGMEGlobal.allPluginsMetadata[UPLOAD_PLUGIN].configStructure.push(config);
}
config.valueItems = dataTypes;
config.value = dataTypes[0];
WebGMEGlobal.InterpreterManager.configureAndRun(metadata, (result) => {
if (!result) {
Materialize.toast('Artifact upload failed!', 2000);
return;
}
this.logger.info('Finished uploading ' + UPLOAD_PLUGIN);
Materialize.toast('Artifact upload complete!', 2000);
});
};
var returnToLastPipeline = () =>
WebGMEGlobal.State.registerActiveObject(window.DeepForge.lastPipeline);
return {
// Meta nodes
MyPipelines_META: [
{
name: 'Create new pipeline',
@@ -156,6 +184,13 @@ define([
action: create.Data
}
],
MyLayers_META: [
{
name: 'Create new layer',
icon: 'queue',
action: createLayer
}
],
MyOperations_META: [
{
name: 'Create new operation',
@@ -163,6 +198,37 @@ define([
action: create.Operation
}
],
MyArtifacts_META: [
{
name: 'Upload artifact',
icon: 'swap_vert',
action: uploadArtifact
}
],
Operation_META: [
{
name: 'Return to Pipeline',
icon: 'input',
filter: () => window.DeepForge && window.DeepForge.lastPipeline,
action: returnToLastPipeline
}
],
// Instances
Data: [
{
name: 'Download',
icon: 'play_for_work',
href: download.data // function to create href url
}
],
Job: [
{
name: 'Download Execution Files',
icon: 'play_for_work',
href: download.execFiles
}
],
Pipeline: [
{
name: 'Create new node',
@@ -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';
@@ -37,14 +45,19 @@ define([
base = this.client.getNode(node.getMetaTypeId()),
isMeta = base && base.getId() === node.getId(),
suffix = isMeta ? '_META' : '',
actions,
basename;
while (base && !ACTIONS[basename]) {
while (base && !(actions && actions.length)) {
basename = base.getAttribute('name') + suffix;
base = this.client.getNode(base.getBaseId());
actions = ACTIONS[basename];
if (actions) {
actions = actions.filter(action => !action.filter || action.filter());
}
}
return ACTIONS[basename] || [];
return actions || [];
};
ForgeActionButton.prototype.onNodeLoad = function(nodeId) {
@@ -70,5 +83,121 @@ 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';
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;
});
@@ -10,5 +10,9 @@
"ImportTorch": {
"icon": "import_export",
"priority": -1
},
"GenerateExecFile": {
"icon": "play_for_work",
"priority": -1
}
}
@@ -0,0 +1,115 @@
/*globals define, _*/
/*jshint browser: true*/
define([
'panels/TextEditor/TextEditorControl'
], function (
TextEditorControl
) {
'use strict';
var NO_CODE_MESSAGE = '-- <%= name %> is not an editable layer!',
LayerEditorControl;
LayerEditorControl = function (options) {
TextEditorControl.call(this, options);
};
_.extend(LayerEditorControl.prototype, TextEditorControl.prototype);
LayerEditorControl.prototype.loadMetaNodes = function () {
return this._client.getAllMetaNodes();
};
// This next function retrieves the relevant node information for the widget
LayerEditorControl.prototype._getObjectDescriptor = function (nodeId) {
var desc = TextEditorControl.prototype._getObjectDescriptor.call(this, nodeId),
node = this._client.getNode(nodeId),
hasCode = node.getValidAttributeNames().indexOf('code') > -1,
template;
// Get own attribute, if set. Otherwise, set the text to the parent's populated
// template
this.loadMetaNodes();
if (hasCode) { // is a custom layer
if (!node.getOwnAttribute('code')) {
// Retrieve the template from the mixin
template = node.getMixinPaths()
.map(id => this._client.getNode(id).getAttribute('code'))
.find(code => !!code) || NO_CODE_MESSAGE;
}
} else {
template = NO_CODE_MESSAGE;
}
if (template) {
desc.text = _.template(template)(desc);
}
return desc;
};
LayerEditorControl.prototype.saveTextFor = function (id, text) {
var r = /:__init\((.*)\)/,
match = text.match(r),
textMatch = match && match[1],
node = this._client.getNode(id),
currentAttrs = node.getValidAttributeNames(),
attributes = [],
msg = `Updating layer definition for ${node.getAttribute('name')}`;
// Parse the attributes and update the node!
if (textMatch) {
attributes = textMatch.split(',')
.map(arg => arg.replace(/\s+/g, '')) // trim white space
.filter(arg => !!arg); // no empty strings!
} else { // inheriting __init
attributes = this.getInheritedAttrs(text);
}
this._client.startTransaction(msg);
TextEditorControl.prototype.saveTextFor.call(this, id, text);
// Remove old attributes
_.difference(currentAttrs, attributes)
.forEach(attr => this._client.removeAttributeSchema(id, attr));
attributes.forEach((attr, i) =>
this._client.setAttributeSchema(id, attr, {type: 'string', argindex: i}));
this._client.completeTransaction();
};
LayerEditorControl.prototype.getInheritedAttrs = function (code) {
// Get the base class
var r = /torch.class\((.*)\)/,
match = code.match(r),
baseType,
metanode,
textMatch = match && match[1];
if (textMatch) {
baseType = textMatch.split(',')[1]
.replace(/^\s*['"]nn\./, '')
.replace(/['"]\s*$/, '');
this._logger.debug(`inheriting the attributes from ${baseType}`);
// Get the meta node and valid attribute names
metanode = this._client.getAllMetaNodes()
.find(node => node.getAttribute('name') === baseType);
if (metanode) {
return metanode.getValidAttributeNames()
.filter(attr => attr !== 'name');
} else {
// Check if the type is known by torch
this._logger.warn(`Unknown base type ${baseType}. Assuming attributes are []`);
}
}
return [];
};
return LayerEditorControl;
});
@@ -0,0 +1,101 @@
/*globals define, _, WebGMEGlobal*/
/*jshint browser: true*/
define([
'js/PanelBase/PanelBaseWithHeader',
'js/PanelManager/IActivePanel',
'widgets/TextEditor/TextEditorWidget',
'./LayerEditorControl'
], function (
PanelBaseWithHeader,
IActivePanel,
TextEditorWidget,
LayerEditorControl
) {
'use strict';
var LayerEditorPanel;
LayerEditorPanel = function (layoutManager, params) {
var options = {};
//set properties from options
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'LayerEditorPanel';
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
//call parent's constructor
PanelBaseWithHeader.apply(this, [options, layoutManager]);
this._client = params.client;
this._embedded = params.embedded;
//initialize UI
this._initialize();
this.logger.debug('ctor finished');
};
//inherit from PanelBaseWithHeader
_.extend(LayerEditorPanel.prototype, PanelBaseWithHeader.prototype);
_.extend(LayerEditorPanel.prototype, IActivePanel.prototype);
LayerEditorPanel.prototype._initialize = function () {
var self = this;
//set Widget title
this.setTitle('');
this.widget = new TextEditorWidget(this.logger, this.$el);
this.widget.setTitle = function (title) {
self.setTitle(title);
};
this.control = new LayerEditorControl({
logger: this.logger,
client: this._client,
embedded: this._embedded,
widget: this.widget
});
this.onActivate();
};
/* OVERRIDE FROM WIDGET-WITH-HEADER */
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
LayerEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
//apply parent's onReadOnlyChanged
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
};
LayerEditorPanel.prototype.onResize = function (width, height) {
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
this.widget.onWidgetContainerResize(width, height);
};
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
LayerEditorPanel.prototype.destroy = function () {
this.control.destroy();
this.widget.destroy();
PanelBaseWithHeader.prototype.destroy.call(this);
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
};
LayerEditorPanel.prototype.onActivate = function () {
this.widget.onActivate();
this.control.onActivate();
WebGMEGlobal.KeyboardManager.setListener(this.widget);
WebGMEGlobal.Toolbar.refresh();
};
LayerEditorPanel.prototype.onDeactivate = function () {
this.widget.onDeactivate();
this.control.onDeactivate();
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
};
return LayerEditorPanel;
});
@@ -0,0 +1,29 @@
/*globals define, _*/
/*jshint browser: true*/
// This is a read-only view of the 'stdout' attribute for a Job node
define([
'panels/TextEditor/TextEditorControl'
], function (
TextEditorControl
) {
'use strict';
var LogViewerControl;
LogViewerControl = function (options) {
options.attributeName = 'stdout';
TextEditorControl.call(this, options);
};
_.extend(LogViewerControl.prototype, TextEditorControl.prototype);
LogViewerControl.prototype._onUpdate = function (id) {
if (id === this._currentNodeId) {
TextEditorControl.prototype._onUpdate.call(this, id);
}
};
return LogViewerControl;
});
@@ -0,0 +1,104 @@
/*globals define, _, WebGMEGlobal*/
/*jshint browser: true*/
/**
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed Jun 15 2016 14:06:10 GMT-0500 (CDT).
*/
define([
'js/PanelBase/PanelBaseWithHeader',
'js/PanelManager/IActivePanel',
'widgets/LogViewer/LogViewerWidget',
'./LogViewerControl'
], function (
PanelBaseWithHeader,
IActivePanel,
LogViewerWidget,
LogViewerControl
) {
'use strict';
var LogViewerPanel;
LogViewerPanel = function (layoutManager, params) {
var options = {};
//set properties from options
options[PanelBaseWithHeader.OPTIONS.LOGGER_INSTANCE_NAME] = 'LogViewerPanel';
options[PanelBaseWithHeader.OPTIONS.FLOATING_TITLE] = true;
//call parent's constructor
PanelBaseWithHeader.apply(this, [options, layoutManager]);
this._client = params.client;
this._embedded = params.embedded;
//initialize UI
this._initialize();
this.logger.debug('ctor finished');
};
//inherit from PanelBaseWithHeader
_.extend(LogViewerPanel.prototype, PanelBaseWithHeader.prototype);
_.extend(LogViewerPanel.prototype, IActivePanel.prototype);
LogViewerPanel.prototype._initialize = function () {
var self = this;
//set Widget title
this.setTitle('');
this.widget = new LogViewerWidget(this.logger, this.$el);
this.widget.setTitle = function (title) {
self.setTitle(title);
};
this.control = new LogViewerControl({
logger: this.logger,
client: this._client,
embedded: this._embedded,
widget: this.widget
});
this.onActivate();
};
/* OVERRIDE FROM WIDGET-WITH-HEADER */
/* METHOD CALLED WHEN THE WIDGET'S READ-ONLY PROPERTY CHANGES */
LogViewerPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
//apply parent's onReadOnlyChanged
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
};
LogViewerPanel.prototype.onResize = function (width, height) {
this.logger.debug('onResize --> width: ' + width + ', height: ' + height);
this.widget.onWidgetContainerResize(width, height);
};
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
LogViewerPanel.prototype.destroy = function () {
this.control.destroy();
this.widget.destroy();
PanelBaseWithHeader.prototype.destroy.call(this);
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
};
LogViewerPanel.prototype.onActivate = function () {
this.widget.onActivate();
this.control.onActivate();
WebGMEGlobal.KeyboardManager.setListener(this.widget);
WebGMEGlobal.Toolbar.refresh();
};
LogViewerPanel.prototype.onDeactivate = function () {
this.widget.onDeactivate();
this.control.onDeactivate();
WebGMEGlobal.KeyboardManager.setListener(undefined);
WebGMEGlobal.Toolbar.refresh();
};
return LogViewerPanel;
});
@@ -2,6 +2,7 @@
/*jshint browser: true*/
define([
'js/Constants',
'panels/EasyDAG/EasyDAGControl',
'deepforge/viz/PipelineControl',
'common/core/coreQ',
@@ -9,6 +10,7 @@ define([
'q',
'underscore'
], function (
CONSTANTS,
EasyDAGControl,
PipelineControl,
Core,
@@ -23,7 +25,12 @@ define([
CONN = {
SRC: 'src',
DST: 'dst'
};
},
DECORATORS = {
ArtifactLoader: 'ArtifactOpDecorator',
ArtifactFinder: 'ArtifactOpDecorator'
},
WIDGET_NAME = 'EasyDAG';
PipelineEditorControl = function (options) {
EasyDAGControl.call(this, options);
@@ -94,6 +101,11 @@ define([
// Add a rule for them
.forEach(opId => this._territories[opId] = this.TERRITORY_RULE);
// Add arch/artifact dir to the territory
// loading more than necessary.... can restrict it in the future
// if perf is a problem
this._territories[CONSTANTS.PROJECT_ROOT_ID] = {children: 2};
this._client.updateTerritory(this._territoryId, this._territories);
};
@@ -116,7 +128,8 @@ define([
if (desc.parentId === this._currentNodeId) {
this.addedIds[desc.id] = true;
return EasyDAGControl.prototype._onLoad.call(this, gmeId);
} else if (this.isContainedInActive(desc.parentId) && desc.isDataPort) {
} else if (desc.parentId !== null &&
this.isContainedInActive(desc.parentId) && desc.isDataPort) {
// port added!
this.addedIds[desc.id] = true;
this._widget.addPort(desc);
@@ -142,6 +155,19 @@ define([
} // Ignore any other updates - ie, Inputs/Outputs containers
};
PipelineEditorControl.prototype._getNodeDecorator = function (nodeObj) {
var decoratorManager = this._client.decoratorManager,
decorator,
decoratorClass;
var base = this._client.getNode(nodeObj.getMetaTypeId()),
baseName = base && base.getAttribute('name');
decorator = DECORATORS[baseName] || this.DEFAULT_DECORATOR;
decoratorClass = decoratorManager.getDecoratorForWidget(decorator, WIDGET_NAME);
return decoratorClass;
};
// Override the getSuccessors method to look up successors by operations
// with input nodes of the selected node's output type (prioritize the
// valid nodes that are using an unused output type, if one exists, ow
@@ -418,5 +444,27 @@ define([
}
};
PipelineEditorControl.prototype._getTargetDirs = function (typeIds) {
// Find the directories containing these types
return this._client.getNode(CONSTANTS.PROJECT_ROOT_ID).getChildrenIds()
// No referencing data meta types
.filter(id => {
var cMeta = this._client.getChildrenMeta(id),
validChildIds;
if (!cMeta) {
return false;
}
validChildIds = cMeta.items.map(item => item.id);
for (var i = typeIds.length; i--;) {
if (validChildIds.indexOf(typeIds[i]) !== -1) {
return true;
}
}
return false;
});
};
return PipelineEditorControl;
});
@@ -39,10 +39,9 @@ define([
};
TextEditorControl.prototype._initWidgetEventHandlers = function () {
// TODO: Add a way to navigate out of the current widget...
this._widget.saveTextFor = (id, text) => {
if (this._currentNodeHasAttr) {
this._client.setAttributes(id, this.ATTRIBUTE_NAME, text);
this.saveTextFor(id, text);
} else {
this._logger.warn(`Cannot save attribute ${this.ATTRIBUTE_NAME} ` +
`for ${id} - node doesn't have the given attribute!`);
@@ -50,10 +49,10 @@ define([
};
};
/* * * * * * * * Visualizer content update callbacks * * * * * * * */
// One major concept here is with managing the territory. The territory
// defines the parts of the project that the visualizer is interested in
// (this allows the browser to then only load those relevant parts).
TextEditorControl.prototype.saveTextFor = function (id, text) {
this._client.setAttributes(id, this.ATTRIBUTE_NAME, text);
};
TextEditorControl.prototype.TERRITORY_RULE = {children: 0};
TextEditorControl.prototype.selectedObjectChanged = function (nodeId) {
var self = this;
@@ -67,8 +66,7 @@ define([
self._currentNodeId = nodeId;
self._currentNodeParentId = undefined;
self._currentNodeHasAttr = (typeof self._client.getNode(self._currentNodeId)
.getAttribute(self.ATTRIBUTE_NAME)) === 'string';
self._currentNodeHasAttr = self._client.getNode(self._currentNodeId).getValidAttributeNames().indexOf(self.ATTRIBUTE_NAME) > -1;
if (typeof self._currentNodeId === 'string') {
var parentId = this._getParentId(nodeId);
@@ -4,14 +4,17 @@
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 08:58:20 GMT-0500 (CDT).
*/
define(['js/PanelBase/PanelBaseWithHeader',
define([
'js/PanelBase/PanelBaseWithHeader',
'js/PanelManager/IActivePanel',
'widgets/TextEditor/TextEditorWidget',
'./TextEditorControl'
], function (PanelBaseWithHeader,
IActivePanel,
TextEditorWidget,
TextEditorControl) {
], function (
PanelBaseWithHeader,
IActivePanel,
TextEditorWidget,
TextEditorControl
) {
'use strict';
var TextEditorPanel;
@@ -65,7 +68,7 @@ define(['js/PanelBase/PanelBaseWithHeader',
TextEditorPanel.prototype.onReadOnlyChanged = function (isReadOnly) {
//apply parent's onReadOnlyChanged
PanelBaseWithHeader.prototype.onReadOnlyChanged.call(this, isReadOnly);
this.widget.setReadOnly(isReadOnly);
};
TextEditorPanel.prototype.onResize = function (width, height) {
@@ -2,9 +2,11 @@
define([
'widgets/EasyDAG/SelectionManager',
'widgets/EasyDAG/Buttons',
'underscore'
], function(
EasyDAGSelectionManager,
Buttons,
_
) {
'use strict';
@@ -15,9 +17,16 @@ define([
_.extend(SelectionManager.prototype, EasyDAGSelectionManager.prototype);
SelectionManager.prototype.createActionButtons = function(/*width, height*/) {
// Add restart btn, etc
SelectionManager.prototype.createActionButtons = function(width/*, height*/) {
// Add 'watch' and 'jumpToDef' buttons
// TODO
new Buttons.Enter({
context: this._widget,
$pEl: this.$selection,
item: this.selectedItem,
x: width,
y: 0
});
};
return SelectionManager;
@@ -0,0 +1,110 @@
/*globals define, _*/
/*jshint browser: true*/
define([
'widgets/TextEditor/TextEditorWidget',
'css!./styles/LogViewerWidget.css'
], function (
TextEditorWidget
) {
'use strict';
var LogViewerWidget,
ANSI_COLORS = [
'black',
'red',
'green',
'yellow',
'blue',
'magenta',
'cyan',
'gray'
];
LogViewerWidget = function () {
this.readOnly = true;
TextEditorWidget.apply(this, arguments);
this._el.addClass('log-viewer');
this.editor.setTheme('ace/theme/twilight');
this.editor.setShowPrintMargin(false);
// Override the textlayer to add support for ansi colors
this.customizeAce();
};
_.extend(LogViewerWidget.prototype, TextEditorWidget.prototype);
LogViewerWidget.prototype.getHeader = function(desc) {
return `Console logging for Operation "${desc.name}":\n`;
};
LogViewerWidget.prototype.customizeAce = function() {
var textLayer = this.editor.renderer.$textLayer,
renderToken = textLayer.$renderToken;
textLayer.$renderToken = function(builder, col, token, value) {
// check for ansi color
var ansiBuilder = LogViewerWidget.renderAnsiFromText(value),
newToken;
for (var i = 1; i < ansiBuilder.length; i+= 3) {
builder.push(ansiBuilder[i-1]);
value = ansiBuilder[i];
newToken = {
type: token.type,
value: value
};
col = renderToken.call(this, builder, col, newToken, value);
builder.push(ansiBuilder[i+1]);
}
return col;
};
};
// Get the editor text and update wrt ansi colors
LogViewerWidget.renderAnsiFromText = function(remaining) {
var r = /\[0(;3([0-7]))?m/,
match,
ansiCode,
text,
color,
nextColor = 'default',
builder = [];
color = color || nextColor;
while (remaining) {
match = remaining.match(r);
if (match) {
ansiCode = match[0];
nextColor = ANSI_COLORS[match[2]] || null;
text = remaining.substring(0, match.index);
remaining = remaining.substring(match.index+ansiCode.length);
} else {
text = remaining;
remaining = '';
}
// Add a "span" node w/ the appropriate color class
builder.push(`<span class='ansi-${color}'>`, text, '</span>');
color = nextColor;
nextColor = 'default';
}
return builder;
};
LogViewerWidget.prototype.getSessionOptions = function() {
return {
firstLineNumber: -1
};
};
LogViewerWidget.prototype.getEditorOptions = function() {
return {
fontSize: '10pt'
};
};
return LogViewerWidget;
});
@@ -0,0 +1,35 @@
/**
* This file is for any css that you may want for this visualizer.
*
* Ideally, you would use the scss file also provided in this directory
* and then generate this file automatically from that. However, you can
* simply write css if you prefer
*/
.log-viewer {
outline: none;
}
.log-viewer .ansi-black {
color: #000000;
}
.log-viewer .ansi-red {
color: rgb(194, 54, 33);
}
.log-viewer .ansi-green {
color: rgb(37, 188, 36);
}
.log-viewer .ansi-yellow {
color: rgb(173, 173, 39);
}
.log-viewer .ansi-blue {
color: rgb(73, 46, 225);
}
.log-viewer .ansi-magenta {
color: rgb(211, 56, 211);
}
.log-viewer .ansi-cyan {
color: rgb(51, 187, 200);
}
.log-viewer .ansi-gray {
color: rgb(203, 204, 205);
}
@@ -0,0 +1,7 @@
/**
* This file is for any scss that you may want for this visualizer.
*/
.log-viewer {
outline: none;
}
@@ -113,10 +113,25 @@ define([
};
var Delete = function(params) {
EasyDAGButtons.DeleteOne.call(this, params);
};
_.extend(Delete.prototype, EasyDAGButtons.DeleteOne.prototype);
Delete.prototype._onClick = function(item) {
// Check if it is a pointer or
if (item.desc.isPointer) {
this.removePtr(item.name);
} else {
this.deleteNode(item.id);
}
};
return {
AddOutput: AddOutput,
AddInput: AddInput,
AddRef: AddRef,
Delete: EasyDAGButtons.Delete
Delete: Delete
};
});
@@ -91,13 +91,5 @@ define([
this.addRefTo(target.node.id);
};
OperationInterfaceEditorWidget.prototype.removeItem = function(item) {
if (item.desc.isPointer) {
this.removePtr(item.name);
} else {
this.removeSubtreeAt(item.id);
}
};
return OperationInterfaceEditorWidget;
});
@@ -0,0 +1,82 @@
/*globals define, WebGMEGlobal*/
define([
'widgets/EasyDAG/Buttons'
], function(
EasyDAGButtons
) {
// Create a GoToBase button
var client = WebGMEGlobal.Client,
LocalOps = {
ArtifactLoader: true,
Save: true
};
var GoToBase = function(params) {
// Check if it should be disabled
var baseId = this._getBaseId(params.item),
base = client.getNode(baseId);
params.disabled = base ? base.isLibraryElement() : false;
EasyDAGButtons.ButtonBase.call(this, params);
};
GoToBase.SIZE = 10;
GoToBase.BORDER = 5;
GoToBase.prototype.BTN_CLASS = 'add';
GoToBase.prototype = new EasyDAGButtons.ButtonBase();
GoToBase.prototype._render = function() {
var lineRadius = GoToBase.SIZE - GoToBase.BORDER,
btnColor = '#90caf9',
lineColor = '#7986cb';
if (this.disabled) {
btnColor = '#e0e0e0';
lineColor = '#9e9e9e';
}
this.$el
.append('circle')
.attr('r', GoToBase.SIZE)
.attr('fill', btnColor);
this.$el
.append('circle')
//.attr('cx', -)
//.attr('cy', 0)
.attr('r', GoToBase.SIZE/3)
.attr('stroke-width', 3)
.attr('stroke', lineColor);
this.$el
.append('line')
.attr('y1', 0)
.attr('y2', 0)
.attr('x1', -lineRadius)
.attr('x2', lineRadius)
.attr('stroke-width', 3)
.attr('stroke', lineColor);
};
GoToBase.prototype._onClick = function(item) {
var node = client.getNode(item.id),
baseId = node.getBaseId();
window.DeepForge = window.DeepForge || {};
window.DeepForge.lastPipeline = item.desc.parentId;
WebGMEGlobal.State.registerActiveObject(baseId);
};
GoToBase.prototype._getBaseId = function(item) {
var n = client.getNode(item.id);
return n.getBaseId();
};
return {
DeleteOne: EasyDAGButtons.DeleteOne,
GoToBase: GoToBase
};
});
@@ -60,6 +60,20 @@ define([
this._visiblePorts = null;
};
OperationNode.prototype.removePort = function(id) {
// Find the given port and remove it
[this.inputs, this.outputs] // Look for the port in both lists
.forEach(ports => {
var port = ports.find(p => p.id === id),
i;
if (port) {
i = ports.indexOf(port);
ports.splice(i, 1);
}
});
};
OperationNode.prototype.updatePort = function(/*desc*/) {
// TODO
};
@@ -78,5 +92,13 @@ define([
this.hidePorts();
};
OperationNode.prototype.update = function() {
DAGItem.prototype.update.apply(this, arguments);
if (this._visiblePorts) {
var areInputs = this._visiblePorts[1];
this.showPorts.call(this, null, areInputs);
}
};
return OperationNode;
});
@@ -35,6 +35,7 @@ define([
this.$el.addClass(WIDGET_CLASS);
this.portIdToNode = {};
this.PORT_STATE = STATE.DEFAULT;
this.srcPortToConnectArgs = null;
this._connForPort = {};
this._itemsShowingPorts = [];
};
@@ -88,6 +89,12 @@ define([
// Update the item's ports
item.refreshPorts();
}
// If in a "connecting-port" state, refresh the port
if (this.PORT_STATE === STATE.CONNECTING) {
this.PORT_STATE = STATE.DEFAULT;
this.connectPort.apply(this, this.srcPortToConnectArgs);
}
};
PipelineEditorWidget.prototype._removeConnection = function(id) {
@@ -139,6 +146,7 @@ define([
PipelineEditorWidget.prototype.connectPort = function(nodeId, id, isOutput) {
this._logger.info('port ' + id + ' has been clicked! (', isOutput, ')');
if (this.PORT_STATE === STATE.DEFAULT) {
this.srcPortToConnectArgs = arguments;
this.startPortConnection(nodeId, id, isOutput);
} else if (this._selectedPort !== id) {
this._logger.info('connecting ' + this._selectedPort + ' to ' + id);
@@ -2,7 +2,7 @@
define([
'widgets/EasyDAG/SelectionManager',
'widgets/EasyDAG/Buttons',
'./Buttons',
'underscore'
], function(
EasyDAGSelectionManager,
@@ -17,7 +17,7 @@ define([
_.extend(SelectionManager.prototype, EasyDAGSelectionManager.prototype);
SelectionManager.prototype.createActionButtons = function(/*width, height*/) {
SelectionManager.prototype.createActionButtons = function(width/*, height*/) {
// move the 'x' to the top left
new Buttons.DeleteOne({
context: this._widget,
@@ -26,6 +26,15 @@ define([
x: 0,
y: 0
});
// If the operation has a user-defined base type,
// show a button for jumping to the base def
new Buttons.GoToBase({
context: this._widget,
$pEl: this.$selection,
item: this.selectedItem,
x: width,
y: 0
});
};
SelectionManager.prototype.deselect = function() {
+6 -2
Ver Arquivo
@@ -1,7 +1,11 @@
<div class="col s2 m4">
<div class="card blue lighten-2">
<div class="col s2 m4" id="card-node<%= htmlId %>" data-rank="<%= rank %>">
<div class="card <%= color %> <%= shade %>">
<div class="card-content">
<% if (typeof icon !== 'undefined') {%>
<div><i class="large material-icons"><%=icon%></i></div>
<%}%>
<span class="card-title"><%= title %></span>
<div
<p><%= description %></p>
</div>
</div>
+34 -5
Ver Arquivo
@@ -30,6 +30,10 @@ define([
// Load the component settings
this._config = {
defaults: {
color: 'blue',
shade: 'lighten-2'
},
nodes:[]
};
ComponentSettings.resolveWithWebGMEGlobal(this._config, this.getComponentId());
@@ -69,7 +73,7 @@ define([
node = this.validNodes[desc[attr]];
if (node) {
_.extend(desc, node);
_.extend(desc, this._config.defaults, node);
desc.title = desc.title || desc.name;
this.addPanel(desc);
}
@@ -77,15 +81,40 @@ define([
};
RootVizWidget.prototype.addPanel = function (desc) {
var html = $(NodeTpl(desc));
var html;
// Create the html from template
if (this.nodes[desc.id]) {
if (this.nodes[desc.id]) { // refresh, if already exists
this.removeNode(desc.id);
}
// Create the html from template
this.$container.append(html);
desc.htmlId = desc.id.replace('/', '-');
html = $(NodeTpl(desc));
// Find the child just before the given one
var children = this.$container.children(),
rank = -Infinity,
id;
desc.rank = +desc.rank;
if (children.length) { // Add it in order
for (var i = 0; i < children.length; i++) {
rank = +children[i].getAttribute('data-rank');
if (rank > desc.rank) {
break;
}
}
if (i < children.length) {
id = children[i].getAttribute('id');
this.$container.find('#' + id).before(html);
} else {
this.$container.append(html);
}
} else {
this.$container.append(html);
}
html.on('click', () => {
this.onNodeClick(desc.id);
event.stopPropagation();
@@ -1,10 +1,6 @@
/*globals define*/
/*globals $, define*/
/*jshint browser: true*/
/**
* Generated by VisualizerGenerator 1.7.0 from webgme on Wed May 18 2016 08:58:20 GMT-0500 (CDT).
*/
define([
'./lib/ace',
'underscore',
@@ -23,19 +19,22 @@ define([
this._el = container;
this._el.css({height: '100%'});
this.editor = ace.edit(this._el[0]);
this.editor.getSession().setMode('ace/mode/lua');
this.$editor = $('<div/>');
this.$editor.css({height: '100%'});
this._el.append(this.$editor[0]);
this.readOnly = this.readOnly || false;
this.editor = ace.edit(this.$editor[0]);
// Get the config from component settings for themes
// TODO
this.editor.setOptions({
fontSize: '12pt'
});
this.editor.getSession().setOptions(this.getSessionOptions());
this.editor.setOptions(this.getEditorOptions());
this.editor.$blockScrolling = Infinity;
this.DELAY = 750;
// this.editor.setTheme('ace/theme/monokai');
this.editor.on('input', _.debounce(this.saveText.bind(this), this.DELAY));
this.setReadOnly(this.readOnly);
this.currentHeader = '';
this.activeNode = null;
this._initialize();
@@ -43,6 +42,20 @@ define([
this._logger.debug('ctor finished');
};
TextEditorWidget.prototype.getEditorOptions = function () {
return {
fontSize: '12pt'
};
};
TextEditorWidget.prototype.getSessionOptions = function () {
return {
mode: 'ace/mode/lua',
tabSize: 3,
useSoftTabs: true
};
};
TextEditorWidget.prototype._initialize = function () {
// set widget class
this._el.addClass(WIDGET_CLASS);
@@ -68,7 +81,13 @@ define([
};
TextEditorWidget.prototype.saveText = function () {
var text = this.editor.getValue().replace(this.currentHeader + '\n', '');
var text;
if (this.readOnly) {
return;
}
text = this.editor.getValue().replace(this.currentHeader + '\n', '');
if (this.activeNode) {
this.saveTextFor(this.activeNode, text);
} else {
@@ -85,7 +104,9 @@ define([
TextEditorWidget.prototype.updateNode = function (desc) {
// Check for header changes
if (this.activeNode === desc.id &&
if (this.readOnly) {
this.addNode(desc);
} else if (this.activeNode === desc.id &&
this.getHeader(desc) !== this.currentHeader) {
this.addNode(desc);
}
@@ -100,6 +121,7 @@ define([
/* * * * * * * * Visualizer life cycle callbacks * * * * * * * */
TextEditorWidget.prototype.destroy = function () {
this.editor.destroy();
};
TextEditorWidget.prototype.onActivate = function () {
@@ -110,5 +132,10 @@ define([
this._logger.debug('TextEditorWidget has been deactivated');
};
TextEditorWidget.prototype.setReadOnly = function (isReadOnly) {
this.readOnly = isReadOnly;
this.editor.setReadOnly(isReadOnly);
};
return TextEditorWidget;
});
@@ -0,0 +1,109 @@
define("ace/theme/twilight",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
exports.isDark = true;
exports.cssClass = "ace-twilight";
exports.cssText = ".ace-twilight .ace_gutter {\
background: #232323;\
color: #E2E2E2\
}\
.ace-twilight .ace_print-margin {\
width: 1px;\
background: #232323\
}\
.ace-twilight {\
background-color: #141414;\
color: #F8F8F8\
}\
.ace-twilight .ace_cursor {\
color: #A7A7A7\
}\
.ace-twilight .ace_marker-layer .ace_selection {\
background: rgba(221, 240, 255, 0.20)\
}\
.ace-twilight.ace_multiselect .ace_selection.ace_start {\
box-shadow: 0 0 3px 0px #141414;\
}\
.ace-twilight .ace_marker-layer .ace_step {\
background: rgb(102, 82, 0)\
}\
.ace-twilight .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid rgba(255, 255, 255, 0.25)\
}\
.ace-twilight .ace_marker-layer .ace_active-line {\
background: rgba(255, 255, 255, 0.031)\
}\
.ace-twilight .ace_gutter-active-line {\
background-color: rgba(255, 255, 255, 0.031)\
}\
.ace-twilight .ace_marker-layer .ace_selected-word {\
border: 1px solid rgba(221, 240, 255, 0.20)\
}\
.ace-twilight .ace_invisible {\
color: rgba(255, 255, 255, 0.25)\
}\
.ace-twilight .ace_keyword,\
.ace-twilight .ace_meta {\
color: #CDA869\
}\
.ace-twilight .ace_constant,\
.ace-twilight .ace_constant.ace_character,\
.ace-twilight .ace_constant.ace_character.ace_escape,\
.ace-twilight .ace_constant.ace_other,\
.ace-twilight .ace_heading,\
.ace-twilight .ace_markup.ace_heading,\
.ace-twilight .ace_support.ace_constant {\
color: #CF6A4C\
}\
.ace-twilight .ace_invalid.ace_illegal {\
color: #F8F8F8;\
background-color: rgba(86, 45, 86, 0.75)\
}\
.ace-twilight .ace_invalid.ace_deprecated {\
text-decoration: underline;\
font-style: italic;\
color: #D2A8A1\
}\
.ace-twilight .ace_support {\
color: #9B859D\
}\
.ace-twilight .ace_fold {\
background-color: #AC885B;\
border-color: #F8F8F8\
}\
.ace-twilight .ace_support.ace_function {\
color: #DAD085\
}\
.ace-twilight .ace_list,\
.ace-twilight .ace_markup.ace_list,\
.ace-twilight .ace_storage {\
color: #F9EE98\
}\
.ace-twilight .ace_entity.ace_name.ace_function,\
.ace-twilight .ace_meta.ace_tag,\
.ace-twilight .ace_variable {\
color: #AC885B\
}\
.ace-twilight .ace_string {\
color: #8F9D6A\
}\
.ace-twilight .ace_string.ace_regexp {\
color: #E9C062\
}\
.ace-twilight .ace_comment {\
font-style: italic;\
color: #5F5A60\
}\
.ace-twilight .ace_variable {\
color: #7587A6\
}\
.ace-twilight .ace_xml-pe {\
color: #494949\
}\
.ace-twilight .ace_indent-guide {\
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERFpYLC1tf0PAAgOAnPnhxyiAAAAAElFTkSuQmCC) right repeat-y\
}";
var dom = require("../lib/dom");
dom.importCssString(exports.cssText, exports.cssClass);
});
@@ -8,5 +8,6 @@
.text-editor {
outline: none;
padding: 0px;
text-align: left !important;
}
@@ -5,7 +5,7 @@
'use strict';
var testFixture = require('../../globals'),
SEED_DIR = testFixture.path.join(testFixture.DF_SEED_DIR, 'devMinimal'),
SEED_DIR = testFixture.path.join(testFixture.DF_SEED_DIR, 'nn'),
assert = require('assert');
describe('CreateTorchMeta', function () {
@@ -20,9 +20,14 @@ describe('CreateTorchMeta', function () {
project,
gmeAuth,
storage,
ORIG_META = {},
META = {},
origRoot,
root,
commitHash;
before(function (done) {
this.timeout(5000);
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
@@ -32,7 +37,7 @@ describe('CreateTorchMeta', function () {
})
.then(function () {
var importParam = {
projectSeed: testFixture.path.join(SEED_DIR, 'devMinimal.webgmex'),
projectSeed: testFixture.path.join(SEED_DIR, 'nn.webgmex'),
projectName: projectName,
branchName: 'master',
logger: logger,
@@ -45,8 +50,56 @@ describe('CreateTorchMeta', function () {
project = importResult.project;
core = importResult.core;
commitHash = importResult.commitHash;
origRoot = importResult.rootNode;
return project.createBranch('test', commitHash);
})
// Run the plugin
.then(() => {
var manager = new PluginCliManager(null, logger, gmeConfig),
metaDict = core.getAllMetaNodes(origRoot),
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/960660211'
};
// Populate the META object
Object.keys(metaDict)
.map(id => metaDict[id])
.forEach(node => ORIG_META[core.getAttribute(node, 'name')] = node);
return Q.ninvoke(
manager,
'executePlugin',
pluginName,
{removeOldLayers: true},
context
);
})
.then(pluginResult => {
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
return project.getBranchHash('test');
})
.then(function (branchHash) {
return Q.ninvoke(project, 'loadObject', branchHash);
})
.then(function (commitObject) {
return Q.ninvoke(core, 'loadRoot', commitObject.root);
})
.then(function (rootNode) {
var metaDict = core.getAllMetaNodes(rootNode);
root = rootNode;
// Populate the META object
Object.keys(metaDict)
.map(id => metaDict[id])
.forEach(node => META[core.getAttribute(node, 'name')] = node);
})
.nodeify(done);
});
@@ -128,122 +181,42 @@ describe('CreateTorchMeta', function () {
});
});
it('should place the nodes in the Language node', function (done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/960660211'
};
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
expect(err).to.equal(null);
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
project.getBranchHash('test')
.then(function (branchHash) {
return Q.ninvoke(project, 'loadObject', branchHash);
})
.then(function (commitObject) {
return Q.ninvoke(core, 'loadRoot', commitObject.root);
})
.then(function (rootNode) {
var metaDict = core.getAllMetaNodes(rootNode),
metaNodes,
nodes,
langNode;
metaNodes = Object.keys(metaDict)
.map(id => metaDict[id]);
langNode = metaNodes
.find(node => core.getAttribute(node, 'name') === 'Language' );
nodes = metaNodes
.filter(node => core.getAttribute(node, 'name') !== 'FCO' &&
core.getAttribute(node, 'name') !== 'Language' );
nodes.forEach(node => assert.equal(core.getParent(node), langNode));
})
.nodeify(done);
});
it('should update existing layers', function () {
var scGuid = core.getGuid(ORIG_META.SpatialConvolution);
// Check the guid of spatial convolution
expect(scGuid).to.equal(core.getGuid(META.SpatialConvolution));
});
// Attributes
describe('attributes', function() {
var rootNode,
META = {};
it('should add attributes', function () {
// check that "Linear" has multiple attrs
var attrs = core.getAttributeNames(META.Linear);
assert.notEqual(attrs.length, 1, `missing attributes! ${attrs}`);
});
before(function(done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/960660211'
};
it('should create string attributes', function () {
// check that "Linear" has an attribute called "output"
var attr = core.getAttributeMeta(META.Add, 'scalar');
assert.equal(attr.type, 'string');
});
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
expect(err).to.equal(null);
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
project.getBranchHash('test')
.then(function (branchHash) {
return Q.ninvoke(project, 'loadObject', branchHash);
})
.then(function (commitObject) {
return Q.ninvoke(core, 'loadRoot', commitObject.root);
})
.then(function (root) {
rootNode = root;
var metaDict = core.getAllMetaNodes(rootNode);
it('should place the nodes in the Language node', function () {
var metaDict = core.getAllMetaNodes(root),
metaNodes,
nodes,
langNode;
// Populate the META object
Object.keys(metaDict)
.map(id => metaDict[id])
.forEach(node => META[core.getAttribute(node, 'name')] = node);
metaNodes = Object.keys(metaDict)
.map(id => metaDict[id]);
})
.nodeify(done);
});
});
langNode = metaNodes
.find(node => core.getAttribute(node, 'name') === 'Language' );
it('should add attributes', function () {
// check that "Linear" has multiple attrs
var attrs = core.getAttributeNames(META.Linear);
assert.notEqual(attrs.length, 1, `missing attributes! ${attrs}`);
});
nodes = metaNodes
.filter(node => core.getAttribute(node, 'name') !== 'FCO' &&
core.getAttribute(node, 'name') !== 'Language' );
it('should support custom types', function () {
// check that "Add" has a boolean attribute called 'isScalar'
var attr = core.getAttributeMeta(META.Add, 'isScalar');
assert.equal(attr.type, 'boolean');
});
it('should create integer type if none specified', function () {
// check that "Linear" has an attribute called "output"
var attr = core.getAttributeMeta(META.Linear, 'output');
assert.notEqual(attr, -1);
assert.equal(attr.type, 'integer');
});
it('should set "min" when specified', function () {
var attr = core.getAttributeMeta(META.Linear, 'output');
assert.equal(attr.min, 1);
});
it('should ignore "ignore" attributes', function () {
// check that "Linear" doesn't have an attribute called "input"
var attrs = core.getAttributeNames(META.Linear);
assert.equal(attrs.indexOf('input'), -1);
});
nodes.forEach(node => assert.equal(core.getParent(node), langNode));
});
});
@@ -58,7 +58,7 @@ describe('GenerateArchitecture', function () {
.nodeify(done);
});
it('should run plugin and not update the branch', function (done) {
it.skip('should run plugin and not update the branch', function (done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
@@ -85,12 +85,12 @@ describe('GenerateArchitecture', function () {
describe('test cases', function() {
var cases = [
['/4', 'basic.lua'],
['/T', 'basic-transfers.lua'],
['/W', 'overfeat.lua']
// TODO: Add more tests
// Need a concat test
// TODO
// Need to update the input args for Reshape!
//['/o', 'basic.lua'],
//['/8', 'basic-transfers.lua'],
//['/M', 'concat-parallel.lua'],
['/e', 'googlenet.lua'],
['/X', 'overfeat.lua']
];
var runTest = function(pair, done) {
@@ -0,0 +1,79 @@
/*jshint node:true, mocha:true*/
/**
* Generated by PluginGenerator 1.7.0 from webgme on Sat Jun 04 2016 18:01:54 GMT-0500 (CDT).
*/
'use strict';
var testFixture = require('../../globals');
describe.skip('GenerateExecFile', function () {
var gmeConfig = testFixture.getGmeConfig(),
expect = testFixture.expect,
logger = testFixture.logger.fork('GenerateExecFile'),
PluginCliManager = testFixture.WebGME.PluginCliManager,
projectName = 'testProject',
pluginName = 'GenerateExecFile',
project,
gmeAuth,
storage,
commitHash;
before(function (done) {
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
return storage.openDatabase();
})
.then(function () {
var importParam = {
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'EmptyProject.webgmex'),
projectName: projectName,
branchName: 'master',
logger: logger,
gmeConfig: gmeConfig
};
return testFixture.importProject(storage, importParam);
})
.then(function (importResult) {
project = importResult.project;
commitHash = importResult.commitHash;
return project.createBranch('test', commitHash);
})
.nodeify(done);
});
after(function (done) {
storage.closeDatabase()
.then(function () {
return gmeAuth.unload();
})
.nodeify(done);
});
it('should run plugin and update the branch', function (done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/960660211',
};
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
expect(err).to.equal(null);
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
project.getBranchHash('test')
.then(function (branchHash) {
expect(branchHash).to.not.equal(commitHash);
})
.nodeify(done);
});
});
});
+2 -2
Ver Arquivo
@@ -8,7 +8,7 @@ var testFixture = require('../../globals'),
path = testFixture.path,
BASE_DIR = testFixture.DF_SEED_DIR;
describe('GenerateYaml', function () {
describe.skip('GenerateYaml', function () {
var gmeConfig = testFixture.getGmeConfig(),
expect = testFixture.expect,
logger = testFixture.logger.fork('GenerateYaml'),
@@ -64,7 +64,7 @@ describe('GenerateYaml', function () {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/4'
activeNode: ''
};
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
@@ -0,0 +1,79 @@
/*jshint node:true, mocha:true*/
/**
* Generated by PluginGenerator 1.7.0 from webgme on Tue Jun 07 2016 11:25:09 GMT-0500 (CDT).
*/
'use strict';
var testFixture = require('../../globals');
describe.skip('ImportArtifact', function () {
var gmeConfig = testFixture.getGmeConfig(),
expect = testFixture.expect,
logger = testFixture.logger.fork('ImportArtifact'),
PluginCliManager = testFixture.WebGME.PluginCliManager,
projectName = 'testProject',
pluginName = 'ImportArtifact',
project,
gmeAuth,
storage,
commitHash;
before(function (done) {
testFixture.clearDBAndGetGMEAuth(gmeConfig, projectName)
.then(function (gmeAuth_) {
gmeAuth = gmeAuth_;
// This uses in memory storage. Use testFixture.getMongoStorage to persist test to database.
storage = testFixture.getMemoryStorage(logger, gmeConfig, gmeAuth);
return storage.openDatabase();
})
.then(function () {
var importParam = {
projectSeed: testFixture.path.join(testFixture.SEED_DIR, 'EmptyProject.webgmex'),
projectName: projectName,
branchName: 'master',
logger: logger,
gmeConfig: gmeConfig
};
return testFixture.importProject(storage, importParam);
})
.then(function (importResult) {
project = importResult.project;
commitHash = importResult.commitHash;
return project.createBranch('test', commitHash);
})
.nodeify(done);
});
after(function (done) {
storage.closeDatabase()
.then(function () {
return gmeAuth.unload();
})
.nodeify(done);
});
it('should run plugin and update the branch', function (done) {
var manager = new PluginCliManager(null, logger, gmeConfig),
pluginConfig = {
},
context = {
project: project,
commitHash: commitHash,
branchName: 'test',
activeNode: '/960660211',
};
manager.executePlugin(pluginName, pluginConfig, context, function (err, pluginResult) {
expect(err).to.equal(null);
expect(typeof pluginResult).to.equal('object');
expect(pluginResult.success).to.equal(true);
project.getBranchHash('test')
.then(function (branchHash) {
expect(branchHash).to.not.equal(commitHash);
})
.nodeify(done);
});
});
});
@@ -19,6 +19,7 @@ var testFixture = require('../../globals'),
'basic4.lua'
],
ONLY_TESTS = [
'vgg.lua'
];
describe('ImportTorch', function () {
+2 -2
Ver Arquivo
@@ -54,7 +54,7 @@ describe('ImportYaml', function () {
checker = new GraphChecker({
core: core,
ignore: {
attributes: ['calculateDimensionality', 'dimensionalityTransform']
attributes: []
}
});
return project.createBranch('test', commitHash);
@@ -167,7 +167,7 @@ describe('ImportYaml', function () {
};
describe('run test cases', function() {
var cases = fs.readdirSync(YAML_DIR)
var cases = ['vgg.yml'] // fs.readdirSync(YAML_DIR)
.filter(name => path.extname(name) === '.yml');
// one test for each test name
+7 -7
Ver Arquivo
@@ -24,9 +24,9 @@ concat:add(conv3xx)
local pool = nn.Sequential()
pool:add(nn.SpatialZeroPadding(1,1,1,1)) -- remove after getting nn R2 into fbcode
if config[4][1] == 'max' then
pool:add(nn.SpatialMaxPooling(3,3,1,1):ceil())
pool:add(nn.SpatialMaxPooling(3,3,1,1))
elseif config[4][1] == 'avg' then
pool:add(nn.SpatialAveragePooling(3,3,1,1):ceil())
pool:add(nn.SpatialAveragePooling(3,3,1,1))
else
error('Unknown pooling')
end
@@ -40,10 +40,10 @@ end
local features = nn.Sequential()
features:add(nn.SpatialConvolution(3,64,7,7,2,2,3,3)):add(nn.ReLU(true))
features:add(nn.SpatialMaxPooling(3,3,2,2):ceil())
features:add(nn.SpatialMaxPooling(3,3,2,2))
features:add(nn.SpatialConvolution(64,64,1,1)):add(nn.ReLU(true))
features:add(nn.SpatialConvolution(64,192,3,3,1,1,1,1)):add(nn.ReLU(true))
features:add(nn.SpatialMaxPooling(3,3,2,2):ceil())
features:add(nn.SpatialMaxPooling(3,3,2,2))
features:add(inception( 192, {{ 64},{ 64, 64},{ 64, 96},{'avg', 32}})) -- 3(a)
features:add(inception( 256, {{ 64},{ 64, 96},{ 64, 96},{'avg', 64}})) -- 3(b)
features:add(inception( 320, {{ 0},{128,160},{ 64, 96},{'max', 0}})) -- 3(c)
@@ -59,15 +59,15 @@ main_branch:add(nn.SpatialConvolution(1024,1024,2,2,2,2))
main_branch:add(inception(1024, {{352},{192,320},{160,224},{'avg',128}})) -- 5(a)
main_branch:add(inception(1024, {{352},{192,320},{192,224},{'max',128}})) -- 5(b)
main_branch:add(nn.SpatialAveragePooling(7,7,1,1))
main_branch:add(nn.View(1024):setNumInputDims(3))
main_branch:add(nn.View(1024))
main_branch:add(nn.Linear(1024,nClasses))
main_branch:add(nn.LogSoftMax())
-- add auxillary classifier here (thanks to Christian Szegedy for the details)
local aux_classifier = nn.Sequential()
aux_classifier:add(nn.SpatialAveragePooling(5,5,3,3):ceil())
aux_classifier:add(nn.SpatialAveragePooling(5,5,3,3))
aux_classifier:add(nn.SpatialConvolution(576,128,1,1,1,1))
aux_classifier:add(nn.View(128*4*4):setNumInputDims(3))
aux_classifier:add(nn.View(128*4*4))
aux_classifier:add(nn.Linear(128*4*4,768))
aux_classifier:add(nn.ReLU())
aux_classifier:add(nn.Linear(768,nClasses))
@@ -0,0 +1,24 @@
require 'nn'
local net = nn.Sequential()
net:add(nn.Reshape(100))
local net_2 = nn.Sequential()
net_2:add(nn.Linear(100, 150))
net_2:add(nn.Tanh())
net_2:add(nn.Linear(150, 50))
local net_3 = nn.Sequential()
net_3:add(nn.Linear(100, 150))
net_3:add(nn.Tanh())
net_3:add(nn.Linear(150, 30))
local concat_7 = nn.Concat(1)
concat_7:add(net_3)
concat_7:add(net_2)
net:add(concat_7)
net:add(nn.Tanh())
net:add(nn.Linear(80, 7))
return net
+341
Ver Arquivo
@@ -0,0 +1,341 @@
require 'nn'
local net = nn.Sequential()
net:add(nn.SpatialConvolution(3, 64, 7, 7, 2, 2, 3, 3))
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(3, 3, 2, 2))
net:add(nn.SpatialConvolution(64, 64, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialConvolution(64, 192, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(3, 3, 2, 2))
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))
local net_4 = nn.Sequential()
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)
net:add(concat_24)
local net_6 = nn.Sequential()
net_6:add(nn.SpatialConvolution(256, 64, 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))
local net_8 = nn.Sequential()
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)
net:add(concat_41)
local net_10 = nn.Sequential()
net_10:add(nn.SpatialConvolution(320, 128, 1, 1, 1, 1))
net_10:add(nn.ReLU(true))
net_10:add(nn.SpatialConvolution(128, 160, 3, 3, 1, 1, 1, 1))
net_10:add(nn.ReLU(true))
local net_11 = nn.Sequential()
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)
net:add(concat_54)
net:add(nn.SpatialConvolution(576, 576, 2, 2, 2, 2))
local net_13 = nn.Sequential()
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, 64, 1, 1, 1, 1))
net_14:add(nn.ReLU(true))
net_14:add(nn.SpatialConvolution(64, 96, 3, 3, 1, 1, 1, 1))
net_14:add(nn.ReLU(true))
local net_15 = nn.Sequential()
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)
net:add(concat_72)
local net_17 = nn.Sequential()
net_17:add(nn.SpatialConvolution(576, 192, 1, 1, 1, 1))
net_17:add(nn.ReLU(true))
local net_18 = nn.Sequential()
net_18:add(nn.SpatialConvolution(576, 96, 1, 1, 1, 1))
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))
local net_19 = nn.Sequential()
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)
net:add(concat_89)
local net_21 = nn.Sequential()
net_21:add(nn.SpatialConvolution(576, 160, 1, 1, 1, 1))
net_21:add(nn.ReLU(true))
local net_22 = nn.Sequential()
net_22:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
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))
local net_23 = nn.Sequential()
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 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, 96, 1, 1, 1, 1))
net_25:add(nn.ReLU(true))
local net_26 = nn.Sequential()
net_26:add(nn.SpatialConvolution(576, 128, 1, 1, 1, 1))
net_26:add(nn.ReLU(true))
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.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)
net:add(concat_123)
local net_29 = nn.Sequential()
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.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.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_136 = nn.Concat(2)
concat_136:add(net_32)
concat_136:add(net_30)
concat_136:add(net_29)
net:add(concat_136)
local net_33 = nn.Sequential()
net_33:add(nn.SpatialConvolution(1024, 1024, 2, 2, 2, 2))
local net_34 = nn.Sequential()
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, 192, 1, 1, 1, 1))
net_35:add(nn.ReLU(true))
net_35:add(nn.SpatialConvolution(192, 320, 3, 3, 1, 1, 1, 1))
net_35:add(nn.ReLU(true))
local net_36 = nn.Sequential()
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_154 = nn.Concat(2)
concat_154:add(net_37)
concat_154:add(net_36)
concat_154:add(net_35)
concat_154:add(net_34)
net_33:add(concat_154)
local net_38 = nn.Sequential()
net_38:add(nn.SpatialConvolution(1024, 352, 1, 1, 1, 1))
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, 320, 3, 3, 1, 1, 1, 1))
net_39:add(nn.ReLU(true))
local net_40 = nn.Sequential()
net_40:add(nn.SpatialConvolution(1024, 192, 1, 1, 1, 1))
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_171 = nn.Concat(2)
concat_171:add(net_41)
concat_171:add(net_40)
concat_171:add(net_39)
concat_171:add(net_38)
net_33:add(concat_171)
net_33:add(nn.SpatialAveragePooling(7, 7, 1, 1))
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_33)
concat_183:add(net_31)
net:add(concat_183)
return net
+11 -11
Ver Arquivo
@@ -2,25 +2,25 @@ require 'nn'
local net = nn.Sequential()
net:add(nn.SpatialConvolution(3, 96, 11, 11, 4, 4))
net:add(nn.ReLU())
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.SpatialConvolution(96, 256, 5, 5, 1, 1))
net:add(nn.ReLU())
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.SpatialConvolution(256, 512, 3, 3, 1, 1))
net:add(nn.ReLU())
net:add(nn.SpatialConvolution(512, 1024, 3, 3, 1, 1))
net:add(nn.ReLU())
net:add(nn.SpatialConvolution(1024, 1024, 3, 3, 1, 1))
net:add(nn.ReLU())
net:add(nn.SpatialConvolution(256, 512, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialConvolution(512, 1024, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialConvolution(1024, 1024, 3, 3, 1, 1, 1, 1))
net:add(nn.ReLU(true))
net:add(nn.SpatialMaxPooling(2, 2, 2, 2))
net:add(nn.View(25600))
net:add(nn.View())
net:add(nn.Dropout(0.5))
net:add(nn.Linear(25600, 3072))
net:add(nn.Threshold(0, 0.000001, false))
net:add(nn.Threshold(0, 0.000001))
net:add(nn.Dropout(0.5))
net:add(nn.Linear(3072, 4096))
net:add(nn.Threshold(0, 0.000001, false))
net:add(nn.Threshold(0, 0.000001))
net:add(nn.Linear(4096, 7))
net:add(nn.LogSoftMax())
+242 -262
Ver Arquivo
@@ -1,292 +1,272 @@
- type: Threshold
id: /Y/1
next:
- /Y/C
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
inplace: false
value: 0.000001
threshold: 0
- type: LogSoftMax
id: /Y/19
next: []
attributes: {}
- type: SpatialConvolution
id: /Y/2
id: /Y/3
next:
- /Y/hb
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 512
nInputPlane: 256
- type: SpatialConvolution
id: /Y/4
next:
- /Y/8
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 64
nInputPlane: 3
- type: SpatialMaxPooling
id: /Y/6
next:
- /Y/IL
attributes:
padW: ''
padH: ''
dH: 2
dW: 2
kH: 2
kW: 2
- type: ReLU
id: /Y/8
next:
- /Y/l
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 512
nInputPlane: 512
- type: SpatialConvolution
id: /Y/5
next:
- /Y/O
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 256
nInputPlane: 128
- type: SpatialConvolution
id: /Y/6
next:
- /Y/9k
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 512
nInputPlane: 512
- type: Dropout
id: /Y/8C
next:
- /Y/W
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
probability: 0.5
- type: ReLU
id: /Y/9k
next:
- /Y/T
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
- type: Dropout
id: /Y/C
next:
- /Y/CC
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
probability: 0.5
- type: Linear
id: /Y/CC
next:
- /Y/qU
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
output: 4096
input: 4096
- type: ReLU
id: /Y/D
next:
- /Y/X
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
- type: SpatialConvolution
id: /Y/H
next:
- /Y/t
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 64
nInputPlane: 3
- type: ReLU
id: /Y/J
next:
- /Y/2
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
p: true
- type: SpatialMaxPooling
id: /Y/K
next:
- /Y/h
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 2
strideWidth: 2
kernelHeight: 2
kernelWidth: 2
- type: ReLU
id: /Y/M
id: /Y/9
next:
- /Y/K
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
- type: ReLU
id: /Y/O
next:
- /Y/Y
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
padW: ''
padH: ''
dH: 2
dW: 2
kH: 2
kW: 2
- type: SpatialConvolution
id: /Y/T
id: /Y/A
next:
- /Y/M
- /Y/y
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 512
nInputPlane: 512
- type: SpatialConvolution
id: /Y/U
next:
- /Y/J
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 512
nInputPlane: 256
- type: Linear
id: /Y/W
next:
- /Y/xG
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
output: 10
input: 4096
- type: SpatialMaxPooling
id: /Y/X
next:
- /Y/U
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 2
strideWidth: 2
kernelHeight: 2
kernelWidth: 2
- type: SpatialConvolution
id: /Y/Y
next:
- /Y/D
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
nOutputPlane: 256
nInputPlane: 256
- type: SpatialConvolution
id: /Y/a
next:
- /Y/v
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 1
strideWidth: 1
kernelHeight: 3
kernelWidth: 3
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 128
nInputPlane: 64
- type: SpatialMaxPooling
id: /Y/e
next:
- /Y/5
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 2
strideWidth: 2
kernelHeight: 2
kernelWidth: 2
- type: View
id: /Y/h
next:
- /Y/zb
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
sizes: 25088
- type: ReLU
id: /Y/l
- type: Threshold
id: /Y/Cg
next:
- /Y/z
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
- type: Threshold
id: /Y/qU
ip: ''
v: 0.000001
th: 0
- type: Linear
id: /Y/D
next:
- /Y/8C
- /Y/f4
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
inplace: false
value: 0.000001
threshold: 0
- type: SpatialMaxPooling
id: /Y/r
next:
- /Y/a
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 2
strideWidth: 2
kernelHeight: 2
kernelWidth: 2
bias: ''
outputSize: 4096
inputSize: 25088
- type: ReLU
id: /Y/t
id: /Y/EE
next:
- /Y/r
- /Y/v
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
- type: ReLU
id: /Y/v
p: true
- type: SpatialConvolution
id: /Y/IL
next:
- /Y/e
- /Y/EE
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
- type: LogSoftMax
id: /Y/xG
next: []
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 512
nInputPlane: 512
- type: SpatialConvolution
id: /Y/K
next:
- /Y/m
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 256
nInputPlane: 128
- type: SpatialMaxPooling
id: /Y/z
id: /Y/M
next:
- /Y/a5
attributes:
padW: ''
padH: ''
dH: 2
dW: 2
kH: 2
kW: 2
- type: Linear
id: /Y/Q
next:
- /Y/19
attributes:
bias: ''
outputSize: 10
inputSize: 4096
- type: ReLU
id: /Y/R
next:
- /Y/M
attributes:
p: true
- type: ReLU
id: /Y/T
next:
- /Y/6
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
strideHeight: 2
strideWidth: 2
kernelHeight: 2
kernelWidth: 2
- type: Linear
id: /Y/zb
p: true
- type: Dropout
id: /Y/U7
next:
- /Y/1
- /Y/k
attributes:
calculateDimensionality: 'function calcDims(layer) return 1; --[[ return output dimensions --]] end'
dimensionalityTransform: same
output: 4096
input: 25088
v1: ''
inplace: ''
p: 0.5
- type: View
id: /Y/a5
next:
- /Y/D
attributes: {}
- type: Threshold
id: /Y/f4
next:
- /Y/U7
attributes:
ip: ''
v: 0.000001
th: 0
- type: ReLU
id: /Y/h
next:
- /Y/j
attributes:
p: true
- type: ReLU
id: /Y/hb
next:
- /Y/l4
attributes:
p: true
- type: SpatialMaxPooling
id: /Y/j
next:
- /Y/3
attributes:
padW: ''
padH: ''
dH: 2
dW: 2
kH: 2
kW: 2
- type: Linear
id: /Y/k
next:
- /Y/Cg
attributes:
bias: ''
outputSize: 4096
inputSize: 4096
- type: SpatialMaxPooling
id: /Y/l
next:
- /Y/A
attributes:
padW: ''
padH: ''
dH: 2
dW: 2
kH: 2
kW: 2
- type: SpatialConvolution
id: /Y/l4
next:
- /Y/T
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 512
nInputPlane: 512
- type: ReLU
id: /Y/m
next:
- /Y/x
attributes:
p: true
- type: SpatialConvolution
id: /Y/v
next:
- /Y/R
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 512
nInputPlane: 512
- type: SpatialConvolution
id: /Y/x
next:
- /Y/h
attributes:
padH: 1
padW: 1
dH: 1
dW: 1
kH: 3
kW: 3
nOutputPlane: 256
nInputPlane: 256
- type: ReLU
id: /Y/y
next:
- /Y/9
attributes:
p: true
- type: Dropout
id: /Y/z
next:
- /Y/Q
attributes:
v1: ''
inplace: ''
p: 0.5
+114
Ver Arquivo
@@ -0,0 +1,114 @@
{
"Convolution": [
"TemporalConvolution",
"TemporalMaxPooling",
"TemporalSubSampling",
"LookupTable",
"SpatialConvolutionMM",
"SpatialConvolution",
"SpatialConvolutionMap",
"SpatialFullConvolutionMap",
"SpatialLPPooling",
"SpatialMaxPooling",
"SpatialAveragePooling",
"SpatialAdaptiveMaxPooling",
"SpatialSubSampling",
"SpatialUpSamplingNearest",
"SpatialZeroPadding",
"SpatialReflectionPadding",
"SpatialReplicationPadding",
"SpatialSubtractiveNormalization",
"SpatialCrossMapLRN",
"SpatialConvolutionLocal",
"SpatialDropout",
"SpatialDilatedConvolution",
"SpatialFractionalMaxPooling",
"SpatialDivisiveNormalization",
"SpatialContrastiveNormalization",
"SpatialBatchNormalization",
"SpatialFullConvolution",
"SpatialMaxUnpooling",
"VolumetricConvolution",
"VolumetricMaxPooling",
"VolumetricAveragePooling",
"VolumetricBatchNormalization",
"VolumetricDropout",
"VolumetricFullConvolution",
"VolumetricMaxUnpooling"
],
"Containers": [
"Concat"
],
"Criterion": [
"BCECriterion",
"WeightedMSECriterion",
"SmoothL1Criterion",
"MSECriterion",
"AbsCriterion",
"MultiCriterion",
"DistKLDivCriterion",
"HingeEmbeddingCriterion",
"CriterionTable",
"MultiMarginCriterion",
"MultiLabelMarginCriterion",
"L1HingeEmbeddingCriterion",
"CosineEmbeddingCriterion",
"MarginRankingCriterion",
"CrossEntropyCriterion",
"MarginCriterion",
"ClassNLLCriterion",
"ParallelCriterion",
"SpatialClassNLLCriterion",
"SoftMarginCriterion",
"MultiLabelSoftMarginCriterion"
],
"Simple": [
"Linear",
"SparseLinear",
"Dropout",
"Abs",
"Add",
"Mul",
"CMul",
"Max",
"Min",
"Mean",
"Sum",
"Euclidean",
"WeightedEuclidean",
"Identity",
"Copy",
"Narrow",
"Replicate",
"Reshape",
"View",
"Select",
"Exp",
"Square",
"Sqrt",
"Power",
"MM",
"AddConstant",
"MulConstant"
],
"Transfer": [
"Threshold",
"HardTanh",
"HardShrink",
"SoftShrink",
"SoftMax",
"SpatialSoftMax",
"SoftMin",
"SoftPlus",
"SoftSign",
"LogSigmoid",
"LogSoftMax",
"Sigmoid",
"Tanh",
"ReLU",
"PReLU",
"RReLU",
"LeakyReLU"
]
}
+99
Ver Arquivo
@@ -0,0 +1,99 @@
var fs = require('fs');
var path = require('path');
var parser = require('../src/common/lua').parser;
var torchPath = process.env.HOME + '/torch/extra/nn/';
var SKIP_LAYERS = {};
var skipLayerList = require('./skipLayers.json');
skipLayerList.forEach(name => SKIP_LAYERS[name] = true);
var findInitParams = function(ast){
// Find '__init' function
var params;
ast.block.stats.forEach(function(block){
if(block.key && block.key.val == '__init' && block.func){
params = block.func.args;
}
});
return params;
};
var findTorchClass = function(ast){
var torchClassArgs, // args for `torch.class(...)`
name = '',
baseType,
params = [];
if(ast.type == 'function'){
ast.block.stats.forEach(function(func){
if(func.type == 'stat.local' && func.right && func.right[0] &&
func.right[0].func && func.right[0].func.self &&
func.right[0].func.self.val == 'torch' &&
func.right[0].func.key.val == 'class'){
torchClassArgs = func.right[0].args.map(arg => arg.val);
name = torchClassArgs[0];
if(name !== ''){
name = name.replace('nn.', '');
params = findInitParams(ast);
if (torchClassArgs.length > 1) {
baseType = torchClassArgs[1].replace('nn.', '');
}
}
}
});
}
return {
name,
baseType,
params
};
};
var categories = require('./categories.json');
var catNames = Object.keys(categories);
var layerToCategory = {};
catNames.forEach(cat => // create layer -> category dictionary
categories[cat].forEach(lname => layerToCategory[lname] = cat)
);
var lookupType = function(name){
var layerType = layerToCategory[name];
if (!layerType) { // try to infer
layerType = name.indexOf('Criterion') > -1 && 'Criterion';
}
return layerType || 'Misc';
};
fs.readdir(torchPath, function(err,files){
if(err) throw err;
var layers,
layerByName = {};
layers = files.filter(filename => path.extname(filename) === '.lua')
.map(filename => fs.readFileSync(torchPath + filename, 'utf8'))
.map(code => parser.parse(code))
.map(ast => findTorchClass(ast)) // create initial layers
.filter(layer => !!layer && layer.name);
layers.forEach(layer => {
layer.type = lookupType(layer.name);
layerByName[layer.name] = layer;
layer.setters = [];
});
// handle inheritance
layers.forEach(layer => {
var iter = layer,
params = layer.params;
while (iter && params === undefined) {
params = iter.params;
iter = layerByName[iter.baseType];
}
layer.params = params;
});
layers = layers.filter(layer => !SKIP_LAYERS[layer.name]);
// eslint-disable-next-line no-console
console.log('Saved nn interface to src/common/layers.json');
fs.writeFileSync('src/common/layers.json', JSON.stringify(layers, null, 2));
});
+7
Ver Arquivo
@@ -0,0 +1,7 @@
[
"Sequential",
"Container",
"Criterion",
"StochasticGradient",
"Module"
]
+35 -3
Ver Arquivo
@@ -28,6 +28,14 @@
"CreateExecution": {
"src": "src/plugins/CreateExecution",
"test": "test/plugins/CreateExecution"
},
"GenerateExecFile": {
"src": "src/plugins/GenerateExecFile",
"test": "test/plugins/GenerateExecFile"
},
"ImportArtifact": {
"src": "src/plugins/ImportArtifact",
"test": "test/plugins/ImportArtifact"
}
},
"layouts": {},
@@ -122,6 +130,27 @@
"panel": "src/visualizers/panels/DeserializeEditor",
"secondary": false,
"widget": "src/visualizers/widgets/DeserializeEditor"
},
"Footer": {
"src": "panels/Footer/FooterPanel",
"title": "Footer",
"panel": "src/visualizers/panels/Footer",
"secondary": false,
"widget": "src/visualizers/widgets/Footer"
},
"LogViewer": {
"src": "panels/LogViewer/LogViewerPanel",
"title": "LogViewer",
"panel": "src/visualizers/panels/LogViewer",
"secondary": false,
"widget": "src/visualizers/widgets/LogViewer"
},
"LayerEditor": {
"src": "panels/LayerEditor/LayerEditorPanel",
"title": "LayerEditor",
"panel": "src/visualizers/panels/LayerEditor",
"secondary": false,
"widget": "src/visualizers/widgets/LayerEditor"
}
},
"addons": {},
@@ -137,6 +166,12 @@
},
"OpIntPtrDecorator": {
"src": "src/decorators/OpIntPtrDecorator"
},
"DcOpDecorator": {
"src": "src/decorators/DcOpDecorator"
},
"ArtifactOpDecorator": {
"src": "src/decorators/ArtifactOpDecorator"
}
},
"seeds": {
@@ -146,9 +181,6 @@
"devTests": {
"src": "src/seeds/devTests"
},
"devMinimal": {
"src": "src/seeds/devMinimal"
},
"devUtilTests": {
"src": "src/seeds/devUtilTests"
},