Fix TensorFlow Device Configuration After Import #947
+153
−13
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fix #911
Fix TensorFlow Device Configuration After Import
Overview
This PR fixes an issue where importing
tensorflow_quantumwould trigger TensorFlow device initialization, preventing users from configuring devices afterward. This caused aRuntimeError: Physical devices cannot be modified after being initializedwhen attempting to set device configuration (e.g., GPU memory growth) after importing TFQ.Problem Statement
Current Behavior (Before Fix)
Error:
RuntimeError: Physical devices cannot be modified after being initializedRoot Cause
Multiple op modules in
tensorflow_quantumcalledload_module()at module-level import time:tfq_utility_ops.pytfq_simulate_ops.pytfq_unitary_op.pytfq_adj_grad_op.pytfq_ps_util_ops.pynoisy_samples_op.pynoisy_sampled_expectation_op.pynoisy_expectation_op.pyThe
load_module()function directly calledload_library.load_op_library(), which initialized TensorFlow devices immediately.Solution
Approach: Lazy Loading
Implemented a
_LazyLoaderclass that defers the actual library loading until the ops are first accessed. This allows TensorFlow device configuration to happen after importing TFQ.Key Changes
File:
tensorflow_quantum/core/ops/load_module.pyAdded
_LazyLoaderclass:__getattr__()to load on first attribute accessModified
load_module()function:_LazyLoaderinstance instead of directly loadingHow It Works
Expected Behavior (After Fix)
Backward Compatibility
✅ Fully backward compatible
__getattr__(), making it transparent to usersFiles Modified/Added
Modified
tensorflow_quantum/core/ops/load_module.py- Core fix with lazy loading implementationAdded
tensorflow_quantum/core/ops/load_module_test.py- Unit tests for lazy loadertest_device_config_after_import.py- Integration test demonstrating the fixTesting
Unit Tests (
load_module_test.py)Integration Test (
test_device_config_after_import.py)Demonstrates the fix in action:
Running Tests
Performance Impact
Minimal impact:
Use Cases Fixed
1. GPU Memory Configuration
2. Device Placement
3. Multiple GPU Setup
Breaking Changes
None. This is a non-breaking fix that improves behavior without changing the API.
Verification
The fix has been verified to:
Related Issues
RuntimeError: Physical devices cannot be modified after being initializedDocumentation
For users encountering this issue, the recommended pattern is now:
Implementation Details
_LazyLoader Class
tensorflow_quantum/core/ops/load_module.py__getattr__()to intercept attribute access_moduleattribute for reuseLoad Process
load_module("name.so")creates_LazyLoaderinstanceUTILITY_OP_MODULE.tfq_append_circuit):__getattr__()is called_load()method loads the actual library_moduleRollback Plan
If needed, rollback is simple:
load_module.pyFuture Improvements
Questions?
For questions about this implementation, refer to:
load_module.pyload_module_test.pytest_device_config_after_import.py