Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
1ffa497a
提交
1ffa497a
authored
6月 26, 2017
作者:
notoraptor
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update Theano enumeration types to add a printing function for debug C mode.
上级
3b914f3b
隐藏空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
69 行增加
和
17 行删除
+69
-17
type.py
theano/gof/type.py
+69
-17
没有找到文件。
theano/gof/type.py
浏览文件 @
1ffa497a
...
@@ -850,19 +850,27 @@ class EnumType(Type, dict):
...
@@ -850,19 +850,27 @@ class EnumType(Type, dict):
int constant_3 = CONSTANT_3; // constant_3 == 0
int constant_3 = CONSTANT_3; // constant_3 == 0
int constant_4 = CONSTANT_4; // constant_4 == 1
int constant_4 = CONSTANT_4; // constant_4 == 1
You can also specify a C type for the op param if you want to pass one of these constant values at runtime.
You can also specify a C type for the op param. Default C type is ``double``.
Default C type is ``double``.
.. code-block:: python
.. code-block:: python
enum = EnumType(CONSTANT_1=0, CONSTANT_2=1, CONSTANT_3=2, ctype='size_t')
enum = EnumType(CONSTANT_1=0, CONSTANT_2=1, CONSTANT_3=2, ctype='size_t')
op_param_value = enum.CONSTANT_1
# In C code, the Op param will then be a ``size_t``.
In C code
:
.. note:
:
.. code-block:: c
You can also specify a C name (``cname``) or the current enumeration. This C name may be
used to name functions related to that specific enumeration, e.g. for debugging
purposes. Default C name is the C type (with any sequence of spaces replaced with
an underscore). If you want to debug and your C type is quite generic (e.g.
``int`` or ``double``), we recommend you specify a C name.
C name must be a valid C identifier.
.. code-block:: python
size_t value = op_param_value; // contains enum.CONSTANT_1, i.e 0
enum = EnumType(CONSTANT_1=0, CONSTANT_2=1, CONSTANT_3=2,
ctype='size_t', cname='MyEnumName')
**Example with aliases**
**Example with aliases**
...
@@ -917,8 +925,14 @@ class EnumType(Type, dict):
...
@@ -917,8 +925,14 @@ class EnumType(Type, dict):
raise
TypeError
(
'
%
s: invalid C type.'
%
type
(
self
)
.
__name__
)
raise
TypeError
(
'
%
s: invalid C type.'
%
type
(
self
)
.
__name__
)
self
.
ctype
=
' '
.
join
(
ctype_parts
)
self
.
ctype
=
' '
.
join
(
ctype_parts
)
def
__init_cname
(
self
,
cname
):
if
not
re
.
match
(
'^[A-Za-z_][A-Za-z0-9_]*$'
,
cname
):
raise
TypeError
(
"
%
s: invalid C name."
%
type
(
self
)
.
__name__
)
self
.
cname
=
cname
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
**
kwargs
):
self
.
__init_ctype
(
kwargs
.
pop
(
'ctype'
,
'double'
))
self
.
__init_ctype
(
kwargs
.
pop
(
'ctype'
,
'double'
))
self
.
__init_cname
(
kwargs
.
pop
(
'cname'
,
self
.
ctype
.
replace
(
' '
,
'_'
)))
self
.
aliases
=
dict
()
self
.
aliases
=
dict
()
for
k
in
kwargs
:
for
k
in
kwargs
:
if
re
.
match
(
'^[A-Z][A-Z0-9_]*$'
,
k
)
is
None
:
if
re
.
match
(
'^[A-Z][A-Z0-9_]*$'
,
k
)
is
None
:
...
@@ -1042,12 +1056,51 @@ class EnumType(Type, dict):
...
@@ -1042,12 +1056,51 @@ class EnumType(Type, dict):
#endif
#endif
"""
"""
def
c_to_string
(
self
):
"""
Return code for a C function that will convert an enumeration value
to a string representation. The function prototype is:
.. code-block:: c
int theano_enum_to_string_<cname>(<ctype> value, char* output_string);
Where ``ctype`` and ``cname`` are the C type and the C name of current Theano enumeration.
``output_string`` should be large enough to contain the longest name in this enumeration.
If given value is unknown, the C function sets a Python ValueError exception and returns a non-zero.
This C function may be useful to retrieve some runtime informations.
It is available in C code when theano flag ``config.cmodule.debug`` is set to ``True``.
"""
return
"""
#ifdef DEBUG
int theano_enum_to_string_
%(cname)
s(
%(ctype)
s in, char* out) {
int ret = 0;
switch(in) {
%(cases)
s
default:
PyErr_SetString(PyExc_ValueError, "
%(classname)
s: unknown enum value.");
ret = -1;
break;
}
return ret;
}
#endif
"""
%
dict
(
cname
=
self
.
cname
,
ctype
=
self
.
ctype
,
classname
=
type
(
self
)
.
__name__
,
cases
=
''
.
join
(
"""
case
%(name)
s: sprintf(out, "
%(name)
s"); break;
"""
%
dict
(
name
=
name
)
for
name
in
self
))
def
c_support_code
(
self
):
def
c_support_code
(
self
):
return
(
return
(
self
.
pyint_compat_code
+
self
.
pyint_compat_code
+
''
.
join
(
"""
''
.
join
(
"""
#define
%
s
%
s
#define
%
s
%
s
"""
%
(
k
,
str
(
self
[
k
]))
for
k
in
sorted
(
self
.
keys
()))
"""
%
(
k
,
str
(
self
[
k
]))
for
k
in
sorted
(
self
.
keys
()))
+
self
.
c_to_string
()
)
)
def
c_declare
(
self
,
name
,
sub
,
check_input
=
True
):
def
c_declare
(
self
,
name
,
sub
,
check_input
=
True
):
...
@@ -1072,7 +1125,7 @@ class EnumType(Type, dict):
...
@@ -1072,7 +1125,7 @@ class EnumType(Type, dict):
"""
%
dict
(
ctype
=
self
.
ctype
,
name
=
name
,
fail
=
sub
[
'fail'
])
"""
%
dict
(
ctype
=
self
.
ctype
,
name
=
name
,
fail
=
sub
[
'fail'
])
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
1
,
1
)
return
(
2
,
self
.
ctype
,
self
.
cname
,
tuple
(
self
.
items
())
)
class
EnumList
(
EnumType
):
class
EnumList
(
EnumType
):
...
@@ -1091,7 +1144,7 @@ class EnumList(EnumType):
...
@@ -1091,7 +1144,7 @@ class EnumList(EnumType):
print (enum.CONSTANT_1, enum.CONSTANT_2, enum.CONSTANT_3, enum.CONSTANT_4, enum.CONSTANT_5)
print (enum.CONSTANT_1, enum.CONSTANT_2, enum.CONSTANT_3, enum.CONSTANT_4, enum.CONSTANT_5)
# will print: 0 1 2 3 4
# will print: 0 1 2 3 4
Like :class:`EnumType`, you can also define the C type for the op param.
Like :class:`EnumType`, you can also define the C type
and a C name
for the op param.
Default C type is ``int``::
Default C type is ``int``::
enum = EnumList('CONSTANT_1', 'CONSTANT_2', 'CONSTANT_3', 'CONSTANT_4', ctype='unsigned int')
enum = EnumList('CONSTANT_1', 'CONSTANT_2', 'CONSTANT_3', 'CONSTANT_4', ctype='unsigned int')
...
@@ -1109,9 +1162,10 @@ class EnumList(EnumType):
...
@@ -1109,9 +1162,10 @@ class EnumList(EnumType):
"""
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
assert
len
(
kwargs
)
==
0
or
(
len
(
kwargs
)
==
1
and
'ctype'
in
kwargs
),
\
assert
len
(
kwargs
)
in
(
0
,
1
,
2
),
(
type
(
self
)
.
__name__
+
type
(
self
)
.
__name__
+
': expected 0 or only 1 extra parameter "ctype".'
': expected 0 to 2 extra parameters ("ctype", "cname").'
)
ctype
=
kwargs
.
pop
(
'ctype'
,
'int'
)
ctype
=
kwargs
.
pop
(
'ctype'
,
'int'
)
cname
=
kwargs
.
pop
(
'cname'
,
ctype
)
for
arg_rank
,
arg
in
enumerate
(
args
):
for
arg_rank
,
arg
in
enumerate
(
args
):
if
isinstance
(
arg
,
(
list
,
tuple
)):
if
isinstance
(
arg
,
(
list
,
tuple
)):
...
@@ -1133,7 +1187,7 @@ class EnumList(EnumType):
...
@@ -1133,7 +1187,7 @@ class EnumList(EnumType):
raise
TypeError
(
'
%
s: constant name already used ("
%
s").'
%
(
type
(
self
)
.
__name__
,
constant_name
))
raise
TypeError
(
'
%
s: constant name already used ("
%
s").'
%
(
type
(
self
)
.
__name__
,
constant_name
))
kwargs
[
constant_name
]
=
constant_value
kwargs
[
constant_name
]
=
constant_value
kwargs
.
update
(
ctype
=
ctype
)
kwargs
.
update
(
ctype
=
ctype
,
cname
=
cname
)
super
(
EnumList
,
self
)
.
__init__
(
**
kwargs
)
super
(
EnumList
,
self
)
.
__init__
(
**
kwargs
)
...
@@ -1150,7 +1204,7 @@ class CEnumType(EnumList):
...
@@ -1150,7 +1204,7 @@ class CEnumType(EnumList):
- In C code, the real values defined in C will be used.
- In C code, the real values defined in C will be used.
They could be used either for choices or for its real values.
They could be used either for choices or for its real values.
Like :class:`EnumList`, you can also define the C type for the op param.
Like :class:`EnumList`, you can also define the C type
and a C name
for the op param.
Default C type is ``int``.
Default C type is ``int``.
.. code-block:: python
.. code-block:: python
...
@@ -1169,7 +1223,7 @@ class CEnumType(EnumList):
...
@@ -1169,7 +1223,7 @@ class CEnumType(EnumList):
"""
"""
def
c_support_code
(
self
):
def
c_support_code
(
self
):
return
self
.
pyint_compat_code
return
self
.
pyint_compat_code
+
self
.
c_to_string
()
def
c_extract
(
self
,
name
,
sub
,
check_input
=
True
):
def
c_extract
(
self
,
name
,
sub
,
check_input
=
True
):
swapped_dict
=
dict
((
v
,
k
)
for
(
k
,
v
)
in
self
.
items
())
swapped_dict
=
dict
((
v
,
k
)
for
(
k
,
v
)
in
self
.
items
())
...
@@ -1190,6 +1244,4 @@ class CEnumType(EnumList):
...
@@ -1190,6 +1244,4 @@ class CEnumType(EnumList):
fail
=
sub
[
'fail'
])
fail
=
sub
[
'fail'
])
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
# C code depends on (C constant name, Python value) associations (given by `self.items()`),
return
(
1
,
super
(
CEnumType
,
self
)
.
c_code_cache_version
())
# so we should better take them into account in C code version.
return
(
1
,
tuple
(
self
.
items
()),
super
(
CEnumType
,
self
)
.
c_code_cache_version
())
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论