moved scalar_ops to scalar, removed old elemwise.py.

上级 f1153866
...@@ -5,7 +5,7 @@ import unittest ...@@ -5,7 +5,7 @@ import unittest
from gof import ResultBase, Op, Env, modes from gof import ResultBase, Op, Env, modes
import gof import gof
from scalar_ops import * from scalar import *
from elemwise2 import * from elemwise2 import *
......
...@@ -22,7 +22,7 @@ class _test_grad_sources_inputs(unittest.TestCase): ...@@ -22,7 +22,7 @@ class _test_grad_sources_inputs(unittest.TestCase):
try: try:
grad_sources_inputs([(a.out, 1)], None) grad_sources_inputs([(a.out, 1)], None)
except ValueError, e: except ValueError, e:
self.failUnless(e[0] is gradient._msg_retNone) self.failUnless(e[0] is gradient._msg_retType)
return return
self.fail() self.fail()
def test_retNone1_b(self): def test_retNone1_b(self):
......
...@@ -4,7 +4,7 @@ import unittest ...@@ -4,7 +4,7 @@ import unittest
from gof import ResultBase, Op, Env, modes from gof import ResultBase, Op, Env, modes
import gof import gof
from scalar_ops import * from scalar import *
def inputs(): def inputs():
......
差异被折叠。
...@@ -4,8 +4,8 @@ import elemwise_cgen as cgen ...@@ -4,8 +4,8 @@ import elemwise_cgen as cgen
import numpy import numpy
from gof import Op, Viewer, Destroyer from gof import Op, Viewer, Destroyer
from base_tensor import BaseTensor as Tensor from base_tensor import BaseTensor as Tensor
import scalar
from scalar import upcast, Scalar from scalar import upcast, Scalar
import scalar_ops
import gof import gof
from gof.python25 import all from gof.python25 import all
...@@ -424,7 +424,7 @@ class CAReduce(Op): ...@@ -424,7 +424,7 @@ class CAReduce(Op):
tosum = self.dimensions_to_reduce tosum = self.dimensions_to_reduce
if tosum == (): if tosum == ():
return Broadcast(scalar_ops.Identity, (input, ))._c_all(inames, onames, sub) return Broadcast(scalar.Identity, (input, ))._c_all(inames, onames, sub)
order1 = [i for i in xrange(len(input.broadcastable)) if i not in tosum] order1 = [i for i in xrange(len(input.broadcastable)) if i not in tosum]
order = order1 + list(tosum) order = order1 + list(tosum)
...@@ -522,7 +522,7 @@ def make_reduce(scalar_opclass, name = None): ...@@ -522,7 +522,7 @@ def make_reduce(scalar_opclass, name = None):
New.__name__ = "Reduce" + scalar_opclass.__name__ New.__name__ = "Reduce" + scalar_opclass.__name__
return New return New
class Sum(make_reduce(scalar_ops.Add)): class Sum(make_reduce(scalar.Add)):
def grad(self, (x, ), (gz, )): def grad(self, (x, ), (gz, )):
if self.dimensions_to_reduce == (): if self.dimensions_to_reduce == ():
return gz, return gz,
...@@ -534,7 +534,7 @@ class Sum(make_reduce(scalar_ops.Add)): ...@@ -534,7 +534,7 @@ class Sum(make_reduce(scalar_ops.Add)):
else: else:
new_dims.append(i) new_dims.append(i)
i += 1 i += 1
return Broadcast(scalar_ops.Second, (x, DimShuffle(gz, new_dims).out)).out, return Broadcast(scalar.Second, (x, DimShuffle(gz, new_dims).out)).out,
def reduce(op): def reduce(op):
......
...@@ -58,6 +58,8 @@ class Op(object): ...@@ -58,6 +58,8 @@ class Op(object):
# #
# Python stdlib compatibility # Python stdlib compatibility
# #
# These are defined so that sets of Ops, Results will have a consistent
# ordering
def __cmp__(self, other): def __cmp__(self, other):
return cmp(id(self), id(other)) return cmp(id(self), id(other))
......
...@@ -3,7 +3,7 @@ import numpy #for numeric_grad ...@@ -3,7 +3,7 @@ import numpy #for numeric_grad
from gof.python25 import all from gof.python25 import all
_msg_retNone = 'op.grad(...) returned None, consider returning [None]' _msg_retType = 'op.grad(...) returned a non-list'
_msg_badlen = 'op.grad(...) returned wrong number of gradients' _msg_badlen = 'op.grad(...) returned wrong number of gradients'
def _unpack_result(lst): def _unpack_result(lst):
...@@ -82,10 +82,8 @@ def grad_sources_inputs(sources, graph_inputs): ...@@ -82,10 +82,8 @@ def grad_sources_inputs(sources, graph_inputs):
output_arg = g_outputs output_arg = g_outputs
input_arg = op.inputs input_arg = op.inputs
op_grad = op.grad(input_arg, output_arg) op_grad = op.grad(input_arg, output_arg)
if op_grad is None: if not isinstance(op_grad, (list,tuple)):
raise ValueError(_msg_retNone, op.__class__) raise ValueError(_msg_retType, op.__class__)
if isinstance(op_grad, float):
raise TypeError('wtf!!!!!!!!', op)
g_inputs = op_grad #_pack_result(op_grad) g_inputs = op_grad #_pack_result(op_grad)
assert isinstance(g_inputs, (list, tuple)) assert isinstance(g_inputs, (list, tuple))
if len(g_inputs) != len(op.inputs): if len(g_inputs) != len(op.inputs):
......
import numpy import numpy
import math
from copy import copy from copy import copy
import inspect import inspect
...@@ -143,6 +144,35 @@ class Scalar(ResultBase): ...@@ -143,6 +144,35 @@ class Scalar(ResultBase):
cpy.data = self.data cpy.data = self.data
return cpy return cpy
#UNARY
def __abs__(self): return Abs(self).out
def __neg__(self): return Neg(self).out
#CASTS
def __int__(self): return AsInt(self).out
def __float__(self): return AsInt(self).out
def __complex__(self): return AsComplex(self).out
#COMPARISONS
def __lt__(self,other): return lt(self, other)
def __le__(self,other): return le(self, other)
def __gt__(self,other): return gt(self, other)
def __ge__(self,other): return ge(self, other)
#ARITHMETIC - NORMAL
def __add__(self,other): return add(self,other)
def __sub__(self,other): return sub(self,other)
def __mul__(self,other): return mul(self,other)
def __div__(self,other): return div(self,other)
def __pow__(self,other): return pow(self,other)
#ARITHMETIC - RIGHT-OPERAND
def __radd__(self,other): return add(other,self)
def __rsub__(self,other): return sub(other,self)
def __rmul__(self,other): return mul(other,self)
def __rdiv__(self,other): return div(other,self)
def __rpow__(self,other): return pow(other,self)
class ScalarMixedOp(GuardedOp): class ScalarMixedOp(GuardedOp):
...@@ -201,4 +231,154 @@ class BinaryScalarOp(PureScalarOp): ...@@ -201,4 +231,154 @@ class BinaryScalarOp(PureScalarOp):
class Add(BinaryScalarOp):
identity = 0
def impl(self, x, y):
return x + y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s + %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz, gz
class Sub(BinaryScalarOp):
def impl(self, x, y):
return x - y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s - %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz, neg(gz)
class Mul(BinaryScalarOp):
def impl(self, x, y):
return x * y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s * %(y)s;" % locals()
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_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s / %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return div(gz, y), neg(div(mul(x, gz), mul(y, y)))
class Pow(BinaryScalarOp):
def impl(self, x, y):
return x ** y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = pow(%(x)s, %(y)s);" % locals()
def grad(self, (x, y), (gz, )):
return mul(gz, mul(y, pow(x, sub(y, as_scalar(1))))), mul(gz, mul(log(x), pow(x, y)))
class First(BinaryScalarOp):
def impl(self, x, y):
return x
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz, None
class Second(BinaryScalarOp):
def impl(self, x, y):
return y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return None, gz
class Identity(UnaryScalarOp):
def impl(self, x):
return x
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = %(x)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz,
class Neg(UnaryScalarOp):
def impl(self, x):
return -x
def grad(self, (x, ), (gz, )):
return neg(gz),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = -%(x)s;" % locals()
class Abs(UnaryScalarOp):
def impl(self, x):
return numpy.abs(x)
def grad(self, (x, ), (gz, )):
return mul(gz, sgn(x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = abs(%(x)s);" % locals()
class Sgn(UnaryScalarOp):
def impl(self, x):
return numpy.abs(x) / x
def grad(self, (x, ), (gz, )):
return None,
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = %(x)s/abs(%(x)s);" % locals() # TODO: C use copysign
class Inv(UnaryScalarOp):
def impl(self, x):
return 1 / x
def grad(self, (x, ), (gz, )):
return div(neg(gz), mul(x, x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = 1 / %(x)s;" % locals()
class Log(UnaryScalarOp):
def impl(self, x):
return math.log(x)
def grad(self, (x, ), (gz, )):
return div(gz, x),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = log(%(x)s);" % locals()
class Log2(UnaryScalarOp):
def impl(self, x):
return numpy.log2(x)
def grad(self, (x, ), (gz, )):
return div(gz, mul(x, as_scalar(math.log(2.0)))),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = log2(%(x)s);" % locals()
class Exp(UnaryScalarOp):
def impl(self, x):
return math.exp(x)
def grad(self, (x, ), (gz, )):
return mul(gz, exp(x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = exp(%(x)s);" % locals()
class Sqr(UnaryScalarOp):
def impl(self, x):
return x*x
def grad(self, (x, ), (gz, )):
return mul(gz, mul(x, as_scalar(2))),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = %(x)s * %(x)s;" % locals()
class Sqrt(UnaryScalarOp):
def impl(self, x):
return math.sqrt(x)
def grad(self, (x, ), (gz, )):
return div(mul(gz, as_scalar(0.5)), sqrt(x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = sqrt(%(x)s);" % locals()
#NOTE WELL!!!
# The following adds functions to this module automatically.
# For every scalar op class, a lower-case symbol is added which is a constructor
# for that class.
from gof import modes
modes.make_constructors(globals())
from scalar import *
import math
class Add(BinaryScalarOp):
identity = 0
def impl(self, x, y):
return x + y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s + %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz, gz
class Sub(BinaryScalarOp):
def impl(self, x, y):
return x - y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s - %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz, neg(gz)
class Mul(BinaryScalarOp):
def impl(self, x, y):
return x * y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s * %(y)s;" % locals()
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_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s / %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return div(gz, y), neg(div(mul(x, gz), mul(y, y)))
class Pow(BinaryScalarOp):
def impl(self, x, y):
return x ** y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = pow(%(x)s, %(y)s);" % locals()
def grad(self, (x, y), (gz, )):
return mul(gz, mul(y, pow(x, sub(y, as_scalar(1))))), mul(gz, mul(log(x), pow(x, y)))
class First(BinaryScalarOp):
def impl(self, x, y):
return x
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(x)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz, None
class Second(BinaryScalarOp):
def impl(self, x, y):
return y
def c_code(self, (x, y), (z, ), sub):
return "%(z)s = %(y)s;" % locals()
def grad(self, (x, y), (gz, )):
return None, gz
class Identity(UnaryScalarOp):
def impl(self, x):
return x
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = %(x)s;" % locals()
def grad(self, (x, y), (gz, )):
return gz,
class Neg(UnaryScalarOp):
def impl(self, x):
return -x
def grad(self, (x, ), (gz, )):
return neg(gz),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = -%(x)s;" % locals()
class Abs(UnaryScalarOp):
def impl(self, x):
return numpy.abs(x)
def grad(self, (x, ), (gz, )):
return mul(gz, sgn(x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = abs(%(x)s);" % locals()
class Sgn(UnaryScalarOp):
def impl(self, x):
return numpy.abs(x) / x
def grad(self, (x, ), (gz, )):
return None,
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = %(x)s/abs(%(x)s);" % locals() # TODO: C use copysign
class Inv(UnaryScalarOp):
def impl(self, x):
return 1 / x
def grad(self, (x, ), (gz, )):
return div(neg(gz), mul(x, x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = 1 / %(x)s;" % locals()
class Log(UnaryScalarOp):
def impl(self, x):
return math.log(x)
def grad(self, (x, ), (gz, )):
return div(gz, x),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = log(%(x)s);" % locals()
class Log2(UnaryScalarOp):
def impl(self, x):
return numpy.log2(x)
def grad(self, (x, ), (gz, )):
return div(gz, mul(x, as_scalar(math.log(2.0)))),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = log2(%(x)s);" % locals()
class Exp(UnaryScalarOp):
def impl(self, x):
return math.exp(x)
def grad(self, (x, ), (gz, )):
return mul(gz, exp(x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = exp(%(x)s);" % locals()
class Sqr(UnaryScalarOp):
def impl(self, x):
return x*x
def grad(self, (x, ), (gz, )):
return mul(gz, mul(x, as_scalar(2))),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = %(x)s * %(x)s;" % locals()
class Sqrt(UnaryScalarOp):
def impl(self, x):
return math.sqrt(x)
def grad(self, (x, ), (gz, )):
return div(mul(gz, as_scalar(0.5)), sqrt(x)),
def c_code(self, (x, ), (z, ), sub):
return "%(z)s = sqrt(%(x)s);" % locals()
# class Sigmoid(UnaryComposite):
# def expand_impl(self, x):
# return 1.0 / (1.0 + exp(-x))
from gof import modes
modes.make_constructors(globals())
...@@ -12,7 +12,7 @@ from base_tensor import BaseTensor, BaseTensorOp ...@@ -12,7 +12,7 @@ from base_tensor import BaseTensor, BaseTensorOp
import blas # for gemm, dot import blas # for gemm, dot
import elemwise2 as s2t import elemwise2 as s2t
import scalar_ops as scal import scalar as scal
class Tensor(BaseTensor): class Tensor(BaseTensor):
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论