Files
pytorch/caffe2/python/lazy_dyndep.py
Bugra Akyildiz 27c7158166 Remove __future__ imports for legacy Python2 supports (#45033)
Summary:
There is a module called `2to3` which you can target for future specifically to remove these, the directory of `caffe2` has the most redundant imports:

```2to3 -f future -w caffe2```

Pull Request resolved: https://github.com/pytorch/pytorch/pull/45033

Reviewed By: seemethere

Differential Revision: D23808648

Pulled By: bugra

fbshipit-source-id: 38971900f0fe43ab44a9168e57f2307580d36a38
2020-09-23 17:57:02 -07:00

85 lines
2.5 KiB
Python

## @package lazy_dyndep
# Module caffe2.python.lazy_dyndep
import os
from caffe2.python import dyndep, lazy
def RegisterOpsLibrary(name):
"""Registers a dynamic library that contains custom operators into Caffe2.
Since Caffe2 uses static variable registration, you can optionally load a
separate .so file that contains custom operators and registers that into
the caffe2 core binary. In C++, this is usually done by either declaring
dependency during compilation time, or via dynload. This allows us to do
registration similarly on the Python side.
Unlike dyndep.InitOpsLibrary, this does not actually parse the c++ file
and refresh operators until caffe2 is called in a fashion which requires
operators. In some large codebases this saves a large amount of time
during import.
It is safe to use within a program that also uses dyndep.InitOpsLibrary
Args:
name: a name that ends in .so, such as "my_custom_op.so". Otherwise,
the command will simply be ignored.
Returns:
None
"""
if not os.path.exists(name):
# Note(jiayq): if the name does not exist, instead of immediately
# failing we will simply print a warning, deferring failure to the
# time when an actual call is made.
print('Ignoring {} as it is not a valid file.'.format(name))
return
global _LAZY_IMPORTED_DYNDEPS
_LAZY_IMPORTED_DYNDEPS.add(name)
_LAZY_IMPORTED_DYNDEPS = set()
_error_handler = None
def SetErrorHandler(handler):
"""Registers an error handler for errors from registering operators
Since the lazy registration may happen at a much later time, having a dedicated
error handler allows for custom error handling logic. It is highly
recomended to set this to prevent errors from bubbling up in weird parts of the
code.
Args:
handler: a function that takes an exception as a single handler.
Returns:
None
"""
global _error_handler
_error_handler = handler
def GetImportedOpsLibraries():
_import_lazy()
return dyndep.GetImportedOpsLibraries()
def _import_lazy():
global _LAZY_IMPORTED_DYNDEPS
if not _LAZY_IMPORTED_DYNDEPS:
return
for name in list(_LAZY_IMPORTED_DYNDEPS):
try:
dyndep.InitOpLibrary(name, trigger_lazy=False)
except BaseException as e:
if _error_handler:
_error_handler(e)
finally:
_LAZY_IMPORTED_DYNDEPS.remove(name)
lazy.RegisterLazyImport(_import_lazy)