Skip to content

Commit

Permalink
Sweet.js macro transforms.
Browse files Browse the repository at this point in the history
  • Loading branch information
dritchie committed Nov 4, 2015
1 parent a06e7db commit 5ce8a23
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/*
7 changes: 4 additions & 3 deletions ad/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
var graph = require('./graph.js');
var func = require('./func.js');
var functions = require('./functions.js');
var Tensor = require('../tensor.js');

function liftScalar(x) { return new graph.ScalarNode(x); };
Expand All @@ -15,8 +13,11 @@ var ad = {
project: function(x) { return graph.isNode(x) ? x.x : x; }
};

var func = require('./func.js');
var functions = require('./functions.js');
var transform = require('./transform.js');
var modules = [
func, functions
func, functions, transform
];
for (var i = 0; i < modules.length; i++) {
var m = modules[i];
Expand Down
File renamed without changes.
53 changes: 53 additions & 0 deletions ad/transform.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
var sweet = require('sweet.js');
var fs = require('fs');
var cp = require('child_process');

var adRequireStr = "var ad = require('adnn/ad');\n";
var macros = undefined;
function getMacros() {
if (macros === undefined) {
macros = sweet.loadNodeModule(__dirname, './macros.sjs');
}
return macros;
}

// Macro transform some code
function macroTransform(code) {
var compiledCode = sweet.compile(code, {
modules: getMacros(),
readableNames: true
}).code;
return adRequireStr + compiledCode;
}

// Macro transform a module before requiring it.
// Optionally cache the transformed module code on disk.
// NOTE: Once cached, it won't be recompiled (unless you macroRequire the same
// module again with 'cacheOnDisk' set to false). So this isn't like 'make',
// which will detect changes and recompile for you. Thus, 'cacheOnDisk' is
// best used for modules which aren't going to change (or which change very
// infrequently).
function macroRequire(modulename, cacheOnDisk) {
var filename = require.resolve(modulename);
var adfilename = filename + '.ad';
var m = require.cache[adfilename];
if (m !== undefined) {
m = m.exports;
} else {
if (!cacheOnDisk || !fs.existsSync(adfilename)) {
var code = fs.readFileSync(filename);
var compiledCode = macroTransform(code);
fs.writeFileSync(adfilename, compiledCode);
}
m = require(adfilename);
if (!cacheOnDisk) {
cp.execSync('rm -f ' + adfilename);
}
}
return m;
}

module.exports = {
macroTransform: macroTransform,
macroRequire: macroRequire
}
24 changes: 24 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "adnn",
"version": "0.0.1",
"description": "Javascript neural networks on top of general scalar/tensor reverse-mode automatic differentiation.",
"author": "dritchie",
"license": "MIT",
"dependencies": {
"sweet.js": "^0.7.4"
},
"repository": {
"type": "git",
"url": "https://github.com/dritchie/adnn"
},
"bugs": {
"url": "https://github.com/dritchie/adnn/issues"
},
"engines": {
"node": ">=0.12.4"
},
"keywords": [
"automatic differentiation",
"neural networks"
]
}
7 changes: 7 additions & 0 deletions testmodule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
function foo(x, y) {
return Math.sqrt(x*x + y*y);
}

module.exports = {
foo: foo
};

0 comments on commit 5ce8a23

Please sign in to comment.