Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
P
pytensor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
testgroup
pytensor
Commits
ee6a7995
提交
ee6a7995
authored
8月 12, 2015
作者:
Iban Harlouchet
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
numpydoc for theano/gof/cmodule.py
上级
d8835a5f
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
236 行增加
和
121 行删除
+236
-121
cmodule.py
theano/gof/cmodule.py
+236
-121
没有找到文件。
theano/gof/cmodule.py
浏览文件 @
ee6a7995
"""Generate and compile C modules for Python,
"""
"""
Generate and compile C modules for Python.
"""
from
__future__
import
print_function
from
__future__
import
print_function
import
atexit
import
atexit
...
@@ -81,16 +82,23 @@ import_time = 0
...
@@ -81,16 +82,23 @@ import_time = 0
class
MissingGXX
(
Exception
):
class
MissingGXX
(
Exception
):
"""
"""
This error is raised when we try to generate c code,
This error is raised when we try to generate c code,
but g++ is not available
but g++ is not available.
"""
"""
pass
pass
def
debug_counter
(
name
,
every
=
1
):
def
debug_counter
(
name
,
every
=
1
):
"""Debug counter to know how often we go through some piece of code.
"""
Debug counter to know how often we go through some piece of code.
This is a utility function one may use when debugging. Usage example:
This is a utility function one may use when debugging.
Example
-------
debug_counter('I want to know how often I run this line')
debug_counter('I want to know how often I run this line')
"""
"""
setattr
(
debug_counter
,
name
,
getattr
(
debug_counter
,
name
,
0
)
+
1
)
setattr
(
debug_counter
,
name
,
getattr
(
debug_counter
,
name
,
0
)
+
1
)
n
=
getattr
(
debug_counter
,
name
)
n
=
getattr
(
debug_counter
,
name
)
...
@@ -99,27 +107,36 @@ def debug_counter(name, every=1):
...
@@ -99,27 +107,36 @@ def debug_counter(name, every=1):
class
ExtFunction
(
object
):
class
ExtFunction
(
object
):
"""A C function to put into a DynamicModule """
"""
A C function to put into a DynamicModule.
"""
name
=
""
name
=
""
"""string - function's name"""
"""
str - function's name.
"""
code_block
=
""
code_block
=
""
"""string - the entire code for the function.
"""
str - the entire code for the function.
Has the form ``static PyObject* <name>([...]){ ... }
Has the form ``static PyObject* <name>([...]){ ... }
See Python's C API Reference for how to write c functions for python
See Python's C API Reference for how to write c functions for python
modules.
modules.
"""
method
=
""
"""
"""
str - calling method for this function (i.e. 'METH_VARARGS', 'METH_NOARGS')
method
=
""
"""
"""
str - calling method for this function (i.e. 'METH_VARARGS', 'METH_NOARGS').
"""
doc
=
""
doc
=
""
"""str - documentation string for this function"""
"""
str - documentation string for this function.
"""
def
__init__
(
self
,
name
,
code_block
,
method
,
doc
=
"undocumented"
):
def
__init__
(
self
,
name
,
code_block
,
method
,
doc
=
"undocumented"
):
self
.
name
=
name
self
.
name
=
name
...
@@ -132,6 +149,7 @@ class ExtFunction(object):
...
@@ -132,6 +149,7 @@ class ExtFunction(object):
Returns the signature for this function.
Returns the signature for this function.
It goes into the DynamicModule's method table.
It goes into the DynamicModule's method table.
"""
"""
return
'
\t
{"
%
s",
%
s,
%
s, "
%
s"}'
%
(
return
'
\t
{"
%
s",
%
s,
%
s, "
%
s"}'
%
(
self
.
name
,
self
.
name
,
self
.
method
,
self
.
doc
)
self
.
name
,
self
.
name
,
self
.
method
,
self
.
doc
)
...
@@ -244,7 +262,10 @@ static struct PyModuleDef moduledef = {{
...
@@ -244,7 +262,10 @@ static struct PyModuleDef moduledef = {{
return
rval
return
rval
def
list_code
(
self
,
ofile
=
sys
.
stdout
):
def
list_code
(
self
,
ofile
=
sys
.
stdout
):
"""Print out the code with line numbers to `ofile` """
"""
Print out the code with line numbers to `ofile`.
"""
for
i
,
line
in
enumerate
(
self
.
code
()
.
split
(
'
\n
'
)):
for
i
,
line
in
enumerate
(
self
.
code
()
.
split
(
'
\n
'
)):
print
((
'
%4
i'
%
(
i
+
1
)),
line
,
file
=
ofile
)
print
((
'
%4
i'
%
(
i
+
1
)),
line
,
file
=
ofile
)
ofile
.
flush
()
ofile
.
flush
()
...
@@ -253,15 +274,21 @@ static struct PyModuleDef moduledef = {{
...
@@ -253,15 +274,21 @@ static struct PyModuleDef moduledef = {{
def
dlimport
(
fullpath
,
suffix
=
None
):
def
dlimport
(
fullpath
,
suffix
=
None
):
"""Dynamically load a .so, .pyd, .dll, or .py file
"""
Dynamically load a .so, .pyd, .dll, or .py file.
:type fullpath: string
Parameters
:param fullpath: a fully-qualified path do a compiled python module
----------
:param suffix: a suffix to strip from the end of fullpath to get the
fullpath : str
import name
A fully-qualified path do a compiled python module.
:type suffix: string
suffix : str
A suffix to strip from the end of fullpath to get the
import name.
:returns: the dynamically loaded module (from __import__)
Returns
-------
object
The dynamically loaded module (from __import__).
"""
"""
if
not
os
.
path
.
isabs
(
fullpath
):
if
not
os
.
path
.
isabs
(
fullpath
):
...
@@ -310,7 +337,8 @@ def dlimport_workdir(basedir):
...
@@ -310,7 +337,8 @@ def dlimport_workdir(basedir):
"""
"""
Return a directory where you should put your .so file for dlimport
Return a directory where you should put your .so file for dlimport
to be able to load it, given a basedir which should normally be
to be able to load it, given a basedir which should normally be
config.compiledir
config.compiledir.
"""
"""
return
tempfile
.
mkdtemp
(
dir
=
basedir
)
return
tempfile
.
mkdtemp
(
dir
=
basedir
)
...
@@ -319,6 +347,7 @@ def last_access_time(path):
...
@@ -319,6 +347,7 @@ def last_access_time(path):
"""
"""
Return the number of seconds since the epoch of the last access of a
Return the number of seconds since the epoch of the last access of a
given file.
given file.
"""
"""
return
os
.
stat
(
path
)[
stat
.
ST_ATIME
]
return
os
.
stat
(
path
)[
stat
.
ST_ATIME
]
...
@@ -327,6 +356,7 @@ def module_name_from_dir(dirname, err=True, files=None):
...
@@ -327,6 +356,7 @@ def module_name_from_dir(dirname, err=True, files=None):
"""
"""
Scan the contents of a cache directory and return full path of the
Scan the contents of a cache directory and return full path of the
dynamic lib in it.
dynamic lib in it.
"""
"""
if
files
is
None
:
if
files
is
None
:
files
=
os
.
listdir
(
dirname
)
files
=
os
.
listdir
(
dirname
)
...
@@ -349,6 +379,7 @@ def is_same_entry(entry_1, entry_2):
...
@@ -349,6 +379,7 @@ def is_same_entry(entry_1, entry_2):
- They are equal.
- They are equal.
- Their real paths are equal.
- Their real paths are equal.
- They share the same temporary work directory and module file name.
- They share the same temporary work directory and module file name.
"""
"""
if
entry_1
==
entry_2
:
if
entry_1
==
entry_2
:
return
True
return
True
...
@@ -372,6 +403,7 @@ def get_module_hash(src_code, key):
...
@@ -372,6 +403,7 @@ def get_module_hash(src_code, key):
3. The compiler options defined in `key` (command line parameters and
3. The compiler options defined in `key` (command line parameters and
libraries to link against).
libraries to link against).
4. The NumPy ABI version.
4. The NumPy ABI version.
"""
"""
# `to_hash` will contain any element such that we know for sure that if
# `to_hash` will contain any element such that we know for sure that if
# it changes, then the module hash should be different.
# it changes, then the module hash should be different.
...
@@ -425,6 +457,7 @@ def get_safe_part(key):
...
@@ -425,6 +457,7 @@ def get_safe_part(key):
It is used to reduce the amount of key comparisons one has to go through
It is used to reduce the amount of key comparisons one has to go through
in order to find broken keys (i.e. keys with bad implementations of __eq__
in order to find broken keys (i.e. keys with bad implementations of __eq__
or __hash__).
or __hash__).
"""
"""
version
=
key
[
0
]
version
=
key
[
0
]
# This function should only be called on versioned keys.
# This function should only be called on versioned keys.
...
@@ -442,35 +475,43 @@ def get_safe_part(key):
...
@@ -442,35 +475,43 @@ def get_safe_part(key):
class
KeyData
(
object
):
class
KeyData
(
object
):
"""Used to store the key information in the cache."""
def
__init__
(
self
,
keys
,
module_hash
,
key_pkl
,
entry
):
"""
"""
Constructor.
Used to store the key information in the cache.
:param keys: Set of keys that are associated to the exact same module.
Parameters
----------
:param module_hash: Hash identifying the module (it should hash both
keys
the code and the compilation options).
Set of keys that are associated to the exact same module.
module_hash
:param key_pkl: Path to the file in which this KeyData object should be
Hash identifying the module (it should hash both the code and the
compilation options).
key_pkl
Path to the file in which this KeyData object should be
pickled.
pickled.
"""
"""
def
__init__
(
self
,
keys
,
module_hash
,
key_pkl
,
entry
):
self
.
keys
=
keys
self
.
keys
=
keys
self
.
module_hash
=
module_hash
self
.
module_hash
=
module_hash
self
.
key_pkl
=
key_pkl
self
.
key_pkl
=
key_pkl
self
.
entry
=
entry
self
.
entry
=
entry
def
add_key
(
self
,
key
,
save_pkl
=
True
):
def
add_key
(
self
,
key
,
save_pkl
=
True
):
"""Add a key to self.keys, and update pickled file if asked to."""
"""
Add a key to self.keys, and update pickled file if asked to.
"""
assert
key
not
in
self
.
keys
assert
key
not
in
self
.
keys
self
.
keys
.
add
(
key
)
self
.
keys
.
add
(
key
)
if
save_pkl
:
if
save_pkl
:
self
.
save_pkl
()
self
.
save_pkl
()
def
remove_key
(
self
,
key
,
save_pkl
=
True
):
def
remove_key
(
self
,
key
,
save_pkl
=
True
):
"""Remove a key from self.keys, and update pickled file if asked to."""
"""
Remove a key from self.keys, and update pickled file if asked to.
"""
self
.
keys
.
remove
(
key
)
self
.
keys
.
remove
(
key
)
if
save_pkl
:
if
save_pkl
:
self
.
save_pkl
()
self
.
save_pkl
()
...
@@ -481,6 +522,7 @@ class KeyData(object):
...
@@ -481,6 +522,7 @@ class KeyData(object):
May raise a cPickle.PicklingError if such an exception is raised at
May raise a cPickle.PicklingError if such an exception is raised at
pickle time (in which case a warning is also displayed).
pickle time (in which case a warning is also displayed).
"""
"""
# Note that writing in binary mode is important under Windows.
# Note that writing in binary mode is important under Windows.
try
:
try
:
...
@@ -493,7 +535,10 @@ class KeyData(object):
...
@@ -493,7 +535,10 @@ class KeyData(object):
raise
raise
def
get_entry
(
self
):
def
get_entry
(
self
):
"""Return path to the module file."""
"""
Return path to the module file.
"""
# TODO This method may be removed in the future (e.g. in 0.5) since
# TODO This method may be removed in the future (e.g. in 0.5) since
# its only purpose is to make sure that old KeyData objects created
# its only purpose is to make sure that old KeyData objects created
# before the 'entry' field was added are properly handled.
# before the 'entry' field was added are properly handled.
...
@@ -508,6 +553,7 @@ class KeyData(object):
...
@@ -508,6 +553,7 @@ class KeyData(object):
Note that broken keys will not appear in the keys field, so we also
Note that broken keys will not appear in the keys field, so we also
manually look for keys associated to the same entry, unless
manually look for keys associated to the same entry, unless
do_manual_check is False.
do_manual_check is False.
"""
"""
entry
=
self
.
get_entry
()
entry
=
self
.
get_entry
()
for
key
in
self
.
keys
:
for
key
in
self
.
keys
:
...
@@ -522,7 +568,8 @@ class KeyData(object):
...
@@ -522,7 +568,8 @@ class KeyData(object):
class
ModuleCache
(
object
):
class
ModuleCache
(
object
):
"""Interface to the cache of dynamically compiled modules on disk
"""
Interface to the cache of dynamically compiled modules on disk.
Note that this interface does not assume exclusive use of the cache
Note that this interface does not assume exclusive use of the cache
directory. It is built to handle the case where multiple programs are also
directory. It is built to handle the case where multiple programs are also
...
@@ -569,43 +616,58 @@ class ModuleCache(object):
...
@@ -569,43 +616,58 @@ class ModuleCache(object):
- They share the same C code.
- They share the same C code.
These three elements uniquely identify a module, and are summarized
These three elements uniquely identify a module, and are summarized
in a single "module hash".
in a single "module hash".
Parameters
----------
check_for_broken_eq
A bad __eq__ implementation can break this cache mechanism.
This option turns on a not-too-expensive sanity check every
time a new key is added to the cache.
do_refresh : bool
If True, then the ``refresh`` method will be called
in the constructor.
"""
"""
dirname
=
""
dirname
=
""
"""The working directory that is managed by this interface"""
"""
The working directory that is managed by this interface.
"""
module_from_name
=
{}
module_from_name
=
{}
"""maps a module filename to the loaded module object"""
"""
Maps a module filename to the loaded module object.
"""
entry_from_key
=
{}
entry_from_key
=
{}
"""Maps keys to the filename of a .so/.pyd.
"""
"""
Maps keys to the filename of a .so/.pyd.
"""
similar_keys
=
{}
similar_keys
=
{}
"""Maps a part-of-key to all keys that share this same part."""
"""
Maps a part-of-key to all keys that share this same part.
"""
module_hash_to_key_data
=
{}
module_hash_to_key_data
=
{}
"""Maps a module hash to its corresponding KeyData object."""
"""
Maps a module hash to its corresponding KeyData object.
"""
stats
=
[]
stats
=
[]
"""
"""
A list with counters for the number of hits, loads, compiles issued by
A list with counters for the number of hits, loads, compiles issued by
module_from_key()
module_from_key().
"""
"""
loaded_key_pkl
=
set
()
loaded_key_pkl
=
set
()
"""set of all key.pkl files that have been loaded.
"""
"""
Set of all key.pkl files that have been loaded.
def
__init__
(
self
,
dirname
,
check_for_broken_eq
=
True
,
do_refresh
=
True
):
"""
"""
:param check_for_broken_eq: A bad __eq__ implementation can break this
cache mechanism. This option turns on a not-too-expensive sanity check
every time a new key is added to the cache.
:param do_refresh: If True, then the ``refresh`` method will be called
def
__init__
(
self
,
dirname
,
check_for_broken_eq
=
True
,
do_refresh
=
True
):
in the constructor.
"""
self
.
dirname
=
dirname
self
.
dirname
=
dirname
self
.
module_from_name
=
dict
(
self
.
module_from_name
)
self
.
module_from_name
=
dict
(
self
.
module_from_name
)
self
.
entry_from_key
=
dict
(
self
.
entry_from_key
)
self
.
entry_from_key
=
dict
(
self
.
entry_from_key
)
...
@@ -624,11 +686,13 @@ class ModuleCache(object):
...
@@ -624,11 +686,13 @@ class ModuleCache(object):
The default age threshold (in seconds) for cache files we want to use.
The default age threshold (in seconds) for cache files we want to use.
Older modules will be deleted in ``clear_old``.
Older modules will be deleted in ``clear_old``.
"""
"""
def
_get_module
(
self
,
name
):
def
_get_module
(
self
,
name
):
"""
"""
Fetch a compiled module from the loaded cache or the disk.
Fetch a compiled module from the loaded cache or the disk.
"""
"""
if
name
not
in
self
.
module_from_name
:
if
name
not
in
self
.
module_from_name
:
_logger
.
debug
(
'loading name
%
s'
,
name
)
_logger
.
debug
(
'loading name
%
s'
,
name
)
...
@@ -641,25 +705,31 @@ class ModuleCache(object):
...
@@ -641,25 +705,31 @@ class ModuleCache(object):
def
refresh
(
self
,
age_thresh_use
=
None
,
delete_if_problem
=
False
,
def
refresh
(
self
,
age_thresh_use
=
None
,
delete_if_problem
=
False
,
cleanup
=
True
):
cleanup
=
True
):
"""Update cache data by walking the cache directory structure.
"""
Update cache data by walking the cache directory structure.
Load key.pkl files that have not been loaded yet.
Load key.pkl files that have not been loaded yet.
Remove entries which have been removed from the filesystem.
Remove entries which have been removed from the filesystem.
Also, remove malformed cache directories.
Also, remove malformed cache directories.
:param age_thresh_use: Do not use modules olther than this.
Parameters
Defaults to self.age_thresh_use.
----------
age_thresh_use
:param delete_if_problem: If True, cache entries that meet one
Do not use modules other than this. Defaults to self.age_thresh_use.
of those two conditions are deleted:
delete_if_problem : bool
If True, cache entries that meet one of those two conditions are
deleted:
- Those for which unpickling the KeyData file fails with
- Those for which unpickling the KeyData file fails with
an unknown exception.
an unknown exception.
- Duplicated modules, regardless of their age.
- Duplicated modules, regardless of their age.
cleanup : bool
Do a cleanup of the cache removing expired and broken modules.
:param cleanup: Do a cleanup of the cache removing expired and
Returns
broken modules.
-------
list
A list of modules of age higher than age_thresh_use.
:returns: a list of modules of age higher than age_thresh_use.
"""
"""
if
age_thresh_use
is
None
:
if
age_thresh_use
is
None
:
age_thresh_use
=
self
.
age_thresh_use
age_thresh_use
=
self
.
age_thresh_use
...
@@ -935,6 +1005,7 @@ class ModuleCache(object):
...
@@ -935,6 +1005,7 @@ class ModuleCache(object):
and None otherwise.
and None otherwise.
May raise ValueError if the key is malformed.
May raise ValueError if the key is malformed.
"""
"""
name
=
None
name
=
None
if
key
is
not
None
:
if
key
is
not
None
:
...
@@ -993,6 +1064,7 @@ class ModuleCache(object):
...
@@ -993,6 +1064,7 @@ class ModuleCache(object):
def
_add_to_cache
(
self
,
module
,
key
,
module_hash
):
def
_add_to_cache
(
self
,
module
,
key
,
module_hash
):
"""
"""
This function expects the compile lock to be held.
This function expects the compile lock to be held.
"""
"""
name
=
module
.
__file__
name
=
module
.
__file__
_logger
.
debug
(
"Adding module to cache
%
s
%
s"
,
_logger
.
debug
(
"Adding module to cache
%
s
%
s"
,
...
@@ -1036,18 +1108,19 @@ class ModuleCache(object):
...
@@ -1036,18 +1108,19 @@ class ModuleCache(object):
"""
"""
Return a module from the cache, compiling it if necessary.
Return a module from the cache, compiling it if necessary.
:param key: The key object associated with the module. If this
Parameters
hits a match, we avoid compilation.
----------
key
:param lnk: Usually a CLinker instance, but it can be any
The key object associated with the module. If this hits a match,
object that defines the `get_src_code()` and
we avoid compilation.
`compile_cmodule(location)` functions. The first
lnk
one returns the source code of the module to
Usually a CLinker instance, but it can be any object that defines
load/compile and the second performs the actual
the `get_src_code()` and `compile_cmodule(location)` functions. The
compilation.
first one returns the source code of the module to load/compile and
the second performs the actual compilation.
keep_lock : bool
If True, the compilation lock will not be released if taken.
:param keep_lock: If True, the compilation lock will not be
released if taken.
"""
"""
# Is the module in the cache?
# Is the module in the cache?
module
=
self
.
_get_from_key
(
key
)
module
=
self
.
_get_from_key
(
key
)
...
@@ -1123,8 +1196,13 @@ class ModuleCache(object):
...
@@ -1123,8 +1196,13 @@ class ModuleCache(object):
"""
"""
Perform checks to detect broken __eq__ / __hash__ implementations.
Perform checks to detect broken __eq__ / __hash__ implementations.
:param key: The key to be checked.
Parameters
:param key_pkl: Its associated pickled file containing a KeyData.
----------
key
The key to be checked.
key_pkl
Its associated pickled file containing a KeyData.
"""
"""
start_time
=
time
.
time
()
start_time
=
time
.
time
()
# Verify that when we reload the KeyData from the pickled file, the
# Verify that when we reload the KeyData from the pickled file, the
...
@@ -1177,18 +1255,24 @@ class ModuleCache(object):
...
@@ -1177,18 +1255,24 @@ class ModuleCache(object):
age_thresh_del
=
60
*
60
*
24
*
31
# 31 days
age_thresh_del
=
60
*
60
*
24
*
31
# 31 days
age_thresh_del_unversioned
=
60
*
60
*
24
*
7
# 7 days
age_thresh_del_unversioned
=
60
*
60
*
24
*
7
# 7 days
"""
The default age threshold for `clear_old` (in seconds).
"""The default age threshold for `clear_old` (in seconds)
"""
"""
def
clear_old
(
self
,
age_thresh_del
=
None
,
delete_if_problem
=
False
):
def
clear_old
(
self
,
age_thresh_del
=
None
,
delete_if_problem
=
False
):
"""
"""
Delete entries from the filesystem for cache entries that are too old.
Delete entries from the filesystem for cache entries that are too old.
:param age_thresh_del: Dynamic modules whose last access time is more
Parameters
than ``age_thresh_del`` seconds ago will be erased. Defaults to 31-day
----------
age if not provided.
age_thresh_del
Dynamic modules whose last access time is more than
``age_thresh_del`` seconds ago will be erased.
Defaults to 31-day age if not provided.
delete_if_problem
See help of refresh() method.
:param delete_if_problem: See help of refresh() method.
"""
"""
if
age_thresh_del
is
None
:
if
age_thresh_del
is
None
:
age_thresh_del
=
self
.
age_thresh_del
age_thresh_del
=
self
.
age_thresh_del
...
@@ -1232,16 +1316,19 @@ class ModuleCache(object):
...
@@ -1232,16 +1316,19 @@ class ModuleCache(object):
"""
"""
Clear all elements in the cache.
Clear all elements in the cache.
:param unversioned_min_age: Forwarded to `clear_unversioned`. In
Parameters
particular, you can set it to -1 in order to delete all unversioned
----------
cached modules regardless of their age.
unversioned_min_age
Forwarded to `clear_unversioned`. In particular, you can set it
:param clear_base_files: If True, then delete base directories
to -1 in order to delete all unversioned cached modules regardless
'cuda_ndarray', 'cutils_ext', 'lazylinker_ext' and 'scan_perform'
of their age.
if they are present.
clear_base_files : bool
If True, then delete base directories 'cuda_ndarray', 'cutils_ext',
'lazylinker_ext' and 'scan_perform' if they are present.
If False, those directories are left intact.
If False, those directories are left intact.
delete_if_problem
See help of refresh() method.
:param delete_if_problem: See help of refresh() method.
"""
"""
with
compilelock
.
lock_ctx
():
with
compilelock
.
lock_ctx
():
self
.
clear_old
(
self
.
clear_old
(
...
@@ -1260,6 +1347,7 @@ class ModuleCache(object):
...
@@ -1260,6 +1347,7 @@ class ModuleCache(object):
some systems due to these modules being currently in use. Instead we
some systems due to these modules being currently in use. Instead we
rename them with the '.delete.me' extension, to mark them to be deleted
rename them with the '.delete.me' extension, to mark them to be deleted
next time we clear the cache.
next time we clear the cache.
"""
"""
with
compilelock
.
lock_ctx
():
with
compilelock
.
lock_ctx
():
for
base_dir
in
(
'cuda_ndarray'
,
'cutils_ext'
,
'lazylinker_ext'
,
for
base_dir
in
(
'cuda_ndarray'
,
'cutils_ext'
,
'lazylinker_ext'
,
...
@@ -1287,8 +1375,12 @@ class ModuleCache(object):
...
@@ -1287,8 +1375,12 @@ class ModuleCache(object):
They are deleted both from the internal dictionaries and from the
They are deleted both from the internal dictionaries and from the
filesystem.
filesystem.
:param min_age: Minimum age to be deleted, in seconds. Defaults to
Parameters
----------
min_age
Minimum age to be deleted, in seconds. Defaults to
7-day age if not provided.
7-day age if not provided.
"""
"""
if
min_age
is
None
:
if
min_age
is
None
:
min_age
=
self
.
age_thresh_del_unversioned
min_age
=
self
.
age_thresh_del_unversioned
...
@@ -1409,8 +1501,13 @@ _module_cache = None
...
@@ -1409,8 +1501,13 @@ _module_cache = None
def
get_module_cache
(
dirname
,
init_args
=
None
):
def
get_module_cache
(
dirname
,
init_args
=
None
):
"""
"""
:param init_args: If not None, the (k, v) pairs in this dictionary will
be forwarded to the ModuleCache constructor as keyword arguments.
Parameters
----------
init_args
If not None, the (k, v) pairs in this dictionary will be forwarded to
the ModuleCache constructor as keyword arguments.
"""
"""
global
_module_cache
global
_module_cache
if
init_args
is
None
:
if
init_args
is
None
:
...
@@ -1429,7 +1526,10 @@ def get_module_cache(dirname, init_args=None):
...
@@ -1429,7 +1526,10 @@ def get_module_cache(dirname, init_args=None):
def
get_lib_extension
():
def
get_lib_extension
():
"""Return the platform-dependent extension for compiled modules."""
"""
Return the platform-dependent extension for compiled modules.
"""
if
sys
.
platform
in
[
'win32'
,
'cygwin'
]:
if
sys
.
platform
in
[
'win32'
,
'cygwin'
]:
return
'pyd'
return
'pyd'
else
:
else
:
...
@@ -1437,7 +1537,10 @@ def get_lib_extension():
...
@@ -1437,7 +1537,10 @@ def get_lib_extension():
def
get_gcc_shared_library_arg
():
def
get_gcc_shared_library_arg
():
"""Return the platform-dependent GCC argument for shared libraries."""
"""
Return the platform-dependent GCC argument for shared libraries.
"""
if
sys
.
platform
==
'darwin'
:
if
sys
.
platform
==
'darwin'
:
return
'-dynamiclib'
return
'-dynamiclib'
else
:
else
:
...
@@ -1534,9 +1637,11 @@ def gcc_version():
...
@@ -1534,9 +1637,11 @@ def gcc_version():
def
gcc_llvm
():
def
gcc_llvm
():
""" Detect if the g++ version used is the llvm one or not.
"""
Detect if the g++ version used is the llvm one or not.
It don't support all g++ parameters even if it support many of them.
It don't support all g++ parameters even if it support many of them.
"""
"""
if
gcc_llvm
.
is_llvm
is
None
:
if
gcc_llvm
.
is_llvm
is
None
:
try
:
try
:
...
@@ -1558,12 +1663,15 @@ gcc_llvm.is_llvm = None
...
@@ -1558,12 +1663,15 @@ gcc_llvm.is_llvm = None
class
Compiler
(
object
):
class
Compiler
(
object
):
"""
"""
Meta compiler that offer some generic function
Meta compiler that offer some generic function.
"""
"""
@staticmethod
@staticmethod
def
_try_compile_tmp
(
src_code
,
tmp_prefix
=
''
,
flags
=
(),
def
_try_compile_tmp
(
src_code
,
tmp_prefix
=
''
,
flags
=
(),
try_run
=
False
,
output
=
False
,
compiler
=
None
):
try_run
=
False
,
output
=
False
,
compiler
=
None
):
"""Try to compile (and run) a test program.
"""
Try to compile (and run) a test program.
This is useful in various occasions, to check if libraries
This is useful in various occasions, to check if libraries
or compilers are behaving as expected.
or compilers are behaving as expected.
...
@@ -1574,6 +1682,7 @@ class Compiler(object):
...
@@ -1574,6 +1682,7 @@ class Compiler(object):
If try_run is False, returns the compilation status.
If try_run is False, returns the compilation status.
If try_run is True, returns a (compile_status, run_status) pair.
If try_run is True, returns a (compile_status, run_status) pair.
If output is there, we append the stdout and stderr to the output.
If output is there, we append the stdout and stderr to the output.
"""
"""
if
not
compiler
:
if
not
compiler
:
return
False
return
False
...
@@ -1631,12 +1740,13 @@ class Compiler(object):
...
@@ -1631,12 +1740,13 @@ class Compiler(object):
@staticmethod
@staticmethod
def
_try_flags
(
flag_list
,
preambule
=
""
,
body
=
""
,
def
_try_flags
(
flag_list
,
preambule
=
""
,
body
=
""
,
try_run
=
False
,
output
=
False
,
compiler
=
None
):
try_run
=
False
,
output
=
False
,
compiler
=
None
):
'''
"""
Try to compile a dummy file with these flags.
Try to compile a dummy file with these flags.
Returns True if compilation was successful, False if there
Returns True if compilation was successful, False if there
were errors.
were errors.
'''
"""
if
not
compiler
:
if
not
compiler
:
return
False
return
False
...
@@ -1933,33 +2043,38 @@ class GCC_compiler(Compiler):
...
@@ -1933,33 +2043,38 @@ class GCC_compiler(Compiler):
include_dirs
=
None
,
lib_dirs
=
None
,
libs
=
None
,
include_dirs
=
None
,
lib_dirs
=
None
,
libs
=
None
,
preargs
=
None
,
py_module
=
True
,
hide_symbols
=
True
):
preargs
=
None
,
py_module
=
True
,
hide_symbols
=
True
):
"""
"""
:param module_name: string (this has been embedded in the src_code
:param src_code: a complete c or c++ source listing for the module
:param location: a pre-existing filesystem directory where the
cpp file and .so will be written
:param include_dirs: a list of include directory names (each
gets prefixed with -I)
:param lib_dirs: a list of library search path directory names
(each gets prefixed with -L)
:param libs: a list of libraries to link with (each gets
prefixed with -l)
:param preargs: a list of extra compiler arguments
:param py_module: if False, compile to a shared library, but do not
import it as a Python module.
:param hide_symbols: if True (the default) all symbols will be
Parameters
hidden from the library symbol table (which means that other
----------
objects can't use them.
module_name : str
This has been embedded in the src_code.
src_code
A complete c or c++ source listing for the module.
location
A pre-existing filesystem directory where the cpp file and .so will
be written.
include_dirs
A list of include directory names (each gets prefixed with -I).
lib_dirs
A list of library search path directory names (each gets prefixed
with -L).
libs
A list of libraries to link with (each gets prefixed with -l).
preargs
A list of extra compiler arguments.
py_module
If False, compile to a shared library, but do not import it as a
Python module.
hide_symbols
If True (the default) all symbols will be hidden from the library
symbol table (which means that other objects can't use them).
Returns
-------
object
Dynamically-imported python module of the compiled code (unless
py_module is False, in that case returns None).
:returns: dynamically-imported python module of the compiled code.
(unless py_module is False, in that case returns None.)
"""
"""
# TODO: Do not do the dlimport in this function
# TODO: Do not do the dlimport in this function
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论