Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bin/jet
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/python
import argparse
import sys, os, shutil
import pkgutil
import imp
from jet.version import __version__

jet_path = pkgutil.get_loader("jet").filename
jet_path = imp.find_module("jet")[1]

description = \
"""
Expand Down
21 changes: 12 additions & 9 deletions jet/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from sys import modules as _modules
import types as _types
import inspect as _inspect
import numpy as _numpy
from jet import config
jet_mode = config.jet_mode
Expand All @@ -13,19 +14,21 @@
module = _modules[__name__]

# decorate numpy attributes
for name, attr in _numpy.__dict__.iteritems():
for name, attr in _numpy.__dict__.items():
if not name.startswith("_") and not isinstance(attr, _types.BuiltinFunctionType):
if callable(attr):
module.__dict__[name] = _helpers.numpy_mode(attr)
module.__dict__[name] = _helpers.numpy_method(attr)
else:
module.__dict__[name] = attr

# decorate jet-intake attributes
for name, attr in _intake.__dict__.iteritems():
if not name.startswith("_") and \
(callable(attr) or hasattr(attr, '__class__')) and \
not isinstance(attr, _types.BuiltinFunctionType):
module.__dict__[name] = _helpers.jet_mode(attr)
for name, attr in _intake.__dict__.items():
if not name.startswith("_"):
if _inspect.isclass(attr):
setattr(module, name, attr)
elif callable(attr) and \
not isinstance(attr, _types.BuiltinFunctionType):
module.__dict__[name] = _helpers.jet_method(attr)

def set_options(jet_mode=True,
debug=False,
Expand All @@ -36,8 +39,8 @@ def set_options(jet_mode=True,
group_class=False,
group_func=False,
DTYPE=_numpy.float64):

jet_mode = jet_mode
setattr(module, 'jet_mode', jet_mode)
config.jet_mode = jet_mode
config.debug = debug
config.draw_graph = draw_graph
Expand Down
2 changes: 1 addition & 1 deletion jet/expander.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ def find_node(n):
def check_type(*args):
arg_list = list(args)
num_types = [float, int, bool, np.ndarray, np.float64, np.float32]
jet_types = [intake.variable, intake.constant, intake.placeholder, intake.array]
jet_types = [intake.variable, intake.constant, intake.placeholder, intake.ndarray]

for i, arg in enumerate(args):
if arg is not None and type(arg) not in jet_types:
Expand Down
54 changes: 37 additions & 17 deletions jet/helpers.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,48 @@
import numpy
from jet import jet_mode
import jet.intake as intake
import jet

def jet_error(attr_name):
raise NotImplementedError('\'{}\' is a special member of '
'JET which is not part of Numpy\'s API.'.format(attr_name))


def numpy_error(attr_name):
raise NotImplementedError('Attribute \'{}\' is available in Numpy but not '
'in JET yet.'.format(attr_name))

def jet_mode(attr):
if jet_mode:
return attr
attr_name = attr.__name__
np_obj = getattr(numpy, attr_name, None)
if np_obj is not None:
return np_obj
return lambda *args, **kwargs: jet_error(attr_name)
def jet_method(attr):
def wrapper(*args, **kwargs):
if jet.jet_mode:
return attr(*args, **kwargs)
attr_name = attr.__name__
np_obj = getattr(numpy, attr_name, None)
if np_obj is not None:
return np_obj(*args, **kwargs)
jet_error(attr_name)
return wrapper

def numpy_method(np_obj):
def wrapper(*args, **kwargs):
if not jet.jet_mode:
return np_obj(*args, **kwargs)
attr_name = np_obj.__name__
numpy_error(attr_name)
return wrapper

def jet_class_method(cls):
def decorator(attr):
def wrapper(*args, **kwargs):
if jet.jet_mode:
return attr(*args, **kwargs)
attr_name = attr.__name__
np_obj = getattr(getattr(numpy, cls, None), attr_name, None)
if np_obj is not None:
return np_obj(*args, **kwargs)
jet_error(attr_name)
return wrapper
return decorator

def numpy_mode(np_obj):
if not jet_mode:
return np_obj
attr_name = np_obj.__name__
attr = getattr(intake, attr_name, None)
return lambda *args, **kwargs: numpy_error(attr_name)
def jet_static_class(cls):
for name, attr in cls.__dict__.items():
if callable(attr):
setattr(cls, name, staticmethod(jet_class_method(cls.__name__)(attr)))
return cls
6 changes: 3 additions & 3 deletions jet/include/supportlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ void set_items(T& lhs, const Q& rhs, const std::array<int, 2>& start,
}
}

template<typename T>
T mod(const T& x, const float m) {
template<typename T, typename S>
T mod(const T& x, const S& m) {
return std::fmod(x, m);
}
}
30 changes: 17 additions & 13 deletions jet/intake.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
from jet import config
from jet import utils
from jet import expander
from jet import helpers


##########################################################################
#### General Functions ####
##########################################################################

def clip(a, a_min, a_max):
op = expander.ClipOp([a, a_min, a_max])
def clip(array, a_min, a_max):
op = expander.ClipOp([array, a_min, a_max])
return op.get_output()

def where(condition, x, y):
Expand Down Expand Up @@ -174,7 +175,6 @@ def transpose(array):
def ravel(array):
return array.ravel()


def reshape(array, shape):
return array.reshape(shape)

Expand Down Expand Up @@ -214,27 +214,28 @@ def logical_not(x):
#### Other Functions ####
##########################################################################

@helpers.jet_static_class
class linalg(object):
def solve(self, lhs, rhs):
def solve( lhs, rhs):
op = expander.SolveOp([lhs, rhs])
return op.get_output()

def norm(self, x, order=2):
def norm(x, order=2):
op = expander.NormOp([x], order)
return op.get_output()
linalg = linalg()

@helpers.jet_static_class
class random(object):
def normal(self, mean=0, sd=1):
def normal(mean=0, sd=1):
op = expander.RandomNormalOp([mean, sd])
return op.get_output()
random = random()

##########################################################################
#### Array Objects ####
##########################################################################

class array(object): # TODO dominique: PEP8 requires CamelCase for class names
# not compatible with numpy's ndarray
class ndarray(object): # TODO dominique: PEP8 requires CamelCase for class names
def __init__(self, value=None, name='array', shape=(), dtype=config.DTYPE,
producer=None, **kwargs):
if value is None:
Expand Down Expand Up @@ -440,7 +441,10 @@ def __abs__(self):
def __array_wrap__(self, result):
return constant(result)

class variable(array): # TODO dominique: PEP8 requires CamelCase for class names
def array(*args, **kwargs):
return ndarray(*args, **kwargs)

class variable(ndarray): # TODO dominique: PEP8 requires CamelCase for class names
# variable results in member variable in generated class
def __init__(self, value=None, name='variable', shape=(), dtype=config.DTYPE):
_check_not_jet_type(value, name)
Expand All @@ -452,7 +456,7 @@ def __init__(self, value=None, name='variable', shape=(), dtype=config.DTYPE):
op = expander.VariableOp([self])
self.producer = op

class placeholder(array): # TODO dominique: PEP8 requires CamelCase for class names
class placeholder(ndarray): # TODO dominique: PEP8 requires CamelCase for class names
# placeholder results in argument to be passed in generated function
def __init__(self, name='placeholder', shape=(), dtype=config.DTYPE):
super(placeholder, self).__init__(name=name, shape=shape, dtype=dtype)
Expand All @@ -466,7 +470,7 @@ def __repr__(self):
return '<placeholder: {}/{} {}>'.format(self.dtype.name, self.shape,
self.name)

class constant(array): # TODO dominique: PEP8 requires CamelCase for class names
class constant(ndarray): # TODO dominique: PEP8 requires CamelCase for class names
# constant results in constant expression in generated class
def __init__(self, value, name='constant', dtype=config.DTYPE):
_check_not_jet_type(value, name)
Expand All @@ -487,7 +491,7 @@ def __repr__(self):
##########################################################################

def _check_not_jet_type(obj, name):
if isinstance(obj, array) or (isinstance(obj, numpy.ndarray) and
if isinstance(obj, ndarray) or (isinstance(obj, numpy.ndarray) and
obj.dtype == object):
raise ValueError('Can\'t add this object to jet {}.'.format(name))

Expand Down
12 changes: 10 additions & 2 deletions jet/jit.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
from jet.compressor import JetBuilder
from jet.utils import sanitize_name, get_caller_info
from jet.intake import placeholder
Expand All @@ -22,7 +23,14 @@ def wrapper(*args):

shapes = _func_cached_dict[func_id]['shapes']

arg_names = func.__code__.co_varnames[0:func.__code__.co_argcount]
if inspect.ismethod(func):
arg_names = func.__code__.co_varnames[1:func.__code__.co_argcount]
else:
arg_names = func.__code__.co_varnames[:func.__code__.co_argcount]

if len(arg_names) != len(args):
assert(len(arg_names) == 0)
arg_names = [get_unique_name('ph') for each in args]

if len(shapes) != len(arg_names) and shapes:
raise ValueError('Shapes length does not match the arguments length.')
Expand All @@ -40,7 +48,7 @@ def wrapper(*args):
file_name=get_unique_name(sanitize_name('{}_{}_{func_name}'.format(
*get_caller_info('jit.py')[1:-1],
func_name=fun_name))),
fun_name=fun_name)
fun_name=get_unique_name(fun_name))

jet_class = getattr(jb.build(), jb.class_name)
jet_func = getattr(jet_class(), jb.fun_name)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def package_files(directory):
],

install_requires=[
'numpy',
'numpy; python_version < "3"',
'networkx'],
packages=['jet'],
scripts=['bin/jet'],
Expand Down
19 changes: 19 additions & 0 deletions tests/0d
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
maximum
minimum
logical_not
logical_or
logical_and
logical_xor
sin
cos
tan
arcsin
arccos
arctan
arctan2
mod
power
sqrt
sign
log
exp
13 changes: 13 additions & 0 deletions tests/1d
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cross
dot
multiply
matmul
divide
true_divide
reciprocal
clip
ravel
transpose
concatenate
vstack
hstack
25 changes: 25 additions & 0 deletions tests/2d
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
where
max
min
amax
amin
fabs
negative
add
subtract
multiply
matmul
dot
divide
true_divide
reciprocal
clip
eye
zeros
ones
reshape
ravel
transpose
concatenate
vstack
hstack
15 changes: 15 additions & 0 deletions tests/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'

def cprint(text, success, metadata=''):
if success:
print(bcolors.OKGREEN + text + bcolors.ENDC)
else:
print(bcolors.FAIL + text + bcolors.ENDC + (metadata and " " + str(metadata)))
8 changes: 8 additions & 0 deletions tests/mix0d
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add
subtract
power
divide
true_divide
multiply
dot
mod
9 changes: 9 additions & 0 deletions tests/mix1d
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
matmul
add
subtract
power
divide
true_divide
multiply
dot
mod
Loading