Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
ea32b4db
提交
ea32b4db
authored
5月 05, 2008
作者:
Olivier Breuleux
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
too many things to list
上级
d2cf55aa
显示空白字符变更
内嵌
并排
正在显示
19 个修改的文件
包含
1532 行增加
和
1125 行删除
+1532
-1125
_test_compile.py
_test_compile.py
+197
-115
_test_gradient.py
_test_gradient.py
+103
-93
_test_sparse.py
_test_sparse.py
+147
-147
_test_tensor.py
_test_tensor.py
+321
-320
_test_cc.py
gof/_test_cc.py
+7
-1
_test_ext.py
gof/_test_ext.py
+1
-2
_test_graph.py
gof/_test_graph.py
+3
-3
_test_link.py
gof/_test_link.py
+13
-7
_test_opt.py
gof/_test_opt.py
+0
-1
cc.py
gof/cc.py
+34
-13
env.py
gof/env.py
+15
-211
ext.py
gof/ext.py
+5
-13
graph.py
gof/graph.py
+58
-42
link.py
gof/link.py
+9
-5
opt.py
gof/opt.py
+11
-7
toolbox.py
gof/toolbox.py
+45
-0
scalar.py
scalar.py
+5
-8
sparse.py
sparse.py
+543
-130
tensor.py
tensor.py
+15
-7
没有找到文件。
_test_compile.py
浏览文件 @
ea32b4db
import
unittest
import
unittest
import
gof
,
gof
.
modes
,
gof
.
opt
import
gof
,
gof
.
opt
import
compile
from
compile
import
*
from
compile
import
*
from
scalar
import
*
import
tensor
class
Double
(
gof
.
result
.
Result
):
#
class Double(gof.result.Result):
def
__init__
(
self
,
data
,
name
=
"oignon"
):
#
def __init__(self, data, name = "oignon"):
assert
isinstance
(
data
,
float
)
#
assert isinstance(data, float)
gof
.
result
.
Result
.
__init__
(
self
,
role
=
None
,
name
=
name
)
#
gof.result.Result.__init__(self, role = None, name = name)
self
.
data
=
data
#
self.data = data
def
__str__
(
self
):
#
def __str__(self):
return
self
.
name
#
return self.name
def
__repr__
(
self
):
#
def __repr__(self):
return
self
.
name
#
return self.name
def
__copy__
(
self
):
#
def __copy__(self):
return
self
.
__class__
(
self
.
data
,
self
.
name
)
#
return self.__class__(self.data, self.name)
class
MyOp
(
gof
.
op
.
Op
):
#
class MyOp(gof.op.Op):
nin
=
-
1
#
nin = -1
def
__init__
(
self
,
*
inputs
):
#
def __init__(self, *inputs):
assert
len
(
inputs
)
==
self
.
nin
#
assert len(inputs) == self.nin
for
input
in
inputs
:
#
for input in inputs:
if
not
isinstance
(
input
,
Double
):
#
if not isinstance(input, Double):
raise
Exception
(
"Error 1"
)
#
raise Exception("Error 1")
self
.
inputs
=
inputs
#
self.inputs = inputs
self
.
outputs
=
[
Double
(
0.0
,
self
.
__class__
.
__name__
+
"_R"
)]
#
self.outputs = [Double(0.0, self.__class__.__name__ + "_R")]
def
perform
(
self
):
#
def perform(self):
self
.
outputs
[
0
]
.
data
=
self
.
impl
(
*
[
input
.
data
for
input
in
self
.
inputs
])
#
self.outputs[0].data = self.impl(*[input.data for input in self.inputs])
class
Unary
(
MyOp
):
#
class Unary(MyOp):
nin
=
1
#
nin = 1
class
Binary
(
MyOp
):
#
class Binary(MyOp):
nin
=
2
#
nin = 2
class
Add
(
Binary
):
#
class Add(Binary):
def
impl
(
self
,
x
,
y
):
#
def impl(self, x, y):
return
x
+
y
#
return x + y
class
Sub
(
Binary
):
#
class Sub(Binary):
def
impl
(
self
,
x
,
y
):
#
def impl(self, x, y):
return
x
-
y
#
return x - y
class
Mul
(
Binary
):
#
class Mul(Binary):
def
impl
(
self
,
x
,
y
):
#
def impl(self, x, y):
return
x
*
y
#
return x * y
class
Div
(
Binary
):
#
class Div(Binary):
def
impl
(
self
,
x
,
y
):
#
def impl(self, x, y):
return
x
/
y
#
return x / y
def
env
(
inputs
,
outputs
,
validate
=
True
,
features
=
[]):
#
def env(inputs, outputs, validate = True, features = []):
return
gof
.
env
.
Env
(
inputs
,
outputs
,
features
=
features
,
consistency_check
=
validate
)
#
return gof.env.Env(inputs, outputs, features = features, consistency_check = validate)
def
perform_linker
(
env
):
#
def perform_linker(env):
lnk
=
gof
.
link
.
PerformLinker
(
env
)
#
lnk = gof.link.PerformLinker(env)
return
lnk
#
return lnk
def
graph1
():
# (x+y) * (x/z)
#
def graph1(): # (x+y) * (x/z)
x
=
gof
.
modes
.
build
(
Double
(
1.0
,
'x'
))
#
x = gof.modes.build(Double(1.0, 'x'))
y
=
gof
.
modes
.
build
(
Double
(
3.0
,
'y'
))
#
y = gof.modes.build(Double(3.0, 'y'))
z
=
gof
.
modes
.
build
(
Double
(
4.0
,
'z'
))
#
z = gof.modes.build(Double(4.0, 'z'))
o
=
Mul
(
Add
(
x
,
y
)
.
out
,
Div
(
x
,
z
)
.
out
)
.
out
#
o = Mul(Add(x, y).out, Div(x, z).out).out
return
[
x
,
y
,
z
],
[
o
]
#
return [x,y,z], [o]
def
graph1
():
# (x+y) * (x/z)
x
,
y
,
z
=
floats
(
'xyz'
)
o
=
mul
(
add
(
x
,
y
),
div
(
x
,
z
))
return
[
x
,
y
,
z
],
[
o
]
class
T_what
:
def
test_nothing
(
self
):
pass
class
T_Function
(
unittest
.
TestCase
):
class
T_Function
(
unittest
.
TestCase
):
def
test_noopt
(
self
):
def
test_noopt
(
self
):
gi
,
go
=
graph1
()
gi
,
go
=
graph1
()
p
=
Function
(
gi
,
go
)
p
=
function
(
gi
,
go
,
optimizer
=
None
,
linker
=
'py'
)
self
.
failUnless
(
p
(
1.0
,
3.0
,
4.0
)
==
1.0
)
self
.
failUnless
(
p
(
1.0
,
3.0
,
4.0
)
==
1.0
)
# def test_link_noopt(self):
# gi, go = graph1()
# fn, i, o = perform_linker(env(gi, go)).make_thunk(True)
# fn()
# self.failUnless(go[0].data == 1.0)
# def test_link_opt(self):
# opt = gof.opt.PatternOptimizer((Div, '1', '2'), (Div, '2', '1'))
# gi, go = graph1()
# e = env(gi, go)
# opt.optimize(e)
# fn, i, o = perform_linker(e).make_thunk(True)
# fn()
# self.failUnless(go[0].data == 16.0)
def
test_link_noopt
(
self
):
gi
,
go
=
graph1
()
fn
,
i
,
o
=
perform_linker
(
env
(
gi
,
go
))
.
make_thunk
(
True
)
fn
()
self
.
failUnless
(
go
[
0
]
.
data
==
1.0
)
def
test_link_opt
(
self
):
opt
=
gof
.
opt
.
PatternOptimizer
((
Div
,
'1'
,
'2'
),
(
Div
,
'2'
,
'1'
))
gi
,
go
=
graph1
()
e
=
env
(
gi
,
go
)
opt
.
optimize
(
e
)
fn
,
i
,
o
=
perform_linker
(
e
)
.
make_thunk
(
True
)
fn
()
self
.
failUnless
(
go
[
0
]
.
data
==
16.0
)
def
test_opt
(
self
):
def
test_opt
(
self
):
opt
=
gof
.
opt
.
PatternOptimizer
((
Div
,
'1'
,
'2'
),
(
D
iv
,
'2'
,
'1'
))
opt
=
gof
.
opt
.
PatternOptimizer
((
div
,
'1'
,
'2'
),
(
d
iv
,
'2'
,
'1'
))
gi
,
go
=
graph1
()
gi
,
go
=
graph1
()
p
=
Function
(
gi
,
go
,
optimizer
=
opt
.
optimize
)
p
=
function
(
gi
,
go
,
optimizer
=
opt
.
optimize
,
linker
=
'py'
)
self
.
failUnless
(
p
(
1.
,
3.
,
4.
)
==
16.0
)
self
.
failUnless
(
p
(
1.
,
3.
,
4.
)
==
16.0
)
def
test_multiout
(
self
):
def
test_multiout
(
self
):
def
graph2
():
def
graph2
():
x
=
gof
.
modes
.
build
(
Double
(
1.0
,
'x'
))
x
,
y
,
z
=
floats
(
'xyz'
)
y
=
gof
.
modes
.
build
(
Double
(
3.0
,
'y'
))
o
=
mul
(
add
(
x
,
y
),
div
(
x
,
z
))
z
=
gof
.
modes
.
build
(
Double
(
4.0
,
'z'
))
o
=
Mul
(
Add
(
x
,
y
)
.
out
,
Div
(
x
,
z
)
.
out
)
.
out
return
[
x
,
y
,
z
],
[
o
,
o
.
owner
.
inputs
[
1
]]
return
[
x
,
y
,
z
],
[
o
,
o
.
owner
.
inputs
[
1
]]
opt
=
gof
.
opt
.
PatternOptimizer
((
Div
,
'1'
,
'2'
),
(
D
iv
,
'2'
,
'1'
))
opt
=
gof
.
opt
.
PatternOptimizer
((
div
,
'1'
,
'2'
),
(
d
iv
,
'2'
,
'1'
))
gi
,
go
=
graph2
()
gi
,
go
=
graph2
()
p
=
F
unction
(
gi
,
go
,
optimizer
=
opt
.
optimize
)
p
=
f
unction
(
gi
,
go
,
optimizer
=
opt
.
optimize
)
a
,
b
=
p
(
1.
,
3.
,
4.
)
a
,
b
=
p
(
1.
,
3.
,
4.
)
self
.
failUnless
(
a
==
16.0
)
self
.
failUnless
(
a
==
16.0
)
self
.
failUnless
(
b
==
4.0
)
self
.
failUnless
(
b
==
4.0
)
def
test_orphans
(
self
):
def
test_make_many_functions
(
self
):
gi
,
go
=
graph1
()
x
,
y
,
z
=
tensor
.
scalars
(
'xyz'
)
opt
=
None
e0
,
e1
,
e2
=
x
+
y
+
z
,
x
*
y
-
z
,
z
*
z
+
x
*
x
+
y
*
y
p0
=
Function
(
gi
[
0
:
0
],
go
)
f1
=
function
([
x
,
y
,
z
],
[
e0
])
f2
=
function
([
x
,
y
,
z
],
[
e0
])
self
.
failUnless
(
p0
()
==
1.0
)
f3
=
function
([
x
,
y
,
z
],
[
e1
])
f4
=
function
([
x
,
y
,
z
],
[
e2
])
p3
=
Function
(
gi
,
go
)
f5
=
function
([
e0
],
[
e0
*
e0
])
p2
=
Function
(
gi
[
0
:
2
],
go
)
ff
=
FunctionFactory
([
x
,
y
,
z
],
[
e0
])
p1
=
Function
(
gi
[
0
:
1
],
go
)
f6
=
ff
.
create
()
try
:
f7
=
ff
.
create
()
self
.
failUnless
(
p3
()
==
6.0
)
f8
=
ff
.
create
()
self
.
fail
()
f9
=
ff
.
partial
(
1.0
,
2.0
)
except
TypeError
,
e
:
assert
f1
(
1.0
,
2.0
,
3.0
)
==
6.0
self
.
failUnless
(
e
[
0
]
.
split
()[
0
:
3
]
==
[
'Function'
,
'call'
,
'takes'
])
assert
f2
(
1.0
,
2.0
,
3.0
)
==
6.0
assert
f3
(
1.0
,
2.0
,
3.0
)
==
-
1.0
self
.
failUnless
(
p3
(
1.
,
3.
,
4.
)
==
1.0
)
assert
f4
(
1.0
,
2.0
,
3.0
)
==
14.0
self
.
failUnless
(
p2
(
1.
,
3.
)
==
1.0
)
assert
f5
(
7.0
)
==
49.0
self
.
failUnless
(
p1
(
1.
,)
==
1.0
)
assert
f6
(
1.0
,
2.0
,
3.0
)
==
6.0
assert
f7
(
1.0
,
2.0
,
3.0
)
==
6.0
assert
f8
(
1.0
,
2.0
,
3.0
)
==
6.0
def
test_some_constant_outputs
(
self
):
assert
f9
(
3.0
)
==
6.0
x
=
gof
.
modes
.
build
(
Double
(
1.0
,
'x'
))
y
=
gof
.
modes
.
build
(
Double
(
3.0
,
'y'
))
def
test_no_inputs
(
self
):
z
=
gof
.
modes
.
build
(
Double
(
4.0
,
'z'
))
x
,
y
,
z
=
tensor
.
value
(
1.0
),
tensor
.
value
(
2.0
),
tensor
.
value
(
3.0
)
xy
=
Mul
(
x
,
y
)
.
out
e
=
x
*
x
+
y
*
y
+
z
*
z
zz
=
Mul
(
z
,
z
)
.
out
assert
function
([],
[
e
],
linker
=
'py'
)()
==
14.0
assert
function
([],
[
e
],
linker
=
'c'
)()
==
14.0
p0
=
Function
([
x
,
y
],
[
xy
,
zz
])
assert
function
([],
[
e
],
linker
=
'c|py'
)()
==
14.0
self
.
failUnless
(
p0
(
1.
,
3.
)
==
[
3.0
,
16.0
])
assert
function
([],
[
e
],
linker
=
'c&py'
)()
==
14.0
self
.
failUnless
(
p0
(
1.5
,
4.
)
==
[
6.0
,
16.0
])
assert
eval_outputs
([
e
])
==
14.0
self
.
failUnless
(
x
.
data
==
1.0
)
assert
fast_compute
(
e
)
==
14.0
self
.
failUnless
(
y
.
data
==
3.0
)
self
.
failUnless
(
z
.
data
==
4.0
)
def
test_borrow_true
(
self
):
x
,
y
,
z
=
tensor
.
scalars
(
'xyz'
)
p1
=
Function
([
z
],
[
xy
,
zz
],
unpack_single
=
False
)
e
=
x
+
y
+
z
self
.
failUnless
(
p1
(
4.
)
==
[
3.0
,
16.0
])
#returns 6.0, 16.10
f
=
function
([
x
,
y
,
z
],
[
e
],
borrow_outputs
=
True
)
self
.
failUnless
(
p1
(
5.
)
==
[
3.0
,
25.0
])
res1
=
f
(
1.0
,
2.0
,
3.0
)
assert
res1
==
6.0
res2
=
f
(
1.0
,
3.0
,
5.0
)
assert
res1
is
res2
assert
res1
==
9.0
assert
res2
==
9.0
def
test_borrow_false
(
self
):
x
,
y
,
z
=
tensor
.
scalars
(
'xyz'
)
e
=
x
+
y
+
z
for
linker
in
'py c c|py c&py'
.
split
():
f
=
function
([
x
,
y
,
z
],
[
e
],
borrow_outputs
=
False
,
linker
=
linker
)
res1
=
f
(
1.0
,
2.0
,
3.0
)
self
.
failUnless
(
res1
==
6.0
,
(
res1
,
linker
))
res2
=
f
(
1.0
,
3.0
,
5.0
)
self
.
failUnless
(
res1
is
not
res2
,
(
res1
,
res2
,
linker
))
self
.
failUnless
(
res1
==
6.0
,
(
res1
,
linker
))
self
.
failUnless
(
res2
==
9.0
,
(
res2
,
linker
))
def
test_borrow_false_through_inplace
(
self
):
x
,
y
,
z
=
tensor
.
scalars
(
'xyz'
)
# if borrow_outputs is False, we must not reuse the temporary created for x+y
e
=
tensor
.
add_inplace
(
x
+
y
,
z
)
for
linker
in
'py c c|py c&py'
.
split
():
f
=
function
([
x
,
y
,
z
],
[
e
],
borrow_outputs
=
False
,
linker
=
linker
)
res1
=
f
(
1.0
,
2.0
,
3.0
)
self
.
failUnless
(
res1
==
6.0
,
(
res1
,
linker
))
res2
=
f
(
1.0
,
3.0
,
5.0
)
self
.
failUnless
(
res1
is
not
res2
,
(
res1
,
res2
,
linker
))
self
.
failUnless
(
res1
==
6.0
,
(
res1
,
linker
))
self
.
failUnless
(
res2
==
9.0
,
(
res2
,
linker
))
class
T_fast_compute
(
unittest
.
TestCase
):
def
test_straightforward
(
self
):
x
,
y
,
z
=
tensor
.
value
(
1.0
),
tensor
.
value
(
2.0
),
tensor
.
value
(
3.0
)
e
=
x
*
x
+
y
*
y
+
z
*
z
assert
fast_compute
(
e
)
==
14.0
assert
compile
.
_fcache
[(
e
,
)]()
==
14.0
# def test_orphans(self):
# gi, go = graph1()
# opt = None
# p0 = function(gi[0:0], go, optimizer = None, linker = 'py')
# self.failUnless(p0() == 1.0)
# p3 = Function(gi,go)
# p2 = Function(gi[0:2], go)
# p1 = Function(gi[0:1], go)
# try:
# self.failUnless(p3() == 6.0)
# self.fail()
# except TypeError, e:
# self.failUnless(e[0].split()[0:3] == ['Function','call', 'takes'])
# self.failUnless(p3(1.,3.,4.) == 1.0)
# self.failUnless(p2(1.,3.) == 1.0)
# self.failUnless(p1(1.,) == 1.0)
# def test_some_constant_outputs(self):
# x = gof.modes.build(Double(1.0, 'x'))
# y = gof.modes.build(Double(3.0, 'y'))
# z = gof.modes.build(Double(4.0, 'z'))
# xy = Mul(x,y).out
# zz = Mul(z,z).out
# p0 = Function([x,y], [xy, zz])
# self.failUnless(p0(1.,3.) == [3.0,16.0])
# self.failUnless(p0(1.5,4.) == [6.0,16.0])
# self.failUnless(x.data == 1.0)
# self.failUnless(y.data == 3.0)
# self.failUnless(z.data == 4.0)
# p1 = Function([z], [xy, zz],unpack_single=False)
# self.failUnless(p1(4.) == [3.0,16.0]) #returns 6.0, 16.10
# self.failUnless(p1(5.) == [3.0,25.0])
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
_test_gradient.py
浏览文件 @
ea32b4db
...
@@ -13,12 +13,13 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -13,12 +13,13 @@ class _test_grad_sources_inputs(unittest.TestCase):
def
test_retNone1
(
self
):
def
test_retNone1
(
self
):
"""Test that it is not ok to return None from op.grad()"""
"""Test that it is not ok to return None from op.grad()"""
class
retNone
(
gof
.
op
.
Op
):
class
retNone
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
):
def
make_node
(
self
):
self
.
inputs
=
[
gof
.
result
.
Result
()]
inputs
=
[
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
()]
outputs
=
[
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
pass
pass
a
=
retNone
(
5
)
a
=
retNone
(
)
.
make_node
(
)
try
:
try
:
grad_sources_inputs
([(
a
.
out
,
1
)],
None
)
grad_sources_inputs
([(
a
.
out
,
1
)],
None
)
except
ValueError
,
e
:
except
ValueError
,
e
:
...
@@ -28,30 +29,30 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -28,30 +29,30 @@ class _test_grad_sources_inputs(unittest.TestCase):
def
test_retNone1_b
(
self
):
def
test_retNone1_b
(
self
):
"""Test that it is ok to return [None] from op.grad()"""
"""Test that it is ok to return [None] from op.grad()"""
class
retNone
(
gof
.
op
.
Op
):
class
retNone
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
):
def
make_node
(
self
,
*
inputs
):
self
.
inputs
=
arg
outputs
=
[
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
return
[
None
]
return
[
None
]
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
a
=
retNone
(
[
i
]
)
a
=
retNone
(
)
.
make_node
(
i
)
g
=
grad_sources_inputs
([(
a
.
out
,
1
)],
None
)
g
=
grad_sources_inputs
([(
a
.
out
,
1
)],
None
)
self
.
failUnless
(
not
i
in
g
)
self
.
failUnless
(
not
i
in
g
)
def
test_wrong_rval_len1
(
self
):
def
test_wrong_rval_len1
(
self
):
"""Test that it is not ok to return the wrong number of gradients"""
"""Test that it is not ok to return the wrong number of gradients"""
class
retNone
(
gof
.
op
.
Op
):
class
retNone
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
):
def
make_node
(
self
,
*
inputs
):
self
.
inputs
=
arg
outputs
=
[
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
inputs
,
(
gz
,
)):
def
grad
(
self
,
inputs
,
(
gz
,
)):
return
[
None
]
return
[
None
]
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
j
=
gof
.
result
.
Result
()
j
=
gof
.
generic
()
a1
=
retNone
(
[
i
]
)
a1
=
retNone
(
)
.
make_node
(
i
)
g
=
grad_sources_inputs
([(
a1
.
out
,
1
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
out
,
1
)],
None
)
a2
=
retNone
(
[
i
,
j
]
)
a2
=
retNone
(
)
.
make_node
(
i
,
j
)
try
:
try
:
g
=
grad_sources_inputs
([(
a2
.
out
,
1
)],
None
)
g
=
grad_sources_inputs
([(
a2
.
out
,
1
)],
None
)
except
ValueError
,
e
:
except
ValueError
,
e
:
...
@@ -63,118 +64,126 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -63,118 +64,126 @@ class _test_grad_sources_inputs(unittest.TestCase):
def
test_stop_on_all_none
(
self
):
def
test_stop_on_all_none
(
self
):
"""Test that op.grad() is not called when output grads are all None"""
"""Test that op.grad() is not called when output grads are all None"""
class
retNone
(
gof
.
op
.
Op
):
class
retNone
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
,
tst
):
def
__init__
(
self
,
tst
):
self
.
inputs
=
arg
self
.
outputs
=
[
gof
.
result
.
Result
()]
self
.
tst
=
tst
self
.
tst
=
tst
def
make_node
(
self
,
*
inputs
):
outputs
=
[
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
inputs
,
(
gz
,
)):
def
grad
(
self
,
inputs
,
(
gz
,
)):
self
.
tst
.
fail
()
self
.
tst
.
fail
()
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
a1
=
retNone
(
[
i
],
self
)
a1
=
retNone
(
self
)
.
make_node
(
i
)
g
=
grad_sources_inputs
([(
a1
.
out
,
None
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
out
,
None
)],
None
)
def
test_1in_1out
(
self
):
def
test_1in_1out
(
self
):
"""Test grad is called correctly for a 1-to-1 op"""
"""Test grad is called correctly for a 1-to-1 op"""
gval
=
gof
.
result
.
Result
()
gval
=
gof
.
generic
()
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
):
def
make_node
(
self
):
self
.
inputs
=
[
gof
.
result
.
Result
()]
inputs
=
[
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
()]
outputs
=
[
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
return
gval
,
return
gval
,
a1
=
O
()
a1
=
O
()
.
make_node
()
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval
)
def
test_1in_Nout
(
self
):
def
test_1in_Nout
(
self
):
"""Test grad is called correctly for a 1-to-many op"""
"""Test grad is called correctly for a 1-to-many op"""
gval
=
gof
.
result
.
Result
()
gval
=
gof
.
generic
()
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
):
def
make_node
(
self
):
self
.
inputs
=
[
gof
.
result
.
Result
()]
inputs
=
[
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x
,
),
(
gz1
,
gz2
)):
def
grad
(
self
,
(
x
,
),
(
gz1
,
gz2
)):
return
gval
,
return
gval
,
a1
=
O
()
a1
=
O
()
.
make_node
()
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval
)
def
test_Nin_1out
(
self
):
def
test_Nin_1out
(
self
):
"""Test grad is called correctly for a many-to-1 op"""
"""Test grad is called correctly for a many-to-1 op"""
gval0
=
gof
.
result
.
Result
()
gval0
=
gof
.
generic
()
gval1
=
gof
.
result
.
Result
()
gval1
=
gof
.
generic
()
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
):
def
make_node
(
self
):
self
.
inputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
inputs
=
[
gof
.
generic
(),
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
()]
outputs
=
[
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x0
,
x1
),
(
gz
,
)):
def
grad
(
self
,
(
x0
,
x1
),
(
gz
,
)):
return
(
gval0
,
gval1
)
return
(
gval0
,
gval1
)
a1
=
O
()
a1
=
O
()
.
make_node
()
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval0
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval0
)
self
.
failUnless
(
g
[
a1
.
inputs
[
1
]]
is
gval1
)
self
.
failUnless
(
g
[
a1
.
inputs
[
1
]]
is
gval1
)
def
test_Nin_Nout
(
self
):
def
test_Nin_Nout
(
self
):
"""Test grad is called correctly for a many-to-many op"""
"""Test grad is called correctly for a many-to-many op"""
gval0
=
gof
.
result
.
Result
()
gval0
=
gof
.
generic
()
gval1
=
gof
.
result
.
Result
()
gval1
=
gof
.
generic
()
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
):
def
make_node
(
self
):
self
.
inputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
inputs
=
[
gof
.
generic
(),
gof
.
generic
()]
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x0
,
x1
),
(
gz0
,
gz1
)):
def
grad
(
self
,
(
x0
,
x1
),
(
gz0
,
gz1
)):
return
gval0
,
gval1
return
gval0
,
gval1
a1
=
O
()
a1
=
O
()
.
make_node
()
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval0
)
self
.
failUnless
(
g
[
a1
.
inputs
[
0
]]
is
gval0
)
self
.
failUnless
(
g
[
a1
.
inputs
[
1
]]
is
gval1
)
self
.
failUnless
(
g
[
a1
.
inputs
[
1
]]
is
gval1
)
def
test_some_None_ograds
(
self
):
def
test_some_None_ograds
(
self
):
"""Test grad is called when some output gradients are None"""
"""Test grad is called when some output gradients are None"""
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
,
tst
):
def
__init__
(
self
,
tst
):
self
.
inputs
=
arg
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
self
.
tst
=
tst
self
.
tst
=
tst
def
make_node
(
self
,
*
inputs
):
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
inputs
,
g_out
):
def
grad
(
self
,
inputs
,
g_out
):
return
[
1
]
return
[
1
]
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
a1
=
O
(
[
i
],
self
)
a1
=
O
(
self
)
.
make_node
(
i
)
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a1
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
i
]
is
1
)
self
.
failUnless
(
g
[
i
]
is
1
)
def
test_some_None_igrads
(
self
):
def
test_some_None_igrads
(
self
):
"""Test that traversal works properly when an op return some None"""
"""Test that traversal works properly when an op return some None"""
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
,
tst
,
grad_ok
):
def
__init__
(
self
,
tst
,
grad_ok
):
self
.
inputs
=
arg
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
self
.
tst
=
tst
self
.
tst
=
tst
self
.
grad_ok
=
grad_ok
self
.
grad_ok
=
grad_ok
def
make_node
(
self
,
*
inputs
):
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
inputs
,
g_out
):
def
grad
(
self
,
inputs
,
g_out
):
if
not
self
.
grad_ok
:
if
not
self
.
grad_ok
:
self
.
tst
.
fail
()
self
.
tst
.
fail
()
else
:
else
:
return
[
1
,
None
]
return
[
1
,
None
]
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
j
=
gof
.
result
.
Result
()
j
=
gof
.
generic
()
k
=
gof
.
result
.
Result
()
k
=
gof
.
generic
()
a1
=
O
(
[
i
,
j
],
self
,
True
)
a1
=
O
(
self
,
True
)
.
make_node
(
i
,
j
)
a2
=
O
(
[
a1
.
outputs
[
1
],
k
],
self
,
True
)
a2
=
O
(
self
,
True
)
.
make_node
(
a1
.
outputs
[
1
],
k
)
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
i
]
is
1
and
j
not
in
g
and
k
not
in
g
)
self
.
failUnless
(
g
[
i
]
is
1
and
j
not
in
g
and
k
not
in
g
)
a1
=
O
(
[
i
,
j
],
self
,
True
)
a1
=
O
(
self
,
True
)
.
make_node
(
i
,
j
)
a2
=
O
(
[
k
,
a1
.
outputs
[
1
]],
self
,
True
)
a2
=
O
(
self
,
True
)
.
make_node
(
k
,
a1
.
outputs
[
1
]
)
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
)],
None
)
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
)],
None
)
self
.
failUnless
(
g
[
k
]
is
1
and
i
not
in
g
and
j
not
in
g
)
self
.
failUnless
(
g
[
k
]
is
1
and
i
not
in
g
and
j
not
in
g
)
def
test_inputs
(
self
):
def
test_inputs
(
self
):
"""Test that passing inputs shortens the traversal"""
"""Test that passing inputs shortens the traversal"""
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
,
tst
,
grad_ok
):
def
__init__
(
self
,
tst
,
grad_ok
):
self
.
inputs
=
arg
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
self
.
tst
=
tst
self
.
tst
=
tst
self
.
grad_ok
=
grad_ok
self
.
grad_ok
=
grad_ok
def
make_node
(
self
,
*
inputs
):
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
inputs
,
(
g0
,
g1
)):
def
grad
(
self
,
inputs
,
(
g0
,
g1
)):
if
not
self
.
grad_ok
:
if
not
self
.
grad_ok
:
self
.
tst
.
fail
()
self
.
tst
.
fail
()
...
@@ -183,11 +192,11 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -183,11 +192,11 @@ class _test_grad_sources_inputs(unittest.TestCase):
return
[
g0
,
g0
+
g1
]
return
[
g0
,
g0
+
g1
]
else
:
else
:
return
[
g0
,
g0
]
return
[
g0
,
g0
]
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
j
=
gof
.
result
.
Result
()
j
=
gof
.
generic
()
k
=
gof
.
result
.
Result
()
k
=
gof
.
generic
()
a1
=
O
(
[
i
,
j
],
self
,
True
)
a1
=
O
(
self
,
True
)
.
make_node
(
i
,
j
)
a2
=
O
(
[
k
,
a1
.
outputs
[
1
]],
self
,
True
)
a2
=
O
(
self
,
True
)
.
make_node
(
k
,
a1
.
outputs
[
1
]
)
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
),
(
a1
.
outputs
[
1
],
4
),
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
),
(
a1
.
outputs
[
1
],
4
),
(
a1
.
outputs
[
0
],
3
),
(
a1
.
outputs
[
0
],
3
)],
a1
.
outputs
)
(
a1
.
outputs
[
0
],
3
),
(
a1
.
outputs
[
0
],
3
)],
a1
.
outputs
)
self
.
failUnless
(
g
[
a2
.
inputs
[
0
]]
==
1
)
self
.
failUnless
(
g
[
a2
.
inputs
[
0
]]
==
1
)
...
@@ -200,11 +209,12 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -200,11 +209,12 @@ class _test_grad_sources_inputs(unittest.TestCase):
def
test_multiple_sources
(
self
):
def
test_multiple_sources
(
self
):
"""Test that passing multiple sources works"""
"""Test that passing multiple sources works"""
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
,
arg
,
tst
,
grad_ok
):
def
__init__
(
self
,
tst
,
grad_ok
):
self
.
inputs
=
arg
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
self
.
tst
=
tst
self
.
tst
=
tst
self
.
grad_ok
=
grad_ok
self
.
grad_ok
=
grad_ok
def
make_node
(
self
,
*
inputs
):
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
inputs
,
(
g0
,
g1
)):
def
grad
(
self
,
inputs
,
(
g0
,
g1
)):
if
not
self
.
grad_ok
:
if
not
self
.
grad_ok
:
self
.
tst
.
fail
()
self
.
tst
.
fail
()
...
@@ -213,11 +223,11 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -213,11 +223,11 @@ class _test_grad_sources_inputs(unittest.TestCase):
return
[
g0
,
g0
+
g1
]
return
[
g0
,
g0
+
g1
]
else
:
else
:
return
[
g0
,
g0
]
return
[
g0
,
g0
]
i
=
gof
.
result
.
Result
()
i
=
gof
.
generic
()
j
=
gof
.
result
.
Result
()
j
=
gof
.
generic
()
k
=
gof
.
result
.
Result
()
k
=
gof
.
generic
()
a1
=
O
(
[
i
,
j
],
self
,
True
)
a1
=
O
(
self
,
True
)
.
make_node
(
i
,
j
)
a2
=
O
(
[
k
,
a1
.
outputs
[
1
]],
self
,
True
)
a2
=
O
(
self
,
True
)
.
make_node
(
k
,
a1
.
outputs
[
1
]
)
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
),
(
a1
.
outputs
[
1
],
4
),
g
=
grad_sources_inputs
([(
a2
.
outputs
[
0
],
1
),
(
a1
.
outputs
[
1
],
4
),
(
a1
.
outputs
[
0
],
3
),
(
a1
.
outputs
[
0
],
3
)],
None
)
(
a1
.
outputs
[
0
],
3
),
(
a1
.
outputs
[
0
],
3
)],
None
)
self
.
failUnless
(
g
[
a2
.
inputs
[
0
]]
==
1
)
self
.
failUnless
(
g
[
a2
.
inputs
[
0
]]
==
1
)
...
@@ -231,47 +241,47 @@ class _test_grad_sources_inputs(unittest.TestCase):
...
@@ -231,47 +241,47 @@ class _test_grad_sources_inputs(unittest.TestCase):
class
_test_grad
(
unittest
.
TestCase
):
class
_test_grad
(
unittest
.
TestCase
):
class
O
(
gof
.
op
.
Op
):
class
O
(
gof
.
op
.
Op
):
def
__init__
(
self
):
def
__init__
(
self
):
self
.
inputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
self
.
gval0
=
gof
.
generic
()
self
.
outputs
=
[
gof
.
result
.
Result
(),
gof
.
result
.
Result
()]
self
.
gval1
=
gof
.
generic
()
self
.
gval0
=
gof
.
result
.
Result
()
def
make_node
(
self
):
self
.
gval1
=
gof
.
result
.
Result
()
inputs
=
[
gof
.
generic
(),
gof
.
generic
()]
outputs
=
[
gof
.
generic
(),
gof
.
generic
()]
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
grad
(
self
,
(
x0
,
x1
),
(
gz0
,
gz1
)):
def
grad
(
self
,
(
x0
,
x1
),
(
gz0
,
gz1
)):
return
self
.
gval0
,
self
.
gval1
return
self
.
gval0
,
self
.
gval1
def
test_1param
(
self
):
def
test_1param
(
self
):
"""grad: Test passing a single result param"""
"""grad: Test passing a single result param"""
a1
=
_test_grad
.
O
()
o
=
_test_grad
.
O
()
self
.
failUnless
(
a1
.
gval0
is
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
[
0
]))
a1
=
o
.
make_node
()
self
.
failUnless
(
o
.
gval0
is
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
[
0
]))
def
test_Nparam
(
self
):
def
test_Nparam
(
self
):
"""grad: Test passing multiple result params"""
"""grad: Test passing multiple result params"""
a1
=
_test_grad
.
O
()
o
=
_test_grad
.
O
()
a1
=
o
.
make_node
()
g0
,
g1
=
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
)
g0
,
g1
=
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
)
self
.
failUnless
(
a1
.
gval0
is
g0
)
self
.
failUnless
(
o
.
gval0
is
g0
)
self
.
failUnless
(
a1
.
gval1
is
g1
)
self
.
failUnless
(
o
.
gval1
is
g1
)
def
test_1None_rval
(
self
):
def
test_1None_rval
(
self
):
"""grad: Test returning a single None from grad"""
"""grad: Test returning a single None from grad"""
a1
=
_test_grad
.
O
()
o
=
_test_grad
.
O
()
a1
=
o
.
make_node
()
self
.
failUnless
(
None
is
grad
(
a1
.
outputs
[
0
],
a1
.
outputs
[
1
]))
self
.
failUnless
(
None
is
grad
(
a1
.
outputs
[
0
],
a1
.
outputs
[
1
]))
self
.
failUnless
(
None
is
grad
(
a1
.
outputs
[
0
],
'wtf'
))
self
.
failUnless
(
None
is
grad
(
a1
.
outputs
[
0
],
'wtf'
))
def
test_NNone_rval
(
self
):
def
test_NNone_rval
(
self
):
"""grad: Test returning some Nones from grad"""
"""grad: Test returning some Nones from grad"""
a1
=
_test_grad
.
O
()
o
=
_test_grad
.
O
()
a1
=
o
.
make_node
()
g0
,
g1
,
g2
=
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
+
[
'wtf'
])
g0
,
g1
,
g2
=
grad
(
a1
.
outputs
[
0
],
a1
.
inputs
+
[
'wtf'
])
self
.
failUnless
(
a1
.
gval0
is
g0
)
self
.
failUnless
(
o
.
gval0
is
g0
)
self
.
failUnless
(
a1
.
gval1
is
g1
)
self
.
failUnless
(
o
.
gval1
is
g1
)
self
.
failUnless
(
None
is
g2
)
self
.
failUnless
(
None
is
g2
)
def
matrix
():
return
tensor
.
Tensor
(
'float64'
,
[
0
,
0
])
def
matrices
(
n
):
return
[
matrix
()
for
i
in
xrange
(
n
)]
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
_test_sparse.py
浏览文件 @
ea32b4db
...
@@ -12,25 +12,25 @@ class T_transpose(unittest.TestCase):
...
@@ -12,25 +12,25 @@ class T_transpose(unittest.TestCase):
numpy
.
random
.
seed
(
44
)
numpy
.
random
.
seed
(
44
)
def
test_transpose_csc
(
self
):
def
test_transpose_csc
(
self
):
sp
=
sparse
.
csc_matrix
(
sparse
.
speye
(
5
,
3
))
sp
=
sparse
.
csc_matrix
(
sparse
.
speye
(
5
,
3
))
a
=
assparse
(
sp
)
a
=
as
_
sparse
(
sp
)
self
.
failUnless
(
a
.
data
is
sp
)
self
.
failUnless
(
a
.
data
is
sp
)
self
.
failUnless
(
a
.
data
.
shape
==
(
5
,
3
))
self
.
failUnless
(
a
.
data
.
shape
==
(
5
,
3
))
self
.
failUnless
(
a
.
dtype
==
'float64'
)
self
.
failUnless
(
a
.
type
.
dtype
==
'float64'
,
a
.
type
.
dtype
)
self
.
failUnless
(
a
.
format
==
'csc'
,
a
.
format
)
self
.
failUnless
(
a
.
type
.
format
==
'csc'
,
a
.
type
.
format
)
ta
=
transpose
(
a
)
ta
=
transpose
(
a
)
self
.
failUnless
(
ta
.
dtype
==
'float64'
,
ta
.
dtype
)
self
.
failUnless
(
ta
.
type
.
dtype
==
'float64'
,
ta
.
type
.
dtype
)
self
.
failUnless
(
ta
.
format
==
'csr'
,
ta
.
format
)
self
.
failUnless
(
ta
.
type
.
format
==
'csr'
,
ta
.
type
.
format
)
vta
=
compile
.
eval_outputs
([
ta
])
vta
=
compile
.
eval_outputs
([
ta
])
self
.
failUnless
(
vta
.
shape
==
(
3
,
5
))
self
.
failUnless
(
vta
.
shape
==
(
3
,
5
))
def
test_transpose_csr
(
self
):
def
test_transpose_csr
(
self
):
a
=
assparse
(
sparse
.
csr_matrix
(
sparse
.
speye
(
5
,
3
)))
a
=
as
_
sparse
(
sparse
.
csr_matrix
(
sparse
.
speye
(
5
,
3
)))
self
.
failUnless
(
a
.
data
.
shape
==
(
5
,
3
))
self
.
failUnless
(
a
.
data
.
shape
==
(
5
,
3
))
self
.
failUnless
(
a
.
dtype
==
'float64'
)
self
.
failUnless
(
a
.
type
.
dtype
==
'float64'
)
self
.
failUnless
(
a
.
format
==
'csr'
)
self
.
failUnless
(
a
.
type
.
format
==
'csr'
)
ta
=
transpose
(
a
)
ta
=
transpose
(
a
)
self
.
failUnless
(
ta
.
dtype
==
'float64'
,
ta
.
dtype
)
self
.
failUnless
(
ta
.
type
.
dtype
==
'float64'
,
ta
.
type
.
dtype
)
self
.
failUnless
(
ta
.
format
==
'csc'
,
ta
.
format
)
self
.
failUnless
(
ta
.
type
.
format
==
'csc'
,
ta
.
type
.
format
)
vta
=
compile
.
eval_outputs
([
ta
])
vta
=
compile
.
eval_outputs
([
ta
])
self
.
failUnless
(
vta
.
shape
==
(
3
,
5
))
self
.
failUnless
(
vta
.
shape
==
(
3
,
5
))
...
@@ -39,13 +39,13 @@ class T_Add(unittest.TestCase):
...
@@ -39,13 +39,13 @@ class T_Add(unittest.TestCase):
def
testSS
(
self
):
def
testSS
(
self
):
for
mtype
in
_mtypes
:
for
mtype
in
_mtypes
:
a
=
mtype
(
numpy
.
array
([[
1.
,
0
],
[
3
,
0
],
[
0
,
6
]]))
a
=
mtype
(
numpy
.
array
([[
1.
,
0
],
[
3
,
0
],
[
0
,
6
]]))
aR
=
assparse
(
a
)
aR
=
as
_
sparse
(
a
)
self
.
failUnless
(
aR
.
data
is
a
)
self
.
failUnless
(
aR
.
data
is
a
)
self
.
failUnless
(
_is_sparse
(
a
))
self
.
failUnless
(
_is_sparse
(
a
))
self
.
failUnless
(
_is_sparse_result
(
aR
))
self
.
failUnless
(
_is_sparse_result
(
aR
))
b
=
mtype
(
numpy
.
asarray
([[
0
,
2.
],
[
0
,
4
],
[
5
,
0
]]))
b
=
mtype
(
numpy
.
asarray
([[
0
,
2.
],
[
0
,
4
],
[
5
,
0
]]))
bR
=
assparse
(
b
)
bR
=
as
_
sparse
(
b
)
self
.
failUnless
(
bR
.
data
is
b
)
self
.
failUnless
(
bR
.
data
is
b
)
self
.
failUnless
(
_is_sparse
(
b
))
self
.
failUnless
(
_is_sparse
(
b
))
self
.
failUnless
(
_is_sparse_result
(
bR
))
self
.
failUnless
(
_is_sparse_result
(
bR
))
...
@@ -53,10 +53,10 @@ class T_Add(unittest.TestCase):
...
@@ -53,10 +53,10 @@ class T_Add(unittest.TestCase):
apb
=
add
(
aR
,
bR
)
apb
=
add
(
aR
,
bR
)
self
.
failUnless
(
_is_sparse_result
(
apb
))
self
.
failUnless
(
_is_sparse_result
(
apb
))
self
.
failUnless
(
apb
.
dtype
==
aR
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
type
.
dtype
==
aR
.
type
.
dtype
,
apb
.
type
.
dtype
)
self
.
failUnless
(
apb
.
dtype
==
bR
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
type
.
dtype
==
bR
.
type
.
dtype
,
apb
.
type
.
dtype
)
self
.
failUnless
(
apb
.
format
==
aR
.
format
,
apb
.
format
)
self
.
failUnless
(
apb
.
type
.
format
==
aR
.
type
.
format
,
apb
.
type
.
format
)
self
.
failUnless
(
apb
.
format
==
bR
.
format
,
apb
.
format
)
self
.
failUnless
(
apb
.
type
.
format
==
bR
.
type
.
format
,
apb
.
type
.
format
)
val
=
compile
.
eval_outputs
([
apb
])
val
=
compile
.
eval_outputs
([
apb
])
self
.
failUnless
(
val
.
shape
==
(
3
,
2
))
self
.
failUnless
(
val
.
shape
==
(
3
,
2
))
...
@@ -66,13 +66,13 @@ class T_Add(unittest.TestCase):
...
@@ -66,13 +66,13 @@ class T_Add(unittest.TestCase):
def
testSD
(
self
):
def
testSD
(
self
):
for
mtype
in
_mtypes
:
for
mtype
in
_mtypes
:
a
=
numpy
.
array
([[
1.
,
0
],
[
3
,
0
],
[
0
,
6
]])
a
=
numpy
.
array
([[
1.
,
0
],
[
3
,
0
],
[
0
,
6
]])
aR
=
tensor
.
astensor
(
a
)
aR
=
tensor
.
as
_
tensor
(
a
)
self
.
failUnless
(
aR
.
data
is
a
)
self
.
failUnless
(
aR
.
data
is
a
)
self
.
failUnless
(
_is_dense
(
a
))
self
.
failUnless
(
_is_dense
(
a
))
self
.
failUnless
(
_is_dense_result
(
aR
))
self
.
failUnless
(
_is_dense_result
(
aR
))
b
=
mtype
(
numpy
.
asarray
([[
0
,
2.
],
[
0
,
4
],
[
5
,
0
]]))
b
=
mtype
(
numpy
.
asarray
([[
0
,
2.
],
[
0
,
4
],
[
5
,
0
]]))
bR
=
assparse
(
b
)
bR
=
as
_
sparse
(
b
)
self
.
failUnless
(
bR
.
data
is
b
)
self
.
failUnless
(
bR
.
data
is
b
)
self
.
failUnless
(
_is_sparse
(
b
))
self
.
failUnless
(
_is_sparse
(
b
))
self
.
failUnless
(
_is_sparse_result
(
bR
))
self
.
failUnless
(
_is_sparse_result
(
bR
))
...
@@ -80,8 +80,8 @@ class T_Add(unittest.TestCase):
...
@@ -80,8 +80,8 @@ class T_Add(unittest.TestCase):
apb
=
add
(
aR
,
bR
)
apb
=
add
(
aR
,
bR
)
self
.
failUnless
(
_is_dense_result
(
apb
))
self
.
failUnless
(
_is_dense_result
(
apb
))
self
.
failUnless
(
apb
.
dtype
==
aR
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
type
.
dtype
==
aR
.
type
.
dtype
,
apb
.
type
.
dtype
)
self
.
failUnless
(
apb
.
dtype
==
bR
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
type
.
dtype
==
bR
.
type
.
dtype
,
apb
.
type
.
dtype
)
val
=
compile
.
eval_outputs
([
apb
])
val
=
compile
.
eval_outputs
([
apb
])
self
.
failUnless
(
val
.
shape
==
(
3
,
2
))
self
.
failUnless
(
val
.
shape
==
(
3
,
2
))
...
@@ -91,13 +91,13 @@ class T_Add(unittest.TestCase):
...
@@ -91,13 +91,13 @@ class T_Add(unittest.TestCase):
def
testDS
(
self
):
def
testDS
(
self
):
for
mtype
in
_mtypes
:
for
mtype
in
_mtypes
:
a
=
mtype
(
numpy
.
array
([[
1.
,
0
],
[
3
,
0
],
[
0
,
6
]]))
a
=
mtype
(
numpy
.
array
([[
1.
,
0
],
[
3
,
0
],
[
0
,
6
]]))
aR
=
assparse
(
a
)
aR
=
as
_
sparse
(
a
)
self
.
failUnless
(
aR
.
data
is
a
)
self
.
failUnless
(
aR
.
data
is
a
)
self
.
failUnless
(
_is_sparse
(
a
))
self
.
failUnless
(
_is_sparse
(
a
))
self
.
failUnless
(
_is_sparse_result
(
aR
))
self
.
failUnless
(
_is_sparse_result
(
aR
))
b
=
numpy
.
asarray
([[
0
,
2.
],
[
0
,
4
],
[
5
,
0
]])
b
=
numpy
.
asarray
([[
0
,
2.
],
[
0
,
4
],
[
5
,
0
]])
bR
=
tensor
.
astensor
(
b
)
bR
=
tensor
.
as
_
tensor
(
b
)
self
.
failUnless
(
bR
.
data
is
b
)
self
.
failUnless
(
bR
.
data
is
b
)
self
.
failUnless
(
_is_dense
(
b
))
self
.
failUnless
(
_is_dense
(
b
))
self
.
failUnless
(
_is_dense_result
(
bR
))
self
.
failUnless
(
_is_dense_result
(
bR
))
...
@@ -105,8 +105,8 @@ class T_Add(unittest.TestCase):
...
@@ -105,8 +105,8 @@ class T_Add(unittest.TestCase):
apb
=
add
(
aR
,
bR
)
apb
=
add
(
aR
,
bR
)
self
.
failUnless
(
_is_dense_result
(
apb
))
self
.
failUnless
(
_is_dense_result
(
apb
))
self
.
failUnless
(
apb
.
dtype
==
aR
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
type
.
dtype
==
aR
.
type
.
dtype
,
apb
.
type
.
dtype
)
self
.
failUnless
(
apb
.
dtype
==
bR
.
dtype
,
apb
.
dtype
)
self
.
failUnless
(
apb
.
type
.
dtype
==
bR
.
type
.
dtype
,
apb
.
type
.
dtype
)
val
=
compile
.
eval_outputs
([
apb
])
val
=
compile
.
eval_outputs
([
apb
])
self
.
failUnless
(
val
.
shape
==
(
3
,
2
))
self
.
failUnless
(
val
.
shape
==
(
3
,
2
))
...
@@ -118,15 +118,15 @@ class T_conversion(unittest.TestCase):
...
@@ -118,15 +118,15 @@ class T_conversion(unittest.TestCase):
numpy
.
random
.
seed
(
44
)
numpy
.
random
.
seed
(
44
)
def
test0
(
self
):
def
test0
(
self
):
a
=
tensor
.
astensor
(
numpy
.
random
.
rand
(
5
))
a
=
tensor
.
as
_
tensor
(
numpy
.
random
.
rand
(
5
))
s
=
sparse_from_dense
(
a
,
'csc'
)
s
=
csc_from_dense
(
a
)
val
=
compile
.
eval_outputs
([
s
])
val
=
compile
.
eval_outputs
([
s
])
self
.
failUnless
(
str
(
val
.
dtype
)
==
'float64'
)
self
.
failUnless
(
str
(
val
.
dtype
)
==
'float64'
)
self
.
failUnless
(
val
.
format
==
'csc'
)
self
.
failUnless
(
val
.
format
==
'csc'
)
def
test1
(
self
):
def
test1
(
self
):
a
=
tensor
.
astensor
(
numpy
.
random
.
rand
(
5
))
a
=
tensor
.
as
_
tensor
(
numpy
.
random
.
rand
(
5
))
s
=
sparse_from_dense
(
a
,
'csr'
)
s
=
csr_from_dense
(
a
)
val
=
compile
.
eval_outputs
([
s
])
val
=
compile
.
eval_outputs
([
s
])
self
.
failUnless
(
str
(
val
.
dtype
)
==
'float64'
)
self
.
failUnless
(
str
(
val
.
dtype
)
==
'float64'
)
self
.
failUnless
(
val
.
format
==
'csr'
)
self
.
failUnless
(
val
.
format
==
'csr'
)
...
@@ -147,7 +147,7 @@ class _testCase_dot(unittest.TestCase):
...
@@ -147,7 +147,7 @@ class _testCase_dot(unittest.TestCase):
def
test_basicSS
(
self
):
def
test_basicSS
(
self
):
for
mtype
in
_mtypes
:
for
mtype
in
_mtypes
:
x
=
assparse
(
mtype
((
500
,
3
)))
x
=
as
_
sparse
(
mtype
((
500
,
3
)))
x
.
data
[(
10
,
1
)]
=
1
x
.
data
[(
10
,
1
)]
=
1
x
.
data
[(
20
,
2
)]
=
2
x
.
data
[(
20
,
2
)]
=
2
self
.
failUnless
(
_is_sparse_result
(
x
))
self
.
failUnless
(
_is_sparse_result
(
x
))
...
@@ -176,126 +176,126 @@ class _testCase_dot(unittest.TestCase):
...
@@ -176,126 +176,126 @@ class _testCase_dot(unittest.TestCase):
w
=
w
.
todense
()
w
=
w
.
todense
()
self
.
failUnless
((
z
==
w
)
.
all
()
==
True
)
self
.
failUnless
((
z
==
w
)
.
all
()
==
True
)
def
test_basicSD
(
self
):
# def test_basicSD(self):
for
mtype
in
_mtypes
:
# for mtype in _mtypes:
x
=
assparse
(
mtype
((
500
,
3
)))
# x = as_sparse(mtype((500,3)))
x
.
data
[(
10
,
1
)]
=
1
# x.data[(10, 1)] = 1
x
.
data
[(
20
,
2
)]
=
2
# x.data[(20, 2)] = 2
self
.
failUnless
(
_is_sparse_result
(
x
))
# self.failUnless(_is_sparse_result(x))
y
=
tensor
.
astensor
([[
1.
,
2
],
[
3
,
4
],
[
2
,
1
]])
# y = tensor.as_tensor([[1., 2], [3, 4], [2, 1]])
self
.
failUnless
(
_is_dense_result
(
y
))
# self.failUnless(_is_dense_result(y))
zop
=
dot
(
x
,
y
)
# zop = dot(x,y)
self
.
failUnless
(
_is_sparse_result
(
zop
))
# self.failUnless(_is_sparse_result(zop))
z
=
compile
.
eval_outputs
([
zop
])
# z = compile.eval_outputs([zop])
self
.
failUnless
(
_is_sparse
(
z
))
# self.failUnless(_is_sparse(z))
self
.
failUnless
(
z
.
shape
==
(
500
,
2
))
# self.failUnless(z.shape == (500,2))
self
.
failUnless
(
type
(
z
)
is
mtype
)
w
=
mtype
((
500
,
2
))
w
[(
10
,
0
)]
=
3.
w
[(
20
,
0
)]
=
4
w
[(
10
,
1
)]
=
4
w
[(
20
,
1
)]
=
2
self
.
failUnless
(
z
.
shape
==
w
.
shape
)
self
.
failUnless
(
type
(
z
)
==
type
(
w
))
self
.
failUnless
(
z
.
dtype
==
w
.
dtype
)
#self.failUnless(z == w)
self
.
failUnless
(
abs
(
z
-
w
)
.
nnz
==
0
)
z
=
z
.
todense
()
w
=
w
.
todense
()
self
.
failUnless
((
z
==
w
)
.
all
()
==
True
)
def
test_basicDS
(
self
):
for
mtype
in
_mtypes
:
x
=
assparse
(
mtype
((
500
,
3
)))
x
.
data
[(
10
,
1
)]
=
1
x
.
data
[(
20
,
2
)]
=
2
self
.
failUnless
(
_is_sparse_result
(
x
))
y
=
tensor
.
astensor
([[
1.
,
2
],
[
3
,
4
],
[
2
,
1
]])
self
.
failUnless
(
_is_dense_result
(
y
))
x
.
data
=
x
.
data
.
T
y
.
data
=
y
.
data
.
T
# zop = dot(y, x)
zop
=
transpose
(
dot
(
y
,
x
))
self
.
failUnless
(
_is_sparse_result
(
zop
))
z
=
compile
.
eval_outputs
([
zop
])
self
.
failUnless
(
_is_sparse
(
z
))
self
.
failUnless
(
z
.
shape
==
(
500
,
2
))
# self.failUnless(type(z) is mtype)
# self.failUnless(type(z) is mtype)
w
=
mtype
((
500
,
2
))
# w = mtype((500,2))
w
[(
10
,
0
)]
=
3.
# w[(10, 0)] = 3.
w
[(
20
,
0
)]
=
4
# w[(20, 0)] = 4
w
[(
10
,
1
)]
=
4
# w[(10, 1)] = 4
w
[(
20
,
1
)]
=
2
# w[(20, 1)] = 2
self
.
failUnless
(
z
.
shape
==
w
.
shape
)
# self.failUnless(z.shape == w.shape)
# Type should switch from csr to csc and vice-versa, so don't perform this test
# self.failUnless(type(z) == type(w))
#self.failUnless(type(z) == type(w))
# self.failUnless(z.dtype == w.dtype)
self
.
failUnless
(
z
.
dtype
==
w
.
dtype
)
# #self.failUnless(z == w)
# Type should switch from csr to csc and vice-versa, so don't perform this test
# self.failUnless(abs(z-w).nnz == 0)
#self.failUnless(z == w)
self
.
failUnless
(
abs
(
z
-
w
)
.
nnz
==
0
)
# z = z.todense()
# w = w.todense()
z
=
z
.
todense
()
# self.failUnless((z == w).all() == True)
w
=
w
.
todense
()
self
.
failUnless
((
z
==
w
)
.
all
()
==
True
)
# def test_basicDS(self):
# for mtype in _mtypes:
def
test_graph_bprop0
(
self
):
# x = as_sparse(mtype((500,3)))
for
mtype
in
_mtypes
:
# x.data[(10, 1)] = 1
x
=
tensor
.
Tensor
(
'float64'
,
broadcastable
=
[
False
,
False
],
name
=
'x'
)
# x.data[(20, 2)] = 2
w
=
SparseResult
(
'float64'
,
_mtype_to_str
[
mtype
])
# self.failUnless(_is_sparse_result(x))
xw
=
dense_from_sparse
(
dot
(
w
,
x
))
y
=
dense_from_sparse
(
dot
(
w
.
T
,
xw
))
# y = tensor.as_tensor([[1., 2], [3, 4], [2, 1]])
diff
=
x
-
y
# self.failUnless(_is_dense_result(y))
loss
=
tensor
.
sum
(
tensor
.
sqr
(
diff
))
gw
=
gradient
.
grad
(
loss
,
w
)
# x.data = x.data.T
trainfn
=
compile
.
Function
([
x
,
w
],
[
y
,
loss
,
gw
])
# y.data = y.data.T
x
=
numpy
.
asarray
([[
1.
,
2
],
[
3
,
4
],
[
2
,
1
]])
# # zop = dot(y, x)
w
=
mtype
((
500
,
3
))
# zop = transpose(dot(y, x))
w
[(
10
,
1
)]
=
1
# self.failUnless(_is_sparse_result(zop))
w
[(
20
,
2
)]
=
2
# z = compile.eval_outputs([zop])
lr
=
0.001
# self.failUnless(_is_sparse(z))
y
,
origloss
,
gw
=
trainfn
(
x
,
w
)
# self.failUnless(z.shape == (500,2))
for
epoch
in
xrange
(
50
):
# # self.failUnless(type(z) is mtype)
y
,
loss
,
gw
=
trainfn
(
x
,
w
)
w
=
w
-
(
lr
*
gw
)
# w = mtype((500,2))
# w[(10, 0)] = 3.
self
.
failUnless
(
origloss
>
loss
)
# w[(20, 0)] = 4
self
.
failUnless
(
'1.0543172285'
==
str
(
loss
))
# w[(10, 1)] = 4
# w[(20, 1)] = 2
def
test_graph_bprop_rand
(
self
):
# self.failUnless(z.shape == w.shape)
for
i
in
range
(
10
):
# # Type should switch from csr to csc and vice-versa, so don't perform this test
xorig
=
numpy
.
random
.
rand
(
3
,
2
)
# #self.failUnless(type(z) == type(w))
for
mtype
in
_mtypes
:
# self.failUnless(z.dtype == w.dtype)
x
=
tensor
.
Tensor
(
'float64'
,
broadcastable
=
[
False
,
False
],
name
=
'x'
)
w
=
SparseResult
(
'float64'
,
_mtype_to_str
[
mtype
])
# # Type should switch from csr to csc and vice-versa, so don't perform this test
xw
=
dense_from_sparse
(
dot
(
w
,
x
))
# #self.failUnless(z == w)
y
=
dense_from_sparse
(
dot
(
w
.
T
,
xw
))
# self.failUnless(abs(z-w).nnz == 0)
diff
=
x
-
y
loss
=
tensor
.
sum
(
tensor
.
sqr
(
diff
))
# z = z.todense()
gw
=
gradient
.
grad
(
loss
,
w
)
# w = w.todense()
trainfn
=
compile
.
Function
([
x
,
w
],
[
y
,
loss
,
gw
])
# self.failUnless((z == w).all() == True)
x
=
xorig
# def test_graph_bprop0(self):
w
=
mtype
((
500
,
3
))
# for mtype in _mtypes:
w
[(
10
,
1
)]
=
1
# x = tensor.Tensor('float64', broadcastable=[False,False], name='x')
w
[(
20
,
2
)]
=
2
# w = SparseResult('float64', _mtype_to_str[mtype])
lr
=
0.001
# xw = dense_from_sparse(dot(w, x))
y
,
origloss
,
gw
=
trainfn
(
x
,
w
)
# y = dense_from_sparse(dot(w.T, xw))
for
epoch
in
xrange
(
50
):
# diff = x-y
y
,
loss
,
gw
=
trainfn
(
x
,
w
)
# loss = tensor.sum(tensor.sqr(diff))
w
=
w
-
(
lr
*
gw
)
# gw = gradient.grad(loss, w)
# trainfn = compile.Function([x, w], [y, loss, gw])
self
.
failUnless
(
origloss
>
loss
)
# x = numpy.asarray([[1., 2], [3, 4], [2, 1]])
# w = mtype((500,3))
# w[(10, 1)] = 1
# w[(20, 2)] = 2
# lr = 0.001
# y, origloss, gw = trainfn(x, w)
# for epoch in xrange(50):
# y, loss, gw = trainfn(x, w)
# w = w - (lr * gw)
# self.failUnless(origloss > loss)
# self.failUnless('1.0543172285' == str(loss))
# def test_graph_bprop_rand(self):
# for i in range(10):
# xorig = numpy.random.rand(3,2)
# for mtype in _mtypes:
# x = tensor.Tensor('float64', broadcastable=[False,False], name='x')
# w = SparseResult('float64', _mtype_to_str[mtype])
# xw = dense_from_sparse(dot(w, x))
# y = dense_from_sparse(dot(w.T, xw))
# diff = x-y
# loss = tensor.sum(tensor.sqr(diff))
# gw = gradient.grad(loss, w)
# trainfn = compile.Function([x, w], [y, loss, gw])
# x = xorig
# w = mtype((500,3))
# w[(10, 1)] = 1
# w[(20, 2)] = 2
# lr = 0.001
# y, origloss, gw = trainfn(x, w)
# for epoch in xrange(50):
# y, loss, gw = trainfn(x, w)
# w = w - (lr * gw)
# self.failUnless(origloss > loss)
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
_test_tensor.py
浏览文件 @
ea32b4db
...
@@ -3,7 +3,7 @@ import tensor # for hidden symbols
...
@@ -3,7 +3,7 @@ import tensor # for hidden symbols
import
unittest
import
unittest
from
copy
import
copy
from
copy
import
copy
from
compile
import
Function
,
eval_outputs
from
compile
import
function
,
FunctionFactory
,
eval_outputs
import
gradient
import
gradient
import
gof
,
gof
.
graph
import
gof
,
gof
.
graph
from
gof.python25
import
any
from
gof.python25
import
any
...
@@ -41,38 +41,38 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
...
@@ -41,38 +41,38 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
def
test_good
(
self
):
def
test_good
(
self
):
for
testname
,
inputs
in
self
.
good
.
items
():
for
testname
,
inputs
in
self
.
good
.
items
():
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputrs
=
[
constant
(
input
)
.
type
(
)
for
input
in
inputs
]
inputrs
=
[
value
(
input
)
for
input
in
inputs
]
try
:
try
:
node
=
self
.
op
.
make_node
(
*
inputrs
)
node
=
self
.
op
.
make_node
(
*
inputrs
)
except
:
except
:
type
,
value
,
traceback
=
sys
.
exc_info
()
type
,
exc_
value
,
traceback
=
sys
.
exc_info
()
err_msg
=
"Test
%
s::
%
s: Error occurred while making a node with inputs
%
s"
\
err_msg
=
"Test
%
s::
%
s: Error occurred while making a node with inputs
%
s"
\
%
(
self
.
op
,
testname
,
inputs
)
%
(
self
.
op
,
testname
,
inputs
)
value
.
args
=
value
.
args
+
(
err_msg
,
)
exc_value
.
args
=
exc_
value
.
args
+
(
err_msg
,
)
raise
type
,
value
,
traceback
raise
type
,
exc_
value
,
traceback
try
:
try
:
f
=
F
unction
(
inputrs
,
node
.
outputs
,
f
=
f
unction
(
inputrs
,
node
.
outputs
,
linker
_cls
=
lambda
env
:
gof
.
DualLinker
(
env
,
checker
=
_numpy_checker
),
linker
=
lambda
env
,
**
kwargs
:
gof
.
DualLinker
(
env
,
checker
=
_numpy_checker
,
**
kwargs
),
unpack_single
=
False
,
unpack_single
=
False
,
optimizer
=
None
)
optimizer
=
None
)
except
:
except
:
type
,
value
,
traceback
=
sys
.
exc_info
()
type
,
exc_
value
,
traceback
=
sys
.
exc_info
()
err_msg
=
"Test
%
s::
%
s: Error occurred while trying to make a Function"
\
err_msg
=
"Test
%
s::
%
s: Error occurred while trying to make a Function"
\
%
(
self
.
op
,
testname
)
%
(
self
.
op
,
testname
)
value
.
args
=
value
.
args
+
(
err_msg
,
)
exc_value
.
args
=
exc_
value
.
args
+
(
err_msg
,
)
raise
type
,
value
,
traceback
raise
type
,
exc_
value
,
traceback
expecteds
=
self
.
expected
(
*
inputs
)
expecteds
=
self
.
expected
(
*
inputs
)
try
:
try
:
results
=
f
(
*
inputs
)
results
=
f
(
*
inputs
)
except
:
except
:
type
,
value
,
traceback
=
sys
.
exc_info
()
type
,
exc_
value
,
traceback
=
sys
.
exc_info
()
err_msg
=
"Test
%
s::
%
s: Error occurred while calling the Function on the inputs
%
s"
\
err_msg
=
"Test
%
s::
%
s: Error occurred while calling the Function on the inputs
%
s"
\
%
(
self
.
op
,
testname
,
inputs
)
%
(
self
.
op
,
testname
,
inputs
)
value
.
args
=
value
.
args
+
(
err_msg
,
)
exc_value
.
args
=
exc_
value
.
args
+
(
err_msg
,
)
raise
type
,
value
,
traceback
raise
type
,
exc_
value
,
traceback
if
not
isinstance
(
expecteds
,
(
list
,
tuple
)):
if
not
isinstance
(
expecteds
,
(
list
,
tuple
)):
expecteds
=
(
expecteds
,
)
expecteds
=
(
expecteds
,
)
...
@@ -89,7 +89,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
...
@@ -89,7 +89,7 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
def
test_bad_build
(
self
):
def
test_bad_build
(
self
):
for
testname
,
inputs
in
self
.
bad_build
.
items
():
for
testname
,
inputs
in
self
.
bad_build
.
items
():
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputrs
=
[
constant
(
input
)
.
type
(
)
for
input
in
inputs
]
inputrs
=
[
value
(
input
)
for
input
in
inputs
]
try
:
try
:
node
=
self
.
op
.
make_node
(
*
inputrs
)
node
=
self
.
op
.
make_node
(
*
inputrs
)
except
:
except
:
...
@@ -100,27 +100,27 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
...
@@ -100,27 +100,27 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
def
test_bad_runtime
(
self
):
def
test_bad_runtime
(
self
):
for
testname
,
inputs
in
self
.
bad_runtime
.
items
():
for
testname
,
inputs
in
self
.
bad_runtime
.
items
():
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputrs
=
[
constant
(
input
)
.
type
(
)
for
input
in
inputs
]
inputrs
=
[
value
(
input
)
for
input
in
inputs
]
try
:
try
:
node
=
self
.
op
.
make_node
(
*
inputrs
)
node
=
self
.
op
.
make_node
(
*
inputrs
)
except
:
except
:
type
,
value
,
traceback
=
sys
.
exc_info
()
type
,
exc_
value
,
traceback
=
sys
.
exc_info
()
err_msg
=
"Test
%
s::
%
s: Error occurred while trying to make a node with inputs
%
s"
\
err_msg
=
"Test
%
s::
%
s: Error occurred while trying to make a node with inputs
%
s"
\
%
(
self
.
op
,
testname
,
inputs
)
%
(
self
.
op
,
testname
,
inputs
)
value
.
args
=
value
.
args
+
(
err_msg
,
)
exc_value
.
args
=
exc_
value
.
args
+
(
err_msg
,
)
raise
type
,
value
,
traceback
raise
type
,
exc_
value
,
traceback
try
:
try
:
f
=
F
unction
(
inputrs
,
node
.
outputs
,
f
=
f
unction
(
inputrs
,
node
.
outputs
,
linker
_cls
=
lambda
env
:
gof
.
DualLinker
(
env
,
checker
=
_numpy_checker
),
linker
=
lambda
env
,
**
kwargs
:
gof
.
DualLinker
(
env
,
checker
=
_numpy_checker
,
**
kwargs
),
unpack_single
=
False
,
unpack_single
=
False
,
optimizer
=
None
)
optimizer
=
None
)
except
:
except
:
type
,
value
,
traceback
=
sys
.
exc_info
()
type
,
exc_
value
,
traceback
=
sys
.
exc_info
()
err_msg
=
"Test
%
s::
%
s: Error occurred while trying to make a Function"
\
err_msg
=
"Test
%
s::
%
s: Error occurred while trying to make a Function"
\
%
(
self
.
op
,
testname
)
%
(
self
.
op
,
testname
)
value
.
args
=
value
.
args
+
(
err_msg
,
)
exc_value
.
args
=
exc_
value
.
args
+
(
err_msg
,
)
raise
type
,
value
,
traceback
raise
type
,
exc_
value
,
traceback
try
:
try
:
results
=
f
(
*
inputs
)
results
=
f
(
*
inputs
)
...
@@ -133,15 +133,15 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
...
@@ -133,15 +133,15 @@ def make_tester(name, op, expected, checks = {}, good = {}, bad_build = {}, bad_
def
test_grad
(
self
):
def
test_grad
(
self
):
for
testname
,
inputs
in
self
.
grad
.
items
():
for
testname
,
inputs
in
self
.
grad
.
items
():
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputs
=
[
copy
(
input
)
for
input
in
inputs
]
inputrs
=
[
constant
(
input
)
.
type
(
)
for
input
in
inputs
]
inputrs
=
[
value
(
input
)
for
input
in
inputs
]
try
:
try
:
verify_grad
(
self
,
self
.
op
,
inputs
)
verify_grad
(
self
,
self
.
op
,
inputs
)
except
:
except
:
type
,
value
,
traceback
=
sys
.
exc_info
()
type
,
exc_
value
,
traceback
=
sys
.
exc_info
()
err_msg
=
"Test
%
s::
%
s: Error occurred while computing the gradient on the following inputs:
%
s"
\
err_msg
=
"Test
%
s::
%
s: Error occurred while computing the gradient on the following inputs:
%
s"
\
%
(
self
.
op
,
testname
,
inputs
)
%
(
self
.
op
,
testname
,
inputs
)
value
.
args
=
value
.
args
+
(
err_msg
,
)
exc_value
.
args
=
exc_
value
.
args
+
(
err_msg
,
)
raise
type
,
value
,
traceback
raise
type
,
exc_
value
,
traceback
Checker
.
__name__
=
name
Checker
.
__name__
=
name
return
Checker
return
Checker
...
@@ -194,287 +194,287 @@ _grad_broadcast_binary_normal = dict(same_shapes = (rand(2, 3), rand(2, 3)),
...
@@ -194,287 +194,287 @@ _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_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
)),
# # integers_positive = (randint_ranged(4, 10, (2, 3)), randint_ranged(1, 6, (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_known_to_fail = (numpy.array(-1), numpy.array(5))
# ),
),
# # integers = (randint(2, 3), randint_nonzero(2, 3)),
# 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_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
)),
# 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))),
DivInplaceTester
=
make_broadcast_tester
(
op
=
div_inplace
,
# inplace = True)
expected
=
lambda
x
,
y
:
x
/
y
,
good
=
dict
(
same_shapes
=
(
rand
(
2
,
3
),
rand
(
2
,
3
)),
# PowTester = make_broadcast_tester(op = pow,
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
# expected = lambda x, y: x ** y,
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
# good = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
column
=
(
rand
(
2
,
3
),
rand
(
2
,
1
)),
# scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
dtype_mixup_1
=
(
rand
(
2
,
3
),
randint_nonzero
(
2
,
3
)),
# row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
dtype_mixup_2
=
(
randint_nonzero
(
2
,
3
),
rand
(
2
,
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
(
2
,
3
),
rand
(
2
,
3
)),
# grad = dict(same_shapes = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 3))),
scalar
=
(
rand
(
2
,
3
),
rand
(
1
,
1
)),
# scalar = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 1))),
row
=
(
rand
(
2
,
3
),
rand
(
1
,
3
)),
# row = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (1, 3))),
column
=
(
rand
(
2
,
3
),
rand
(
2
,
1
))),
# column = (rand_ranged(1, 5, (2, 3)), rand_ranged(-3, 3, (2, 1))))
inplace
=
True
)
# )
# PowInplaceTester = make_broadcast_tester(op = pow_inplace,
PowTester
=
make_broadcast_tester
(
op
=
pow
,
# expected = lambda x, y: x ** y,
expected
=
lambda
x
,
y
:
x
**
y
,
# good = 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)))),
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))),
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))),
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
))))
# inplace = True)
)
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
))),
# _good_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),),
scalar
=
(
rand_ranged
(
1
,
5
,
(
2
,
3
)),
rand_ranged
(
-
3
,
3
,
(
1
,
1
))),
# integers = (randint_ranged(-5, 5, (2, 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
))),
# _grad_broadcast_unary_normal = dict(normal = (rand_ranged(-5, 5, (2, 3)),))
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
))),
# AbsTester = make_broadcast_tester(op = tensor._abs,
row
=
(
rand_ranged
(
1
,
5
,
(
2
,
3
)),
rand_ranged
(
-
3
,
3
,
(
1
,
3
))),
# expected = lambda x: abs(x),
column
=
(
rand_ranged
(
1
,
5
,
(
2
,
3
)),
rand_ranged
(
-
3
,
3
,
(
2
,
1
)))),
# good = _good_broadcast_unary_normal,
inplace
=
True
)
# grad = _grad_broadcast_unary_normal)
# AbsInplaceTester = make_broadcast_tester(op = abs_inplace,
# expected = lambda x: abs(x),
# good = _good_broadcast_unary_normal,
_good_broadcast_unary_normal
=
dict
(
normal
=
(
rand_ranged
(
-
5
,
5
,
(
2
,
3
)),),
# grad = _grad_broadcast_unary_normal,
integers
=
(
randint_ranged
(
-
5
,
5
,
(
2
,
3
)),))
# inplace = True)
_grad_broadcast_unary_normal
=
dict
(
normal
=
(
rand_ranged
(
-
5
,
5
,
(
2
,
3
)),))
# NegTester = make_broadcast_tester(op = neg,
# expected = lambda x: -x,
# good = _good_broadcast_unary_normal,
AbsTester
=
make_broadcast_tester
(
op
=
tensor
.
_abs
,
# grad = _grad_broadcast_unary_normal)
expected
=
lambda
x
:
abs
(
x
),
# NegInplaceTester = make_broadcast_tester(op = neg_inplace,
good
=
_good_broadcast_unary_normal
,
# expected = lambda x: -x,
grad
=
_grad_broadcast_unary_normal
)
# good = _good_broadcast_unary_normal,
AbsInplaceTester
=
make_broadcast_tester
(
op
=
abs_inplace
,
# grad = _grad_broadcast_unary_normal,
expected
=
lambda
x
:
abs
(
x
),
# inplace = True)
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
# SgnTester = make_broadcast_tester(op = sgn,
inplace
=
True
)
# expected = numpy.sign,
# good = _good_broadcast_unary_normal)
NegTester
=
make_broadcast_tester
(
op
=
neg
,
# SgnInplaceTester = make_broadcast_tester(op = sgn_inplace,
expected
=
lambda
x
:
-
x
,
# expected = numpy.sign,
good
=
_good_broadcast_unary_normal
,
# good = _good_broadcast_unary_normal,
grad
=
_grad_broadcast_unary_normal
)
# inplace = True)
NegInplaceTester
=
make_broadcast_tester
(
op
=
neg_inplace
,
expected
=
lambda
x
:
-
x
,
# SqrTester = make_broadcast_tester(op = sqr,
good
=
_good_broadcast_unary_normal
,
# expected = numpy.square,
grad
=
_grad_broadcast_unary_normal
,
# good = _good_broadcast_unary_normal,
inplace
=
True
)
# grad = _grad_broadcast_unary_normal)
# SqrInplaceTester = make_broadcast_tester(op = sqr_inplace,
SgnTester
=
make_broadcast_tester
(
op
=
sgn
,
# expected = numpy.square,
expected
=
numpy
.
sign
,
# good = _good_broadcast_unary_normal,
good
=
_good_broadcast_unary_normal
)
# grad = _grad_broadcast_unary_normal,
SgnInplaceTester
=
make_broadcast_tester
(
op
=
sgn_inplace
,
# inplace = True)
expected
=
numpy
.
sign
,
good
=
_good_broadcast_unary_normal
,
# ExpTester = make_broadcast_tester(op = exp,
inplace
=
True
)
# expected = numpy.exp,
# good = _good_broadcast_unary_normal,
SqrTester
=
make_broadcast_tester
(
op
=
sqr
,
# grad = _grad_broadcast_unary_normal)
expected
=
numpy
.
square
,
# ExpInplaceTester = make_broadcast_tester(op = exp_inplace,
good
=
_good_broadcast_unary_normal
,
# expected = numpy.exp,
grad
=
_grad_broadcast_unary_normal
)
# good = _good_broadcast_unary_normal,
SqrInplaceTester
=
make_broadcast_tester
(
op
=
sqr_inplace
,
# grad = _grad_broadcast_unary_normal,
expected
=
numpy
.
square
,
# inplace = True)
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)),))
ExpTester
=
make_broadcast_tester
(
op
=
exp
,
expected
=
numpy
.
exp
,
# _grad_broadcast_unary_positive = dict(normal = (rand_ranged(0.001, 5, (2, 3)),))
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
)
# LogTester = make_broadcast_tester(op = log,
ExpInplaceTester
=
make_broadcast_tester
(
op
=
exp_inplace
,
# expected = numpy.log,
expected
=
numpy
.
exp
,
# good = _good_broadcast_unary_positive,
good
=
_good_broadcast_unary_normal
,
# grad = _grad_broadcast_unary_positive)
grad
=
_grad_broadcast_unary_normal
,
# LogInplaceTester = make_broadcast_tester(op = log_inplace,
inplace
=
True
)
# expected = numpy.log,
# good = _good_broadcast_unary_positive,
# grad = _grad_broadcast_unary_positive,
_good_broadcast_unary_positive
=
dict
(
normal
=
(
rand_ranged
(
0.001
,
5
,
(
2
,
3
)),),
# inplace = True)
integers
=
(
randint_ranged
(
1
,
5
,
(
2
,
3
)),))
# Log2Tester = make_broadcast_tester(op = log2,
_grad_broadcast_unary_positive
=
dict
(
normal
=
(
rand_ranged
(
0.001
,
5
,
(
2
,
3
)),))
# expected = numpy.log2,
# good = _good_broadcast_unary_positive,
LogTester
=
make_broadcast_tester
(
op
=
log
,
# grad = _grad_broadcast_unary_positive)
expected
=
numpy
.
log
,
# Log2InplaceTester = make_broadcast_tester(op = log2_inplace,
good
=
_good_broadcast_unary_positive
,
# expected = numpy.log2,
grad
=
_grad_broadcast_unary_positive
)
# good = _good_broadcast_unary_positive,
LogInplaceTester
=
make_broadcast_tester
(
op
=
log_inplace
,
# grad = _grad_broadcast_unary_positive,
expected
=
numpy
.
log
,
# inplace = True)
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
,
# SqrtTester = make_broadcast_tester(op = sqrt,
inplace
=
True
)
# expected = numpy.sqrt,
# good = _good_broadcast_unary_positive,
Log2Tester
=
make_broadcast_tester
(
op
=
log2
,
# grad = _grad_broadcast_unary_positive)
expected
=
numpy
.
log2
,
# SqrtInplaceTester = make_broadcast_tester(op = sqrt_inplace,
good
=
_good_broadcast_unary_positive
,
# expected = numpy.sqrt,
grad
=
_grad_broadcast_unary_positive
)
# good = _good_broadcast_unary_positive,
Log2InplaceTester
=
make_broadcast_tester
(
op
=
log2_inplace
,
# grad = _grad_broadcast_unary_positive,
expected
=
numpy
.
log2
,
# inplace = True)
good
=
_good_broadcast_unary_positive
,
grad
=
_grad_broadcast_unary_positive
,
inplace
=
True
)
# _good_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),),
SqrtTester
=
make_broadcast_tester
(
op
=
sqrt
,
# integers = (randint_ranged(-1000, 1000, (2, 3)),))
expected
=
numpy
.
sqrt
,
good
=
_good_broadcast_unary_positive
,
# _grad_broadcast_unary_wide = dict(normal = (rand_ranged(-1000, 1000, (2, 3)),))
grad
=
_grad_broadcast_unary_positive
)
SqrtInplaceTester
=
make_broadcast_tester
(
op
=
sqrt_inplace
,
expected
=
numpy
.
sqrt
,
# SinTester = make_broadcast_tester(op = sin,
good
=
_good_broadcast_unary_positive
,
# expected = numpy.sin,
grad
=
_grad_broadcast_unary_positive
,
# good = _good_broadcast_unary_wide,
inplace
=
True
)
# grad = _grad_broadcast_unary_wide)
# SinInplaceTester = make_broadcast_tester(op = sin_inplace,
# expected = numpy.sin,
# good = _good_broadcast_unary_wide,
_good_broadcast_unary_wide
=
dict
(
normal
=
(
rand_ranged
(
-
1000
,
1000
,
(
2
,
3
)),),
# grad = _grad_broadcast_unary_wide,
integers
=
(
randint_ranged
(
-
1000
,
1000
,
(
2
,
3
)),))
# inplace = True)
_grad_broadcast_unary_wide
=
dict
(
normal
=
(
rand_ranged
(
-
1000
,
1000
,
(
2
,
3
)),))
# CosTester = make_broadcast_tester(op = cos,
# expected = numpy.cos,
# good = _good_broadcast_unary_wide,
SinTester
=
make_broadcast_tester
(
op
=
sin
,
# grad = _grad_broadcast_unary_wide)
expected
=
numpy
.
sin
,
# CosInplaceTester = make_broadcast_tester(op = cos_inplace,
good
=
_good_broadcast_unary_wide
,
# expected = numpy.cos,
grad
=
_grad_broadcast_unary_wide
)
# good = _good_broadcast_unary_wide,
SinInplaceTester
=
make_broadcast_tester
(
op
=
sin_inplace
,
# grad = _grad_broadcast_unary_wide,
expected
=
numpy
.
sin
,
# inplace = True)
good
=
_good_broadcast_unary_wide
,
grad
=
_grad_broadcast_unary_wide
,
# TanTester = make_broadcast_tester(op = tan,
inplace
=
True
)
# expected = numpy.tan,
# good = dict(normal = (rand_ranged(-3.14, 3.14, (2, 3)),),
CosTester
=
make_broadcast_tester
(
op
=
cos
,
# shifted = (rand_ranged(3.15, 6.28, (2, 3)),)),
expected
=
numpy
.
cos
,
# grad = 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
)
# TanInplaceTester = make_broadcast_tester(op = tan_inplace,
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)),)),
# inplace = True)
TanTester
=
make_broadcast_tester
(
op
=
tan
,
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)
TanInplaceTester
=
make_broadcast_tester
(
op
=
tan_inplace
,
# CoshInplaceTester = make_broadcast_tester(op = cosh_inplace,
expected
=
numpy
.
tan
,
# expected = numpy.cosh,
good
=
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,
grad
=
dict
(
normal
=
(
rand_ranged
(
-
3.14
,
3.14
,
(
2
,
3
)),),
# inplace = True)
shifted
=
(
rand_ranged
(
3.15
,
6.28
,
(
2
,
3
)),)),
inplace
=
True
)
# SinhTester = make_broadcast_tester(op = sinh,
# expected = numpy.sinh,
# good = _good_broadcast_unary_normal,
CoshTester
=
make_broadcast_tester
(
op
=
cosh
,
# grad = _grad_broadcast_unary_normal)
expected
=
numpy
.
cosh
,
# SinhInplaceTester = make_broadcast_tester(op = sinh_inplace,
good
=
_good_broadcast_unary_normal
,
# expected = numpy.sinh,
grad
=
_grad_broadcast_unary_normal
)
# good = _good_broadcast_unary_normal,
CoshInplaceTester
=
make_broadcast_tester
(
op
=
cosh_inplace
,
# grad = _grad_broadcast_unary_normal,
expected
=
numpy
.
cosh
,
# inplace = True)
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
# TanhTester = make_broadcast_tester(op = tanh,
inplace
=
True
)
# expected = numpy.tanh,
# good = _good_broadcast_unary_normal,
SinhTester
=
make_broadcast_tester
(
op
=
sinh
,
# grad = _grad_broadcast_unary_normal)
expected
=
numpy
.
sinh
,
# TanhInplaceTester = make_broadcast_tester(op = tanh_inplace,
good
=
_good_broadcast_unary_normal
,
# expected = numpy.tanh,
grad
=
_grad_broadcast_unary_normal
)
# good = _good_broadcast_unary_normal,
SinhInplaceTester
=
make_broadcast_tester
(
op
=
sinh_inplace
,
# grad = _grad_broadcast_unary_normal,
expected
=
numpy
.
sinh
,
# inplace = True)
good
=
_good_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
# DotTester = make_tester(name = 'DotTester',
TanhTester
=
make_broadcast_tester
(
op
=
tanh
,
# op = dot,
expected
=
numpy
.
tanh
,
# expected = lambda x, y: numpy.dot(x, y),
good
=
_good_broadcast_unary_normal
,
# checks = {},
grad
=
_grad_broadcast_unary_normal
)
# good = dict(correct1 = (rand(5, 7), rand(7, 5)),
TanhInplaceTester
=
make_broadcast_tester
(
op
=
tanh_inplace
,
# correct2 = (rand(5, 7), rand(7, 9))),
expected
=
numpy
.
tanh
,
# bad_build = dict(),
good
=
_good_broadcast_unary_normal
,
# bad_runtime = dict(bad1 = (rand(5, 7), rand(5, 7)),
grad
=
_grad_broadcast_unary_normal
,
# bad2 = (rand(5, 7), rand(8, 3))))
inplace
=
True
)
DotTester
=
make_tester
(
name
=
'DotTester'
,
op
=
dot
,
expected
=
lambda
x
,
y
:
numpy
.
dot
(
x
,
y
),
checks
=
{},
good
=
dict
(
correct1
=
(
rand
(
5
,
7
),
rand
(
7
,
5
)),
correct2
=
(
rand
(
5
,
7
),
rand
(
7
,
9
))),
bad_build
=
dict
(),
bad_runtime
=
dict
(
bad1
=
(
rand
(
5
,
7
),
rand
(
5
,
7
)),
bad2
=
(
rand
(
5
,
7
),
rand
(
8
,
3
))))
...
@@ -500,14 +500,14 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to
...
@@ -500,14 +500,14 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to
# we could make loop over outputs making random projections R for each,
# we could make loop over outputs making random projections R for each,
# but this doesn't handle the case where not all the outputs are
# but this doesn't handle the case where not all the outputs are
# differentiable... so I leave this as TODO for now -JB.
# differentiable... so I leave this as TODO for now -JB.
o_fn
=
F
unction
(
tensor_pt
,
o_outputs
)
o_fn
=
f
unction
(
tensor_pt
,
o_outputs
)
o_fn_out
=
o_fn
(
*
pt
)
o_fn_out
=
o_fn
(
*
pt
)
random_projection
=
rng
.
rand
(
*
o_fn_out
.
shape
)
random_projection
=
rng
.
rand
(
*
o_fn_out
.
shape
)
t_r
=
as_tensor
(
random_projection
)
t_r
=
as_tensor
(
random_projection
)
#random projection of o onto t_r
#random projection of o onto t_r
cost
=
sum
(
t_r
*
o_outputs
[
0
])
cost
=
sum
(
t_r
*
o_outputs
[
0
])
cost_fn
=
F
unction
(
tensor_pt
,
[
cost
])
cost_fn
=
f
unction
(
tensor_pt
,
[
cost
])
num_grad
=
gradient
.
numeric_grad
(
cost_fn
,
pt
)
num_grad
=
gradient
.
numeric_grad
(
cost_fn
,
pt
)
...
@@ -518,7 +518,7 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to
...
@@ -518,7 +518,7 @@ def verify_grad(testcase, op, pt, n_tests=1, rng=numpy.random, eps=0.0000001, to
for
op
in
gof
.
graph
.
io_toposort
(
tensor_pt
,
symbolic_grad
):
for
op
in
gof
.
graph
.
io_toposort
(
tensor_pt
,
symbolic_grad
):
print
op
print
op
grad_fn
=
F
unction
(
tensor_pt
,
symbolic_grad
)
grad_fn
=
f
unction
(
tensor_pt
,
symbolic_grad
)
analytic_grad
=
grad_fn
(
*
pt
)
analytic_grad
=
grad_fn
(
*
pt
)
if
not
isinstance
(
analytic_grad
,
(
list
,
tuple
)):
if
not
isinstance
(
analytic_grad
,
(
list
,
tuple
)):
...
@@ -635,7 +635,7 @@ class T_transpose(unittest.TestCase):
...
@@ -635,7 +635,7 @@ class T_transpose(unittest.TestCase):
n
=
as_tensor
(
numpy
.
ones
(()))
n
=
as_tensor
(
numpy
.
ones
(()))
t
=
transpose
(
n
)
t
=
transpose
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
f
=
F
unction
([
n
],
[
t
])
f
=
f
unction
([
n
],
[
t
])
tval
=
f
(
n
.
data
)
tval
=
f
(
n
.
data
)
self
.
failUnless
(
tval
.
shape
==
n
.
data
.
shape
)
self
.
failUnless
(
tval
.
shape
==
n
.
data
.
shape
)
...
@@ -647,7 +647,7 @@ class T_transpose(unittest.TestCase):
...
@@ -647,7 +647,7 @@ class T_transpose(unittest.TestCase):
n
=
as_tensor
(
numpy
.
ones
(
5
))
n
=
as_tensor
(
numpy
.
ones
(
5
))
t
=
transpose
(
n
)
t
=
transpose
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
f
=
F
unction
([
n
],
[
t
])
f
=
f
unction
([
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
...
@@ -658,7 +658,7 @@ class T_transpose(unittest.TestCase):
...
@@ -658,7 +658,7 @@ class T_transpose(unittest.TestCase):
n
=
as_tensor
(
numpy
.
ones
((
5
,
3
)))
n
=
as_tensor
(
numpy
.
ones
((
5
,
3
)))
t
=
transpose
(
n
)
t
=
transpose
(
n
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
f
=
F
unction
([
n
],
[
t
])
f
=
f
unction
([
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
...
@@ -670,7 +670,7 @@ class T_transpose(unittest.TestCase):
...
@@ -670,7 +670,7 @@ class T_transpose(unittest.TestCase):
n
=
as_tensor
(
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
.
op
==
transpose_inplace
)
self
.
failUnless
(
t
.
owner
.
op
==
transpose_inplace
)
f
=
F
unction
([
n
],
[
t
])
f
=
f
unction
([
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
...
@@ -1036,7 +1036,7 @@ class _testCase_matinv(unittest.TestCase):
...
@@ -1036,7 +1036,7 @@ class _testCase_matinv(unittest.TestCase):
# 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
=
F
unction
([
a
,
b
],
[
ssdiff
,
g_b
])
fn
=
f
unction
([
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
...
@@ -1133,7 +1133,7 @@ class t_gemm(unittest.TestCase):
...
@@ -1133,7 +1133,7 @@ class t_gemm(unittest.TestCase):
z_orig
=
z
.
copy
()
z_orig
=
z
.
copy
()
tz
,
ta
,
tx
,
ty
,
tb
=
[
as_tensor
(
p
)
.
type
()
for
p
in
z
,
a
,
x
,
y
,
b
]
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
)
f
=
function
([
tz
,
ta
,
tx
,
ty
,
tb
],
[
gemm
(
tz
,
ta
,
tx
,
ty
,
tb
)],
linker
=
l
)
new_z
=
f
(
z
,
a
,
x
,
y
,
b
)
new_z
=
f
(
z
,
a
,
x
,
y
,
b
)
z_after
=
self
.
_gemm
(
z_orig
,
a
,
x
,
y
,
b
)
z_after
=
self
.
_gemm
(
z_orig
,
a
,
x
,
y
,
b
)
...
@@ -1236,8 +1236,8 @@ class t_gemm(unittest.TestCase):
...
@@ -1236,8 +1236,8 @@ class t_gemm(unittest.TestCase):
def
test_destroy_map4
(
self
):
def
test_destroy_map4
(
self
):
"""test that dot args can be aliased"""
"""test that dot args can be aliased"""
Z
=
as_tensor
(
self
.
rand
(
2
,
2
))
Z
=
value
(
self
.
rand
(
2
,
2
))
A
=
as_tensor
(
self
.
rand
(
2
,
2
))
A
=
value
(
self
.
rand
(
2
,
2
))
eval_outputs
([
gemm
(
Z
,
1.0
,
A
,
A
,
1.0
)])
eval_outputs
([
gemm
(
Z
,
1.0
,
A
,
A
,
1.0
)])
eval_outputs
([
gemm
(
Z
,
1.0
,
A
,
A
.
T
,
1.0
)])
eval_outputs
([
gemm
(
Z
,
1.0
,
A
,
A
.
T
,
1.0
)])
...
@@ -1253,9 +1253,9 @@ class t_gemm(unittest.TestCase):
...
@@ -1253,9 +1253,9 @@ class t_gemm(unittest.TestCase):
z_orig
=
z
.
copy
()
z_orig
=
z
.
copy
()
z_after
=
self
.
_gemm
(
z
,
a
,
x
,
y
,
b
)
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
]
tz
,
ta
,
tx
,
ty
,
tb
=
[
value
(
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
=
function
([
tz
,
ta
,
tx
,
ty
,
tb
],
[
gemm
(
tz
,
ta
,
tx
,
ty
,
tb
)],
linker
=
l
)
f
(
z
,
a
,
x
,
y
,
b
)
f
(
z
,
a
,
x
,
y
,
b
)
self
.
failUnless
(
_approx_eq
(
z_after
,
z
),
(
z_orig
,
z_after
,
z
))
self
.
failUnless
(
_approx_eq
(
z_after
,
z
),
(
z_orig
,
z_after
,
z
))
f
(
z
.
T
,
a
,
y
.
T
,
x
.
T
,
b
)
f
(
z
.
T
,
a
,
y
.
T
,
x
.
T
,
b
)
...
@@ -1424,3 +1424,4 @@ class t_gemm(unittest.TestCase):
...
@@ -1424,3 +1424,4 @@ class t_gemm(unittest.TestCase):
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
unittest
.
main
()
unittest
.
main
()
#AddTester('test_grad').debug()
gof/_test_cc.py
浏览文件 @
ea32b4db
...
@@ -6,7 +6,8 @@ from cc import *
...
@@ -6,7 +6,8 @@ from cc import *
from
type
import
Type
from
type
import
Type
from
graph
import
Result
,
as_result
,
Apply
,
Constant
from
graph
import
Result
,
as_result
,
Apply
,
Constant
from
op
import
Op
from
op
import
Op
from
env
import
Env
import
env
import
toolbox
class
TDouble
(
Type
):
class
TDouble
(
Type
):
def
filter
(
self
,
data
):
def
filter
(
self
,
data
):
...
@@ -125,6 +126,11 @@ def inputs():
...
@@ -125,6 +126,11 @@ def inputs():
return
x
,
y
,
z
return
x
,
y
,
z
def
Env
(
inputs
,
outputs
):
e
=
env
.
Env
(
inputs
,
outputs
)
return
e
class
_test_CLinker
(
unittest
.
TestCase
):
class
_test_CLinker
(
unittest
.
TestCase
):
def
test_straightforward
(
self
):
def
test_straightforward
(
self
):
...
...
gof/_test_ext.py
浏览文件 @
ea32b4db
...
@@ -257,7 +257,6 @@ class _test_all(unittest.TestCase):
...
@@ -257,7 +257,6 @@ class _test_all(unittest.TestCase):
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
#unittest.main()
unittest
.
main
()
_test_all
(
'test_usage_loop_through_views'
)
.
debug
()
gof/_test_graph.py
浏览文件 @
ea32b4db
...
@@ -161,14 +161,14 @@ class _test_clone(unittest.TestCase):
...
@@ -161,14 +161,14 @@ class _test_clone(unittest.TestCase):
def
test_accurate
(
self
):
def
test_accurate
(
self
):
r1
,
r2
=
MyResult
(
1
),
MyResult
(
2
)
r1
,
r2
=
MyResult
(
1
),
MyResult
(
2
)
node
=
MyOp
.
make_node
(
r1
,
r2
)
node
=
MyOp
.
make_node
(
r1
,
r2
)
new
=
clone
([
r1
,
r2
],
node
.
outputs
)
_
,
new
=
clone
([
r1
,
r2
],
node
.
outputs
,
False
)
assert
self
.
str
([
r1
,
r2
],
new
)
==
[
"MyOp(1, 2)"
]
assert
self
.
str
([
r1
,
r2
],
new
)
==
[
"MyOp(1, 2)"
]
def
test_copy
(
self
):
def
test_copy
(
self
):
r1
,
r2
,
r5
=
MyResult
(
1
),
MyResult
(
2
),
MyResult
(
5
)
r1
,
r2
,
r5
=
MyResult
(
1
),
MyResult
(
2
),
MyResult
(
5
)
node
=
MyOp
.
make_node
(
r1
,
r2
)
node
=
MyOp
.
make_node
(
r1
,
r2
)
node2
=
MyOp
.
make_node
(
node
.
outputs
[
0
],
r5
)
node2
=
MyOp
.
make_node
(
node
.
outputs
[
0
],
r5
)
new
=
clone
([
r1
,
r2
,
r5
],
node2
.
outputs
)
_
,
new
=
clone
([
r1
,
r2
,
r5
],
node2
.
outputs
,
False
)
assert
node2
.
outputs
[
0
]
.
type
==
new
[
0
]
.
type
and
node2
.
outputs
[
0
]
is
not
new
[
0
]
# the new output is like the old one but not the same object
assert
node2
.
outputs
[
0
]
.
type
==
new
[
0
]
.
type
and
node2
.
outputs
[
0
]
is
not
new
[
0
]
# the new output is like the old one but not the same object
assert
node2
is
not
new
[
0
]
.
owner
# the new output has a new owner
assert
node2
is
not
new
[
0
]
.
owner
# the new output has a new owner
assert
new
[
0
]
.
owner
.
inputs
[
1
]
is
r5
# the inputs are not copied
assert
new
[
0
]
.
owner
.
inputs
[
1
]
is
r5
# the inputs are not copied
...
@@ -178,7 +178,7 @@ class _test_clone(unittest.TestCase):
...
@@ -178,7 +178,7 @@ class _test_clone(unittest.TestCase):
# Checks that manipulating a cloned graph leaves the original unchanged.
# Checks that manipulating a cloned graph leaves the original unchanged.
r1
,
r2
,
r5
=
MyResult
(
1
),
MyResult
(
2
),
MyResult
(
5
)
r1
,
r2
,
r5
=
MyResult
(
1
),
MyResult
(
2
),
MyResult
(
5
)
node
=
MyOp
.
make_node
(
MyOp
.
make_node
(
r1
,
r2
)
.
outputs
[
0
],
r5
)
node
=
MyOp
.
make_node
(
MyOp
.
make_node
(
r1
,
r2
)
.
outputs
[
0
],
r5
)
new
=
clone
([
r1
,
r2
,
r5
],
node
.
outputs
)
_
,
new
=
clone
([
r1
,
r2
,
r5
],
node
.
outputs
,
False
)
new_node
=
new
[
0
]
.
owner
new_node
=
new
[
0
]
.
owner
new_node
.
inputs
=
MyResult
(
7
),
MyResult
(
8
)
new_node
.
inputs
=
MyResult
(
7
),
MyResult
(
8
)
...
...
gof/_test_link.py
浏览文件 @
ea32b4db
...
@@ -2,10 +2,12 @@
...
@@ -2,10 +2,12 @@
import
unittest
import
unittest
from
graph
import
Result
,
as_result
,
Apply
import
graph
from
graph
import
Result
,
as_result
,
Apply
,
Constant
from
type
import
Type
from
type
import
Type
from
op
import
Op
from
op
import
Op
from
env
import
Env
import
env
import
toolbox
from
link
import
*
from
link
import
*
...
@@ -67,6 +69,10 @@ def perform_linker(env):
...
@@ -67,6 +69,10 @@ def perform_linker(env):
lnk
=
PerformLinker
(
env
)
lnk
=
PerformLinker
(
env
)
return
lnk
return
lnk
def
Env
(
inputs
,
outputs
):
e
=
env
.
Env
(
inputs
,
outputs
)
return
e
class
_test_PerformLinker
(
unittest
.
TestCase
):
class
_test_PerformLinker
(
unittest
.
TestCase
):
...
@@ -94,16 +100,14 @@ class _test_PerformLinker(unittest.TestCase):
...
@@ -94,16 +100,14 @@ class _test_PerformLinker(unittest.TestCase):
def
test_input_output_same
(
self
):
def
test_input_output_same
(
self
):
x
,
y
,
z
=
inputs
()
x
,
y
,
z
=
inputs
()
a
,
d
=
add
(
x
,
y
),
div
(
x
,
y
)
fn
=
perform_linker
(
Env
([
x
],
[
x
]))
.
make_function
()
e
=
mul
(
a
,
d
)
fn
=
perform_linker
(
Env
([
e
],
[
e
]))
.
make_function
()
self
.
failUnless
(
1.0
is
fn
(
1.0
))
self
.
failUnless
(
1.0
is
fn
(
1.0
))
def
test_input_dependency0
(
self
):
def
test_input_dependency0
(
self
):
x
,
y
,
z
=
inputs
()
x
,
y
,
z
=
inputs
()
a
,
d
=
add
(
x
,
y
),
div
(
x
,
y
)
a
,
d
=
add
(
x
,
y
),
div
(
x
,
y
)
e
=
mul
(
a
,
d
)
e
=
mul
(
a
,
d
)
fn
=
perform_linker
(
Env
(
[
x
,
y
,
a
],
[
e
]
))
.
make_function
()
fn
=
perform_linker
(
Env
(
*
graph
.
clone
([
x
,
y
,
a
],
[
e
])
))
.
make_function
()
self
.
failUnless
(
fn
(
1.0
,
2.0
,
9.0
)
==
4.5
)
self
.
failUnless
(
fn
(
1.0
,
2.0
,
9.0
)
==
4.5
)
def
test_skiphole
(
self
):
def
test_skiphole
(
self
):
...
@@ -111,9 +115,11 @@ class _test_PerformLinker(unittest.TestCase):
...
@@ -111,9 +115,11 @@ class _test_PerformLinker(unittest.TestCase):
a
=
add
(
x
,
y
)
a
=
add
(
x
,
y
)
r
=
raise_err
(
a
)
r
=
raise_err
(
a
)
e
=
add
(
r
,
a
)
e
=
add
(
r
,
a
)
fn
=
perform_linker
(
Env
(
[
x
,
y
,
r
],
[
e
]
))
.
make_function
()
fn
=
perform_linker
(
Env
(
*
graph
.
clone
([
x
,
y
,
r
],
[
e
])
))
.
make_function
()
self
.
failUnless
(
fn
(
1.0
,
2.0
,
4.5
)
==
7.5
)
self
.
failUnless
(
fn
(
1.0
,
2.0
,
4.5
)
==
7.5
)
# def test_disconnected_input_output(self):
# def test_disconnected_input_output(self):
# x,y,z = inputs()
# x,y,z = inputs()
# a = add(x,y)
# a = add(x,y)
...
...
gof/_test_opt.py
浏览文件 @
ea32b4db
...
@@ -415,4 +415,3 @@ if __name__ == '__main__':
...
@@ -415,4 +415,3 @@ if __name__ == '__main__':
unittest
.
main
()
unittest
.
main
()
gof/cc.py
浏览文件 @
ea32b4db
from
graph
import
Constant
import
graph
from
graph
import
Constant
,
Value
from
link
import
Linker
,
LocalLinker
,
raise_with_op
,
Filter
,
map_storage
,
PerformLinker
from
link
import
Linker
,
LocalLinker
,
raise_with_op
,
Filter
,
map_storage
,
PerformLinker
from
copy
import
copy
from
copy
import
copy
from
utils
import
AbstractFunctionError
from
utils
import
AbstractFunctionError
...
@@ -284,10 +285,11 @@ def apply_policy(policy, r, name, sub):
...
@@ -284,10 +285,11 @@ def apply_policy(policy, r, name, sub):
@type r: L{Result}
@type r: L{Result}
@return: C{policy[0](r) + policy[1](r) + ...}
@return: C{policy[0](r) + policy[1](r) + ...}
"""
"""
if
isinstance
(
r
,
(
list
,
tuple
)):
if
isinstance
(
policy
,
(
list
,
tuple
)):
ret
=
""
ret
=
""
for
sub_policy
in
policy
:
for
sub_policy
in
policy
:
ret
+=
sub_policy
(
r
,
name
,
sub
)
ret
+=
sub_policy
(
r
,
name
,
sub
)
return
ret
return
policy
(
r
,
name
,
sub
)
return
policy
(
r
,
name
,
sub
)
...
@@ -345,7 +347,7 @@ class CLinker(Linker):
...
@@ -345,7 +347,7 @@ class CLinker(Linker):
self
.
outputs
=
env
.
outputs
self
.
outputs
=
env
.
outputs
self
.
results
=
list
(
env
.
results
)
self
.
results
=
list
(
env
.
results
)
# The orphans field is listified to ensure a consistent order.
# The orphans field is listified to ensure a consistent order.
self
.
orphans
=
list
(
env
.
orphans
.
difference
(
self
.
outputs
))
self
.
orphans
=
list
(
r
for
r
in
self
.
results
if
isinstance
(
r
,
Value
)
and
r
not
in
self
.
inputs
)
#list(
env.orphans.difference(self.outputs))
self
.
temps
=
list
(
set
(
self
.
results
)
.
difference
(
self
.
inputs
)
.
difference
(
self
.
outputs
)
.
difference
(
self
.
orphans
))
self
.
temps
=
list
(
set
(
self
.
results
)
.
difference
(
self
.
inputs
)
.
difference
(
self
.
outputs
)
.
difference
(
self
.
orphans
))
self
.
node_order
=
env
.
toposort
()
self
.
node_order
=
env
.
toposort
()
...
@@ -403,8 +405,9 @@ class CLinker(Linker):
...
@@ -403,8 +405,9 @@ class CLinker(Linker):
policy
=
[[
get_nothing
,
get_nothing
,
get_nothing
],
policy
=
[[
get_nothing
,
get_nothing
,
get_nothing
],
[
get_c_declare
,
get_c_extract
,
get_c_cleanup
]]
[
get_c_declare
,
get_c_extract
,
get_c_cleanup
]]
elif
result
in
self
.
orphans
:
elif
result
in
self
.
orphans
:
if
not
isinstance
(
result
,
Constant
):
if
not
isinstance
(
result
,
Value
):
raise
TypeError
(
"All orphans to CLinker must be Constant."
,
result
)
raise
TypeError
(
"All orphans to CLinker must be Value instances."
,
result
)
if
isinstance
(
result
,
Constant
):
try
:
try
:
symbol
[
result
]
=
"("
+
result
.
type
.
c_literal
(
result
.
data
)
+
")"
symbol
[
result
]
=
"("
+
result
.
type
.
c_literal
(
result
.
data
)
+
")"
consts
.
append
(
result
)
consts
.
append
(
result
)
...
@@ -428,7 +431,6 @@ class CLinker(Linker):
...
@@ -428,7 +431,6 @@ class CLinker(Linker):
elif
result
in
self
.
outputs
:
elif
result
in
self
.
outputs
:
# outputs don't need to be extracted from Python, so we call c_init rather than c_extract
# outputs don't need to be extracted from Python, so we call c_init rather than c_extract
if
result
.
type
.
c_is_simple
()
or
result
in
no_recycling
:
if
result
.
type
.
c_is_simple
()
or
result
in
no_recycling
:
policy
=
[[
get_nothing
,
get_nothing
,
get_nothing
],
policy
=
[[
get_nothing
,
get_nothing
,
get_nothing
],
[
get_c_declare
,
get_c_init
,
(
get_c_sync
,
get_c_cleanup
)]]
[
get_c_declare
,
get_c_init
,
(
get_c_sync
,
get_c_cleanup
)]]
else
:
else
:
...
@@ -599,7 +601,12 @@ class CLinker(Linker):
...
@@ -599,7 +601,12 @@ class CLinker(Linker):
if
input_storage
is
None
:
if
input_storage
is
None
:
input_storage
=
[[
None
]
for
result
in
self
.
inputs
]
input_storage
=
[[
None
]
for
result
in
self
.
inputs
]
if
output_storage
is
None
:
if
output_storage
is
None
:
output_storage
=
[[
None
]
for
result
in
self
.
outputs
]
map
=
{}
output_storage
=
[]
for
result
in
self
.
outputs
:
if
result
not
in
map
:
map
[
result
]
=
[
None
]
output_storage
.
append
(
map
[
result
])
thunk
=
self
.
cthunk_factory
(
error_storage
,
thunk
=
self
.
cthunk_factory
(
error_storage
,
input_storage
,
input_storage
,
output_storage
)
output_storage
)
...
@@ -642,13 +649,13 @@ class CLinker(Linker):
...
@@ -642,13 +649,13 @@ class CLinker(Linker):
if
not
getattr
(
self
,
'instantiate'
,
False
):
if
not
getattr
(
self
,
'instantiate'
,
False
):
self
.
code_gen
()
self
.
code_gen
()
module_name
=
self
.
hash
# Eliminate duplicate inputs and outputs from the storage that we will pass to instantiate
# Eliminate duplicate inputs and outputs from the storage that we will pass to instantiate
out_storage
=
[
x
for
i
,
x
in
enumerate
(
out_storage
)
if
(
i
+
len
(
in_storage
))
not
in
self
.
dupidx
]
out_storage
=
[
x
for
i
,
x
in
enumerate
(
out_storage
)
if
(
i
+
len
(
in_storage
))
not
in
self
.
dupidx
]
in_storage
=
[
x
for
i
,
x
in
enumerate
(
in_storage
)
if
i
not
in
self
.
dupidx
]
in_storage
=
[
x
for
i
,
x
in
enumerate
(
in_storage
)
if
i
not
in
self
.
dupidx
]
cthunk
=
object
()
# dummy so weave can get the type
cthunk
=
object
()
# dummy so weave can get the type
module_name
=
self
.
hash
mod
=
weave
.
ext_tools
.
ext_module
(
module_name
)
mod
=
weave
.
ext_tools
.
ext_module
(
module_name
)
argnames
=
[
"i
%
i"
%
i
for
i
in
xrange
(
len
(
in_storage
))]
\
argnames
=
[
"i
%
i"
%
i
for
i
in
xrange
(
len
(
in_storage
))]
\
...
@@ -710,8 +717,11 @@ class CLinker(Linker):
...
@@ -710,8 +717,11 @@ class CLinker(Linker):
# Eliminate duplicate inputs and outputs from the storage that we will pass to instantiate
# Eliminate duplicate inputs and outputs from the storage that we will pass to instantiate
out_storage
=
[
x
for
i
,
x
in
enumerate
(
out_storage
)
if
(
i
+
len
(
in_storage
))
not
in
self
.
dupidx
]
out_storage
=
[
x
for
i
,
x
in
enumerate
(
out_storage
)
if
(
i
+
len
(
in_storage
))
not
in
self
.
dupidx
]
in_storage
=
[
x
for
i
,
x
in
enumerate
(
in_storage
)
if
i
not
in
self
.
dupidx
]
in_storage
=
[
x
for
i
,
x
in
enumerate
(
in_storage
)
if
i
not
in
self
.
dupidx
]
module_name
=
self
.
hash
module
=
__import__
(
"
%
s"
%
(
module_name
),
{},
{},
[
module_name
])
ret
=
module
.
instantiate
(
error_storage
,
*
(
in_storage
+
out_storage
+
[
orphan
.
data
for
orphan
in
self
.
orphans
]))
orphd
=
[[
orphan
.
data
]
for
orphan
in
self
.
orphans
]
ret
=
module
.
instantiate
(
error_storage
,
*
(
in_storage
+
out_storage
+
orphd
))
assert
sys
.
getrefcount
(
ret
)
==
2
# refcount leak check
assert
sys
.
getrefcount
(
ret
)
==
2
# refcount leak check
return
ret
return
ret
...
@@ -751,7 +761,9 @@ class OpWiseCLinker(LocalLinker):
...
@@ -751,7 +761,9 @@ class OpWiseCLinker(LocalLinker):
node_input_storage
=
[
storage_map
[
r
]
for
r
in
node
.
inputs
]
node_input_storage
=
[
storage_map
[
r
]
for
r
in
node
.
inputs
]
node_output_storage
=
[
storage_map
[
r
]
for
r
in
node
.
outputs
]
node_output_storage
=
[
storage_map
[
r
]
for
r
in
node
.
outputs
]
try
:
try
:
cl
=
CLinker
(
Env
(
node
.
inputs
,
node
.
outputs
))
e
=
Env
(
*
graph
.
clone
(
node
.
inputs
,
node
.
outputs
))
e
.
toposort
=
lambda
:
e
.
nodes
cl
=
CLinker
(
e
,
[
r
for
r
,
r2
in
zip
(
e
.
outputs
,
node
.
outputs
)
if
r2
in
no_recycling
])
thunk
,
node_input_filters
,
node_output_filters
=
cl
.
make_thunk
(
thunk
,
node_input_filters
,
node_output_filters
=
cl
.
make_thunk
(
input_storage
=
node_input_storage
,
input_storage
=
node_input_storage
,
output_storage
=
node_output_storage
)
output_storage
=
node_output_storage
)
...
@@ -823,7 +835,7 @@ class DualLinker(Linker):
...
@@ -823,7 +835,7 @@ class DualLinker(Linker):
function.
function.
"""
"""
def
__init__
(
self
,
env
,
checker
=
_default_checker
):
def
__init__
(
self
,
env
,
checker
=
_default_checker
,
no_recycling
=
[]
):
"""
"""
Initialize a DualLinker.
Initialize a DualLinker.
...
@@ -844,6 +856,7 @@ class DualLinker(Linker):
...
@@ -844,6 +856,7 @@ class DualLinker(Linker):
"""
"""
self
.
env
=
env
self
.
env
=
env
self
.
checker
=
checker
self
.
checker
=
checker
self
.
no_recycling
=
no_recycling
def
make_thunk
(
self
,
**
kwargs
):
def
make_thunk
(
self
,
**
kwargs
):
# if inplace:
# if inplace:
...
@@ -865,8 +878,10 @@ class DualLinker(Linker):
...
@@ -865,8 +878,10 @@ class DualLinker(Linker):
# thunks2 = [c_make_thunk(op) for op in op_order_2]
# thunks2 = [c_make_thunk(op) for op in op_order_2]
env
=
self
.
env
env
=
self
.
env
_f
,
i1
,
o1
,
thunks1
,
order1
=
PerformLinker
(
env
)
.
make_all
(
**
kwargs
)
no_recycling
=
self
.
no_recycling
_f
,
i2
,
o2
,
thunks2
,
order2
=
OpWiseCLinker
(
env
)
.
make_all
(
**
kwargs
)
_f
,
i1
,
o1
,
thunks1
,
order1
=
PerformLinker
(
env
,
no_recycling
=
no_recycling
)
.
make_all
(
**
kwargs
)
_f
,
i2
,
o2
,
thunks2
,
order2
=
OpWiseCLinker
(
env
,
no_recycling
=
no_recycling
)
.
make_all
(
**
kwargs
)
def
f
():
def
f
():
for
input1
,
input2
in
zip
(
i1
,
i2
):
for
input1
,
input2
in
zip
(
i1
,
i2
):
...
@@ -874,6 +889,12 @@ class DualLinker(Linker):
...
@@ -874,6 +889,12 @@ class DualLinker(Linker):
# the copy is necessary in order for inplace ops not to interfere
# the copy is necessary in order for inplace ops not to interfere
input2
.
storage
[
0
]
=
copy
(
input1
.
storage
[
0
])
input2
.
storage
[
0
]
=
copy
(
input1
.
storage
[
0
])
for
thunk1
,
thunk2
,
node1
,
node2
in
zip
(
thunks1
,
thunks2
,
order1
,
order2
):
for
thunk1
,
thunk2
,
node1
,
node2
in
zip
(
thunks1
,
thunks2
,
order1
,
order2
):
for
output
,
storage
in
zip
(
node1
.
outputs
,
thunk1
.
outputs
):
if
output
in
no_recycling
:
storage
[
0
]
=
None
for
output
,
storage
in
zip
(
node2
.
outputs
,
thunk2
.
outputs
):
if
output
in
no_recycling
:
storage
[
0
]
=
None
try
:
try
:
thunk1
()
thunk1
()
thunk2
()
thunk2
()
...
...
gof/env.py
浏览文件 @
ea32b4db
...
@@ -26,15 +26,7 @@ class Env(object): #(graph.Graph):
...
@@ -26,15 +26,7 @@ class Env(object): #(graph.Graph):
The Env supports the replace operation which allows to replace a
The Env supports the replace operation which allows to replace a
result in the subgraph by another, e.g. replace (x + x).out by (2
result in the subgraph by another, e.g. replace (x + x).out by (2
* x).out. This is the basis for optimization in omega.
* x).out. This is the basis for optimization in theano.
Regarding inputs and orphans:
In the context of a computation graph, the inputs and orphans are
both results that are the source nodes of computation. Those
results that are named as inputs will be assumed to contain fresh.
In other words, the backward search from outputs will stop at any
node that has been explicitly named as an input.
"""
"""
### Special ###
### Special ###
...
@@ -69,10 +61,6 @@ class Env(object): #(graph.Graph):
...
@@ -69,10 +61,6 @@ class Env(object): #(graph.Graph):
self
.
node_locks
=
{}
self
.
node_locks
=
{}
self
.
result_locks
=
{}
self
.
result_locks
=
{}
# # List of functions that undo the replace operations performed.
# # e.g. to recover the initial graph one could write: for u in self.history.__reversed__(): u()
# self.history = []
### Setup a Result ###
### Setup a Result ###
...
@@ -237,99 +225,13 @@ class Env(object): #(graph.Graph):
...
@@ -237,99 +225,13 @@ class Env(object): #(graph.Graph):
raise
TypeError
(
"The type of the replacement must be the same as the type of the original Result."
,
r
,
new_r
)
raise
TypeError
(
"The type of the replacement must be the same as the type of the original Result."
,
r
,
new_r
)
assert
r
in
self
.
results
assert
r
in
self
.
results
for
node
,
i
in
r
.
clients
:
for
node
,
i
in
list
(
r
.
clients
)
:
assert
node
==
'output'
and
self
.
outputs
[
i
]
is
r
or
node
.
inputs
[
i
]
is
r
assert
node
==
'output'
and
self
.
outputs
[
i
]
is
r
or
node
.
inputs
[
i
]
is
r
self
.
change_input
(
node
,
i
,
new_r
)
self
.
change_input
(
node
,
i
,
new_r
)
# # Save where we are so we can backtrack
def
replace_all
(
self
,
pairs
):
# if consistency_check:
for
r
,
new_r
in
pairs
:
# chk = self.checkpoint()
self
.
replace
(
r
,
new_r
)
# # The copy is required so undo can know what clients to move back!
# clients = copy(self.clients(r))
# # Messy checks so we know what to do if we are replacing an output
# # result. Note that if v is an input result, we do nothing at all for
# # now (it's not clear what it means to replace an input result).
# was_output = False
# if r in self.outputs:
# was_output = True
# self.outputs[self.outputs.index(r)] = new_r
# was_input = False
# if r in self.inputs:
# was_input = True
# self.inputs[self.inputs.index(r)] = new_r
# # The actual replacement operation occurs here. This might raise
# # an error.
# self.__move_clients__(clients, r, new_r) # not sure how to order this wrt to adjusting the outputs
# # This function undoes the replacement.
# def undo():
# # Restore self.outputs
# if was_output:
# self.outputs[self.outputs.index(new_r)] = r
# # Restore self.inputs
# if was_input:
# self.inputs[self.inputs.index(new_r)] = r
# # Move back the clients. This should never raise an error.
# self.__move_clients__(clients, new_r, r)
# self.history.append(undo)
# if consistency_check:
# try:
# self.validate()
# except InconsistencyError, e:
# self.revert(chk)
# raise
def
replace_all
(
self
,
d
):
"""
For (r, new_r) in d.items(), replaces r with new_r. Checks for
consistency at the end and raises an InconsistencyError if the
graph is not consistent. If an error is raised, the graph is
restored to what it was before.
"""
for
r
,
new_r
in
d
.
items
():
self
.
replace
(
r
,
new_r
,
False
)
# chk = self.checkpoint()
# try:
# for r, new_r in d.items():
# self.replace(r, new_r, False)
# except Exception, e:
# self.revert(chk)
# raise
# try:
# self.validate()
# except InconsistencyError, e:
# self.revert(chk)
# raise
# def checkpoint(self):
# """
# Returns an object that can be passed to self.revert in order to backtrack
# to a previous state.
# """
# return len(self.history)
# def consistent(self):
# """
# Returns True iff the subgraph is consistent and does not violate the
# constraints set by the listeners.
# """
# try:
# self.validate()
# except InconsistencyError:
# return False
# return True
### features ###
### features ###
...
@@ -386,6 +288,16 @@ class Env(object): #(graph.Graph):
...
@@ -386,6 +288,16 @@ class Env(object): #(graph.Graph):
### misc ###
### misc ###
def
toposort
(
self
):
env
=
self
ords
=
{}
for
feature
in
env
.
_features
:
if
hasattr
(
feature
,
'orderings'
):
for
op
,
prereqs
in
feature
.
orderings
(
env
)
.
items
():
ords
.
setdefault
(
op
,
set
())
.
update
(
prereqs
)
order
=
graph
.
io_toposort
(
env
.
inputs
,
env
.
outputs
,
ords
)
return
order
def
nclients
(
self
,
r
):
def
nclients
(
self
,
r
):
"Same as len(self.clients(r))."
"Same as len(self.clients(r))."
return
len
(
self
.
clients
(
r
))
return
len
(
self
.
clients
(
r
))
...
@@ -439,117 +351,9 @@ class Env(object): #(graph.Graph):
...
@@ -439,117 +351,9 @@ class Env(object): #(graph.Graph):
if
node
.
inputs
[
i
]
is
not
result
:
if
node
.
inputs
[
i
]
is
not
result
:
raise
Exception
(
"Inconsistent clients list."
,
result
,
node
.
inputs
[
i
])
raise
Exception
(
"Inconsistent clients list."
,
result
,
node
.
inputs
[
i
])
# def revert(self, checkpoint):
# """
# Reverts the graph to whatever it was at the provided
# checkpoint (undoes all replacements). A checkpoint at any
# given time can be obtained using self.checkpoint().
# """
# while len(self.history) > checkpoint:
# f = self.history.pop()
# f()
# def supplemental_orderings(self):
# """
# Returns a dictionary of {op: set(prerequisites)} that must
# be satisfied in addition to the order defined by the structure
# of the graph (returns orderings that not related to input/output
# relationships).
# """
# ords = {}
# for feature in self._features:
# if hasattr(feature, 'orderings'):
# for op, prereqs in feature.orderings().items():
# ords.setdefault(op, set()).update(prereqs)
# return ords
# def toposort(self):
# """
# Returns a list of nodes in the order that they must be executed
# in order to preserve the semantics of the graph and respect
# the constraints put forward by the listeners.
# """
# ords = self.supplemental_orderings()
# order = graph.io_toposort(self.inputs, self.outputs, ords)
# return order
# def validate(self):
# """
# Raises an error if the graph is inconsistent.
# """
# self.execute_callbacks('validate')
# # for constraint in self._constraints.values():
# # constraint.validate()
# return True
### Private interface ###
# def __move_clients__(self, clients, r, new_r):
# if not (r.type == new_r.type):
# raise TypeError("Cannot move clients between Results that have different types.", r, new_r)
# # We import the new result in the fold
# self.__import_r__([new_r])
# for op, i in clients:
# op.inputs[i] = new_r
# # try:
# # # Try replacing the inputs
# # for op, i in clients:
# # op.set_input(i, new_r)
# # except:
# # # Oops!
# # for op, i in clients:
# # op.set_input(i, r)
# # self.__prune_r__([new_r])
# # raise
# self.__remove_clients__(r, clients)
# self.__add_clients__(new_r, clients)
# # # We import the new result in the fold
# # # why was this line AFTER the set_inputs???
# # # if we do it here then satisfy in import fucks up...
# # self.__import_r__([new_r])
# self.execute_callbacks('on_rewire', clients, r, new_r)
# # for listener in self._listeners.values():
# # try:
# # listener.on_rewire(clients, r, new_r)
# # except AbstractFunctionError:
# # pass
# # We try to get rid of the old one
# self.__prune_r__([r])
def
__str__
(
self
):
def
__str__
(
self
):
return
"[
%
s]"
%
", "
.
join
(
graph
.
as_string
(
self
.
inputs
,
self
.
outputs
))
return
"[
%
s]"
%
", "
.
join
(
graph
.
as_string
(
self
.
inputs
,
self
.
outputs
))
# def clone_get_equiv(self, clone_inputs = True):
# equiv = graph.clone_get_equiv(self.inputs, self.outputs, clone_inputs)
# new = self.__class__([equiv[input] for input in self.inputs],
# [equiv[output] for output in self.outputs])
# for feature in self._features:
# new.extend(feature)
# return new, equiv
# def clone(self, clone_inputs = True):
# equiv = graph.clone_get_equiv(self.inputs, self.outputs, clone_inputs)
# new = self.__class__([equiv[input] for input in self.inputs],
# [equiv[output] for output in self.outputs])
# for feature in self._features:
# new.extend(feature)
# try:
# new.set_equiv(equiv)
# except AttributeError:
# pass
# return new
# def __copy__(self):
# return self.clone()
...
...
gof/ext.py
浏览文件 @
ea32b4db
#from features import Listener, Constraint, Orderings, Tool
#from features import Listener, Constraint, Orderings, Tool
import
graph
import
utils
import
utils
from
utils
import
AbstractFunctionError
from
utils
import
AbstractFunctionError
...
@@ -253,7 +256,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
...
@@ -253,7 +256,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
"""
"""
self
.
seen
.
add
(
op
)
self
.
seen
.
add
(
op
)
op
.
deps
[
'destroy'
]
=
[]
view_map
,
destroy_map
=
self
.
get_maps
(
op
)
view_map
,
destroy_map
=
self
.
get_maps
(
op
)
for
input
in
op
.
inputs
:
for
input
in
op
.
inputs
:
...
@@ -334,7 +336,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
...
@@ -334,7 +336,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
del
self
.
children
[
output
]
del
self
.
children
[
output
]
self
.
seen
.
remove
(
op
)
self
.
seen
.
remove
(
op
)
del
op
.
deps
[
'destroy'
]
def
__add_destroyer__
(
self
,
path
):
def
__add_destroyer__
(
self
,
path
):
...
@@ -350,9 +351,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
...
@@ -350,9 +351,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
destroyers
=
self
.
destroyers
.
setdefault
(
foundation
,
{})
destroyers
=
self
.
destroyers
.
setdefault
(
foundation
,
{})
path
=
destroyers
.
setdefault
(
node
,
path
)
path
=
destroyers
.
setdefault
(
node
,
path
)
print
"add"
,
path
node
.
deps
[
'destroy'
]
+=
[
user
.
owner
for
user
in
self
.
__users__
(
foundation
)
if
user
not
in
node
.
outputs
]
# for foundation, destroyers in self.destroyers.items():
# for foundation, destroyers in self.destroyers.items():
# for op in destroyers.keys():
# for op in destroyers.keys():
# ords.setdefault(op, set()).update([user.owner for user in self.__users__(foundation) if user not in op.outputs])
# ords.setdefault(op, set()).update([user.owner for user in self.__users__(foundation) if user not in op.outputs])
...
@@ -361,7 +359,7 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
...
@@ -361,7 +359,7 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
self
.
dups
.
add
(
foundation
)
self
.
dups
.
add
(
foundation
)
# results marked 'indestructible' must not be destroyed.
# results marked 'indestructible' must not be destroyed.
if
getattr
(
foundation
,
'indestructible'
,
False
):
if
getattr
(
foundation
,
'indestructible'
,
False
)
or
isinstance
(
foundation
,
graph
.
Constant
)
:
self
.
illegal
.
add
(
foundation
)
self
.
illegal
.
add
(
foundation
)
...
@@ -374,13 +372,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
...
@@ -374,13 +372,6 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
target
=
path
[
-
1
]
target
=
path
[
-
1
]
node
=
target
.
owner
node
=
target
.
owner
print
"rm"
,
path
print
node
.
deps
[
'destroy'
]
for
user
in
self
.
__users__
(
foundation
):
print
" -- "
,
user
if
user
not
in
node
.
outputs
:
node
.
deps
[
'destroy'
]
.
remove
(
user
.
owner
)
destroyers
=
self
.
destroyers
[
foundation
]
destroyers
=
self
.
destroyers
[
foundation
]
del
destroyers
[
node
]
del
destroyers
[
node
]
...
@@ -477,6 +468,7 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
...
@@ -477,6 +468,7 @@ class DestroyHandler(Bookkeeper): #(Listener, Constraint, Orderings, Tool):
In particular, all the users of a destroyed result have priority over the
In particular, all the users of a destroyed result have priority over the
L{Op} that destroys the result.
L{Op} that destroys the result.
"""
"""
self
.
validate
(
env
)
ords
=
{}
ords
=
{}
for
foundation
,
destroyers
in
self
.
destroyers
.
items
():
for
foundation
,
destroyers
in
self
.
destroyers
.
items
():
for
op
in
destroyers
.
keys
():
for
op
in
destroyers
.
keys
():
...
...
gof/graph.py
浏览文件 @
ea32b4db
...
@@ -163,7 +163,6 @@ def as_apply(x):
...
@@ -163,7 +163,6 @@ def as_apply(x):
@deprecated
@deprecated
def
inputs
(
o
):
def
inputs
(
o
):
"""
"""
...
@@ -173,7 +172,6 @@ def inputs(o):
...
@@ -173,7 +172,6 @@ def inputs(o):
Returns the set of inputs necessary to compute the outputs in o
Returns the set of inputs necessary to compute the outputs in o
such that input.owner is None.
such that input.owner is None.
"""
"""
print
'gof.graph.inputs deprecated: April 29'
results
=
set
()
results
=
set
()
def
seek
(
r
):
def
seek
(
r
):
op
=
r
.
owner
op
=
r
.
owner
...
@@ -187,53 +185,71 @@ def inputs(o):
...
@@ -187,53 +185,71 @@ def inputs(o):
return
results
return
results
def
results_and_orphans
(
i
,
o
,
except_unreachable_input
=
False
):
# def results_and_orphans(i, o, except_unreachable_input=False):
"""
# """
@type i: list
# @type i: list
@param i: input L{Result}s
# @param i: input L{Result}s
@type o: list
# @type o: list
@param o: output L{Result}s
# @param o: output L{Result}s
# Returns the pair (results, orphans). The former is the set of
# L{Result}s that are involved in the subgraph that lies between i and
# o. This includes i, o, orphans(i, o) and all results of all
# intermediary steps from i to o. The second element of the returned
# pair is orphans(i, o).
# """
# results = set()
# i = set(i)
# # results.update(i)
# incomplete_paths = []
# reached = set()
# def helper(r, path):
# if r in i:
# reached.add(r)
# results.update(path)
# elif r.owner is None:
# incomplete_paths.append(path)
# else:
# op = r.owner
# for r2 in op.inputs:
# helper(r2, path + [r2])
Returns the pair (results, orphans). The former is the set of
# for output in o:
L{Result}s that are involved in the subgraph that lies between i and
# helper(output, [output])
o. This includes i, o, orphans(i, o) and all results of all
intermediary steps from i to o. The second element of the returned
pair is orphans(i, o).
"""
results
=
set
()
i
=
set
(
i
)
# results.update(i)
incomplete_paths
=
[]
reached
=
set
()
def
helper
(
r
,
path
):
if
r
in
i
:
reached
.
add
(
r
)
results
.
update
(
path
)
elif
r
.
owner
is
None
:
incomplete_paths
.
append
(
path
)
else
:
op
=
r
.
owner
for
r2
in
op
.
inputs
:
helper
(
r2
,
path
+
[
r2
])
for
output
in
o
:
# orphans = set()
helper
(
output
,
[
output
])
# for path in incomplete_paths:
# for r in path:
# if r not in results:
# orphans.add(r)
# break
orphans
=
set
()
# if except_unreachable_input and len(i) != len(reached):
for
path
in
incomplete_paths
:
# raise Exception(results_and_orphans.E_unreached)
for
r
in
path
:
if
r
not
in
results
:
orphans
.
add
(
r
)
break
if
except_unreachable_input
and
len
(
i
)
!=
len
(
reached
):
# results.update(orphans)
raise
Exception
(
results_and_orphans
.
E_unreached
)
results
.
update
(
orphans
)
# return results, orphans
# results_and_orphans.E_unreached = 'there were unreachable inputs'
def
results_and_orphans
(
i
,
o
):
results
=
set
()
orphans
=
set
()
def
helper
(
r
):
if
r
in
results
:
return
results
.
add
(
r
)
if
r
.
owner
is
None
:
if
r
not
in
i
:
orphans
.
add
(
r
)
else
:
for
r2
in
r
.
owner
.
inputs
:
helper
(
r2
)
for
output
in
o
:
helper
(
output
)
return
results
,
orphans
return
results
,
orphans
results_and_orphans
.
E_unreached
=
'there were unreachable inputs'
def
ops
(
i
,
o
):
def
ops
(
i
,
o
):
...
...
gof/link.py
浏览文件 @
ea32b4db
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
from
utils
import
AbstractFunctionError
from
utils
import
AbstractFunctionError
import
utils
import
utils
from
graph
import
Constant
from
graph
import
Value
import
sys
import
sys
import
traceback
import
traceback
...
@@ -135,16 +135,20 @@ def map_storage(env, order, input_storage, output_storage):
...
@@ -135,16 +135,20 @@ def map_storage(env, order, input_storage, output_storage):
storage_map
=
{}
storage_map
=
{}
for
r
,
storage
in
zip
(
env
.
inputs
,
input_storage
):
for
r
,
storage
in
zip
(
env
.
inputs
,
input_storage
):
storage_map
[
r
]
=
storage
storage_map
[
r
]
=
storage
for
orphan
in
env
.
orphans
:
#
for orphan in env.orphans:
if
not
isinstance
(
orphan
,
Constant
):
#
if not isinstance(orphan, Constant):
raise
TypeError
(
"Cannot link a graph with non-constant orphans."
,
orphan
)
#
raise TypeError("Cannot link a graph with non-constant orphans.", orphan)
storage_map
[
orphan
]
=
[
orphan
.
data
]
#
storage_map[orphan] = [orphan.data]
if
output_storage
is
not
None
:
if
output_storage
is
not
None
:
assert
len
(
env
.
outputs
)
==
len
(
output_storage
)
assert
len
(
env
.
outputs
)
==
len
(
output_storage
)
for
r
,
storage
in
zip
(
env
.
outputs
,
output_storage
):
for
r
,
storage
in
zip
(
env
.
outputs
,
output_storage
):
storage_map
[
r
]
=
storage
storage_map
[
r
]
=
storage
thunks
=
[]
thunks
=
[]
for
node
in
order
:
for
node
in
order
:
for
r
in
node
.
inputs
:
if
r
not
in
storage_map
:
assert
isinstance
(
r
,
Value
)
storage_map
[
r
]
=
[
r
.
data
]
for
r
in
node
.
outputs
:
for
r
in
node
.
outputs
:
storage_map
.
setdefault
(
r
,
[
None
])
storage_map
.
setdefault
(
r
,
[
None
])
...
...
gof/opt.py
浏览文件 @
ea32b4db
...
@@ -430,11 +430,16 @@ class MergeOptimizer(Optimizer):
...
@@ -430,11 +430,16 @@ class MergeOptimizer(Optimizer):
are constant.
are constant.
"""
"""
def
add_requirements
(
self
,
env
):
try
:
env
.
extend
(
toolbox
.
ReplaceValidate
())
except
:
pass
def
apply
(
self
,
env
):
def
apply
(
self
,
env
):
cid
=
_metadict
()
#result -> result.desc() (for constants)
cid
=
_metadict
()
#result -> result.desc() (for constants)
inv_cid
=
_metadict
()
#desc -> result (for constants)
inv_cid
=
_metadict
()
#desc -> result (for constants)
for
i
,
r
in
enumerate
(
env
.
orphans
.
union
(
env
.
inputs
)):
for
i
,
r
in
enumerate
(
[
r
for
r
in
env
.
results
if
isinstance
(
r
,
Constant
)]):
#
env.orphans.union(env.inputs)):
if
isinstance
(
r
,
Constant
):
#
if isinstance(r, Constant):
sig
=
r
.
signature
()
sig
=
r
.
signature
()
other_r
=
inv_cid
.
get
(
sig
,
None
)
other_r
=
inv_cid
.
get
(
sig
,
None
)
if
other_r
is
not
None
:
if
other_r
is
not
None
:
...
@@ -446,20 +451,19 @@ class MergeOptimizer(Optimizer):
...
@@ -446,20 +451,19 @@ class MergeOptimizer(Optimizer):
# and it's more efficient to give them an integer cid like the other Results
# and it's more efficient to give them an integer cid like the other Results
cid
.
clear
()
cid
.
clear
()
inv_cid
.
clear
()
inv_cid
.
clear
()
for
i
,
r
in
enumerate
(
env
.
orphans
.
union
(
env
.
inputs
)
):
for
i
,
r
in
enumerate
(
r
for
r
in
env
.
results
if
r
.
owner
is
None
):
cid
[
r
]
=
i
cid
[
r
]
=
i
inv_cid
[
i
]
=
r
inv_cid
[
i
]
=
r
for
node
in
env
.
io_toposort
(
):
for
node
in
graph
.
io_toposort
(
env
.
inputs
,
env
.
outputs
):
node_cid
=
(
node
.
op
,
tuple
([
cid
[
input
]
for
input
in
node
.
inputs
]))
node_cid
=
(
node
.
op
,
tuple
([
cid
[
input
]
for
input
in
node
.
inputs
]))
dup
=
inv_cid
.
get
(
node_cid
,
None
)
dup
=
inv_cid
.
get
(
node_cid
,
None
)
success
=
False
success
=
False
if
dup
is
not
None
:
if
dup
is
not
None
:
success
=
True
success
=
True
d
=
dict
(
zip
(
node
.
outputs
,
dup
.
outputs
))
try
:
try
:
env
.
replace_all
(
d
)
env
.
replace_all
_validate
(
zip
(
node
.
outputs
,
dup
.
outputs
)
)
except
Exception
,
e
:
except
InconsistencyError
,
e
:
success
=
False
success
=
False
if
not
success
:
if
not
success
:
cid
[
node
]
=
node_cid
cid
[
node
]
=
node_cid
...
...
gof/toolbox.py
浏览文件 @
ea32b4db
...
@@ -16,6 +16,51 @@ class Bookkeeper:
...
@@ -16,6 +16,51 @@ class Bookkeeper:
self
.
on_prune
(
env
,
node
)
self
.
on_prune
(
env
,
node
)
class
Toposorter
:
def
on_attach
(
self
,
env
):
if
hasattr
(
env
,
'toposort'
):
raise
Exception
(
"Toposorter feature is already present or in conflict with another plugin."
)
env
.
toposort
=
partial
(
self
.
toposort
,
env
)
def
on_deattach
(
self
,
env
):
del
env
.
toposort
def
toposort
(
self
,
env
):
ords
=
{}
for
feature
in
env
.
_features
:
if
hasattr
(
feature
,
'orderings'
):
for
op
,
prereqs
in
feature
.
orderings
(
env
)
.
items
():
ords
.
setdefault
(
op
,
set
())
.
update
(
prereqs
)
order
=
graph
.
io_toposort
(
env
.
inputs
,
env
.
outputs
,
ords
)
return
order
# def supplemental_orderings(self):
# """
# Returns a dictionary of {op: set(prerequisites)} that must
# be satisfied in addition to the order defined by the structure
# of the graph (returns orderings that not related to input/output
# relationships).
# """
# ords = {}
# for feature in self._features:
# if hasattr(feature, 'orderings'):
# for op, prereqs in feature.orderings().items():
# ords.setdefault(op, set()).update(prereqs)
# return ords
# def toposort(self):
# """
# Returns a list of nodes in the order that they must be executed
# in order to preserve the semantics of the graph and respect
# the constraints put forward by the listeners.
# """
# ords = self.supplemental_orderings()
# order = graph.io_toposort(self.inputs, self.outputs, ords)
# return order
class
History
:
class
History
:
def
__init__
(
self
):
def
__init__
(
self
):
...
...
scalar.py
浏览文件 @
ea32b4db
...
@@ -25,10 +25,6 @@ def as_scalar(x, name = None):
...
@@ -25,10 +25,6 @@ def as_scalar(x, name = None):
if
not
isinstance
(
x
.
type
,
Scalar
):
if
not
isinstance
(
x
.
type
,
Scalar
):
raise
TypeError
(
"Result type field must be a Scalar."
,
x
,
x
.
type
)
raise
TypeError
(
"Result type field must be a Scalar."
,
x
,
x
.
type
)
return
x
return
x
if
isinstance
(
x
,
Constant
):
if
not
isinstance
(
x
.
type
,
Scalar
):
raise
TypeError
(
"Constant type field must be a Scalar."
,
x
,
x
.
type
)
return
x
try
:
try
:
return
constant
(
x
)
return
constant
(
x
)
except
TypeError
:
except
TypeError
:
...
@@ -582,7 +578,7 @@ tanh = Tanh(upgrade_to_float, name = 'tanh')
...
@@ -582,7 +578,7 @@ tanh = Tanh(upgrade_to_float, name = 'tanh')
class
Composite
(
ScalarOp
):
class
Composite
(
ScalarOp
):
def
__init__
(
self
,
inputs
,
outputs
):
def
__init__
(
self
,
inputs
,
outputs
):
env
=
Env
(
inputs
,
outputs
)
.
clone
(
)
env
=
Env
(
*
gof
.
graph
.
clone
(
inputs
,
outputs
)
)
inputs
,
outputs
=
env
.
inputs
,
env
.
outputs
inputs
,
outputs
=
env
.
inputs
,
env
.
outputs
for
node
in
env
.
nodes
:
for
node
in
env
.
nodes
:
...
@@ -594,7 +590,8 @@ class Composite(ScalarOp):
...
@@ -594,7 +590,8 @@ class Composite(ScalarOp):
zip
(
outputs
,
zip
(
outputs
,
[
"
%%
(o
%
i)s"
%
i
for
i
in
range
(
len
(
outputs
))]))
[
"
%%
(o
%
i)s"
%
i
for
i
in
range
(
len
(
outputs
))]))
for
orphan
in
env
.
orphans
:
for
orphan
in
env
.
results
:
#env.orphans:
if
orphan
.
owner
is
None
and
orphan
not
in
env
.
inputs
:
if
isinstance
(
orphan
,
Constant
):
if
isinstance
(
orphan
,
Constant
):
subd
[
orphan
]
=
orphan
.
type
.
c_literal
(
orphan
.
data
)
subd
[
orphan
]
=
orphan
.
type
.
c_literal
(
orphan
.
data
)
else
:
else
:
...
@@ -611,7 +608,7 @@ class Composite(ScalarOp):
...
@@ -611,7 +608,7 @@ class Composite(ScalarOp):
name
=
"V
%%(id)
s_tmp
%
i"
%
i
name
=
"V
%%(id)
s_tmp
%
i"
%
i
subd
[
output
]
=
name
subd
[
output
]
=
name
_c_code
+=
"
%
s
%
s;
\n
"
%
(
output
.
type
.
dtype_specs
()[
1
],
name
)
_c_code
+=
"
%
s
%
s;
\n
"
%
(
output
.
type
.
dtype_specs
()[
1
],
name
)
_c_code
+=
node
.
op
.
c_code
(
node
.
inputs
,
_c_code
+=
node
.
op
.
c_code
(
node
,
"
%(name)
s"
,
"
%(name)
s"
,
[
subd
[
input
]
for
input
in
node
.
inputs
],
[
subd
[
input
]
for
input
in
node
.
inputs
],
[
subd
[
output
]
for
output
in
node
.
outputs
],
[
subd
[
output
]
for
output
in
node
.
outputs
],
...
@@ -629,7 +626,7 @@ class Composite(ScalarOp):
...
@@ -629,7 +626,7 @@ class Composite(ScalarOp):
if
r
in
env
.
inputs
:
if
r
in
env
.
inputs
:
idx
=
env
.
inputs
.
index
(
r
)
idx
=
env
.
inputs
.
index
(
r
)
return
lambda
inputs
:
inputs
[
idx
]
return
lambda
inputs
:
inputs
[
idx
]
elif
r
in
env
.
orphans
:
elif
r
.
owner
is
None
:
#
in env.orphans:
return
lambda
inputs
:
r
.
data
return
lambda
inputs
:
r
.
data
node
=
r
.
owner
node
=
r
.
owner
producers
=
[
compose_impl
(
input
)
for
input
in
node
.
inputs
]
producers
=
[
compose_impl
(
input
)
for
input
in
node
.
inputs
]
...
...
sparse.py
浏览文件 @
ea32b4db
...
@@ -6,11 +6,11 @@ To read about different sparse formats, see U{http://www-users.cs.umn.edu/~saad/
...
@@ -6,11 +6,11 @@ To read about different sparse formats, see U{http://www-users.cs.umn.edu/~saad/
@todo: Automatic methods for determining best sparse format?
@todo: Automatic methods for determining best sparse format?
"""
"""
import
copy
#for __copy__
import
numpy
import
numpy
from
scipy
import
sparse
from
scipy
import
sparse
import
gof.op
,
gof
.
result
import
gof
import
gof.op
import
tensor
import
tensor
...
@@ -20,24 +20,22 @@ _mtypes = [sparse.csc_matrix, sparse.csr_matrix]
...
@@ -20,24 +20,22 @@ _mtypes = [sparse.csc_matrix, sparse.csr_matrix]
_mtype_to_str
=
{
sparse
.
csc_matrix
:
"csc"
,
sparse
.
csr_matrix
:
"csr"
}
_mtype_to_str
=
{
sparse
.
csc_matrix
:
"csc"
,
sparse
.
csr_matrix
:
"csr"
}
## Type checking
def
_is_sparse_result
(
x
):
def
_is_sparse_result
(
x
):
"""
"""
@rtype: boolean
@rtype: boolean
@return: True iff x is a L{SparseResult} (and not a L{tensor.Tensor})
@return: True iff x is a L{SparseResult} (and not a L{tensor.Tensor})
"""
"""
if
not
isinstance
(
x
,
SparseResult
)
and
not
isinstance
(
x
,
tensor
.
Tensor
):
if
not
isinstance
(
x
.
type
,
Sparse
)
and
not
isinstance
(
x
.
type
,
tensor
.
Tensor
):
raise
NotImplementedError
(
"
_is_sparse should only be called on sparse.SparseResult
or tensor.Tensor, not,"
,
x
)
raise
NotImplementedError
(
"
this function should only be called on results of type sparse.Sparse
or tensor.Tensor, not,"
,
x
)
return
isinstance
(
x
,
SparseResult
)
return
isinstance
(
x
.
type
,
Sparse
)
def
_is_dense_result
(
x
):
def
_is_dense_result
(
x
):
"""
"""
@rtype: boolean
@rtype: boolean
@return: True unless x is a L{SparseResult} (and not a L{tensor.Tensor})
@return: True unless x is a L{SparseResult} (and not a L{tensor.Tensor})
"""
"""
if
not
isinstance
(
x
,
SparseResult
)
and
not
isinstance
(
x
,
tensor
.
Tensor
):
if
not
isinstance
(
x
.
type
,
Sparse
)
and
not
isinstance
(
x
.
type
,
tensor
.
Tensor
):
raise
NotImplementedError
(
"
_is_sparse should only be called on sparse.SparseResult
or tensor.Tensor, not,"
,
x
)
raise
NotImplementedError
(
"
this function should only be called on results of type sparse.Sparse
or tensor.Tensor, not,"
,
x
)
return
isinstance
(
x
,
tensor
.
Tensor
)
return
isinstance
(
x
.
type
,
tensor
.
Tensor
)
def
_is_sparse
(
x
):
def
_is_sparse
(
x
):
"""
"""
...
@@ -45,7 +43,7 @@ def _is_sparse(x):
...
@@ -45,7 +43,7 @@ def _is_sparse(x):
@return: True iff x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
@return: True iff x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
"""
"""
if
not
isinstance
(
x
,
sparse
.
spmatrix
)
and
not
isinstance
(
x
,
numpy
.
ndarray
):
if
not
isinstance
(
x
,
sparse
.
spmatrix
)
and
not
isinstance
(
x
,
numpy
.
ndarray
):
raise
NotImplementedError
(
"
_is_sparse
should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,"
,
x
)
raise
NotImplementedError
(
"
this function
should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,"
,
x
)
return
isinstance
(
x
,
sparse
.
spmatrix
)
return
isinstance
(
x
,
sparse
.
spmatrix
)
def
_is_dense
(
x
):
def
_is_dense
(
x
):
"""
"""
...
@@ -53,37 +51,61 @@ def _is_dense(x):
...
@@ -53,37 +51,61 @@ def _is_dense(x):
@return: True unless x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
@return: True unless x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
"""
"""
if
not
isinstance
(
x
,
sparse
.
spmatrix
)
and
not
isinstance
(
x
,
numpy
.
ndarray
):
if
not
isinstance
(
x
,
sparse
.
spmatrix
)
and
not
isinstance
(
x
,
numpy
.
ndarray
):
raise
NotImplementedError
(
"
_is_sparse
should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,"
,
x
)
raise
NotImplementedError
(
"
this function
should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,"
,
x
)
return
isinstance
(
x
,
numpy
.
ndarray
)
return
isinstance
(
x
,
numpy
.
ndarray
)
# Wrapper type
# Wrapper type
def
as
sparse
(
sp
,
**
kwargs
):
def
as
_sparse
(
x
):
"""
"""
Wrapper around SparseResult constructor.
Wrapper around SparseResult constructor.
@param
sp: A sparse matrix. as
sparse reads dtype and format properties
@param
x: A sparse matrix. as_
sparse reads dtype and format properties
out of this sparse matrix.
out of this sparse matrix.
@return: SparseResult version of sp.
@return: SparseResult version of sp.
@todo Verify that sp is sufficiently sparse, and raise a warning if it is not
@todo Verify that sp is sufficiently sparse, and raise a warning if it is not
"""
"""
if
isinstance
(
sp
,
SparseResult
):
if
isinstance
(
x
,
gof
.
Apply
):
rval
=
sp
if
len
(
x
.
outputs
)
!=
1
:
raise
ValueError
(
"It is ambiguous which output of a multi-output Op has to be fetched."
,
x
)
else
:
else
:
# @todo Verify that sp is sufficiently sparse, and raise a
x
=
x
.
outputs
[
0
]
# warning if it is not
if
isinstance
(
x
,
gof
.
Result
):
rval
=
SparseResult
(
str
(
sp
.
dtype
),
sp
.
format
,
**
kwargs
)
if
not
isinstance
(
x
.
type
,
Sparse
):
rval
.
data
=
sp
raise
TypeError
(
"Result type field must be a Sparse."
,
x
,
x
.
type
)
assert
_is_sparse_result
(
rval
)
return
x
return
rval
try
:
return
constant
(
x
)
class
SparseResult
(
gof
.
result
.
Result
):
except
TypeError
:
raise
TypeError
(
"Cannot convert
%
s to Sparse"
%
x
,
type
(
x
))
def
constant
(
x
):
if
not
isinstance
(
x
,
sparse
.
spmatrix
):
raise
TypeError
(
"sparse.constant must be called on a scipy.sparse.spmatrix"
)
try
:
return
SparseConstant
(
Sparse
(
format
=
x
.
format
,
dtype
=
x
.
dtype
),
x
)
except
TypeError
:
raise
TypeError
(
"Could not convert
%
s to Sparse"
%
x
,
type
(
x
))
def
value
(
x
):
if
not
isinstance
(
x
,
sparse
.
spmatrix
):
raise
TypeError
(
"sparse.value must be called on a scipy.sparse.spmatrix"
)
try
:
return
SparseValue
(
Sparse
(
format
=
x
.
format
,
dtype
=
x
.
dtype
),
x
)
except
TypeError
:
raise
TypeError
(
"Could not convert
%
s to Sparse"
%
x
,
type
(
x
))
class
Sparse
(
gof
.
Type
):
"""
"""
@type
_
dtype: numpy dtype string such as 'int64' or 'float64' (among others)
@type dtype: numpy dtype string such as 'int64' or 'float64' (among others)
@type
_
format: string
@type format: string
@ivar
_
format: The sparse storage strategy.
@ivar format: The sparse storage strategy.
@note As far as I can tell, L{scipy.sparse} objects must be matrices, i.e. have dimension 2.
@note As far as I can tell, L{scipy.sparse} objects must be matrices, i.e. have dimension 2.
"""
"""
...
@@ -92,8 +114,9 @@ class SparseResult(gof.result.Result):
...
@@ -92,8 +114,9 @@ class SparseResult(gof.result.Result):
'csc'
:
sparse
.
csc_matrix
'csc'
:
sparse
.
csc_matrix
}
}
dtype_set
=
set
([
'int'
,
'int32'
,
'int64'
,
'float32'
,
'float64'
])
dtype_set
=
set
([
'int'
,
'int32'
,
'int64'
,
'float32'
,
'float64'
])
ndim
=
2
def
__init__
(
self
,
dtype
,
format
,
**
kwargs
):
def
__init__
(
self
,
format
,
dtype
=
'float64'
):
"""
"""
Fundamental way to create a sparse node.
Fundamental way to create a sparse node.
@param dtype: Type of numbers in the matrix.
@param dtype: Type of numbers in the matrix.
...
@@ -101,147 +124,169 @@ class SparseResult(gof.result.Result):
...
@@ -101,147 +124,169 @@ class SparseResult(gof.result.Result):
@return An empty SparseResult instance.
@return An empty SparseResult instance.
"""
"""
gof
.
Result
.
__init__
(
self
,
**
kwargs
)
dtype
=
str
(
dtype
)
if
dtype
in
SparseResult
.
dtype_set
:
if
dtype
in
self
.
dtype_set
:
self
.
_dtype
=
dtype
self
.
dtype
=
dtype
assert
isinstance
(
format
,
str
)
else
:
raise
NotImplementedError
(
'unsupported dtype "
%
s" not in list'
%
dtype
,
list
(
self
.
dtype_set
))
#print format, type(format), SparseResult.format_cls.keys(), format in SparseResult.format_cls
assert
isinstance
(
format
,
str
)
if
format
in
SparseResult
.
format_cls
:
if
format
in
self
.
format_cls
:
self
.
_
format
=
format
self
.
format
=
format
else
:
else
:
raise
NotImplementedError
(
'unsupported format "
%
s" not in list'
%
format
,
SparseResult
.
format_cls
.
keys
())
raise
NotImplementedError
(
'unsupported format "
%
s" not in list'
%
format
,
self
.
format_cls
.
keys
())
def
filter
(
self
,
value
):
def
filter
(
self
,
value
,
strict
=
False
):
if
isinstance
(
value
,
SparseResult
.
format_cls
[
self
.
format
])
\
if
isinstance
(
value
,
self
.
format_cls
[
self
.
format
])
\
and
value
.
dtype
==
self
.
dtype
:
and
value
.
dtype
==
self
.
dtype
:
return
value
return
value
#print 'pass-through failed', type(value)
if
strict
:
sp
=
SparseResult
.
format_cls
[
self
.
format
](
value
)
raise
TypeError
(
"
%
s is not sparse"
%
value
)
sp
=
self
.
format_cls
[
self
.
format
](
value
)
if
str
(
sp
.
dtype
)
!=
self
.
dtype
:
if
str
(
sp
.
dtype
)
!=
self
.
dtype
:
raise
NotImplementedError
()
raise
NotImplementedError
()
if
sp
.
format
!=
self
.
format
:
if
sp
.
format
!=
self
.
format
:
raise
NotImplementedError
()
raise
NotImplementedError
()
return
sp
return
sp
def
__copy__
(
self
):
def
make_result
(
self
,
name
=
None
):
if
self
.
name
is
not
None
:
return
SparseResult
(
self
,
name
=
name
)
rval
=
SparseResult
(
self
.
_dtype
,
self
.
_format
,
name
=
self
.
name
)
else
:
rval
=
SparseResult
(
self
.
_dtype
,
self
.
_format
)
rval
.
data
=
copy
.
copy
(
self
.
data
)
return
rval
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
and
other
.
dtype
==
self
.
dtype
and
other
.
format
==
self
.
format
dtype
=
property
(
lambda
self
:
self
.
_dtype
)
def
__hash__
(
self
):
format
=
property
(
lambda
self
:
self
.
_format
)
return
hash
(
self
.
dtype
)
^
hash
(
self
.
format
)
T
=
property
(
lambda
self
:
transpose
(
self
),
doc
=
"Return aliased transpose of self (read-only)"
)
def
__str__
(
self
):
return
"Sparse[
%
s,
%
s]"
%
(
str
(
self
.
dtype
),
str
(
self
.
format
))
def
__repr__
(
self
):
return
"Sparse[
%
s,
%
s]"
%
(
str
(
self
.
dtype
),
str
(
self
.
format
))
class
_sparse_py_operators
:
T
=
property
(
lambda
self
:
transpose
(
self
),
doc
=
"Return aliased transpose of self (read-only)"
)
def
__add__
(
left
,
right
):
return
add
(
left
,
right
)
def
__add__
(
left
,
right
):
return
add
(
left
,
right
)
def
__radd__
(
right
,
left
):
return
add
(
left
,
right
)
def
__radd__
(
right
,
left
):
return
add
(
left
,
right
)
class
SparseResult
(
gof
.
Result
,
_sparse_py_operators
):
pass
class
SparseConstant
(
gof
.
Constant
,
_sparse_py_operators
):
pass
class
SparseValue
(
gof
.
Value
,
_sparse_py_operators
):
pass
#
#
# Conversion
# Conversion
#
#
# convert a sparse matrix to an ndarray
# convert a sparse matrix to an ndarray
class
DenseFromSparse
(
gof
.
op
.
Op
):
class
DenseFromSparse
(
gof
.
op
.
Op
):
def
__init__
(
self
,
x
,
**
kwargs
):
def
make_node
(
self
,
x
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
x
=
as_sparse
(
x
)
self
.
inputs
=
[
assparse
(
x
)]
return
gof
.
Apply
(
self
,
self
.
outputs
=
[
tensor
.
Tensor
(
x
.
dtype
,[
0
,
0
])]
[
x
],
def
impl
(
self
,
x
):
[
tensor
.
Tensor
(
dtype
=
x
.
type
.
dtype
,
assert
_is_sparse
(
x
)
broadcastable
=
(
False
,
False
))
.
make_result
()]
)
return
numpy
.
asarray
(
x
.
todense
())
def
perform
(
self
,
node
,
(
x
,
),
(
out
,
)):
def
grad
(
self
,
(
x
,),
(
gz
,)):
out
[
0
]
=
numpy
.
asarray
(
x
.
todense
())
assert
_is_sparse_result
(
x
)
and
_is_dense_result
(
gz
)
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
return
sparse_from_dense
(
gz
,
x
.
format
),
return
SparseFromDense
(
x
.
type
.
format
)(
gz
),
dense_from_sparse
=
gof
.
op
.
constructor
(
DenseFromSparse
)
dense_from_sparse
=
DenseFromSparse
(
)
class
SparseFromDense
(
gof
.
op
.
Op
):
class
SparseFromDense
(
gof
.
op
.
Op
):
def
__init__
(
self
,
x
,
format
,
**
kwargs
):
def
__init__
(
self
,
format
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
self
.
format
=
format
if
isinstance
(
format
,
gof
.
result
.
Result
):
def
make_node
(
self
,
x
):
self
.
inputs
=
[
tensor
.
astensor
(
x
),
format
]
x
=
tensor
.
as_tensor
(
x
)
else
:
return
gof
.
Apply
(
self
,
self
.
inputs
=
[
tensor
.
astensor
(
x
),
gof
.
result
.
PythonResult
()]
[
x
],
self
.
inputs
[
1
]
.
data
=
format
[
Sparse
(
dtype
=
x
.
type
.
dtype
,
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
self
.
inputs
[
1
]
.
data
)]
format
=
self
.
format
)
.
make_result
()])
def
impl
(
self
,
x
,
fmt
):
def
perform
(
self
,
node
,
(
x
,
),
(
out
,
)):
# this would actually happen anyway when we try to assign to
out
[
0
]
=
Sparse
.
format_cls
[
self
.
format
](
x
)
# self.outputs[0].data, but that seems hackish -JB
def
grad
(
self
,
(
x
,
),
(
gz
,
)):
assert
_is_dense
(
x
)
return
dense_from_sparse
(
gz
),
return
SparseResult
.
format_cls
[
fmt
](
x
)
def
__eq__
(
self
,
other
):
def
grad
(
self
,
(
x
,
fmt
),
(
gz
,)):
return
type
(
self
)
==
type
(
other
)
and
self
.
format
==
other
.
format
assert
_is_dense_result
(
x
)
and
_is_sparse_result
(
gz
)
def
__hash__
(
self
):
return
dense_from_sparse
(
gz
),
None
return
hash
(
self
.
format
)
sparse_from_dense
=
gof
.
op
.
constructor
(
SparseFromDense
)
csr_from_dense
=
SparseFromDense
(
'csr'
)
csc_from_dense
=
SparseFromDense
(
'csc'
)
# Linear Algebra
# Linear Algebra
class
Transpose
(
gof
.
op
.
Op
):
class
Transpose
(
gof
.
op
.
Op
):
format_map
=
{
format_map
=
{
'csr'
:
'csc'
,
'csr'
:
'csc'
,
'csc'
:
'csr'
}
'csc'
:
'csr'
}
def
__init__
(
self
,
x
,
**
kwargs
):
def
make_node
(
self
,
x
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
x
=
as_sparse
(
x
)
x
=
assparse
(
x
)
return
gof
.
Apply
(
self
,
self
.
inputs
=
[
x
]
[
x
],
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
Transpose
.
format_map
[
x
.
format
])]
[
Sparse
(
dtype
=
x
.
type
.
dtype
,
def
impl
(
self
,
x
):
format
=
self
.
format_map
[
x
.
type
.
format
])
.
make_result
()])
def
perform
(
self
,
node
,
(
x
,
),
(
out
,
)):
assert
_is_sparse
(
x
)
assert
_is_sparse
(
x
)
return
x
.
transpose
()
out
[
0
]
=
x
.
transpose
()
def
grad
(
self
,
(
x
,),
(
gz
,)):
def
grad
(
self
,
(
x
,),
(
gz
,)):
assert
_is_sparse_result
(
x
)
and
_is_sparse_result
(
gz
)
assert
_is_sparse_result
(
x
)
and
_is_sparse_result
(
gz
)
return
transpose
(
gz
),
return
transpose
(
gz
),
transpose
=
gof
.
op
.
constructor
(
Transpose
)
transpose
=
Transpose
(
)
class
AddSS
(
gof
.
op
.
Op
):
class
AddSS
(
gof
.
op
.
Op
):
''' Add two sparse matrices '''
''' Add two sparse matrices '''
def
__init__
(
self
,
x
,
y
,
**
kwargs
):
def
make_node
(
self
,
x
,
y
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
x
,
y
=
map
(
as_sparse
,
[
x
,
y
])
x
,
y
=
[
assparse
(
x
),
assparse
(
y
)]
if
x
.
type
.
dtype
!=
y
.
type
.
dtype
:
self
.
inputs
=
[
x
,
y
]
if
x
.
dtype
!=
y
.
dtype
:
raise
NotImplementedError
()
raise
NotImplementedError
()
if
x
.
format
!=
y
.
format
:
if
x
.
type
.
format
!=
y
.
type
.
format
:
raise
NotImplementedError
()
raise
NotImplementedError
()
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
x
.
format
)]
return
gof
.
Apply
(
self
,
def
impl
(
self
,
x
,
y
):
[
x
,
y
],
[
Sparse
(
dtype
=
x
.
type
.
dtype
,
format
=
x
.
type
.
format
)
.
make_result
()])
def
perform
(
self
,
node
,
(
x
,
y
),
(
out
,
)):
assert
_is_sparse
(
x
)
and
_is_sparse
(
y
)
assert
_is_sparse
(
x
)
and
_is_sparse
(
y
)
return
x
+
y
out
[
0
]
=
x
+
y
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
assert
_is_sparse_result
(
x
)
and
_is_sparse_result
(
y
)
assert
_is_sparse_result
(
x
)
and
_is_sparse_result
(
y
)
assert
_is_sparse_result
(
gz
)
assert
_is_sparse_result
(
gz
)
return
gz
,
gz
return
gz
,
gz
add_s_s
=
gof
.
op
.
constructor
(
AddSS
)
add_s_s
=
AddSS
(
)
class
AddSD
(
gof
.
op
.
Op
):
class
AddSD
(
gof
.
op
.
Op
):
''' Add a sparse and a dense matrix '''
''' Add a sparse and a dense matrix '''
def
__init__
(
self
,
x
,
y
,
**
kwargs
):
def
make_node
(
self
,
x
,
y
):
gof
.
op
.
Op
.
__init__
(
self
,
**
kwargs
)
x
,
y
=
as_sparse
(
x
),
tensor
.
as_tensor
(
y
)
x
,
y
=
[
assparse
(
x
),
tensor
.
astensor
(
y
)]
if
x
.
type
.
dtype
!=
y
.
type
.
dtype
:
self
.
inputs
=
[
x
,
y
]
if
x
.
dtype
!=
y
.
dtype
:
raise
NotImplementedError
()
raise
NotImplementedError
()
# The magic number two here arises because L{scipy.sparse}
# The magic number two here arises because L{scipy.sparse}
# objects must be matrices (have dimension 2)
# objects must be matrices (have dimension 2)
assert
len
(
y
.
broadcastable
)
==
2
assert
y
.
type
.
ndim
==
2
self
.
outputs
=
[
tensor
.
Tensor
(
y
.
dtype
,
y
.
broadcastable
)]
return
gof
.
Apply
(
self
,
def
impl
(
self
,
x
,
y
):
[
x
,
y
],
[
tensor
.
Tensor
(
dtype
=
y
.
type
.
dtype
,
broadcastable
=
y
.
type
.
broadcastable
)
.
make_result
()])
def
perform
(
self
,
node
,
(
x
,
y
),
(
out
,
)):
assert
_is_sparse
(
x
)
and
_is_dense
(
y
)
assert
_is_sparse
(
x
)
and
_is_dense
(
y
)
return
x
+
y
out
[
0
]
=
x
+
y
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
assert
_is_sparse_result
(
x
)
and
_is_dense_result
(
y
)
assert
_is_sparse_result
(
x
)
and
_is_dense_result
(
y
)
assert
_is_dense_result
(
gz
)
assert
_is_dense_result
(
gz
)
return
SparseFromDense
(
gz
),
gz
return
SparseFromDense
(
x
.
type
.
format
)(
gz
),
gz
add_s_d
=
gof
.
op
.
constructor
(
AddSD
)
add_s_d
=
AddSD
(
)
def
add
(
x
,
y
):
def
add
(
x
,
y
):
"""
"""
Add two matrices, at least one of which is sparse.
Add two matrices, at least one of which is sparse.
"""
"""
if
hasattr
(
x
,
'getnnz'
):
x
=
assparse
(
x
)
if
hasattr
(
x
,
'getnnz'
):
x
=
as
_
sparse
(
x
)
if
hasattr
(
y
,
'getnnz'
):
y
=
assparse
(
y
)
if
hasattr
(
y
,
'getnnz'
):
y
=
as
_
sparse
(
y
)
x_is_sparse_result
=
_is_sparse_result
(
x
)
x_is_sparse_result
=
_is_sparse_result
(
x
)
y_is_sparse_result
=
_is_sparse_result
(
y
)
y_is_sparse_result
=
_is_sparse_result
(
y
)
...
@@ -266,57 +311,425 @@ class Dot(gof.op.Op):
...
@@ -266,57 +311,425 @@ class Dot(gof.op.Op):
@todo: Simplify code by splitting into DotSS and DotSD.
@todo: Simplify code by splitting into DotSS and DotSD.
"""
"""
def
__init__
(
self
,
x
,
y
,
grad_preserves_dense
=
True
):
def
__init__
(
self
,
grad_preserves_dense
=
True
):
self
.
grad_preserves_dense
=
grad_preserves_dense
def
make_node
(
self
,
x
,
y
):
"""
"""
Because of trickiness of implementing, we assume that the left argument x is SparseResult (not dense)
Because of trickiness of implementing, we assume that the left argument x is SparseResult (not dense)
"""
"""
if
x
.
dtype
!=
y
.
dtype
:
if
x
.
type
.
dtype
!=
y
.
type
.
dtype
:
raise
NotImplementedError
()
raise
NotImplementedError
()
assert
_is_sparse_result
(
x
)
assert
_is_sparse_result
(
x
)
# These are the conversions performed by scipy.sparse.dot
# These are the conversions performed by scipy.sparse.dot
if
x
.
format
==
"csc"
or
x
.
format
==
"coo"
:
if
x
.
type
.
format
==
"csc"
or
x
.
type
.
format
==
"coo"
:
myformat
=
"csc"
myformat
=
"csc"
elif
x
.
format
==
"csr"
:
elif
x
.
type
.
format
==
"csr"
:
myformat
=
"csr"
myformat
=
"csr"
else
:
else
:
raise
NotImplementedError
()
raise
NotImplementedError
()
self
.
inputs
=
[
x
,
y
]
# Need to convert? e.g. assparse
inputs
=
[
x
,
y
]
# Need to convert? e.g. assparse
self
.
outputs
=
[
SparseResult
(
x
.
dtype
,
myformat
)]
outputs
=
[
Sparse
(
dtype
=
x
.
type
.
dtype
,
format
=
myformat
)
.
make_result
(
)]
self
.
grad_preserves_dense
=
grad_preserves_dense
return
gof
.
Apply
(
self
,
inputs
,
outputs
)
def
perform
(
self
):
def
perform
(
self
,
node
,
(
x
,
y
),
(
out
,
)
):
"""
"""
@todo: Verify that output is sufficiently sparse, and raise a warning if it is not
@todo: Verify that output is sufficiently sparse, and raise a warning if it is not
@todo: Also determine that we are storing the output in the best storage format?
@todo: Also determine that we are storing the output in the best storage format?
"""
"""
self
.
outputs
[
0
]
.
data
=
self
.
inputs
[
0
]
.
data
.
dot
(
self
.
inputs
[
1
]
.
data
)
out
[
0
]
=
x
.
dot
(
y
)
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
def
grad
(
self
,
(
x
,
y
),
(
gz
,)):
assert
_is_sparse_result
(
gz
)
assert
_is_sparse_result
(
gz
)
rval
=
[
dot
(
gz
,
y
.
T
),
dot
(
x
.
T
,
gz
)]
assert
_is_sparse_result
(
x
)
assert
_is_sparse_result
(
x
)
rval
=
[
dot
(
gz
,
y
.
T
),
dot
(
x
.
T
,
gz
)]
if
_is_dense_result
(
y
):
if
_is_dense_result
(
y
):
if
self
.
grad_preserves_dense
:
if
self
.
grad_preserves_dense
:
rval
[
1
]
=
dense_from_sparse
(
rval
[
1
])
rval
[
1
]
=
dense_from_sparse
(
rval
[
1
])
return
rval
return
rval
def
__copy__
(
self
):
def
__eq__
(
self
,
other
):
return
self
.
__class__
(
self
.
inputs
[
0
],
self
.
inputs
[
1
],
self
.
grad_preserves_dense
)
return
type
(
self
)
==
type
(
other
)
and
self
.
grad_preserves_dense
==
other
.
grad_preserves_dense
def
clone_with_new_inputs
(
self
,
*
new_inputs
):
def
__hash__
(
self
):
return
self
.
__class__
(
new_inputs
[
0
],
new_inputs
[
1
],
self
.
grad_preserves_dense
)
return
hash
(
self
.
grad_preserves_dense
)
def
dot
(
x
,
y
,
grad_preserves_dense
=
True
):
def
dot
(
x
,
y
,
grad_preserves_dense
=
True
):
"""
"""
@todo: Maybe the triple-transposition formulation (when x is dense)
@todo: Maybe the triple-transposition formulation (when x is dense)
is slow. See if there is a direct way to do this.
is slow. See if there is a direct way to do this.
"""
"""
if
hasattr
(
x
,
'getnnz'
):
x
=
assparse
(
x
)
if
hasattr
(
x
,
'getnnz'
):
x
=
as
_
sparse
(
x
)
if
hasattr
(
y
,
'getnnz'
):
y
=
assparse
(
y
)
if
hasattr
(
y
,
'getnnz'
):
y
=
as
_
sparse
(
y
)
x_is_sparse_result
=
_is_sparse_result
(
x
)
x_is_sparse_result
=
_is_sparse_result
(
x
)
y_is_sparse_result
=
_is_sparse_result
(
y
)
y_is_sparse_result
=
_is_sparse_result
(
y
)
if
not
x_is_sparse_result
and
not
y_is_sparse_result
:
if
not
x_is_sparse_result
and
not
y_is_sparse_result
:
raise
TypeError
()
raise
TypeError
()
if
x_is_sparse_result
:
if
x_is_sparse_result
:
return
Dot
(
x
,
y
,
grad_preserves_dense
)
.
outputs
[
0
]
return
Dot
(
grad_preserves_dense
)(
x
,
y
)
else
:
else
:
assert
y_is_sparse_result
assert
y_is_sparse_result
return
transpose
(
Dot
(
y
.
T
,
x
.
T
,
grad_preserves_dense
)
.
outputs
[
0
])
return
transpose
(
Dot
(
grad_preserves_dense
)(
y
.
T
,
x
.
T
))
# """
# Classes for handling sparse matrices.
# To read about different sparse formats, see U{http://www-users.cs.umn.edu/~saad/software/SPARSKIT/paper.ps}.
# @todo: Automatic methods for determining best sparse format?
# """
# import copy #for __copy__
# import numpy
# from scipy import sparse
# import gof.op, gof.result
# import tensor
# """ Types of sparse matrices to use for testing """
# _mtypes = [sparse.csc_matrix, sparse.csr_matrix]
# #_mtypes = [sparse.csc_matrix, sparse.csr_matrix, sparse.dok_matrix, sparse.lil_matrix, sparse.coo_matrix]
# _mtype_to_str = {sparse.csc_matrix: "csc", sparse.csr_matrix: "csr"}
# ## Type checking
# def _is_sparse_result(x):
# """
# @rtype: boolean
# @return: True iff x is a L{SparseResult} (and not a L{tensor.Tensor})
# """
# if not isinstance(x, SparseResult) and not isinstance(x, tensor.Tensor):
# raise NotImplementedError("_is_sparse should only be called on sparse.SparseResult or tensor.Tensor, not,", x)
# return isinstance(x, SparseResult)
# def _is_dense_result(x):
# """
# @rtype: boolean
# @return: True unless x is a L{SparseResult} (and not a L{tensor.Tensor})
# """
# if not isinstance(x, SparseResult) and not isinstance(x, tensor.Tensor):
# raise NotImplementedError("_is_sparse should only be called on sparse.SparseResult or tensor.Tensor, not,", x)
# return isinstance(x, tensor.Tensor)
# def _is_sparse(x):
# """
# @rtype: boolean
# @return: True iff x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
# """
# if not isinstance(x, sparse.spmatrix) and not isinstance(x, numpy.ndarray):
# raise NotImplementedError("_is_sparse should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,", x)
# return isinstance(x, sparse.spmatrix)
# def _is_dense(x):
# """
# @rtype: boolean
# @return: True unless x is a L{scipy.sparse.spmatrix} (and not a L{numpy.ndarray})
# """
# if not isinstance(x, sparse.spmatrix) and not isinstance(x, numpy.ndarray):
# raise NotImplementedError("_is_sparse should only be called on sparse.scipy.sparse.spmatrix or numpy.ndarray, not,", x)
# return isinstance(x, numpy.ndarray)
# # Wrapper type
# def assparse(sp, **kwargs):
# """
# Wrapper around SparseResult constructor.
# @param sp: A sparse matrix. assparse reads dtype and format properties
# out of this sparse matrix.
# @return: SparseResult version of sp.
# @todo Verify that sp is sufficiently sparse, and raise a warning if it is not
# """
# if isinstance(sp, SparseResult):
# rval = sp
# else:
# # @todo Verify that sp is sufficiently sparse, and raise a
# # warning if it is not
# rval = SparseResult(str(sp.dtype), sp.format, **kwargs)
# rval.data = sp
# assert _is_sparse_result(rval)
# return rval
# class SparseResult(gof.result.Result):
# """
# @type _dtype: numpy dtype string such as 'int64' or 'float64' (among others)
# @type _format: string
# @ivar _format: The sparse storage strategy.
# @note As far as I can tell, L{scipy.sparse} objects must be matrices, i.e. have dimension 2.
# """
# format_cls = {
# 'csr' : sparse.csr_matrix,
# 'csc' : sparse.csc_matrix
# }
# dtype_set = set(['int', 'int32', 'int64', 'float32', 'float64'])
# def __init__(self, dtype, format, **kwargs):
# """
# Fundamental way to create a sparse node.
# @param dtype: Type of numbers in the matrix.
# @param format: The sparse storage strategy.
# @return An empty SparseResult instance.
# """
# gof.Result.__init__(self, **kwargs)
# if dtype in SparseResult.dtype_set:
# self._dtype = dtype
# assert isinstance(format, str)
# #print format, type(format), SparseResult.format_cls.keys(), format in SparseResult.format_cls
# if format in SparseResult.format_cls:
# self._format = format
# else:
# raise NotImplementedError('unsupported format "%s" not in list' % format, SparseResult.format_cls.keys())
# def filter(self, value):
# if isinstance(value, SparseResult.format_cls[self.format])\
# and value.dtype == self.dtype:
# return value
# #print 'pass-through failed', type(value)
# sp = SparseResult.format_cls[self.format](value)
# if str(sp.dtype) != self.dtype:
# raise NotImplementedError()
# if sp.format != self.format:
# raise NotImplementedError()
# return sp
# def __copy__(self):
# if self.name is not None:
# rval = SparseResult(self._dtype, self._format, name=self.name)
# else:
# rval = SparseResult(self._dtype, self._format)
# rval.data = copy.copy(self.data)
# return rval
# dtype = property(lambda self: self._dtype)
# format = property(lambda self: self._format)
# T = property(lambda self: transpose(self), doc = "Return aliased transpose of self (read-only)")
# def __add__(left, right): return add(left, right)
# def __radd__(right, left): return add(left, right)
# #
# # Conversion
# #
# # convert a sparse matrix to an ndarray
# class DenseFromSparse(gof.op.Op):
# def __init__(self, x, **kwargs):
# gof.op.Op.__init__(self, **kwargs)
# self.inputs = [assparse(x)]
# self.outputs = [tensor.Tensor(x.dtype,[0,0])]
# def impl(self, x):
# assert _is_sparse(x)
# return numpy.asarray(x.todense())
# def grad(self, (x,), (gz,)):
# assert _is_sparse_result(x) and _is_dense_result(gz)
# return sparse_from_dense(gz, x.format),
# dense_from_sparse = gof.op.constructor(DenseFromSparse)
# class SparseFromDense(gof.op.Op):
# def __init__(self, x, format, **kwargs):
# gof.op.Op.__init__(self, **kwargs)
# if isinstance(format, gof.result.Result):
# self.inputs = [tensor.astensor(x), format]
# else:
# self.inputs = [tensor.astensor(x), gof.result.PythonResult()]
# self.inputs[1].data = format
# self.outputs = [SparseResult(x.dtype, self.inputs[1].data)]
# def impl(self, x, fmt):
# # this would actually happen anyway when we try to assign to
# # self.outputs[0].data, but that seems hackish -JB
# assert _is_dense(x)
# return SparseResult.format_cls[fmt](x)
# def grad(self, (x, fmt), (gz,)):
# assert _is_dense_result(x) and _is_sparse_result(gz)
# return dense_from_sparse(gz), None
# sparse_from_dense = gof.op.constructor(SparseFromDense)
# # Linear Algebra
# class Transpose(gof.op.Op):
# format_map = {
# 'csr' : 'csc',
# 'csc' : 'csr'}
# def __init__(self, x, **kwargs):
# gof.op.Op.__init__(self, **kwargs)
# x = assparse(x)
# self.inputs = [x]
# self.outputs = [SparseResult(x.dtype, Transpose.format_map[x.format])]
# def impl(self, x):
# assert _is_sparse(x)
# return x.transpose()
# def grad(self, (x,), (gz,)):
# assert _is_sparse_result(x) and _is_sparse_result(gz)
# return transpose(gz),
# transpose = gof.op.constructor(Transpose)
# class AddSS(gof.op.Op):
# ''' Add two sparse matrices '''
# def __init__(self, x, y, **kwargs):
# gof.op.Op.__init__(self, **kwargs)
# x, y = [assparse(x), assparse(y)]
# self.inputs = [x, y]
# if x.dtype != y.dtype:
# raise NotImplementedError()
# if x.format != y.format:
# raise NotImplementedError()
# self.outputs = [SparseResult(x.dtype, x.format)]
# def impl(self, x,y):
# assert _is_sparse(x) and _is_sparse(y)
# return x + y
# def grad(self, (x, y), (gz,)):
# assert _is_sparse_result(x) and _is_sparse_result(y)
# assert _is_sparse_result(gz)
# return gz, gz
# add_s_s = gof.op.constructor(AddSS)
# class AddSD(gof.op.Op):
# ''' Add a sparse and a dense matrix '''
# def __init__(self, x, y, **kwargs):
# gof.op.Op.__init__(self, **kwargs)
# x, y = [assparse(x), tensor.astensor(y)]
# self.inputs = [x, y]
# if x.dtype != y.dtype:
# raise NotImplementedError()
# # The magic number two here arises because L{scipy.sparse}
# # objects must be matrices (have dimension 2)
# assert len(y.broadcastable) == 2
# self.outputs = [tensor.Tensor(y.dtype, y.broadcastable)]
# def impl(self, x,y):
# assert _is_sparse(x) and _is_dense(y)
# return x + y
# def grad(self, (x, y), (gz,)):
# assert _is_sparse_result(x) and _is_dense_result(y)
# assert _is_dense_result(gz)
# return SparseFromDense(gz), gz
# add_s_d = gof.op.constructor(AddSD)
# def add(x,y):
# """
# Add two matrices, at least one of which is sparse.
# """
# if hasattr(x, 'getnnz'): x = assparse(x)
# if hasattr(y, 'getnnz'): y = assparse(y)
# x_is_sparse_result = _is_sparse_result(x)
# y_is_sparse_result = _is_sparse_result(y)
# assert x_is_sparse_result or y_is_sparse_result
# if x_is_sparse_result and y_is_sparse_result: return add_s_s(x,y)
# elif x_is_sparse_result and not y_is_sparse_result: return add_s_d(x,y)
# elif y_is_sparse_result and not x_is_sparse_result: return add_s_d(y,x)
# else: raise NotImplementedError()
# class Dot(gof.op.Op):
# """
# Attributes:
# grad_preserves_dense - a boolean flags [default: True].
# grad_preserves_dense controls whether gradients with respect to inputs
# are converted to dense matrices when the corresponding input y is
# dense (not in a L{SparseResult} wrapper). This is generally a good idea
# when L{Dot} is in the middle of a larger graph, because the types
# of gy will match that of y. This conversion might be inefficient if
# the gradients are graph outputs though, hence this mask.
# @todo: Simplify code by splitting into DotSS and DotSD.
# """
# def __init__(self, x, y, grad_preserves_dense=True):
# """
# Because of trickiness of implementing, we assume that the left argument x is SparseResult (not dense)
# """
# if x.dtype != y.dtype:
# raise NotImplementedError()
# assert _is_sparse_result(x)
# # These are the conversions performed by scipy.sparse.dot
# if x.format == "csc" or x.format == "coo":
# myformat = "csc"
# elif x.format == "csr":
# myformat = "csr"
# else:
# raise NotImplementedError()
# self.inputs = [x, y] # Need to convert? e.g. assparse
# self.outputs = [SparseResult(x.dtype, myformat)]
# self.grad_preserves_dense = grad_preserves_dense
# def perform(self):
# """
# @todo: Verify that output is sufficiently sparse, and raise a warning if it is not
# @todo: Also determine that we are storing the output in the best storage format?
# """
# self.outputs[0].data = self.inputs[0].data.dot(self.inputs[1].data)
# def grad(self, (x, y), (gz,)):
# assert _is_sparse_result(gz)
# rval = [dot(gz, y.T), dot(x.T, gz)]
# assert _is_sparse_result(x)
# if _is_dense_result(y):
# if self.grad_preserves_dense:
# rval[1] = dense_from_sparse(rval[1])
# return rval
# def __copy__(self):
# return self.__class__(self.inputs[0], self.inputs[1], self.grad_preserves_dense)
# def clone_with_new_inputs(self, *new_inputs):
# return self.__class__(new_inputs[0], new_inputs[1], self.grad_preserves_dense)
# def dot(x, y, grad_preserves_dense=True):
# """
# @todo: Maybe the triple-transposition formulation (when x is dense)
# is slow. See if there is a direct way to do this.
# """
# if hasattr(x, 'getnnz'): x = assparse(x)
# if hasattr(y, 'getnnz'): y = assparse(y)
# x_is_sparse_result = _is_sparse_result(x)
# y_is_sparse_result = _is_sparse_result(y)
# if not x_is_sparse_result and not y_is_sparse_result:
# raise TypeError()
# if x_is_sparse_result:
# return Dot(x, y, grad_preserves_dense).outputs[0]
# else:
# assert y_is_sparse_result
# return transpose(Dot(y.T, x.T, grad_preserves_dense).outputs[0])
tensor.py
浏览文件 @
ea32b4db
...
@@ -6,7 +6,7 @@ import numpy
...
@@ -6,7 +6,7 @@ import numpy
from
copy
import
copy
from
copy
import
copy
from
gof
import
Result
,
Op
,
utils
,
Destroyer
,
Viewer
,
AbstractFunctionError
,
Type
,
Result
,
Constant
,
Apply
from
gof
import
Result
,
Op
,
utils
,
Destroyer
,
Viewer
,
AbstractFunctionError
,
Type
,
Result
,
Constant
,
Apply
,
Value
import
gof
import
gof
import
blas
# for gemm, dot
import
blas
# for gemm, dot
...
@@ -27,14 +27,9 @@ def as_tensor(x, name = None):
...
@@ -27,14 +27,9 @@ def as_tensor(x, name = None):
if
not
isinstance
(
x
.
type
,
Tensor
):
if
not
isinstance
(
x
.
type
,
Tensor
):
raise
TypeError
(
"Result type field must be a Tensor."
,
x
,
x
.
type
)
raise
TypeError
(
"Result type field must be a Tensor."
,
x
,
x
.
type
)
return
x
return
x
if
isinstance
(
x
,
Constant
):
if
not
isinstance
(
x
.
type
,
Tensor
):
raise
TypeError
(
"Constant type field must be a Tensor."
,
x
,
x
.
type
)
return
x
try
:
try
:
return
constant
(
x
)
return
constant
(
x
)
except
TypeError
:
except
TypeError
:
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
# 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.
# to upcast their arguments... this internal-use function is a good place to put debugging stuff, better than the global astensor.
...
@@ -48,10 +43,19 @@ def constant(x):
...
@@ -48,10 +43,19 @@ def constant(x):
return
TensorConstant
(
Tensor
(
dtype
=
x
.
dtype
,
return
TensorConstant
(
Tensor
(
dtype
=
x
.
dtype
,
broadcastable
=
[
d
==
1
for
d
in
x
.
shape
]),
x
)
broadcastable
=
[
d
==
1
for
d
in
x
.
shape
]),
x
)
except
:
except
:
raise
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
_x
,
type
(
_x
))
def
value
(
x
):
if
not
isinstance
(
x
,
numpy
.
ndarray
):
x
=
numpy
.
asarray
(
x
)
try
:
return
TensorValue
(
Tensor
(
dtype
=
x
.
dtype
,
broadcastable
=
[
d
==
1
for
d
in
x
.
shape
]),
x
)
except
:
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
_x
,
type
(
_x
))
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
_x
,
type
(
_x
))
class
Tensor
(
Type
):
class
Tensor
(
Type
):
"""
"""
L{Type} representing L{numpy.ndarray} in Theano.
L{Type} representing L{numpy.ndarray} in Theano.
...
@@ -342,10 +346,14 @@ class TensorResult(Result, _tensor_py_operators):
...
@@ -342,10 +346,14 @@ class TensorResult(Result, _tensor_py_operators):
class
TensorConstant
(
Constant
,
_tensor_py_operators
):
class
TensorConstant
(
Constant
,
_tensor_py_operators
):
pass
pass
class
TensorValue
(
Value
,
_tensor_py_operators
):
pass
s2t
.
as_tensor
=
as_tensor
s2t
.
as_tensor
=
as_tensor
s2t
.
Tensor
=
Tensor
s2t
.
Tensor
=
Tensor
s2t
.
TensorResult
=
TensorResult
s2t
.
TensorResult
=
TensorResult
s2t
.
TensorConstant
=
TensorConstant
s2t
.
TensorConstant
=
TensorConstant
s2t
.
TensorValue
=
TensorValue
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论