Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
6a0852fd
提交
6a0852fd
authored
4月 29, 2008
作者:
Olivier Breuleux
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ported dot, gemm
上级
2fd6ea22
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
975 行增加
和
1069 行删除
+975
-1069
_test_tensor.py
_test_tensor.py
+680
-680
_test_tensor_opt.py
_test_tensor_opt.py
+4
-4
ext.py
gof/ext.py
+5
-12
op.py
gof/op.py
+5
-1
opt.py
gof/opt.py
+8
-2
tensor.py
tensor.py
+273
-370
没有找到文件。
_test_tensor.py
浏览文件 @
6a0852fd
...
...
@@ -52,7 +52,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
raise
type
,
value
,
traceback
try
:
f
=
Function
(
node
.
input
s
,
node
.
outputs
,
f
=
Function
(
inputr
s
,
node
.
outputs
,
linker_cls
=
lambda
env
:
gof
.
DualLinker
(
env
,
checker
=
_numpy_checker
),
unpack_single
=
False
,
optimizer
=
None
)
...
...
@@ -111,7 +111,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
raise
type
,
value
,
traceback
try
:
f
=
Function
(
node
.
input
s
,
node
.
outputs
,
f
=
Function
(
inputr
s
,
node
.
outputs
,
linker_cls
=
lambda
env
:
gof
.
DualLinker
(
env
,
checker
=
_numpy_checker
),
unpack_single
=
False
,
optimizer
=
None
)
...
...
@@ -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
)),
not_same_dimensions
=
(
rand
(
2
,
2
),
rand
(
2
)),
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
column
=
(
rand
(
2
,
3
),
rand
(
2
,
1
)),
...
...
@@ -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_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_row
=
(
rand
(
2
,
3
),
rand
(
1
,
2
)))
...
...
@@ -193,280 +194,280 @@ _grad_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)),
column
=
(
rand
(
2
,
3
),
rand
(
2
,
1
)))
AddTester
=
make_broadcast_tester
(
op
=
add
,
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
)),
four_inputs_broadcast
=
(
rand
(
2
,
3
),
rand
(
1
,
3
),
rand
(
2
,
1
),
rand
(
1
,
1
)),
**
_good_broadcast_binary_normal
),
bad_build
=
_bad_build_broadcast_binary_normal
,
bad_runtime
=
_bad_runtime_broadcast_binary_normal
)
AddInplaceTester
=
make_broadcast_tester
(
op
=
add_inplace
,
expected
=
lambda
x
,
y
:
x
+
y
,
good
=
_good_broadcast_binary_normal
,
bad_build
=
_bad_build_broadcast_binary_normal
,
bad_runtime
=
_bad_runtime_broadcast_binary_normal
,
inplace
=
True
)
SubTester
=
make_broadcast_tester
(
op
=
sub
,
expected
=
lambda
x
,
y
:
x
-
y
,
good
=
_good_broadcast_binary_normal
,
bad_build
=
_bad_build_broadcast_binary_normal
,
bad_runtime
=
_bad_runtime_broadcast_binary_normal
,
grad
=
_grad_broadcast_binary_normal
)
SubInplaceTester
=
make_broadcast_tester
(
op
=
sub_inplace
,
expected
=
lambda
x
,
y
:
x
-
y
,
good
=
_good_broadcast_binary_normal
,
bad_build
=
_bad_build_broadcast_binary_normal
,
bad_runtime
=
_bad_runtime_broadcast_binary_normal
,
grad
=
_grad_broadcast_binary_normal
,
inplace
=
True
)
MulTester
=
make_broadcast_tester
(
op
=
mul
,
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
)),
four_inputs_broadcast
=
(
rand
(
2
,
3
),
rand
(
1
,
3
),
rand
(
2
,
1
),
rand
(
1
,
1
)),
**
_good_broadcast_binary_normal
),
bad_build
=
_bad_build_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
)),
four_inputs_broadcast
=
(
rand
(
2
,
3
),
rand
(
1
,
3
),
rand
(
2
,
1
),
rand
(
1
,
1
)),
**
_grad_broadcast_binary_normal
))
MulInplaceTester
=
make_broadcast_tester
(
op
=
mul_inplace
,
expected
=
lambda
x
,
y
:
x
*
y
,
good
=
_good_broadcast_binary_normal
,
bad_build
=
_bad_build_broadcast_binary_normal
,
bad_runtime
=
_bad_runtime_broadcast_binary_normal
,
grad
=
_grad_broadcast_binary_normal
,
inplace
=
True
)
DivTester
=
make_broadcast_tester
(
op
=
div
,
expected
=
lambda
x
,
y
:
x
/
y
,
good
=
dict
(
same_shapes
=
(
rand
(
2
,
3
),
rand
(
2
,
3
)),
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
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)),
# AddTester = make_broadcast_tester(op = add,
# 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)),
# four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)),
# **_good_broadcast_binary_normal),
# bad_build = _bad_build_broadcast_binary_normal,
# bad_runtime = _bad_runtime_broadcast_binary_normal)
# AddInplaceTester = make_broadcast_tester(op = add_inplace,
# expected = lambda x, y: x + y,
# good = _good_broadcast_binary_normal,
# bad_build = _bad_build_broadcast_binary_normal,
# bad_runtime = _bad_runtime_broadcast_binary_normal,
# inplace = True)
# SubTester = make_broadcast_tester(op = sub,
# expected = lambda x, y: x - y,
# good = _good_broadcast_binary_normal,
# bad_build = _bad_build_broadcast_binary_normal,
# bad_runtime = _bad_runtime_broadcast_binary_normal,
# grad = _grad_broadcast_binary_normal)
# SubInplaceTester = make_broadcast_tester(op = sub_inplace,
# expected = lambda x, y: x - y,
# good = _good_broadcast_binary_normal,
# bad_build = _bad_build_broadcast_binary_normal,
# bad_runtime = _bad_runtime_broadcast_binary_normal,
# grad = _grad_broadcast_binary_normal,
# inplace = True)
# MulTester = make_broadcast_tester(op = mul,
# 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)),
# four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)),
# **_good_broadcast_binary_normal),
# bad_build = _bad_build_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)),
# four_inputs_broadcast = (rand(2, 3), rand(1, 3), rand(2, 1), rand(1, 1)),
# **_grad_broadcast_binary_normal))
# MulInplaceTester = make_broadcast_tester(op = mul_inplace,
# expected = lambda x, y: x * y,
# good = _good_broadcast_binary_normal,
# bad_build = _bad_build_broadcast_binary_normal,
# bad_runtime = _bad_runtime_broadcast_binary_normal,
# grad = _grad_broadcast_binary_normal,
# inplace = True)
# DivTester = make_broadcast_tester(op = div,
# expected = lambda x, y: x / y,
# good = dict(same_shapes = (rand(2, 3), rand(2, 3)),
# scalar = (rand(2, 3), rand(1, 1)),
# row = (rand(2, 3), rand(1, 3)),
# 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))),
grad
=
dict
(
same_shapes
=
(
rand
(
2
,
3
),
rand
(
2
,
3
)),
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
column
=
(
rand
(
2
,
3
),
rand
(
2
,
1
))))
DivInplaceTester
=
make_broadcast_tester
(
op
=
div_inplace
,
expected
=
lambda
x
,
y
:
x
/
y
,
good
=
dict
(
same_shapes
=
(
rand
(
2
,
3
),
rand
(
2
,
3
)),
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
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
))
),
grad
=
dict
(
same_shapes
=
(
rand
(
2
,
3
),
rand
(
2
,
3
)),
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
column
=
(
rand
(
2
,
3
),
rand
(
2
,
1
))),
inplace
=
True
)
PowTester
=
make_broadcast_tester
(
op
=
pow
,
expected
=
lambda
x
,
y
:
x
**
y
,
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
))),
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
))),
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
))),
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
,
expected
=
lambda
x
,
y
:
x
**
y
,
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
))),
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
))),
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
))),
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
)))),
inplace
=
True
)
_good_broadcast_unary_normal
=
dict
(
normal
=
(
rand_ranged
(
-
5
,
5
,
(
2
,
3
)),),
integers
=
(
randint_ranged
(
-
5
,
5
,
(
2
,
3
)),))
_grad_broadcast_unary_normal
=
dict
(
normal
=
(
rand_ranged
(
-
5
,
5
,
(
2
,
3
)),))
AbsTester
=
make_broadcast_tester
(
op
=
tensor
.
_abs
,
expected
=
lambda
x
:
abs
(
x
),
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
AbsInplaceTester
=
make_broadcast_tester
(
op
=
abs_inplace
,
expected
=
lambda
x
:
abs
(
x
),
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
NegTester
=
make_broadcast_tester
(
op
=
neg
,
expected
=
lambda
x
:
-
x
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
NegInplaceTester
=
make_broadcast_tester
(
op
=
neg_inplace
,
expected
=
lambda
x
:
-
x
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
SgnTester
=
make_broadcast_tester
(
op
=
sgn
,
expected
=
numpy
.
sign
,
good
=
_good_broadcast_unary_normal
)
SgnInplaceTester
=
make_broadcast_tester
(
op
=
sgn_inplace
,
expected
=
numpy
.
sign
,
good
=
_good_broadcast_unary_normal
,
inplace
=
True
)
SqrTester
=
make_broadcast_tester
(
op
=
sqr
,
expected
=
numpy
.
square
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
SqrInplaceTester
=
make_broadcast_tester
(
op
=
sqr_inplace
,
expected
=
numpy
.
square
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
ExpTester
=
make_broadcast_tester
(
op
=
exp
,
expected
=
numpy
.
exp
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
ExpInplaceTester
=
make_broadcast_tester
(
op
=
exp_inplace
,
expected
=
numpy
.
exp
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
_good_broadcast_unary_positive
=
dict
(
normal
=
(
rand_ranged
(
0.001
,
5
,
(
2
,
3
)),),
integers
=
(
randint_ranged
(
1
,
5
,
(
2
,
3
)),))
_grad_broadcast_unary_positive
=
dict
(
normal
=
(
rand_ranged
(
0.001
,
5
,
(
2
,
3
)),))
LogTester
=
make_broadcast_tester
(
op
=
log
,
expected
=
numpy
.
log
,
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
)
LogInplaceTester
=
make_broadcast_tester
(
op
=
log_inplace
,
expected
=
numpy
.
log
,
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
,
inplace
=
True
)
Log2Tester
=
make_broadcast_tester
(
op
=
log2
,
expected
=
numpy
.
log2
,
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
)
Log2InplaceTester
=
make_broadcast_tester
(
op
=
log2_inplace
,
expected
=
numpy
.
log2
,
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
,
inplace
=
True
)
SqrtTester
=
make_broadcast_tester
(
op
=
sqrt
,
expected
=
numpy
.
sqrt
,
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
)
SqrtInplaceTester
=
make_broadcast_tester
(
op
=
sqrt_inplace
,
expected
=
numpy
.
sqrt
,
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
,
inplace
=
True
)
_good_broadcast_unary_wide
=
dict
(
normal
=
(
rand_ranged
(
-
1000
,
1000
,
(
2
,
3
)),),
integers
=
(
randint_ranged
(
-
1000
,
1000
,
(
2
,
3
)),))
_grad_broadcast_unary_wide
=
dict
(
normal
=
(
rand_ranged
(
-
1000
,
1000
,
(
2
,
3
)),))
SinTester
=
make_broadcast_tester
(
op
=
sin
,
expected
=
numpy
.
sin
,
good
=
_good_broadcast_unary_wide
,
grad
=
_grad_broadcast_unary_wide
)
SinInplaceTester
=
make_broadcast_tester
(
op
=
sin_inplace
,
expected
=
numpy
.
sin
,
good
=
_good_broadcast_unary_wide
,
grad
=
_grad_broadcast_unary_wide
,
inplace
=
True
)
CosTester
=
make_broadcast_tester
(
op
=
cos
,
expected
=
numpy
.
cos
,
good
=
_good_broadcast_unary_wide
,
grad
=
_grad_broadcast_unary_wide
)
CosInplaceTester
=
make_broadcast_tester
(
op
=
cos_inplace
,
expected
=
numpy
.
cos
,
good
=
_good_broadcast_unary_wide
,
grad
=
_grad_broadcast_unary_wide
,
inplace
=
True
)
TanTester
=
make_broadcast_tester
(
op
=
tan
,
expected
=
numpy
.
tan
,
good
=
dict
(
normal
=
(
rand_ranged
(
-
3.14
,
3.14
,
(
2
,
3
)),),
shifted
=
(
rand_ranged
(
3.15
,
6.28
,
(
2
,
3
)),)),
grad
=
dict
(
normal
=
(
rand_ranged
(
-
3.14
,
3.14
,
(
2
,
3
)),),
shifted
=
(
rand_ranged
(
3.15
,
6.28
,
(
2
,
3
)),)))
TanInplaceTester
=
make_broadcast_tester
(
op
=
tan_inplace
,
expected
=
numpy
.
tan
,
good
=
dict
(
normal
=
(
rand_ranged
(
-
3.14
,
3.14
,
(
2
,
3
)),),
shifted
=
(
rand_ranged
(
3.15
,
6.28
,
(
2
,
3
)),)),
grad
=
dict
(
normal
=
(
rand_ranged
(
-
3.14
,
3.14
,
(
2
,
3
)),),
shifted
=
(
rand_ranged
(
3.15
,
6.28
,
(
2
,
3
)),)),
inplace
=
True
)
CoshTester
=
make_broadcast_tester
(
op
=
cosh
,
expected
=
numpy
.
cosh
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
CoshInplaceTester
=
make_broadcast_tester
(
op
=
cosh_inplace
,
expected
=
numpy
.
cosh
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
SinhTester
=
make_broadcast_tester
(
op
=
sinh
,
expected
=
numpy
.
sinh
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
SinhInplaceTester
=
make_broadcast_tester
(
op
=
sinh_inplace
,
expected
=
numpy
.
sinh
,
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
TanhTester
=
make_broadcast_tester
(
op
=
tanh
,
expected
=
numpy
.
tanh
,
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
)
# 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_2 = (randint_nonzero(2, 3), rand(2, 3))),
# grad = dict(same_shapes = (rand(2, 3), rand(2, 3)),
# scalar = (rand(2, 3), rand(1, 1)),
# row = (rand(2, 3), rand(1, 3)),
# column = (rand(2, 3), rand(2, 1))))
# DivInplaceTester = make_broadcast_tester(op = div_inplace,
# expected = lambda x, y: x / y,
# good = dict(same_shapes = (rand(2, 3), rand(2, 3)),
# scalar = (rand(2, 3), rand(1, 1)),
# row = (rand(2, 3), rand(1, 3)),
# 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))
# ),
# grad = dict(same_shapes = (rand(2, 3), rand(2, 3)),
# scalar = (rand(2, 3), rand(1, 1)),
# row = (rand(2, 3), rand(1, 3)),
# column = (rand(2, 3), rand(2, 1))),
# inplace = True)
# PowTester = make_broadcast_tester(op = pow,
# expected = lambda x, y: x ** y,
# 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))),
# 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))),
# 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))),
# 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,
# expected = lambda x, y: x ** y,
# 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))),
# 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))),
# 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))),
# 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)))),
# inplace = True)
# _good_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),),
# integers = (randint_ranged(-5, 5, (2, 3)),))
# _grad_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),))
# AbsTester = make_broadcast_tester(op = tensor._abs,
# expected = lambda x: abs(x),
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# AbsInplaceTester = make_broadcast_tester(op = abs_inplace,
# expected = lambda x: abs(x),
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# NegTester = make_broadcast_tester(op = neg,
# expected = lambda x: -x,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# NegInplaceTester = make_broadcast_tester(op = neg_inplace,
# expected = lambda x: -x,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# SgnTester = make_broadcast_tester(op = sgn,
# expected = numpy.sign,
# good = _good_broadcast_unary_normal)
# SgnInplaceTester = make_broadcast_tester(op = sgn_inplace,
# expected = numpy.sign,
# good = _good_broadcast_unary_normal,
# inplace = True)
# SqrTester = make_broadcast_tester(op = sqr,
# expected = numpy.square,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# SqrInplaceTester = make_broadcast_tester(op = sqr_inplace,
# expected = numpy.square,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# ExpTester = make_broadcast_tester(op = exp,
# expected = numpy.exp,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# ExpInplaceTester = make_broadcast_tester(op = exp_inplace,
# expected = numpy.exp,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# _good_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),),
# integers = (randint_ranged(1, 5, (2, 3)),))
# _grad_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),))
# LogTester = make_broadcast_tester(op = log,
# expected = numpy.log,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive)
# LogInplaceTester = make_broadcast_tester(op = log_inplace,
# expected = numpy.log,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive,
# inplace = True)
# Log2Tester = make_broadcast_tester(op = log2,
# expected = numpy.log2,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive)
# Log2InplaceTester = make_broadcast_tester(op = log2_inplace,
# expected = numpy.log2,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive,
# inplace = True)
# SqrtTester = make_broadcast_tester(op = sqrt,
# expected = numpy.sqrt,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive)
# SqrtInplaceTester = make_broadcast_tester(op = sqrt_inplace,
# expected = numpy.sqrt,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive,
# inplace = True)
# _good_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),),
# integers = (randint_ranged(-1000, 1000, (2, 3)),))
# _grad_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),))
# SinTester = make_broadcast_tester(op = sin,
# expected = numpy.sin,
# good = _good_broadcast_unary_wide,
# grad = _grad_broadcast_unary_wide)
# SinInplaceTester = make_broadcast_tester(op = sin_inplace,
# expected = numpy.sin,
# good = _good_broadcast_unary_wide,
# grad = _grad_broadcast_unary_wide,
# inplace = True)
# CosTester = make_broadcast_tester(op = cos,
# expected = numpy.cos,
# good = _good_broadcast_unary_wide,
# grad = _grad_broadcast_unary_wide)
# CosInplaceTester = make_broadcast_tester(op = cos_inplace,
# expected = numpy.cos,
# good = _good_broadcast_unary_wide,
# grad = _grad_broadcast_unary_wide,
# inplace = True)
# TanTester = make_broadcast_tester(op = tan,
# expected = numpy.tan,
# good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
# shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
# grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
# shifted = (rand_ranged(3.15, 6.28, (2, 3)),)))
# TanInplaceTester = make_broadcast_tester(op = tan_inplace,
# expected = numpy.tan,
# good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
# shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
# grad = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
# shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
# inplace = True)
# CoshTester = make_broadcast_tester(op = cosh,
# expected = numpy.cosh,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# CoshInplaceTester = make_broadcast_tester(op = cosh_inplace,
# expected = numpy.cosh,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# SinhTester = make_broadcast_tester(op = sinh,
# expected = numpy.sinh,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal)
# SinhInplaceTester = make_broadcast_tester(op = sinh_inplace,
# expected = numpy.sinh,
# good = _good_broadcast_unary_normal,
# grad = _grad_broadcast_unary_normal,
# inplace = True)
# TanhTester = make_broadcast_tester(op = tanh,
# expected = numpy.tanh,
# 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',
# op =
D
ot,
# op =
d
ot,
# expected = lambda x, y: numpy.dot(x, y),
# checks = {},
# 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
verify_grad
.
E_grad
=
'gradient error exceeded tolerance'
#
#
useful mostly for unit tests
#
def _approx_eq(a,b,eps=1.0e-9):
#
a = numpy.asarray(a)
#
b = numpy.asarray(b)
#
if a.shape != b.shape:
#
if _approx_eq.debug:
#
print a.shape, b.shape
#
return False
#
if numpy.max(numpy.abs(a-b)) >= eps:
#
if _approx_eq.debug:
#
print a, b
#
return False
#
return True
#
_approx_eq.debug = 0
#
def check_eq(self, node_in, node_out, arg_in, arg_out):
#
fn = Function([node_in], [node_out])
#
self.failUnless( numpy.all(fn(arg_in) == arg_out), (arg_in, arg_out))
#
def check_eq2(self, inputs, output, args_in, arg_out):
#
fn = Function(inputs, [output])
#
val = fn(*args_in)
#
self.failUnless( numpy.all(val == arg_out), (val, arg_out))
#
def check_eq2_c(self, inputs, output, args_in, arg_out):
#
fn = Function(inputs, [output], linker_cls = gof.CLinker)
#
val = fn(*args_in)
#
self.failUnless( numpy.all(val == arg_out), (val, 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))
#
val = fn(*args_in)
#
self.failUnless( numpy.all(val == arg_out), (val, arg_out))
#
class T_argmax(unittest.TestCase):
#
def setUp(self):
#
numpy.random.seed(123784)
#
Argmax.debug = 0
#
def test0(self):
# n = as
tensor(5.0)
#
v,i = eval_outputs(argmax(n))
#
self.failUnless(v == 5.0)
#
self.failUnless(i == 0)
#
def test1(self):
# n = as
tensor([1,2,3,2,-6])
#
v,i = eval_outputs(argmax(n))
#
self.failUnless(v == 3)
#
self.failUnless(i == 2)
#
def test2(self):
# n = as
tensor(numpy.random.rand(2,3))
#
v,i = eval_outputs(argmax(n))
#
self.failUnless(numpy.all(i == [0,1]))
#
def test2b(self):
# n = as
tensor(numpy.random.rand(2,3))
# v,i = eval_outputs(argmax(n,axis=
0))
#
self.failUnless(numpy.all(i == [0,1,1]))
#
def test2_invalid(self):
# n = as
tensor(numpy.random.rand(2,3))
#
try:
# eval_outputs(argmax(n,axis=
3))
#
except ValueError, e:
#
return
#
self.fail()
#
def test2_invalid_neg(self):
# n = as
tensor(numpy.random.rand(2,3))
#
try:
# eval_outputs(argmax(n,axis=
-3))
#
except ValueError, e:
#
return
#
self.fail()
#
def test2_valid_neg(self):
# n = as
tensor(numpy.random.rand(2,3))
# v,i = eval_outputs(argmax(n,axis=
-1))
#
self.failUnless(v.shape == (2,))
# v,i = eval_outputs(argmax(n,axis=
-2))
#
self.failUnless(v.shape == (3,))
#
def test3(self):
# n = as
tensor(numpy.random.rand(2,3,4))
# v,i = eval_outputs(argmax(n,axis=
0))
#
self.failUnless(v.shape == (3,4))
#
self.failUnless(i.shape == (3,4))
# v,i = eval_outputs(argmax(n,axis=
1))
#
self.failUnless(v.shape == (2,4))
#
self.failUnless(i.shape == (2,4))
# v,i = eval_outputs(argmax(n,axis=
2))
#
self.failUnless(v.shape == (2,3))
#
self.failUnless(i.shape == (2,3))
#
class T_transpose(unittest.TestCase):
#
def test0(self):
# n = as
tensor(numpy.ones(()))
#
t = transpose(n)
# self.failUnless(t.owner.__class__ is TransposeI
nplace)
#
f = Function([n], [t])
#
tval = f(n.data)
#
self.failUnless(tval.shape == n.data.shape)
#
#test aliasing
#
tval += 55.0
#
self.failUnless(n.data == 1.0)
#useful mostly for unit tests
def
_approx_eq
(
a
,
b
,
eps
=
1.0e-9
):
a
=
numpy
.
asarray
(
a
)
b
=
numpy
.
asarray
(
b
)
if
a
.
shape
!=
b
.
shape
:
if
_approx_eq
.
debug
:
print
a
.
shape
,
b
.
shape
return
False
if
numpy
.
max
(
numpy
.
abs
(
a
-
b
))
>=
eps
:
if
_approx_eq
.
debug
:
print
a
,
b
return
False
return
True
_approx_eq
.
debug
=
0
def
check_eq
(
self
,
node_in
,
node_out
,
arg_in
,
arg_out
):
fn
=
Function
([
node_in
],
[
node_out
])
self
.
failUnless
(
numpy
.
all
(
fn
(
arg_in
)
==
arg_out
),
(
arg_in
,
arg_out
))
def
check_eq2
(
self
,
inputs
,
output
,
args_in
,
arg_out
):
fn
=
Function
(
inputs
,
[
output
])
val
=
fn
(
*
args_in
)
self
.
failUnless
(
numpy
.
all
(
val
==
arg_out
),
(
val
,
arg_out
))
def
check_eq2_c
(
self
,
inputs
,
output
,
args_in
,
arg_out
):
fn
=
Function
(
inputs
,
[
output
],
linker_cls
=
gof
.
CLinker
)
val
=
fn
(
*
args_in
)
self
.
failUnless
(
numpy
.
all
(
val
==
arg_out
),
(
val
,
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
))
val
=
fn
(
*
args_in
)
self
.
failUnless
(
numpy
.
all
(
val
==
arg_out
),
(
val
,
arg_out
))
class
T_argmax
(
unittest
.
TestCase
):
def
setUp
(
self
):
numpy
.
random
.
seed
(
123784
)
Argmax
.
debug
=
0
def
test0
(
self
):
n
=
as_
tensor
(
5.0
)
v
,
i
=
eval_outputs
(
argmax
(
n
))
self
.
failUnless
(
v
==
5.0
)
self
.
failUnless
(
i
==
0
)
def
test1
(
self
):
n
=
as_
tensor
([
1
,
2
,
3
,
2
,
-
6
])
v
,
i
=
eval_outputs
(
argmax
(
n
))
self
.
failUnless
(
v
==
3
)
self
.
failUnless
(
i
==
2
)
def
test2
(
self
):
n
=
as_
tensor
(
numpy
.
random
.
rand
(
2
,
3
))
v
,
i
=
eval_outputs
(
argmax
(
n
))
self
.
failUnless
(
numpy
.
all
(
i
==
[
0
,
1
]))
def
test2b
(
self
):
n
=
as_
tensor
(
numpy
.
random
.
rand
(
2
,
3
))
v
,
i
=
eval_outputs
(
argmax
(
n
,
0
))
self
.
failUnless
(
numpy
.
all
(
i
==
[
0
,
1
,
1
]))
def
test2_invalid
(
self
):
n
=
as_
tensor
(
numpy
.
random
.
rand
(
2
,
3
))
try
:
eval_outputs
(
argmax
(
n
,
3
))
except
ValueError
,
e
:
return
self
.
fail
()
def
test2_invalid_neg
(
self
):
n
=
as_
tensor
(
numpy
.
random
.
rand
(
2
,
3
))
try
:
eval_outputs
(
argmax
(
n
,
-
3
))
except
ValueError
,
e
:
return
self
.
fail
()
def
test2_valid_neg
(
self
):
n
=
as_
tensor
(
numpy
.
random
.
rand
(
2
,
3
))
v
,
i
=
eval_outputs
(
argmax
(
n
,
-
1
))
self
.
failUnless
(
v
.
shape
==
(
2
,))
v
,
i
=
eval_outputs
(
argmax
(
n
,
-
2
))
self
.
failUnless
(
v
.
shape
==
(
3
,))
def
test3
(
self
):
n
=
as_
tensor
(
numpy
.
random
.
rand
(
2
,
3
,
4
))
v
,
i
=
eval_outputs
(
argmax
(
n
,
0
))
self
.
failUnless
(
v
.
shape
==
(
3
,
4
))
self
.
failUnless
(
i
.
shape
==
(
3
,
4
))
v
,
i
=
eval_outputs
(
argmax
(
n
,
1
))
self
.
failUnless
(
v
.
shape
==
(
2
,
4
))
self
.
failUnless
(
i
.
shape
==
(
2
,
4
))
v
,
i
=
eval_outputs
(
argmax
(
n
,
2
))
self
.
failUnless
(
v
.
shape
==
(
2
,
3
))
self
.
failUnless
(
i
.
shape
==
(
2
,
3
))
class
T_transpose
(
unittest
.
TestCase
):
def
test0
(
self
):
n
=
as_
tensor
(
numpy
.
ones
(()))
t
=
transpose
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_i
nplace
)
f
=
Function
([
n
],
[
t
])
tval
=
f
(
n
.
data
)
self
.
failUnless
(
tval
.
shape
==
n
.
data
.
shape
)
#test aliasing
tval
+=
55.0
self
.
failUnless
(
n
.
data
==
1.0
)
#
def test1(self):
# n = as
tensor(numpy.ones(5))
#
t = transpose(n)
# self.failUnless(t.owner.__class__ is TransposeI
nplace)
#
f = Function([n], [t])
#
tval = f(n.data)
#
self.failUnless(tval.shape == n.data.shape)
#
#test aliasing
#
tval += 55.0
#
self.failUnless(n.data[0] == 1.0)
def
test1
(
self
):
n
=
as_
tensor
(
numpy
.
ones
(
5
))
t
=
transpose
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_i
nplace
)
f
=
Function
([
n
],
[
t
])
tval
=
f
(
n
.
data
)
self
.
failUnless
(
tval
.
shape
==
n
.
data
.
shape
)
#test aliasing
tval
+=
55.0
self
.
failUnless
(
n
.
data
[
0
]
==
1.0
)
#
def test2(self):
# n = as
tensor(numpy.ones((5,3)))
#
t = transpose(n)
# self.failUnless(t.owner.__class__ is TransposeI
nplace)
#
f = Function([n], [t])
#
tval = f(n.data)
#
self.failUnless(tval.shape == (3,5))
#
#test aliasing
#
tval += 55.0
#
self.failUnless(n.data[0,0] == 1.0)
#
def test3(self):
#
"""Test transpose of tensor, inplace version"""
# n = as
tensor(numpy.ones((5,3,2)))
#
t = transpose_inplace(n)
# self.failUnless(t.owner.__class__ is TransposeI
nplace)
#
f = Function([n], [t])
#
tval = f(n.data)
#
self.failUnless(tval.shape == (2,3,5))
#
#test aliasing
#
tval += 55.0
#
self.failUnless(n.data[0,0,0] == 56.0)
#
def test_grad(self):
# verify_grad(self, TransposeI
nplace, [numpy.random.rand(2, 3)])
# verify_grad(self, TransposeI
nplace, [numpy.ones(3)])
def
test2
(
self
):
n
=
as_
tensor
(
numpy
.
ones
((
5
,
3
)))
t
=
transpose
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_i
nplace
)
f
=
Function
([
n
],
[
t
])
tval
=
f
(
n
.
data
)
self
.
failUnless
(
tval
.
shape
==
(
3
,
5
))
#test aliasing
tval
+=
55.0
self
.
failUnless
(
n
.
data
[
0
,
0
]
==
1.0
)
def
test3
(
self
):
"""Test transpose of tensor, inplace version"""
n
=
as_
tensor
(
numpy
.
ones
((
5
,
3
,
2
)))
t
=
transpose_inplace
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_i
nplace
)
f
=
Function
([
n
],
[
t
])
tval
=
f
(
n
.
data
)
self
.
failUnless
(
tval
.
shape
==
(
2
,
3
,
5
))
#test aliasing
tval
+=
55.0
self
.
failUnless
(
n
.
data
[
0
,
0
,
0
]
==
56.0
)
def
test_grad
(
self
):
verify_grad
(
self
,
transpose_i
nplace
,
[
numpy
.
random
.
rand
(
2
,
3
)])
verify_grad
(
self
,
transpose_i
nplace
,
[
numpy
.
ones
(
3
)])
# class T_subtensor(unittest.TestCase):
# def test0_err_invalid(self):
...
...
@@ -1013,276 +1014,275 @@ verify_grad.E_grad = 'gradient error exceeded tolerance'
# def test_col(self):
# verify_grad(self, Pow, [numpy.random.rand(3, 5), numpy.random.rand(3, 1)])
# class _testCase_matinv(unittest.TestCase):
# def setUp(self):
# numpy.random.seed(1)
# def mat_reciprocal(self,dim):
# # symbolic program
# # broadcastable=[False,False] means that the shape of matrix is two dimensional,
# # and none of the dimensions are constrained to have length 1.
# # 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.
# a = Tensor('float64', broadcastable=[False,False], name='a')
# b = Tensor('float64', broadcastable=[False,False], name='b')
# ab = a*b
# # Here, astensor actually uses the data allocated by numpy.
# diff = ab - astensor(numpy.ones((dim,dim)))
# # Sum of squared errors
# ssdiff = sum((diff**2.0))
# g_b = gradient.grad(ssdiff, b)
# # compilation to function
# # [a,b] are the inputs, [ssdiff,g_b] are the outputs
# fn = Function([a,b], [ssdiff,g_b])
# # use the function
# x = numpy.random.rand(dim,dim)+0.1 # Initialized s.t. x is not too tiny
# w = numpy.random.rand(dim,dim)
# for i in xrange(300):
# ssd, gw = fn(x,w)
# #print ssd, x*w, x, w
# if i == 0:
# str0 = str(ssd)
# w -= 0.4 * gw
# return str0, str(ssd)
# def test_reciprocal(self):
# """Matrix reciprocal by gradient descent"""
# self.assertEqual(('6.10141615619', '0.00703816291711'), self.mat_reciprocal(3))
# class t_dot(unittest.TestCase):
# def setUp(self):
# numpy.random.seed(44)
# @staticmethod
# def rand(*args):
# return numpy.random.rand(*args)
# def cmp_dot(self,x,y):
# #x, y are matrices or numbers
# def spec(x):
# x = numpy.asarray(x)
# return type(x), x.dtype, x.shape
# nz = numpy.dot(x,y)
# tz = eval_outputs([dot(astensor(x), astensor(y))])
# self.failUnless(tz.dtype == nz.dtype)
# self.failUnless(tz.shape == nz.shape)
# self.failUnless(_approx_eq(nz, tz))
# 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_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_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_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_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_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_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_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 not_aligned(self, x, y):
# z = dot(x,y)
# try:
# tz = eval_outputs([z])
# except ValueError, e:
# self.failUnless(e[0].split()[1:4] == ['are', 'not', 'aligned'], e)
# return
# self.fail()
# 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_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,7))
# 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_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_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)
# #cmp_linker(copy(z), a, x, y, b, gof.cc.CLinker)
# cmp_linker(copy(z), a, x, y, b, gof.link.PerformLinker)
# def test0a(self):
# Gemm.debug = True
# try:
# g = gemm([1.], 1., [1.], [1.], 1.)
# except ValueError, e:
# if e[0] is Gemm.E_rank:
# return
# self.fail()
# def test0(self):
# try:
# self.cmp(1., 0., 1.0, 1.0, 1.0)
# except ValueError, e:
# if e[0] is Gemm.E_rank:
# return
# self.fail()
# def test2(self):
# try:
# self.cmp(2., 1.0, [3,2,1.], [[1],[2],[3.]], 1.0)
# except ValueError, e:
# self.failUnless(e[0] == Gemm.E_rank)
# return
# 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):
# """test that dot args can be aliased"""
# Z = astensor(self.rand(2,2))
# A = astensor(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]
class
_testCase_matinv
(
unittest
.
TestCase
):
def
setUp
(
self
):
numpy
.
random
.
seed
(
1
)
def
mat_reciprocal
(
self
,
dim
):
# symbolic program
# broadcastable=[False,False] means that the shape of matrix is two dimensional,
# and none of the dimensions are constrained to have length 1.
# 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.
a
,
b
=
matrices
(
'ab'
)
ab
=
a
*
b
# Here, as_tensor actually uses the data allocated by numpy.
diff
=
ab
-
as_tensor
(
numpy
.
ones
((
dim
,
dim
)))
# Sum of squared errors
ssdiff
=
sum
((
diff
**
2.0
))
g_b
=
gradient
.
grad
(
ssdiff
,
b
)
# compilation to function
# [a,b] are the inputs, [ssdiff,g_b] are the outputs
fn
=
Function
([
a
,
b
],
[
ssdiff
,
g_b
])
# use the function
x
=
numpy
.
random
.
rand
(
dim
,
dim
)
+
0.1
# Initialized s.t. x is not too tiny
w
=
numpy
.
random
.
rand
(
dim
,
dim
)
for
i
in
xrange
(
300
):
ssd
,
gw
=
fn
(
x
,
w
)
#print ssd, x*w, x, w
if
i
==
0
:
str0
=
str
(
ssd
)
w
-=
0.4
*
gw
return
str0
,
str
(
ssd
)
def
test_reciprocal
(
self
):
"""Matrix reciprocal by gradient descent"""
self
.
assertEqual
((
'6.10141615619'
,
'0.00703816291711'
),
self
.
mat_reciprocal
(
3
))
class
t_dot
(
unittest
.
TestCase
):
def
setUp
(
self
):
numpy
.
random
.
seed
(
44
)
@staticmethod
def
rand
(
*
args
):
return
numpy
.
random
.
rand
(
*
args
)
def
cmp_dot
(
self
,
x
,
y
):
#x, y are matrices or numbers
def
spec
(
x
):
x
=
numpy
.
asarray
(
x
)
return
type
(
x
),
x
.
dtype
,
x
.
shape
nz
=
numpy
.
dot
(
x
,
y
)
tz
=
eval_outputs
([
dot
(
as_tensor
(
x
),
as_tensor
(
y
))])
self
.
failUnless
(
tz
.
dtype
==
nz
.
dtype
)
self
.
failUnless
(
tz
.
shape
==
nz
.
shape
)
self
.
failUnless
(
_approx_eq
(
nz
,
tz
))
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_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_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_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_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_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_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_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
not_aligned
(
self
,
x
,
y
):
z
=
dot
(
x
,
y
)
try
:
tz
=
eval_outputs
([
z
])
except
ValueError
,
e
:
self
.
failUnless
(
e
[
0
]
.
split
()[
1
:
4
]
==
[
'are'
,
'not'
,
'aligned'
],
e
)
return
self
.
fail
()
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_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
,
7
))
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_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_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
=
[
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
))
#cmp_linker(copy(z), a, x, y, b, gof.cc.OpWiseCLinker)
#cmp_linker(copy(z), a, x, y, b, gof.cc.CLinker)
cmp_linker
(
copy
(
z
),
a
,
x
,
y
,
b
,
gof
.
link
.
PerformLinker
)
def
test0a
(
self
):
Gemm
.
debug
=
True
try
:
g
=
gemm
([
1.
],
1.
,
[
1.
],
[
1.
],
1.
)
except
ValueError
,
e
:
if
e
[
0
]
is
Gemm
.
E_rank
:
return
self
.
fail
()
def
test0
(
self
):
try
:
self
.
cmp
(
1.
,
0.
,
1.0
,
1.0
,
1.0
)
except
ValueError
,
e
:
if
e
[
0
]
is
Gemm
.
E_rank
:
return
self
.
fail
()
def
test2
(
self
):
try
:
self
.
cmp
(
2.
,
1.0
,
[
3
,
2
,
1.
],
[[
1
],[
2
],[
3.
]],
1.0
)
except
ValueError
,
e
:
self
.
failUnless
(
e
[
0
]
==
Gemm
.
E_rank
)
return
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
=
as_tensor
(
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
=
as_tensor
(
self
.
rand
(
2
,
2
))
A
=
as_tensor
(
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
=
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:
#
t(C.T, A[:2,:], B[:, :2].T)
#
except ValueError, e:
#
if e[0].find('aligned') >= 0:
#
return
#
self.fail()
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
:
t
(
C
.
T
,
A
[:
2
,:],
B
[:,
:
2
]
.
T
)
except
ValueError
,
e
:
if
e
[
0
]
.
find
(
'aligned'
)
>=
0
:
return
self
.
fail
()
...
...
_test_tensor_opt.py
浏览文件 @
6a0852fd
...
...
@@ -12,12 +12,12 @@ import scalar_opt
def
inputs
(
xbc
=
(
0
,
0
),
ybc
=
(
0
,
0
),
zbc
=
(
0
,
0
)):
x
=
Tensor
(
broadcastable
=
xbc
,
dtype
=
'float64'
,
name
=
'x'
)
y
=
Tensor
(
broadcastable
=
ybc
,
dtype
=
'float64'
,
name
=
'y'
)
z
=
Tensor
(
broadcastable
=
zbc
,
dtype
=
'float64'
,
name
=
'z'
)
x
=
Tensor
(
broadcastable
=
xbc
,
dtype
=
'float64'
)(
'x'
)
y
=
Tensor
(
broadcastable
=
ybc
,
dtype
=
'float64'
)(
'y'
)
z
=
Tensor
(
broadcastable
=
zbc
,
dtype
=
'float64'
)(
'z'
)
return
x
,
y
,
z
ds
=
gof
.
op
.
constructor
(
DimShuffle
)
ds
=
DimShuffle
class
_test_inplace_opt
(
unittest
.
TestCase
):
...
...
gof/ext.py
浏览文件 @
6a0852fd
...
...
@@ -6,14 +6,6 @@ from copy import copy
from
env
import
InconsistencyError
__all__
=
[
'Destroyer'
,
'Viewer'
,
'view_roots'
,
'DestroyHandler'
,
]
class
DestroyHandler
(
Listener
,
Constraint
,
Orderings
,
Tool
):
"""
This feature ensures that an env represents a consistent data flow
...
...
@@ -488,13 +480,14 @@ def view_roots(r):
owner
=
r
.
owner
if
owner
is
not
None
:
try
:
view_map
=
owner
.
view_map
()
except
AttributeError
,
AbstractFunctionError
:
view_map
=
owner
.
op
.
view_map
view_map
=
dict
([(
owner
.
outputs
[
o
],
i
)
for
o
,
i
in
view_map
.
items
()])
except
AttributeError
:
return
[
r
]
if
r
in
view_map
:
answer
=
[]
for
r2
in
view_map
[
r
]:
answer
+=
view_roots
(
r2
)
for
i
in
view_map
[
r
]:
answer
+=
view_roots
(
owner
.
inputs
[
i
]
)
return
answer
else
:
return
[
r
]
...
...
gof/op.py
浏览文件 @
6a0852fd
...
...
@@ -24,7 +24,11 @@ class Op(object2):
raise
AbstractFunctionError
()
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
#########################
...
...
gof/opt.py
浏览文件 @
6a0852fd
...
...
@@ -396,8 +396,14 @@ class _metadict:
return
self
.
d
[
item
]
except
:
for
item2
,
value
in
self
.
l
:
if
item
==
item2
:
return
value
try
:
if
item
==
item2
:
return
value
if
item
.
equals
(
item2
):
return
value
except
:
if
item
is
item2
:
return
value
else
:
return
default
def
clear
(
self
):
...
...
tensor.py
浏览文件 @
6a0852fd
...
...
@@ -36,6 +36,9 @@ def as_tensor(x, name = None):
except
TypeError
:
raise
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
):
...
...
@@ -226,6 +229,9 @@ class Tensor(Type):
# Easy constructors
def
tensor
(
*
args
):
return
Tensor
(
*
args
)
.
make_result
()
def
_multi
(
*
fns
):
def
f2
(
f
,
names
):
if
len
(
names
)
==
1
:
...
...
@@ -347,115 +353,39 @@ s2t.TensorConstant = TensorConstant
# 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
##########################
class
Argmax
(
Op
):
"""Calculate the max and argmax over a given axis"""
nin
=
2
# tensor, axis
nout
=
2
# max val, max idx
E_axis
=
'invalid axis'
def
make_node
(
self
,
x
,
axis
=
None
):
x
=
_as_tensor
(
x
)
if
axis
is
None
:
axis
=
x
.
type
.
ndim
-
1
axis
=
_as_tensor
(
axis
)
inputs
=
[
x
,
axis
]
broadcastable
=
[
False
]
*
(
x
.
type
.
ndim
-
1
)
outputs
=
[
tensor
(
x
.
type
.
dtype
,
broadcastable
),
tensor
(
axis
.
type
.
dtype
,
broadcastable
)]
return
Apply
(
self
,
inputs
,
outputs
)
def
perform
(
self
,
node
,
(
x
,
axis
),
(
max
,
max_idx
)):
max
[
0
]
=
numpy
.
max
(
x
,
axis
)
max_idx
[
0
]
=
numpy
.
argmax
(
x
,
axis
)
argmax
=
Argmax
()
# def broadcast(scalar_opclass, name, module_name = None, inplace_versions = True):
# C = s2t.make_broadcast(scalar_opclass, name = name, module_name = module_name) # this returns a class
# C.__module__ = module_name
# c = gof.op.constructor(s2t.wrap_broadcast(C))
# if inplace_versions:
# CInplace = s2t.make_broadcast(scalar_opclass, {0:0}, name = name+"Inplace")
# CInplace.__module__ = module_name
# c_inplace = gof.op.constructor(s2t.wrap_broadcast(CInplace))
# return C, c, CInplace, c_inplace
# else:
# return C, c
# def _broadcast(scalar_opclass, name, inplace_versions = True):
# return broadcast(scalar_opclass, name, 'tensor', inplace_versions)
def
max
(
x
,
axis
=
None
):
"""Return maximum elements obtained by iterating over given axis
# class Argmax(Op):
# """Calculate the max and argmax over a given axis"""
# nin=2 # tensor, axis
# nout=2 # max val, max idx
# E_axis = 'invalid axis'
# debug = 0
# def __init__(self, x, axis=None):
# x = _as_tensor(x)
# if axis is None:
# axis = len(x.broadcastable) -1
# axis = _as_tensor(axis)
# self.inputs = [x, axis]
# broadcastable = [0] * (len(x.broadcastable) - 1)
# 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]
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
):
...
...
@@ -508,7 +438,8 @@ pow, pow_inplace = _elemwise(scal.pow, 'pow')
##########################
class
TransposeInplace
(
Op
):
view_map
=
{
0
:
[
0
]}
def
make_node
(
self
,
input
):
return
Apply
(
self
,
[
input
],
[
input
.
type
()])
...
...
@@ -531,32 +462,24 @@ transpose_inplace = TransposeInplace()
def
transpose
(
x
,
**
kwargs
):
return
transpose_inplace
(
tensor_copy
(
x
),
**
kwargs
)
# class Subtensor(Op
, Viewer
):
# class Subtensor(Op):
# nin = 2
# nout = 1
# e_invalid = 'invalid index'
#
debug = 0
# def
__init__(self, *args,**kwarg
s):
#
view_map = {0: [0]}
# def
make_node(self, *input
s):
# def as_tuple_result(obj):
# if isinstance(obj, Result):
# if isinstance(obj,
gof.
Result):
# return obj
# r = gof.result.PythonResult(None)
# if isinstance(obj, tuple):
# r.data = obj
# else:
# r.data = (obj,)
# assert isinstance(obj, (list, tuple))
# r = gof.Constant(gof.generic, obj)
# return r
# def pad(tplR, N):
# l = list(tplR.data)
# for i in range(len(l), N):
# l.append(slice(0,sys.maxint,1))
# 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)
# # def pad(tplR, N):
# # l = list(tplR.data)
# # for i in range(len(l), N):
# # l.append(slice(0,sys.maxint,1))
# # tplR.data = tuple(l)
# t, coord = args
# t = _as_tensor(t)
# coord = as_tuple_result(coord)
...
...
@@ -564,26 +487,17 @@ def transpose(x, **kwargs):
# raise ValueError(Subtensor.e_invalid)
# # add the implicit extra unbounded slices
# # e.g. n[0] on a 3d tensor pads to n[0,:,:]
# pad(coord, len(t.broadcastable))
# broadcastable = [0 for c in coord.data if isinstance(c, slice)]
# if Subtensor.debug:
# print 'brdcstble', broadcastable
# print 't', t.data
# print 'coord', coord.data
# ###pad(coord, len(t.broadcastable))
# broadcastable = [False for c in coord.data if isinstance(c, slice)]
# self.inputs = [t, coord]
# self.outputs = [Tensor(t.dtype, broadcastable)]
# def view_map(self):
# return {self.out: [self.inputs[0]]}
# def perform(self):
# x = self.inputs[0].data
# c = self.inputs[1].data
# if Subtensor.debug:
# print 'perform: x', x
# print 'perform: c', c
# def perform(self, node, (x, c), (out, )):
# if len(c) == 1:
#
self.outputs[0].data
= x.__getitem__(c[0])
#
out[0]
= x.__getitem__(c[0])
# else:
#
self.outputs[0].data
= x.__getitem__(c)
#
out[0]
= x.__getitem__(c)
# def grad(self, (x,), (gz,)):
# # - option: allocate a potentially large matrix of zeros, and fill in
# # the appropriate elements from gz
...
...
@@ -591,7 +505,7 @@ def transpose(x, **kwargs):
# # - option: return gz, but think about how to include a special addition
# # function that works on a corresponding view of the original data
# raise NotImplementedError()
# subtensor =
gof.op.constructor(Subtensor
)
# subtensor =
Subtensor(
)
#########################
...
...
@@ -599,8 +513,6 @@ def transpose(x, **kwargs):
#########################
class
Dot
(
Op
):
# nin=2
# nout=1
def
make_node
(
self
,
*
inputs
):
inputs
=
map
(
as_tensor
,
inputs
)
if
len
(
inputs
)
!=
2
:
...
...
@@ -608,9 +520,6 @@ class Dot(Op):
i_broadcastables
=
[
input
.
type
.
broadcastable
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
if
len
(
bx
)
==
0
:
# x is a scalar
bz
=
by
...
...
@@ -624,7 +533,7 @@ class Dot(Op):
o_broadcastables
=
[
bz
]
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
)
def
perform
(
self
,
node
,
(
x
,
y
),
(
z
,
)):
...
...
@@ -633,228 +542,222 @@ class Dot(Op):
return
dot
(
gz
,
y
.
T
),
dot
(
x
.
T
,
gz
)
dot
=
Dot
()
# class Gemm(_Op):
# nin=5
# nout=1
# E_rank = 'gemm only works for rank 2'
# E_scalar = 'gemm requires scalar argument'
# E_z_uniq = 'argument z aliased to x or y'
# debug = False
# def __init__(self, *args, **kwargs):
# _Op.__init__(self, *args, **kwargs)
# z, a, x, y, b = self.inputs
# zr, xr, yr = [set(gof.view_roots(i)) for i in z,x,y]
# if zr.intersection(xr):
# raise ValueError(Gemm.E_z_uniq, (z, x))
# if zr.intersection(yr):
# raise ValueError(Gemm.E_z_uniq, (z, y))
# def destroy_map(self):
# return {self.out:[self.inputs[0]]}
# def propagate_broadcastable(self, bz, ba, bx, by, bb):
# if len(bz) != 2: raise ValueError(Gemm.E_rank, len(bz))
# if len(bx) != 2: raise ValueError(Gemm.E_rank, len(bx))
# if len(by) != 2: raise ValueError(Gemm.E_rank, len(by))
# if len(ba): raise ValueError(Gemm.E_scalar, ba)
# if len(bb): raise ValueError(Gemm.E_scalar, bb)
# return [bz]
# def impl(self, z, a, x, y, b):
# assert a.shape == ()
# assert b.shape == ()
# if z.shape == ():
# z.itemset(z*a + b*numpy.dot(x,y))
# return z
# else:
# if b == 0.0:
# if a == 1.0:
# z[:] = numpy.dot(x,y)
# elif a == -1.0:
# z[:] = -numpy.dot(x,y)
# else:
# z[:] = a * numpy.dot(x,y)
# elif b == 1.0:
# if a == 1.0:
# z += numpy.dot(x,y)
# elif a == -1.0:
# z -= numpy.dot(x,y)
# else:
# z += a * numpy.dot(x,y)
# else:
# z *= b
# z += a * numpy.dot(x,y)
# return z
# 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_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)
class
Gemm
(
Op
):
E_rank
=
'gemm only works for rank 2'
E_scalar
=
'gemm requires scalar argument'
E_z_uniq
=
'argument z aliased to x or y'
destroy_map
=
{
0
:
[
0
]}
def
make_node
(
self
,
*
inputs
):
inputs
=
map
(
as_tensor
,
inputs
)
if
len
(
inputs
)
!=
5
:
raise
TypeError
(
"Wrong number of inputs for
%
s (expected 5, got
%
s)"
%
(
self
,
len
(
inputs
)))
z
,
a
,
x
,
y
,
b
=
inputs
zr
,
xr
,
yr
=
[
set
(
gof
.
view_roots
(
i
))
for
i
in
z
,
x
,
y
]
if
zr
.
intersection
(
xr
):
raise
ValueError
(
Gemm
.
E_z_uniq
,
(
z
,
x
))
if
zr
.
intersection
(
yr
):
raise
ValueError
(
Gemm
.
E_z_uniq
,
(
z
,
y
))
bz
,
ba
,
bx
,
by
,
bb
=
[
r
.
type
.
broadcastable
for
r
in
inputs
]
if
len
(
bz
)
!=
2
:
raise
ValueError
(
Gemm
.
E_rank
,
len
(
bz
))
if
len
(
bx
)
!=
2
:
raise
ValueError
(
Gemm
.
E_rank
,
len
(
bx
))
if
len
(
by
)
!=
2
:
raise
ValueError
(
Gemm
.
E_rank
,
len
(
by
))
if
len
(
ba
):
raise
ValueError
(
Gemm
.
E_scalar
,
ba
)
if
len
(
bb
):
raise
ValueError
(
Gemm
.
E_scalar
,
bb
)
output
=
z
.
type
()
return
Apply
(
self
,
inputs
,
[
output
])
def
perform
(
self
,
node
,
(
z
,
a
,
x
,
y
,
b
),
(
zout
,
)):
assert
a
.
shape
==
()
assert
b
.
shape
==
()
if
z
.
shape
==
():
z
.
itemset
(
z
*
a
+
b
*
numpy
.
dot
(
x
,
y
))
zout
[
0
]
=
z
else
:
if
b
==
0.0
:
if
a
==
1.0
:
z
[:]
=
numpy
.
dot
(
x
,
y
)
elif
a
==
-
1.0
:
z
[:]
=
-
numpy
.
dot
(
x
,
y
)
else
:
z
[:]
=
a
*
numpy
.
dot
(
x
,
y
)
elif
b
==
1.0
:
if
a
==
1.0
:
z
+=
numpy
.
dot
(
x
,
y
)
elif
a
==
-
1.0
:
z
-=
numpy
.
dot
(
x
,
y
)
else
:
z
+=
a
*
numpy
.
dot
(
x
,
y
)
else
:
z
*=
b
z
+=
a
*
numpy
.
dot
(
x
,
y
)
zout
[
0
]
=
z
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;
}
"""
%
dict
(
locals
(),
**
sub
)
gemm
=
Gemm
()
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论