提交 6a0852fd authored 作者: Olivier Breuleux's avatar Olivier Breuleux

ported dot, gemm

上级 2fd6ea22
...@@ -52,7 +52,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_ ...@@ -52,7 +52,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
raise type, value, traceback raise type, value, traceback
try: try:
f = Function(node.inputs, node.outputs, f = Function(inputrs, node.outputs,
linker_cls = lambda env: gof.DualLinker(env, checker = _numpy_checker), linker_cls = lambda env: gof.DualLinker(env, checker = _numpy_checker),
unpack_single = False, unpack_single = False,
optimizer = None) optimizer = None)
...@@ -111,7 +111,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_ ...@@ -111,7 +111,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
raise type, value, traceback raise type, value, traceback
try: try:
f = Function(node.inputs, node.outputs, f = Function(inputrs, node.outputs,
linker_cls = lambda env: gof.DualLinker(env, checker = _numpy_checker), linker_cls = lambda env: gof.DualLinker(env, checker = _numpy_checker),
unpack_single = False, unpack_single = False,
optimizer = None) optimizer = None)
...@@ -175,6 +175,7 @@ def make_broadcast_tester(op, expected, checks = {}, **kwargs): ...@@ -175,6 +175,7 @@ def make_broadcast_tester(op, expected, checks = {}, **kwargs):
_good_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)), _good_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)),
not_same_dimensions = (rand(2, 2), rand(2)),
scalar = (rand(2, 3), rand(1, 1)), scalar = (rand(2, 3), rand(1, 1)),
row = (rand(2, 3), rand(1, 3)), row = (rand(2, 3), rand(1, 3)),
column = (rand(2, 3), rand(2, 1)), column = (rand(2, 3), rand(2, 1)),
...@@ -182,7 +183,7 @@ _good_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)), ...@@ -182,7 +183,7 @@ _good_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)),
dtype_mixup_1 = (rand(2, 3), randint(2, 3)), dtype_mixup_1 = (rand(2, 3), randint(2, 3)),
dtype_mixup_2 = (randint(2, 3), rand(2, 3))) dtype_mixup_2 = (randint(2, 3), rand(2, 3)))
_bad_build_broadcast_binary_normal = dict(not_same_dimensions = (rand(2), rand(2, 2))) _bad_build_broadcast_binary_normal = dict()#not_same_dimensions = (rand(2), rand(2, 2)))
_bad_runtime_broadcast_binary_normal = dict(bad_shapes = (rand(2, 3), rand(3, 2)), _bad_runtime_broadcast_binary_normal = dict(bad_shapes = (rand(2, 3), rand(3, 2)),
bad_row = (rand(2, 3), rand(1, 2))) bad_row = (rand(2, 3), rand(1, 2)))
...@@ -193,280 +194,280 @@ _grad_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)), ...@@ -193,280 +194,280 @@ _grad_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)),
column = (rand(2, 3), rand(2, 1))) column = (rand(2, 3), rand(2, 1)))
AddTester = make_broadcast_tester(op = add, # AddTester = make_broadcast_tester(op = add,
expected = lambda *inputs: reduce(lambda x, y: x + y, inputs), # expected = lambda *inputs: reduce(lambda x, y: x + y, inputs),
good = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)), # good = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)),
four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)), # four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)),
**_good_broadcast_binary_normal), # **_good_broadcast_binary_normal),
bad_build = _bad_build_broadcast_binary_normal, # bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal) # bad_runtime = _bad_runtime_broadcast_binary_normal)
AddInplaceTester = make_broadcast_tester(op = add_inplace, # AddInplaceTester = make_broadcast_tester(op = add_inplace,
expected = lambda x, y: x + y, # expected = lambda x, y: x + y,
good = _good_broadcast_binary_normal, # good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal, # bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal, # bad_runtime = _bad_runtime_broadcast_binary_normal,
inplace = True) # inplace = True)
SubTester = make_broadcast_tester(op = sub, # SubTester = make_broadcast_tester(op = sub,
expected = lambda x, y: x - y, # expected = lambda x, y: x - y,
good = _good_broadcast_binary_normal, # good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal, # bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal, # bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal) # grad = _grad_broadcast_binary_normal)
SubInplaceTester = make_broadcast_tester(op = sub_inplace, # SubInplaceTester = make_broadcast_tester(op = sub_inplace,
expected = lambda x, y: x - y, # expected = lambda x, y: x - y,
good = _good_broadcast_binary_normal, # good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal, # bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal, # bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal, # grad = _grad_broadcast_binary_normal,
inplace = True) # inplace = True)
MulTester = make_broadcast_tester(op = mul, # MulTester = make_broadcast_tester(op = mul,
expected = lambda *inputs: reduce(lambda x, y: x * y, inputs), # expected = lambda *inputs: reduce(lambda x, y: x * y, inputs),
good = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)), # good = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)),
four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)), # four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)),
**_good_broadcast_binary_normal), # **_good_broadcast_binary_normal),
bad_build = _bad_build_broadcast_binary_normal, # bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal, # bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)), # grad = dict(three_inputs_same_shapes = (rand(2, 3), rand(2, 3), rand(2, 3)),
four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)), # four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)),
**_grad_broadcast_binary_normal)) # **_grad_broadcast_binary_normal))
MulInplaceTester = make_broadcast_tester(op = mul_inplace, # MulInplaceTester = make_broadcast_tester(op = mul_inplace,
expected = lambda x, y: x * y, # expected = lambda x, y: x * y,
good = _good_broadcast_binary_normal, # good = _good_broadcast_binary_normal,
bad_build = _bad_build_broadcast_binary_normal, # bad_build = _bad_build_broadcast_binary_normal,
bad_runtime = _bad_runtime_broadcast_binary_normal, # bad_runtime = _bad_runtime_broadcast_binary_normal,
grad = _grad_broadcast_binary_normal, # grad = _grad_broadcast_binary_normal,
inplace = True) # inplace = True)
DivTester = make_broadcast_tester(op = div, # DivTester = make_broadcast_tester(op = div,
expected = lambda x, y: x / y, # expected = lambda x, y: x / y,
good = dict(same_shapes = (rand(2, 3), rand(2, 3)), # good = dict(same_shapes = (rand(2, 3), rand(2, 3)),
scalar = (rand(2, 3), rand(1, 1)), # scalar = (rand(2, 3), rand(1, 1)),
row = (rand(2, 3), rand(1, 3)), # row = (rand(2, 3), rand(1, 3)),
column = (rand(2, 3), rand(2, 1)), # column = (rand(2, 3), rand(2, 1)),
dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)),
dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3)),
# integers_positive = (randint_ranged(4, 10, (2, 3)), randint_ranged(1, 6, (2, 3))),
# integers_known_to_fail = (numpy.array(-1), numpy.array(5))
),
# integers = (randint(2, 3), randint_nonzero(2, 3)),
# dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)), # dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)),
# dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3))), # dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3)),
grad = dict(same_shapes = (rand(2, 3), rand(2, 3)), # # integers_positive = (randint_ranged(4, 10, (2, 3)), randint_ranged(1, 6, (2, 3))),
scalar = (rand(2, 3), rand(1, 1)), # # integers_known_to_fail = (numpy.array(-1), numpy.array(5))
row = (rand(2, 3), rand(1, 3)), # ),
column = (rand(2, 3), rand(2, 1)))) # # integers = (randint(2, 3), randint_nonzero(2, 3)),
DivInplaceTester = make_broadcast_tester(op = div_inplace, # # dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)),
expected = lambda x, y: x / y, # # dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3))),
good = dict(same_shapes = (rand(2, 3), rand(2, 3)), # grad = dict(same_shapes = (rand(2, 3), rand(2, 3)),
scalar = (rand(2, 3), rand(1, 1)), # scalar = (rand(2, 3), rand(1, 1)),
row = (rand(2, 3), rand(1, 3)), # row = (rand(2, 3), rand(1, 3)),
column = (rand(2, 3), rand(2, 1)), # column = (rand(2, 3), rand(2, 1))))
dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)), # DivInplaceTester = make_broadcast_tester(op = div_inplace,
dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3)) # expected = lambda x, y: x / y,
), # good = dict(same_shapes = (rand(2, 3), rand(2, 3)),
grad = dict(same_shapes = (rand(2, 3), rand(2, 3)), # scalar = (rand(2, 3), rand(1, 1)),
scalar = (rand(2, 3), rand(1, 1)), # row = (rand(2, 3), rand(1, 3)),
row = (rand(2, 3), rand(1, 3)), # column = (rand(2, 3), rand(2, 1)),
column = (rand(2, 3), rand(2, 1))), # dtype_mixup_1 = (rand(2, 3), randint_nonzero(2, 3)),
inplace = True) # dtype_mixup_2 = (randint_nonzero(2, 3), rand(2, 3))
# ),
PowTester = make_broadcast_tester(op = pow, # grad = dict(same_shapes = (rand(2, 3), rand(2, 3)),
expected = lambda x, y: x ** y, # scalar = (rand(2, 3), rand(1, 1)),
good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))), # row = (rand(2, 3), rand(1, 3)),
scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))), # column = (rand(2, 3), rand(2, 1))),
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), # inplace = True)
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))),
dtype_mixup = (rand_ranged(-3, 3, (2, 3)), randint_ranged(-3, 3, (2, 3)))), # PowTester = make_broadcast_tester(op = pow,
grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))), # expected = lambda x, y: x ** y,
scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))), # good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), # scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1)))) # row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
) # column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))),
PowInplaceTester = make_broadcast_tester(op = pow_inplace, # dtype_mixup = (rand_ranged(-3, 3, (2, 3)), randint_ranged(-3, 3, (2, 3)))),
expected = lambda x, y: x ** y, # grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))), # scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))), # row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), # column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))))
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))), # )
dtype_mixup = (rand_ranged(-3, 3, (2, 3)), randint_ranged(-3, 3, (2, 3)))), # PowInplaceTester = make_broadcast_tester(op = pow_inplace,
grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))), # expected = lambda x, y: x ** y,
scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))), # good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))), # scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1)))), # row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
inplace = True) # column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))),
# dtype_mixup = (rand_ranged(-3, 3, (2, 3)), randint_ranged(-3, 3, (2, 3)))),
# grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
# scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
_good_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),), # row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
integers = (randint_ranged(-5, 5, (2, 3)),)) # column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1)))),
# inplace = True)
_grad_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),))
AbsTester = make_broadcast_tester(op = tensor._abs, # _good_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),),
expected = lambda x: abs(x), # integers = (randint_ranged(-5, 5, (2, 3)),))
good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal) # _grad_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),))
AbsInplaceTester = make_broadcast_tester(op = abs_inplace,
expected = lambda x: abs(x),
good = _good_broadcast_unary_normal, # AbsTester = make_broadcast_tester(op = tensor._abs,
grad = _grad_broadcast_unary_normal, # expected = lambda x: abs(x),
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
NegTester = make_broadcast_tester(op = neg, # AbsInplaceTester = make_broadcast_tester(op = abs_inplace,
expected = lambda x: -x, # expected = lambda x: abs(x),
good = _good_broadcast_unary_normal, # good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal) # grad = _grad_broadcast_unary_normal,
NegInplaceTester = make_broadcast_tester(op = neg_inplace, # inplace = True)
expected = lambda x: -x,
good = _good_broadcast_unary_normal, # NegTester = make_broadcast_tester(op = neg,
grad = _grad_broadcast_unary_normal, # expected = lambda x: -x,
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
SgnTester = make_broadcast_tester(op = sgn, # NegInplaceTester = make_broadcast_tester(op = neg_inplace,
expected = numpy.sign, # expected = lambda x: -x,
good = _good_broadcast_unary_normal) # good = _good_broadcast_unary_normal,
SgnInplaceTester = make_broadcast_tester(op = sgn_inplace, # grad = _grad_broadcast_unary_normal,
expected = numpy.sign, # inplace = True)
good = _good_broadcast_unary_normal,
inplace = True) # SgnTester = make_broadcast_tester(op = sgn,
# expected = numpy.sign,
SqrTester = make_broadcast_tester(op = sqr, # good = _good_broadcast_unary_normal)
expected = numpy.square, # SgnInplaceTester = make_broadcast_tester(op = sgn_inplace,
good = _good_broadcast_unary_normal, # expected = numpy.sign,
grad = _grad_broadcast_unary_normal) # good = _good_broadcast_unary_normal,
SqrInplaceTester = make_broadcast_tester(op = sqr_inplace, # inplace = True)
expected = numpy.square,
good = _good_broadcast_unary_normal, # SqrTester = make_broadcast_tester(op = sqr,
grad = _grad_broadcast_unary_normal, # expected = numpy.square,
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
ExpTester = make_broadcast_tester(op = exp, # SqrInplaceTester = make_broadcast_tester(op = sqr_inplace,
expected = numpy.exp, # expected = numpy.square,
good = _good_broadcast_unary_normal, # good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal) # grad = _grad_broadcast_unary_normal,
ExpInplaceTester = make_broadcast_tester(op = exp_inplace, # inplace = True)
expected = numpy.exp,
good = _good_broadcast_unary_normal, # ExpTester = make_broadcast_tester(op = exp,
grad = _grad_broadcast_unary_normal, # expected = numpy.exp,
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# ExpInplaceTester = make_broadcast_tester(op = exp_inplace,
_good_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),), # expected = numpy.exp,
integers = (randint_ranged(1, 5, (2, 3)),)) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
_grad_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),)) # inplace = True)
LogTester = make_broadcast_tester(op = log,
expected = numpy.log, # _good_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),),
good = _good_broadcast_unary_positive, # integers = (randint_ranged(1, 5, (2, 3)),))
grad = _grad_broadcast_unary_positive)
LogInplaceTester = make_broadcast_tester(op = log_inplace, # _grad_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),))
expected = numpy.log,
good = _good_broadcast_unary_positive, # LogTester = make_broadcast_tester(op = log,
grad = _grad_broadcast_unary_positive, # expected = numpy.log,
inplace = True) # good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive)
Log2Tester = make_broadcast_tester(op = log2, # LogInplaceTester = make_broadcast_tester(op = log_inplace,
expected = numpy.log2, # expected = numpy.log,
good = _good_broadcast_unary_positive, # good = _good_broadcast_unary_positive,
grad = _grad_broadcast_unary_positive) # grad = _grad_broadcast_unary_positive,
Log2InplaceTester = make_broadcast_tester(op = log2_inplace, # inplace = True)
expected = numpy.log2,
good = _good_broadcast_unary_positive, # Log2Tester = make_broadcast_tester(op = log2,
grad = _grad_broadcast_unary_positive, # expected = numpy.log2,
inplace = True) # good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive)
SqrtTester = make_broadcast_tester(op = sqrt, # Log2InplaceTester = make_broadcast_tester(op = log2_inplace,
expected = numpy.sqrt, # expected = numpy.log2,
good = _good_broadcast_unary_positive, # good = _good_broadcast_unary_positive,
grad = _grad_broadcast_unary_positive) # grad = _grad_broadcast_unary_positive,
SqrtInplaceTester = make_broadcast_tester(op = sqrt_inplace, # inplace = True)
expected = numpy.sqrt,
good = _good_broadcast_unary_positive, # SqrtTester = make_broadcast_tester(op = sqrt,
grad = _grad_broadcast_unary_positive, # expected = numpy.sqrt,
inplace = True) # good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive)
# SqrtInplaceTester = make_broadcast_tester(op = sqrt_inplace,
# expected = numpy.sqrt,
_good_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),), # good = _good_broadcast_unary_positive,
integers = (randint_ranged(-1000, 1000, (2, 3)),)) # grad = _grad_broadcast_unary_positive,
# inplace = True)
_grad_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),))
SinTester = make_broadcast_tester(op = sin, # _good_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),),
expected = numpy.sin, # integers = (randint_ranged(-1000, 1000, (2, 3)),))
good = _good_broadcast_unary_wide,
grad = _grad_broadcast_unary_wide) # _grad_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),))
SinInplaceTester = make_broadcast_tester(op = sin_inplace,
expected = numpy.sin,
good = _good_broadcast_unary_wide, # SinTester = make_broadcast_tester(op = sin,
grad = _grad_broadcast_unary_wide, # expected = numpy.sin,
inplace = True) # good = _good_broadcast_unary_wide,
# grad = _grad_broadcast_unary_wide)
CosTester = make_broadcast_tester(op = cos, # SinInplaceTester = make_broadcast_tester(op = sin_inplace,
expected = numpy.cos, # expected = numpy.sin,
good = _good_broadcast_unary_wide, # good = _good_broadcast_unary_wide,
grad = _grad_broadcast_unary_wide) # grad = _grad_broadcast_unary_wide,
CosInplaceTester = make_broadcast_tester(op = cos_inplace, # inplace = True)
expected = numpy.cos,
good = _good_broadcast_unary_wide, # CosTester = make_broadcast_tester(op = cos,
grad = _grad_broadcast_unary_wide, # expected = numpy.cos,
inplace = True) # good = _good_broadcast_unary_wide,
# grad = _grad_broadcast_unary_wide)
TanTester = make_broadcast_tester(op = tan, # CosInplaceTester = make_broadcast_tester(op = cos_inplace,
expected = numpy.tan, # expected = numpy.cos,
good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),), # good = _good_broadcast_unary_wide,
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)), # grad = _grad_broadcast_unary_wide,
grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),), # inplace = True)
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)))
TanInplaceTester = make_broadcast_tester(op = tan_inplace, # TanTester = make_broadcast_tester(op = tan,
expected = numpy.tan, # expected = numpy.tan,
good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),), # good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)), # shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),), # grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
shifted = (rand_ranged(3.15, 6.28, (2, 3)),)), # shifted = (rand_ranged(3.15, 6.28, (2, 3)),)))
inplace = True) # TanInplaceTester = make_broadcast_tester(op = tan_inplace,
# expected = numpy.tan,
# good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
CoshTester = make_broadcast_tester(op = cosh, # shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
expected = numpy.cosh, # grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
good = _good_broadcast_unary_normal, # shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
grad = _grad_broadcast_unary_normal) # inplace = True)
CoshInplaceTester = make_broadcast_tester(op = cosh_inplace,
expected = numpy.cosh,
good = _good_broadcast_unary_normal, # CoshTester = make_broadcast_tester(op = cosh,
grad = _grad_broadcast_unary_normal, # expected = numpy.cosh,
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
SinhTester = make_broadcast_tester(op = sinh, # CoshInplaceTester = make_broadcast_tester(op = cosh_inplace,
expected = numpy.sinh, # expected = numpy.cosh,
good = _good_broadcast_unary_normal, # good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal) # grad = _grad_broadcast_unary_normal,
SinhInplaceTester = make_broadcast_tester(op = sinh_inplace, # inplace = True)
expected = numpy.sinh,
good = _good_broadcast_unary_normal, # SinhTester = make_broadcast_tester(op = sinh,
grad = _grad_broadcast_unary_normal, # expected = numpy.sinh,
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
TanhTester = make_broadcast_tester(op = tanh, # SinhInplaceTester = make_broadcast_tester(op = sinh_inplace,
expected = numpy.tanh, # expected = numpy.sinh,
good = _good_broadcast_unary_normal, # good = _good_broadcast_unary_normal,
grad = _grad_broadcast_unary_normal) # grad = _grad_broadcast_unary_normal,
TanhInplaceTester = make_broadcast_tester(op = tanh_inplace, # inplace = True)
expected = numpy.tanh,
good = _good_broadcast_unary_normal, # TanhTester = make_broadcast_tester(op = tanh,
grad = _grad_broadcast_unary_normal, # expected = numpy.tanh,
inplace = True) # good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# TanhInplaceTester = make_broadcast_tester(op = tanh_inplace,
# expected = numpy.tanh,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# DotTester = make_tester(name = 'DotTester', # DotTester = make_tester(name = 'DotTester',
# op = Dot, # op = dot,
# expected = lambda x, y: numpy.dot(x, y), # expected = lambda x, y: numpy.dot(x, y),
# checks = {}, # checks = {},
# good = dict(correct1 = (rand(5, 7), rand(7, 5)), # good = dict(correct1 = (rand(5, 7), rand(7, 5)),
...@@ -537,147 +538,147 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to ...@@ -537,147 +538,147 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to
verify_grad.E_grad = 'gradient error exceeded tolerance' verify_grad.E_grad = 'gradient error exceeded tolerance'
# #useful mostly for unit tests #useful mostly for unit tests
# def _approx_eq(a,b,eps=1.0e-9): def _approx_eq(a,b,eps=1.0e-9):
# a = numpy.asarray(a) a = numpy.asarray(a)
# b = numpy.asarray(b) b = numpy.asarray(b)
# if a.shape != b.shape: if a.shape != b.shape:
# if _approx_eq.debug: if _approx_eq.debug:
# print a.shape, b.shape print a.shape, b.shape
# return False return False
# if numpy.max(numpy.abs(a-b)) >= eps: if numpy.max(numpy.abs(a-b)) >= eps:
# if _approx_eq.debug: if _approx_eq.debug:
# print a, b print a, b
# return False return False
# return True return True
# _approx_eq.debug = 0 _approx_eq.debug = 0
# def check_eq(self, node_in, node_out, arg_in, arg_out): def check_eq(self, node_in, node_out, arg_in, arg_out):
# fn = Function([node_in], [node_out]) fn = Function([node_in], [node_out])
# self.failUnless( numpy.all(fn(arg_in) == arg_out), (arg_in, arg_out)) self.failUnless( numpy.all(fn(arg_in) == arg_out), (arg_in, arg_out))
# def check_eq2(self, inputs, output, args_in, arg_out): def check_eq2(self, inputs, output, args_in, arg_out):
# fn = Function(inputs, [output]) fn = Function(inputs, [output])
# val = fn(*args_in) val = fn(*args_in)
# self.failUnless( numpy.all(val == arg_out), (val, arg_out)) self.failUnless( numpy.all(val == arg_out), (val, arg_out))
# def check_eq2_c(self, inputs, output, args_in, arg_out): def check_eq2_c(self, inputs, output, args_in, arg_out):
# fn = Function(inputs, [output], linker_cls = gof.CLinker) fn = Function(inputs, [output], linker_cls = gof.CLinker)
# val = fn(*args_in) val = fn(*args_in)
# self.failUnless( numpy.all(val == arg_out), (val, arg_out)) self.failUnless( numpy.all(val == arg_out), (val, arg_out))
# def check_eq2_both(self, inputs, output, args_in, arg_out): def check_eq2_both(self, inputs, output, args_in, arg_out):
# fn = Function(inputs, [output], linker_cls = lambda env: gof.DualLinker(env, _numpy_checker)) fn = Function(inputs, [output], linker_cls = lambda env: gof.DualLinker(env, _numpy_checker))
# val = fn(*args_in) val = fn(*args_in)
# self.failUnless( numpy.all(val == arg_out), (val, arg_out)) self.failUnless( numpy.all(val == arg_out), (val, arg_out))
# class T_argmax(unittest.TestCase): class T_argmax(unittest.TestCase):
# def setUp(self): def setUp(self):
# numpy.random.seed(123784) numpy.random.seed(123784)
# Argmax.debug = 0 Argmax.debug = 0
# def test0(self): def test0(self):
# n = astensor(5.0) n = as_tensor(5.0)
# v,i = eval_outputs(argmax(n)) v,i = eval_outputs(argmax(n))
# self.failUnless(v == 5.0) self.failUnless(v == 5.0)
# self.failUnless(i == 0) self.failUnless(i == 0)
# def test1(self): def test1(self):
# n = astensor([1,2,3,2,-6]) n = as_tensor([1,2,3,2,-6])
# v,i = eval_outputs(argmax(n)) v,i = eval_outputs(argmax(n))
# self.failUnless(v == 3) self.failUnless(v == 3)
# self.failUnless(i == 2) self.failUnless(i == 2)
# def test2(self): def test2(self):
# n = astensor(numpy.random.rand(2,3)) n = as_tensor(numpy.random.rand(2,3))
# v,i = eval_outputs(argmax(n)) v,i = eval_outputs(argmax(n))
# self.failUnless(numpy.all(i == [0,1])) self.failUnless(numpy.all(i == [0,1]))
# def test2b(self): def test2b(self):
# n = astensor(numpy.random.rand(2,3)) n = as_tensor(numpy.random.rand(2,3))
# v,i = eval_outputs(argmax(n,axis=0)) v,i = eval_outputs(argmax(n,0))
# self.failUnless(numpy.all(i == [0,1,1])) self.failUnless(numpy.all(i == [0,1,1]))
# def test2_invalid(self): def test2_invalid(self):
# n = astensor(numpy.random.rand(2,3)) n = as_tensor(numpy.random.rand(2,3))
# try: try:
# eval_outputs(argmax(n,axis=3)) eval_outputs(argmax(n,3))
# except ValueError, e: except ValueError, e:
# return return
# self.fail() self.fail()
# def test2_invalid_neg(self): def test2_invalid_neg(self):
# n = astensor(numpy.random.rand(2,3)) n = as_tensor(numpy.random.rand(2,3))
# try: try:
# eval_outputs(argmax(n,axis=-3)) eval_outputs(argmax(n,-3))
# except ValueError, e: except ValueError, e:
# return return
# self.fail() self.fail()
# def test2_valid_neg(self): def test2_valid_neg(self):
# n = astensor(numpy.random.rand(2,3)) n = as_tensor(numpy.random.rand(2,3))
# v,i = eval_outputs(argmax(n,axis=-1)) v,i = eval_outputs(argmax(n,-1))
# self.failUnless(v.shape == (2,)) self.failUnless(v.shape == (2,))
# v,i = eval_outputs(argmax(n,axis=-2)) v,i = eval_outputs(argmax(n,-2))
# self.failUnless(v.shape == (3,)) self.failUnless(v.shape == (3,))
# def test3(self): def test3(self):
# n = astensor(numpy.random.rand(2,3,4)) n = as_tensor(numpy.random.rand(2,3,4))
# v,i = eval_outputs(argmax(n,axis=0)) v,i = eval_outputs(argmax(n,0))
# self.failUnless(v.shape == (3,4)) self.failUnless(v.shape == (3,4))
# self.failUnless(i.shape == (3,4)) self.failUnless(i.shape == (3,4))
# v,i = eval_outputs(argmax(n,axis=1)) v,i = eval_outputs(argmax(n,1))
# self.failUnless(v.shape == (2,4)) self.failUnless(v.shape == (2,4))
# self.failUnless(i.shape == (2,4)) self.failUnless(i.shape == (2,4))
# v,i = eval_outputs(argmax(n,axis=2)) v,i = eval_outputs(argmax(n,2))
# self.failUnless(v.shape == (2,3)) self.failUnless(v.shape == (2,3))
# self.failUnless(i.shape == (2,3)) self.failUnless(i.shape == (2,3))
# class T_transpose(unittest.TestCase): class T_transpose(unittest.TestCase):
# def test0(self): def test0(self):
# n = astensor(numpy.ones(())) n = as_tensor(numpy.ones(()))
# t = transpose(n) t = transpose(n)
# self.failUnless(t.owner.__class__ is TransposeInplace) self.failUnless(t.owner.op == transpose_inplace)
# f = Function([n], [t]) f = Function([n], [t])
# tval = f(n.data) tval = f(n.data)
# self.failUnless(tval.shape == n.data.shape) self.failUnless(tval.shape == n.data.shape)
# #test aliasing #test aliasing
# tval += 55.0 tval += 55.0
# self.failUnless(n.data == 1.0) self.failUnless(n.data == 1.0)
# def test1(self): def test1(self):
# n = astensor(numpy.ones(5)) n = as_tensor(numpy.ones(5))
# t = transpose(n) t = transpose(n)
# self.failUnless(t.owner.__class__ is TransposeInplace) self.failUnless(t.owner.op == transpose_inplace)
# f = Function([n], [t]) f = Function([n], [t])
# tval = f(n.data) tval = f(n.data)
# self.failUnless(tval.shape == n.data.shape) self.failUnless(tval.shape == n.data.shape)
# #test aliasing #test aliasing
# tval += 55.0 tval += 55.0
# self.failUnless(n.data[0] == 1.0) self.failUnless(n.data[0] == 1.0)
# def test2(self): def test2(self):
# n = astensor(numpy.ones((5,3))) n = as_tensor(numpy.ones((5,3)))
# t = transpose(n) t = transpose(n)
# self.failUnless(t.owner.__class__ is TransposeInplace) self.failUnless(t.owner.op == transpose_inplace)
# f = Function([n], [t]) f = Function([n], [t])
# tval = f(n.data) tval = f(n.data)
# self.failUnless(tval.shape == (3,5)) self.failUnless(tval.shape == (3,5))
# #test aliasing #test aliasing
# tval += 55.0 tval += 55.0
# self.failUnless(n.data[0,0] == 1.0) self.failUnless(n.data[0,0] == 1.0)
# def test3(self): def test3(self):
# """Test transpose of tensor, inplace version""" """Test transpose of tensor, inplace version"""
# n = astensor(numpy.ones((5,3,2))) n = as_tensor(numpy.ones((5,3,2)))
# t = transpose_inplace(n) t = transpose_inplace(n)
# self.failUnless(t.owner.__class__ is TransposeInplace) self.failUnless(t.owner.op == transpose_inplace)
# f = Function([n], [t]) f = Function([n], [t])
# tval = f(n.data) tval = f(n.data)
# self.failUnless(tval.shape == (2,3,5)) self.failUnless(tval.shape == (2,3,5))
# #test aliasing #test aliasing
# tval += 55.0 tval += 55.0
# self.failUnless(n.data[0,0,0] == 56.0) self.failUnless(n.data[0,0,0] == 56.0)
# def test_grad(self): def test_grad(self):
# verify_grad(self, TransposeInplace, [numpy.random.rand(2, 3)]) verify_grad(self, transpose_inplace, [numpy.random.rand(2, 3)])
# verify_grad(self, TransposeInplace, [numpy.ones(3)]) verify_grad(self, transpose_inplace, [numpy.ones(3)])
# class T_subtensor(unittest.TestCase): # class T_subtensor(unittest.TestCase):
# def test0_err_invalid(self): # def test0_err_invalid(self):
...@@ -1013,276 +1014,275 @@ verify_grad.E_grad = 'gradient error exceeded tolerance' ...@@ -1013,276 +1014,275 @@ verify_grad.E_grad = 'gradient error exceeded tolerance'
# def test_col(self): # def test_col(self):
# verify_grad(self, Pow, [numpy.random.rand(3, 5), numpy.random.rand(3, 1)]) # verify_grad(self, Pow, [numpy.random.rand(3, 5), numpy.random.rand(3, 1)])
# class _testCase_matinv(unittest.TestCase): class _testCase_matinv(unittest.TestCase):
# def setUp(self): def setUp(self):
# numpy.random.seed(1) numpy.random.seed(1)
# def mat_reciprocal(self,dim): def mat_reciprocal(self,dim):
# # symbolic program # symbolic program
# # broadcastable=[False,False] means that the shape of matrix is two dimensional, # broadcastable=[False,False] means that the shape of matrix is two dimensional,
# # and none of the dimensions are constrained to have length 1. # and none of the dimensions are constrained to have length 1.
# # Note that Tensor's constructor does not actually allocate any memory. # Note that Tensor's constructor does not actually allocate any memory.
# # TODO: Make Tensor syntax more explicit, and maybe give shape or number of dimensions. # TODO: Make Tensor syntax more explicit, and maybe give shape or number of dimensions.
# a = Tensor('float64', broadcastable=[False,False], name='a') a, b = matrices('ab')
# b = Tensor('float64', broadcastable=[False,False], name='b') ab = a*b
# ab = a*b # Here, as_tensor actually uses the data allocated by numpy.
# # Here, astensor actually uses the data allocated by numpy. diff = ab - as_tensor(numpy.ones((dim,dim)))
# diff = ab - astensor(numpy.ones((dim,dim))) # Sum of squared errors
# # Sum of squared errors ssdiff = sum((diff**2.0))
# ssdiff = sum((diff**2.0))
g_b = gradient.grad(ssdiff, b)
# g_b = gradient.grad(ssdiff, b)
# compilation to function
# # compilation to function # [a,b] are the inputs, [ssdiff,g_b] are the outputs
# # [a,b] are the inputs, [ssdiff,g_b] are the outputs fn = Function([a,b], [ssdiff,g_b])
# fn = Function([a,b], [ssdiff,g_b])
# use the function
# # use the function x = numpy.random.rand(dim,dim)+0.1 # Initialized s.t. x is not too tiny
# x = numpy.random.rand(dim,dim)+0.1 # Initialized s.t. x is not too tiny w = numpy.random.rand(dim,dim)
# w = numpy.random.rand(dim,dim) for i in xrange(300):
# for i in xrange(300): ssd, gw = fn(x,w)
# ssd, gw = fn(x,w) #print ssd, x*w, x, w
# #print ssd, x*w, x, w if i == 0:
# if i == 0: str0 = str(ssd)
# str0 = str(ssd) w -= 0.4 * gw
# w -= 0.4 * gw
return str0, str(ssd)
# return str0, str(ssd)
def test_reciprocal(self):
# def test_reciprocal(self): """Matrix reciprocal by gradient descent"""
# """Matrix reciprocal by gradient descent""" self.assertEqual(('6.10141615619', '0.00703816291711'), self.mat_reciprocal(3))
# self.assertEqual(('6.10141615619', '0.00703816291711'), self.mat_reciprocal(3))
class t_dot(unittest.TestCase):
# class t_dot(unittest.TestCase): def setUp(self):
# def setUp(self): numpy.random.seed(44)
# numpy.random.seed(44)
@staticmethod
# @staticmethod def rand(*args):
# def rand(*args): return numpy.random.rand(*args)
# return numpy.random.rand(*args)
def cmp_dot(self,x,y):
# def cmp_dot(self,x,y): #x, y are matrices or numbers
# #x, y are matrices or numbers def spec(x):
# def spec(x): x = numpy.asarray(x)
# x = numpy.asarray(x) return type(x), x.dtype, x.shape
# return type(x), x.dtype, x.shape nz = numpy.dot(x,y)
# nz = numpy.dot(x,y) tz = eval_outputs([dot(as_tensor(x), as_tensor(y))])
# tz = eval_outputs([dot(astensor(x), astensor(y))]) self.failUnless(tz.dtype == nz.dtype)
# self.failUnless(tz.dtype == nz.dtype) self.failUnless(tz.shape == nz.shape)
# self.failUnless(tz.shape == nz.shape) self.failUnless(_approx_eq(nz, tz))
# self.failUnless(_approx_eq(nz, tz))
def test_dot_0d_0d(self): self.cmp_dot(1.1, 2.2)
# def test_dot_0d_0d(self): self.cmp_dot(1.1, 2.2) def test_dot_0d_1d(self): self.cmp_dot(1.1, self.rand(5))
# def test_dot_0d_1d(self): self.cmp_dot(1.1, self.rand(5)) def test_dot_0d_2d(self): self.cmp_dot(3.0, self.rand(6,7))
# def test_dot_0d_2d(self): self.cmp_dot(3.0, self.rand(6,7)) def test_dot_0d_3d(self): self.cmp_dot(3.0, self.rand(8,6,7))
# def test_dot_0d_3d(self): self.cmp_dot(3.0, self.rand(8,6,7)) def test_dot_1d_0d(self): self.cmp_dot(self.rand(5), 1.1 )
# def test_dot_1d_0d(self): self.cmp_dot(self.rand(5), 1.1 ) def test_dot_1d_1d(self): self.cmp_dot(self.rand(5), self.rand(5))
# def test_dot_1d_1d(self): self.cmp_dot(self.rand(5), self.rand(5)) def test_dot_1d_2d(self): self.cmp_dot(self.rand(6), self.rand(6,7))
# def test_dot_1d_2d(self): self.cmp_dot(self.rand(6), self.rand(6,7)) def test_dot_1d_3d(self): self.cmp_dot(self.rand(6), self.rand(8,6,7))
# def test_dot_1d_3d(self): self.cmp_dot(self.rand(6), self.rand(8,6,7)) def test_dot_2d_0d(self): self.cmp_dot(self.rand(5,6), 1.0)
# def test_dot_2d_0d(self): self.cmp_dot(self.rand(5,6), 1.0) def test_dot_2d_1d(self): self.cmp_dot(self.rand(5,6), self.rand(6))
# def test_dot_2d_1d(self): self.cmp_dot(self.rand(5,6), self.rand(6)) def test_dot_2d_2d(self): self.cmp_dot(self.rand(5,6), self.rand(6,7))
# def test_dot_2d_2d(self): self.cmp_dot(self.rand(5,6), self.rand(6,7)) def test_dot_2d_3d(self): self.cmp_dot(self.rand(5,6), self.rand(8,6,7))
# def test_dot_2d_3d(self): self.cmp_dot(self.rand(5,6), self.rand(8,6,7)) def test_dot_3d_0d(self): self.cmp_dot(self.rand(4,5,6), 1.0)
# def test_dot_3d_0d(self): self.cmp_dot(self.rand(4,5,6), 1.0) def test_dot_3d_1d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6))
# def test_dot_3d_1d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6)) def test_dot_3d_2d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6,7))
# def test_dot_3d_2d(self): self.cmp_dot(self.rand(4,5,6), self.rand(6,7)) def test_dot_3d_3d(self): self.cmp_dot(self.rand(4,5,6), self.rand(8,6,7))
# def test_dot_3d_3d(self): self.cmp_dot(self.rand(4,5,6), self.rand(8,6,7))
def not_aligned(self, x, y):
# def not_aligned(self, x, y): z = dot(x,y)
# z = dot(x,y) try:
# try: tz = eval_outputs([z])
# tz = eval_outputs([z]) except ValueError, e:
# except ValueError, e: self.failUnless(e[0].split()[1:4] == ['are', 'not', 'aligned'], e)
# self.failUnless(e[0].split()[1:4] == ['are', 'not', 'aligned'], e) return
# return self.fail()
# self.fail()
def test_align_1_1(self): self.not_aligned(self.rand(5), self.rand(6))
# def test_align_1_1(self): self.not_aligned(self.rand(5), self.rand(6)) def test_align_1_2(self): self.not_aligned(self.rand(5), self.rand(6,4))
# def test_align_1_2(self): self.not_aligned(self.rand(5), self.rand(6,4)) def test_align_1_3(self): self.not_aligned(self.rand(5), self.rand(6,4,7))
# def test_align_1_3(self): self.not_aligned(self.rand(5), self.rand(6,4,7)) def test_align_2_1(self): self.not_aligned(self.rand(5,4), self.rand(6))
# def test_align_2_1(self): self.not_aligned(self.rand(5,4), self.rand(6)) def test_align_2_1(self): self.not_aligned(self.rand(5,4), self.rand(6,7))
# def test_align_2_1(self): self.not_aligned(self.rand(5,4), self.rand(6,7)) def test_align_2_3(self): self.not_aligned(self.rand(5,4), self.rand(6,7,8))
# def test_align_2_3(self): self.not_aligned(self.rand(5,4), self.rand(6,7,8)) def test_align_3_1(self): self.not_aligned(self.rand(5,4,3), self.rand(6))
# def test_align_3_1(self): self.not_aligned(self.rand(5,4,3), self.rand(6)) def test_align_3_2(self): self.not_aligned(self.rand(5,4,3), self.rand(6,7))
# def test_align_3_2(self): self.not_aligned(self.rand(5,4,3), self.rand(6,7)) def test_align_3_3(self): self.not_aligned(self.rand(5,4,3), self.rand(6,7,8))
# def test_align_3_3(self): self.not_aligned(self.rand(5,4,3), self.rand(6,7,8))
# def test_grad(self):
# verify_grad(self, Dot, [self.rand(2,3), self.rand(3,2)])
# class t_gemm(unittest.TestCase):
# def setUp(self):
# numpy.random.seed(44)
# _approx_eq.debug = 0
# Gemm.debug = False
# @staticmethod
# def _gemm(z,a,x,y,b):
# assert a.shape == ()
# assert b.shape == ()
# return b * z + a * numpy.dot(x,y)
# @staticmethod
# def rand(*args):
# return numpy.random.rand(*args)
# def cmp(self, z, a, x, y, b):
# def cmp_linker(z, a, x, y, b, l):
# z,a,x,y,b = [numpy.asarray(p) for p in z,a,x,y,b]
# z_orig = z.copy()
# tz,ta,tx,ty,tb = [astensor(p) for p in z,a,x,y,b]
# f = Function([tz,ta,tx,ty,tb], [gemm(tz,ta,tx,ty,tb)], linker_cls=l)
# new_z = f(z,a,x,y,b)
# z_after = self._gemm(z_orig, a, x, y, b)
# self.failUnless(z is new_z)
# #print z_orig, z_after, z, type(z_orig), type(z_after), type(z)
# #_approx_eq.debug = 1
# self.failUnless(_approx_eq(z_after, z))
# if a == 0.0 and b == 1.0:
# return
# else:
# self.failIf(numpy.all(z_orig == z))
# cmp_linker(copy(z), a, x, y, b, gof.cc.OpWiseCLinker) def test_grad(self):
# #cmp_linker(copy(z), a, x, y, b, gof.cc.CLinker) verify_grad(self, dot, [self.rand(2,3), self.rand(3,2)])
# cmp_linker(copy(z), a, x, y, b, gof.link.PerformLinker)
class t_gemm(unittest.TestCase):
def setUp(self):
numpy.random.seed(44)
_approx_eq.debug = 0
Gemm.debug = False
@staticmethod
def _gemm(z,a,x,y,b):
assert a.shape == ()
assert b.shape == ()
return b * z + a * numpy.dot(x,y)
@staticmethod
def rand(*args):
return numpy.random.rand(*args)
def cmp(self, z, a, x, y, b):
def cmp_linker(z, a, x, y, b, l):
z,a,x,y,b = [numpy.asarray(p) for p in z,a,x,y,b]
z_orig = z.copy()
tz,ta,tx,ty,tb = [as_tensor(p).type() for p in z,a,x,y,b]
f = Function([tz,ta,tx,ty,tb], [gemm(tz,ta,tx,ty,tb)], linker_cls=l)
new_z = f(z,a,x,y,b)
z_after = self._gemm(z_orig, a, x, y, b)
self.failUnless(z is new_z)
#print z_orig, z_after, z, type(z_orig), type(z_after), type(z)
#_approx_eq.debug = 1
self.failUnless(_approx_eq(z_after, z))
if a == 0.0 and b == 1.0:
return
else:
self.failIf(numpy.all(z_orig == z))
# def test0a(self): #cmp_linker(copy(z), a, x, y, b, gof.cc.OpWiseCLinker)
# Gemm.debug = True #cmp_linker(copy(z), a, x, y, b, gof.cc.CLinker)
# try: cmp_linker(copy(z), a, x, y, b, gof.link.PerformLinker)
# g = gemm([1.], 1., [1.], [1.], 1.)
# except ValueError, e:
# if e[0] is Gemm.E_rank:
# return
# self.fail()
# def test0(self): def test0a(self):
# try: Gemm.debug = True
# self.cmp(1., 0., 1.0, 1.0, 1.0) try:
# except ValueError, e: g = gemm([1.], 1., [1.], [1.], 1.)
# if e[0] is Gemm.E_rank: except ValueError, e:
# return if e[0] is Gemm.E_rank:
# self.fail() return
self.fail()
# def test2(self): def test0(self):
# try: try:
# self.cmp(2., 1.0, [3,2,1.], [[1],[2],[3.]], 1.0) self.cmp(1., 0., 1.0, 1.0, 1.0)
# except ValueError, e: except ValueError, e:
# self.failUnless(e[0] == Gemm.E_rank) if e[0] is Gemm.E_rank:
# return return
# self.fail() self.fail()
# def test4(self):
# self.cmp(self.rand(3,4), 1.0, self.rand(3,5), self.rand(5,4), 0.0)
# def test5(self): self.cmp(self.rand(3,4), 1.0,
# self.rand(3,5), self.rand(5,4), 1.0)
# def test6(self): self.cmp(self.rand(3,4), 1.0,
# self.rand(3,5), self.rand(5,4), -1.0)
# def test7(self): self.cmp(self.rand(3,4), 0.0,
# self.rand(3,5), self.rand(5,4), 0.0)
# def test8(self): self.cmp(self.rand(3,4), 0.0,
# self.rand(3,5), self.rand(5,4), 0.6)
# def test9(self): self.cmp(self.rand(3,4), 0.0,
# self.rand(3,5), self.rand(5,4), -1.0)
# def test10(self):
# _approx_eq.debug = 1
# self.cmp(self.rand(3,4), -1.0, self.rand(3,5), self.rand(5,4), 0.0)
# def test11(self): self.cmp(self.rand(3,4), -1.0,
# self.rand(3,5), self.rand(5,4), 1.0)
# def test12(self): self.cmp(self.rand(3,4), -1.0,
# self.rand(3,5), self.rand(5,4), -1.0)
# def test_destroy_map0(self):
# """test that only first input can be overwritten"""
# Z = astensor(self.rand(2,2))
# try:
# gemm(Z, 1.0, Z, Z, 1.0)
# except ValueError, e:
# if e[0] == Gemm.E_z_uniq:
# return
# self.fail()
# def test_destroy_map1(self):
# """test that only first input can be overwritten"""
# Z = astensor(self.rand(2,2))
# A = astensor(self.rand(2,2))
# try:
# gemm(Z, 1.0, A, transpose_inplace(Z), 1.0)
# except ValueError, e:
# if e[0] == Gemm.E_z_uniq:
# return
# self.fail()
# def test_destroy_map2(self):
# """test that only first input can be overwritten"""
# Z = astensor(self.rand(2,2))
# A = astensor(self.rand(2,2))
# try:
# gemm(Z, 1.0, transpose_inplace(Z), A, 1.0)
# except ValueError, e:
# if e[0] == Gemm.E_z_uniq:
# return
# self.fail()
# def test_destroy_map3(self):
# """test that only first input can be overwritten"""
# Z = astensor(self.rand(2,2))
# A = astensor(self.rand(2,2))
# try:
# gemm(Z, 1.0, Z, A, 1.0)
# except ValueError, e:
# if e[0] == Gemm.E_z_uniq:
# return
# self.fail()
# def test_destroy_map4(self): def test2(self):
# """test that dot args can be aliased""" try:
# Z = astensor(self.rand(2,2)) self.cmp(2., 1.0, [3,2,1.], [[1],[2],[3.]], 1.0)
# A = astensor(self.rand(2,2)) except ValueError, e:
# eval_outputs([gemm(Z, 1.0, A, A, 1.0)]) self.failUnless(e[0] == Gemm.E_rank)
# eval_outputs([gemm(Z, 1.0, A, A.T, 1.0)]) return
self.fail()
def test4(self):
# def test_transposes(self): self.cmp(self.rand(3,4), 1.0, self.rand(3,5), self.rand(5,4), 0.0)
# # three square matrices which are not contiguous def test5(self): self.cmp(self.rand(3,4), 1.0,
# A = self.rand(4,5)[:,:4] self.rand(3,5), self.rand(5,4), 1.0)
# B = self.rand(4,5)[:,:4] def test6(self): self.cmp(self.rand(3,4), 1.0,
# C = self.rand(4,5)[:,:4] self.rand(3,5), self.rand(5,4), -1.0)
def test7(self): self.cmp(self.rand(3,4), 0.0,
# def t(z,x,y,a=1.0, b=0.0,l=gof.cc.OpWiseCLinker,dt='float64'): self.rand(3,5), self.rand(5,4), 0.0)
# z,a,x,y,b = [numpy.asarray(p,dtype=dt) for p in z,a,x,y,b] def test8(self): self.cmp(self.rand(3,4), 0.0,
# z_orig = z.copy() self.rand(3,5), self.rand(5,4), 0.6)
# z_after = self._gemm(z, a, x, y, b) def test9(self): self.cmp(self.rand(3,4), 0.0,
self.rand(3,5), self.rand(5,4), -1.0)
# tz,ta,tx,ty,tb = [astensor(p) for p in z,a,x,y,b] def test10(self):
_approx_eq.debug = 1
# f = Function([tz,ta,tx,ty,tb], [gemm(tz,ta,tx,ty,tb)], linker_cls=l) self.cmp(self.rand(3,4), -1.0, self.rand(3,5), self.rand(5,4), 0.0)
# f(z, a, x, y, b) def test11(self): self.cmp(self.rand(3,4), -1.0,
# self.failUnless(_approx_eq(z_after, z), (z_orig, z_after, z)) self.rand(3,5), self.rand(5,4), 1.0)
# f(z.T, a, y.T, x.T, b) def test12(self): self.cmp(self.rand(3,4), -1.0,
# self.failUnless(_approx_eq(z_after, z)) self.rand(3,5), self.rand(5,4), -1.0)
# t(C,A,B) def test_destroy_map0(self):
# t(C.T, A, B) """test that only first input can be overwritten"""
# t(C, A.T, B, dt='float32') Z = as_tensor(self.rand(2,2))
# t(C, A, B.T) try:
# t(C.T, A.T, B) gemm(Z, 1.0, Z, Z, 1.0)
# t(C, A.T, B.T, dt='float32') except ValueError, e:
# t(C.T, A, B.T) if e[0] == Gemm.E_z_uniq:
# t(C.T, A.T, B.T, dt='float32') return
self.fail()
# t(C, A[:,:2], B[:2, :]) def test_destroy_map1(self):
# t(C.T, A[:,:2], B[:2, :], dt='float32') """test that only first input can be overwritten"""
# t(C, A[:2,:].T, B[:2, :]) Z = as_tensor(self.rand(2,2))
# t(C.T, A[:2,:].T, B[:2, :], dt='float32') A = as_tensor(self.rand(2,2))
# t(C, A[:2,:].T, B[:, :2].T) try:
# t(C.T, A[:2,:].T, B[:, :2].T) gemm(Z, 1.0, A, transpose_inplace(Z), 1.0)
except ValueError, e:
if e[0] == Gemm.E_z_uniq:
return
self.fail()
def test_destroy_map2(self):
"""test that only first input can be overwritten"""
Z = as_tensor(self.rand(2,2))
A = as_tensor(self.rand(2,2))
try:
gemm(Z, 1.0, transpose_inplace(Z), A, 1.0)
except ValueError, e:
if e[0] == Gemm.E_z_uniq:
return
self.fail()
def test_destroy_map3(self):
"""test that only first input can be overwritten"""
Z = as_tensor(self.rand(2,2))
A = as_tensor(self.rand(2,2))
try:
gemm(Z, 1.0, Z, A, 1.0)
except ValueError, e:
if e[0] == Gemm.E_z_uniq:
return
self.fail()
def test_destroy_map4(self):
"""test that dot args can be aliased"""
Z = as_tensor(self.rand(2,2))
A = as_tensor(self.rand(2,2))
eval_outputs([gemm(Z, 1.0, A, A, 1.0)])
eval_outputs([gemm(Z, 1.0, A, A.T, 1.0)])
def test_transposes(self):
# three square matrices which are not contiguous
A = self.rand(4,5)[:,:4]
B = self.rand(4,5)[:,:4]
C = self.rand(4,5)[:,:4]
def t(z,x,y,a=1.0, b=0.0,l=gof.cc.OpWiseCLinker,dt='float64'):
z,a,x,y,b = [numpy.asarray(p,dtype=dt) for p in z,a,x,y,b]
z_orig = z.copy()
z_after = self._gemm(z, a, x, y, b)
tz,ta,tx,ty,tb = [as_tensor(p) for p in z,a,x,y,b]
f = Function([tz,ta,tx,ty,tb], [gemm(tz,ta,tx,ty,tb)], linker_cls=l)
f(z, a, x, y, b)
self.failUnless(_approx_eq(z_after, z), (z_orig, z_after, z))
f(z.T, a, y.T, x.T, b)
self.failUnless(_approx_eq(z_after, z))
t(C,A,B)
t(C.T, A, B)
t(C, A.T, B, dt='float32')
t(C, A, B.T)
t(C.T, A.T, B)
t(C, A.T, B.T, dt='float32')
t(C.T, A, B.T)
t(C.T, A.T, B.T, dt='float32')
t(C, A[:,:2], B[:2, :])
t(C.T, A[:,:2], B[:2, :], dt='float32')
t(C, A[:2,:].T, B[:2, :])
t(C.T, A[:2,:].T, B[:2, :], dt='float32')
t(C, A[:2,:].T, B[:, :2].T)
t(C.T, A[:2,:].T, B[:, :2].T)
# try: try:
# t(C.T, A[:2,:], B[:, :2].T) t(C.T, A[:2,:], B[:, :2].T)
# except ValueError, e: except ValueError, e:
# if e[0].find('aligned') >= 0: if e[0].find('aligned') >= 0:
# return return
# self.fail() self.fail()
......
...@@ -12,12 +12,12 @@ import scalar_opt ...@@ -12,12 +12,12 @@ import scalar_opt
def inputs(xbc = (0, 0), ybc = (0, 0), zbc = (0, 0)): def inputs(xbc = (0, 0), ybc = (0, 0), zbc = (0, 0)):
x = Tensor(broadcastable = xbc, dtype = 'float64', name = 'x') x = Tensor(broadcastable = xbc, dtype = 'float64')('x')
y = Tensor(broadcastable = ybc, dtype = 'float64', name = 'y') y = Tensor(broadcastable = ybc, dtype = 'float64')('y')
z = Tensor(broadcastable = zbc, dtype = 'float64', name = 'z') z = Tensor(broadcastable = zbc, dtype = 'float64')('z')
return x, y, z return x, y, z
ds = gof.op.constructor(DimShuffle) ds = DimShuffle
class _test_inplace_opt(unittest.TestCase): class _test_inplace_opt(unittest.TestCase):
......
...@@ -6,14 +6,6 @@ from copy import copy ...@@ -6,14 +6,6 @@ from copy import copy
from env import InconsistencyError from env import InconsistencyError
__all__ = ['Destroyer',
'Viewer',
'view_roots',
'DestroyHandler',
]
class DestroyHandler(Listener, Constraint, Orderings, Tool): class DestroyHandler(Listener, Constraint, Orderings, Tool):
""" """
This feature ensures that an env represents a consistent data flow This feature ensures that an env represents a consistent data flow
...@@ -488,13 +480,14 @@ def view_roots(r): ...@@ -488,13 +480,14 @@ def view_roots(r):
owner = r.owner owner = r.owner
if owner is not None: if owner is not None:
try: try:
view_map = owner.view_map() view_map = owner.op.view_map
except AttributeError, AbstractFunctionError: view_map = dict([(owner.outputs[o], i) for o, i in view_map.items()])
except AttributeError:
return [r] return [r]
if r in view_map: if r in view_map:
answer = [] answer = []
for r2 in view_map[r]: for i in view_map[r]:
answer += view_roots(r2) answer += view_roots(owner.inputs[i])
return answer return answer
else: else:
return [r] return [r]
......
...@@ -24,7 +24,11 @@ class Op(object2): ...@@ -24,7 +24,11 @@ class Op(object2):
raise AbstractFunctionError() raise AbstractFunctionError()
def __call__(self, *inputs): def __call__(self, *inputs):
return self.make_node(*inputs).out node = self.make_node(*inputs)
if len(node.outputs) == 1:
return node.outputs[0]
else:
return node.outputs
######################### #########################
......
...@@ -396,8 +396,14 @@ class _metadict: ...@@ -396,8 +396,14 @@ class _metadict:
return self.d[item] return self.d[item]
except: except:
for item2, value in self.l: for item2, value in self.l:
try:
if item == item2: if item == item2:
return value return value
if item.equals(item2):
return value
except:
if item is item2:
return value
else: else:
return default return default
def clear(self): def clear(self):
......
...@@ -36,6 +36,9 @@ def as_tensor(x, name = None): ...@@ -36,6 +36,9 @@ def as_tensor(x, name = None):
except TypeError: except TypeError:
raise raise
raise TypeError("Cannot convert %s to Tensor" % x, type(x)) raise TypeError("Cannot convert %s to Tensor" % x, type(x))
# this has a different name, because _as_tensor is the function which ops use
# to upcast their arguments... this internal-use function is a good place to put debugging stuff, better than the global astensor.
_as_tensor = as_tensor
def constant(x): def constant(x):
...@@ -226,6 +229,9 @@ class Tensor(Type): ...@@ -226,6 +229,9 @@ class Tensor(Type):
# Easy constructors # Easy constructors
def tensor(*args):
return Tensor(*args).make_result()
def _multi(*fns): def _multi(*fns):
def f2(f, names): def f2(f, names):
if len(names) == 1: if len(names) == 1:
...@@ -347,115 +353,39 @@ s2t.TensorConstant = TensorConstant ...@@ -347,115 +353,39 @@ s2t.TensorConstant = TensorConstant
# Supporting Ops # Supporting Ops
############################ ############################
# this has a different name, because _as_tensor is the function which ops use
# to upcast their arguments... this internal-use function is a good place to put debugging stuff, better than the global astensor.
_as_tensor = as_tensor
# class _Op(Op):
# """
# A basic L{Op} subclass that can be used to make L{Op}s that operate on L{Tensor}s.
# It is not mandatory to inherit from this class, but it is practical.
# @ivar nin: number of inputs
# @ivar nout: number of outputs
# @ivar out_tensor_class: L{Tensor} subclass used to instantiate the outputs
# - input_wrapper: returns a L{Tensor} from its argument
# - propagate_dtype: returns a list of dtypes corresponding to the
# output dtypes from a list of input dtypes (if an input is not a
# L{Tensor}, the passed value will be None)
# - propagate_broadcastable: returns a list of tuples corresponding
# to the output broadcastable flags from the input broadcastable flags
# (if an input is not a L{Tensor}, the passed value will be None).
# """
# nin = -1 # nin == -1 means: arbitrary number of inputs
# nout = 1
# def __init__(self, *inputs):
# inputs = map(_as_tensor, 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_broadcastables = [getattr(input, 'broadcastable', None) for input in inputs]
# i_dtypes = [getattr(input, 'dtype', None) for input in inputs]
# o_broadcastables = utils.from_return_values(self.propagate_broadcastable(*i_broadcastables))
# o_dtypes = utils.from_return_values(self.propagate_dtype(*i_dtypes))
# self.inputs = inputs
# self.outputs = [Tensor(dtype, broadcastable) for broadcastable, dtype in zip(o_broadcastables, o_dtypes)]
# def propagate_broadcastable(self, *inputs):
# raise AbstractFunctionError()
# def propagate_dtype(self, *i_dtypes):
# rval = set([dtype for dtype in i_dtypes if dtype is not None])
# if len(rval) == 0:
# raise ValueError("Cannot infer the dtypes of the outputs with no Tensor inputs.")
# elif len(rval) > 1:
# raise ValueError("The dtypes of all inputs should be identical.")
# return [rval.pop()] * self.nout
########################## ##########################
# Unary Operations # Unary Operations
########################## ##########################
# def broadcast(scalar_opclass, name, module_name = None, inplace_versions = True): class Argmax(Op):
# C = s2t.make_broadcast(scalar_opclass, name = name, module_name = module_name) # this returns a class """Calculate the max and argmax over a given axis"""
# C.__module__ = module_name nin=2 # tensor, axis
# c = gof.op.constructor(s2t.wrap_broadcast(C)) nout=2 # max val, max idx
# if inplace_versions: E_axis = 'invalid axis'
# CInplace = s2t.make_broadcast(scalar_opclass, {0:0}, name = name+"Inplace") def make_node(self, x, axis=None):
# CInplace.__module__ = module_name x = _as_tensor(x)
# c_inplace = gof.op.constructor(s2t.wrap_broadcast(CInplace)) if axis is None:
# return C, c, CInplace, c_inplace axis = x.type.ndim - 1
# else: axis = _as_tensor(axis)
# return C, c inputs = [x, axis]
broadcastable = [False] * (x.type.ndim - 1)
# def _broadcast(scalar_opclass, name, inplace_versions = True): outputs = [tensor(x.type.dtype, broadcastable),
# return broadcast(scalar_opclass, name, 'tensor', inplace_versions) tensor(axis.type.dtype, broadcastable)]
return Apply(self, inputs, outputs)
def perform(self, node, (x, axis), (max, max_idx)):
# class Argmax(Op): max[0] = numpy.max(x, axis)
# """Calculate the max and argmax over a given axis""" max_idx[0] = numpy.argmax(x, axis)
# nin=2 # tensor, axis argmax = Argmax()
# nout=2 # max val, max idx
# E_axis = 'invalid axis' def max(x, axis=None):
# debug = 0 """Return maximum elements obtained by iterating over given axis
# def __init__(self, x, axis=None):
# x = _as_tensor(x) Default axis is the last one.
# if axis is None: """
# axis = len(x.broadcastable) -1 # In python (using Argmax.perform()) this leads to an wasteful
# axis = _as_tensor(axis) # implementation that goes through the data twice instead of once
# self.inputs = [x, axis] # but when Argmax.c_impl() is in place, it should be fine.
# broadcastable = [0] * (len(x.broadcastable) - 1) return argmax(x,axis)[0]
# self.outputs = [Tensor(x.dtype, broadcastable),
# Tensor(axis.dtype, broadcastable)]
# def perform(self):
# axis = self.inputs[1].data
# x = self.inputs[0].data
# self.outputs[0].data = numpy.max(x, axis)
# self.outputs[1].data = numpy.argmax(x,axis)
# argmax = gof.op.constructor(Argmax)
# def max(x, axis=None):
# """Return maximum elements obtained by iterating over given axis
# Default axis is the last one.
# """
# # In python (using Argmax.perform()) this leads to an wasteful
# # implementation that goes through the data twice instead of once
# # but when Argmax.c_impl() is in place, it should be fine.
# return argmax(x,axis)[0]
def _elemwise(scalar_op, name): def _elemwise(scalar_op, name):
...@@ -508,6 +438,7 @@ pow, pow_inplace = _elemwise(scal.pow, 'pow') ...@@ -508,6 +438,7 @@ pow, pow_inplace = _elemwise(scal.pow, 'pow')
########################## ##########################
class TransposeInplace(Op): class TransposeInplace(Op):
view_map = {0: [0]}
def make_node(self, input): def make_node(self, input):
return Apply(self, [input], [input.type()]) return Apply(self, [input], [input.type()])
...@@ -531,32 +462,24 @@ transpose_inplace = TransposeInplace() ...@@ -531,32 +462,24 @@ transpose_inplace = TransposeInplace()
def transpose(x, **kwargs): def transpose(x, **kwargs):
return transpose_inplace(tensor_copy(x), **kwargs) return transpose_inplace(tensor_copy(x), **kwargs)
# class Subtensor(Op, Viewer): # class Subtensor(Op):
# nin = 2 # nin = 2
# nout = 1 # nout = 1
# e_invalid = 'invalid index' # e_invalid = 'invalid index'
# debug = 0 # view_map = {0: [0]}
# def __init__(self, *args,**kwargs): # def make_node(self, *inputs):
# def as_tuple_result(obj): # def as_tuple_result(obj):
# if isinstance(obj, Result): # if isinstance(obj, gof.Result):
# return obj # return obj
# r = gof.result.PythonResult(None) # assert isinstance(obj, (list, tuple))
# if isinstance(obj, tuple): # r = gof.Constant(gof.generic, obj)
# r.data = obj
# else:
# r.data = (obj,)
# return r # return r
# def pad(tplR, N): # # def pad(tplR, N):
# l = list(tplR.data) # # l = list(tplR.data)
# for i in range(len(l), N): # # for i in range(len(l), N):
# l.append(slice(0,sys.maxint,1)) # # l.append(slice(0,sys.maxint,1))
# tplR.data = tuple(l) # # tplR.data = tuple(l)
# if Subtensor.debug:
# print 'Subtensor.__init__', args, kwargs
# #Olivier says not to call this
# #Op.__init__(self, *args,**kwargs)
# #Viewer.__init__(self, *args,**kwargs)
# t, coord = args # t, coord = args
# t = _as_tensor(t) # t = _as_tensor(t)
# coord = as_tuple_result(coord) # coord = as_tuple_result(coord)
...@@ -564,26 +487,17 @@ def transpose(x, **kwargs): ...@@ -564,26 +487,17 @@ def transpose(x, **kwargs):
# raise ValueError(Subtensor.e_invalid) # raise ValueError(Subtensor.e_invalid)
# # add the implicit extra unbounded slices # # add the implicit extra unbounded slices
# # e.g. n[0] on a 3d tensor pads to n[0,:,:] # # e.g. n[0] on a 3d tensor pads to n[0,:,:]
# pad(coord, len(t.broadcastable)) # ###pad(coord, len(t.broadcastable))
# broadcastable = [0 for c in coord.data if isinstance(c, slice)] # broadcastable = [False for c in coord.data if isinstance(c, slice)]
# if Subtensor.debug:
# print 'brdcstble', broadcastable
# print 't', t.data
# print 'coord', coord.data
# self.inputs = [t, coord] # self.inputs = [t, coord]
# self.outputs = [Tensor(t.dtype, broadcastable)] # self.outputs = [Tensor(t.dtype, broadcastable)]
# def view_map(self): # def view_map(self):
# return {self.out: [self.inputs[0]]} # return {self.out: [self.inputs[0]]}
# def perform(self): # def perform(self, node, (x, c), (out, )):
# x = self.inputs[0].data
# c = self.inputs[1].data
# if Subtensor.debug:
# print 'perform: x', x
# print 'perform: c', c
# if len(c) == 1: # if len(c) == 1:
# self.outputs[0].data = x.__getitem__(c[0]) # out[0] = x.__getitem__(c[0])
# else: # else:
# self.outputs[0].data = x.__getitem__(c) # out[0] = x.__getitem__(c)
# def grad(self, (x,), (gz,)): # def grad(self, (x,), (gz,)):
# # - option: allocate a potentially large matrix of zeros, and fill in # # - option: allocate a potentially large matrix of zeros, and fill in
# # the appropriate elements from gz # # the appropriate elements from gz
...@@ -591,7 +505,7 @@ def transpose(x, **kwargs): ...@@ -591,7 +505,7 @@ def transpose(x, **kwargs):
# # - option: return gz, but think about how to include a special addition # # - option: return gz, but think about how to include a special addition
# # function that works on a corresponding view of the original data # # function that works on a corresponding view of the original data
# raise NotImplementedError() # raise NotImplementedError()
# subtensor = gof.op.constructor(Subtensor) # subtensor = Subtensor()
######################### #########################
...@@ -599,8 +513,6 @@ def transpose(x, **kwargs): ...@@ -599,8 +513,6 @@ def transpose(x, **kwargs):
######################### #########################
class Dot(Op): class Dot(Op):
# nin=2
# nout=1
def make_node(self, *inputs): def make_node(self, *inputs):
inputs = map(as_tensor, inputs) inputs = map(as_tensor, inputs)
if len(inputs) != 2: if len(inputs) != 2:
...@@ -608,9 +520,6 @@ class Dot(Op): ...@@ -608,9 +520,6 @@ class Dot(Op):
i_broadcastables = [input.type.broadcastable for input in inputs] i_broadcastables = [input.type.broadcastable for input in inputs]
i_dtypes = [input.type.dtype for input in inputs] i_dtypes = [input.type.dtype for input in inputs]
# o_broadcastables = utils.from_return_values(self.propagate_broadcastable(*i_broadcastables))
# o_dtypes = utils.from_return_values(self.propagate_dtype(*i_dtypes))
bx, by = i_broadcastables bx, by = i_broadcastables
if len(bx) == 0: # x is a scalar if len(bx) == 0: # x is a scalar
bz = by bz = by
...@@ -624,7 +533,7 @@ class Dot(Op): ...@@ -624,7 +533,7 @@ class Dot(Op):
o_broadcastables = [bz] o_broadcastables = [bz]
o_dtypes = [scal.upcast(*i_dtypes)] o_dtypes = [scal.upcast(*i_dtypes)]
outputs = [Tensor(t, b)() for b, t in zip(o_broadcastables, o_dtypes)] outputs = [tensor(t, b) for b, t in zip(o_broadcastables, o_dtypes)]
return Apply(self, inputs, outputs) return Apply(self, inputs, outputs)
def perform(self, node, (x, y), (z, )): def perform(self, node, (x, y), (z, )):
...@@ -633,228 +542,222 @@ class Dot(Op): ...@@ -633,228 +542,222 @@ class Dot(Op):
return dot(gz, y.T), dot(x.T, gz) return dot(gz, y.T), dot(x.T, gz)
dot = Dot() dot = Dot()
# class Gemm(_Op): class Gemm(Op):
# nin=5 E_rank = 'gemm only works for rank 2'
# nout=1 E_scalar = 'gemm requires scalar argument'
# E_rank = 'gemm only works for rank 2' E_z_uniq = 'argument z aliased to x or y'
# E_scalar = 'gemm requires scalar argument' destroy_map = {0: [0]}
# E_z_uniq = 'argument z aliased to x or y' def make_node(self, *inputs):
# debug = False inputs = map(as_tensor, inputs)
# def __init__(self, *args, **kwargs): if len(inputs) != 5:
# _Op.__init__(self, *args, **kwargs) raise TypeError("Wrong number of inputs for %s (expected 5, got %s)" % (self, len(inputs)))
# z, a, x, y, b = self.inputs z, a, x, y, b = inputs
# zr, xr, yr = [set(gof.view_roots(i)) for i in z,x,y] zr, xr, yr = [set(gof.view_roots(i)) for i in z,x,y]
# if zr.intersection(xr): if zr.intersection(xr):
# raise ValueError(Gemm.E_z_uniq, (z, x)) raise ValueError(Gemm.E_z_uniq, (z, x))
# if zr.intersection(yr): if zr.intersection(yr):
# raise ValueError(Gemm.E_z_uniq, (z, y)) raise ValueError(Gemm.E_z_uniq, (z, y))
# def destroy_map(self): bz, ba, bx, by, bb = [r.type.broadcastable for r in inputs]
# return {self.out:[self.inputs[0]]} if len(bz) != 2: raise ValueError(Gemm.E_rank, len(bz))
# def propagate_broadcastable(self, bz, ba, bx, by, bb): if len(bx) != 2: raise ValueError(Gemm.E_rank, len(bx))
# if len(bz) != 2: raise ValueError(Gemm.E_rank, len(bz)) if len(by) != 2: raise ValueError(Gemm.E_rank, len(by))
# if len(bx) != 2: raise ValueError(Gemm.E_rank, len(bx)) if len(ba): raise ValueError(Gemm.E_scalar, ba)
# if len(by) != 2: raise ValueError(Gemm.E_rank, len(by)) if len(bb): raise ValueError(Gemm.E_scalar, bb)
# if len(ba): raise ValueError(Gemm.E_scalar, ba) output = z.type()
# if len(bb): raise ValueError(Gemm.E_scalar, bb) return Apply(self, inputs, [output])
def perform(self, node, (z, a, x, y, b), (zout, )):
# return [bz] assert a.shape == ()
# def impl(self, z, a, x, y, b): assert b.shape == ()
# assert a.shape == () if z.shape == ():
# assert b.shape == () z.itemset(z*a + b*numpy.dot(x,y))
# if z.shape == (): zout[0] = z
# z.itemset(z*a + b*numpy.dot(x,y)) else:
# return z if b == 0.0:
# else: if a == 1.0:
# if b == 0.0: z[:] = numpy.dot(x,y)
# if a == 1.0: elif a == -1.0:
# z[:] = numpy.dot(x,y) z[:] = -numpy.dot(x,y)
# elif a == -1.0: else:
# z[:] = -numpy.dot(x,y) z[:] = a * numpy.dot(x,y)
# else: elif b == 1.0:
# z[:] = a * numpy.dot(x,y) if a == 1.0:
# elif b == 1.0: z += numpy.dot(x,y)
# if a == 1.0: elif a == -1.0:
# z += numpy.dot(x,y) z -= numpy.dot(x,y)
# elif a == -1.0: else:
# z -= numpy.dot(x,y) z += a * numpy.dot(x,y)
# else: else:
# z += a * numpy.dot(x,y) z *= b
# else: z += a * numpy.dot(x,y)
# z *= b zout[0] = z
# z += a * numpy.dot(x,y) def grad(self, (z, a, x, y, b), (gz,)):
# return z raise NotImplementedError()
# def grad(self, (z, a, x, y, b), (gz,)):
# raise NotImplementedError() def c_support_code(self):
#return blas.cblas_header_text()
mod_str = """
#ifndef MOD
#define MOD %
#endif
"""
return blas.blas_proto() + mod_str
def c_headers(self):
return ['<iostream>']
def c_libraries(self):
return blas.ldflags()
def c_code(self, node, name, (_z, _a, _x, _y, _b), (_zout, ), sub):
return """
int unit = 0;
int type_num = %(_x)s->descr->type_num;
int type_size = %(_x)s->descr->elsize; // in bytes
npy_intp* Nx = %(_x)s->dimensions;
npy_intp* Ny = %(_y)s->dimensions;
npy_intp* Nz = %(_z)s->dimensions;
npy_intp* Sx = %(_x)s->strides;
npy_intp* Sy = %(_y)s->strides;
npy_intp* Sz = %(_z)s->strides;
//strides for x, y, z in dimensions 0, 1
int sx_0, sx_1, sy_0, sy_1, sz_0, sz_1;
if (%(_zout)s != %(_z)s)
{
if (%(_zout)s)
{
Py_DECREF(%(_zout)s);
}
%(_zout)s = %(_z)s;
Py_INCREF(%(_zout)s);
}
if (%(_x)s->nd != 2) {PyErr_SetString(PyExc_NotImplementedError, "rank(x) != 2"); %(fail)s;}
if (%(_y)s->nd != 2) {PyErr_SetString(PyExc_NotImplementedError, "rank(y) != 2"); %(fail)s;}
if (%(_z)s->nd != 2) {PyErr_SetString(PyExc_NotImplementedError, "rank(z) != 2"); %(fail)s;}
if ((%(_a)s->descr->type_num != PyArray_DOUBLE)
&& (%(_a)s->descr->type_num != PyArray_FLOAT))
{PyErr_SetString(PyExc_NotImplementedError, "type(a) is not double or float"); %(fail)s;}
if ((%(_b)s->descr->type_num != PyArray_DOUBLE)
&& (%(_b)s->descr->type_num != PyArray_FLOAT))
{PyErr_SetString(PyExc_NotImplementedError, "type(b) is not double or float"); %(fail)s;}
if ((%(_x)s->descr->type_num != PyArray_DOUBLE)
&& (%(_x)s->descr->type_num != PyArray_FLOAT))
{PyErr_SetString(PyExc_NotImplementedError, "type(x) is not double or float"); %(fail)s;}
if ((%(_y)s->descr->type_num != PyArray_DOUBLE)
&& (%(_y)s->descr->type_num != PyArray_FLOAT))
{PyErr_SetString(PyExc_NotImplementedError, "type(y) is not double or float"); %(fail)s;}
if ((%(_z)s->descr->type_num != PyArray_DOUBLE)
&& (%(_z)s->descr->type_num != PyArray_FLOAT))
{PyErr_SetString(PyExc_NotImplementedError, "type(z) is not double or float"); %(fail)s;}
if ((%(_x)s->descr->type_num != %(_y)s->descr->type_num)
||(%(_x)s->descr->type_num != %(_z)s->descr->type_num))
{ PyErr_SetString(PyExc_NotImplementedError, "type(z), type(y), type(z) are not all the same"); %(fail)s; }
if ((Nx[0] != Nz[0]) || (Nx[1] != Ny[0]) || (Ny[1] != Nz[1]))
{
PyErr_SetString(PyExc_ValueError, "Input dimensions do not agree");
%(fail)s;
}
if ((Sx[0] < 1) || (Sx[1] < 1) || (Sx[0] MOD type_size) || (Sx[1] MOD type_size)
|| (Sy[0] < 1) || (Sy[1] < 1) || (Sy[0] MOD type_size) || (Sy[1] MOD type_size)
|| (Sz[0] < 1) || (Sz[1] < 1) || (Sz[0] MOD type_size) || (Sz[1] MOD type_size))
{
PyErr_SetString(PyExc_ValueError, "stride is not multiple of element size"); %(fail)s;
}
/*
encode the stride structure of _x,_y,_z into a single integer
*/
unit |= ((Sx[1] == type_size) ? 0x0 : (Sx[0] == type_size) ? 0x1 : 0x2) << 8;
unit |= ((Sy[1] == type_size) ? 0x0 : (Sy[0] == type_size) ? 0x1 : 0x2) << 4;
unit |= ((Sz[1] == type_size) ? 0x0 : (Sz[0] == type_size) ? 0x1 : 0x2) << 0;
/* create appropriate strides for malformed matrices that are row or column
* vectors
*/
sx_0 = (Nx[0] > 1) ? Sx[0]/type_size : Nx[1];
sx_1 = (Nx[1] > 1) ? Sx[1]/type_size : Nx[0];
sy_0 = (Ny[0] > 1) ? Sy[0]/type_size : Ny[1];
sy_1 = (Ny[1] > 1) ? Sy[1]/type_size : Ny[0];
sz_0 = (Nz[0] > 1) ? Sz[0]/type_size : Nz[1];
sz_1 = (Nz[1] > 1) ? Sz[1]/type_size : Nz[0];
switch (type_num)
{
case PyArray_FLOAT:
{
#define REAL float
float a = (%(_a)s->descr->type_num == PyArray_FLOAT)
? (REAL)(((float*)%(_a)s->data)[0])
: (REAL)(((double*)%(_a)s->data)[0]);
float b = (%(_b)s->descr->type_num == PyArray_FLOAT) ?
(REAL)(((float*)%(_b)s->data)[0])
: (REAL)(((double*)%(_b)s->data)[0]);
float* x = (float*)PyArray_DATA(%(_x)s);
float* y = (float*)PyArray_DATA(%(_y)s);
float* z = (float*)PyArray_DATA(%(_z)s);
char N = 'N';
char T = 'T';
int Nz0 = Nz[0], Nz1 = Nz[1], Nx1 = Nx[1];
//std::cerr << (unit/256) MOD 16 << (unit / 16) MOD 16 << unit MOD 16<< '\\n';
switch(unit)
{
case 0x000: sgemm_(&N, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_0, &b, z, &sz_0); break;
case 0x100: sgemm_(&N, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_1, &b, z, &sz_0); break;
case 0x010: sgemm_(&T, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_0, &b, z, &sz_0); break;
case 0x110: sgemm_(&T, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_1, &b, z, &sz_0); break;
case 0x001: sgemm_(&T, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_0, &b, z, &sz_1); break;
case 0x101: sgemm_(&N, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_0, &b, z, &sz_1); break;
case 0x011: sgemm_(&T, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_1, &b, z, &sz_1); break;
case 0x111: sgemm_(&N, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_1, &b, z, &sz_1); break;
default: PyErr_SetString(PyExc_ValueError, "some matrix has no unit stride"); %(fail)s;
};
#undef REAL
}
break;
case PyArray_DOUBLE:
{
#define REAL double
double a = (%(_a)s->descr->type_num == PyArray_FLOAT)
? (REAL)(((float*)%(_a)s->data)[0])
: (REAL)(((double*)%(_a)s->data)[0]);
double b = (%(_b)s->descr->type_num == PyArray_FLOAT) ?
(REAL)(((float*)%(_b)s->data)[0])
: (REAL)(((double*)%(_b)s->data)[0]);
double* x = (double*)PyArray_DATA(%(_x)s);
double* y = (double*)PyArray_DATA(%(_y)s);
double* z = (double*)PyArray_DATA(%(_z)s);
char N = 'N';
char T = 'T';
int Nz0 = Nz[0], Nz1 = Nz[1], Nx1 = Nx[1];
//std::cerr << (unit/256) MOD 16 << (unit / 16) MOD 16 << unit MOD 16<< '\\n';
switch(unit)
{
case 0x000: dgemm_(&N, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_0, &b, z, &sz_0); break;
case 0x100: dgemm_(&N, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_1, &b, z, &sz_0); break;
case 0x010: dgemm_(&T, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_0, &b, z, &sz_0); break;
case 0x110: dgemm_(&T, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_1, &b, z, &sz_0); break;
case 0x001: dgemm_(&T, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_0, &b, z, &sz_1); break;
case 0x101: dgemm_(&N, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_0, &b, z, &sz_1); break;
case 0x011: dgemm_(&T, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_1, &b, z, &sz_1); break;
case 0x111: dgemm_(&N, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_1, &b, z, &sz_1); break;
default: PyErr_SetString(PyExc_ValueError, "some matrix has no unit stride"); %(fail)s;
};
#undef REAL
}
break;
}
# def c_support_code(self): """ % dict(locals(), **sub)
# #return blas.cblas_header_text() gemm = Gemm()
# mod_str = """
# #ifndef MOD
# #define MOD %
# #endif
# """
# return blas.blas_proto() + mod_str
# def c_headers(self):
# return ['<iostream>']
# def c_libraries(self):
# return blas.ldflags()
# def c_validate_update(self, *args):
# return ""
# def c_validate_update_cleanup(self, *args):
# return ""
# def c_code(self, (_z, _a, _x, _y, _b), (_zout, ), sub):
# return """
# int unit = 0;
# int type_num = %(_x)s->descr->type_num;
# int type_size = %(_x)s->descr->elsize; // in bytes
# npy_intp* Nx = %(_x)s->dimensions;
# npy_intp* Ny = %(_y)s->dimensions;
# npy_intp* Nz = %(_z)s->dimensions;
# npy_intp* Sx = %(_x)s->strides;
# npy_intp* Sy = %(_y)s->strides;
# npy_intp* Sz = %(_z)s->strides;
# //strides for x, y, z in dimensions 0, 1
# int sx_0, sx_1, sy_0, sy_1, sz_0, sz_1;
# if (%(_zout)s != %(_z)s)
# {
# if (%(_zout)s)
# {
# Py_DECREF(%(_zout)s);
# }
# %(_zout)s = %(_z)s;
# Py_INCREF(%(_zout)s);
# }
# if (%(_x)s->nd != 2) {PyErr_SetString(PyExc_NotImplementedError, "rank(x) != 2"); %(fail)s;}
# if (%(_y)s->nd != 2) {PyErr_SetString(PyExc_NotImplementedError, "rank(y) != 2"); %(fail)s;}
# if (%(_z)s->nd != 2) {PyErr_SetString(PyExc_NotImplementedError, "rank(z) != 2"); %(fail)s;}
# if ((%(_a)s->descr->type_num != PyArray_DOUBLE)
# && (%(_a)s->descr->type_num != PyArray_FLOAT))
# {PyErr_SetString(PyExc_NotImplementedError, "type(a) is not double or float"); %(fail)s;}
# if ((%(_b)s->descr->type_num != PyArray_DOUBLE)
# && (%(_b)s->descr->type_num != PyArray_FLOAT))
# {PyErr_SetString(PyExc_NotImplementedError, "type(b) is not double or float"); %(fail)s;}
# if ((%(_x)s->descr->type_num != PyArray_DOUBLE)
# && (%(_x)s->descr->type_num != PyArray_FLOAT))
# {PyErr_SetString(PyExc_NotImplementedError, "type(x) is not double or float"); %(fail)s;}
# if ((%(_y)s->descr->type_num != PyArray_DOUBLE)
# && (%(_y)s->descr->type_num != PyArray_FLOAT))
# {PyErr_SetString(PyExc_NotImplementedError, "type(y) is not double or float"); %(fail)s;}
# if ((%(_z)s->descr->type_num != PyArray_DOUBLE)
# && (%(_z)s->descr->type_num != PyArray_FLOAT))
# {PyErr_SetString(PyExc_NotImplementedError, "type(z) is not double or float"); %(fail)s;}
# if ((%(_x)s->descr->type_num != %(_y)s->descr->type_num)
# ||(%(_x)s->descr->type_num != %(_z)s->descr->type_num))
# { PyErr_SetString(PyExc_NotImplementedError, "type(z), type(y), type(z) are not all the same"); %(fail)s; }
# if ((Nx[0] != Nz[0]) || (Nx[1] != Ny[0]) || (Ny[1] != Nz[1]))
# {
# PyErr_SetString(PyExc_ValueError, "Input dimensions do not agree");
# %(fail)s;
# }
# if ((Sx[0] < 1) || (Sx[1] < 1) || (Sx[0] MOD type_size) || (Sx[1] MOD type_size)
# || (Sy[0] < 1) || (Sy[1] < 1) || (Sy[0] MOD type_size) || (Sy[1] MOD type_size)
# || (Sz[0] < 1) || (Sz[1] < 1) || (Sz[0] MOD type_size) || (Sz[1] MOD type_size))
# {
# PyErr_SetString(PyExc_ValueError, "stride is not multiple of element size"); %(fail)s;
# }
# /*
# encode the stride structure of _x,_y,_z into a single integer
# */
# unit |= ((Sx[1] == type_size) ? 0x0 : (Sx[0] == type_size) ? 0x1 : 0x2) << 8;
# unit |= ((Sy[1] == type_size) ? 0x0 : (Sy[0] == type_size) ? 0x1 : 0x2) << 4;
# unit |= ((Sz[1] == type_size) ? 0x0 : (Sz[0] == type_size) ? 0x1 : 0x2) << 0;
# /* create appropriate strides for malformed matrices that are row or column
# * vectors
# */
# sx_0 = (Nx[0] > 1) ? Sx[0]/type_size : Nx[1];
# sx_1 = (Nx[1] > 1) ? Sx[1]/type_size : Nx[0];
# sy_0 = (Ny[0] > 1) ? Sy[0]/type_size : Ny[1];
# sy_1 = (Ny[1] > 1) ? Sy[1]/type_size : Ny[0];
# sz_0 = (Nz[0] > 1) ? Sz[0]/type_size : Nz[1];
# sz_1 = (Nz[1] > 1) ? Sz[1]/type_size : Nz[0];
# switch (type_num)
# {
# case PyArray_FLOAT:
# {
# #define REAL float
# float a = (%(_a)s->descr->type_num == PyArray_FLOAT)
# ? (REAL)(((float*)%(_a)s->data)[0])
# : (REAL)(((double*)%(_a)s->data)[0]);
# float b = (%(_b)s->descr->type_num == PyArray_FLOAT) ?
# (REAL)(((float*)%(_b)s->data)[0])
# : (REAL)(((double*)%(_b)s->data)[0]);
# float* x = (float*)PyArray_DATA(%(_x)s);
# float* y = (float*)PyArray_DATA(%(_y)s);
# float* z = (float*)PyArray_DATA(%(_z)s);
# char N = 'N';
# char T = 'T';
# int Nz0 = Nz[0], Nz1 = Nz[1], Nx1 = Nx[1];
# //std::cerr << (unit/256) MOD 16 << (unit / 16) MOD 16 << unit MOD 16<< '\\n';
# switch(unit)
# {
# case 0x000: sgemm_(&N, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_0, &b, z, &sz_0); break;
# case 0x100: sgemm_(&N, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_1, &b, z, &sz_0); break;
# case 0x010: sgemm_(&T, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_0, &b, z, &sz_0); break;
# case 0x110: sgemm_(&T, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_1, &b, z, &sz_0); break;
# case 0x001: sgemm_(&T, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_0, &b, z, &sz_1); break;
# case 0x101: sgemm_(&N, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_0, &b, z, &sz_1); break;
# case 0x011: sgemm_(&T, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_1, &b, z, &sz_1); break;
# case 0x111: sgemm_(&N, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_1, &b, z, &sz_1); break;
# default: PyErr_SetString(PyExc_ValueError, "some matrix has no unit stride"); %(fail)s;
# };
# #undef REAL
# }
# break;
# case PyArray_DOUBLE:
# {
# #define REAL double
# double a = (%(_a)s->descr->type_num == PyArray_FLOAT)
# ? (REAL)(((float*)%(_a)s->data)[0])
# : (REAL)(((double*)%(_a)s->data)[0]);
# double b = (%(_b)s->descr->type_num == PyArray_FLOAT) ?
# (REAL)(((float*)%(_b)s->data)[0])
# : (REAL)(((double*)%(_b)s->data)[0]);
# double* x = (double*)PyArray_DATA(%(_x)s);
# double* y = (double*)PyArray_DATA(%(_y)s);
# double* z = (double*)PyArray_DATA(%(_z)s);
# char N = 'N';
# char T = 'T';
# int Nz0 = Nz[0], Nz1 = Nz[1], Nx1 = Nx[1];
# //std::cerr << (unit/256) MOD 16 << (unit / 16) MOD 16 << unit MOD 16<< '\\n';
# switch(unit)
# {
# case 0x000: dgemm_(&N, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_0, &b, z, &sz_0); break;
# case 0x100: dgemm_(&N, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_0, x, &sx_1, &b, z, &sz_0); break;
# case 0x010: dgemm_(&T, &N, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_0, &b, z, &sz_0); break;
# case 0x110: dgemm_(&T, &T, &Nz1, &Nz0, &Nx1, &a, y, &sy_1, x, &sx_1, &b, z, &sz_0); break;
# case 0x001: dgemm_(&T, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_0, &b, z, &sz_1); break;
# case 0x101: dgemm_(&N, &T, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_0, &b, z, &sz_1); break;
# case 0x011: dgemm_(&T, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_0, y, &sy_1, &b, z, &sz_1); break;
# case 0x111: dgemm_(&N, &N, &Nz0, &Nz1, &Nx1, &a, x, &sx_1, y, &sy_1, &b, z, &sz_1); break;
# default: PyErr_SetString(PyExc_ValueError, "some matrix has no unit stride"); %(fail)s;
# };
# #undef REAL
# }
# break;
# }
# """ % dict(locals(), **sub)
# gemm = gof.op.constructor(Gemm)
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论