Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
6af6f546
提交
6af6f546
authored
10月 22, 2014
作者:
Pierre Luc Carrier
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Replaced ifndef-define structure with section markers in C code.
上级
b1247c12
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
97 行增加
和
26 行删除
+97
-26
extending_theano_c.txt
doc/tutorial/extending_theano_c.txt
+27
-20
op.py
theano/gof/op.py
+70
-6
没有找到文件。
doc/tutorial/extending_theano_c.txt
浏览文件 @
6af6f546
...
@@ -740,16 +740,18 @@ C file named vectorTimesVector.c :
...
@@ -740,16 +740,18 @@ C file named vectorTimesVector.c :
.. code-block:: c
.. code-block:: c
// Support code
THEANO_SUPPORT_CODE_SECTION
#ifndef VECTOR_TIMES_VECTOR_SUPPORT_CODE
#define VECTOR_TIMES_VECTOR_SUPPORT_CODE
// Support code function
bool vector_same_shape(PyArrayObject* arr1, PyArrayObject* arr2)
bool vector_same_shape(PyArrayObject* arr1, PyArrayObject* arr2)
{
{
return (PyArray_DIMS(arr1)[0] == PyArray_DIMS(arr2)[0]);
return (PyArray_DIMS(arr1)[0] == PyArray_DIMS(arr2)[0]);
}
}
#endif
// Apply-specific support code
THEANO_APPLY_CODE_SECTION
// Apply-specific support function
void APPLY_SPECIFIC(vector_elemwise_mult)(
void APPLY_SPECIFIC(vector_elemwise_mult)(
DTYPE_INPUT_0* x_ptr, int x_str,
DTYPE_INPUT_0* x_ptr, int x_str,
DTYPE_INPUT_1* y_ptr, int y_str,
DTYPE_INPUT_1* y_ptr, int y_str,
...
@@ -760,7 +762,7 @@ C file named vectorTimesVector.c :
...
@@ -760,7 +762,7 @@ C file named vectorTimesVector.c :
}
}
}
}
//
M
ain function
//
Apply-specific m
ain function
int APPLY_SPECIFIC(vector_times_vector)(PyArrayObject* input0,
int APPLY_SPECIFIC(vector_times_vector)(PyArrayObject* input0,
PyArrayObject* input1,
PyArrayObject* input1,
PyArrayObject** output0)
PyArrayObject** output0)
...
@@ -918,26 +920,31 @@ wasn't apply-specific was simply defined in the ``c_support_code()`` method.
...
@@ -918,26 +920,31 @@ wasn't apply-specific was simply defined in the ``c_support_code()`` method.
When using the ``COp`` class, we still have to make the distinction between
When using the ``COp`` class, we still have to make the distinction between
apply-specific and apply-agnostic support code but we express it differently
apply-specific and apply-agnostic support code but we express it differently
in the code since it is all defined in the same external C file.
in the code since it is all defined in the same external C file.
Apply-agnostic code should now be defined inside a ``ifndef``-``define``
These two types of support code should each be defined in their own section of
structure (like the function ``vector_same_shape()`` in the example above) to
the file, like in the example above. These sections should be delimited by the
ensure that it is only defined once. On the other hand, apply-specific
markers ``THEANO_SUPPORT_CODE_SECTION`` (to be put on its own line, at the
functions and global variables only need to include the name of the
beginning of the apply-agnostic support code section) and
:ref:`Apply` node in their names. To achieve this, the macro
``THEANO_APPLY_CODE_SECTION`` (to be put on its own line at the beginning of
``APPLY_SPECIFIC(str)`` should be used when defining those elements as well as
the apply-specific code section). Moreover, just like in the previous examples
when referring to them. In the above example, this macro is used when defining
of this tutorial, apply-specific functions and global variables need to
the functions ``vector_elemwise_mult()`` and ``vector_times_vector()`` as well
include the name of the :ref:`Apply` node in their names. To achieve this,
as when calling function ``vector_elemwise_mult()`` from inside
the macro ``APPLY_SPECIFIC(str)`` should be used when defining those elements
``vector_times_vector()``.
as well as when referring to them. In the above example, this macro is used
when defining the functions ``vector_elemwise_mult()`` and
``vector_times_vector()`` as well as when calling function
``vector_elemwise_mult()`` from inside ``vector_times_vector()``.
:note:
:note:
The macro ``APPLY_SPECIFIC(str)`` should only ever be used for
The macro ``APPLY_SPECIFIC(str)`` should only ever be used for
apply-specific code. It should not be used for apply-agnostic code.
apply-specific code. It should not be used for apply-agnostic code.
The rules for knowing if a piece of code should be treated as apply-specific
The rules for knowing if a piece of code should be put in the apply-agnostic
or not are simple; if it uses any of the macros defined by the class ``COp``
or the apply-specific support code section of the file are simple. If it uses
then it is apply-specific, if it calls any apply-specific code then it is
any of the macros defined by the class ``COp`` then it is apply-specific and
apply-specific. Otherwise, it is apply-agnostic.
goes in the corresponding section. If it calls any apply-specific code then
it is apply-specific. Otherwise, it is apply-agnostic and goes in the
apply-agnostic support code section.
In the above example, the ``function vector_same_shape()`` is apply-agnostic
In the above example, the ``function vector_same_shape()`` is apply-agnostic
because it uses none of the macros defined by the class ``COp`` and it doesn't
because it uses none of the macros defined by the class ``COp`` and it doesn't
...
...
theano/gof/op.py
浏览文件 @
6af6f546
...
@@ -992,21 +992,85 @@ class COp(Op):
...
@@ -992,21 +992,85 @@ class COp(Op):
self
.
func_file
=
func_file
self
.
func_file
=
func_file
self
.
func_name
=
func_name
self
.
func_name
=
func_name
# Load the func
# Define the markers that can be used to delimit sections in the
# external C code
self
.
support_code_marker
=
"THEANO_SUPPORT_CODE_SECTION"
self
.
apply_code_marker
=
"THEANO_APPLY_CODE_SECTION"
self
.
c_code_markers
=
[
self
.
support_code_marker
,
self
.
apply_code_marker
]
# Load the external C code
f
=
open
(
self
.
func_file
,
"r"
)
f
=
open
(
self
.
func_file
,
"r"
)
self
.
func_code
=
f
.
read
()
self
.
func_code
=
f
.
read
()
f
.
close
()
f
.
close
()
# Separate the contents of the file in sections and validate that at
# lest one of the necessary code sections has been defined
self
.
code_sections
=
self
.
parse_external_c_code
(
self
.
func_code
)
if
sum
([
marker
in
self
.
code_sections
.
keys
()
for
marker
in
self
.
c_code_markers
])
==
0
:
raise
(
RuntimeError
,
"The provided C implementation does not "
"define a support code section or a support code apply "
"section."
)
def
parse_external_c_code
(
self
,
code
):
# Obtain the positions of the C code markers used in the C code
positions
=
[(
code
.
index
(
marker
),
marker
)
for
marker
in
self
.
c_code_markers
if
marker
in
code
]
# Go over the markers in their order of occurence and extract
# the C code they concern
positions
.
sort
()
code_sections
=
{}
for
i
in
range
(
len
(
positions
)):
marker_start
,
marker
=
positions
[
i
]
if
i
<
len
(
positions
)
-
1
:
# This is not the last section in the code : extract the code
# between the beginning of the current marker and the
# beginning of the next one.
next_marker_start
=
positions
[
i
+
1
][
0
]
section
=
code
[
marker_start
:
next_marker_start
]
else
:
# This is the last section in the code : extract the remaining
# C code
section
=
code
[
marker_start
:]
cleaned_section
=
section
.
replace
(
marker
,
""
)
code_sections
[
marker
]
=
cleaned_section
return
code_sections
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
hash
(
self
.
func_code
)
return
hash
(
self
.
func_code
)
def
c_support_code
(
self
):
if
self
.
support_code_marker
in
self
.
code_sections
:
return
self
.
code_sections
[
self
.
support_code_marker
]
else
:
return
""
def
c_support_code_apply
(
self
,
node
,
name
):
def
c_support_code_apply
(
self
,
node
,
name
):
if
hasattr
(
self
,
'check_inputs'
)
and
self
.
check_inputs
==
False
:
return
self
.
func_code
if
self
.
apply_code_marker
in
self
.
code_sections
:
apply_code
=
self
.
code_sections
[
self
.
apply_code_marker
]
if
hasattr
(
self
,
'check_inputs'
)
and
self
.
check_inputs
==
False
:
return
apply_code
else
:
define_macros
,
undef_macros
=
self
.
get_c_macros
(
node
,
name
)
return
os
.
linesep
.
join
([
define_macros
,
apply_code
,
undef_macros
])
else
:
else
:
define_macros
,
undef_macros
=
self
.
get_c_macros
(
node
,
name
)
return
""
return
os
.
linesep
.
join
([
define_macros
,
self
.
func_code
,
undef_macros
])
def
format_c_function_args
(
self
,
inp
,
out
):
def
format_c_function_args
(
self
,
inp
,
out
):
# Generate an string containing the arguments sent to the external C
# Generate an string containing the arguments sent to the external C
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论