Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
cc3b43d9
提交
cc3b43d9
authored
9月 23, 2008
作者:
bergstrj@lgcm
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
added docs, gen_op_list
上级
a8242ddf
隐藏空白字符变更
内嵌
并排
正在显示
2 个修改的文件
包含
110 行增加
和
33 行删除
+110
-33
gen_op_list.py
gen_op_list.py
+20
-0
tensor.py
tensor.py
+90
-33
没有找到文件。
gen_op_list.py
0 → 100644
浏览文件 @
cc3b43d9
import
gof
import
tensor
def
isOp
(
thing
):
return
hasattr
(
thing
,
'perform'
)
for
module
in
[
tensor
]:
title
=
'Ops in module: `
%
s`'
%
module
.
__name__
print
title
print
'-'
*
len
(
title
)
for
symbol_name
in
dir
(
module
):
symbol
=
getattr
(
module
,
symbol_name
)
if
isOp
(
symbol
):
print
""
print
"- `
%
s.
%
s`"
%
(
module
.
__name__
,
symbol_name
)
tensor.py
浏览文件 @
cc3b43d9
"""A L{Result} to store L{numpy.ndarray} with basic accompanying L{Op}s"""
"""A `Type` and `Op` classes to work with numpy.ndarrays symbolically."""
__docformat__
=
"restructuredtext en"
import
sys
# for sys.maxint
import
sys
# for sys.maxint
import
inspect
import
inspect
import
functools
import
functools
...
@@ -24,7 +27,27 @@ import tensor_random as random
...
@@ -24,7 +27,27 @@ import tensor_random as random
def
as_tensor
(
x
,
name
=
None
):
def
as_tensor
(
x
,
name
=
None
):
"""Return `x`, transformed into a `Tensor`
This function is often used by `make_node` methods of `Op` subclasses to
turn ndarrays, numbers, `Scalar` instances, `Apply` instances and `Tensor`
instances into valid input list elemnts.
:Parameters:
- `x`: Apply instance, Result instance, numpy.ndarray, or number
This thing will be transformed into a `Result` in a sensible way. An
ndarray argument will not be copied, but a list of numbers will be copied
to make an ndarray.
- `name`: str or None
If a new `Result` instance is created, it will be named with this string.
:Exceptions:
- `ValueError`: raised if an `Apply` with no default output is fetched
- `TypeError`: raised if `x` cannot be converted to a Tensor Result
"""
if
isinstance
(
x
,
gof
.
Apply
):
if
isinstance
(
x
,
gof
.
Apply
):
#TODO: use Apply's default output mechanism
if
len
(
x
.
outputs
)
!=
1
:
if
len
(
x
.
outputs
)
!=
1
:
raise
ValueError
(
"It is ambiguous which output of a multi-output Op has to be fetched."
,
x
)
raise
ValueError
(
"It is ambiguous which output of a multi-output Op has to be fetched."
,
x
)
else
:
else
:
...
@@ -39,56 +62,74 @@ def as_tensor(x, name = None):
...
@@ -39,56 +62,74 @@ def as_tensor(x, name = None):
return
constant
(
x
)
return
constant
(
x
)
except
TypeError
:
except
TypeError
:
raise
TypeError
(
"Cannot convert
%
s to Tensor"
%
x
,
type
(
x
))
raise
TypeError
(
"Cannot convert
%
s to Tensor"
%
x
,
type
(
x
))
# this has a different name, because _as_tensor is the function which ops use
# this has a different name, because _as_tensor is the function which ops use
# to upcast their arguments... this internal-use function is a good place to put debugging stuff, better than the global astensor.
# to upcast their arguments... this internal-use function is a good place to put debugging stuff, better than the global astensor.
_as_tensor
=
as_tensor
_as_tensor
=
as_tensor
def
constant
(
_x
):
def
constant
(
x
):
if
not
isinstance
(
_x
,
numpy
.
ndarray
):
"""Return a symbolic `Constant` with value `x`
x
=
numpy
.
asarray
(
_x
)
:Exceptions:
- `TypeError`: `x` could not be converted to a numpy.ndarray
"""
if
isinstance
(
x
,
numpy
.
ndarray
):
x_
=
x
else
:
else
:
x
=
_x
x
_
=
numpy
.
asarray
(
x
)
try
:
try
:
return
TensorConstant
(
Tensor
(
dtype
=
x
.
dtype
,
return
TensorConstant
(
Tensor
(
dtype
=
x
_
.
dtype
,
broadcastable
=
[
d
==
1
for
d
in
x
.
shape
]),
x
)
broadcastable
=
[
d
==
1
for
d
in
x
_
.
shape
]),
x_
)
except
:
except
:
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
_x
,
type
(
_
x
))
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
x
,
type
(
x
))
def
value
(
x
):
def
value
(
x
):
if
not
isinstance
(
x
,
numpy
.
ndarray
):
"""Return a symbolic `Value` with default value `x`
x
=
numpy
.
asarray
(
x
)
:Exceptions:
- `TypeError`: `x` could not be converted to a numpy.ndarray
"""
if
isinstance
(
x
,
numpy
.
ndarray
):
x_
=
x
else
:
x_
=
numpy
.
asarray
(
x
)
try
:
try
:
return
TensorValue
(
Tensor
(
dtype
=
x
.
dtype
,
return
TensorValue
(
Tensor
(
dtype
=
x
_
.
dtype
,
broadcastable
=
[
d
==
1
for
d
in
x
.
shape
]),
x
)
broadcastable
=
[
d
==
1
for
d
in
x
_
.
shape
]),
x_
)
except
:
except
:
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
_x
,
type
(
_
x
))
raise
TypeError
(
"Could not convert
%
s to Tensor"
%
x
,
type
(
x
))
class
Tensor
(
Type
):
class
Tensor
(
Type
):
"""
"""Symbolic `Type` representing a numpy.ndarray value."""
L{Type} representing L{numpy.ndarray} in Theano.
@todo: At some point we should document a glossary, such as terms like
broadcasting and shape.
@type dtype: numpy dtype string such as 'int64' or 'float64' (among others)
@type broadcastable: tuple or list or array of boolean values, whose length
is the number of dimensions of the L{ndarray} represented by this Type.
@ivar broadcastable: Each element of the broadcastable vector tells us
something about the corresponding dimension:
- False means the dimension can be anything.
- True means the dimension must be 1. Also, this dimension will be considered
for L{broadcasting}, as described and implemented in Numpy.
"""
def
__init__
(
self
,
dtype
,
broadcastable
):
def
__init__
(
self
,
dtype
,
broadcastable
):
"""Initialize self.dtype and self.broadcastable.
:Parameters:
- `dtype`: str corresponding to numpy dtype (e.g., 'int64')
The value (ndarray) associated to a `Result` of this `Type` will have
this dtype.
- `broadcastable`: tuple, list, or array of boolean values
This argument serves two purposes. First, the True elements of this
list indicate the dimensions where the shape of an associated value
must be 1. Secondly, the length of this list is the number of
dimensions that an associated value must have. See
:doc:`broadcasting` for an explanation of how this list is used.
"""
self
.
dtype
=
str
(
dtype
)
self
.
dtype
=
str
(
dtype
)
self
.
broadcastable
=
tuple
(
broadcastable
)
self
.
broadcastable
=
tuple
(
broadcastable
)
self
.
dtype_specs
()
# error checking is done there
self
.
dtype_specs
()
# error checking is done there
def
filter
(
self
,
data
,
strict
=
False
):
def
filter
(
self
,
data
,
strict
=
False
):
"""Convert `data` to something which can be associated to a `TensorResult`.
This function is not meant to be called in user code. It is for
`Linker` instances to use when running a compiled graph.
"""
_data
=
data
_data
=
data
if
strict
:
if
strict
:
if
not
isinstance
(
data
,
numpy
.
ndarray
):
if
not
isinstance
(
data
,
numpy
.
ndarray
):
...
@@ -107,10 +148,10 @@ class Tensor(Type):
...
@@ -107,10 +148,10 @@ class Tensor(Type):
return
data
return
data
def
dtype_specs
(
self
):
def
dtype_specs
(
self
):
"""Return
python - C type correspondance tuple for self.data
"""Return
a tuple (python type, c type, numpy typenum) that corresponds to
self.dtype.
Return a tuple (python type, c type, numpy typenum) that corresponds to
L{self.dtype}. It is for use in
C code generation.
This function is used internally as part of
C code generation.
"""
"""
#TODO: add more type correspondances for e.g. int32, int64, float32,
#TODO: add more type correspondances for e.g. int32, int64, float32,
#complex64, etc.
#complex64, etc.
...
@@ -131,14 +172,23 @@ class Tensor(Type):
...
@@ -131,14 +172,23 @@ class Tensor(Type):
raise
TypeError
(
"Unsupported dtype for
%
s:
%
s"
%
(
self
.
__class__
.
__name__
,
self
.
dtype
))
raise
TypeError
(
"Unsupported dtype for
%
s:
%
s"
%
(
self
.
__class__
.
__name__
,
self
.
dtype
))
def
__eq__
(
self
,
other
):
def
__eq__
(
self
,
other
):
"""Compare True iff other is the same kind of Tensor"""
return
type
(
self
)
==
type
(
other
)
and
other
.
dtype
==
self
.
dtype
and
other
.
broadcastable
==
self
.
broadcastable
return
type
(
self
)
==
type
(
other
)
and
other
.
dtype
==
self
.
dtype
and
other
.
broadcastable
==
self
.
broadcastable
def
__hash__
(
self
):
def
__hash__
(
self
):
"""Hash equal for same kinds of Tensor"""
return
hash
(
self
.
dtype
)
^
hash
(
self
.
broadcastable
)
return
hash
(
self
.
dtype
)
^
hash
(
self
.
broadcastable
)
ndim
=
property
(
lambda
self
:
len
(
self
.
broadcastable
),
doc
=
"read-only access to the number of dimensions"
)
# this read-only property is the preferred way to get the number of
# dimensions
ndim
=
property
(
lambda
self
:
len
(
self
.
broadcastable
),
doc
=
"number of dimensions"
)
def
make_result
(
self
,
name
=
None
):
def
make_result
(
self
,
name
=
None
):
"""Return a `TensorResult` of this type
:Parameters:
- `name`: str
A pretty name to identify this `Result` when printing and debugging
"""
return
TensorResult
(
self
,
name
=
name
)
return
TensorResult
(
self
,
name
=
name
)
def
__str__
(
self
):
def
__str__
(
self
):
...
@@ -148,6 +198,7 @@ class Tensor(Type):
...
@@ -148,6 +198,7 @@ class Tensor(Type):
return
"Tensor{
%
s,
%
s}"
%
(
str
(
self
.
dtype
),
str
(
self
.
broadcastable
))
return
"Tensor{
%
s,
%
s}"
%
(
str
(
self
.
dtype
),
str
(
self
.
broadcastable
))
def
c_declare
(
self
,
name
,
sub
):
def
c_declare
(
self
,
name
,
sub
):
"""Override `CLinkerOp.c_declare` """
return
"""
return
"""
PyArrayObject*
%(name)
s;
PyArrayObject*
%(name)
s;
int type_num_
%(name)
s;
int type_num_
%(name)
s;
...
@@ -155,12 +206,14 @@ class Tensor(Type):
...
@@ -155,12 +206,14 @@ class Tensor(Type):
"""
%
dict
(
sub
,
name
=
name
,
dtype
=
self
.
dtype_specs
()[
1
])
"""
%
dict
(
sub
,
name
=
name
,
dtype
=
self
.
dtype_specs
()[
1
])
def
c_init
(
self
,
name
,
sub
):
def
c_init
(
self
,
name
,
sub
):
"""Override `CLinkerOp.c_init` """
return
"""
return
"""
%(name)
s = NULL;
%(name)
s = NULL;
type_num_
%(name)
s =
%(type_num)
s;
type_num_
%(name)
s =
%(type_num)
s;
"""
%
dict
(
sub
,
name
=
name
,
type_num
=
self
.
dtype_specs
()[
2
])
"""
%
dict
(
sub
,
name
=
name
,
type_num
=
self
.
dtype_specs
()[
2
])
def
c_extract
(
self
,
name
,
sub
):
def
c_extract
(
self
,
name
,
sub
):
"""Override `CLinkerOp.c_extract` """
return
"""
return
"""
%(name)
s = NULL;
%(name)
s = NULL;
type_num_
%(name)
s =
%(type_num)
s;
type_num_
%(name)
s =
%(type_num)
s;
...
@@ -186,6 +239,7 @@ class Tensor(Type):
...
@@ -186,6 +239,7 @@ class Tensor(Type):
"""
%
dict
(
sub
,
name
=
name
,
type_num
=
self
.
dtype_specs
()[
2
])
"""
%
dict
(
sub
,
name
=
name
,
type_num
=
self
.
dtype_specs
()[
2
])
def
c_cleanup
(
self
,
name
,
sub
):
def
c_cleanup
(
self
,
name
,
sub
):
"""Override `CLinkerOp.c_cleanup` """
return
"""
return
"""
if (
%(name)
s) {
if (
%(name)
s) {
Py_XDECREF(
%(name)
s);
Py_XDECREF(
%(name)
s);
...
@@ -193,6 +247,7 @@ class Tensor(Type):
...
@@ -193,6 +247,7 @@ class Tensor(Type):
"""
%
locals
()
"""
%
locals
()
def
c_sync
(
self
,
name
,
sub
):
def
c_sync
(
self
,
name
,
sub
):
"""Override `CLinkerOp.c_sync` """
return
"""
return
"""
Py_XDECREF(py_
%(name)
s);
Py_XDECREF(py_
%(name)
s);
if (!
%(name)
s) {
if (!
%(name)
s) {
...
@@ -205,12 +260,14 @@ class Tensor(Type):
...
@@ -205,12 +260,14 @@ class Tensor(Type):
"""
%
locals
()
"""
%
locals
()
def
c_headers
(
self
):
def
c_headers
(
self
):
"""Override `CLinkerOp.c_headers` """
return
[]
return
[]
def
c_libraries
(
self
):
def
c_libraries
(
self
):
return
[]
return
[]
def
c_support_code
(
cls
):
def
c_support_code
(
cls
):
"""Override `CLinkerOp.c_support_code` """
template
=
"""
template
=
"""
struct theano_complex
%(nbits)
s : public npy_complex
%(nbits)
s
struct theano_complex
%(nbits)
s : public npy_complex
%(nbits)
s
{
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论