forked from tensorflow/quantum
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathload_module.py
More file actions
84 lines (68 loc) · 3.04 KB
/
load_module.py
File metadata and controls
84 lines (68 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# Copyright 2020 The TensorFlow Quantum Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
"""Module to load python op libraries."""
import os
import types
from distutils.sysconfig import get_python_lib
from tensorflow.python.framework import load_library
from tensorflow.python.platform import resource_loader
class _LazyLoader(types.ModuleType):
"""Lazily loads a TensorFlow op library on first attribute access.
This defers the call to `load_library.load_op_library` until the module
is actually used, preventing TensorFlow device initialization at import
time. This allows users to configure TensorFlow devices (e.g., enabling
memory growth) after importing tensorflow_quantum.
"""
def __init__(self, name):
"""Initialize the lazy loader.
Args:
name: The name of the module, e.g. "_tfq_simulate_ops.so"
"""
super().__init__(name)
self._name = name
self._module = None
def _load(self):
"""Load the module if not already loaded."""
if self._module is None:
try:
path = resource_loader.get_path_to_datafile(self._name)
self._module = load_library.load_op_library(path)
except Exception: # pylint: disable=broad-except
path = os.path.join(get_python_lib(),
"tensorflow_quantum/core/ops", self._name)
self._module = load_library.load_op_library(path)
return self._module
def __getattr__(self, name):
"""Load the module on first attribute access and delegate."""
module = self._load()
return getattr(module, name)
def __dir__(self):
"""Return the directory of the loaded module for introspection."""
module = self._load()
return dir(module)
def load_module(name):
"""Returns a lazy loader for the module with the given name.
The actual library loading is deferred until the module is first used.
This prevents TensorFlow device initialization at import time, allowing
users to configure TensorFlow devices after importing tensorflow_quantum.
Args:
name: The name of the module, e.g. "_tfq_simulate_ops.so"
Returns:
A lazy loader object that behaves like the loaded module but defers
loading until first attribute access.
Raises:
RuntimeError: If the library cannot be found when first accessed.
"""
return _LazyLoader(name)