Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
9f56e418
提交
9f56e418
authored
10月 15, 2020
作者:
Brandon T. Willard
提交者:
Brandon T. Willard
10月 15, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Remove redundant AdvancedBoolean*Subtensor classes
This change also fixes the `set_subtensor` boolean gradient bug in #105.
上级
9733a2ab
隐藏空白字符变更
内嵌
并排
正在显示
8 个修改的文件
包含
84 行增加
和
326 行删除
+84
-326
test_subtensor.py
tests/gpuarray/test_subtensor.py
+0
-3
test_subtensor.py
tests/tensor/test_subtensor.py
+40
-73
test_var.py
tests/tensor/test_var.py
+5
-7
opt.py
theano/gpuarray/opt.py
+0
-23
subtensor.py
theano/gpuarray/subtensor.py
+0
-43
jaxify.py
theano/sandbox/jaxify.py
+7
-7
subtensor.py
theano/tensor/subtensor.py
+13
-148
var.py
theano/tensor/var.py
+19
-22
没有找到文件。
tests/gpuarray/test_subtensor.py
浏览文件 @
9f56e418
...
@@ -11,7 +11,6 @@ from theano.gpuarray.subtensor import (
...
@@ -11,7 +11,6 @@ from theano.gpuarray.subtensor import (
GpuSubtensor
,
GpuSubtensor
,
GpuAdvancedSubtensor1
,
GpuAdvancedSubtensor1
,
GpuAdvancedSubtensor
,
GpuAdvancedSubtensor
,
GpuAdvancedBooleanSubtensor
,
GpuAdvancedIncSubtensor
,
GpuAdvancedIncSubtensor
,
GpuAdvancedIncSubtensor1
,
GpuAdvancedIncSubtensor1
,
GpuAdvancedIncSubtensor1_dev20
,
GpuAdvancedIncSubtensor1_dev20
,
...
@@ -37,7 +36,6 @@ class TestGPUSubtensor(TestSubtensor):
...
@@ -37,7 +36,6 @@ class TestGPUSubtensor(TestSubtensor):
self
.
adv_sub1
=
GpuAdvancedSubtensor1
self
.
adv_sub1
=
GpuAdvancedSubtensor1
self
.
adv_incsub1
=
GpuAdvancedIncSubtensor1
self
.
adv_incsub1
=
GpuAdvancedIncSubtensor1
self
.
adv_sub
=
GpuAdvancedSubtensor
self
.
adv_sub
=
GpuAdvancedSubtensor
self
.
adv_bool_sub
=
GpuAdvancedBooleanSubtensor
self
.
dimshuffle
=
GpuDimShuffle
self
.
dimshuffle
=
GpuDimShuffle
self
.
mode
=
mode_with_gpu
self
.
mode
=
mode_with_gpu
# avoid errors with limited devices
# avoid errors with limited devices
...
@@ -60,7 +58,6 @@ class TestGPUSubtensorF16(TestSubtensor):
...
@@ -60,7 +58,6 @@ class TestGPUSubtensorF16(TestSubtensor):
self
.
adv_sub1
=
GpuAdvancedSubtensor1
self
.
adv_sub1
=
GpuAdvancedSubtensor1
self
.
adv_incsub1
=
GpuAdvancedIncSubtensor1
self
.
adv_incsub1
=
GpuAdvancedIncSubtensor1
self
.
adv_sub
=
GpuAdvancedSubtensor
self
.
adv_sub
=
GpuAdvancedSubtensor
self
.
adv_bool_sub
=
GpuAdvancedBooleanSubtensor
self
.
dimshuffle
=
GpuDimShuffle
self
.
dimshuffle
=
GpuDimShuffle
self
.
mode
=
mode_with_gpu
self
.
mode
=
mode_with_gpu
# avoid errors with limited devices
# avoid errors with limited devices
...
...
tests/tensor/test_subtensor.py
浏览文件 @
9f56e418
...
@@ -46,8 +46,6 @@ from theano.tensor.subtensor import (
...
@@ -46,8 +46,6 @@ from theano.tensor.subtensor import (
AdvancedIncSubtensor1
,
AdvancedIncSubtensor1
,
AdvancedSubtensor
,
AdvancedSubtensor
,
AdvancedSubtensor1
,
AdvancedSubtensor1
,
AdvancedBooleanSubtensor
,
AdvancedBooleanIncSubtensor
,
advanced_inc_subtensor
,
advanced_inc_subtensor
,
advanced_inc_subtensor1
,
advanced_inc_subtensor1
,
advanced_set_subtensor
,
advanced_set_subtensor
,
...
@@ -67,8 +65,6 @@ subtensor_ops = (
...
@@ -67,8 +65,6 @@ subtensor_ops = (
IncSubtensor
,
IncSubtensor
,
AdvancedSubtensor1
,
AdvancedSubtensor1
,
AdvancedIncSubtensor1
,
AdvancedIncSubtensor1
,
AdvancedBooleanSubtensor
,
AdvancedBooleanIncSubtensor
,
)
)
...
@@ -368,12 +364,10 @@ class TestSubtensor(utt.OptimizationTestMixin):
...
@@ -368,12 +364,10 @@ class TestSubtensor(utt.OptimizationTestMixin):
# indexing with a mask for some dimensions
# indexing with a mask for some dimensions
mask
=
np
.
array
([
True
,
False
])
mask
=
np
.
array
([
True
,
False
])
val
=
self
.
eval_output_and_check
(
val
=
self
.
eval_output_and_check
(
test_array
[
mask
],
op_type
=
AdvancedSubtensor
)
test_array
[
mask
],
op_type
=
AdvancedBooleanSubtensor
)
assert_array_equal
(
test_array_np
[
mask
],
val
)
assert_array_equal
(
test_array_np
[
mask
],
val
)
val
=
self
.
eval_output_and_check
(
val
=
self
.
eval_output_and_check
(
inc_subtensor
(
test_array
[
mask
],
1
),
op_type
=
Advanced
Boolean
IncSubtensor
inc_subtensor
(
test_array
[
mask
],
1
),
op_type
=
AdvancedIncSubtensor
)
)
assert_array_equal
(
numpy_inc_subtensor
(
test_array_np
,
mask
,
1
),
val
)
assert_array_equal
(
numpy_inc_subtensor
(
test_array_np
,
mask
,
1
),
val
)
assert_array_equal
(
assert_array_equal
(
...
@@ -580,8 +574,8 @@ class TestSubtensor(utt.OptimizationTestMixin):
...
@@ -580,8 +574,8 @@ class TestSubtensor(utt.OptimizationTestMixin):
topo_
=
[
node
for
node
in
topo
if
not
isinstance
(
node
.
op
,
DeepCopyOp
)]
topo_
=
[
node
for
node
in
topo
if
not
isinstance
(
node
.
op
,
DeepCopyOp
)]
if
not
self
.
fast_compile
:
if
not
self
.
fast_compile
:
assert
len
(
topo_
)
==
6
assert
len
(
topo_
)
==
6
assert
np
.
sum
([
isinstance
(
node
.
op
,
IncSubtensor
)
for
node
in
topo_
])
==
1
assert
any
(
isinstance
(
node
.
op
,
IncSubtensor
)
for
node
in
topo_
)
assert
np
.
sum
([
isinstance
(
node
.
op
,
Subtensor
)
for
node
in
topo_
])
==
1
assert
any
(
isinstance
(
node
.
op
,
Subtensor
)
for
node
in
topo_
)
gval
=
f
()
gval
=
f
()
good
=
np
.
zeros_like
(
data
)
good
=
np
.
zeros_like
(
data
)
...
@@ -1161,47 +1155,6 @@ class TestSubtensor(utt.OptimizationTestMixin):
...
@@ -1161,47 +1155,6 @@ class TestSubtensor(utt.OptimizationTestMixin):
val
=
f
()
val
=
f
()
assert
np
.
allclose
(
val
,
data
[
idx
]
.
shape
)
assert
np
.
allclose
(
val
,
data
[
idx
]
.
shape
)
def
test_grad_advanced_inc_subtensor
(
self
):
def
inc_slice
(
*
s
):
def
just_numeric_args
(
a
,
b
):
cost
=
(
a
[
s
]
+
b
)
.
sum
()
cost_wrt_a
=
tensor
.
grad
(
cost
,
a
)
cost_wrt_b
=
tensor
.
grad
(
cost
,
b
)
grads
=
cost_wrt_a
.
sum
()
+
cost_wrt_b
.
sum
()
return
grads
return
just_numeric_args
# vector
utt
.
verify_grad
(
inc_slice
(
slice
(
2
,
4
,
None
)),
(
np
.
asarray
([
0
,
1
,
2
,
3
,
4
,
5.0
]),
np
.
asarray
([
9
,
9.0
]),
),
mode
=
self
.
mode
,
)
# matrix
utt
.
verify_grad
(
inc_slice
(
slice
(
1
,
2
,
None
),
slice
(
None
,
None
,
None
)),
(
np
.
asarray
([[
0
,
1
],
[
2
,
3
],
[
4
,
5.0
]]),
np
.
asarray
([[
9
,
9.0
]]),
),
mode
=
self
.
mode
,
)
# single element
utt
.
verify_grad
(
inc_slice
(
2
,
1
),
(
np
.
asarray
([[
0
,
1
],
[
2
,
3
],
[
4
,
5.0
]]),
np
.
asarray
(
9.0
),
),
mode
=
self
.
mode
,
)
def
test_inc_and_set_subtensor
(
self
):
def
test_inc_and_set_subtensor
(
self
):
# Test increment and set with broadcast
# Test increment and set with broadcast
...
@@ -1323,21 +1276,6 @@ class TestSubtensor(utt.OptimizationTestMixin):
...
@@ -1323,21 +1276,6 @@ class TestSubtensor(utt.OptimizationTestMixin):
all_params
.
append
(
all_params
.
append
(
(
set_instead_of_inc
,
inplace
,
data_shape
,
inc_shape
)
(
set_instead_of_inc
,
inplace
,
data_shape
,
inc_shape
)
)
)
if
False
:
# Enable for debugging purpose.
f
=
self
.
function
(
[
data_var
,
idx_var
,
inc_var
],
output
,
accept_inplace
=
inplace
,
op
=
AdvancedIncSubtensor1
,
)
if
inplace
:
# Ensure calling `f` will not alter `data_num`.
data_num
=
data_num
.
copy
()
f_out
=
f
(
data_num
.
copy
(),
idx_num
,
inc_num
)
assert
np
.
allclose
(
f_out
,
data_copy
)
if
not
inplace
:
# Sanity check: `data_num` should be intact.
assert
(
data_num
==
data_num_init
)
.
all
()
# Actual test (we compile a single Theano function to make it faster).
# Actual test (we compile a single Theano function to make it faster).
orig_warn
=
theano
.
config
.
warn
.
gpu_set_subtensor1
orig_warn
=
theano
.
config
.
warn
.
gpu_set_subtensor1
...
@@ -1647,18 +1585,18 @@ class TestAdvancedSubtensor:
...
@@ -1647,18 +1585,18 @@ class TestAdvancedSubtensor:
rep
[
idx
]
+=
y_val
rep
[
idx
]
+=
y_val
check
(
idx
,
y_val
,
x_val
,
rep
)
check
(
idx
,
y_val
,
x_val
,
rep
)
def
eval_output_and_check
(
self
,
t
):
def
eval_output_and_check
(
self
,
t
,
op
):
f
=
inplace_func
([],
t
,
mode
=
self
.
mode
)
f
=
inplace_func
([],
t
,
mode
=
self
.
mode
)
topo
=
f
.
maker
.
fgraph
.
toposort
()
topo
=
f
.
maker
.
fgraph
.
toposort
()
topo_
=
[
node
for
node
in
topo
if
not
isinstance
(
node
.
op
,
DeepCopyOp
)]
topo_
=
[
node
for
node
in
topo
if
not
isinstance
(
node
.
op
,
DeepCopyOp
)]
assert
len
(
topo_
)
==
1
assert
len
(
topo_
)
==
1
assert
isinstance
(
topo_
[
0
]
.
op
,
AdvancedSubtensor
)
assert
isinstance
(
topo_
[
0
]
.
op
,
op
)
tval
=
f
()
tval
=
f
()
return
tval
return
tval
def
test_cant_adv_idx_into_scalar
(
self
):
def
test_cant_adv_idx_into_scalar
(
self
):
with
pytest
.
raises
(
IndexError
):
with
pytest
.
raises
(
IndexError
):
(
lambda
:
self
.
s
[
self
.
ix1
])()
self
.
s
[
self
.
ix1
]
def
test_index_into_vec_w_vec
(
self
):
def
test_index_into_vec_w_vec
(
self
):
a
=
self
.
v
[
self
.
ix1
]
a
=
self
.
v
[
self
.
ix1
]
...
@@ -1698,7 +1636,7 @@ class TestAdvancedSubtensor:
...
@@ -1698,7 +1636,7 @@ class TestAdvancedSubtensor:
assert
isinstance
(
t
.
owner
.
op
,
AdvancedSubtensor
)
assert
isinstance
(
t
.
owner
.
op
,
AdvancedSubtensor
)
val
=
self
.
eval_output_and_check
(
t
)
val
=
self
.
eval_output_and_check
(
t
,
AdvancedSubtensor
)
if
isinstance
(
idx
,
list
):
if
isinstance
(
idx
,
list
):
good
=
data
[
0
,
idx
]
good
=
data
[
0
,
idx
]
else
:
else
:
...
@@ -1942,6 +1880,35 @@ class TestAdvancedSubtensor:
...
@@ -1942,6 +1880,35 @@ class TestAdvancedSubtensor:
mode
=
self
.
mode
,
mode
=
self
.
mode
,
)
)
# Test boolean gradients
def
fun
(
x
,
y
):
return
advanced_inc_subtensor
(
x
,
y
,
tensor
.
as_tensor
(
np
.
array
([[
True
,
False
],
[
False
,
True
]]))
)
utt
.
verify_grad
(
fun
,
[
np
.
random
.
rand
(
2
,
2
)
.
astype
(
self
.
dtype
),
np
.
random
.
rand
(
2
)
.
astype
(
self
.
dtype
),
],
mode
=
self
.
mode
,
)
def
fun
(
x
,
y
):
return
advanced_set_subtensor
(
x
,
y
,
tensor
.
as_tensor
(
np
.
array
([[
True
,
False
],
[
False
,
True
]]))
)
utt
.
verify_grad
(
fun
,
[
np
.
random
.
rand
(
2
,
2
)
.
astype
(
self
.
dtype
),
np
.
random
.
rand
(
2
)
.
astype
(
self
.
dtype
),
],
mode
=
self
.
mode
,
)
class
TestInferShape
(
utt
.
InferShapeTester
):
class
TestInferShape
(
utt
.
InferShapeTester
):
def
test_IncSubtensor
(
self
):
def
test_IncSubtensor
(
self
):
...
@@ -2216,7 +2183,7 @@ class TestInferShape(utt.InferShapeTester):
...
@@ -2216,7 +2183,7 @@ class TestInferShape(utt.InferShapeTester):
AdvancedSubtensor
,
AdvancedSubtensor
,
)
)
def
test_Advanced
BooleanSubtensor
(
self
):
def
test_Advanced
Subtensor_bool
(
self
):
n
=
dmatrix
()
n
=
dmatrix
()
n_val
=
np
.
arange
(
6
)
.
reshape
((
2
,
3
))
n_val
=
np
.
arange
(
6
)
.
reshape
((
2
,
3
))
...
@@ -2225,14 +2192,14 @@ class TestInferShape(utt.InferShapeTester):
...
@@ -2225,14 +2192,14 @@ class TestInferShape(utt.InferShapeTester):
[
n
],
[
n
],
[
n
[
n
[:,
0
]
>
2
,
n
[
0
,
:]
>
2
]],
[
n
[
n
[:,
0
]
>
2
,
n
[
0
,
:]
>
2
]],
[
n_val
],
[
n_val
],
Advanced
Boolean
Subtensor
,
AdvancedSubtensor
,
check_topo
=
False
,
check_topo
=
False
,
)
)
self
.
_compile_and_check
(
self
.
_compile_and_check
(
[
n
],
[
n
],
[
n
[
n
[:,
0
]
>
2
]],
[
n
[
n
[:,
0
]
>
2
]],
[
n_val
],
[
n_val
],
Advanced
Boolean
Subtensor
,
AdvancedSubtensor
,
check_topo
=
False
,
check_topo
=
False
,
)
)
...
...
tests/tensor/test_var.py
浏览文件 @
9f56e418
...
@@ -11,7 +11,6 @@ from theano.tensor.var import TensorConstant
...
@@ -11,7 +11,6 @@ from theano.tensor.var import TensorConstant
from
theano.tensor.subtensor
import
(
from
theano.tensor.subtensor
import
(
Subtensor
,
Subtensor
,
AdvancedSubtensor
,
AdvancedSubtensor
,
AdvancedBooleanSubtensor
,
AdvancedSubtensor1
,
AdvancedSubtensor1
,
)
)
from
theano.tensor.elemwise
import
DimShuffle
from
theano.tensor.elemwise
import
DimShuffle
...
@@ -124,31 +123,30 @@ def test__getitem__Subtensor():
...
@@ -124,31 +123,30 @@ def test__getitem__Subtensor():
assert
op_types
[
-
1
]
==
Subtensor
assert
op_types
[
-
1
]
==
Subtensor
def
test__getitem__AdvancedBooleanSubtensor
():
def
test__getitem__AdvancedSubtensor_bool
():
# Make sure we get `AdvancedBooleanSubtensor`s for basic indexing operations
x
=
tt
.
matrix
(
"x"
)
x
=
tt
.
matrix
(
"x"
)
i
=
tt
.
type
.
TensorType
(
"bool"
,
(
False
,
False
))(
"i"
)
i
=
tt
.
type
.
TensorType
(
"bool"
,
(
False
,
False
))(
"i"
)
z
=
x
[
i
]
z
=
x
[
i
]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
assert
op_types
[
-
1
]
==
Advanced
Boolean
Subtensor
assert
op_types
[
-
1
]
==
AdvancedSubtensor
i
=
tt
.
type
.
TensorType
(
"bool"
,
(
False
,))(
"i"
)
i
=
tt
.
type
.
TensorType
(
"bool"
,
(
False
,))(
"i"
)
z
=
x
[:,
i
]
z
=
x
[:,
i
]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
assert
op_types
[
-
1
]
==
Advanced
Boolean
Subtensor
assert
op_types
[
-
1
]
==
AdvancedSubtensor
i
=
tt
.
type
.
TensorType
(
"bool"
,
(
False
,))(
"i"
)
i
=
tt
.
type
.
TensorType
(
"bool"
,
(
False
,))(
"i"
)
z
=
x
[
...
,
i
]
z
=
x
[
...
,
i
]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
assert
op_types
[
-
1
]
==
Advanced
Boolean
Subtensor
assert
op_types
[
-
1
]
==
AdvancedSubtensor
with
pytest
.
raises
(
TypeError
):
with
pytest
.
raises
(
TypeError
):
z
=
x
[[
True
,
False
],
i
]
z
=
x
[[
True
,
False
],
i
]
z
=
x
[
tt
.
ivector
(
"b"
),
i
]
z
=
x
[
tt
.
ivector
(
"b"
),
i
]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
op_types
=
[
type
(
node
.
op
)
for
node
in
theano
.
gof
.
graph
.
io_toposort
([
x
,
i
],
[
z
])]
assert
op_types
[
-
1
]
==
Advanced
Boolean
Subtensor
assert
op_types
[
-
1
]
==
AdvancedSubtensor
def
test__getitem__AdvancedSubtensor
():
def
test__getitem__AdvancedSubtensor
():
...
...
theano/gpuarray/opt.py
浏览文件 @
9f56e418
...
@@ -130,11 +130,9 @@ from .subtensor import (
...
@@ -130,11 +130,9 @@ from .subtensor import (
GpuSubtensor
,
GpuSubtensor
,
GpuAdvancedSubtensor
,
GpuAdvancedSubtensor
,
GpuAdvancedSubtensor1
,
GpuAdvancedSubtensor1
,
GpuAdvancedBooleanSubtensor
,
GpuAdvancedIncSubtensor
,
GpuAdvancedIncSubtensor
,
GpuAdvancedIncSubtensor1
,
GpuAdvancedIncSubtensor1
,
GpuAdvancedIncSubtensor1_dev20
,
GpuAdvancedIncSubtensor1_dev20
,
GpuAdvancedBooleanIncSubtensor
,
GpuAllocDiag
,
GpuAllocDiag
,
GpuExtractDiag
,
GpuExtractDiag
,
)
)
...
@@ -1291,13 +1289,6 @@ def local_gpua_advanced_subtensor(op, context_name, inputs, outputs):
...
@@ -1291,13 +1289,6 @@ def local_gpua_advanced_subtensor(op, context_name, inputs, outputs):
return
GpuAdvancedSubtensor
()
return
GpuAdvancedSubtensor
()
@register_opt
(
"fast_compile"
)
@op_lifter
([
tensor
.
AdvancedBooleanSubtensor
])
@register_opt2
([
tensor
.
AdvancedBooleanSubtensor
],
"fast_compile"
)
def
local_gpua_advanced_boolean_subtensor
(
op
,
context_name
,
inputs
,
outputs
):
return
GpuAdvancedBooleanSubtensor
()
@register_opt
(
"fast_compile"
)
@register_opt
(
"fast_compile"
)
@op_lifter
([
tensor
.
AdvancedIncSubtensor1
])
@op_lifter
([
tensor
.
AdvancedIncSubtensor1
])
@register_opt2
([
tensor
.
AdvancedIncSubtensor1
],
"fast_compile"
)
@register_opt2
([
tensor
.
AdvancedIncSubtensor1
],
"fast_compile"
)
...
@@ -1342,20 +1333,6 @@ def local_gpua_advanced_incsubtensor(op, context_name, inputs, outputs):
...
@@ -1342,20 +1333,6 @@ def local_gpua_advanced_incsubtensor(op, context_name, inputs, outputs):
return
False
return
False
# Do not register this optimization for now, as it slows down the
# execution by a lot in important cases.
# @register_opt('fast_compile')
# @op_lifter([tensor.AdvancedBooleanIncSubtensor])
# @register_opt2([tensor.AdvancedBooleanIncSubtensor], 'fast_compile')
def
local_gpua_advanced_boolean_incsubtensor
(
op
,
context_name
,
inputs
,
outputs
):
# GpuAdvancedIncSubtensor only works with a single boolean mask,
# but not with fancy combinations.
if
not
op
.
set_instead_of_inc
and
len
(
inputs
)
==
3
:
return
GpuAdvancedBooleanIncSubtensor
()
else
:
return
False
@register_inplace
()
@register_inplace
()
@local_optimizer
([
GpuAdvancedIncSubtensor1
,
GpuAdvancedIncSubtensor1_dev20
])
@local_optimizer
([
GpuAdvancedIncSubtensor1
,
GpuAdvancedIncSubtensor1_dev20
])
def
local_advincsub1_gpua_inplace
(
node
):
def
local_advincsub1_gpua_inplace
(
node
):
...
...
theano/gpuarray/subtensor.py
浏览文件 @
9f56e418
...
@@ -683,9 +683,6 @@ class GpuAdvancedSubtensor(HideC, BaseGpuAdvancedSubtensor, tensor.AdvancedSubte
...
@@ -683,9 +683,6 @@ class GpuAdvancedSubtensor(HideC, BaseGpuAdvancedSubtensor, tensor.AdvancedSubte
def
make_node
(
self
,
x
,
*
inputs
):
def
make_node
(
self
,
x
,
*
inputs
):
ctx_name
=
infer_context_name
(
x
)
ctx_name
=
infer_context_name
(
x
)
# This method relies on AdvancedSubtensor.make_node to
# call tensor.subtensor.check_and_reject_bool(inputs),
# which raises an IndexError if there are any boolean indices.
rval
=
tensor
.
AdvancedSubtensor
.
make_node
(
self
,
x
,
*
inputs
)
rval
=
tensor
.
AdvancedSubtensor
.
make_node
(
self
,
x
,
*
inputs
)
otype
=
GpuArrayType
(
otype
=
GpuArrayType
(
dtype
=
rval
.
outputs
[
0
]
.
type
.
dtype
,
dtype
=
rval
.
outputs
[
0
]
.
type
.
dtype
,
...
@@ -696,25 +693,6 @@ class GpuAdvancedSubtensor(HideC, BaseGpuAdvancedSubtensor, tensor.AdvancedSubte
...
@@ -696,25 +693,6 @@ class GpuAdvancedSubtensor(HideC, BaseGpuAdvancedSubtensor, tensor.AdvancedSubte
return
gof
.
Apply
(
self
,
[
x
]
+
rval
.
inputs
[
1
:],
[
otype
()])
return
gof
.
Apply
(
self
,
[
x
]
+
rval
.
inputs
[
1
:],
[
otype
()])
class
GpuAdvancedBooleanSubtensor
(
HideC
,
BaseGpuAdvancedSubtensor
,
tensor
.
AdvancedBooleanSubtensor
):
"""
AdvancedBooleanSubtensor on the GPU.
"""
def
make_node
(
self
,
x
,
*
inputs
):
ctx_name
=
infer_context_name
(
x
)
rval
=
tensor
.
AdvancedBooleanSubtensor
.
make_node
(
self
,
x
,
*
inputs
)
otype
=
GpuArrayType
(
dtype
=
rval
.
outputs
[
0
]
.
type
.
dtype
,
broadcastable
=
rval
.
outputs
[
0
]
.
type
.
broadcastable
,
context_name
=
ctx_name
,
)
x
=
as_gpuarray_variable
(
x
,
ctx_name
)
return
gof
.
Apply
(
self
,
[
x
]
+
rval
.
inputs
[
1
:],
[
otype
()])
class
BaseGpuAdvancedIncSubtensor
(
object
):
class
BaseGpuAdvancedIncSubtensor
(
object
):
def
perform
(
self
,
node
,
inp
,
out_
):
def
perform
(
self
,
node
,
inp
,
out_
):
(
out
,)
=
out_
(
out
,)
=
out_
...
@@ -852,27 +830,6 @@ class GpuAdvancedIncSubtensor(
...
@@ -852,27 +830,6 @@ class GpuAdvancedIncSubtensor(
return
gof
.
Apply
(
self
,
[
x
,
y
]
+
rval
.
inputs
[
2
:],
[
otype
()])
return
gof
.
Apply
(
self
,
[
x
,
y
]
+
rval
.
inputs
[
2
:],
[
otype
()])
class
GpuAdvancedBooleanIncSubtensor
(
HideC
,
BaseGpuAdvancedIncSubtensor
,
tensor
.
AdvancedBooleanIncSubtensor
):
"""
Implement AdvancedBooleanIncSubtensor on the gpu.
"""
def
make_node
(
self
,
x
,
y
,
*
inputs
):
ctx_name
=
infer_context_name
(
x
,
y
)
rval
=
tensor
.
AdvancedBooleanIncSubtensor
.
make_node
(
self
,
x
,
y
,
*
inputs
)
otype
=
GpuArrayType
(
dtype
=
rval
.
outputs
[
0
]
.
type
.
dtype
,
broadcastable
=
rval
.
outputs
[
0
]
.
type
.
broadcastable
,
context_name
=
ctx_name
,
)
x
=
as_gpuarray_variable
(
x
,
ctx_name
)
y
=
as_gpuarray_variable
(
y
,
ctx_name
)
return
gof
.
Apply
(
self
,
[
x
,
y
]
+
rval
.
inputs
[
2
:],
[
otype
()])
class
GpuAdvancedIncSubtensor1
(
Op
):
class
GpuAdvancedIncSubtensor1
(
Op
):
"""
"""
Implement AdvancedIncSubtensor1 on the gpu.
Implement AdvancedIncSubtensor1 on the gpu.
...
...
theano/sandbox/jaxify.py
浏览文件 @
9f56e418
...
@@ -21,8 +21,8 @@ from theano.tensor.subtensor import (
...
@@ -21,8 +21,8 @@ from theano.tensor.subtensor import (
AdvancedSubtensor1
,
AdvancedSubtensor1
,
AdvancedIncSubtensor1
,
AdvancedIncSubtensor1
,
# Boolean mask indexing and setting
# Boolean mask indexing and setting
Base
AdvancedSubtensor
,
AdvancedSubtensor
,
Base
AdvancedIncSubtensor
,
AdvancedIncSubtensor
,
)
)
from
theano.scan_module.scan_op
import
Scan
from
theano.scan_module.scan_op
import
Scan
from
theano.scan_module.scan_utils
import
scan_args
as
ScanArgs
from
theano.scan_module.scan_utils
import
scan_args
as
ScanArgs
...
@@ -97,7 +97,7 @@ try:
...
@@ -97,7 +97,7 @@ try:
except
AttributeError
:
except
AttributeError
:
pass
pass
subtensor_ops
=
(
Subtensor
,
AdvancedSubtensor1
,
Base
AdvancedSubtensor
)
subtensor_ops
=
(
Subtensor
,
AdvancedSubtensor1
,
AdvancedSubtensor
)
incsubtensor_ops
=
(
IncSubtensor
,
AdvancedIncSubtensor1
)
incsubtensor_ops
=
(
IncSubtensor
,
AdvancedIncSubtensor1
)
...
@@ -588,18 +588,18 @@ def jax_funcify_IncSubtensor(op):
...
@@ -588,18 +588,18 @@ def jax_funcify_IncSubtensor(op):
_
=
[
jax_funcify
.
register
(
op
,
jax_funcify_IncSubtensor
)
for
op
in
incsubtensor_ops
]
_
=
[
jax_funcify
.
register
(
op
,
jax_funcify_IncSubtensor
)
for
op
in
incsubtensor_ops
]
@jax_funcify.register
(
Base
AdvancedIncSubtensor
)
@jax_funcify.register
(
AdvancedIncSubtensor
)
def
jax_funcify_
Base
AdvancedIncSubtensor
(
op
):
def
jax_funcify_AdvancedIncSubtensor
(
op
):
if
getattr
(
op
,
"set_instead_of_inc"
,
False
):
if
getattr
(
op
,
"set_instead_of_inc"
,
False
):
jax_fn
=
jax
.
ops
.
index_update
jax_fn
=
jax
.
ops
.
index_update
else
:
else
:
jax_fn
=
jax
.
ops
.
index_add
jax_fn
=
jax
.
ops
.
index_add
def
base
advancedincsubtensor
(
x
,
y
,
*
ilist
,
jax_fn
=
jax_fn
):
def
advancedincsubtensor
(
x
,
y
,
*
ilist
,
jax_fn
=
jax_fn
):
return
jax_fn
(
x
,
ilist
,
y
)
return
jax_fn
(
x
,
ilist
,
y
)
return
base
advancedincsubtensor
return
advancedincsubtensor
@jax_funcify.register
(
FunctionGraph
)
@jax_funcify.register
(
FunctionGraph
)
...
...
theano/tensor/subtensor.py
浏览文件 @
9f56e418
...
@@ -9,7 +9,6 @@ import theano
...
@@ -9,7 +9,6 @@ import theano
from
textwrap
import
dedent
from
textwrap
import
dedent
from
itertools
import
groupby
,
chain
from
itertools
import
groupby
,
chain
from
collections.abc
import
Iterable
from
six
import
integer_types
from
six
import
integer_types
...
@@ -42,15 +41,6 @@ class AdvancedIndexingError(TypeError):
...
@@ -42,15 +41,6 @@ class AdvancedIndexingError(TypeError):
pass
pass
class
AdvancedBooleanIndexingError
(
TypeError
):
"""
Raised when Subtensor is asked to perform advanced indexing with boolean masks.
"""
pass
def
as_index_constant
(
a
):
def
as_index_constant
(
a
):
"""Convert Python literals to Theano constants--when possible--in Subtensor arguments.
"""Convert Python literals to Theano constants--when possible--in Subtensor arguments.
...
@@ -501,9 +491,7 @@ class Subtensor(Op):
...
@@ -501,9 +491,7 @@ class Subtensor(Op):
and
hasattr
(
entry
,
"dtype"
)
and
hasattr
(
entry
,
"dtype"
)
and
entry
.
dtype
==
"bool"
and
entry
.
dtype
==
"bool"
):
):
raise
AdvancedBooleanIndexingError
(
raise
AdvancedIndexingError
(
"Invalid index type or slice for Subtensor"
)
"Invalid index type or slice for Subtensor"
)
if
isinstance
(
entry
,
gof
.
Variable
)
and
(
if
isinstance
(
entry
,
gof
.
Variable
)
and
(
entry
.
type
in
invalid_scal_types
or
entry
.
type
in
invalid_tensor_types
entry
.
type
in
invalid_scal_types
or
entry
.
type
in
invalid_tensor_types
...
@@ -1305,17 +1293,8 @@ def inc_subtensor(
...
@@ -1305,17 +1293,8 @@ def inc_subtensor(
elif
isinstance
(
x
.
owner
.
op
,
AdvancedSubtensor
):
elif
isinstance
(
x
.
owner
.
op
,
AdvancedSubtensor
):
real_x
=
x
.
owner
.
inputs
[
0
]
real_x
=
x
.
owner
.
inputs
[
0
]
ilist
=
x
.
owner
.
inputs
[
1
:]
ilist
=
x
.
owner
.
inputs
[
1
:]
the_op
=
AdvancedIncSubtensor
(
inplace
,
set_instead_of_inc
=
set_instead_of_inc
)
the_op
=
AdvancedIncSubtensor
(
inplace
,
set_instead_of_inc
=
set_instead_of_inc
)
return
the_op
(
real_x
,
y
,
*
ilist
)
return
the_op
(
real_x
,
y
,
*
ilist
)
elif
isinstance
(
x
.
owner
.
op
,
AdvancedBooleanSubtensor
):
real_x
=
x
.
owner
.
inputs
[
0
]
ilist
=
x
.
owner
.
inputs
[
1
:]
the_op
=
AdvancedBooleanIncSubtensor
(
inplace
,
set_instead_of_inc
=
set_instead_of_inc
)
return
the_op
(
real_x
,
y
,
*
ilist
)
elif
isinstance
(
x
.
owner
.
op
,
DimShuffle
):
elif
isinstance
(
x
.
owner
.
op
,
DimShuffle
):
inner_x
=
x
.
owner
.
inputs
[
0
]
inner_x
=
x
.
owner
.
inputs
[
0
]
# In the dimshuffle case, there are in fact two dimshuffles:
# In the dimshuffle case, there are in fact two dimshuffles:
...
@@ -2329,38 +2308,12 @@ def check_advanced_indexing_dimensions(input, idx_list):
...
@@ -2329,38 +2308,12 @@ def check_advanced_indexing_dimensions(input, idx_list):
dim_seen
+=
1
dim_seen
+=
1
def
check_and_reject_bool
(
args_el
):
class
AdvancedSubtensor
(
Op
):
try
:
"""Implements NumPy's advanced indexing."""
if
isinstance
(
args_el
,
(
np
.
bool_
,
bool
))
or
args_el
.
dtype
==
"bool"
:
raise
TypeError
(
"AdvancedSubtensor does not support boolean "
"masks for indexing. Use AdvancedBooleanSubtensor "
"instead. "
)
except
AttributeError
:
pass
if
not
isinstance
(
args_el
,
theano
.
tensor
.
Variable
)
and
isinstance
(
args_el
,
Iterable
):
for
el
in
args_el
:
check_and_reject_bool
(
el
)
class
BaseAdvancedSubtensor
(
Op
):
"""Abstract base class for AdvancedSubtensor and AdvancedBooleanSubtensor.
Implements advanced indexing with boolean masks.
Should be used by __getitem__ and __getslice__, as follows:
- AdvancedSubtensor()(self, *args) or
- AdvancedBooleanSubtensor()(self, *args), if args contain advanced indices
"""
__props__
=
()
__props__
=
()
def
make_node
(
self
,
x
,
*
index
,
is_boolean
=
False
):
def
make_node
(
self
,
x
,
*
index
):
x
=
theano
.
tensor
.
as_tensor_variable
(
x
)
x
=
theano
.
tensor
.
as_tensor_variable
(
x
)
index
=
tuple
(
map
(
as_index_variable
,
index
))
index
=
tuple
(
map
(
as_index_variable
,
index
))
...
@@ -2373,16 +2326,14 @@ class BaseAdvancedSubtensor(Op):
...
@@ -2373,16 +2326,14 @@ class BaseAdvancedSubtensor(Op):
for
bcast
in
x
.
broadcastable
for
bcast
in
x
.
broadcastable
)
)
bcast_index
=
index
bcast_index
=
tuple
(
if
is_boolean
:
chain
.
from_iterable
(
bcast_index
=
tuple
(
theano
.
tensor
.
basic
.
nonzero
(
idx
)
chain
.
from_iterable
(
if
getattr
(
idx
,
"ndim"
,
0
)
>
0
and
getattr
(
idx
,
"dtype"
,
None
)
==
"bool"
theano
.
tensor
.
basic
.
nonzero
(
idx
)
else
(
idx
,)
if
getattr
(
idx
,
"ndim"
,
0
)
>
0
for
idx
in
index
else
(
idx
,)
for
idx
in
bcast_index
)
)
)
)
bcast
=
[
bcast
=
[
getattr
(
i
,
"value"
,
i
)
==
1
getattr
(
i
,
"value"
,
i
)
==
1
...
@@ -2443,17 +2394,6 @@ class BaseAdvancedSubtensor(Op):
...
@@ -2443,17 +2394,6 @@ class BaseAdvancedSubtensor(Op):
return
rval
return
rval
class
AdvancedSubtensor
(
BaseAdvancedSubtensor
):
"""
Return a subtensor copy, using advanced indexing.
"""
def
make_node
(
self
,
x
,
*
index
):
check_and_reject_bool
(
index
)
return
super
(
AdvancedSubtensor
,
self
)
.
make_node
(
x
,
*
index
)
def
grad
(
self
,
inputs
,
grads
):
def
grad
(
self
,
inputs
,
grads
):
(
gz
,)
=
grads
(
gz
,)
=
grads
x
=
inputs
[
0
]
x
=
inputs
[
0
]
...
@@ -2473,39 +2413,8 @@ class AdvancedSubtensor(BaseAdvancedSubtensor):
...
@@ -2473,39 +2413,8 @@ class AdvancedSubtensor(BaseAdvancedSubtensor):
advanced_subtensor
=
AdvancedSubtensor
()
advanced_subtensor
=
AdvancedSubtensor
()
class
AdvancedBooleanSubtensor
(
BaseAdvancedSubtensor
):
class
AdvancedIncSubtensor
(
Op
):
"""
"""Increments a subtensor using advanced indexing."""
Return a subtensor copy, using advanced indexing with boolean masks.
"""
def
make_node
(
self
,
x
,
*
index
):
return
super
()
.
make_node
(
x
,
*
index
,
is_boolean
=
True
)
def
grad
(
self
,
inputs
,
grads
):
(
gz
,)
=
grads
x
=
inputs
[
0
]
if
x
.
dtype
in
theano
.
tensor
.
discrete_dtypes
:
# The output dtype is the same as x
gx
=
x
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)
elif
x
.
dtype
in
theano
.
tensor
.
complex_dtypes
:
raise
NotImplementedError
(
"No support for complex grad yet"
)
else
:
gx
=
x
.
zeros_like
()
rest
=
inputs
[
1
:]
return
[
advanced_boolean_inc_subtensor
(
gx
,
gz
,
*
rest
)]
+
[
DisconnectedType
()()
]
*
len
(
rest
)
advanced_boolean_subtensor
=
AdvancedBooleanSubtensor
()
class
BaseAdvancedIncSubtensor
(
Op
):
"""
Base class for AdvancedIncSubtensor and AdvancedBooleanIncSubtensor.
Increments a subtensor using advanced indexing.
"""
__props__
=
(
"inplace"
,
"set_instead_of_inc"
)
__props__
=
(
"inplace"
,
"set_instead_of_inc"
)
...
@@ -2578,16 +2487,6 @@ class BaseAdvancedIncSubtensor(Op):
...
@@ -2578,16 +2487,6 @@ class BaseAdvancedIncSubtensor(Op):
return
[
None
]
return
[
None
]
return
self
.
make_node
(
eval_points
[
0
],
eval_points
[
1
],
*
inputs
[
2
:])
.
outputs
return
self
.
make_node
(
eval_points
[
0
],
eval_points
[
1
],
*
inputs
[
2
:])
.
outputs
class
AdvancedIncSubtensor
(
BaseAdvancedIncSubtensor
):
"""
Increments a subtensor using advanced indexing.
"""
def
make_node
(
self
,
x
,
y
,
*
inputs
):
check_and_reject_bool
(
inputs
)
return
super
(
AdvancedIncSubtensor
,
self
)
.
make_node
(
x
,
y
,
*
inputs
)
def
grad
(
self
,
inpt
,
output_gradients
):
def
grad
(
self
,
inpt
,
output_gradients
):
x
,
y
=
inpt
[:
2
]
x
,
y
=
inpt
[:
2
]
idxs
=
inpt
[
2
:]
idxs
=
inpt
[
2
:]
...
@@ -2617,40 +2516,6 @@ advanced_inc_subtensor = AdvancedIncSubtensor()
...
@@ -2617,40 +2516,6 @@ advanced_inc_subtensor = AdvancedIncSubtensor()
advanced_set_subtensor
=
AdvancedIncSubtensor
(
set_instead_of_inc
=
True
)
advanced_set_subtensor
=
AdvancedIncSubtensor
(
set_instead_of_inc
=
True
)
class
AdvancedBooleanIncSubtensor
(
BaseAdvancedIncSubtensor
):
"""
Increments a subtensor using advanced indexing with boolean masks.
"""
def
grad
(
self
,
inpt
,
output_gradients
):
x
,
y
=
inpt
[:
2
]
idxs
=
inpt
[
2
:]
(
outgrad
,)
=
output_gradients
if
x
.
dtype
in
theano
.
tensor
.
discrete_dtypes
:
# The output dtype is the same as x
gx
=
x
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)
if
y
.
dtype
in
theano
.
tensor
.
discrete_dtypes
:
gy
=
y
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)
else
:
gy
=
y
.
zeros_like
()
elif
x
.
dtype
in
theano
.
tensor
.
complex_dtypes
:
raise
NotImplementedError
(
"No support for complex grad yet"
)
else
:
if
self
.
set_instead_of_inc
:
gx
=
advanced_set_subtensor
(
outgrad
,
y
.
zeros_like
(),
*
idxs
)
else
:
gx
=
outgrad
gy
=
advanced_boolean_subtensor
(
outgrad
,
*
idxs
)
# Make sure to sum gy over the dimensions of y that have been
# added or broadcasted
gy
=
_sum_grad_over_bcasted_dims
(
y
,
gy
)
return
[
gx
,
gy
]
+
[
DisconnectedType
()()
for
_
in
idxs
]
advanced_boolean_inc_subtensor
=
AdvancedBooleanIncSubtensor
()
advanced_boolean_set_subtensor
=
AdvancedBooleanIncSubtensor
(
set_instead_of_inc
=
True
)
def
take
(
a
,
indices
,
axis
=
None
,
mode
=
"raise"
):
def
take
(
a
,
indices
,
axis
=
None
,
mode
=
"raise"
):
"""Take elements from an array along an axis.
"""Take elements from an array along an axis.
...
...
theano/tensor/var.py
浏览文件 @
9f56e418
...
@@ -523,33 +523,30 @@ class _tensor_py_operators(object):
...
@@ -523,33 +523,30 @@ class _tensor_py_operators(object):
]
]
)
)
# Determine if advanced indexing is needed or not
# Determine if advanced indexing is needed or not. The logic is
# The logic is already in Subtensor.convert: if it succeeds,
# already in `Subtensor.convert`: if it succeeds, standard indexing is
# standard indexing is used; if it fails with
# used; if it fails with AdvancedIndexingError, advanced indexing is
# AdvancedIndexingError, advanced indexing, or
# used
# AdvancedBooleanIndexingError, advanced indexing with boolean masks
advanced
=
False
advanced
=
False
advanced_boolean
=
False
axis
=
None
axis
=
None
for
i
,
arg
in
enumerate
(
args
):
for
i
,
arg
in
enumerate
(
args
):
try
:
if
includes_bool
(
arg
):
if
arg
is
not
np
.
newaxis
:
advanced
=
True
theano
.
tensor
.
subtensor
.
Subtensor
.
convert
(
arg
)
axis
=
None
except
theano
.
tensor
.
subtensor
.
AdvancedIndexingError
:
if
advanced
:
axis
=
None
break
else
:
advanced
=
True
axis
=
i
except
theano
.
tensor
.
subtensor
.
AdvancedBooleanIndexingError
:
advanced
=
False
advanced_boolean
=
True
break
break
if
advanced_boolean
:
if
arg
is
not
np
.
newaxis
:
return
theano
.
tensor
.
subtensor
.
advanced_boolean_subtensor
(
self
,
*
args
)
try
:
elif
advanced
:
theano
.
tensor
.
subtensor
.
Subtensor
.
convert
(
arg
)
except
theano
.
tensor
.
subtensor
.
AdvancedIndexingError
:
if
advanced
:
axis
=
None
break
else
:
advanced
=
True
axis
=
i
if
advanced
:
if
(
if
(
axis
is
not
None
axis
is
not
None
and
all
(
isinstance
(
a
,
slice
)
and
a
==
slice
(
None
)
for
a
in
args
[:
axis
])
and
all
(
isinstance
(
a
,
slice
)
and
a
==
slice
(
None
)
for
a
in
args
[:
axis
])
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论