Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
ac04eccd
提交
ac04eccd
authored
4月 21, 2017
作者:
Pascal Lamblin
提交者:
GitHub
4月 21, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5877 from lamblin/fix_5875
Remove goto in OpenMP Elemwise fail code
上级
93c3e777
25297b8d
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
48 行增加
和
26 行删除
+48
-26
cc.py
theano/gof/cc.py
+17
-3
basic.py
theano/scalar/basic.py
+24
-22
elemwise.py
theano/tensor/elemwise.py
+7
-1
没有找到文件。
theano/gof/cc.py
浏览文件 @
ac04eccd
...
@@ -94,22 +94,36 @@ class CodeBlock:
...
@@ -94,22 +94,36 @@ class CodeBlock:
"
\n
double __DUMMY_
%(id)
i;
\n
"
%
sub
)
# % sub
"
\n
double __DUMMY_
%(id)
i;
\n
"
%
sub
)
# % sub
def
failure_code
(
sub
):
def
failure_code
(
sub
,
use_goto
=
True
):
"""
"""
Code contained in sub['fail'], usually substituted for
%(fail)
s.
Code contained in sub['fail'], usually substituted for
%(fail)
s.
It sets information about current error, then goto the code
It sets information about current error, then goto the code
actually handling the failure, which is defined in struct_gen().
actually handling the failure, which is defined in struct_gen().
Parameters
----------
sub: dict
Contains other code snippets that can be substituted,
in particular 'failure_var' and 'id'.
use_goto: bool, True by default
Include a "goto" statement to the failure label.
Passing False is sometimes required, in which cases we have to
be careful to avoid executing incorrect code.
"""
"""
if
use_goto
:
goto_statement
=
'goto __label_
%(id)
i;'
%
sub
else
:
goto_statement
=
''
return
'''{
return
'''{
%(failure_var)
s =
%(id)
s
;
%(failure_var)
s =
%(id)
i
;
if (!PyErr_Occurred()) {
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_RuntimeError,
PyErr_SetString(PyExc_RuntimeError,
"Unexpected error in an Op's C code. "
"Unexpected error in an Op's C code. "
"No Python exception was set.");
"No Python exception was set.");
}
}
goto __label_
%(id)
i;}'''
%
sub
%(goto_statement)
s}'''
%
dict
(
sub
,
goto_statement
=
goto_statement
)
def
failure_code_init
(
sub
):
def
failure_code_init
(
sub
):
...
...
theano/scalar/basic.py
浏览文件 @
ac04eccd
...
@@ -1928,22 +1928,24 @@ class IntDiv(BinaryScalarOp):
...
@@ -1928,22 +1928,24 @@ class IntDiv(BinaryScalarOp):
t
=
node
.
inputs
[
0
]
.
type
.
upcast
(
*
[
i
.
type
for
i
in
node
.
inputs
[
1
:]])
t
=
node
.
inputs
[
0
]
.
type
.
upcast
(
*
[
i
.
type
for
i
in
node
.
inputs
[
1
:]])
if
t
in
imap
(
str
,
discrete_types
):
if
t
in
imap
(
str
,
discrete_types
):
x_div_y_pp
=
'(
%(x)
s /
%(y)
s)'
%
locals
()
x_div_y_mp
=
'((-
%(x)
s) /
%(y)
s)'
%
locals
()
x_mod_y_mp
=
'THEANO_MACRO_MOD((-
%(x)
s),
%(y)
s)'
%
locals
()
x_div_y_pm
=
'(
%(x)
s / (-
%(y)
s))'
%
locals
()
x_mod_y_pm
=
'THEANO_MACRO_MOD(
%(x)
s, (-
%(y)
s))'
%
locals
()
x_div_y_mm
=
'((-
%(x)
s) / (-
%(y)
s))'
%
locals
()
# If we are in a gpuarray kernel, %(fail)s exits the kernel,
# If we are in a gpuarray kernel, %(fail)s exits the kernel,
# and we do not have any error report, and we cannot set
# and we do not have any error report, and we cannot set
# Python error messages either, so for now we just call the
# Python error messages either, so for now we just call the
# cuda function, which return a binary pattern of all 1s.
# cuda function, which return a binary pattern of all 1s.
check
=
dedent
(
'''
div_zero
=
dedent
(
'''
#ifndef KERNEL
#ifdef KERNEL
%(z)
s =
%(x_div_y_pp)
s;
#else
PyErr_SetString(PyExc_ZeroDivisionError, "integer division by zero");
PyErr_SetString(PyExc_ZeroDivisionError, "integer division by zero");
%(fail)
s
%(fail)
s
#endif
#endif
'''
)
%
locals
()
'''
)
%
locals
()
x_div_y_pp
=
'(
%(x)
s /
%(y)
s)'
%
locals
()
x_div_y_mp
=
'((-
%(x)
s) /
%(y)
s)'
%
locals
()
x_mod_y_mp
=
'THEANO_MACRO_MOD((-
%(x)
s),
%(y)
s)'
%
locals
()
x_div_y_pm
=
'(
%(x)
s / (-
%(y)
s))'
%
locals
()
x_mod_y_pm
=
'THEANO_MACRO_MOD(
%(x)
s, (-
%(y)
s))'
%
locals
()
x_div_y_mm
=
'((-
%(x)
s) / (-
%(y)
s))'
%
locals
()
elif
t
in
imap
(
str
,
float_types
):
elif
t
in
imap
(
str
,
float_types
):
# We need to call different functions of math.h
# We need to call different functions of math.h
# depending on the type
# depending on the type
...
@@ -1956,13 +1958,13 @@ class IntDiv(BinaryScalarOp):
...
@@ -1956,13 +1958,13 @@ class IntDiv(BinaryScalarOp):
else
:
else
:
raise
NotImplementedError
(
'type not supported'
,
t
)
raise
NotImplementedError
(
'type not supported'
,
t
)
check
=
''
x_div_y_pp
=
'
%(floor)
s(
%(x)
s /
%(y)
s)'
%
locals
()
x_div_y_pp
=
'
%(floor)
s(
%(x)
s /
%(y)
s)'
%
locals
()
x_div_y_mp
=
'
%(floor)
s((-
%(x)
s) /
%(y)
s)'
%
locals
()
x_div_y_mp
=
'
%(floor)
s((-
%(x)
s) /
%(y)
s)'
%
locals
()
x_mod_y_mp
=
'
%(fmod)
s((-
%(x)
s),
%(y)
s)'
%
locals
()
x_mod_y_mp
=
'
%(fmod)
s((-
%(x)
s),
%(y)
s)'
%
locals
()
x_div_y_pm
=
'
%(floor)
s(
%(x)
s / (-
%(y)
s))'
%
locals
()
x_div_y_pm
=
'
%(floor)
s(
%(x)
s / (-
%(y)
s))'
%
locals
()
x_mod_y_pm
=
'
%(fmod)
s(
%(x)
s, (-
%(y)
s))'
%
locals
()
x_mod_y_pm
=
'
%(fmod)
s(
%(x)
s, (-
%(y)
s))'
%
locals
()
x_div_y_mm
=
'
%(floor)
s((-
%(x)
s) / (-
%(y)
s))'
%
locals
()
x_div_y_mm
=
'
%(floor)
s((-
%(x)
s) / (-
%(y)
s))'
%
locals
()
div_zero
=
'
%(z)
s =
%(x_div_y_pp)
s;'
%
locals
()
elif
t
in
complex_types
:
elif
t
in
complex_types
:
raise
self
.
complex_error
raise
self
.
complex_error
else
:
else
:
...
@@ -1970,8 +1972,7 @@ class IntDiv(BinaryScalarOp):
...
@@ -1970,8 +1972,7 @@ class IntDiv(BinaryScalarOp):
return
dedent
(
"""
return
dedent
(
"""
if (
%(y)
s == 0) {
if (
%(y)
s == 0) {
%(check)
s
%(div_zero)
s;
%(z)
s =
%(x_div_y_pp)
s;
} else if (
%(y)
s < 0) {
} else if (
%(y)
s < 0) {
if (
%(x)
s < 0) {
if (
%(x)
s < 0) {
%(z)
s =
%(x_div_y_mm)
s;
%(z)
s =
%(x_div_y_mm)
s;
...
@@ -1988,7 +1989,7 @@ class IntDiv(BinaryScalarOp):
...
@@ -1988,7 +1989,7 @@ class IntDiv(BinaryScalarOp):
"""
)
%
locals
()
"""
)
%
locals
()
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
5
,)
return
(
6
,)
def
grad
(
self
,
inputs
,
g_output
):
def
grad
(
self
,
inputs
,
g_output
):
return
[
inp
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)
return
[
inp
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)
...
@@ -2020,7 +2021,7 @@ class Mod(BinaryScalarOp):
...
@@ -2020,7 +2021,7 @@ class Mod(BinaryScalarOp):
return
x
%
y
return
x
%
y
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
8
,)
return
(
9
,)
def
c_support_code
(
self
):
def
c_support_code
(
self
):
# We use a macro as python use % as a special string character,
# We use a macro as python use % as a special string character,
...
@@ -2046,20 +2047,22 @@ class Mod(BinaryScalarOp):
...
@@ -2046,20 +2047,22 @@ class Mod(BinaryScalarOp):
# keep them out of safety, and verify they are useless with an
# keep them out of safety, and verify they are useless with an
# assert.
# assert.
assert
str
(
t
)
in
imap
(
str
,
discrete_types
)
assert
str
(
t
)
in
imap
(
str
,
discrete_types
)
x_mod_y
=
"THEANO_MACRO_MOD(
%(x)
s,
%(y)
s)"
%
locals
()
x_mod_ymm
=
"THEANO_MACRO_MOD(-
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ypm
=
"THEANO_MACRO_MOD(
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ymp
=
"THEANO_MACRO_MOD(-
%(x)
s,
%(y)
s)"
%
locals
()
# If we are in a gpuarray kernel, %(fail)s exits the kernel,
# If we are in a gpuarray kernel, %(fail)s exits the kernel,
# and we do not have any error report, and we cannot set
# and we do not have any error report, and we cannot set
# Python error messages either, so for now we just call the
# Python error messages either, so for now we just call the
# cuda function, returning a binary pattern depending on dtype
# cuda function, returning a binary pattern depending on dtype
check
=
dedent
(
'''
mod_zero
=
dedent
(
'''
#ifndef KERNEL
#ifdef KERNEL
%(z)
s =
%(x_mod_y)
s;
#else
PyErr_SetString(PyExc_ZeroDivisionError, "integer modulo by zero");
PyErr_SetString(PyExc_ZeroDivisionError, "integer modulo by zero");
%(fail)
s
%(fail)
s
#endif
#endif
'''
)
%
locals
()
'''
)
%
locals
()
x_mod_y
=
"THEANO_MACRO_MOD(
%(x)
s,
%(y)
s)"
%
locals
()
x_mod_ymm
=
"THEANO_MACRO_MOD(-
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ypm
=
"THEANO_MACRO_MOD(
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ymp
=
"THEANO_MACRO_MOD(-
%(x)
s,
%(y)
s)"
%
locals
()
elif
(
str
(
t
)
in
imap
(
str
,
float_types
)
or
elif
(
str
(
t
)
in
imap
(
str
,
float_types
)
or
t
in
[
'float32'
,
'float64'
]
or
t
in
[
'float32'
,
'float64'
]
or
t
in
float_types
):
t
in
float_types
):
...
@@ -2067,11 +2070,11 @@ class Mod(BinaryScalarOp):
...
@@ -2067,11 +2070,11 @@ class Mod(BinaryScalarOp):
# keep them out of safety, and verify they are useless with an
# keep them out of safety, and verify they are useless with an
# assert.
# assert.
assert
str
(
t
)
in
imap
(
str
,
float_types
)
assert
str
(
t
)
in
imap
(
str
,
float_types
)
check
=
''
x_mod_y
=
"fmod(
%(x)
s,
%(y)
s)"
%
locals
()
x_mod_y
=
"fmod(
%(x)
s,
%(y)
s)"
%
locals
()
x_mod_ymm
=
"fmod(-
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ymm
=
"fmod(-
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ypm
=
"fmod(
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ypm
=
"fmod(
%(x)
s, -
%(y)
s)"
%
locals
()
x_mod_ymp
=
"fmod(-
%(x)
s,
%(y)
s)"
%
locals
()
x_mod_ymp
=
"fmod(-
%(x)
s,
%(y)
s)"
%
locals
()
mod_zero
=
"
%(z)
s =
%(x_mod_y)
s;"
%
locals
()
elif
str
(
t
)
in
imap
(
str
,
complex_types
):
elif
str
(
t
)
in
imap
(
str
,
complex_types
):
raise
self
.
complex_error
raise
self
.
complex_error
else
:
else
:
...
@@ -2079,8 +2082,7 @@ class Mod(BinaryScalarOp):
...
@@ -2079,8 +2082,7 @@ class Mod(BinaryScalarOp):
return
dedent
(
"""
return
dedent
(
"""
if (
%(y)
s == 0) {
if (
%(y)
s == 0) {
%(check)
s
%(mod_zero)
s;
%(z)
s =
%(x_mod_y)
s;
} else if (
%(y)
s < 0){
} else if (
%(y)
s < 0){
if (
%(x)
s < 0){
if (
%(x)
s < 0){
%(z)
s = -(
%(x_mod_ymm)
s);
%(z)
s = -(
%(x_mod_ymm)
s);
...
...
theano/tensor/elemwise.py
浏览文件 @
ac04eccd
...
@@ -1037,12 +1037,18 @@ second dimension
...
@@ -1037,12 +1037,18 @@ second dimension
# the index of the last of these aliased outputs.
# the index of the last of these aliased outputs.
# We generate the C code of the inner loop using the scalar op
# We generate the C code of the inner loop using the scalar op
if
self
.
openmp
:
# If we are using openmp, we need to get rid of the "goto"
# statement in sub['fail']. For now we recreate it here.
fail
=
gof
.
cc
.
failure_code
(
sub
,
use_goto
=
False
)
else
:
fail
=
sub
[
'fail'
]
task_code
=
self
.
scalar_op
.
c_code
(
task_code
=
self
.
scalar_op
.
c_code
(
node
.
tag
.
fake_node
,
node
.
tag
.
fake_node
,
nodename
+
'_scalar_'
,
nodename
+
'_scalar_'
,
[
"
%
s_i"
%
s
for
s
in
_inames
],
[
"
%
s_i"
%
s
for
s
in
_inames
],
[
"
%
s_i"
%
s
for
s
in
onames
],
[
"
%
s_i"
%
s
for
s
in
onames
],
sub
)
dict
(
sub
,
fail
=
fail
)
)
code
=
"""
code
=
"""
{
{
%(defines)
s
%(defines)
s
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论