initializing scalar/tensor modules

上级 42e90582
import unittest
from gof import ResultBase
from gof import Op
from gof import Env
from gof import modes
from scalar_ops import *
def inputs():
x = modes.BuildEvalMode(as_scalar(1.0, 'x'))
y = modes.BuildEvalMode(as_scalar(2.0, 'y'))
z = modes.BuildEvalMode(as_scalar(3.0, 'z'))
return x, y, z
def env(inputs, outputs, validate = True, features = []):
inputs = [input.r for input in inputs]
outputs = [output.r for output in outputs]
return Env(inputs, outputs, features = features, consistency_check = validate)
class _test_ScalarOps(unittest.TestCase):
def test_0(self):
x, y, z = inputs()
e = mul(add(x, y), div(x, y))
assert e.r.data == 1.5
if __name__ == '__main__':
unittest.main()
...@@ -64,7 +64,6 @@ class Div(Binary): ...@@ -64,7 +64,6 @@ class Div(Binary):
import modes import modes
modes.make_constructors(globals()) modes.make_constructors(globals())
def inputs(): def inputs():
x = modes.BuildMode(Double(1.0, 'x')) x = modes.BuildMode(Double(1.0, 'x'))
y = modes.BuildMode(Double(2.0, 'y')) y = modes.BuildMode(Double(2.0, 'y'))
......
import numpy
from copy import copy
from gof import ResultBase
from gof import Op
from gof import utils
def as_scalar(x, name = None):
if isinstance(x, float):
s = Scalar('float64', name = name)
s.data = x
return s
if isinstance(x, Scalar):
return x
class Scalar(ResultBase):
def __init__(self, dtype, name=None):
self.dtype = dtype
ResultBase.__init__(self, role = None, data = None, name = name)
def validate(self, data):
py_type = self.py_type()
if not isinstance(data, py_type):
raise TypeError("Expected %s instance." % py_type)
def py_type(self):
return {'float64': float}[self.dtype]
def c_type(self):
return {'float64': 'double'}[self.dtype]
def c_from(self):
return {'float64': 'PyFloat_FromDouble'}[self.dtype]
def c_as(self):
return {'float64': 'PyFloat_AsDouble'}[self.dtype]
def c_declare(self):
return """
%(dtype)s* %%(name)s;
typedef %(dtype)s %%(name)s_dtype;
""" % dict(dtype = self.c_type())
def c_data_extract(self):
return """
%%(name)s = (%(dtype)s)%(conv)s(py_%%(name)s);
if (!%%(name)s)
%%(fail)s
""" % dict(dtype = self.c_type(),
conv = self.c_as())
def c_data_sync(self):
return """
Py_XDECREF(py_%%(name)s);
py_%%(name)s = %(conv)s((%(dtype)s)%%(name)s);
if (!py_%%(name)s)
py_%%(name)s = Py_None;
""" % dict(dtype = self.c_type(),
conv = self.c_as())
def c_data_cleanup(self):
return ""
def c_headers(self):
return []
def c_libraries(self):
return []
class ScalarMixedOp(Op):
nin = -1
nout = 1
def __init__(self, *inputs):
if self.nin >= 0:
if len(inputs) != self.nin:
raise TypeError("Wrong number of inputs for %s (got %i, expected %i)") \
% (self, len(inputs), self.nin)
i_dtypes = [getattr(input, 'dtype', None) for input in inputs]
o_dtypes = utils.from_return_values(self.propagate_dtypes(*i_dtypes))
self.inputs = inputs
self.outputs = [Scalar(dtype) for dtype in o_dtypes]
def propagate_dtypes(self, *inputs):
raise AbstractFunctionError()
def impl(self, *inputs):
raise AbstractFunctionError()
def grad(self, inputs, output_gradients):
raise AbstractFunctionError()
def perform(self):
self.outputs[0].data = self.impl(*[input.data for input in self.inputs])
def upcast(dtype, *dtypes):
z = numpy.zeros((), dtype = dtype)
for dtype in dtypes:
z = z + numpy.zeros((), dtype = dtype)
return str(z.dtype)
class PureScalarOp(ScalarMixedOp):
cast_method = lambda self, *args: upcast(*args)
def propagate_dtypes(self, *i_dtypes):
for dtype in i_dtypes:
if dtype is None:
raise TypeError("Expected a Scalar.")
return self.cast_method(*i_dtypes)
class UnaryScalarOp(PureScalarOp):
nin = 1
class BinaryScalarOp(PureScalarOp):
nin = 2
from scalar import *
import math
class Add(BinaryScalarOp):
def impl(self, x, y):
return x + y
def c_impl(self, (x, y), z):
return "%(z)s = %(x)s + %(y)s;"
def grad(self, (x, y), gz):
return gz, gz
class Sub(BinaryScalarOp):
def impl(self, x, y):
return x - y
def c_impl(self, (x, y), z):
return "%(z)s = %(x)s - %(y)s;"
def grad(self, (x, y), gz):
return gz, -gz
class Mul(BinaryScalarOp):
def impl(self, x, y):
return x * y
def c_impl(self, (x, y), z):
return "%(z)s = %(x)s * %(y)s;"
def grad(self, (x, y), gz):
return mul(y, gz), mul(x, gz)
class Div(BinaryScalarOp):
def impl(self, x, y):
return x / y
def c_impl(self, (x, y), z):
return "%(z)s = %(x)s / %(y)s;"
def grad(self, (x, y), gz):
return div(gz, y), -div(mul(x, gz), y*y)
class Pow(BinaryScalarOp):
def impl(self, x, y):
return x ** y
def c_impl(self, (x, y), z):
return "%(z)s = pow(%(x)s, %(y)s);"
class Neg(UnaryScalarOp):
def impl(self, x):
return -x
def grad(self, x, gz):
return -gz
def c_impl(self, x, z):
return "%(z)s = -%(x)s;"
class Inv(UnaryScalarOp):
def impl(self, x):
return 1 / x
def grad(self, x, gz):
return -gz / (x*x)
def c_impl(self, x, z):
return "%(z)s = 1 / %(x)s;"
class Log(UnaryScalarOp):
def impl(self, x):
return math.log(x)
def c_impl(self, x, z):
return "%(z)s = log(%(x)s);"
class Exp(UnaryScalarOp):
def impl(self, x):
return math.exp(x)
def c_impl(self, x, z):
return "%(z)s = exp(%(x)s);"
# class Sigmoid(UnaryComposite):
# def expand_impl(self, x):
# return 1.0 / (1.0 + exp(-x))
from gof import modes
modes.make_constructors(globals())
import numpy
from copy import copy
from gof import ResultBase
from gof import Op
class NumpyR(ResultBase):
def __init__(self, dtype, nd, name=None):
self.nd = nd
self.dtype = dtype
ResultBase.__init__(self, role = None, data = None, name = name)
def validate(self, data):
if not isinstance(data, numpy.ndarray):
raise TypeError("Expected ndarray instance.")
elif not len(data.shape) == self.nd:
raise TypeError("Expected ndarray with %i dimensions." % self.nd)
elif not str(data.dtype) == self.dtype:
raise TypeError("Expected ndarray with data type %i." % self.dtype)
def to_c_type(self, dtype):
if dtype == "float64":
return "double"
else:
raise TypeError("Cannot translate dtype to C.")
def c_declare(self):
return """
PyArrayObject* %%(name)s;
typedef %(dtype)s %%(name)s_dtype;
""" % dict(dtype = self.to_c_type(self.dtype))
def c_data_extract(self):
return """
if (py_%(name)s == Py_None)
%(name)s = NULL;
else
%(name)s = (PyArrayObject*)(py_%(name)s);
"""
def c_data_cleanup(self):
return ""
def c_data_sync(self):
return """
if (!%(name)s) {
Py_XDECREF(py_%(name));
py_%(name)s = Py_None;
}
else if ((void*)py_%(name)s != (void*)%(name)s) {
Py_XDECREF(py_%(name));
py_%(name)s = (PyObject*)%(name)s;
}
"""
def c_headers(self):
return []
def c_libraries(self):
return []
def __copy__(self):
cpy = self.__class__(self.dtype, self.nd, self.name)
cpy.data = copy(self.data)
return cpy
def TheanoOp(Op):
nin = -1
nout = 1
def __init__(self, *inputs):
if self.nin >= 0:
if len(inputs) != self.nin:
raise TypeError("Wrong number of inputs for %s (got %i, expected %i)") \
% (self, len(inputs), self.nin)
i_nds = [getattr(input, 'nd', None) for input in inputs]
i_dtypes = [getattr(input, 'dtype', None) for input in inputs]
o_nds = self.propagate_nd(*i_nds)
o_dtypes = self.propagate_dtypes(*i_dtypes)
return [NumpyR(nd, dtype) for nd, dtype in zip(o_nds, o_dtypes)]
def propagate_nds(self, *inputs):
raise AbstractFunctionError()
def propagate_dtypes(self, *inputs):
raise AbstractFunctionError()
def impl(self, *inputs):
raise AbstractFunctionError()
def perform(self):
self.outputs[0].data = self.impl(*[input.data for input in self.inputs])
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论