提交 2e323b39 authored 作者: James Bergstra's avatar James Bergstra

integrating get_compiledir, set_compiledir -> config.compiledir

上级 0f798670
#!/usr/bin/env python #!/usr/bin/env python
import sys import sys
from theano.gof.cc import get_compiledir, get_module_cache from theano import config
from theano.gof.cc import get_module_cache
if len(sys.argv) == 1: if len(sys.argv) == 1:
print get_compiledir() print config.compiledir
elif sys.argv[1] in ('clear'): elif sys.argv[1] in ('clear'):
get_module_cache().clear() get_module_cache().clear()
else: else:
......
...@@ -19,43 +19,122 @@ read-only. ...@@ -19,43 +19,122 @@ read-only.
*As a rule, the attributes in this module should not be modified by user code.* *As a rule, the attributes in this module should not be modified by user code.*
Reference Theano's code comes with default values for these attributes, but you can
========= override them from your .theanorc file, and override those values in turn by
the :envvar:`THEANO_FLAGS` environment variable.
The order of precedence is:
1. an assignment to theano.config.<property>
2. an assignment in :envvar:`THEANO_FLAGS`
3. an assignment in the .theanorc file (or the file indicated in :envvar:`THEANORC`)
You can print out the current/effective configuration at any time by printing
theano.config. For example, to see a list of all active configuration
variables, type this from the command-line:
.. code-block:: bash
python -c 'import theano; print theano.config' | less
Environment Variables
=====================
.. envvar:: THEANO_FLAGS .. envvar:: THEANO_FLAGS
This is a list of comma-delimited key=value pairs that control Theano's behavior. This is a list of comma-delimited key[=value] pairs that control Theano's behavior. A key that appears without an '=value' must be for a boolean value, and it acts as setting it to True.
For example, in bash, you can type: For example, in bash, you can override your :envvar:`THEANORC` defaults
for <myscript>.py by typing this:
.. code-block:: bash .. code-block:: bash
THEANO_FLAGS=floatX=float32 python <myscript>.py THEANO_FLAGS='floatX=float32,device=gpu0,nvcc.fastmath' python <myscript>.py
.. envvar:: THEANORC
This is the location of the .theanorc file which is in ConfigParser
format. It defaults to ``$HOME/.theanorc``.
Here is the .theanorc equivalent to the THEANO_FLAGS in the example above:
.. bode-block:: text
[global]
floatX = float32
device = gpu0
[nvcc]
fastmath = True
The rest of this page describes some of the more common and important flags
that you might want to use. For the complete list (including documentation),
import theano and print the config variable, as in:
.. code-block:: bash
python -c 'import theano; print theano.config' | less
Config Attributes
=====================
***TODO*** .. attribute:: device
Which will cause String value: either 'cpu', 'gpu0', 'gpu1', 'gpu2', or 'gpu3'
Choose the default compute device for theano graphs. Setting this to a
gpu string will make the corresponding graphics device the default storage
for shared tensor variables with dtype float32.
.. attribute:: floatX .. attribute:: floatX
String value: either 'float32' or 'float64'. String value: either 'float64' or 'float32'.
Default: 'float64' Default: 'float64'
Set with the 'floatX' key in :envvar:`THEANO_FLAGS` This sets the default dtype returned by tensor.matrix(), tensor.vector(),
and similar functions. It also sets the default theano bit width for
arguments passed as Python floating-point numbers.
.. attribute:: mode
String value: 'FAST_RUN', 'FAST_COMPILE', 'PROFILE_MODE', 'DEBUG_MODE'
Default 'FAST_RUN'
This sets the default compilation mode for theano functions.
.. attribute:: home
Default: env-variable $HOME
This is used to compute the compiledir and base_compiledir attributes
.. attribute:: base_compiledir
Default: $HOME/.theano
This directory stores the architecture-dependent compilation directories.
.. attribute:: compiledir
Default: $HOME/.theano/<arch-identifier>
This directory stores dynamically-compiled modules for a particular
architecture.
.. attribute:: THEANO_DEFAULT_MODE .. attribute:: blas.ldflags
String value: any valid mode string (see :func:`theano.function`). Default: '-lblas'
Default: 'FAST_RUN' Link arguments to link against a (Fortran) level-3 blas implementation.
Set with the 'THEANO_DEFAULT_MODE' environment variable. .. attribute:: cuda.root
Default: $CUDA_ROOT or failing that, "/usr/local/cuda"
***TODO*** Consider moving many config elements to THEANO_FLAGS right away before taking the A directory with bin/, lib/, include/ folders containing cuda utilities.
time to document the current madness.
...@@ -14,7 +14,6 @@ Types and Ops that you can use to build and compile expression graphs. ...@@ -14,7 +14,6 @@ Types and Ops that you can use to build and compile expression graphs.
tensor/index tensor/index
gradient gradient
config config
floatX
printing printing
compile/index compile/index
sparse/index sparse/index
......
...@@ -263,7 +263,7 @@ them perfectly, but a dscalar otherwise. ...@@ -263,7 +263,7 @@ them perfectly, but a dscalar otherwise.
.. note:: .. note::
When floatX=float32 is given in :envvar:`THEANO_FLAGS`, then Python floats When config.floatX==float32 (see :module:`config`), then Python floats
are stored instead as single-precision floats. are stored instead as single-precision floats.
For fine control of this rounding policy, see For fine control of this rounding policy, see
......
...@@ -40,8 +40,7 @@ from gof import \ ...@@ -40,8 +40,7 @@ from gof import \
opt, \ opt, \
toolbox, \ toolbox, \
Type, Generic, generic, \ Type, Generic, generic, \
object2, utils, \ object2, utils
set_compiledir, get_compiledir, clear_compiledir
from compile import \ from compile import \
SymbolicInput, In, \ SymbolicInput, In, \
......
...@@ -20,6 +20,29 @@ from theano.compile.function_module import (FunctionMaker, ...@@ -20,6 +20,29 @@ from theano.compile.function_module import (FunctionMaker,
SymbolicOutput, SymbolicOutput,
Supervisor) Supervisor)
from theano.compile.mode import Mode, register_mode from theano.compile.mode import Mode, register_mode
from ..configparser import config, AddConfigVar, IntParam, BoolParam
AddConfigVar('DebugMode.patience',
"Optimize graph this many times to detect inconsistency",
IntParam(10, lambda i: i > 0))
AddConfigVar('DebugMode.check_c',
"Run C implementations where possible",
BoolParam(True))
AddConfigVar('DebugMode.check_py',
"Run Python implementations where possible",
BoolParam(True))
AddConfigVar('DebugMode.check_finite',
"True -> complain about NaN/Inf results",
BoolParam(True))
AddConfigVar('DebugMode.check_strides',
("Check that Python- and C-produced ndarrays have same strides. "
"On difference: (0) - ignore, (1) warn, or (2) raise error"),
IntParam(1, lambda i: i in (0,1,2)))
import logging import logging
_logger=logging.getLogger("theano.compile.debugmode") _logger=logging.getLogger("theano.compile.debugmode")
......
...@@ -6,10 +6,19 @@ from theano.compile.mode import Mode, register_mode, predefined_modes, predefine ...@@ -6,10 +6,19 @@ from theano.compile.mode import Mode, register_mode, predefined_modes, predefine
from theano.gof.cc import OpWiseCLinker from theano.gof.cc import OpWiseCLinker
from theano.gof.python25 import any from theano.gof.python25 import any
from theano import gof from theano import gof
from ..configparser import config from ..configparser import config, AddConfigVar, IntParam
import_time = time.time() import_time = time.time()
AddConfigVar('ProfileMode.n_apply_to_print',
"Number of apply instances to print by default",
IntParam(15, lambda i: i > 0))
AddConfigVar('ProfileMode.n_ops_to_print',
"Number of ops to print by default",
IntParam(20, lambda i: i > 0))
class ProfileMode(Mode): class ProfileMode(Mode):
def __init__(self, linker=default_linker, optimizer=default_optimizer): def __init__(self, linker=default_linker, optimizer=default_optimizer):
local_time = [0.0] local_time = [0.0]
......
...@@ -10,8 +10,9 @@ AddConfigVar('floatX', ...@@ -10,8 +10,9 @@ AddConfigVar('floatX',
AddConfigVar('device', AddConfigVar('device',
"Default device for computations", "Default device for computations",
EnumStr('cpu', *['gpu%i'%i for i in range(16)]) EnumStr('cpu', *['gpu%i'%i for i in range(4)])
) )
AddConfigVar('mode', AddConfigVar('mode',
"Default compilation mode", "Default compilation mode",
EnumStr('FAST_RUN', 'FAST_COMPILE', 'PROFILE_MODE', 'DEBUG_MODE')) EnumStr('FAST_RUN', 'FAST_COMPILE', 'PROFILE_MODE', 'DEBUG_MODE'))
...@@ -20,51 +21,14 @@ AddConfigVar('home', ...@@ -20,51 +21,14 @@ AddConfigVar('home',
"User home directory", "User home directory",
EnumStr(os.getenv("HOME"))) EnumStr(os.getenv("HOME")))
AddConfigVar('base_compiledir',
"arch-independent cache directory for compiled modules",
StrParam(os.path.join(config.home, '.theano')))
AddConfigVar('compiledir',
"arch-dependent cache directory for compiled modules",
StrParam("")) #NO DEFAULT??
AddConfigVar('nocleanup', AddConfigVar('nocleanup',
"suppress the deletion of code files that did not compile cleanly", "suppress the deletion of code files that did not compile cleanly",
BoolParam(False)) BoolParam(False))
AddConfigVar('blas.ldflags', AddConfigVar('blas.ldflags',
"lib[s] to include for level-3 blas implementation", "lib[s] to include for [Fortran] level-3 blas implementation",
StrParam("-lblas")) StrParam("-lblas"))
AddConfigVar('DebugMode.patience',
"Optimize graph this many times",
IntParam(10, lambda i: i > 0))
AddConfigVar('DebugMode.check_c',
"Run C implementations where possible",
BoolParam(True))
AddConfigVar('DebugMode.check_py',
"Run Python implementations where possible",
BoolParam(True))
AddConfigVar('DebugMode.check_finite',
"True -> complain about NaN/Inf results",
BoolParam(True))
AddConfigVar('DebugMode.check_strides',
("Check that Python- and C-produced ndarrays have same strides. "
"On difference: (0) - ignore, (1) warn, or (2) raise error"),
IntParam(1, lambda i: i in (0,1,2)))
AddConfigVar('ProfileMode.n_apply_to_print',
"",
IntParam(15, lambda i: i > 0))
AddConfigVar('ProfileMode.n_ops_to_print',
"",
IntParam(20, lambda i: i > 0))
AddConfigVar('tensor.cmp_sloppy', AddConfigVar('tensor.cmp_sloppy',
"Relax tensor._allclose (0) not at all, (1) a bit, (2) more", "Relax tensor._allclose (0) not at all, (1) a bit, (2) more",
IntParam(0, lambda i: i in (0,1,2))) IntParam(0, lambda i: i in (0,1,2)))
...@@ -87,7 +51,7 @@ AddConfigVar('nvcc.fastmath', ...@@ -87,7 +51,7 @@ AddConfigVar('nvcc.fastmath',
AddConfigVar('cuda.root', AddConfigVar('cuda.root',
"directory with bin/, lib/, include/ for cuda utilities", "directory with bin/, lib/, include/ for cuda utilities",
StrParam("/usr/local/cuda")) StrParam(os.getenv('CUDA_ROOT', "/usr/local/cuda")))
AddConfigVar('gpuelemwise.sync', AddConfigVar('gpuelemwise.sync',
"when true, wait that the gpu fct finished and check it error code.", "when true, wait that the gpu fct finished and check it error code.",
......
import os, StringIO import os, StringIO, sys
import ConfigParser import ConfigParser
import logging import logging
_logger = logging.getLogger('theano.config') _logger = logging.getLogger('theano.config')
for key in os.environ:
if key.startswith("THEANO"):
if key not in ("THEANO_FLAGS", "THEANORC"):
print >> sys.stderr, "ERROR: Ignoring deprecated environment variable", key
THEANO_FLAGS=os.getenv("THEANO_FLAGS","") THEANO_FLAGS=os.getenv("THEANO_FLAGS","")
# The THEANO_FLAGS environement variable should be a list of comma-separated # The THEANO_FLAGS environement variable should be a list of comma-separated
# [section.]option[=value] entries. If the section part is omited, their should be only one # [section.]option[=value] entries. If the section part is omited, their should be only one
# section with that contain the gived option. # section with that contain the gived option.
theano_cfg_path = os.getenv('THEANORC', '~/.theanorc')
theano_cfg = ConfigParser.SafeConfigParser() theano_cfg = ConfigParser.SafeConfigParser()
theano_cfg.read(['theano.cfg', os.path.expanduser('~/.theano.cfg')]) theano_cfg.read([os.path.expanduser(theano_cfg_path)])
def parse_env_flags(flags, name , default_value=None): def parse_env_flags(flags, name , default_value=None):
#The value in the env variable THEANO_FLAGS override the previous value #The value in the env variable THEANO_FLAGS override the previous value
...@@ -33,12 +40,11 @@ def fetch_val_for_key(key): ...@@ -33,12 +40,11 @@ def fetch_val_for_key(key):
The priority order is: The priority order is:
- THEANO_FLAGS - THEANO_FLAGS
- ~./theano.cfg - ~./theanorc
""" """
# first try to find it in the FLAGS # first try to find it in the FLAGS
matches = []
for name_val in THEANO_FLAGS.split(','): for name_val in THEANO_FLAGS.split(','):
if not name_val: if not name_val:
continue continue
...@@ -48,14 +54,8 @@ def fetch_val_for_key(key): ...@@ -48,14 +54,8 @@ def fetch_val_for_key(key):
else: else:
name, val = name_val_tuple name, val = name_val_tuple
if name.endswith(key): #we found it in FLAGS if name == key:
matches.append((name, val)) return val
if matches:
if len(matches) > 1:
_logging.error('ambiguous THEANO_FLAGS flag %s matches %s (ignoring it)' % (key, [name for name,val in matches]))
else:
return matches[0][1]
# next try to find it in the config file # next try to find it in the config file
......
...@@ -131,8 +131,7 @@ else: ...@@ -131,8 +131,7 @@ else:
from cc import \ from cc import \
CLinker, OpWiseCLinker, DualLinker CLinker, OpWiseCLinker, DualLinker
from compiledir import \ import compiledir # adds config vars
set_compiledir, get_compiledir, clear_compiledir
from env import \ from env import \
InconsistencyError, Env InconsistencyError, Env
......
...@@ -44,13 +44,13 @@ def error(*args): ...@@ -44,13 +44,13 @@ def error(*args):
from theano.gof.callcache import CallCache from theano.gof.callcache import CallCache
def get_module_cache(): def get_module_cache():
return cmodule.get_module_cache(get_compiledir()) return cmodule.get_module_cache(config.compiledir)
_persistent_module_cache = None _persistent_module_cache = None
def get_persistent_module_cache(): def get_persistent_module_cache():
global _persistent_module_cache global _persistent_module_cache
if _persistent_module_cache is None: if _persistent_module_cache is None:
_persistent_module_cache = CallCache(os.path.join(get_compiledir(), 'persistent_cache')) _persistent_module_cache = CallCache(os.path.join(config.compiledir, 'persistent_cache'))
return _persistent_module_cache return _persistent_module_cache
class CodeBlock: class CodeBlock:
...@@ -903,7 +903,7 @@ class CLinker(link.Linker): ...@@ -903,7 +903,7 @@ class CLinker(link.Linker):
This method is a callback for `ModuleCache.module_from_key` This method is a callback for `ModuleCache.module_from_key`
""" """
if location is None: if location is None:
location = cmodule.dlimport_workdir(get_compiledir()) location = cmodule.dlimport_workdir(config.compiledir)
mod = self.build_dynamic_module() mod = self.build_dynamic_module()
get_lock() get_lock()
try: try:
......
...@@ -172,7 +172,7 @@ def dlimport(fullpath, suffix=None): ...@@ -172,7 +172,7 @@ def dlimport(fullpath, suffix=None):
def dlimport_workdir(basedir): def dlimport_workdir(basedir):
"""Return a directory where you should put your .so file for dlimport to be able to load """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 the result of get_compiledir()""" it, given a basedir which should normally be config.compiledir"""
return tempfile.mkdtemp(dir=basedir) return tempfile.mkdtemp(dir=basedir)
def last_access_time(path): def last_access_time(path):
......
import errno import errno
import os import os, sys
import platform import platform
import re import re
from ..configparser import config from ..configparser import config, AddConfigVar, StrParam
def set_compiledir(path=None): def default_compiledirname():
"""Set the directory into which theano will compile code objects platform_id = platform.platform() + '-' + platform.processor()
platform_id = re.sub("[\(\)\s]+", "_", platform_id)
@param path: an absolute path or relative path. An argument of None will return 'compiledir_'+platform_id
trigger one of two default paths: firstly an environment variable called
'THEANO_COMPILEDIR' will be sought; failing that, an architecture-specific
directory will be chosen within $HOME/.theano.
@type path: string or None
@return: None
@note: This function will create the path (recursively) as a folder if it
is not present, not readable, or not writable. New folders will be created
with mode 0700.
"""
# N.B. The path is stored as an attribute of this function
if path is None:
# we need to set the default, which can come from one of two places
if config.compiledir:
path = config.compiledir
else:
platform_id = platform.platform() + '-' + platform.processor()
platform_id = re.sub("[\(\)\s]+", "_", platform_id)
if config.base_compiledir:
base = config.base_compiledir
else:
base = os.path.join(config.home,'.theano')
path = os.path.join(base, 'compiledir_'+platform_id)
def is_valid_compiledir(path):
if not os.access(path, os.R_OK | os.W_OK): if not os.access(path, os.R_OK | os.W_OK):
try: try:
os.makedirs(path, 0770) #read-write-execute for this user only os.makedirs(path, 0770) #read-write-execute for this user only
...@@ -45,35 +19,29 @@ def set_compiledir(path=None): ...@@ -45,35 +19,29 @@ def set_compiledir(path=None):
# Maybe another parallel execution of theano was trying to create # Maybe another parallel execution of theano was trying to create
# the same directory at the same time. # the same directory at the same time.
if e.errno != errno.EEXIST: if e.errno != errno.EEXIST:
raise return False
# PROBLEM: sometimes the first approach based on os.system('touch') try:
# returned -1 for an unknown reason; the alternate approach here worked # PROBLEM: sometimes the first approach based on os.system('touch')
# in all cases... it was weird. # returned -1 for an unknown reason; the alternate approach here worked
open(os.path.join(path, '__init__.py'), 'w').close() # in all cases... it was weird.
open(os.path.join(path, '__init__.py'), 'w').close()
set_compiledir.compiledir = path if path not in sys.path:
sys.path.append(path)
def get_compiledir(): except:
"""Return the directory where theano code objects should be compiled return False
@rtype: string return True
"""
if not hasattr(set_compiledir, 'compiledir'): AddConfigVar('base_compiledir',
set_compiledir() "arch-independent cache directory for compiled modules",
return set_compiledir.compiledir StrParam(os.path.join(config.home, '.theano')))
def clear_compiledir(verbose=False): AddConfigVar('compiledir',
if not hasattr(set_compiledir, 'compiledir'): "arch-dependent cache directory for compiled modules",
set_compiledir() StrParam(
compiledir = get_compiledir() os.path.join(
for l in os.listdir(compiledir): os.path.expanduser(config.base_compiledir),
if l.endswith('.so'): default_compiledirname()),
if verbose: print 'removing', l is_valid=is_valid_compiledir
os.remove(os.path.join(compiledir, l)) ))
elif l.endswith('.cpp'):
if verbose: print 'removing', l
os.remove(os.path.join(compiledir, l))
else:
if verbose: print 'skipping ', l
pass
# Locking mechanism to ensure no two compilations occur simultaneously in the # Locking mechanism to ensure no two compilations occur simultaneously in the
# same compilation directory (which can cause crashes). # same compilation directory (which can cause crashes).
from theano import config
import compiledir import compiledir
import os, random, time import os, random, time
import logging import logging
...@@ -37,11 +38,11 @@ def get_lock(): ...@@ -37,11 +38,11 @@ def get_lock():
if not hasattr(get_lock, 'lock_is_enabled'): if not hasattr(get_lock, 'lock_is_enabled'):
# Enable lock by default. # Enable lock by default.
get_lock.lock_is_enabled = True get_lock.lock_is_enabled = True
get_lock.lock_dir = os.path.join(compiledir.get_compiledir(), get_lock.lock_dir = os.path.join(config.compiledir,
'lock_dir') 'lock_dir')
get_lock.unlocker = Unlocker(get_lock.lock_dir) get_lock.unlocker = Unlocker(get_lock.lock_dir)
else: else:
lock_dir = os.path.join(compiledir.get_compiledir(), 'lock_dir') lock_dir = os.path.join(config.compiledir, 'lock_dir')
if lock_dir != get_lock.lock_dir: if lock_dir != get_lock.lock_dir:
# Compilation directory has changed. # Compilation directory has changed.
# First ensure all old locks were released. # First ensure all old locks were released.
......
...@@ -6,7 +6,6 @@ import sys ...@@ -6,7 +6,6 @@ import sys
try: try:
sys.path.append(get_compiledir())
from cutils_ext import * from cutils_ext import *
except ImportError: except ImportError:
...@@ -36,7 +35,7 @@ except ImportError: ...@@ -36,7 +35,7 @@ except ImportError:
mod.add_function(fun) mod.add_function(fun)
get_lock() get_lock()
try: try:
mod.compile(location = get_compiledir()) mod.compile(location = config.compiledir)
except: except:
release_lock() release_lock()
raise raise
......
import os, sys, stat import os, sys, stat
from theano.gof.compiledir import get_compiledir
from theano.compile import optdb from theano.compile import optdb
from theano import config from theano import config
...@@ -46,14 +45,13 @@ def set_cuda_disabled(): ...@@ -46,14 +45,13 @@ def set_cuda_disabled():
'working properly') 'working properly')
#cuda_ndarray compile and import #cuda_ndarray compile and import
sys.path.append(get_compiledir())
cuda_path = os.path.split(__file__)[0] cuda_path = os.path.split(__file__)[0]
date = os.stat(os.path.join(cuda_path,'cuda_ndarray.cu'))[stat.ST_MTIME] date = os.stat(os.path.join(cuda_path,'cuda_ndarray.cu'))[stat.ST_MTIME]
date = max(date,os.stat(os.path.join(cuda_path,'cuda_ndarray.cuh'))[stat.ST_MTIME]) date = max(date,os.stat(os.path.join(cuda_path,'cuda_ndarray.cuh'))[stat.ST_MTIME])
date = max(date,os.stat(os.path.join(cuda_path,'conv_full_kernel.cu'))[stat.ST_MTIME]) date = max(date,os.stat(os.path.join(cuda_path,'conv_full_kernel.cu'))[stat.ST_MTIME])
date = max(date,os.stat(os.path.join(cuda_path,'conv_kernel.cu'))[stat.ST_MTIME]) date = max(date,os.stat(os.path.join(cuda_path,'conv_kernel.cu'))[stat.ST_MTIME])
cuda_ndarray_loc = os.path.join(get_compiledir(),'cuda_ndarray') cuda_ndarray_loc = os.path.join(config.compiledir,'cuda_ndarray')
cuda_ndarray_so = os.path.join(cuda_ndarray_loc,'cuda_ndarray.so') cuda_ndarray_so = os.path.join(cuda_ndarray_loc,'cuda_ndarray.so')
compile_cuda_ndarray = True compile_cuda_ndarray = True
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论