Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
4025a2dc
提交
4025a2dc
authored
4月 18, 2017
作者:
Frédéric Bastien
提交者:
GitHub
4月 18, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5755 from notoraptor/op-param-gpudnnsoftmax
Use Op params for GpuDnnSoftmax
上级
a9b6985d
574d0203
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
9 个修改的文件
包含
84 行增加
和
35 行删除
+84
-35
params_type.txt
doc/library/gof/params_type.txt
+2
-2
op.py
theano/gof/op.py
+1
-1
params_type.py
theano/gof/params_type.py
+0
-0
test_params_type.py
theano/gof/tests/test_params_type.py
+30
-1
test_types.py
theano/gof/tests/test_types.py
+25
-7
type.py
theano/gof/type.py
+0
-0
dnn.py
theano/gpuarray/dnn.py
+18
-16
dnn_softmax.c
theano/gpuarray/dnn_softmax.c
+4
-4
dnn_softmax_grad.c
theano/gpuarray/dnn_softmax_grad.c
+4
-4
没有找到文件。
doc/library/gof/params_type.txt
浏览文件 @
4025a2dc
...
@@ -12,4 +12,5 @@ Reference
...
@@ -12,4 +12,5 @@ Reference
:platform: Unix, Windows
:platform: Unix, Windows
:synopsis: Wrapper class for op params
:synopsis: Wrapper class for op params
:members:
:members:
.. moduleauthor:: LISA
:member-order: bysource
\ No newline at end of file
.. moduleauthor:: LISA
theano/gof/op.py
浏览文件 @
4025a2dc
...
@@ -808,7 +808,7 @@ class Op(utils.object2, PureOp, CLinkerOp):
...
@@ -808,7 +808,7 @@ class Op(utils.object2, PureOp, CLinkerOp):
field
=
wrapper
.
fields
[
i
]
field
=
wrapper
.
fields
[
i
]
_type
=
wrapper
.
types
[
i
]
_type
=
wrapper
.
types
[
i
]
wrap_dict
[
field
]
=
_type
.
filter
(
getattr
(
self
,
field
),
strict
=
False
,
allow_downcast
=
True
)
wrap_dict
[
field
]
=
_type
.
filter
(
getattr
(
self
,
field
),
strict
=
False
,
allow_downcast
=
True
)
return
theano
.
gof
.
Params
(
wrapper
,
**
wrap_dict
)
return
self
.
params_type
.
get_params
(
self
)
raise
theano
.
gof
.
utils
.
MethodNotDefined
(
'get_params'
)
raise
theano
.
gof
.
utils
.
MethodNotDefined
(
'get_params'
)
def
prepare_node
(
self
,
node
,
storage_map
,
compute_map
,
impl
):
def
prepare_node
(
self
,
node
,
storage_map
,
compute_map
,
impl
):
...
...
theano/gof/params_type.py
浏览文件 @
4025a2dc
差异被折叠。
点击展开。
theano/gof/tests/test_params_type.py
浏览文件 @
4025a2dc
...
@@ -6,7 +6,7 @@ from theano.gof import Op, COp, Apply
...
@@ -6,7 +6,7 @@ from theano.gof import Op, COp, Apply
from
theano
import
Generic
from
theano
import
Generic
from
theano.scalar
import
Scalar
from
theano.scalar
import
Scalar
from
theano.tensor
import
TensorType
from
theano.tensor
import
TensorType
from
theano.gof
import
ParamsType
,
Params
from
theano.gof
import
ParamsType
,
Params
,
EnumList
from
theano
import
tensor
from
theano
import
tensor
from
theano.tests
import
unittest_tools
as
utt
from
theano.tests
import
unittest_tools
as
utt
...
@@ -213,6 +213,35 @@ class TestParamsType(TestCase):
...
@@ -213,6 +213,35 @@ class TestParamsType(TestCase):
a3
=
2000.0
-
0.00000000000000001
)
a3
=
2000.0
-
0.00000000000000001
)
assert
w
.
values_eq_approx
(
o1
,
o3
)
assert
w
.
values_eq_approx
(
o1
,
o3
)
def
test_params_type_with_enums
(
self
):
# Test that we fail if we create a params type with common enum names inside different enum types.
try
:
ParamsType
(
enum1
=
EnumList
(
'A'
,
'B'
,
'C'
),
enum2
=
EnumList
(
'A'
,
'B'
,
'F'
))
except
AttributeError
:
pass
else
:
raise
Exception
(
'ParamsType should fail with common enum names inside different enum types.'
)
# Test that we fail if we create a params type with common names in both aliases and constants.
try
:
ParamsType
(
enum1
=
EnumList
((
'A'
,
'a'
),
(
'B'
,
'b'
)),
enum2
=
EnumList
((
'ONE'
,
'a'
),
(
'TWO'
,
'two'
)))
except
AttributeError
:
ParamsType
(
enum1
=
EnumList
((
'A'
,
'a'
),
(
'B'
,
'b'
)),
enum2
=
EnumList
((
'ONE'
,
'one'
),
(
'TWO'
,
'two'
)))
else
:
raise
Exception
(
'ParamsType should fail when there are aliases with same names as some constants.'
)
# Test that we can access enum values through wrapper directly.
w
=
ParamsType
(
enum1
=
EnumList
(
'A'
,
(
'B'
,
'beta'
),
'C'
),
enum2
=
EnumList
((
'D'
,
'delta'
),
'E'
,
'F'
))
assert
w
.
A
==
0
and
w
.
B
==
1
and
w
.
C
==
2
assert
w
.
D
==
0
and
w
.
E
==
1
and
w
.
F
==
2
# Test constants access through aliases.
assert
w
.
enum_from_alias
(
'beta'
)
==
w
.
B
assert
w
.
enum_from_alias
(
'delta'
)
==
w
.
D
assert
w
.
enum_from_alias
(
'C'
)
==
w
.
C
# C is not an alias, so it should return a constant named C.
# Test that other regular wrapper attributes are still available.
assert
len
(
w
.
fields
)
==
len
(
w
.
types
)
==
w
.
length
assert
w
.
name
def
test_op_params
(
self
):
def
test_op_params
(
self
):
a
,
b
,
c
=
2
,
3
,
-
7
a
,
b
,
c
=
2
,
3
,
-
7
x
=
tensor
.
matrix
(
dtype
=
'float64'
)
x
=
tensor
.
matrix
(
dtype
=
'float64'
)
...
...
theano/gof/tests/test_types.py
浏览文件 @
4025a2dc
...
@@ -81,18 +81,19 @@ def test_cdata():
...
@@ -81,18 +81,19 @@ def test_cdata():
class
MyOpEnumList
(
Op
):
class
MyOpEnumList
(
Op
):
__props__
=
(
'op_chosen'
,)
__props__
=
(
'op_chosen'
,)
params_type
=
EnumList
(
'ADD'
,
'SUB'
,
'MULTIPLY'
,
'DIVIDE'
,
ctype
=
'unsigned long long'
)
params_type
=
EnumList
(
(
'ADD'
,
'+'
),
(
'SUB'
,
'-'
),
(
'MULTIPLY'
,
'*'
),
(
'DIVIDE'
,
'/'
)
,
ctype
=
'unsigned long long'
)
def
__init__
(
self
,
choose_op
):
def
__init__
(
self
,
choose_op
):
assert
self
.
params_type
.
ADD
==
0
assert
self
.
params_type
.
ADD
==
0
assert
self
.
params_type
.
SUB
==
1
assert
self
.
params_type
.
SUB
==
1
assert
self
.
params_type
.
MULTIPLY
==
2
assert
self
.
params_type
.
MULTIPLY
==
2
assert
self
.
params_type
.
DIVIDE
==
3
assert
self
.
params_type
.
DIVIDE
==
3
op_to_const
=
{
'+'
:
self
.
params_type
.
ADD
,
assert
self
.
params_type
.
fromalias
(
'+'
)
==
self
.
params_type
.
ADD
'-'
:
self
.
params_type
.
SUB
,
assert
self
.
params_type
.
fromalias
(
'-'
)
==
self
.
params_type
.
SUB
'*'
:
self
.
params_type
.
MULTIPLY
,
assert
self
.
params_type
.
fromalias
(
'*'
)
==
self
.
params_type
.
MULTIPLY
'/'
:
self
.
params_type
.
DIVIDE
}
assert
self
.
params_type
.
fromalias
(
'/'
)
==
self
.
params_type
.
DIVIDE
self
.
op_chosen
=
op_to_const
[
choose_op
]
assert
self
.
params_type
.
has_alias
(
choose_op
)
self
.
op_chosen
=
choose_op
def
get_params
(
self
,
node
):
def
get_params
(
self
,
node
):
return
self
.
op_chosen
return
self
.
op_chosen
...
@@ -204,7 +205,7 @@ class TestEnumTypes(TestCase):
...
@@ -204,7 +205,7 @@ class TestEnumTypes(TestCase):
# Check that invalid enum value raises exception.
# Check that invalid enum value raises exception.
try
:
try
:
EnumType
(
INVALID_VALUE
=
'string is not allowed.'
)
EnumType
(
INVALID_VALUE
=
'string is not allowed.'
)
except
Valu
eError
:
except
Typ
eError
:
pass
pass
else
:
else
:
raise
Exception
(
'EnumType with invalid value should fail.'
)
raise
Exception
(
'EnumType with invalid value should fail.'
)
...
@@ -218,6 +219,23 @@ class TestEnumTypes(TestCase):
...
@@ -218,6 +219,23 @@ class TestEnumTypes(TestCase):
# Check access to attributes.
# Check access to attributes.
assert
len
((
e1
.
ctype
,
e1
.
C1
,
e1
.
C2
,
e1
.
C3
,
e1
.
C4
,
e1
.
C5
,
e1
.
C6
))
==
7
assert
len
((
e1
.
ctype
,
e1
.
C1
,
e1
.
C2
,
e1
.
C3
,
e1
.
C4
,
e1
.
C5
,
e1
.
C6
))
==
7
# Check enum with aliases.
e1
=
EnumType
(
A
=
(
'alpha'
,
0
),
B
=
(
'beta'
,
1
),
C
=
2
)
e2
=
EnumType
(
A
=
(
'alpha'
,
0
),
B
=
(
'beta'
,
1
),
C
=
2
)
e3
=
EnumType
(
A
=
(
'a'
,
0
),
B
=
(
'beta'
,
1
),
C
=
2
)
assert
e1
==
e2
assert
e1
!=
e3
assert
e1
.
filter
(
'beta'
)
==
e1
.
fromalias
(
'beta'
)
==
e1
.
B
==
1
assert
e1
.
filter
(
'C'
)
==
e1
.
fromalias
(
'C'
)
==
e1
.
C
==
2
# Check that invalid alias (same as a constant) raises exception.
try
:
EnumList
((
'A'
,
'a'
),
(
'B'
,
'B'
))
except
TypeError
:
EnumList
((
'A'
,
'a'
),
(
'B'
,
'b'
))
else
:
raise
Exception
(
'Enum with an alias name equal to a constant name should fail.'
)
def
test_op_with_enumlist
(
self
):
def
test_op_with_enumlist
(
self
):
a
=
scalar
.
int32
()
a
=
scalar
.
int32
()
b
=
scalar
.
int32
()
b
=
scalar
.
int32
()
...
...
theano/gof/type.py
浏览文件 @
4025a2dc
差异被折叠。
点击展开。
theano/gpuarray/dnn.py
浏览文件 @
4025a2dc
...
@@ -12,7 +12,7 @@ from theano import Op, Apply, tensor, config, Variable
...
@@ -12,7 +12,7 @@ from theano import Op, Apply, tensor, config, Variable
from
theano.scalar
import
as_scalar
,
constant
,
Log
,
get_scalar_type
from
theano.scalar
import
as_scalar
,
constant
,
Log
,
get_scalar_type
from
theano.tensor
import
as_tensor_variable
from
theano.tensor
import
as_tensor_variable
from
theano.gradient
import
DisconnectedType
,
grad_not_implemented
from
theano.gradient
import
DisconnectedType
,
grad_not_implemented
from
theano.gof
import
Optimizer
,
local_optimizer
,
COp
from
theano.gof
import
Optimizer
,
local_optimizer
,
COp
,
ParamsType
,
CEnumType
from
theano.gof.cmodule
import
GCC_compiler
from
theano.gof.cmodule
import
GCC_compiler
from
theano.gof.type
import
CDataType
,
Generic
from
theano.gof.type
import
CDataType
,
Generic
from
theano.compile
import
optdb
from
theano.compile
import
optdb
...
@@ -234,6 +234,11 @@ class DnnBase(COp):
...
@@ -234,6 +234,11 @@ class DnnBase(COp):
ptr
=
ctx
.
cudnn_handle
.
value
ptr
=
ctx
.
cudnn_handle
.
value
res
=
handle_type
.
make_value
(
ptr
)
res
=
handle_type
.
make_value
(
ptr
)
ctx
.
cudnn_handle_param
=
res
ctx
.
cudnn_handle_param
=
res
if
isinstance
(
self
.
params_type
,
ParamsType
):
if
not
self
.
params_type
.
has_type
(
handle_type
):
raise
TypeError
(
'DnnBase: params_type must take into account the cuDNN handle type.'
)
handle_field
=
self
.
params_type
.
get_field
(
handle_type
)
return
self
.
params_type
.
get_params
(
self
,
**
{
handle_field
:
ctx
.
cudnn_handle_param
})
return
ctx
.
cudnn_handle_param
return
ctx
.
cudnn_handle_param
def
__init__
(
self
,
files
=
None
,
c_func
=
None
):
def
__init__
(
self
,
files
=
None
,
c_func
=
None
):
...
@@ -1504,6 +1509,18 @@ class GpuDnnSoftmaxBase(DnnBase):
...
@@ -1504,6 +1509,18 @@ class GpuDnnSoftmaxBase(DnnBase):
"""
"""
__props__
=
(
'mode'
,
'algo'
)
__props__
=
(
'mode'
,
'algo'
)
# Neither inputs nor output types properties are used
# neither in dnn_base.c nor in dnn_softmax*.c,
# so we can disable input checking.
check_input
=
False
params_type
=
ParamsType
(
algo
=
CEnumType
((
'CUDNN_SOFTMAX_FAST'
,
'fast'
),
(
'CUDNN_SOFTMAX_LOG'
,
'log'
),
(
'CUDNN_SOFTMAX_ACCURATE'
,
'accurate'
),
ctype
=
'cudnnSoftmaxAlgorithm_t'
),
mode
=
CEnumType
((
'CUDNN_SOFTMAX_MODE_INSTANCE'
,
'instance'
),
(
'CUDNN_SOFTMAX_MODE_CHANNEL'
,
'channel'
),
ctype
=
'cudnnSoftmaxMode_t'
),
handle
=
handle_type
)
def
__init__
(
self
,
algo
,
mode
):
def
__init__
(
self
,
algo
,
mode
):
DnnBase
.
__init__
(
self
,
[
self
.
file
],
self
.
c_func
)
DnnBase
.
__init__
(
self
,
[
self
.
file
],
self
.
c_func
)
...
@@ -1520,21 +1537,6 @@ class GpuDnnSoftmaxBase(DnnBase):
...
@@ -1520,21 +1537,6 @@ class GpuDnnSoftmaxBase(DnnBase):
else
:
else
:
return
[
shape
[
1
]]
return
[
shape
[
1
]]
def
get_op_params
(
self
):
if
self
.
mode
==
'instance'
:
mode
=
"CUDNN_SOFTMAX_MODE_INSTANCE"
else
:
mode
=
"CUDNN_SOFTMAX_MODE_CHANNEL"
if
self
.
algo
==
'fast'
:
algo
=
"CUDNN_SOFTMAX_FAST"
elif
self
.
algo
==
'log'
:
algo
=
"CUDNN_SOFTMAX_LOG"
else
:
algo
=
"CUDNN_SOFTMAX_ACCURATE"
return
[(
"SOFTMAX_MODE"
,
mode
),
(
"SOFTMAX_ALGO"
,
algo
)]
class
GpuDnnSoftmax
(
GpuDnnSoftmaxBase
):
class
GpuDnnSoftmax
(
GpuDnnSoftmaxBase
):
...
...
theano/gpuarray/dnn_softmax.c
浏览文件 @
4025a2dc
...
@@ -35,7 +35,7 @@ if (APPLY_SPECIFIC(output) != NULL)
...
@@ -35,7 +35,7 @@ if (APPLY_SPECIFIC(output) != NULL)
int
APPLY_SPECIFIC
(
softmax
)(
PyGpuArrayObject
*
x
,
int
APPLY_SPECIFIC
(
softmax
)(
PyGpuArrayObject
*
x
,
PyGpuArrayObject
**
out
,
PyGpuArrayObject
**
out
,
cudnnHandle_t
_handle
)
{
PARAMS_TYPE
*
wrapper
)
{
PyGpuContextObject
*
c
=
x
->
context
;
PyGpuContextObject
*
c
=
x
->
context
;
cudnnStatus_t
err
;
cudnnStatus_t
err
;
...
@@ -83,9 +83,9 @@ int APPLY_SPECIFIC(softmax)(PyGpuArrayObject *x,
...
@@ -83,9 +83,9 @@ int APPLY_SPECIFIC(softmax)(PyGpuArrayObject *x,
cuda_wait
((
*
out
)
->
ga
.
data
,
GPUARRAY_CUDA_WAIT_WRITE
);
cuda_wait
((
*
out
)
->
ga
.
data
,
GPUARRAY_CUDA_WAIT_WRITE
);
err
=
cudnnSoftmaxForward
(
err
=
cudnnSoftmaxForward
(
_
handle
,
wrapper
->
handle
,
SOFTMAX_ALGO
,
wrapper
->
algo
,
SOFTMAX_MODE
,
wrapper
->
mode
,
alpha
,
alpha
,
APPLY_SPECIFIC
(
input
),
APPLY_SPECIFIC
(
input
),
PyGpuArray_DEV_DATA
(
x
),
PyGpuArray_DEV_DATA
(
x
),
...
...
theano/gpuarray/dnn_softmax_grad.c
浏览文件 @
4025a2dc
...
@@ -46,7 +46,7 @@ if (APPLY_SPECIFIC(dx) != NULL)
...
@@ -46,7 +46,7 @@ if (APPLY_SPECIFIC(dx) != NULL)
int
APPLY_SPECIFIC
(
softmax_grad
)(
PyGpuArrayObject
*
dy
,
int
APPLY_SPECIFIC
(
softmax_grad
)(
PyGpuArrayObject
*
dy
,
PyGpuArrayObject
*
sm
,
PyGpuArrayObject
*
sm
,
PyGpuArrayObject
**
dx
,
PyGpuArrayObject
**
dx
,
cudnnHandle_t
_handle
)
{
PARAMS_TYPE
*
wrapper
)
{
PyGpuContextObject
*
c
=
dy
->
context
;
PyGpuContextObject
*
c
=
dy
->
context
;
cudnnStatus_t
err
;
cudnnStatus_t
err
;
...
@@ -97,9 +97,9 @@ int APPLY_SPECIFIC(softmax_grad)(PyGpuArrayObject *dy,
...
@@ -97,9 +97,9 @@ int APPLY_SPECIFIC(softmax_grad)(PyGpuArrayObject *dy,
cuda_wait
((
*
dx
)
->
ga
.
data
,
GPUARRAY_CUDA_WAIT_WRITE
);
cuda_wait
((
*
dx
)
->
ga
.
data
,
GPUARRAY_CUDA_WAIT_WRITE
);
err
=
cudnnSoftmaxBackward
(
err
=
cudnnSoftmaxBackward
(
_
handle
,
wrapper
->
handle
,
SOFTMAX_ALGO
,
wrapper
->
algo
,
SOFTMAX_MODE
,
wrapper
->
mode
,
alpha
,
alpha
,
APPLY_SPECIFIC
(
sm
),
APPLY_SPECIFIC
(
sm
),
PyGpuArray_DEV_DATA
(
sm
),
PyGpuArray_DEV_DATA
(
sm
),
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论