Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
bf9413c8
提交
bf9413c8
authored
10月 31, 2016
作者:
Pascal Lamblin
提交者:
GitHub
10月 31, 2016
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5091 from abergeron/bool
Add bool dtype in scalar and tensor.
上级
58164835
46a30357
显示空白字符变更
内嵌
并排
正在显示
22 个修改的文件
包含
301 行增加
和
501 行删除
+301
-501
gradients.txt
doc/tutorial/gradients.txt
+1
-1
setup.py
setup.py
+1
-1
test_fg.py
theano/gof/tests/test_fg.py
+5
-11
elemwise.py
theano/gpuarray/elemwise.py
+2
-1
type.py
theano/gpuarray/type.py
+1
-0
gradient.py
theano/gradient.py
+6
-7
opt.py
theano/sandbox/cuda/opt.py
+7
-4
rng_curand.py
theano/sandbox/cuda/rng_curand.py
+5
-5
basic.py
theano/scalar/basic.py
+130
-84
test_basic.py
theano/scalar/tests/test_basic.py
+0
-11
basic.py
theano/tensor/basic.py
+14
-15
blas.py
theano/tensor/blas.py
+1
-1
elemwise.py
theano/tensor/elemwise.py
+17
-25
extra_ops.py
theano/tensor/extra_ops.py
+1
-99
sigm.py
theano/tensor/nnet/sigm.py
+1
-1
opt.py
theano/tensor/opt.py
+3
-0
test_basic.py
theano/tensor/tests/test_basic.py
+8
-32
test_elemwise.py
theano/tensor/tests/test_elemwise.py
+80
-85
test_extra_ops.py
theano/tensor/tests/test_extra_ops.py
+10
-102
type.py
theano/tensor/type.py
+2
-7
var.py
theano/tensor/var.py
+6
-8
test_flake8.py
theano/tests/test_flake8.py
+0
-1
没有找到文件。
doc/tutorial/gradients.txt
浏览文件 @
bf9413c8
...
@@ -124,7 +124,7 @@ do is to loop over the entries in *y* and compute the gradient of
...
@@ -124,7 +124,7 @@ do is to loop over the entries in *y* and compute the gradient of
>>> import theano.tensor as T
>>> import theano.tensor as T
>>> x = T.dvector('x')
>>> x = T.dvector('x')
>>> y = x ** 2
>>> y = x ** 2
>>> J, updates = theano.scan(lambda i, y,
x : T.grad(y[i], x), sequences=T.arange(y.shape[0]), non_sequences=[y,
x])
>>> J, updates = theano.scan(lambda i, y,
x : T.grad(y[i], x), sequences=T.arange(y.shape[0]), non_sequences=[y,
x])
>>> f = theano.function([x], J, updates=updates)
>>> f = theano.function([x], J, updates=updates)
>>> f([4, 4])
>>> f([4, 4])
array([[ 8., 0.],
array([[ 8., 0.],
...
...
setup.py
浏览文件 @
bf9413c8
...
@@ -53,7 +53,7 @@ PLATFORMS = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"]
...
@@ -53,7 +53,7 @@ PLATFORMS = ["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"]
MAJOR
=
0
MAJOR
=
0
MINOR
=
9
MINOR
=
9
MICRO
=
0
MICRO
=
0
SUFFIX
=
"dev
3
"
# Should be blank except for rc's, betas, etc.
SUFFIX
=
"dev
4
"
# Should be blank except for rc's, betas, etc.
ISRELEASED
=
False
ISRELEASED
=
False
VERSION
=
'
%
d.
%
d.
%
d
%
s'
%
(
MAJOR
,
MINOR
,
MICRO
,
SUFFIX
)
VERSION
=
'
%
d.
%
d.
%
d
%
s'
%
(
MAJOR
,
MINOR
,
MICRO
,
SUFFIX
)
...
...
theano/gof/tests/test_fg.py
浏览文件 @
bf9413c8
from
__future__
import
absolute_import
,
print_function
,
division
from
__future__
import
absolute_import
,
print_function
,
division
import
os
import
os
import
pickle
import
pickle
import
sys
import
unittest
import
unittest
from
nose.plugins.skip
import
SkipTest
import
theano
import
theano
from
theano.compat
import
PY3
from
theano.compat
import
PY3
from
theano.gof
import
CachedConstantError
,
FunctionGraph
from
theano.gof
import
CachedConstantError
,
FunctionGraph
...
@@ -32,14 +29,11 @@ class TFunctionGraph(unittest.TestCase):
...
@@ -32,14 +29,11 @@ class TFunctionGraph(unittest.TestCase):
pickle
.
loads
(
s
)
pickle
.
loads
(
s
)
def
test_node_outputs_not_used
(
self
):
def
test_node_outputs_not_used
(
self
):
"""In the past, we where removing some not used variable from
# In the past, we where removing some not used variable from
fgraph.variables event if the apply had other output used in
# fgraph.variables event if the apply had other output used in
the graph. This caused a crash.
# the graph. This caused a crash.
This test run the pickle that reproduce this case.
# This test run the pickle that reproduce this case.
"""
if
sys
.
version_info
[:
2
]
<
(
2
,
7
):
raise
SkipTest
(
"This test need python 2.7 or more recent."
)
with
open
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
with
open
(
os
.
path
.
join
(
os
.
path
.
dirname
(
__file__
),
'test_fg_old_crash.pkl'
),
'test_fg_old_crash.pkl'
),
'rb'
)
as
f
:
'rb'
)
as
f
:
...
...
theano/gpuarray/elemwise.py
浏览文件 @
bf9413c8
...
@@ -129,7 +129,8 @@ class GpuElemwise(HideC, Elemwise):
...
@@ -129,7 +129,8 @@ class GpuElemwise(HideC, Elemwise):
support_code
+=
fake_node
.
op
.
c_support_code
()
support_code
+=
fake_node
.
op
.
c_support_code
()
except
MethodNotDefined
:
except
MethodNotDefined
:
pass
pass
for
npy
,
ga
in
[(
"npy_uint8"
,
"ga_ubyte"
),
for
npy
,
ga
in
[(
"npy_bool"
,
"ga_bool"
),
(
"npy_uint8"
,
"ga_ubyte"
),
(
"npy_uint16"
,
"ga_ushort"
),
(
"npy_uint16"
,
"ga_ushort"
),
(
"npy_uint32"
,
"ga_uint"
),
(
"npy_uint32"
,
"ga_uint"
),
(
"npy_uint64"
,
"ga_ulong"
),
(
"npy_uint64"
,
"ga_ulong"
),
...
...
theano/gpuarray/type.py
浏览文件 @
bf9413c8
...
@@ -408,6 +408,7 @@ class GpuArrayType(Type):
...
@@ -408,6 +408,7 @@ class GpuArrayType(Type):
'float16'
:
(
float
,
'npy_float16'
,
'NPY_FLOAT16'
),
'float16'
:
(
float
,
'npy_float16'
,
'NPY_FLOAT16'
),
'float32'
:
(
float
,
'npy_float32'
,
'NPY_FLOAT32'
),
'float32'
:
(
float
,
'npy_float32'
,
'NPY_FLOAT32'
),
'float64'
:
(
float
,
'npy_float64'
,
'NPY_FLOAT64'
),
'float64'
:
(
float
,
'npy_float64'
,
'NPY_FLOAT64'
),
'bool'
:
(
int
,
'npy_bool'
,
'NPY_BOOL'
),
'uint8'
:
(
int
,
'npy_uint8'
,
'NPY_UINT8'
),
'uint8'
:
(
int
,
'npy_uint8'
,
'NPY_UINT8'
),
'int8'
:
(
int
,
'npy_int8'
,
'NPY_INT8'
),
'int8'
:
(
int
,
'npy_int8'
,
'NPY_INT8'
),
'uint16'
:
(
int
,
'npy_uint16'
,
'NPY_UINT16'
),
'uint16'
:
(
int
,
'npy_uint16'
,
'NPY_UINT16'
),
...
...
theano/gradient.py
浏览文件 @
bf9413c8
...
@@ -477,7 +477,7 @@ def grad(cost, wrt, consider_constant=None,
...
@@ -477,7 +477,7 @@ def grad(cost, wrt, consider_constant=None,
# function, sure, but nonetheless one we can and should support.
# function, sure, but nonetheless one we can and should support.
# So before we try to cast it make sure it even has a dtype
# So before we try to cast it make sure it even has a dtype
if
(
hasattr
(
g_cost
.
type
,
'dtype'
)
and
if
(
hasattr
(
g_cost
.
type
,
'dtype'
)
and
cost
.
type
.
dtype
not
in
tensor
.
discrete
_dtypes
):
cost
.
type
.
dtype
in
tensor
.
continuous
_dtypes
):
# Here we enforce the constraint that floating point variables
# Here we enforce the constraint that floating point variables
# have the same dtype as their gradient.
# have the same dtype as their gradient.
g_cost
=
g_cost
.
astype
(
cost
.
type
.
dtype
)
g_cost
=
g_cost
.
astype
(
cost
.
type
.
dtype
)
...
@@ -485,7 +485,7 @@ def grad(cost, wrt, consider_constant=None,
...
@@ -485,7 +485,7 @@ def grad(cost, wrt, consider_constant=None,
# This is to be enforced by the Op.grad method for the
# This is to be enforced by the Op.grad method for the
# Op that outputs cost.
# Op that outputs cost.
if
hasattr
(
g_cost
.
type
,
'dtype'
):
if
hasattr
(
g_cost
.
type
,
'dtype'
):
assert
g_cost
.
type
.
dtype
not
in
tensor
.
discrete
_dtypes
assert
g_cost
.
type
.
dtype
in
tensor
.
continuous
_dtypes
grad_dict
[
cost
]
=
g_cost
grad_dict
[
cost
]
=
g_cost
...
@@ -1335,12 +1335,11 @@ def _float_ones_like(x):
...
@@ -1335,12 +1335,11 @@ def _float_ones_like(x):
""" Like ones_like, but forces the object to have a
""" Like ones_like, but forces the object to have a
floating point dtype """
floating point dtype """
rval
=
tensor
.
ones_like
(
x
)
dtype
=
x
.
type
.
dtype
if
dtype
not
in
tensor
.
float_dtypes
:
dtype
=
theano
.
config
.
floatX
if
rval
.
type
.
dtype
.
find
(
'float'
)
!=
-
1
:
return
tensor
.
ones_like
(
x
,
dtype
=
dtype
)
return
rval
return
rval
.
astype
(
theano
.
config
.
floatX
)
class
numeric_grad
(
object
):
class
numeric_grad
(
object
):
...
...
theano/sandbox/cuda/opt.py
浏览文件 @
bf9413c8
...
@@ -237,8 +237,11 @@ optdb['canonicalize'].register('local_cut_gpu_host_gpu',
...
@@ -237,8 +237,11 @@ optdb['canonicalize'].register('local_cut_gpu_host_gpu',
# 'float64', 'complex128' and 'complex64' are not supported in elemwise
# 'float64', 'complex128' and 'complex64' are not supported in elemwise
# on the gpu.
# on the gpu.
elemwise_cuda_dtype_supported
=
[
'float32'
,
'uint8'
,
'int8'
,
'uint16'
,
'int16'
,
elemwise_cuda_dtype_supported
=
[
'float32'
,
'bool'
,
'uint32'
,
'int32'
,
'uint64'
,
'int64'
]
'uint8'
,
'int8'
,
'uint16'
,
'int16'
,
'uint32'
,
'int32'
,
'uint64'
,
'int64'
]
def
dtype_in_elemwise_supported
(
op
):
def
dtype_in_elemwise_supported
(
op
):
...
@@ -298,8 +301,8 @@ def local_gpu_elemwise_0(node):
...
@@ -298,8 +301,8 @@ def local_gpu_elemwise_0(node):
return
False
return
False
# first establish that float32 can store all inputs
# first establish that float32 can store all inputs
upcastable
=
set
([
'float32'
,
'
int8'
,
'int16'
,
'uint8
'
,
upcastable
=
set
([
'float32'
,
'
bool'
,
'int8'
,
'int16
'
,
'uint16'
])
'uint
8'
,
'uint
16'
])
# case 1 - all inputs are already float32
# case 1 - all inputs are already float32
if
all
([
i
.
type
.
dtype
==
'float32'
for
i
in
node
.
inputs
]):
if
all
([
i
.
type
.
dtype
==
'float32'
for
i
in
node
.
inputs
]):
# TODO: change this when fusion makes Elemwise with
# TODO: change this when fusion makes Elemwise with
...
...
theano/sandbox/cuda/rng_curand.py
浏览文件 @
bf9413c8
...
@@ -28,7 +28,7 @@ class CURAND_Base(GpuOp):
...
@@ -28,7 +28,7 @@ class CURAND_Base(GpuOp):
CURAND. This Op uses a generic-typed shared variable to point to a CObject
CURAND. This Op uses a generic-typed shared variable to point to a CObject
that encapsulates this opaque reference.
that encapsulates this opaque reference.
Each random variable is created with a generator of
Fals
e.
Each random variable is created with a generator of
Non
e.
The actual random number generator is allocated from the seed, on the first
The actual random number generator is allocated from the seed, on the first
call to allocate random numbers (see c_code).
call to allocate random numbers (see c_code).
...
@@ -210,7 +210,7 @@ class CURAND_Base(GpuOp):
...
@@ -210,7 +210,7 @@ class CURAND_Base(GpuOp):
%(fail)
s;
%(fail)
s;
}
}
%(o_generator)
s = PyCObject_FromVoidPtr(gen, &free_generator);
%(o_generator)
s = PyCObject_FromVoidPtr(gen, &free_generator);
assert (
%(i_generator)
s == Py_
Fals
e);
assert (
%(i_generator)
s == Py_
Non
e);
}
}
else if (
%(destructive)
s)
else if (
%(destructive)
s)
{
{
...
@@ -244,7 +244,7 @@ class CURAND_Base(GpuOp):
...
@@ -244,7 +244,7 @@ class CURAND_Base(GpuOp):
return
code
return
code
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
return
(
4
,)
return
(
5
,)
class
CURAND_Normal
(
CURAND_Base
):
class
CURAND_Normal
(
CURAND_Base
):
...
@@ -328,7 +328,7 @@ class CURAND_RandomStreams(object):
...
@@ -328,7 +328,7 @@ class CURAND_RandomStreams(object):
else
:
else
:
msg
=
"size must be a tuple of int or a Theano variable"
msg
=
"size must be a tuple of int or a Theano variable"
assert
isinstance
(
size
,
Variable
)
and
size
.
ndim
==
1
,
msg
assert
isinstance
(
size
,
Variable
)
and
size
.
ndim
==
1
,
msg
generator
=
theano
.
shared
(
Fals
e
)
# makes a generic
generator
=
theano
.
shared
(
Non
e
)
# makes a generic
s_size
=
theano
.
tensor
.
as_tensor_variable
(
size
)
s_size
=
theano
.
tensor
.
as_tensor_variable
(
size
)
u
=
CURAND_Uniform
.
new_auto_update
(
generator
,
ndim
,
dtype
,
s_size
,
u
=
CURAND_Uniform
.
new_auto_update
(
generator
,
ndim
,
dtype
,
s_size
,
self
.
next_seed
())
self
.
next_seed
())
...
@@ -360,7 +360,7 @@ class CURAND_RandomStreams(object):
...
@@ -360,7 +360,7 @@ class CURAND_RandomStreams(object):
else
:
else
:
msg
=
"size must be a tuple of int or a Theano variable"
msg
=
"size must be a tuple of int or a Theano variable"
assert
isinstance
(
size
,
Variable
)
and
size
.
ndim
==
1
,
msg
assert
isinstance
(
size
,
Variable
)
and
size
.
ndim
==
1
,
msg
generator
=
theano
.
shared
(
Fals
e
)
# makes a generic
generator
=
theano
.
shared
(
Non
e
)
# makes a generic
s_size
=
theano
.
tensor
.
as_tensor_variable
(
size
)
s_size
=
theano
.
tensor
.
as_tensor_variable
(
size
)
u
=
CURAND_Normal
.
new_auto_update
(
generator
,
ndim
,
dtype
,
s_size
,
u
=
CURAND_Normal
.
new_auto_update
(
generator
,
ndim
,
dtype
,
s_size
,
self
.
next_seed
())
self
.
next_seed
())
...
...
theano/scalar/basic.py
浏览文件 @
bf9413c8
...
@@ -34,6 +34,7 @@ from theano.gradient import grad_undefined
...
@@ -34,6 +34,7 @@ from theano.gradient import grad_undefined
from
theano.printing
import
pprint
from
theano.printing
import
pprint
import
collections
import
collections
builtin_bool
=
bool
builtin_complex
=
complex
builtin_complex
=
complex
builtin_int
=
int
builtin_int
=
int
builtin_float
=
float
builtin_float
=
float
...
@@ -161,7 +162,7 @@ class Scalar(Type):
...
@@ -161,7 +162,7 @@ class Scalar(Type):
TODO: refactor to be named ScalarType for consistency with TensorType.
TODO: refactor to be named ScalarType for consistency with TensorType.
"""
"""
__props__
=
(
'dtype'
,)
ndim
=
0
ndim
=
0
def
__init__
(
self
,
dtype
):
def
__init__
(
self
,
dtype
):
...
@@ -200,6 +201,8 @@ class Scalar(Type):
...
@@ -200,6 +201,8 @@ class Scalar(Type):
def
values_eq_approx
(
self
,
a
,
b
,
tolerance
=
1e-4
):
def
values_eq_approx
(
self
,
a
,
b
,
tolerance
=
1e-4
):
# The addition have risk of overflow especially with [u]int8
# The addition have risk of overflow especially with [u]int8
if
self
.
dtype
==
'bool'
:
return
a
==
b
diff
=
a
-
b
diff
=
a
-
b
if
diff
==
0
:
if
diff
==
0
:
return
True
return
True
...
@@ -227,12 +230,6 @@ class Scalar(Type):
...
@@ -227,12 +230,6 @@ class Scalar(Type):
else
:
else
:
return
[]
return
[]
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
and
other
.
dtype
==
self
.
dtype
def
__hash__
(
self
):
return
hash
(
'theano.scalar.Scalar'
)
^
hash
(
self
.
dtype
)
def
dtype_specs
(
self
):
def
dtype_specs
(
self
):
try
:
try
:
# To help debug dtype/typenum problem, here is code to get
# To help debug dtype/typenum problem, here is code to get
...
@@ -244,7 +241,8 @@ class Scalar(Type):
...
@@ -244,7 +241,8 @@ class Scalar(Type):
# now, as Theano always expect the exact typenum that
# now, as Theano always expect the exact typenum that
# correspond to our supported dtype.
# correspond to our supported dtype.
"""
"""
for dtype in ['int8', 'uint8', 'short', 'ushort', 'intc', 'uintc',
for dtype in ['bool', 'int8', 'uint8', 'short', 'ushort', 'intc',
'uintc',
'longlong', 'ulonglong', 'single', 'double',
'longlong', 'ulonglong', 'single', 'double',
'longdouble', 'csingle', 'cdouble', 'clongdouble',
'longdouble', 'csingle', 'cdouble', 'clongdouble',
'float32', 'float64', 'int8', 'int16', 'int32',
'float32', 'float64', 'int8', 'int16', 'int32',
...
@@ -260,6 +258,7 @@ class Scalar(Type):
...
@@ -260,6 +258,7 @@ class Scalar(Type):
'complex128'
:
(
numpy
.
complex128
,
'theano_complex128'
,
'complex128'
:
(
numpy
.
complex128
,
'theano_complex128'
,
'Complex128'
),
'Complex128'
),
'complex64'
:
(
numpy
.
complex64
,
'theano_complex64'
,
'Complex64'
),
'complex64'
:
(
numpy
.
complex64
,
'theano_complex64'
,
'Complex64'
),
'bool'
:
(
numpy
.
bool_
,
'npy_bool'
,
'Bool'
),
'uint8'
:
(
numpy
.
uint8
,
'npy_uint8'
,
'UInt8'
),
'uint8'
:
(
numpy
.
uint8
,
'npy_uint8'
,
'UInt8'
),
'int8'
:
(
numpy
.
int8
,
'npy_int8'
,
'Int8'
),
'int8'
:
(
numpy
.
int8
,
'npy_int8'
,
'Int8'
),
'uint16'
:
(
numpy
.
uint16
,
'npy_uint16'
,
'UInt16'
),
'uint16'
:
(
numpy
.
uint16
,
'npy_uint16'
,
'UInt16'
),
...
@@ -288,12 +287,13 @@ class Scalar(Type):
...
@@ -288,12 +287,13 @@ class Scalar(Type):
def
c_literal
(
self
,
data
):
def
c_literal
(
self
,
data
):
if
'complex'
in
self
.
dtype
:
if
'complex'
in
self
.
dtype
:
raise
NotImplementedError
(
"No literal for complex values."
)
raise
NotImplementedError
(
"No literal for complex values."
)
if
self
.
dtype
==
'bool'
:
return
'1'
if
data
else
'0'
return
str
(
data
)
return
str
(
data
)
def
c_declare
(
self
,
name
,
sub
,
check_input
=
True
):
def
c_declare
(
self
,
name
,
sub
,
check_input
=
True
):
if
(
check_input
):
if
(
check_input
):
pre
=
"""
pre
=
"""
typedef
%(dtype)
s
%(name)
s_dtype; // Deprecated use dtype_
%(name)
s instead.
typedef
%(dtype)
s dtype_
%(name)
s;
typedef
%(dtype)
s dtype_
%(name)
s;
"""
%
dict
(
name
=
name
,
dtype
=
self
.
dtype_specs
()[
1
])
"""
%
dict
(
name
=
name
,
dtype
=
self
.
dtype_specs
()[
1
])
else
:
else
:
...
@@ -309,6 +309,7 @@ class Scalar(Type):
...
@@ -309,6 +309,7 @@ class Scalar(Type):
def
c_extract
(
self
,
name
,
sub
,
check_input
=
True
):
def
c_extract
(
self
,
name
,
sub
,
check_input
=
True
):
if
self
.
dtype
==
'float16'
:
if
self
.
dtype
==
'float16'
:
# This doesn't work at the numpy level
raise
NotImplementedError
(
'float16'
)
raise
NotImplementedError
(
'float16'
)
specs
=
self
.
dtype_specs
()
specs
=
self
.
dtype_specs
()
if
(
check_input
):
if
(
check_input
):
...
@@ -517,6 +518,7 @@ theano.compile.register_view_op_c_code(
...
@@ -517,6 +518,7 @@ theano.compile.register_view_op_c_code(
1
)
1
)
bool
=
get_scalar_type
(
'bool'
)
int8
=
get_scalar_type
(
'int8'
)
int8
=
get_scalar_type
(
'int8'
)
int16
=
get_scalar_type
(
'int16'
)
int16
=
get_scalar_type
(
'int16'
)
int32
=
get_scalar_type
(
'int32'
)
int32
=
get_scalar_type
(
'int32'
)
...
@@ -536,7 +538,8 @@ uint_types = uint8, uint16, uint32, uint64
...
@@ -536,7 +538,8 @@ uint_types = uint8, uint16, uint32, uint64
float_types
=
float16
,
float32
,
float64
float_types
=
float16
,
float32
,
float64
complex_types
=
complex64
,
complex128
complex_types
=
complex64
,
complex128
discrete_types
=
int_types
+
uint_types
integer_types
=
int_types
+
uint_types
discrete_types
=
(
bool
,)
+
integer_types
continuous_types
=
float_types
+
complex_types
continuous_types
=
float_types
+
complex_types
all_types
=
discrete_types
+
continuous_types
all_types
=
discrete_types
+
continuous_types
...
@@ -681,24 +684,32 @@ complexs64 = _multi(complex64)
...
@@ -681,24 +684,32 @@ complexs64 = _multi(complex64)
complexs128
=
_multi
(
complex128
)
complexs128
=
_multi
(
complex128
)
# Using a class instead of a function makes it possible to deep-copy it in
def
upcast_out
(
*
types
):
# Python 2.4.
# Note that currently only a few functions use this mechanism, because it is
# enough to make the test-suite pass with Python 2.4. However, it may prove
# necessary to use this same mechanism in other places as well in the future.
class
upcast_out
(
object
):
def
__new__
(
self
,
*
types
):
dtype
=
Scalar
.
upcast
(
*
types
)
dtype
=
Scalar
.
upcast
(
*
types
)
return
get_scalar_type
(
dtype
),
return
get_scalar_type
(
dtype
),
class
upgrade_to_float
(
object
):
def
upcast_out_nobool
(
*
types
):
def
__new__
(
self
,
*
types
):
type
=
upcast_out
(
*
types
)
if
type
[
0
]
==
bool
:
raise
TypeError
(
"bool output not supported"
)
return
type
def
upcast_out_min8
(
*
types
):
type
=
upcast_out
(
*
types
)
if
type
[
0
]
==
bool
:
return
int8
,
return
type
def
upgrade_to_float
(
*
types
):
"""
"""
Upgrade any int types to float32 or float64 to avoid losing precision.
Upgrade any int types to float32 or float64 to avoid losing precision.
"""
"""
conv
=
{
int8
:
float32
,
conv
=
{
bool
:
float32
,
int8
:
float32
,
int16
:
float32
,
int16
:
float32
,
int32
:
float64
,
int32
:
float64
,
int64
:
float64
,
int64
:
float64
,
...
@@ -710,8 +721,19 @@ class upgrade_to_float(object):
...
@@ -710,8 +721,19 @@ class upgrade_to_float(object):
for
type
in
types
])),
for
type
in
types
])),
class
same_out
(
object
):
def
same_out
(
type
):
def
__new__
(
self
,
type
):
return
type
,
def
same_out_nobool
(
type
):
if
type
==
bool
:
raise
TypeError
(
"bool input not supported"
)
return
type
,
def
same_out_min8
(
type
):
if
type
==
bool
:
return
int8
,
return
type
,
return
type
,
...
@@ -728,6 +750,8 @@ def same_out_float_only(type):
...
@@ -728,6 +750,8 @@ def same_out_float_only(type):
class
transfer_type
(
gof
.
utils
.
object2
):
class
transfer_type
(
gof
.
utils
.
object2
):
__props__
=
(
'transfer'
,)
def
__init__
(
self
,
*
transfer
):
def
__init__
(
self
,
*
transfer
):
assert
all
(
type
(
x
)
in
[
int
,
str
]
or
x
is
None
for
x
in
transfer
)
assert
all
(
type
(
x
)
in
[
int
,
str
]
or
x
is
None
for
x
in
transfer
)
self
.
transfer
=
transfer
self
.
transfer
=
transfer
...
@@ -748,26 +772,16 @@ class transfer_type(gof.utils.object2):
...
@@ -748,26 +772,16 @@ class transfer_type(gof.utils.object2):
return
retval
return
retval
# return [upcast if i is None else types[i] for i in self.transfer]
# return [upcast if i is None else types[i] for i in self.transfer]
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
and
self
.
transfer
==
other
.
transfer
def
__hash__
(
self
):
return
hash
(
self
.
transfer
)
class
specific_out
(
gof
.
utils
.
object2
):
class
specific_out
(
gof
.
utils
.
object2
):
__props__
=
(
'spec'
,)
def
__init__
(
self
,
*
spec
):
def
__init__
(
self
,
*
spec
):
self
.
spec
=
spec
self
.
spec
=
spec
def
__call__
(
self
,
*
types
):
def
__call__
(
self
,
*
types
):
return
self
.
spec
return
self
.
spec
def
__eq__
(
self
,
other
):
return
type
(
self
)
==
type
(
other
)
and
self
.
spec
==
other
.
spec
def
__hash__
(
self
):
return
hash
(
self
.
spec
)
def
int_out
(
*
types
):
def
int_out
(
*
types
):
return
int64
,
return
int64
,
...
@@ -914,15 +928,15 @@ class ScalarOp(Op):
...
@@ -914,15 +928,15 @@ class ScalarOp(Op):
return
test
return
test
def
__hash__
(
self
):
def
__hash__
(
self
):
return
hash
(
type
(
self
)
.
__name__
)
^
hash
(
return
hash
(
(
type
(
self
),
getattr
(
self
,
'output_types_preference'
,
0
))
getattr
(
self
,
'output_types_preference'
,
0
)
))
def
__str__
(
self
):
def
__str__
(
self
):
if
hasattr
(
self
,
'name'
)
and
self
.
name
:
if
hasattr
(
self
,
'name'
)
and
self
.
name
:
return
self
.
name
return
self
.
name
else
:
else
:
param
=
[(
k
,
v
)
for
k
,
v
in
self
.
__dict__
.
items
()
param
=
[(
k
,
v
)
for
k
,
v
in
self
.
__dict__
.
items
()
if
k
not
in
[
"name"
,
"_op_use_c_code"
,
if
k
not
in
[
"name"
,
"_op_use_c_code"
,
"bool"
,
"output_types_preference"
]]
"output_types_preference"
]]
if
param
:
if
param
:
return
"
%
s{
%
s}"
%
(
self
.
__class__
.
__name__
,
return
"
%
s{
%
s}"
%
(
self
.
__class__
.
__name__
,
...
@@ -1006,31 +1020,65 @@ class BinaryScalarOp(ScalarOp):
...
@@ -1006,31 +1020,65 @@ class BinaryScalarOp(ScalarOp):
###############
###############
class
LogicalComparison
(
BinaryScalarOp
):
class
LogicalComparison
(
BinaryScalarOp
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
BinaryScalarOp
.
__init__
(
self
,
*
args
,
**
kwargs
)
# This is for compat with old pickles.
self
.
bool
=
True
def
__eq__
(
self
,
other
):
return
(
BinaryScalarOp
.
__eq__
(
self
,
other
)
and
getattr
(
self
,
'bool'
,
False
)
==
getattr
(
self
,
'bool'
,
False
))
def
__hash__
(
self
):
# bool should always be True
return
BinaryScalarOp
.
__hash__
(
self
)
def
output_types
(
self
,
*
input_dtypes
):
def
output_types
(
self
,
*
input_dtypes
):
return
[
int8
]
return
[
bool
]
if
getattr
(
self
,
'bool'
,
False
)
else
[
int8
]
def
grad
(
self
,
inputs
,
output_gradients
):
def
grad
(
self
,
inputs
,
output_gradients
):
x
,
y
=
inputs
x
,
y
=
inputs
out
=
self
(
x
,
y
)
out
=
self
(
x
,
y
)
assert
str
(
out
.
type
.
dtype
)
.
find
(
'int'
)
!=
-
1
assert
out
.
type
==
bool
return
[
x
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
),
return
[
x
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
),
y
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
)]
y
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
)]
def
c_code_cache_version
(
self
):
super_version
=
super
(
LogicalComparison
,
self
)
.
c_code_cache_version
()
return
super_version
+
(
0
,)
class
FixedLogicalComparison
(
UnaryScalarOp
):
class
FixedLogicalComparison
(
UnaryScalarOp
):
"""
"""
Comparison to a fixed value.
Comparison to a fixed value.
"""
"""
def
__init__
(
self
,
*
args
,
**
kwargs
):
UnaryScalarOp
.
__init__
(
self
,
*
args
,
**
kwargs
)
# This is for compat with old pickles
self
.
bool
=
True
def
__eq__
(
self
,
other
):
return
(
UnaryScalarOp
.
__eq__
(
self
,
other
)
and
getattr
(
self
,
'bool'
,
False
)
==
getattr
(
self
,
'bool'
,
False
))
def
__hash__
(
self
):
# bool should always be True
return
UnaryScalarOp
.
__hash__
(
self
)
def
output_types
(
self
,
*
input_dtypes
):
def
output_types
(
self
,
*
input_dtypes
):
return
[
int8
]
return
[
bool
]
if
getattr
(
self
,
'bool'
,
False
)
else
[
int8
]
def
grad
(
self
,
inputs
,
output_gradients
):
def
grad
(
self
,
inputs
,
output_gradients
):
x
,
=
inputs
x
,
=
inputs
out
=
self
(
x
)
out
=
self
(
x
)
assert
str
(
out
.
type
.
dtype
)
.
find
(
'int'
)
!=
-
1
assert
out
.
type
==
bool
return
[
x
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
)]
return
[
x
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
)]
def
c_code_cache_version
(
self
):
super_version
=
super
(
FixedLogicalComparison
,
self
)
.
c_code_cache_version
()
return
super_version
+
(
0
,)
class
LT
(
LogicalComparison
):
class
LT
(
LogicalComparison
):
identity
=
False
identity
=
False
...
@@ -1202,21 +1250,10 @@ class InRange(LogicalComparison):
...
@@ -1202,21 +1250,10 @@ class InRange(LogicalComparison):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
(
x
,
low
,
hi
)
=
inputs
(
x
,
low
,
hi
)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
if
self
.
openlow
:
cmp1
=
'>'
else
:
cmp1
=
'>='
# backport
# cmp1 = '>' if self.openlow else '>='
if
self
.
openhi
:
cmp1
=
'>'
if
self
.
openlow
else
'>='
cmp2
=
'<'
cmp2
=
'<'
if
self
.
openhi
else
'<='
else
:
cmp2
=
'<='
# backport
# cmp2 = '<' if self.openhi else '<='
return
(
"
%(z)
s =
%(x)
s
%(cmp1)
s
%(low)
s &&"
return
(
"
%(z)
s =
%(x)
s
%(cmp1)
s
%(low)
s &&"
"
%(x)
s
%(cmp2)
s
%(hi)
s;"
%
locals
())
"
%(x)
s
%(cmp2)
s
%(hi)
s;"
%
locals
())
...
@@ -1247,13 +1284,8 @@ class Switch(ScalarOp):
...
@@ -1247,13 +1284,8 @@ class Switch(ScalarOp):
nfunc_spec
=
(
'where'
,
3
,
1
)
nfunc_spec
=
(
'where'
,
3
,
1
)
def
impl
(
self
,
cond
,
ift
,
iff
):
def
impl
(
self
,
cond
,
ift
,
iff
):
if
cond
:
return
ift
if
cond
else
iff
return
ift
else
:
return
iff
# backport
# return ift if cond else iff
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
(
cond
,
ift
,
iff
)
=
inputs
(
cond
,
ift
,
iff
)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
...
@@ -1290,9 +1322,9 @@ switch = Switch()
...
@@ -1290,9 +1322,9 @@ switch = Switch()
class
UnaryBitOp
(
UnaryScalarOp
):
class
UnaryBitOp
(
UnaryScalarOp
):
def
output_types
(
self
,
*
input_types
):
def
output_types
(
self
,
*
input_types
):
for
i
in
input_types
[
0
]:
for
i
in
input_types
[
0
]:
if
i
not
in
(
int8
,
int16
,
int32
,
int64
)
:
if
i
not
in
discrete_types
:
raise
TypeError
(
'input to a BitOp must have type
int8,
'
raise
TypeError
(
'input to a BitOp must have type
(u)int8,
'
'
int16, int32 or int64...
not
%
s'
%
i
)
'
(u)int16, (u)int32 or (u)int64 or bool
not
%
s'
%
i
)
return
upcast_out
(
*
input_types
[
0
])
return
upcast_out
(
*
input_types
[
0
])
def
grad
(
self
,
inputs
,
output_gradients
):
def
grad
(
self
,
inputs
,
output_gradients
):
...
@@ -1302,10 +1334,13 @@ class UnaryBitOp(UnaryScalarOp):
...
@@ -1302,10 +1334,13 @@ class UnaryBitOp(UnaryScalarOp):
class
BinaryBitOp
(
BinaryScalarOp
):
class
BinaryBitOp
(
BinaryScalarOp
):
def
output_types
(
self
,
*
input_types
):
def
output_types
(
self
,
*
input_types
):
t0
,
t1
=
input_types
[
0
]
t0
,
t1
=
input_types
[
0
]
if
t0
==
bool
and
t1
==
bool
:
return
[
bool
]
for
i
in
input_types
[
0
]:
for
i
in
input_types
[
0
]:
if
i
not
in
(
int8
,
int16
,
int32
,
int64
):
if
i
not
in
integer_types
:
raise
TypeError
(
'input to a BitOp must have type int8,'
raise
TypeError
(
'input to a BitOp must have type (u)int8, '
' int16, int32 or int64... not
%
s'
%
i
)
'(u)int16, (u)int32 or (u)int64 or '
'be all bools not
%
s'
%
i
)
return
upcast_out
(
*
input_types
[
0
])
return
upcast_out
(
*
input_types
[
0
])
def
grad
(
self
,
inputs
,
output_gradients
):
def
grad
(
self
,
inputs
,
output_gradients
):
...
@@ -1371,6 +1406,8 @@ class Invert(UnaryBitOp):
...
@@ -1371,6 +1406,8 @@ class Invert(UnaryBitOp):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
(
x
,)
=
inputs
(
x
,)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
if
node
.
outputs
[
0
]
.
type
==
bool
:
return
"
%(z)
s = (!
%(x)
s);"
%
locals
()
return
"
%(z)
s = (~
%(x)
s);"
%
locals
()
return
"
%(z)
s = (~
%(x)
s);"
%
locals
()
invert
=
Invert
()
invert
=
Invert
()
...
@@ -1463,10 +1500,13 @@ class Add(ScalarOp):
...
@@ -1463,10 +1500,13 @@ class Add(ScalarOp):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
(
z
,)
=
outputs
(
z
,)
=
outputs
op
=
" + "
if
node
.
outputs
[
0
]
.
type
==
bool
:
op
=
" || "
if
not
inputs
:
if
not
inputs
:
return
z
+
" = 0;"
return
z
+
" = 0;"
else
:
else
:
return
z
+
" = "
+
" + "
.
join
(
inputs
)
+
";"
return
z
+
" = "
+
op
.
join
(
inputs
)
+
";"
def
grad
(
self
,
inputs
,
gout
):
def
grad
(
self
,
inputs
,
gout
):
(
gz
,)
=
gout
(
gz
,)
=
gout
...
@@ -1502,10 +1542,13 @@ class Mul(ScalarOp):
...
@@ -1502,10 +1542,13 @@ class Mul(ScalarOp):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
(
z
,)
=
outputs
(
z
,)
=
outputs
op
=
" * "
if
node
.
outputs
[
0
]
.
type
==
bool
:
op
=
" && "
if
not
inputs
:
if
not
inputs
:
return
z
+
" = 1;"
return
z
+
" = 1;"
else
:
else
:
return
z
+
" = "
+
" * "
.
join
(
inputs
)
+
";"
return
z
+
" = "
+
op
.
join
(
inputs
)
+
";"
def
grad
(
self
,
inputs
,
gout
):
def
grad
(
self
,
inputs
,
gout
):
(
gz
,)
=
gout
(
gz
,)
=
gout
...
@@ -1571,7 +1614,7 @@ class Sub(BinaryScalarOp):
...
@@ -1571,7 +1614,7 @@ class Sub(BinaryScalarOp):
second_part
=
-
gz
second_part
=
-
gz
return
first_part
,
second_part
return
first_part
,
second_part
sub
=
Sub
(
upcast_out
,
name
=
'sub'
)
sub
=
Sub
(
upcast_out
_nobool
,
name
=
'sub'
)
def
int_or_true_div
(
x_discrete
,
y_discrete
):
def
int_or_true_div
(
x_discrete
,
y_discrete
):
...
@@ -1937,7 +1980,7 @@ class Pow(BinaryScalarOp):
...
@@ -1937,7 +1980,7 @@ class Pow(BinaryScalarOp):
raise
theano
.
gof
.
utils
.
MethodNotDefined
()
raise
theano
.
gof
.
utils
.
MethodNotDefined
()
pow
=
Pow
(
upcast_out
,
name
=
'pow'
)
pow
=
Pow
(
upcast_out
_min8
,
name
=
'pow'
)
class
Clip
(
ScalarOp
):
class
Clip
(
ScalarOp
):
...
@@ -2062,6 +2105,8 @@ class Cast(UnaryScalarOp):
...
@@ -2062,6 +2105,8 @@ class Cast(UnaryScalarOp):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
def
c_code
(
self
,
node
,
name
,
inputs
,
outputs
,
sub
):
(
x
,)
=
inputs
(
x
,)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
if
node
.
outputs
[
0
]
.
type
==
bool
:
return
"
%
s = (
%
s) ? 1 : 0;"
%
(
z
,
x
)
return
"
%
s = (
%
s)
%
s;"
%
(
z
,
node
.
outputs
[
0
]
.
type
.
dtype_specs
()[
1
],
x
)
return
"
%
s = (
%
s)
%
s;"
%
(
z
,
node
.
outputs
[
0
]
.
type
.
dtype_specs
()[
1
],
x
)
def
grad
(
self
,
inputs
,
gout
):
def
grad
(
self
,
inputs
,
gout
):
...
@@ -2075,10 +2120,11 @@ class Cast(UnaryScalarOp):
...
@@ -2075,10 +2120,11 @@ class Cast(UnaryScalarOp):
def
c_code_cache_version
(
self
):
def
c_code_cache_version
(
self
):
s
=
super
(
Cast
,
self
)
.
c_code_cache_version
()
s
=
super
(
Cast
,
self
)
.
c_code_cache_version
()
if
s
:
if
s
:
return
(
3
,)
+
s
return
(
4
,)
+
s
else
:
else
:
return
s
return
s
convert_to_bool
=
Cast
(
bool
,
name
=
'convert_to_bool'
)
convert_to_int8
=
Cast
(
int8
,
name
=
'convert_to_int8'
)
convert_to_int8
=
Cast
(
int8
,
name
=
'convert_to_int8'
)
convert_to_int16
=
Cast
(
int16
,
name
=
'convert_to_int16'
)
convert_to_int16
=
Cast
(
int16
,
name
=
'convert_to_int16'
)
convert_to_int32
=
Cast
(
int32
,
name
=
'convert_to_int32'
)
convert_to_int32
=
Cast
(
int32
,
name
=
'convert_to_int32'
)
...
@@ -2094,6 +2140,7 @@ convert_to_complex64 = Cast(complex64, name='convert_to_complex64')
...
@@ -2094,6 +2140,7 @@ convert_to_complex64 = Cast(complex64, name='convert_to_complex64')
convert_to_complex128
=
Cast
(
complex128
,
name
=
'convert_to_complex128'
)
convert_to_complex128
=
Cast
(
complex128
,
name
=
'convert_to_complex128'
)
_cast_mapping
=
{
_cast_mapping
=
{
'bool'
:
convert_to_bool
,
'int8'
:
convert_to_int8
,
'int8'
:
convert_to_int8
,
'int16'
:
convert_to_int16
,
'int16'
:
convert_to_int16
,
'int32'
:
convert_to_int32
,
'int32'
:
convert_to_int32
,
...
@@ -2173,6 +2220,12 @@ abs_ = Abs(same_out)
...
@@ -2173,6 +2220,12 @@ abs_ = Abs(same_out)
class
Sgn
(
UnaryScalarOp
):
class
Sgn
(
UnaryScalarOp
):
nfunc_spec
=
(
'sign'
,
1
,
1
)
nfunc_spec
=
(
'sign'
,
1
,
1
)
@staticmethod
def
output_types_preference
(
x
):
if
x
==
bool
:
raise
TypeError
(
x
)
return
same_out_nocomplex
(
x
)
def
impl
(
self
,
x
):
def
impl
(
self
,
x
):
# casting to output type is handled by filter
# casting to output type is handled by filter
return
numpy
.
sign
(
x
)
return
numpy
.
sign
(
x
)
...
@@ -2205,7 +2258,7 @@ class Sgn(UnaryScalarOp):
...
@@ -2205,7 +2258,7 @@ class Sgn(UnaryScalarOp):
return
(
4
,)
+
s
return
(
4
,)
+
s
else
:
# if parent is unversioned, we are too
else
:
# if parent is unversioned, we are too
return
s
return
s
sgn
=
Sgn
(
same_out_nocomplex
,
name
=
'sgn'
)
sgn
=
Sgn
(
name
=
'sgn'
)
class
Ceil
(
UnaryScalarOp
):
class
Ceil
(
UnaryScalarOp
):
...
@@ -2228,7 +2281,7 @@ class Ceil(UnaryScalarOp):
...
@@ -2228,7 +2281,7 @@ class Ceil(UnaryScalarOp):
(
x
,)
=
inputs
(
x
,)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
return
"
%(z)
s = ceil(
%(x)
s);"
%
locals
()
return
"
%(z)
s = ceil(
%(x)
s);"
%
locals
()
ceil
=
Ceil
(
same_out_no
complex
,
name
=
'ceil'
)
ceil
=
Ceil
(
upgrade_to_float_no_
complex
,
name
=
'ceil'
)
class
Floor
(
UnaryScalarOp
):
class
Floor
(
UnaryScalarOp
):
...
@@ -2251,7 +2304,7 @@ class Floor(UnaryScalarOp):
...
@@ -2251,7 +2304,7 @@ class Floor(UnaryScalarOp):
(
x
,)
=
inputs
(
x
,)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
return
"
%(z)
s = floor(
%(x)
s);"
%
locals
()
return
"
%(z)
s = floor(
%(x)
s);"
%
locals
()
floor
=
Floor
(
same_out_no
complex
,
name
=
'floor'
)
floor
=
Floor
(
upgrade_to_float_no_
complex
,
name
=
'floor'
)
class
Trunc
(
UnaryScalarOp
):
class
Trunc
(
UnaryScalarOp
):
...
@@ -2269,7 +2322,7 @@ class Trunc(UnaryScalarOp):
...
@@ -2269,7 +2322,7 @@ class Trunc(UnaryScalarOp):
(
x
,)
=
inputs
(
x
,)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
return
"
%(z)
s =
%(x)
s >= 0? floor(
%(x)
s): -floor(-
%(x)
s);"
%
locals
()
return
"
%(z)
s =
%(x)
s >= 0? floor(
%(x)
s): -floor(-
%(x)
s);"
%
locals
()
trunc
=
Trunc
(
same_out_no
complex
,
name
=
'trunc'
)
trunc
=
Trunc
(
upgrade_to_float_no_
complex
,
name
=
'trunc'
)
class
RoundHalfToEven
(
UnaryScalarOp
):
class
RoundHalfToEven
(
UnaryScalarOp
):
...
@@ -2409,13 +2462,6 @@ class Neg(UnaryScalarOp):
...
@@ -2409,13 +2462,6 @@ class Neg(UnaryScalarOp):
nfunc_spec
=
(
'negative'
,
1
,
1
)
nfunc_spec
=
(
'negative'
,
1
,
1
)
def
impl
(
self
,
x
):
def
impl
(
self
,
x
):
# We have to make sure x is not a numpy.bool_, because
# `-numpy.bool_(True)` is `False` (we want 0), and
# `-numpy.bool_(False)` is `True` (we want 1).
# This happens for Composite, as the intermediate results are not
# casted in the dtype of the intermediate variable in general.
if
isinstance
(
x
,
numpy
.
bool_
):
x
=
numpy
.
int8
(
x
)
return
-
x
return
-
x
def
grad
(
self
,
inputs
,
gout
):
def
grad
(
self
,
inputs
,
gout
):
...
@@ -2433,7 +2479,7 @@ class Neg(UnaryScalarOp):
...
@@ -2433,7 +2479,7 @@ class Neg(UnaryScalarOp):
(
x
,)
=
inputs
(
x
,)
=
inputs
(
z
,)
=
outputs
(
z
,)
=
outputs
return
"
%(z)
s = -
%(x)
s;"
%
locals
()
return
"
%(z)
s = -
%(x)
s;"
%
locals
()
neg
=
Neg
(
same_out
,
name
=
'neg'
)
neg
=
Neg
(
same_out
_nobool
,
name
=
'neg'
)
pprint
.
assign
(
add
,
printing
.
OperatorPrinter
(
'+'
,
-
2
,
'either'
))
pprint
.
assign
(
add
,
printing
.
OperatorPrinter
(
'+'
,
-
2
,
'either'
))
pprint
.
assign
(
mul
,
printing
.
OperatorPrinter
(
'*'
,
-
1
,
'either'
))
pprint
.
assign
(
mul
,
printing
.
OperatorPrinter
(
'*'
,
-
1
,
'either'
))
...
@@ -3423,7 +3469,7 @@ class Conj(UnaryScalarOp):
...
@@ -3423,7 +3469,7 @@ class Conj(UnaryScalarOp):
def
impl
(
self
,
x
):
def
impl
(
self
,
x
):
return
numpy
.
conj
(
x
)
return
numpy
.
conj
(
x
)
conj
=
Conj
(
same_out
,
name
=
'conj'
)
conj
=
Conj
(
same_out
_min8
,
name
=
'conj'
)
class
ComplexFromPolar
(
BinaryScalarOp
):
class
ComplexFromPolar
(
BinaryScalarOp
):
...
...
theano/scalar/tests/test_basic.py
浏览文件 @
bf9413c8
...
@@ -155,17 +155,6 @@ class test_composite(unittest.TestCase):
...
@@ -155,17 +155,6 @@ class test_composite(unittest.TestCase):
si3
=
theano
.
scalar
.
float32
()
si3
=
theano
.
scalar
.
float32
()
sop
.
make_node
(
si0
*
si3
,
si1
,
si2
)
sop
.
make_node
(
si0
*
si3
,
si1
,
si2
)
def
test_composite_neg_bool
(
self
):
# Check that taking the negation of a Boolean intermediate value
# works correctly with Python code. It used to be an issue because
# `-numpy.bool_(True)` is False and `-numpy.bool_(False)` is True.
x
=
floats
(
'x'
)
y
=
-
(
x
>
0
)
z
=
Composite
([
x
],
[
y
])
.
make_node
(
x
)
.
outputs
[
0
]
f
=
theano
.
function
([
x
],
z
,
mode
=
theano
.
Mode
(
linker
=
'py'
))
for
inp
,
out
in
zip
([
-
1
,
0
,
1
],
[
0
,
0
,
-
1
]):
self
.
assertTrue
(
f
(
inp
)
==
out
)
class
test_logical
(
unittest
.
TestCase
):
class
test_logical
(
unittest
.
TestCase
):
def
test_gt
(
self
):
def
test_gt
(
self
):
...
...
theano/tensor/basic.py
浏览文件 @
bf9413c8
...
@@ -52,6 +52,7 @@ python_all = all
...
@@ -52,6 +52,7 @@ python_all = all
complex_dtypes
=
list
(
map
(
str
,
scal
.
complex_types
))
complex_dtypes
=
list
(
map
(
str
,
scal
.
complex_types
))
continuous_dtypes
=
list
(
map
(
str
,
scal
.
continuous_types
))
continuous_dtypes
=
list
(
map
(
str
,
scal
.
continuous_types
))
float_dtypes
=
list
(
map
(
str
,
scal
.
float_types
))
float_dtypes
=
list
(
map
(
str
,
scal
.
float_types
))
integer_dtypes
=
list
(
map
(
str
,
scal
.
integer_types
))
discrete_dtypes
=
list
(
map
(
str
,
scal
.
discrete_types
))
discrete_dtypes
=
list
(
map
(
str
,
scal
.
discrete_types
))
all_dtypes
=
list
(
map
(
str
,
scal
.
all_types
))
all_dtypes
=
list
(
map
(
str
,
scal
.
all_types
))
int_dtypes
=
list
(
map
(
str
,
scal
.
int_types
))
int_dtypes
=
list
(
map
(
str
,
scal
.
int_types
))
...
@@ -302,7 +303,7 @@ class NumpyAutocaster(object):
...
@@ -302,7 +303,7 @@ class NumpyAutocaster(object):
# returns either an exact x_==x, or the last cast x_
# returns either an exact x_==x, or the last cast x_
return
x_
return
x_
autocast_int
=
NumpyAutocaster
((
'int16'
,
'int32'
,
'int64'
))
autocast_int
=
NumpyAutocaster
((
'int
8'
,
'int
16'
,
'int32'
,
'int64'
))
autocast_float
=
NumpyAutocaster
((
'float16'
,
'float32'
,
'float64'
))
autocast_float
=
NumpyAutocaster
((
'float16'
,
'float32'
,
'float64'
))
...
@@ -379,16 +380,10 @@ def constant_or_value(x, rtype, name=None, ndim=None, dtype=None):
...
@@ -379,16 +380,10 @@ def constant_or_value(x, rtype, name=None, ndim=None, dtype=None):
x_
=
autocast_float
(
x
)
x_
=
autocast_float
(
x
)
elif
isinstance
(
x
,
numpy
.
ndarray
):
elif
isinstance
(
x
,
numpy
.
ndarray
):
x_
=
x
x_
=
x
# Currently we do not have a bool dtype in Theano.
# So we upcast it to uint8 to avoid breaking our interface for
# constant.
if
x
.
dtype
==
'bool'
:
x_
=
numpy
.
asarray
(
x_
,
dtype
=
'uint8'
)
else
:
else
:
# Here x is probably a list or a tuple. If it contains a long,
# Here x is probably a list or a tuple. If it contains a
# we will behave like the current NumPy version: 1.7 and below,
# long, we will behave like the current NumPy version: it
# it will only work if the long fits in int64. For NumPy 1.7.1+,
# will work if the long fits in int64 or uint64.
# it will work if the long fits in int64 or uint64.
x_
=
numpy
.
asarray
(
x
)
x_
=
numpy
.
asarray
(
x
)
if
x_
.
size
==
0
and
not
hasattr
(
x
,
'dtype'
):
if
x_
.
size
==
0
and
not
hasattr
(
x
,
'dtype'
):
x_
=
numpy
.
asarray
(
x
,
dtype
=
config
.
floatX
)
x_
=
numpy
.
asarray
(
x
,
dtype
=
config
.
floatX
)
...
@@ -521,11 +516,6 @@ def _allclose(a, b, rtol=None, atol=None):
...
@@ -521,11 +516,6 @@ def _allclose(a, b, rtol=None, atol=None):
if
atol
is
not
None
:
if
atol
is
not
None
:
atol_
=
atol
atol_
=
atol
# Work around bug in Numpy, see
# http://projects.scipy.org/numpy/ticket/1684
if
str
(
b
.
dtype
)
in
int_dtypes
and
(
numpy
.
absolute
(
b
)
<
0
)
.
any
():
b
=
theano
.
_asarray
(
b
,
dtype
=
'float64'
)
return
numpy
.
allclose
(
a
,
b
,
atol
=
atol_
,
rtol
=
rtol_
)
return
numpy
.
allclose
(
a
,
b
,
atol
=
atol_
,
rtol
=
rtol_
)
...
@@ -1247,6 +1237,10 @@ def _conversion(real_value, name):
...
@@ -1247,6 +1237,10 @@ def _conversion(real_value, name):
# what types you are casting to what. That logic is implemented by the
# what types you are casting to what. That logic is implemented by the
# `cast()` function below.
# `cast()` function below.
_convert_to_bool
=
_conversion
(
elemwise
.
Elemwise
(
scal
.
convert_to_bool
),
'bool'
)
"""Cast to boolean"""
_convert_to_int8
=
_conversion
(
_convert_to_int8
=
_conversion
(
elemwise
.
Elemwise
(
scal
.
convert_to_int8
),
'int8'
)
elemwise
.
Elemwise
(
scal
.
convert_to_int8
),
'int8'
)
"""Cast to 8-bit integer"""
"""Cast to 8-bit integer"""
...
@@ -1300,6 +1294,7 @@ _convert_to_complex128 = _conversion(
...
@@ -1300,6 +1294,7 @@ _convert_to_complex128 = _conversion(
"""Cast to double-precision complex"""
"""Cast to double-precision complex"""
_cast_mapping
=
{
_cast_mapping
=
{
'bool'
:
_convert_to_bool
,
'int8'
:
_convert_to_int8
,
'int8'
:
_convert_to_int8
,
'int16'
:
_convert_to_int16
,
'int16'
:
_convert_to_int16
,
'int32'
:
_convert_to_int32
,
'int32'
:
_convert_to_int32
,
...
@@ -3191,6 +3186,10 @@ def mean(input, axis=None, dtype=None, op=False, keepdims=False,
...
@@ -3191,6 +3186,10 @@ def mean(input, axis=None, dtype=None, op=False, keepdims=False,
for
i
in
axis
:
for
i
in
axis
:
s
=
true_div
(
s
,
shp
[
i
])
s
=
true_div
(
s
,
shp
[
i
])
# This can happen when axis is an empty list/tuple
if
s
.
dtype
!=
shp
.
dtype
and
s
.
dtype
in
discrete_dtypes
:
s
=
cast
(
s
,
shp
.
dtype
)
if
dtype
==
'float16'
or
(
dtype
is
None
and
input
.
dtype
==
'float16'
):
if
dtype
==
'float16'
or
(
dtype
is
None
and
input
.
dtype
==
'float16'
):
s
=
cast
(
s
,
'float16'
)
s
=
cast
(
s
,
'float16'
)
s
.
name
=
'mean'
s
.
name
=
'mean'
...
...
theano/tensor/blas.py
浏览文件 @
bf9413c8
...
@@ -1189,7 +1189,7 @@ def _gemm_canonicalize(r, scale, rval, maxclients):
...
@@ -1189,7 +1189,7 @@ def _gemm_canonicalize(r, scale, rval, maxclients):
def
scaled
(
thing
):
def
scaled
(
thing
):
if
scale
==
1
:
if
scale
==
1
:
return
thing
return
thing
if
scale
==
-
1
:
if
scale
==
-
1
and
thing
.
type
.
dtype
!=
'bool'
:
return
-
thing
return
-
thing
else
:
else
:
return
scale
*
thing
return
scale
*
thing
...
...
theano/tensor/elemwise.py
浏览文件 @
bf9413c8
...
@@ -20,12 +20,6 @@ from theano.tensor import elemwise_cgen as cgen
...
@@ -20,12 +20,6 @@ from theano.tensor import elemwise_cgen as cgen
config
=
theano
.
config
config
=
theano
.
config
# We cannot import discrete_dtypes or float_dtypes from tensor.basic yet,
# so we redefine them here
discrete_dtypes
=
list
(
map
(
str
,
scalar
.
discrete_types
))
float_dtypes
=
list
(
map
(
str
,
scalar
.
float_types
))
int_dtypes
=
list
(
map
(
str
,
scalar
.
int_types
))
# tensor depends on elemwise to provide definitions for several ops
# tensor depends on elemwise to provide definitions for several ops
# but elemwise needs to make TensorType instances, so we have these as
# but elemwise needs to make TensorType instances, so we have these as
...
@@ -818,9 +812,9 @@ second dimension
...
@@ -818,9 +812,9 @@ second dimension
# NumPy 1.10.1 raise an error when giving the signature
# NumPy 1.10.1 raise an error when giving the signature
# when the input is complex. So add it only when inputs is int.
# when the input is complex. So add it only when inputs is int.
out_dtype
=
node
.
outputs
[
0
]
.
dtype
out_dtype
=
node
.
outputs
[
0
]
.
dtype
if
(
out_dtype
in
float_dtypes
and
if
(
out_dtype
in
theano
.
tensor
.
float_dtypes
and
isinstance
(
self
.
nfunc
,
numpy
.
ufunc
)
and
isinstance
(
self
.
nfunc
,
numpy
.
ufunc
)
and
node
.
inputs
[
0
]
.
dtype
in
discrete_dtypes
):
node
.
inputs
[
0
]
.
dtype
in
theano
.
tensor
.
discrete_dtypes
):
char
=
numpy
.
sctype2char
(
out_dtype
)
char
=
numpy
.
sctype2char
(
out_dtype
)
sig
=
char
*
node
.
nin
+
'->'
+
char
*
node
.
nout
sig
=
char
*
node
.
nin
+
'->'
+
char
*
node
.
nout
node
.
tag
.
sig
=
sig
node
.
tag
.
sig
=
sig
...
@@ -1076,7 +1070,7 @@ second dimension
...
@@ -1076,7 +1070,7 @@ second dimension
# We loop over the "aliased" outputs, i.e., those that are
# We loop over the "aliased" outputs, i.e., those that are
# inplace (overwrite the contents of one of the inputs) and
# inplace (overwrite the contents of one of the inputs) and
# make the output pointers point to the
u
r corresponding input
# make the output pointers point to the
i
r corresponding input
# pointers.
# pointers.
for
output
,
oname
in
izip
(
aliased_outputs
,
aliased_onames
):
for
output
,
oname
in
izip
(
aliased_outputs
,
aliased_onames
):
olv_index
=
inputs
.
index
(
dmap
[
output
][
0
])
olv_index
=
inputs
.
index
(
dmap
[
output
][
0
])
...
@@ -1641,10 +1635,10 @@ for(int i=0;i<PyArray_NDIM(%(iname)s);i++){
...
@@ -1641,10 +1635,10 @@ for(int i=0;i<PyArray_NDIM(%(iname)s);i++){
task1_code
=
self
.
scalar_op
.
c_code
(
task1_code
=
self
.
scalar_op
.
c_code
(
Apply
(
self
.
scalar_op
,
Apply
(
self
.
scalar_op
,
[
get_scalar_type
(
dtype
=
i
nput
.
type
.
dtype
)
.
make_variable
()
[
get_scalar_type
(
dtype
=
i
v
.
type
.
dtype
)
.
make_variable
()
for
i
nput
in
(
node
.
inputs
*
2
)],
for
i
v
in
(
node
.
inputs
*
2
)],
[
get_scalar_type
(
dtype
=
o
utput
.
type
.
dtype
)
.
make_variable
()
[
get_scalar_type
(
dtype
=
o
v
.
type
.
dtype
)
.
make_variable
()
for
input
in
node
.
outputs
]),
for
ov
in
node
.
outputs
]),
None
,
None
,
[
"
%
s_i"
%
aname
,
"
%
s_i"
%
inames
[
0
]],
[
"
%
s_i"
%
aname
,
"
%
s_i"
%
inames
[
0
]],
[
"
%
s_i"
%
aname
],
[
"
%
s_i"
%
aname
],
...
@@ -1708,18 +1702,16 @@ for(int i=0;i<PyArray_NDIM(%(iname)s);i++){
...
@@ -1708,18 +1702,16 @@ for(int i=0;i<PyArray_NDIM(%(iname)s);i++){
class
All
(
CAReduce
):
class
All
(
CAReduce
):
""" Applies `
bitwise
and` to all the values of a tensor along the
""" Applies `
logical
and` to all the values of a tensor along the
specified axis(es).
specified axis(es).
Equivalent to `CAReduce(scalar.and
\
_, axis=axis)`.
"""
"""
def
__init__
(
self
,
axis
=
None
):
def
__init__
(
self
,
axis
=
None
):
CAReduce
.
__init__
(
self
,
scalar
.
and_
,
axis
)
CAReduce
.
__init__
(
self
,
scalar
.
and_
,
axis
)
def
_output_dtype
(
self
,
idtype
):
def
_output_dtype
(
self
,
idtype
):
return
"
int8
"
return
"
bool
"
def
__str__
(
self
):
def
__str__
(
self
):
if
self
.
axis
is
None
:
if
self
.
axis
is
None
:
...
@@ -1729,7 +1721,7 @@ class All(CAReduce):
...
@@ -1729,7 +1721,7 @@ class All(CAReduce):
def
make_node
(
self
,
input
):
def
make_node
(
self
,
input
):
input
=
as_tensor_variable
(
input
)
input
=
as_tensor_variable
(
input
)
if
input
.
dtype
not
in
[
"int8"
,
"uint8"
]
:
if
input
.
dtype
!=
"bool"
:
input
=
theano
.
tensor
.
neq
(
input
,
0
)
input
=
theano
.
tensor
.
neq
(
input
,
0
)
ret
=
super
(
All
,
self
)
.
make_node
(
input
)
ret
=
super
(
All
,
self
)
.
make_node
(
input
)
return
ret
return
ret
...
@@ -1743,15 +1735,13 @@ class Any(CAReduce):
...
@@ -1743,15 +1735,13 @@ class Any(CAReduce):
""" Applies `bitwise or` to all the values of a tensor along the
""" Applies `bitwise or` to all the values of a tensor along the
specified axis(es).
specified axis(es).
Equivalent to `CAReduce(scalar.or
\
_, axis=axis)`.
"""
"""
def
__init__
(
self
,
axis
=
None
):
def
__init__
(
self
,
axis
=
None
):
CAReduce
.
__init__
(
self
,
scalar
.
or_
,
axis
)
CAReduce
.
__init__
(
self
,
scalar
.
or_
,
axis
)
def
_output_dtype
(
self
,
idtype
):
def
_output_dtype
(
self
,
idtype
):
return
"
int8
"
return
"
bool
"
def
__str__
(
self
):
def
__str__
(
self
):
if
self
.
axis
is
None
:
if
self
.
axis
is
None
:
...
@@ -1761,7 +1751,7 @@ class Any(CAReduce):
...
@@ -1761,7 +1751,7 @@ class Any(CAReduce):
def
make_node
(
self
,
input
):
def
make_node
(
self
,
input
):
input
=
as_tensor_variable
(
input
)
input
=
as_tensor_variable
(
input
)
if
input
.
dtype
not
in
[
"int8"
,
"uint8"
]
:
if
input
.
dtype
!=
"bool"
:
input
=
theano
.
tensor
.
neq
(
input
,
0
)
input
=
theano
.
tensor
.
neq
(
input
,
0
)
ret
=
super
(
Any
,
self
)
.
make_node
(
input
)
ret
=
super
(
Any
,
self
)
.
make_node
(
input
)
return
ret
return
ret
...
@@ -1863,6 +1853,7 @@ class CAReduceDtype(CAReduce):
...
@@ -1863,6 +1853,7 @@ class CAReduceDtype(CAReduce):
if
dtype
is
None
:
if
dtype
is
None
:
# If input has a discrete dtype, upcast it to 64
# If input has a discrete dtype, upcast it to 64
return
dict
(
return
dict
(
bool
=
'int64'
,
int8
=
'int64'
,
int8
=
'int64'
,
int16
=
'int64'
,
int16
=
'int64'
,
int32
=
'int64'
,
int32
=
'int64'
,
...
@@ -1878,6 +1869,7 @@ class CAReduceDtype(CAReduce):
...
@@ -1878,6 +1869,7 @@ class CAReduceDtype(CAReduce):
acc_dtype
=
self
.
acc_dtype
acc_dtype
=
self
.
acc_dtype
if
acc_dtype
is
None
:
if
acc_dtype
is
None
:
return
dict
(
return
dict
(
bool
=
'int64'
,
int8
=
'int64'
,
int8
=
'int64'
,
int16
=
'int64'
,
int16
=
'int64'
,
int32
=
'int64'
,
int32
=
'int64'
,
...
@@ -1990,7 +1982,7 @@ class Sum(CAReduceDtype):
...
@@ -1990,7 +1982,7 @@ class Sum(CAReduceDtype):
out
=
self
(
*
inp
)
out
=
self
(
*
inp
)
if
out
.
dtype
.
find
(
'int'
)
!=
-
1
:
if
out
.
dtype
not
in
theano
.
tensor
.
continuous_dtypes
:
return
[
x
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)]
return
[
x
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)]
gz
,
=
grads
gz
,
=
grads
...
@@ -2101,8 +2093,8 @@ class Prod(CAReduceDtype):
...
@@ -2101,8 +2093,8 @@ class Prod(CAReduceDtype):
out
=
self
(
*
inp
)
out
=
self
(
*
inp
)
if
(
out
.
dtype
in
discrete_dtypes
or
if
(
out
.
dtype
in
theano
.
tensor
.
discrete_dtypes
or
self
.
acc_dtype
in
discrete_dtypes
):
self
.
acc_dtype
in
theano
.
tensor
.
discrete_dtypes
):
# There is an int conversion in the way
# There is an int conversion in the way
return
[
prod_in
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)]
return
[
prod_in
.
zeros_like
(
dtype
=
theano
.
config
.
floatX
)]
...
...
theano/tensor/extra_ops.py
浏览文件 @
bf9413c8
from
__future__
import
absolute_import
,
print_function
,
division
from
__future__
import
absolute_import
,
print_function
,
division
import
numpy
as
np
import
numpy
as
np
import
numpy
import
numpy
import
warnings
from
six.moves
import
xrange
from
six.moves
import
xrange
import
theano
import
theano
...
@@ -561,103 +560,6 @@ def diff(x, n=1, axis=-1):
...
@@ -561,103 +560,6 @@ def diff(x, n=1, axis=-1):
return
DiffOp
(
n
=
n
,
axis
=
axis
)(
x
)
return
DiffOp
(
n
=
n
,
axis
=
axis
)(
x
)
class
BinCountOp
(
theano
.
Op
):
"""
.. note:: Deprecated
Use bincount() instead.
See function bincount for docstring.
"""
compatible_type
=
(
'int8'
,
'int16'
,
'int32'
,
'int64'
,
'uint8'
,
'uint16'
,
'uint32'
,
'uint64'
)
"""Tuple of all compatible dtype for the parameter of this op."""
__props__
=
(
"minlength"
,)
def
__init__
(
self
,
minlength
=
None
):
self
.
minlength
=
minlength
if
minlength
is
not
None
:
numpy_ver
=
[
int
(
n
)
for
n
in
numpy
.
__version__
.
split
(
'.'
)[:
2
]]
if
not
bool
(
numpy_ver
>=
[
1
,
6
]):
raise
NotImplementedError
(
"BinCountOp with minlength attribute"
" requires NumPy 1.6 or higher."
)
def
make_node
(
self
,
x
,
weights
):
warnings
.
warn
((
"Tile op is deprecated, use tile function instead."
),
stacklevel
=
3
)
x
=
basic
.
as_tensor_variable
(
x
)
if
x
.
dtype
not
in
BinCountOp
.
compatible_type
:
raise
TypeError
(
"Inputs dtype must be an integer."
)
# Some dtypes are not supported by numpy's implementation of bincount.
# Until another one is available, we should fail at graph construction
# time, not wait for execution.
int_bitwidth
=
theano
.
configdefaults
.
python_int_bitwidth
()
if
int_bitwidth
==
64
:
numpy_unsupported_dtypes
=
(
'uint64'
,)
if
int_bitwidth
==
32
:
numpy_unsupported_dtypes
=
(
'uint32'
,
'int64'
,
'uint64'
)
intp_bitwidth
=
theano
.
configdefaults
.
local_bitwidth
()
if
intp_bitwidth
==
32
:
out_type
=
basic
.
ivector
()
elif
intp_bitwidth
==
64
:
out_type
=
basic
.
lvector
()
if
x
.
dtype
in
numpy_unsupported_dtypes
:
raise
TypeError
(
(
"Input dtypes
%
s are not supported by numpy.bincount, "
%
numpy_unsupported_dtypes
),
x
.
dtype
)
if
x
.
ndim
!=
1
:
raise
TypeError
(
"Inputs must be of dimension 1."
)
if
weights
is
None
:
weights
=
theano
.
gof
.
Constant
(
theano
.
gof
.
Generic
(),
None
)
else
:
weights
=
basic
.
as_tensor_variable
(
weights
)
out_type
=
basic
.
dvector
()
if
weights
.
ndim
!=
1
:
raise
TypeError
(
"Weights cannot have a number of"
"dimension different of 1."
)
return
theano
.
Apply
(
self
,
[
x
,
weights
],
[
out_type
])
def
perform
(
self
,
node
,
inputs
,
output_storage
):
x
=
inputs
[
0
]
weights
=
inputs
[
1
]
z
=
output_storage
[
0
]
if
weights
is
not
None
and
weights
.
shape
!=
x
.
shape
:
raise
TypeError
(
"All inputs must have the same shape."
)
# Needed for numpy 1.4.1 compatibility
if
self
.
minlength
:
out
=
np
.
bincount
(
x
,
weights
=
weights
,
minlength
=
self
.
minlength
)
else
:
out
=
np
.
bincount
(
x
,
weights
=
weights
)
z
[
0
]
=
theano
.
_asarray
(
out
,
dtype
=
node
.
outputs
[
0
]
.
dtype
)
def
grad
(
self
,
inputs
,
outputs_gradients
):
output
=
self
(
*
inputs
)
if
output
.
dtype
.
find
(
'int'
)
!=
-
1
:
return
[
inp
.
zeros_like
()
.
astype
(
theano
.
config
.
floatX
)
for
inp
in
inputs
]
raise
NotImplementedError
()
def
infer_shape
(
self
,
node
,
ins_shapes
):
x
=
node
.
inputs
[
0
]
m
=
basic
.
max
(
x
)
+
1
if
self
.
minlength
is
not
None
:
m
=
basic
.
maximum
(
m
,
self
.
minlength
)
return
[[
m
]]
def
bincount
(
x
,
weights
=
None
,
minlength
=
None
,
assert_nonneg
=
False
):
def
bincount
(
x
,
weights
=
None
,
minlength
=
None
,
assert_nonneg
=
False
):
"""Count number of occurrences of each value in array of ints.
"""Count number of occurrences of each value in array of ints.
...
@@ -773,7 +675,7 @@ class RepeatOp(theano.Op):
...
@@ -773,7 +675,7 @@ class RepeatOp(theano.Op):
x
=
basic
.
as_tensor_variable
(
x
)
x
=
basic
.
as_tensor_variable
(
x
)
repeats
=
basic
.
as_tensor_variable
(
repeats
)
repeats
=
basic
.
as_tensor_variable
(
repeats
)
if
repeats
.
dtype
not
in
tensor
.
discrete
_dtypes
:
if
repeats
.
dtype
not
in
tensor
.
integer
_dtypes
:
raise
TypeError
(
"repeats.dtype must be an integer."
)
raise
TypeError
(
"repeats.dtype must be an integer."
)
# Some dtypes are not supported by numpy's implementation of repeat.
# Some dtypes are not supported by numpy's implementation of repeat.
...
...
theano/tensor/nnet/sigm.py
浏览文件 @
bf9413c8
...
@@ -75,7 +75,7 @@ class ScalarSigmoid(scalar.UnaryScalarOp):
...
@@ -75,7 +75,7 @@ class ScalarSigmoid(scalar.UnaryScalarOp):
# float16 limits: -11.0, 7.0f
# float16 limits: -11.0, 7.0f
# We use the float32 limits for float16 for now as the
# We use the float32 limits for float16 for now as the
# computation will happen
d
in float32 anyway.
# computation will happen in float32 anyway.
if
(
node
.
inputs
[
0
]
.
type
==
scalar
.
float32
or
if
(
node
.
inputs
[
0
]
.
type
==
scalar
.
float32
or
node
.
inputs
[
0
]
.
type
==
scalar
.
float16
):
node
.
inputs
[
0
]
.
type
==
scalar
.
float16
):
return
"""
%(z)
s =
%(x)
s < -88.0f ? 0.0 :
%(x)
s > 15.0f ? 1.0f : 1.0f /(1.0f + exp(-
%(x)
s));"""
%
locals
()
return
"""
%(z)
s =
%(x)
s < -88.0f ? 0.0 :
%(x)
s > 15.0f ? 1.0f : 1.0f /(1.0f + exp(-
%(x)
s));"""
%
locals
()
...
...
theano/tensor/opt.py
浏览文件 @
bf9413c8
...
@@ -5906,6 +5906,9 @@ def local_mul_specialize(node):
...
@@ -5906,6 +5906,9 @@ def local_mul_specialize(node):
if
new_inputs
:
if
new_inputs
:
if
len
(
new_inputs
)
==
1
:
if
len
(
new_inputs
)
==
1
:
if
neg
:
if
neg
:
if
new_inputs
[
0
]
.
dtype
in
(
T
.
uint_dtypes
+
[
'bool'
]):
return
else
:
rval
=
-
new_inputs
[
0
]
rval
=
-
new_inputs
[
0
]
else
:
else
:
rval
=
new_inputs
[
0
]
rval
=
new_inputs
[
0
]
...
...
theano/tensor/tests/test_basic.py
浏览文件 @
bf9413c8
...
@@ -1206,9 +1206,7 @@ IntDivInplaceTester = makeBroadcastTester(
...
@@ -1206,9 +1206,7 @@ IntDivInplaceTester = makeBroadcastTester(
CeilTester
=
makeBroadcastTester
(
op
=
tensor
.
ceil
,
CeilTester
=
makeBroadcastTester
(
op
=
tensor
.
ceil
,
expected
=
lambda
a
:
numpy
.
asarray
(
expected
=
upcast_float16_ufunc
(
numpy
.
ceil
),
numpy
.
ceil
(
a
),
a
.
dtype
),
good
=
_good_broadcast_unary_normal_no_complex
,
good
=
_good_broadcast_unary_normal_no_complex
,
grad
=
copymod
(
_grad_broadcast_unary_normal
,
grad
=
copymod
(
_grad_broadcast_unary_normal
,
without
=
[
'corner_case'
],
without
=
[
'corner_case'
],
...
@@ -1217,7 +1215,7 @@ CeilTester = makeBroadcastTester(op=tensor.ceil,
...
@@ -1217,7 +1215,7 @@ CeilTester = makeBroadcastTester(op=tensor.ceil,
dtype
=
floatX
)]))
dtype
=
floatX
)]))
CeilInplaceTester
=
makeBroadcastTester
(
op
=
inplace
.
ceil_inplace
,
CeilInplaceTester
=
makeBroadcastTester
(
op
=
inplace
.
ceil_inplace
,
expected
=
lambda
a
:
numpy
.
asarray
(
numpy
.
ceil
(
a
),
a
.
dtype
),
expected
=
upcast_float16_ufunc
(
numpy
.
ceil
),
good
=
_good_broadcast_unary_normal_no_complex
,
good
=
_good_broadcast_unary_normal_no_complex
,
# corner cases includes a lot of integers: points where Ceil is not
# corner cases includes a lot of integers: points where Ceil is not
# continuous (not differentiable)
# continuous (not differentiable)
...
@@ -1229,7 +1227,7 @@ CeilInplaceTester = makeBroadcastTester(op=inplace.ceil_inplace,
...
@@ -1229,7 +1227,7 @@ CeilInplaceTester = makeBroadcastTester(op=inplace.ceil_inplace,
inplace
=
True
)
inplace
=
True
)
FloorTester
=
makeBroadcastTester
(
op
=
tensor
.
floor
,
FloorTester
=
makeBroadcastTester
(
op
=
tensor
.
floor
,
expected
=
lambda
a
:
numpy
.
asarray
(
numpy
.
floor
(
a
),
a
.
dtype
),
expected
=
upcast_float16_ufunc
(
numpy
.
floor
),
good
=
_good_broadcast_unary_normal_no_complex
,
good
=
_good_broadcast_unary_normal_no_complex
,
# XXX: why does grad of floor not give huge values at
# XXX: why does grad of floor not give huge values at
# the integer points in the 'corner_case' in
# the integer points in the 'corner_case' in
...
@@ -1238,20 +1236,20 @@ FloorTester = makeBroadcastTester(op=tensor.floor,
...
@@ -1238,20 +1236,20 @@ FloorTester = makeBroadcastTester(op=tensor.floor,
grad
=
_grad_broadcast_unary_normal
)
grad
=
_grad_broadcast_unary_normal
)
FloorInplaceTester
=
makeBroadcastTester
(
op
=
inplace
.
floor_inplace
,
FloorInplaceTester
=
makeBroadcastTester
(
op
=
inplace
.
floor_inplace
,
expected
=
lambda
a
:
numpy
.
asarray
(
numpy
.
floor
(
a
),
a
.
dtype
),
expected
=
upcast_float16_ufunc
(
numpy
.
floor
),
good
=
_good_broadcast_unary_normal_no_complex
,
good
=
_good_broadcast_unary_normal_no_complex
,
grad
=
_grad_broadcast_unary_normal
,
grad
=
_grad_broadcast_unary_normal
,
inplace
=
True
)
inplace
=
True
)
TruncInplaceTester
=
makeBroadcastTester
(
TruncInplaceTester
=
makeBroadcastTester
(
op
=
inplace
.
trunc_inplace
,
op
=
inplace
.
trunc_inplace
,
expected
=
lambda
a
:
numpy
.
asarray
(
numpy
.
trunc
(
a
),
a
.
dtype
),
expected
=
upcast_float16_ufunc
(
numpy
.
trunc
),
good
=
_good_broadcast_unary_normal_no_complex
,
good
=
_good_broadcast_unary_normal_no_complex
,
inplace
=
True
)
inplace
=
True
)
TruncTester
=
makeBroadcastTester
(
TruncTester
=
makeBroadcastTester
(
op
=
tensor
.
trunc
,
op
=
tensor
.
trunc
,
expected
=
lambda
a
:
numpy
.
asarray
(
numpy
.
trunc
(
a
),
a
.
dtype
),
expected
=
upcast_float16_ufunc
(
numpy
.
trunc
),
good
=
_good_broadcast_unary_normal_no_complex
)
good
=
_good_broadcast_unary_normal_no_complex
)
RoundHalfToEvenTester
=
makeBroadcastTester
(
RoundHalfToEvenTester
=
makeBroadcastTester
(
...
@@ -5005,7 +5003,7 @@ class T_scalarfromtensor(unittest.TestCase):
...
@@ -5005,7 +5003,7 @@ class T_scalarfromtensor(unittest.TestCase):
self
.
assertTrue
(
v
==
56
,
v
)
self
.
assertTrue
(
v
==
56
,
v
)
if
config
.
cast_policy
==
'custom'
:
if
config
.
cast_policy
==
'custom'
:
self
.
assertTrue
(
isinstance
(
v
,
numpy
.
int
16
))
self
.
assertTrue
(
isinstance
(
v
,
numpy
.
int
8
))
elif
config
.
cast_policy
in
(
'numpy'
,
'numpy+floatX'
):
elif
config
.
cast_policy
in
(
'numpy'
,
'numpy+floatX'
):
self
.
assertTrue
(
isinstance
(
self
.
assertTrue
(
isinstance
(
v
,
getattr
(
numpy
,
str
(
numpy
.
asarray
(
56
)
.
dtype
))))
v
,
getattr
(
numpy
,
str
(
numpy
.
asarray
(
56
)
.
dtype
))))
...
@@ -7120,7 +7118,7 @@ class T_as_tensor_variable(unittest.TestCase):
...
@@ -7120,7 +7118,7 @@ class T_as_tensor_variable(unittest.TestCase):
def
test_ndarray_bool
(
self
):
def
test_ndarray_bool
(
self
):
ten
=
as_tensor_variable
(
numpy
.
array
([
True
,
False
,
False
,
True
,
True
]))
ten
=
as_tensor_variable
(
numpy
.
array
([
True
,
False
,
False
,
True
,
True
]))
assert
ten
.
type
.
dtype
==
'
uint8
'
assert
ten
.
type
.
dtype
==
'
bool
'
def
test_memmap
(
self
):
def
test_memmap
(
self
):
inp
=
numpy
.
random
.
rand
(
4
,
3
)
inp
=
numpy
.
random
.
rand
(
4
,
3
)
...
@@ -8192,25 +8190,3 @@ def test_symbolic_slice():
...
@@ -8192,25 +8190,3 @@ def test_symbolic_slice():
a
,
b
=
x
.
shape
[:
2
]
a
,
b
=
x
.
shape
[:
2
]
output
=
a
.
eval
({
x
:
numpy
.
zeros
((
5
,
4
,
3
,
2
),
dtype
=
theano
.
config
.
floatX
)})
output
=
a
.
eval
({
x
:
numpy
.
zeros
((
5
,
4
,
3
,
2
),
dtype
=
theano
.
config
.
floatX
)})
assert
output
==
numpy
.
array
(
5
)
assert
output
==
numpy
.
array
(
5
)
def
test_composite_neg_bool
():
# Check that taking the negation of a Boolean intermediate value
# works correctly with Python code. It used to be an issue because
# `-numpy.bool_(True)` is False and `-numpy.bool_(False)` is True.
x
=
theano
.
tensor
.
vector
()
f
=
theano
.
function
([
x
],
-
(
x
>
0
),
mode
=
theano
.
Mode
(
linker
=
'py'
))
utt
.
assert_allclose
(
f
([
-
1
,
0
,
1
]),
[
0
,
0
,
-
1
])
"""
if __name__ == '__main__':
if 0:
unittest.main()
else:
testcase = FloorInplaceTester
suite = unittest.TestLoader()
suite = suite.loadTestsFromTestCase(testcase)
unittest.TextTestRunner(verbosity=2).run(suite)
"""
theano/tensor/tests/test_elemwise.py
浏览文件 @
bf9413c8
...
@@ -113,42 +113,42 @@ class test_reduce_axes(unittest.TestCase):
...
@@ -113,42 +113,42 @@ class test_reduce_axes(unittest.TestCase):
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
for
a
in
axes
:
for
a
in
axes
:
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
m
=
x
.
sum
(
a
)
x
.
sum
(
a
)
def
test_mean_axes
(
self
):
def
test_mean_axes
(
self
):
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
for
a
in
axes
:
for
a
in
axes
:
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
m
=
x
.
mean
(
a
)
x
.
mean
(
a
)
def
test_max_axes
(
self
):
def
test_max_axes
(
self
):
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
for
a
in
axes
:
for
a
in
axes
:
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
m
=
x
.
max
(
a
)
x
.
max
(
a
)
def
test_min_axes
(
self
):
def
test_min_axes
(
self
):
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
for
a
in
axes
:
for
a
in
axes
:
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
m
=
x
.
min
(
a
)
x
.
min
(
a
)
def
test_argmax_axes
(
self
):
def
test_argmax_axes
(
self
):
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
for
a
in
axes
:
for
a
in
axes
:
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
m
=
x
.
argmax
(
a
)
x
.
argmax
(
a
)
def
test_var_axes
(
self
):
def
test_var_axes
(
self
):
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
axes
=
[
None
,
0
,
1
,
[
0
,
1
],
numpy
.
array
(
1
),
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
[
numpy
.
array
(
0
),
numpy
.
array
(
1
)]]
for
a
in
axes
:
for
a
in
axes
:
x
=
tensor
.
matrix
()
x
=
tensor
.
matrix
()
m
=
x
.
var
(
a
)
x
.
var
(
a
)
class
test_Broadcast
(
unittest
.
TestCase
):
class
test_Broadcast
(
unittest
.
TestCase
):
...
@@ -159,7 +159,7 @@ class test_Broadcast(unittest.TestCase):
...
@@ -159,7 +159,7 @@ class test_Broadcast(unittest.TestCase):
ctype
=
TensorType
ctype
=
TensorType
cop
=
Elemwise
cop
=
Elemwise
openmp_minsize
=
2
*
config
.
openmp_elemwise_minsize
openmp_minsize
=
2
*
config
.
openmp_elemwise_minsize
openmp_minsize_sqrt
=
int
(
math
.
ceil
(
math
.
sqrt
(
openmp_minsize
)))
openmp_minsize_sqrt
=
int
(
math
.
ceil
(
math
.
sqrt
(
openmp_minsize
)))
# The order is important if you change them.
# The order is important if you change them.
...
@@ -346,8 +346,7 @@ class test_CAReduce(unittest_tools.InferShapeTester):
...
@@ -346,8 +346,7 @@ class test_CAReduce(unittest_tools.InferShapeTester):
((
5
,
0
),
(
1
,
)),
((
5
,
0
),
(
1
,
)),
((
5
,
0
),
()),
((
5
,
0
),
()),
((),
None
),
((),
None
),
((),
())
((),
())]
]
type
=
TensorType
type
=
TensorType
def
with_linker
(
self
,
linker
,
scalar_op
=
scalar
.
add
,
dtype
=
"floatX"
,
def
with_linker
(
self
,
linker
,
scalar_op
=
scalar
.
add
,
dtype
=
"floatX"
,
...
@@ -371,7 +370,7 @@ class test_CAReduce(unittest_tools.InferShapeTester):
...
@@ -371,7 +370,7 @@ class test_CAReduce(unittest_tools.InferShapeTester):
f
=
copy
(
linker
)
.
accept
(
FunctionGraph
([
x
],
[
e
]))
.
make_function
()
f
=
copy
(
linker
)
.
accept
(
FunctionGraph
([
x
],
[
e
]))
.
make_function
()
xv
=
numpy
.
asarray
(
numpy
.
random
.
rand
(
*
xsh
))
xv
=
numpy
.
asarray
(
numpy
.
random
.
rand
(
*
xsh
))
if
not
"int"
in
dtype
:
if
"int"
not
in
dtype
:
xv
=
numpy
.
asarray
(
xv
,
dtype
=
dtype
)
xv
=
numpy
.
asarray
(
xv
,
dtype
=
dtype
)
else
:
else
:
xv
=
numpy
.
asarray
(
xv
<
0.5
,
dtype
=
dtype
)
xv
=
numpy
.
asarray
(
xv
<
0.5
,
dtype
=
dtype
)
...
@@ -452,10 +451,6 @@ class test_CAReduce(unittest_tools.InferShapeTester):
...
@@ -452,10 +451,6 @@ class test_CAReduce(unittest_tools.InferShapeTester):
else
:
else
:
self
.
fail
()
self
.
fail
()
else
:
else
:
# numpy.{all,any} return bool type,
# but theano ops return an int8 array instead
if
scalar_op
in
[
scalar
.
and_
,
scalar
.
or_
]:
zv
=
numpy
.
asarray
(
zv
,
dtype
=
'int8'
)
if
test_nan
:
if
test_nan
:
try
:
try
:
self
.
assertTrue
(
self
.
assertTrue
(
...
@@ -614,18 +609,20 @@ class test_Prod(unittest.TestCase):
...
@@ -614,18 +609,20 @@ class test_Prod(unittest.TestCase):
x
=
theano
.
tensor
.
dmatrix
()
x
=
theano
.
tensor
.
dmatrix
()
# sanity check
# sanity check
x2
=
theano
.
tensor
.
dmatrix
()
p
=
Prod
(
axis
=
1
)(
x
)
p
=
Prod
(
axis
=
1
)(
x
)
p2
=
Prod
(
axis
=
1
)(
x2
)
fn
=
theano
.
function
([
x
,
x2
],
[
p
-
p2
],
mode
=
self
.
mode
)
# Uncomment this for debugging if needed
# print "hand computed diff for each row"
# x2 = theano.tensor.dmatrix()
x2_val
=
numpy
.
asarray
([[
1.
,
2.
,
3.003
],
[
0.003
,
5.
,
6
],
[
# p2 = Prod(axis=1)(x2)
0.
,
0.
,
9.01
]])
# fn = theano.function([x, x2], [p - p2], mode=self.mode)
# print fn(x_val, x2_val)
# print("hand computed diff for each row")
fn2
=
theano
.
function
([
x
],
[
theano
.
tensor
.
grad
(
p
.
sum
(),
x
)],
# x2_val = numpy.asarray([[1., 2., 3.003], [0.003, 5., 6], [
mode
=
self
.
mode
)
# 0., 0., 9.01]])
# print "real grad"
# print(fn(x_val, x2_val))
# print fn2(x_val)
# fn2 = theano.function([x], [theano.tensor.grad(p.sum(), x)],
# mode=self.mode)
# print("real grad")
# print(fn2(x_val))
fn3
=
theano
.
function
([
x
],
[
p
],
mode
=
self
.
mode
)
fn3
=
theano
.
function
([
x
],
[
p
],
mode
=
self
.
mode
)
assert
numpy
.
allclose
(
fn3
(
x_val
),
[
6.
,
0.
,
0.
])
assert
numpy
.
allclose
(
fn3
(
x_val
),
[
6.
,
0.
,
0.
])
...
@@ -637,14 +634,14 @@ class test_Prod(unittest.TestCase):
...
@@ -637,14 +634,14 @@ class test_Prod(unittest.TestCase):
# def fn5(x5):
# def fn5(x5):
# return theano.tensor.sqr(Prod(axis=1)(x5))
# return theano.tensor.sqr(Prod(axis=1)(x5))
#x4 = theano.tensor.dmatrix()
#
x4 = theano.tensor.dmatrix()
#p4 = theano.tensor.sqr(Prod(axis=1)(x4))
#
p4 = theano.tensor.sqr(Prod(axis=1)(x4))
#fn4 = theano.function([x4], p4)
#
fn4 = theano.function([x4], p4)
# print
"with sqr"
# print
("with sqr")
# print
fn4(x_val
)
# print
(fn4(x_val)
)
# print
fn4(x2_val
)
# print
(fn4(x2_val)
)
#unittest_tools.verify_grad(fn5, [x_val])
#
unittest_tools.verify_grad(fn5, [x_val])
@attr
(
'slow'
)
@attr
(
'slow'
)
def
test_prod_no_zeros_in_input
(
self
):
def
test_prod_no_zeros_in_input
(
self
):
...
@@ -695,7 +692,7 @@ class test_Prod(unittest.TestCase):
...
@@ -695,7 +692,7 @@ class test_Prod(unittest.TestCase):
x
=
theano
.
tensor
.
dmatrix
()
x
=
theano
.
tensor
.
dmatrix
()
pwz_a1
=
ProdWithoutZeros
(
axis
=
0
)(
x
)
pwz_a1
=
ProdWithoutZeros
(
axis
=
0
)(
x
)
pwz_grad
=
theano
.
grad
(
theano
.
tensor
.
sum
(
pwz_a1
),
x
)
pwz_grad
=
theano
.
grad
(
theano
.
tensor
.
sum
(
pwz_a1
),
x
)
fn_a1
=
theano
.
function
([
x
],
pwz_grad
,
mode
=
self
.
mode
)
theano
.
function
([
x
],
pwz_grad
,
mode
=
self
.
mode
)
@attr
(
'slow'
)
@attr
(
'slow'
)
def
test_other_grad_tests
(
self
):
def
test_other_grad_tests
(
self
):
...
@@ -709,16 +706,19 @@ class test_Prod(unittest.TestCase):
...
@@ -709,16 +706,19 @@ class test_Prod(unittest.TestCase):
p
=
Prod
(
axis
=
1
)
p
=
Prod
(
axis
=
1
)
grad_p
=
theano
.
tensor
.
grad
(
p
(
x
)
.
sum
(),
x
)
grad_p
=
theano
.
tensor
.
grad
(
p
(
x
)
.
sum
(),
x
)
grad_fn
=
theano
.
function
([
x
],
grad_p
,
mode
=
self
.
mode
)
grad_fn
=
theano
.
function
([
x
],
grad_p
,
mode
=
self
.
mode
)
assert
numpy
.
allclose
(
grad_fn
(
x_val1
),
[[
6.
,
3.
,
2.
],
[
30.
,
0.
,
assert
numpy
.
allclose
(
0.
],
[
0.
,
0.
,
0.
]])
grad_fn
(
x_val1
),
assert
numpy
.
allclose
(
grad_fn
(
x_val2
),
[[
0.
,
0.
,
2.
],
[
30.
,
[[
6.
,
3.
,
2.
],
[
30.
,
0.
,
0.
],
[
0.
,
0.
,
0.
]])
0.
,
0.
],
[
72.
,
63.
,
56.
],
[
0.
,
0.
,
90.
]])
assert
numpy
.
allclose
(
grad_fn
(
x_val2
),
[[
0.
,
0.
,
2.
],
[
30.
,
0.
,
0.
],
[
72.
,
63.
,
56.
],
[
0.
,
0.
,
90.
]])
p_axis0
=
Prod
(
axis
=
0
)
p_axis0
=
Prod
(
axis
=
0
)
grad_p_axis0
=
theano
.
tensor
.
grad
(
p_axis0
(
x
)
.
sum
(),
x
)
grad_p_axis0
=
theano
.
tensor
.
grad
(
p_axis0
(
x
)
.
sum
(),
x
)
grad_fn_axis0
=
theano
.
function
([
x
],
grad_p_axis0
,
mode
=
self
.
mode
)
grad_fn_axis0
=
theano
.
function
([
x
],
grad_p_axis0
,
mode
=
self
.
mode
)
assert
numpy
.
allclose
(
grad_fn_axis0
(
x_val2
),
[[
0.
,
400.
,
assert
numpy
.
allclose
(
0.
],
[
63.
,
160.
,
0.
],
[
0.
,
100.
,
0.
],
[
0.
,
80.
,
0.
]])
grad_fn_axis0
(
x_val2
),
[[
0.
,
400.
,
0.
],
[
63.
,
160.
,
0.
],
[
0.
,
100.
,
0.
],
[
0.
,
80.
,
0.
]])
tensor
.
verify_grad
(
p
,
[
x_val1
],
rng
=
rng
,
mode
=
self
.
mode
)
tensor
.
verify_grad
(
p
,
[
x_val1
],
rng
=
rng
,
mode
=
self
.
mode
)
...
@@ -788,12 +788,10 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -788,12 +788,10 @@ class T_reduce_dtype(unittest.TestCase):
op
=
CAReduce
op
=
CAReduce
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
methods
=
[
'sum'
,
'prod'
]
methods
=
[
'sum'
,
'prod'
]
dtypes
=
imap
(
str
,
theano
.
scalar
.
all_types
)
dtypes
=
list
(
imap
(
str
,
theano
.
scalar
.
all_types
)
)
# Test the default dtype of a method().
def
test_reduce_default_dtype
(
self
):
def
test_reduce_default_dtype
(
self
):
"""
Test the default dtype of a method().
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
for
method
in
self
.
methods
:
for
method
in
self
.
methods
:
for
idx
,
dtype
in
enumerate
(
self
.
dtypes
):
for
idx
,
dtype
in
enumerate
(
self
.
dtypes
):
...
@@ -801,6 +799,7 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -801,6 +799,7 @@ class T_reduce_dtype(unittest.TestCase):
x
=
tensor
.
matrix
(
dtype
=
dtype
)
x
=
tensor
.
matrix
(
dtype
=
dtype
)
s
=
getattr
(
x
,
method
)(
axis
=
axis
)
s
=
getattr
(
x
,
method
)(
axis
=
axis
)
assert
s
.
dtype
==
dict
(
assert
s
.
dtype
==
dict
(
bool
=
'int64'
,
int8
=
'int64'
,
int8
=
'int64'
,
int16
=
'int64'
,
int16
=
'int64'
,
int32
=
'int64'
,
int32
=
'int64'
,
...
@@ -818,6 +817,7 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -818,6 +817,7 @@ class T_reduce_dtype(unittest.TestCase):
def
test_reduce_default_acc_dtype
(
self
):
def
test_reduce_default_acc_dtype
(
self
):
# Test the default acc_dtype of a reduce().
# Test the default acc_dtype of a reduce().
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
for
method
in
self
.
methods
:
for
method
in
self
.
methods
:
for
idx
,
dtype
in
enumerate
(
self
.
dtypes
):
for
idx
,
dtype
in
enumerate
(
self
.
dtypes
):
...
@@ -825,12 +825,14 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -825,12 +825,14 @@ class T_reduce_dtype(unittest.TestCase):
x
=
tensor
.
matrix
(
dtype
=
dtype
)
x
=
tensor
.
matrix
(
dtype
=
dtype
)
s
=
getattr
(
x
,
method
)(
axis
=
axis
)
s
=
getattr
(
x
,
method
)(
axis
=
axis
)
assert
s
.
owner
.
op
.
acc_dtype
==
dict
(
assert
s
.
owner
.
op
.
acc_dtype
==
dict
(
bool
=
'int64'
,
int8
=
'int64'
,
int8
=
'int64'
,
int16
=
'int64'
,
int16
=
'int64'
,
int32
=
'int64'
,
int32
=
'int64'
,
uint8
=
'uint64'
,
uint8
=
'uint64'
,
uint16
=
'uint64'
,
uint16
=
'uint64'
,
uint32
=
'uint64'
,
uint32
=
'uint64'
,
float16
=
'float32'
,
float32
=
'float64'
,
float32
=
'float64'
,
complex64
=
'complex128'
,
complex64
=
'complex128'
,
)
.
get
(
dtype
,
dtype
)
)
.
get
(
dtype
,
dtype
)
...
@@ -844,20 +846,18 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -844,20 +846,18 @@ class T_reduce_dtype(unittest.TestCase):
@attr
(
'slow'
)
@attr
(
'slow'
)
def
test_reduce_custom_dtype
(
self
):
def
test_reduce_custom_dtype
(
self
):
"""
# Test the ability to provide your own output dtype for a reduce.
Test the ability to provide your own output dtype for a reduce.
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
idx
=
0
idx
=
0
for
method
in
self
.
methods
:
for
method
in
self
.
methods
:
for
input_dtype
in
self
.
dtypes
:
for
input_dtype
in
self
.
dtypes
:
x
=
tensor
.
matrix
(
dtype
=
input_dtype
)
x
=
tensor
.
matrix
(
dtype
=
input_dtype
)
for
output_dtype
in
self
.
dtypes
:
for
output_dtype
in
self
.
dtypes
:
# If the output is a complex, the gradient of the reduce will
# Only tests case where both input and output are complex.
# cast the complex to the input dtype. We can't call the normal
icomplex
=
input_dtype
.
startswith
(
'complex'
)
# cast on a complex to a not complex as this is ambiguous.
ocomplex
=
output_dtype
.
startswith
(
'complex'
)
if
(
not
input_dtype
.
startswith
(
'complex'
)
and
if
icomplex
!=
ocomplex
:
output_dtype
.
startswith
(
'complex'
)):
continue
continue
axis
=
self
.
axes
[
idx
%
len
(
self
.
axes
)]
axis
=
self
.
axes
[
idx
%
len
(
self
.
axes
)]
...
@@ -866,8 +866,8 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -866,8 +866,8 @@ class T_reduce_dtype(unittest.TestCase):
f
=
theano
.
function
([
x
],
var
,
mode
=
self
.
mode
)
f
=
theano
.
function
([
x
],
var
,
mode
=
self
.
mode
)
topo
=
f
.
maker
.
fgraph
.
toposort
()
topo
=
f
.
maker
.
fgraph
.
toposort
()
assert
[
n
for
n
in
topo
if
isinstance
(
n
.
op
,
self
.
op
)],
(
topo
,
assert
[
n
for
n
in
topo
if
isinstance
(
n
.
op
,
self
.
op
)],
\
dtype
)
(
topo
,
output_
dtype
)
data
=
numpy
.
random
.
rand
(
3
,
4
)
*
10
data
=
numpy
.
random
.
rand
(
3
,
4
)
*
10
data
=
data
.
astype
(
input_dtype
)
data
=
data
.
astype
(
input_dtype
)
f
(
data
)
f
(
data
)
...
@@ -879,9 +879,8 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -879,9 +879,8 @@ class T_reduce_dtype(unittest.TestCase):
idx
+=
1
idx
+=
1
def
test_reduce_custom_acc_dtype
(
self
):
def
test_reduce_custom_acc_dtype
(
self
):
"""
# Test the ability to provide your own accumulator dtype for a reduce.
Test the ability to provide your own accumulator dtype for a reduce.
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
idx
=
0
idx
=
0
for
method
in
self
.
methods
:
for
method
in
self
.
methods
:
...
@@ -901,8 +900,7 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -901,8 +900,7 @@ class T_reduce_dtype(unittest.TestCase):
upcasted_dtype
=
scalar
.
upcast
(
input_dtype
,
acc_dtype
)
upcasted_dtype
=
scalar
.
upcast
(
input_dtype
,
acc_dtype
)
if
(
acc_dtype
==
upcasted_dtype
or
if
(
acc_dtype
==
upcasted_dtype
or
(
input_dtype
in
tensor
.
discrete_dtypes
and
(
input_dtype
in
tensor
.
discrete_dtypes
and
acc_dtype
in
tensor
.
continuous_dtypes
)
acc_dtype
in
tensor
.
continuous_dtypes
)):
):
var
=
getattr
(
x
,
method
)(
acc_dtype
=
acc_dtype
,
var
=
getattr
(
x
,
method
)(
acc_dtype
=
acc_dtype
,
axis
=
axis
)
axis
=
axis
)
assert
var
.
owner
.
op
.
acc_dtype
==
acc_dtype
assert
var
.
owner
.
op
.
acc_dtype
==
acc_dtype
...
@@ -927,8 +925,7 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -927,8 +925,7 @@ class T_reduce_dtype(unittest.TestCase):
s
=
getattr
(
x
,
method
)()
s
=
getattr
(
x
,
method
)()
f
=
theano
.
function
([],
s
,
mode
=
self
.
mode
)
f
=
theano
.
function
([],
s
,
mode
=
self
.
mode
)
topo
=
f
.
maker
.
fgraph
.
toposort
()
topo
=
f
.
maker
.
fgraph
.
toposort
()
assert
[
n
for
n
in
topo
if
isinstance
(
n
.
op
,
self
.
op
)],
(
topo
,
assert
[
n
for
n
in
topo
if
isinstance
(
n
.
op
,
self
.
op
)],
topo
dtype
)
s_val
=
f
()
s_val
=
f
()
# Use extra precision in NumPy to compute the good answer.
# Use extra precision in NumPy to compute the good answer.
ret
=
getattr
(
numpy
.
asarray
([
1e8
,
1
,
-
1e8
],
dtype
=
'float64'
),
ret
=
getattr
(
numpy
.
asarray
([
1e8
,
1
,
-
1e8
],
dtype
=
'float64'
),
...
@@ -938,16 +935,15 @@ class T_reduce_dtype(unittest.TestCase):
...
@@ -938,16 +935,15 @@ class T_reduce_dtype(unittest.TestCase):
class
T_mean_dtype
(
unittest
.
TestCase
):
class
T_mean_dtype
(
unittest
.
TestCase
):
def
test_mean_default_dtype
(
self
):
def
test_mean_default_dtype
(
self
):
"""
# Test the default dtype of a mean().
Test the default dtype of a mean().
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
for
idx
,
dtype
in
enumerate
(
imap
(
str
,
theano
.
scalar
.
all_types
)):
for
idx
,
dtype
in
enumerate
(
imap
(
str
,
theano
.
scalar
.
all_types
)):
axis
=
axes
[
idx
%
len
(
axes
)]
axis
=
axes
[
idx
%
len
(
axes
)]
x
=
tensor
.
matrix
(
dtype
=
dtype
)
x
=
tensor
.
matrix
(
dtype
=
dtype
)
m
=
x
.
mean
(
axis
=
axis
)
m
=
x
.
mean
(
axis
=
axis
)
if
dtype
in
tensor
.
discrete_dtypes
and
axis
!=
[]
:
if
dtype
in
tensor
.
discrete_dtypes
:
assert
m
.
dtype
==
'float64'
assert
m
.
dtype
==
'float64'
else
:
else
:
assert
m
.
dtype
==
dtype
,
(
m
,
m
.
dtype
,
dtype
)
assert
m
.
dtype
==
dtype
,
(
m
,
m
.
dtype
,
dtype
)
...
@@ -958,9 +954,8 @@ class T_mean_dtype(unittest.TestCase):
...
@@ -958,9 +954,8 @@ class T_mean_dtype(unittest.TestCase):
@attr
(
'slow'
)
@attr
(
'slow'
)
def
test_mean_custom_dtype
(
self
):
def
test_mean_custom_dtype
(
self
):
"""
# Test the ability to provide your own output dtype for a mean.
Test the ability to provide your own output dtype for a mean.
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
idx
=
0
idx
=
0
...
@@ -976,7 +971,7 @@ class T_mean_dtype(unittest.TestCase):
...
@@ -976,7 +971,7 @@ class T_mean_dtype(unittest.TestCase):
pass
pass
else
:
else
:
# Executed if no TypeError was raised
# Executed if no TypeError was raised
if
sum_dtype
in
tensor
.
discrete_dtypes
and
axis
!=
[]
:
if
sum_dtype
in
tensor
.
discrete_dtypes
:
assert
mean_var
.
dtype
==
'float64'
,
(
assert
mean_var
.
dtype
==
'float64'
,
(
(
mean_var
.
dtype
,
sum_dtype
))
(
mean_var
.
dtype
,
sum_dtype
))
else
:
else
:
...
@@ -1017,15 +1012,15 @@ class T_mean_dtype(unittest.TestCase):
...
@@ -1017,15 +1012,15 @@ class T_mean_dtype(unittest.TestCase):
class
T_prod_without_zeros_dtype
(
unittest
.
TestCase
):
class
T_prod_without_zeros_dtype
(
unittest
.
TestCase
):
def
test_prod_without_zeros_default_dtype
(
self
):
def
test_prod_without_zeros_default_dtype
(
self
):
"""
# Test the default dtype of a ProdWithoutZeros().
Test the default dtype of a ProdWithoutZeros().
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
for
idx
,
dtype
in
enumerate
(
imap
(
str
,
theano
.
scalar
.
all_types
)):
for
idx
,
dtype
in
enumerate
(
imap
(
str
,
theano
.
scalar
.
all_types
)):
axis
=
axes
[
idx
%
len
(
axes
)]
axis
=
axes
[
idx
%
len
(
axes
)]
x
=
ProdWithoutZeros
(
axis
=
axis
)(
tensor
.
matrix
(
dtype
=
dtype
))
x
=
ProdWithoutZeros
(
axis
=
axis
)(
tensor
.
matrix
(
dtype
=
dtype
))
assert
x
.
dtype
==
dict
(
assert
x
.
dtype
==
dict
(
bool
=
'int64'
,
int8
=
'int64'
,
int8
=
'int64'
,
int16
=
'int64'
,
int16
=
'int64'
,
int32
=
'int64'
,
int32
=
'int64'
,
...
@@ -1035,9 +1030,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
...
@@ -1035,9 +1030,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
)
.
get
(
dtype
,
dtype
)
)
.
get
(
dtype
,
dtype
)
def
test_prod_without_zeros_default_acc_dtype
(
self
):
def
test_prod_without_zeros_default_acc_dtype
(
self
):
"""
# Test the default dtype of a ProdWithoutZeros().
Test the default dtype of a ProdWithoutZeros().
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
for
idx
,
dtype
in
enumerate
(
imap
(
str
,
theano
.
scalar
.
all_types
)):
for
idx
,
dtype
in
enumerate
(
imap
(
str
,
theano
.
scalar
.
all_types
)):
...
@@ -1045,6 +1039,7 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
...
@@ -1045,6 +1039,7 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
x
=
tensor
.
matrix
(
dtype
=
dtype
)
x
=
tensor
.
matrix
(
dtype
=
dtype
)
p
=
ProdWithoutZeros
(
axis
=
axis
)(
x
)
p
=
ProdWithoutZeros
(
axis
=
axis
)(
x
)
assert
p
.
owner
.
op
.
acc_dtype
==
dict
(
assert
p
.
owner
.
op
.
acc_dtype
==
dict
(
bool
=
'int64'
,
int8
=
'int64'
,
int8
=
'int64'
,
int16
=
'int64'
,
int16
=
'int64'
,
int32
=
'int64'
,
int32
=
'int64'
,
...
@@ -1065,9 +1060,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
...
@@ -1065,9 +1060,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
@attr
(
'slow'
)
@attr
(
'slow'
)
def
test_prod_without_zeros_custom_dtype
(
self
):
def
test_prod_without_zeros_custom_dtype
(
self
):
"""
# Test ability to provide your own output dtype for a ProdWithoutZeros().
Test ability to provide your own output dtype for a ProdWithoutZeros().
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
idx
=
0
idx
=
0
...
@@ -1089,9 +1083,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
...
@@ -1089,9 +1083,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
@attr
(
'slow'
)
@attr
(
'slow'
)
def
test_prod_without_zeros_custom_acc_dtype
(
self
):
def
test_prod_without_zeros_custom_acc_dtype
(
self
):
"""
# Test ability to provide your own acc_dtype for a ProdWithoutZeros().
Test ability to provide your own acc_dtype for a ProdWithoutZeros().
"""
# We try multiple axis combinations even though axis should not matter.
# We try multiple axis combinations even though axis should not matter.
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
axes
=
[
None
,
0
,
1
,
[],
[
0
],
[
1
],
[
0
,
1
]]
idx
=
0
idx
=
0
...
@@ -1104,8 +1097,7 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
...
@@ -1104,8 +1097,7 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
upcasted_dtype
=
scalar
.
upcast
(
input_dtype
,
acc_dtype
)
upcasted_dtype
=
scalar
.
upcast
(
input_dtype
,
acc_dtype
)
if
(
acc_dtype
==
upcasted_dtype
or
if
(
acc_dtype
==
upcasted_dtype
or
(
input_dtype
in
tensor
.
discrete_dtypes
and
(
input_dtype
in
tensor
.
discrete_dtypes
and
acc_dtype
in
tensor
.
continuous_dtypes
)
acc_dtype
in
tensor
.
continuous_dtypes
)):
):
prod_woz_var
=
ProdWithoutZeros
(
prod_woz_var
=
ProdWithoutZeros
(
axis
=
axis
,
acc_dtype
=
acc_dtype
)(
x
)
axis
=
axis
,
acc_dtype
=
acc_dtype
)(
x
)
assert
prod_woz_var
.
owner
.
op
.
acc_dtype
==
acc_dtype
assert
prod_woz_var
.
owner
.
op
.
acc_dtype
==
acc_dtype
...
@@ -1118,7 +1110,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
...
@@ -1118,7 +1110,8 @@ class T_prod_without_zeros_dtype(unittest.TestCase):
data
=
data
.
astype
(
input_dtype
)
data
=
data
.
astype
(
input_dtype
)
f
(
data
)
f
(
data
)
else
:
else
:
self
.
assertRaises
(
TypeError
,
self
.
assertRaises
(
TypeError
,
ProdWithoutZeros
(
axis
=
axis
,
acc_dtype
=
acc_dtype
),
ProdWithoutZeros
(
axis
=
axis
,
acc_dtype
=
acc_dtype
),
x
)
x
)
...
@@ -1160,7 +1153,8 @@ class TestElemwise(unittest_tools.InferShapeTester):
...
@@ -1160,7 +1153,8 @@ class TestElemwise(unittest_tools.InferShapeTester):
def
test_infer_shape
(
self
):
def
test_infer_shape
(
self
):
for
s_left
,
s_right
in
[((
5
,
6
),
(
5
,
6
)),
for
s_left
,
s_right
in
[
((
5
,
6
),
(
5
,
6
)),
((
5
,
6
),
(
5
,
1
)),
((
5
,
6
),
(
5
,
1
)),
((
5
,
6
),
(
1
,
6
)),
((
5
,
6
),
(
1
,
6
)),
((
5
,
1
),
(
5
,
6
)),
((
5
,
1
),
(
5
,
6
)),
...
@@ -1175,7 +1169,8 @@ class TestElemwise(unittest_tools.InferShapeTester):
...
@@ -1175,7 +1169,8 @@ class TestElemwise(unittest_tools.InferShapeTester):
t_right
=
TensorType
(
dtype
,
[(
entry
==
1
)
for
entry
in
s_right
])()
t_right
=
TensorType
(
dtype
,
[(
entry
==
1
)
for
entry
in
s_right
])()
t_left_val
=
numpy
.
zeros
(
s_left
,
dtype
=
dtype
)
t_left_val
=
numpy
.
zeros
(
s_left
,
dtype
=
dtype
)
t_right_val
=
numpy
.
zeros
(
s_right
,
dtype
=
dtype
)
t_right_val
=
numpy
.
zeros
(
s_right
,
dtype
=
dtype
)
self
.
_compile_and_check
([
t_left
,
t_right
],
self
.
_compile_and_check
(
[
t_left
,
t_right
],
[
Elemwise
(
scalar
.
add
)(
t_left
,
t_right
)],
[
Elemwise
(
scalar
.
add
)(
t_left
,
t_right
)],
[
t_left_val
,
t_right_val
],
Elemwise
)
[
t_left_val
,
t_right_val
],
Elemwise
)
...
...
theano/tensor/tests/test_extra_ops.py
浏览文件 @
bf9413c8
...
@@ -8,7 +8,7 @@ from theano.tests import unittest_tools as utt
...
@@ -8,7 +8,7 @@ from theano.tests import unittest_tools as utt
from
theano.tensor.extra_ops
import
(
SearchsortedOp
,
searchsorted
,
from
theano.tensor.extra_ops
import
(
SearchsortedOp
,
searchsorted
,
CumsumOp
,
cumsum
,
CumprodOp
,
cumprod
,
CumsumOp
,
cumsum
,
CumprodOp
,
cumprod
,
CpuContiguous
,
cpu_contiguous
,
BinCountOp
,
CpuContiguous
,
cpu_contiguous
,
bincount
,
DiffOp
,
diff
,
squeeze
,
compress
,
bincount
,
DiffOp
,
diff
,
squeeze
,
compress
,
RepeatOp
,
repeat
,
Bartlett
,
bartlett
,
RepeatOp
,
repeat
,
Bartlett
,
bartlett
,
FillDiagonal
,
fill_diagonal
,
FillDiagonal
,
fill_diagonal
,
...
@@ -18,9 +18,6 @@ from theano import tensor as T
...
@@ -18,9 +18,6 @@ from theano import tensor as T
from
theano
import
config
,
tensor
,
function
from
theano
import
config
,
tensor
,
function
from
theano.tests.unittest_tools
import
attr
from
theano.tests.unittest_tools
import
attr
numpy_ver
=
[
int
(
n
)
for
n
in
numpy
.
__version__
.
split
(
'.'
)[:
2
]]
numpy_16
=
bool
(
numpy_ver
>=
[
1
,
6
])
def
test_cpu_contiguous
():
def
test_cpu_contiguous
():
a
=
T
.
fmatrix
(
'a'
)
a
=
T
.
fmatrix
(
'a'
)
...
@@ -218,12 +215,7 @@ class TestCumprodOp(utt.InferShapeTester):
...
@@ -218,12 +215,7 @@ class TestCumprodOp(utt.InferShapeTester):
utt
.
verify_grad
(
self
.
op_class
(
axis
=
axis
),
[
a
])
utt
.
verify_grad
(
self
.
op_class
(
axis
=
axis
),
[
a
])
class
TestBinCountOp
(
utt
.
InferShapeTester
):
class
TestBinCount
(
utt
.
InferShapeTester
):
def
setUp
(
self
):
super
(
TestBinCountOp
,
self
)
.
setUp
()
self
.
op_class
=
BinCountOp
self
.
op
=
BinCountOp
()
def
test_bincountFn
(
self
):
def
test_bincountFn
(
self
):
w
=
T
.
vector
(
'w'
)
w
=
T
.
vector
(
'w'
)
...
@@ -263,84 +255,6 @@ class TestBinCountOp(utt.InferShapeTester):
...
@@ -263,84 +255,6 @@ class TestBinCountOp(utt.InferShapeTester):
f5
=
theano
.
function
([
x
],
bincount
(
x
,
assert_nonneg
=
True
))
f5
=
theano
.
function
([
x
],
bincount
(
x
,
assert_nonneg
=
True
))
self
.
assertRaises
(
AssertionError
,
f5
,
a
)
self
.
assertRaises
(
AssertionError
,
f5
,
a
)
def
test_bincountOp
(
self
):
w
=
T
.
vector
(
'w'
)
for
dtype
in
(
'int8'
,
'int16'
,
'int32'
,
'int64'
,
'uint8'
,
'uint16'
,
'uint32'
,
'uint64'
):
# uint64 always fails
# int64 and uint32 also fail if python int are 32-bit
int_bitwidth
=
theano
.
configdefaults
.
python_int_bitwidth
()
if
int_bitwidth
==
64
:
numpy_unsupported_dtypes
=
(
'uint64'
,)
if
int_bitwidth
==
32
:
numpy_unsupported_dtypes
=
(
'uint32'
,
'int64'
,
'uint64'
)
x
=
T
.
vector
(
'x'
,
dtype
=
dtype
)
if
dtype
in
numpy_unsupported_dtypes
:
self
.
assertRaises
(
TypeError
,
BinCountOp
(),
x
)
else
:
a
=
np
.
random
.
randint
(
1
,
51
,
size
=
(
25
))
.
astype
(
dtype
)
weights
=
np
.
random
.
random
((
25
,))
.
astype
(
config
.
floatX
)
f1
=
theano
.
function
([
x
],
BinCountOp
()(
x
,
weights
=
None
))
f2
=
theano
.
function
([
x
,
w
],
BinCountOp
()(
x
,
weights
=
w
))
assert
(
np
.
bincount
(
a
)
==
f1
(
a
))
.
all
()
assert
np
.
allclose
(
np
.
bincount
(
a
,
weights
=
weights
),
f2
(
a
,
weights
))
if
not
numpy_16
:
continue
f3
=
theano
.
function
([
x
],
BinCountOp
(
minlength
=
23
)(
x
,
weights
=
None
))
f4
=
theano
.
function
([
x
],
BinCountOp
(
minlength
=
5
)(
x
,
weights
=
None
))
assert
(
np
.
bincount
(
a
,
minlength
=
23
)
==
f3
(
a
))
.
all
()
assert
(
np
.
bincount
(
a
,
minlength
=
5
)
==
f4
(
a
))
.
all
()
@attr
(
'slow'
)
def
test_infer_shape
(
self
):
for
dtype
in
tensor
.
discrete_dtypes
:
# uint64 always fails
# int64 and uint32 also fail if python int are 32-bit
int_bitwidth
=
theano
.
configdefaults
.
python_int_bitwidth
()
if
int_bitwidth
==
64
:
numpy_unsupported_dtypes
=
(
'uint64'
,)
if
int_bitwidth
==
32
:
numpy_unsupported_dtypes
=
(
'uint32'
,
'int64'
,
'uint64'
)
x
=
T
.
vector
(
'x'
,
dtype
=
dtype
)
if
dtype
in
numpy_unsupported_dtypes
:
self
.
assertRaises
(
TypeError
,
BinCountOp
(),
x
)
else
:
self
.
_compile_and_check
([
x
],
[
BinCountOp
()(
x
,
None
)],
[
np
.
random
.
randint
(
1
,
51
,
size
=
(
25
,))
.
astype
(
dtype
)],
self
.
op_class
)
weights
=
np
.
random
.
random
((
25
,))
.
astype
(
config
.
floatX
)
self
.
_compile_and_check
([
x
],
[
BinCountOp
()(
x
,
weights
=
weights
)],
[
np
.
random
.
randint
(
1
,
51
,
size
=
(
25
,))
.
astype
(
dtype
)],
self
.
op_class
)
if
not
numpy_16
:
continue
self
.
_compile_and_check
([
x
],
[
BinCountOp
(
minlength
=
60
)(
x
,
weights
=
weights
)],
[
np
.
random
.
randint
(
1
,
51
,
size
=
(
25
,))
.
astype
(
dtype
)],
self
.
op_class
)
self
.
_compile_and_check
([
x
],
[
BinCountOp
(
minlength
=
5
)(
x
,
weights
=
weights
)],
[
np
.
random
.
randint
(
1
,
51
,
size
=
(
25
,))
.
astype
(
dtype
)],
self
.
op_class
)
class
TestDiffOp
(
utt
.
InferShapeTester
):
class
TestDiffOp
(
utt
.
InferShapeTester
):
nb
=
10
# Number of time iterating for n
nb
=
10
# Number of time iterating for n
...
@@ -510,7 +424,7 @@ class TestRepeatOp(utt.InferShapeTester):
...
@@ -510,7 +424,7 @@ class TestRepeatOp(utt.InferShapeTester):
a
=
np
.
random
.
random
((
10
,
)
*
ndim
)
.
astype
(
config
.
floatX
)
a
=
np
.
random
.
random
((
10
,
)
*
ndim
)
.
astype
(
config
.
floatX
)
for
axis
in
self
.
_possible_axis
(
ndim
):
for
axis
in
self
.
_possible_axis
(
ndim
):
for
dtype
in
tensor
.
discrete
_dtypes
:
for
dtype
in
tensor
.
integer
_dtypes
:
r_var
=
T
.
scalar
(
dtype
=
dtype
)
r_var
=
T
.
scalar
(
dtype
=
dtype
)
r
=
numpy
.
asarray
(
3
,
dtype
=
dtype
)
r
=
numpy
.
asarray
(
3
,
dtype
=
dtype
)
if
(
dtype
==
'uint64'
or
if
(
dtype
==
'uint64'
or
...
@@ -569,7 +483,7 @@ class TestRepeatOp(utt.InferShapeTester):
...
@@ -569,7 +483,7 @@ class TestRepeatOp(utt.InferShapeTester):
a
=
np
.
random
.
random
(
shp
)
.
astype
(
config
.
floatX
)
a
=
np
.
random
.
random
(
shp
)
.
astype
(
config
.
floatX
)
for
axis
in
self
.
_possible_axis
(
ndim
):
for
axis
in
self
.
_possible_axis
(
ndim
):
for
dtype
in
tensor
.
discrete
_dtypes
:
for
dtype
in
tensor
.
integer
_dtypes
:
r_var
=
T
.
scalar
(
dtype
=
dtype
)
r_var
=
T
.
scalar
(
dtype
=
dtype
)
r
=
numpy
.
asarray
(
3
,
dtype
=
dtype
)
r
=
numpy
.
asarray
(
3
,
dtype
=
dtype
)
if
dtype
in
self
.
numpy_unsupported_dtypes
:
if
dtype
in
self
.
numpy_unsupported_dtypes
:
...
@@ -798,13 +712,11 @@ class test_Unique(utt.InferShapeTester):
...
@@ -798,13 +712,11 @@ class test_Unique(utt.InferShapeTester):
self
.
ops
=
[
Unique
(),
self
.
ops
=
[
Unique
(),
Unique
(
True
),
Unique
(
True
),
Unique
(
False
,
True
),
Unique
(
False
,
True
),
Unique
(
True
,
True
)]
Unique
(
True
,
True
),
if
bool
(
numpy_ver
>=
[
1
,
9
]):
self
.
ops
.
extend
([
Unique
(
False
,
False
,
True
),
Unique
(
False
,
False
,
True
),
Unique
(
True
,
False
,
True
),
Unique
(
True
,
False
,
True
),
Unique
(
False
,
True
,
True
),
Unique
(
False
,
True
,
True
),
Unique
(
True
,
True
,
True
)])
Unique
(
True
,
True
,
True
)]
def
test_basic_vector
(
self
):
def
test_basic_vector
(
self
):
"""
"""
...
@@ -816,13 +728,11 @@ class test_Unique(utt.InferShapeTester):
...
@@ -816,13 +728,11 @@ class test_Unique(utt.InferShapeTester):
list_outs_expected
=
[[
np
.
unique
(
inp
)],
list_outs_expected
=
[[
np
.
unique
(
inp
)],
np
.
unique
(
inp
,
True
),
np
.
unique
(
inp
,
True
),
np
.
unique
(
inp
,
False
,
True
),
np
.
unique
(
inp
,
False
,
True
),
np
.
unique
(
inp
,
True
,
True
)]
np
.
unique
(
inp
,
True
,
True
),
if
bool
(
numpy_ver
>=
[
1
,
9
]):
list_outs_expected
.
extend
([
np
.
unique
(
inp
,
False
,
False
,
True
),
np
.
unique
(
inp
,
False
,
False
,
True
),
np
.
unique
(
inp
,
True
,
False
,
True
),
np
.
unique
(
inp
,
True
,
False
,
True
),
np
.
unique
(
inp
,
False
,
True
,
True
),
np
.
unique
(
inp
,
False
,
True
,
True
),
np
.
unique
(
inp
,
True
,
True
,
True
)])
np
.
unique
(
inp
,
True
,
True
,
True
)]
for
op
,
outs_expected
in
zip
(
self
.
ops
,
list_outs_expected
):
for
op
,
outs_expected
in
zip
(
self
.
ops
,
list_outs_expected
):
f
=
theano
.
function
(
inputs
=
[
x
],
outputs
=
op
(
x
,
return_list
=
True
))
f
=
theano
.
function
(
inputs
=
[
x
],
outputs
=
op
(
x
,
return_list
=
True
))
outs
=
f
(
inp
)
outs
=
f
(
inp
)
...
@@ -839,13 +749,11 @@ class test_Unique(utt.InferShapeTester):
...
@@ -839,13 +749,11 @@ class test_Unique(utt.InferShapeTester):
list_outs_expected
=
[[
np
.
unique
(
inp
)],
list_outs_expected
=
[[
np
.
unique
(
inp
)],
np
.
unique
(
inp
,
True
),
np
.
unique
(
inp
,
True
),
np
.
unique
(
inp
,
False
,
True
),
np
.
unique
(
inp
,
False
,
True
),
np
.
unique
(
inp
,
True
,
True
)]
np
.
unique
(
inp
,
True
,
True
),
if
bool
(
numpy_ver
>=
[
1
,
9
]):
list_outs_expected
.
extend
([
np
.
unique
(
inp
,
False
,
False
,
True
),
np
.
unique
(
inp
,
False
,
False
,
True
),
np
.
unique
(
inp
,
True
,
False
,
True
),
np
.
unique
(
inp
,
True
,
False
,
True
),
np
.
unique
(
inp
,
False
,
True
,
True
),
np
.
unique
(
inp
,
False
,
True
,
True
),
np
.
unique
(
inp
,
True
,
True
,
True
)])
np
.
unique
(
inp
,
True
,
True
,
True
)]
for
op
,
outs_expected
in
zip
(
self
.
ops
,
list_outs_expected
):
for
op
,
outs_expected
in
zip
(
self
.
ops
,
list_outs_expected
):
f
=
theano
.
function
(
inputs
=
[
x
],
outputs
=
op
(
x
,
return_list
=
True
))
f
=
theano
.
function
(
inputs
=
[
x
],
outputs
=
op
(
x
,
return_list
=
True
))
outs
=
f
(
inp
)
outs
=
f
(
inp
)
...
...
theano/tensor/type.py
浏览文件 @
bf9413c8
...
@@ -255,6 +255,7 @@ class TensorType(Type):
...
@@ -255,6 +255,7 @@ class TensorType(Type):
'float16'
:
(
float
,
'npy_float16'
,
'NPY_FLOAT16'
),
'float16'
:
(
float
,
'npy_float16'
,
'NPY_FLOAT16'
),
'float32'
:
(
float
,
'npy_float32'
,
'NPY_FLOAT32'
),
'float32'
:
(
float
,
'npy_float32'
,
'NPY_FLOAT32'
),
'float64'
:
(
float
,
'npy_float64'
,
'NPY_FLOAT64'
),
'float64'
:
(
float
,
'npy_float64'
,
'NPY_FLOAT64'
),
'bool'
:
(
bool
,
'npy_bool'
,
'NPY_BOOL'
),
'uint8'
:
(
int
,
'npy_uint8'
,
'NPY_UINT8'
),
'uint8'
:
(
int
,
'npy_uint8'
,
'NPY_UINT8'
),
'int8'
:
(
int
,
'npy_int8'
,
'NPY_INT8'
),
'int8'
:
(
int
,
'npy_int8'
,
'NPY_INT8'
),
'uint16'
:
(
int
,
'npy_uint16'
,
'NPY_UINT16'
),
'uint16'
:
(
int
,
'npy_uint16'
,
'NPY_UINT16'
),
...
@@ -340,15 +341,9 @@ class TensorType(Type):
...
@@ -340,15 +341,9 @@ class TensorType(Type):
return
False
return
False
if
a
.
dtype
!=
b
.
dtype
:
if
a
.
dtype
!=
b
.
dtype
:
return
False
return
False
if
'int'
in
str
(
a
.
dtype
)
:
if
str
(
a
.
dtype
)
not
in
theano
.
tensor
.
continuous_dtypes
:
return
numpy
.
all
(
a
==
b
)
return
numpy
.
all
(
a
==
b
)
else
:
else
:
# work around a numpy.allclose bug:
# http://projects.scipy.org/numpy/ticket/1672
if
a
.
ndim
==
0
and
numpy
.
isinf
(
a
):
a
=
a
.
reshape
(
1
)
b
=
b
.
reshape
(
1
)
cmp
=
theano
.
tensor
.
basic
.
_allclose
(
a
,
b
,
rtol
=
rtol
,
atol
=
atol
)
cmp
=
theano
.
tensor
.
basic
.
_allclose
(
a
,
b
,
rtol
=
rtol
,
atol
=
atol
)
if
cmp
:
if
cmp
:
# Numpy claims they are close, this is good enough for us.
# Numpy claims they are close, this is good enough for us.
...
...
theano/tensor/var.py
浏览文件 @
bf9413c8
...
@@ -470,19 +470,17 @@ class _tensor_py_operators(object):
...
@@ -470,19 +470,17 @@ class _tensor_py_operators(object):
def
check_bool
(
args_el
):
def
check_bool
(
args_el
):
try
:
try
:
if
isinstance
(
args_el
,
(
numpy
.
bool_
,
bool
))
or
\
if
(
isinstance
(
args_el
,
(
numpy
.
bool_
,
bool
))
or
args_el
.
dtype
==
'int8'
or
args_el
.
dtype
==
'uint8'
:
args_el
.
dtype
==
'bool'
)
:
raise
TypeError
(
(
'TensorType does not support boolean '
raise
TypeError
(
'TensorType does not support boolean '
'mask for indexing such as tensor[x==0]. '
'mask for indexing such as tensor[x==0]. '
'Instead you can use non_zeros() such as '
'Instead you can use non_zeros() such as '
'tensor[(x == 0).nonzeros()]. '
'tensor[(x == 0).nonzeros()]. '
)
'If you are indexing on purpose with an '
'int8, please cast it to int16.'
))
except
AttributeError
:
except
AttributeError
:
pass
pass
if
not
isinstance
(
args_el
,
theano
.
tensor
.
Variable
)
and
\
if
(
not
isinstance
(
args_el
,
theano
.
tensor
.
Variable
)
and
isinstance
(
args_el
,
collections
.
Iterable
):
isinstance
(
args_el
,
collections
.
Iterable
)
):
for
el
in
args_el
:
for
el
in
args_el
:
check_bool
(
el
)
check_bool
(
el
)
...
...
theano/tests/test_flake8.py
浏览文件 @
bf9413c8
...
@@ -56,7 +56,6 @@ whitelist_flake8 = [
...
@@ -56,7 +56,6 @@ whitelist_flake8 = [
"tensor/tests/test_opt.py"
,
"tensor/tests/test_opt.py"
,
"tensor/tests/test_basic.py"
,
"tensor/tests/test_basic.py"
,
"tensor/tests/test_blas.py"
,
"tensor/tests/test_blas.py"
,
"tensor/tests/test_elemwise.py"
,
"tensor/tests/test_merge.py"
,
"tensor/tests/test_merge.py"
,
"tensor/tests/test_gc.py"
,
"tensor/tests/test_gc.py"
,
"tensor/tests/test_complex.py"
,
"tensor/tests/test_complex.py"
,
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论