提交 3e475958 authored 作者: Michael Osthege's avatar Michael Osthege 提交者: Brandon T. Willard

Move compiledir and compilelock to compile module

And specify their purpose and public API.
上级 edea0b85
...@@ -14,7 +14,7 @@ if sys.platform == "win32": ...@@ -14,7 +14,7 @@ if sys.platform == "win32":
os.environ["THEANO_FLAGS"] = theano_flags os.environ["THEANO_FLAGS"] = theano_flags
import theano import theano
import theano.gof.compiledir import theano.compile.compiledir
from theano import config from theano import config
from theano.link.c.basic import get_module_cache from theano.link.c.basic import get_module_cache
...@@ -81,16 +81,16 @@ def main(): ...@@ -81,16 +81,16 @@ def main():
) )
_logger.debug(f"Remaining elements ({len(items)}): {', '.join(items)}") _logger.debug(f"Remaining elements ({len(items)}): {', '.join(items)}")
elif sys.argv[1] == "list": elif sys.argv[1] == "list":
theano.gof.compiledir.print_compiledir_content() theano.compile.compiledir.print_compiledir_content()
elif sys.argv[1] == "cleanup": elif sys.argv[1] == "cleanup":
theano.gof.compiledir.cleanup() theano.compile.compiledir.cleanup()
cache = get_module_cache(init_args=dict(do_refresh=False)) cache = get_module_cache(init_args=dict(do_refresh=False))
cache.clear_old() cache.clear_old()
elif sys.argv[1] == "unlock": elif sys.argv[1] == "unlock":
theano.gof.compilelock.force_unlock() theano.compile.compilelock.force_unlock()
print("Lock successfully removed!") print("Lock successfully removed!")
elif sys.argv[1] == "purge": elif sys.argv[1] == "purge":
theano.gof.compiledir.compiledir_purge() theano.compile.compiledir.compiledir_purge()
elif sys.argv[1] == "basecompiledir": elif sys.argv[1] == "basecompiledir":
# Simply print the base_compiledir # Simply print the base_compiledir
print(theano.config.base_compiledir) print(theano.config.base_compiledir)
...@@ -98,9 +98,9 @@ def main(): ...@@ -98,9 +98,9 @@ def main():
print_help(exit_status=1) print_help(exit_status=1)
elif len(sys.argv) == 3 and sys.argv[1] == "basecompiledir": elif len(sys.argv) == 3 and sys.argv[1] == "basecompiledir":
if sys.argv[2] == "list": if sys.argv[2] == "list":
theano.gof.compiledir.basecompiledir_ls() theano.compile.compiledir.basecompiledir_ls()
elif sys.argv[2] == "purge": elif sys.argv[2] == "purge":
theano.gof.compiledir.basecompiledir_purge() theano.compile.compiledir.basecompiledir_purge()
else: else:
print_help(exit_status=1) print_help(exit_status=1)
else: else:
......
...@@ -116,7 +116,7 @@ case if ``borrow`` was True, the thunk would be allowed to reuse (or ...@@ -116,7 +116,7 @@ case if ``borrow`` was True, the thunk would be allowed to reuse (or
crashes with paralell execution of some scripts). This mechanism is crashes with paralell execution of some scripts). This mechanism is
currently enabled by default, but if it causes any problem it may be currently enabled by default, but if it causes any problem it may be
disabled using the function disabled using the function
``theano.gof.compilelock.set_lock_status(..)``. ``theano.compile.compilelock.set_lock_status(..)``.
Step 4 - Wrap the thunk in a pretty package Step 4 - Wrap the thunk in a pretty package
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
"""
This module contains housekeeping functions for cleaning/purging the "compiledir".
It is used by the "theano-cache" CLI tool, located in the /bin folder of the repository.
"""
import logging import logging
import os import os
import pickle import pickle
...@@ -10,7 +14,7 @@ from theano.configdefaults import config ...@@ -10,7 +14,7 @@ from theano.configdefaults import config
from theano.utils import flatten from theano.utils import flatten
_logger = logging.getLogger("theano.gof.compiledir") _logger = logging.getLogger("theano.compile.compiledir")
def cleanup(): def cleanup():
......
...@@ -5,7 +5,7 @@ in the same compilation directory (which can cause crashes). ...@@ -5,7 +5,7 @@ in the same compilation directory (which can cause crashes).
import atexit import atexit
import logging import logging
import os import os
import socket # only used for gethostname() import socket
import time import time
from contextlib import contextmanager from contextlib import contextmanager
...@@ -14,16 +14,24 @@ import numpy as np ...@@ -14,16 +14,24 @@ import numpy as np
from theano.configdefaults import config from theano.configdefaults import config
random = np.random.RandomState([2015, 8, 2]) __all__ = [
"force_unlock",
"get_lock",
"lock",
"lock_ctx",
"release_lock",
"set_lock_status",
]
_logger = logging.getLogger("theano.gof.compilelock")
_random = np.random.RandomState([2015, 8, 2])
_logger = logging.getLogger("theano.compile.compilelock")
# If the user provided a logging level, we don't want to override it. # If the user provided a logging level, we don't want to override it.
if _logger.level == logging.NOTSET: if _logger.level == logging.NOTSET:
# INFO will show the "Refreshing lock" messages # INFO will show the "Refreshing lock" messages
_logger.setLevel(logging.INFO) _logger.setLevel(logging.INFO)
hostname = socket.gethostname()
def force_unlock(): def force_unlock():
""" """
...@@ -201,6 +209,7 @@ def lock(tmp_dir, timeout=notset, min_wait=None, max_wait=None, verbosity=1): ...@@ -201,6 +209,7 @@ def lock(tmp_dir, timeout=notset, min_wait=None, max_wait=None, verbosity=1):
# Variable initialization. # Variable initialization.
lock_file = os.path.join(tmp_dir, "lock") lock_file = os.path.join(tmp_dir, "lock")
hostname = socket.gethostname()
my_pid = os.getpid() my_pid = os.getpid()
no_display = verbosity == 0 no_display = verbosity == 0
...@@ -276,7 +285,7 @@ def lock(tmp_dir, timeout=notset, min_wait=None, max_wait=None, verbosity=1): ...@@ -276,7 +285,7 @@ def lock(tmp_dir, timeout=notset, min_wait=None, max_wait=None, verbosity=1):
if verbosity <= 1: if verbosity <= 1:
no_display = True no_display = True
nb_wait += 1 nb_wait += 1
time.sleep(random.uniform(min_wait, max_wait)) time.sleep(_random.uniform(min_wait, max_wait))
try: try:
os.mkdir(tmp_dir) os.mkdir(tmp_dir)
...@@ -312,7 +321,7 @@ def lock(tmp_dir, timeout=notset, min_wait=None, max_wait=None, verbosity=1): ...@@ -312,7 +321,7 @@ def lock(tmp_dir, timeout=notset, min_wait=None, max_wait=None, verbosity=1):
nb_error += 1 nb_error += 1
if nb_error > 10: if nb_error > 10:
raise raise
time.sleep(random.uniform(min_wait, max_wait)) time.sleep(_random.uniform(min_wait, max_wait))
continue continue
...@@ -324,8 +333,8 @@ def refresh_lock(lock_file): ...@@ -324,8 +333,8 @@ def refresh_lock(lock_file):
""" """
unique_id = "{}_{}_{}".format( unique_id = "{}_{}_{}".format(
os.getpid(), os.getpid(),
"".join([str(random.randint(0, 9)) for i in range(10)]), "".join([str(_random.randint(0, 9)) for i in range(10)]),
hostname, socket.gethostname(),
) )
try: try:
with open(lock_file, "w") as lock_write: with open(lock_file, "w") as lock_write:
...@@ -381,7 +390,7 @@ class Unlocker: ...@@ -381,7 +390,7 @@ class Unlocker:
with open(lock_file) as f: with open(lock_file) as f:
owner = f.readlines()[0].strip() owner = f.readlines()[0].strip()
pid, _, hname = owner.split("_") pid, _, hname = owner.split("_")
if pid != str(os.getpid()) or hname != hostname: if pid != str(os.getpid()) or hname != socket.gethostname():
return return
except Exception: except Exception:
pass pass
......
...@@ -1361,7 +1361,7 @@ class FunctionMaker: ...@@ -1361,7 +1361,7 @@ class FunctionMaker:
# This function is not finished # This function is not finished
import os.path import os.path
from theano.gof.compilelock import get_lock, release_lock from theano.compile.compilelock import get_lock, release_lock
graph_db_file = os.path.join(config.compiledir, "optimized_graphs.pkl") graph_db_file = os.path.join(config.compiledir, "optimized_graphs.pkl")
......
...@@ -11,9 +11,9 @@ from io import StringIO ...@@ -11,9 +11,9 @@ from io import StringIO
import numpy as np import numpy as np
from theano.compile.compilelock import get_lock, release_lock
from theano.configdefaults import config from theano.configdefaults import config
from theano.gof.callcache import CallCache from theano.gof.callcache import CallCache
from theano.gof.compilelock import get_lock, release_lock
from theano.gof.graph import Constant, NoParams, io_toposort from theano.gof.graph import Constant, NoParams, io_toposort
from theano.gof.graph import variables as get_variables from theano.gof.graph import variables as get_variables
from theano.gof.utils import MethodNotDefined from theano.gof.utils import MethodNotDefined
......
...@@ -23,10 +23,10 @@ from io import BytesIO, StringIO ...@@ -23,10 +23,10 @@ from io import BytesIO, StringIO
import numpy.distutils import numpy.distutils
import theano import theano
from theano.configdefaults import config, gcc_version_str
# we will abuse the lockfile mechanism when reading and writing the registry # we will abuse the lockfile mechanism when reading and writing the registry
from theano.gof import compilelock from theano.compile.compilelock import lock_ctx
from theano.configdefaults import config, gcc_version_str
from theano.link.c.exceptions import MissingGXX from theano.link.c.exceptions import MissingGXX
from theano.utils import ( from theano.utils import (
LOCAL_BITWIDTH, LOCAL_BITWIDTH,
...@@ -1015,7 +1015,7 @@ class ModuleCache: ...@@ -1015,7 +1015,7 @@ class ModuleCache:
self.loaded_key_pkl.remove(pkl_file_to_remove) self.loaded_key_pkl.remove(pkl_file_to_remove)
if to_delete or to_delete_empty: if to_delete or to_delete_empty:
with compilelock.lock_ctx(): with lock_ctx():
for a, kw in to_delete: for a, kw in to_delete:
_rmtree(*a, **kw) _rmtree(*a, **kw)
for a, kw in to_delete_empty: for a, kw in to_delete_empty:
...@@ -1055,7 +1055,7 @@ class ModuleCache: ...@@ -1055,7 +1055,7 @@ class ModuleCache:
if module_hash in self.module_hash_to_key_data: if module_hash in self.module_hash_to_key_data:
key_data = self.module_hash_to_key_data[module_hash] key_data = self.module_hash_to_key_data[module_hash]
module = self._get_from_key(None, key_data) module = self._get_from_key(None, key_data)
with compilelock.lock_ctx(keep_lock=keep_lock): with lock_ctx(keep_lock=keep_lock):
try: try:
key_data.add_key(key, save_pkl=bool(key[0])) key_data.add_key(key, save_pkl=bool(key[0]))
key_broken = False key_broken = False
...@@ -1160,7 +1160,7 @@ class ModuleCache: ...@@ -1160,7 +1160,7 @@ class ModuleCache:
if module is not None: if module is not None:
return module return module
with compilelock.lock_ctx(keep_lock=keep_lock): with lock_ctx(keep_lock=keep_lock):
# 1) Maybe somebody else compiled it for us while we # 1) Maybe somebody else compiled it for us while we
# where waiting for the lock. Try to load it again. # where waiting for the lock. Try to load it again.
# 2) If other repo that import Theano have Theano ops defined, # 2) If other repo that import Theano have Theano ops defined,
...@@ -1247,7 +1247,7 @@ class ModuleCache: ...@@ -1247,7 +1247,7 @@ class ModuleCache:
# same time. This can happen as we read the cache # same time. This can happen as we read the cache
# without taking the lock. # without taking the lock.
if i == 2: if i == 2:
with compilelock.lock_ctx(): with lock_ctx():
with open(key_pkl, "rb") as f: with open(key_pkl, "rb") as f:
key_data = pickle.load(f) key_data = pickle.load(f)
time.sleep(2) time.sleep(2)
...@@ -1334,7 +1334,7 @@ class ModuleCache: ...@@ -1334,7 +1334,7 @@ class ModuleCache:
) )
if not too_old_to_use: if not too_old_to_use:
return return
with compilelock.lock_ctx(): with lock_ctx():
# Update the age of modules that have been accessed by other # Update the age of modules that have been accessed by other
# processes and get all module that are too old to use # processes and get all module that are too old to use
# (not loaded in self.entry_from_key). # (not loaded in self.entry_from_key).
...@@ -1374,7 +1374,7 @@ class ModuleCache: ...@@ -1374,7 +1374,7 @@ class ModuleCache:
See help of refresh() method. See help of refresh() method.
""" """
with compilelock.lock_ctx(): with lock_ctx():
self.clear_old(age_thresh_del=-1.0, delete_if_problem=delete_if_problem) self.clear_old(age_thresh_del=-1.0, delete_if_problem=delete_if_problem)
self.clear_unversioned(min_age=unversioned_min_age) self.clear_unversioned(min_age=unversioned_min_age)
if clear_base_files: if clear_base_files:
...@@ -1391,7 +1391,7 @@ class ModuleCache: ...@@ -1391,7 +1391,7 @@ class ModuleCache:
next time we clear the cache. next time we clear the cache.
""" """
with compilelock.lock_ctx(): with lock_ctx():
for base_dir in ("cutils_ext", "lazylinker_ext", "scan_perform"): for base_dir in ("cutils_ext", "lazylinker_ext", "scan_perform"):
to_delete = os.path.join(self.dirname, base_dir + ".delete.me") to_delete = os.path.join(self.dirname, base_dir + ".delete.me")
if os.path.isdir(to_delete): if os.path.isdir(to_delete):
......
...@@ -2,8 +2,8 @@ import errno ...@@ -2,8 +2,8 @@ import errno
import os import os
import sys import sys
from theano.compile.compilelock import get_lock, release_lock
from theano.configdefaults import config from theano.configdefaults import config
from theano.gof.compilelock import get_lock, release_lock
from theano.link.c import cmodule from theano.link.c import cmodule
......
...@@ -6,8 +6,8 @@ import warnings ...@@ -6,8 +6,8 @@ import warnings
from importlib import reload from importlib import reload
import theano import theano
from theano.compile.compilelock import get_lock, release_lock
from theano.configdefaults import config from theano.configdefaults import config
from theano.gof.compilelock import get_lock, release_lock
from theano.link.c.cmodule import GCC_compiler from theano.link.c.cmodule import GCC_compiler
......
...@@ -17,8 +17,8 @@ from importlib import reload ...@@ -17,8 +17,8 @@ from importlib import reload
import numpy as np import numpy as np
import theano import theano
from theano.compile.compilelock import get_lock, release_lock
from theano.configdefaults import config from theano.configdefaults import config
from theano.gof.compilelock import get_lock, release_lock
from theano.link.c import cmodule from theano.link.c import cmodule
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论