| ## @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) |