Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
fe6e6a1c
提交
fe6e6a1c
authored
3月 06, 2009
作者:
James Bergstra
浏览文件
操作
浏览文件
下载
差异文件
merge
上级
5a3a683b
379917a9
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
173 行增加
和
3 行删除
+173
-3
compilation.txt
doc/advanced/compilation.txt
+12
-0
links.txt
doc/links.txt
+2
-0
cop.txt
doc/tutorials/advanced/ex1/cop.txt
+157
-0
ctype.txt
doc/tutorials/advanced/ex1/ctype.txt
+0
-0
op.txt
doc/tutorials/advanced/ex1/op.txt
+1
-3
basic.py
theano/tensor/basic.py
+1
-0
没有找到文件。
doc/advanced/compilation.txt
浏览文件 @
fe6e6a1c
...
@@ -4,3 +4,15 @@
...
@@ -4,3 +4,15 @@
=======================
=======================
Compilation and Linking
Compilation and Linking
=======================
=======================
.. index::
single: Linker
.. _linker:
Linker
======
WRITEME
doc/links.txt
浏览文件 @
fe6e6a1c
...
@@ -31,6 +31,7 @@ This is a sort of memo for developers and would-be developers.
...
@@ -31,6 +31,7 @@ This is a sort of memo for developers and would-be developers.
- networkx_: A package to create and manipulate graph structures.
- networkx_: A package to create and manipulate graph structures.
- pycppad_: Python bindings to an AD package in C++.
- pycppad_: Python bindings to an AD package in C++.
- pypy_: Optimizing compiler for Python in Python.
- pypy_: Optimizing compiler for Python in Python.
- shedskin_: An experimental (restricted-)Python-to-C++ compiler.
- swig_: An interoperability layer between Python and C/C++
- swig_: An interoperability layer between Python and C/C++
- unpython_: Python to C compiler.
- unpython_: Python to C compiler.
...
@@ -52,4 +53,5 @@ This is a sort of memo for developers and would-be developers.
...
@@ -52,4 +53,5 @@ This is a sort of memo for developers and would-be developers.
.. _swig: http://www.swig.org/
.. _swig: http://www.swig.org/
.. _unpython: http://code.google.com/p/unpython/
.. _unpython: http://code.google.com/p/unpython/
.. _pycppad: http://www.seanet.com/~bradbell/pycppad/index.xml
.. _pycppad: http://www.seanet.com/~bradbell/pycppad/index.xml
.. _shedskin: http://shed-skin.blogspot.com/
doc/tutorials/advanced/ex1/cop.txt
浏览文件 @
fe6e6a1c
...
@@ -3,6 +3,163 @@
...
@@ -3,6 +3,163 @@
Implementing the arithmetic Ops in C
Implementing the arithmetic Ops in C
====================================
====================================
Now that we have set up our ``double`` type properly to allow C
implementations for operations that work on it, all we have to do now
is to actually define these operations in C.
How does it work?
=================
Before a C :ref:`op` is executed, the variables related to each of its
inputs will be declared and will be filled appropriately, either from
an input provided by the end user (using c_extract) or it might simply
have been calculated by another operation. For each of the outputs,
the variables associated to them will be declared and initialized.
The operation then simply has to compute what it needs to using the
input variables and place the results in the output variables.
What needs to be defined
========================
There are less methods to define for an Op than for a Type:
- **c_code(node, name, input_names, output_names, sub)**
- This must return C code that carries the computation we want to
do.
- **c_code_cleanup(node, name, input_names, output_names, sub)**
- This must return C code that cleans up whatever c_code allocated
and that we must free.
- *Default* The default behavior is to do nothing.
- **c_compile_args(), c_headers(), c_libraries(), c_support_code()**
- Allows you to specify headers, libraries, special g++ arguments or
helper functions/structs that the type needs. See :ref:`op`.
The ``name`` argument is currently given an invalid value, so steer
away from it. As was the case with Type, ``sub['fail']`` provides
failure code that you *must* use if you want to raise an exception,
after setting the exception message.
The ``node`` argument is an :ref:`apply` node representing an
application of the current Op on a list of inputs, producing a list of
outputs. ``input_names`` and ``output_names`` arguments contain as
many strings as there are inputs and outputs to the application of the
Op and they correspond to the ``name`` that is passed to the type of
each Result in these lists. For example, if ``node.inputs[0].type ==
double``, then ``input_names[0]`` is the ``name`` argument passed to
``double.c_declare`` etc. when the first input is processed by Theano.
In a nutshell, ``input_names`` and ``output_names`` parameterize the
names of the inputs your operation needs to use and the outputs it
needs to put results into. But this will be clear with the examples.
Defining the methods
====================
We will be defining C code for the multiplication Op on doubles.
**c_code**
.. code-block:: python
def c_code(node, name, input_names, output_names, sub):
x_name, y_name = input_names[0], input_names[1]
output_name = output_names[0]
return """
%(output_name)s = %(x_name)s * %(y_name)s;
""" % locals()
mul.c_code = c_code
And that's it. As we enter the scope of the C code we are defining in
the method above, many variables are defined for us. Namely, the
variables x_name, y_name and output_name are all of the primitive C
``double`` type and they were declared using the C code returned by
``double.c_declare``.
Implementing multiplication is as simple as multiplying the two input
doubles and setting the output double to what comes out of it. If you
had more than one output, you would simply set the variable(s) for
each output to what they should be.
.. warning::
Do *NOT* use C's ``return`` statement to return the result(s) of
the computations. Set the output variables directly as shown
above. Theano will pick them up for you.
**c_code_cleanup**
There is nothing to cleanup after multiplying two doubles. Typically,
you won't need to define this method unless you malloc() some
temporary storage (which you would free() here) or create temporary
Python objects (which you would Py_XDECREF() here).
Final version
=============
As before, I tried to organize the code in order to minimize
repetition. You can check that mul produces the same C code in this
version that it produces in the code I gave above.
.. code-block:: python
from theano import gof
class BinaryDoubleOp(gof.Op):
def __init__(self, name, fn, ccode):
self.name = name
self.fn = fn
self.ccode = ccode
def make_node(self, x, y):
if isinstance(x, (int, float)):
x = gof.Constant(double, x)
if isinstance(y, (int, float)):
y = gof.Constant(double, y)
if x.type != double or y.type != double:
raise TypeError('%s only works on doubles' % self.name)
return gof.Apply(self, [x, y], [double()])
def perform(self, node, (x, y), (z, )):
z[0] = self.fn(x, y)
def __str__(self):
return self.name
def c_code(self, node, name, (x, y), (z, ), sub):
return self.ccode % locals()
add = BinaryDoubleOp(name = 'add',
fn = lambda x, y: x + y,
ccode = "%(z)s = %(x)s + %(y)s;")
sub = BinaryDoubleOp(name = 'sub',
fn = lambda x, y: x - y,
ccode = "%(z)s = %(x)s - %(y)s;")
mul = BinaryDoubleOp(name = 'mul',
fn = lambda x, y: x * y,
ccode = "%(z)s = %(x)s * %(y)s;")
div = BinaryDoubleOp(name = 'div',
fn = lambda x, y: x / y,
ccode = "%(z)s = %(x)s / %(y)s;")
**Next:** `Example 2 - cons_cell`_
**Next:** `Example 2 - cons_cell`_
...
...
doc/tutorials/advanced/ex1/ctype.txt
浏览文件 @
fe6e6a1c
差异被折叠。
点击展开。
doc/tutorials/advanced/ex1/op.txt
浏览文件 @
fe6e6a1c
...
@@ -245,11 +245,9 @@ operators (well, pending revision of this tutorial, I guess):
...
@@ -245,11 +245,9 @@ operators (well, pending revision of this tutorial, I guess):
class BinaryDoubleOp(gof.Op):
class BinaryDoubleOp(gof.Op):
def __init__(self, name, fn
, gradfnx, gradfny
):
def __init__(self, name, fn):
self.name = name
self.name = name
self.fn = fn
self.fn = fn
self.gradfnx = gradfnx
self.gradfny = gradfny
def make_node(self, x, y):
def make_node(self, x, y):
if isinstance(x, (int, float)):
if isinstance(x, (int, float)):
...
...
theano/tensor/basic.py
浏览文件 @
fe6e6a1c
...
@@ -328,6 +328,7 @@ class Tensor(Type):
...
@@ -328,6 +328,7 @@ class Tensor(Type):
return
"""
return
"""
Py_XDECREF(py_
%(name)
s);
Py_XDECREF(py_
%(name)
s);
if (!
%(name)
s) {
if (!
%(name)
s) {
Py_XINCREF(Py_None);
py_
%(name)
s = Py_None;
py_
%(name)
s = Py_None;
}
}
else if ((void*)py_
%(name)
s != (void*)
%(name)
s) {
else if ((void*)py_
%(name)
s != (void*)
%(name)
s) {
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论