Skip to content

Module deep-copies LoadBackendOptionsMap on load (#19673)#19673

Merged
meta-codesync[bot] merged 1 commit into
pytorch:mainfrom
metascroy:export-D105100372
May 19, 2026
Merged

Module deep-copies LoadBackendOptionsMap on load (#19673)#19673
meta-codesync[bot] merged 1 commit into
pytorch:mainfrom
metascroy:export-D105100372

Conversation

@metascroy
Copy link
Copy Markdown
Contributor

@metascroy metascroy commented May 19, 2026

Summary:

Module::load(LoadBackendOptionsMap&, ...) previously stored a raw
const-pointer to the caller's map (backend_options_), forcing every
caller (and every language binding) to keep the input map and its
backing BackendOption arrays alive past the load() call to keep lazy
load_method invocations safe. That contract is hard to express across
language boundaries (it's the reason the Apple bindings carry an extra
ivar to retain the wrapper -- removed in a follow-up).

Replace the borrowed-pointer with a Module-owned copy:

  • Module gains a (storage, owned map, has-flag) triple replacing the
    raw pointer. The storage is a vector-of-vectors that owns the
    BackendOption arrays; the owned map's Spans reference it.
  • load(LoadBackendOptionsMap&, ...) deep-copies via the new
    LoadBackendOptionsMap::entry_at(i) accessor into a local
    (storage, map) pair, calls load_internal, and only commits to the
    members on success. Transactional rollback for free.
  • load_method's fallback (when called with no explicit options) now
    reads the Module-owned map.

The signature of the public load(LoadBackendOptionsMap&, ...) overload
is unchanged; existing callers (XNNPACK runtime tests, dynamic_shim,
module_test) get the upgrade for free and may now release their
input map immediately after load() returns.

Reviewed By: shoumikhin

Differential Revision: D105100372

@metascroy metascroy requested a review from shoumikhin as a code owner May 19, 2026 16:31
@pytorch-bot
Copy link
Copy Markdown

pytorch-bot Bot commented May 19, 2026

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/19673

Note: Links to docs will display an error until the docs builds have been completed.

❗ 2 Active SEVs

There are 2 currently active SEVs. If your PR is affected, please view them below:

✅ No Failures

As of commit cba9369 with merge base f3387d0 (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 19, 2026
@meta-codesync
Copy link
Copy Markdown
Contributor

meta-codesync Bot commented May 19, 2026

@metascroy has exported this pull request. If you are a Meta employee, you can view the originating Diff in D105100372.

@github-actions
Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

@meta-codesync meta-codesync Bot changed the title Module deep-copies LoadBackendOptionsMap on load Module deep-copies LoadBackendOptionsMap on load (#19673) May 19, 2026
metascroy added a commit to metascroy/executorch that referenced this pull request May 19, 2026
Summary:

Module::load(LoadBackendOptionsMap&, ...) previously stored a raw
const-pointer to the caller's map (backend_options_), forcing every
caller (and every language binding) to keep the input map and its
backing BackendOption arrays alive past the load() call to keep lazy
load_method invocations safe. That contract is hard to express across
language boundaries (it's the reason the Apple bindings carry an extra
ivar to retain the wrapper -- removed in a follow-up).

Replace the borrowed-pointer with a Module-owned copy:

- Module gains a (storage, owned map, has-flag) triple replacing the
  raw pointer. The storage is a vector-of-vectors that owns the
  BackendOption arrays; the owned map's Spans reference it.
- load(LoadBackendOptionsMap&, ...) deep-copies via the new
  LoadBackendOptionsMap::entry_at(i) accessor into a local
  (storage, map) pair, calls load_internal, and only commits to the
  members on success. Transactional rollback for free.
- load_method's fallback (when called with no explicit options) now
  reads the Module-owned map.

The signature of the public load(LoadBackendOptionsMap&, ...) overload
is unchanged; existing callers (XNNPACK runtime tests, dynamic_shim,
module_test) get the upgrade for free and may now release their
input map immediately after load() returns.

Reviewed By: shoumikhin

Differential Revision: D105100372
@metascroy metascroy force-pushed the export-D105100372 branch from 54809fc to b12afa4 Compare May 19, 2026 16:47
metascroy added a commit to metascroy/executorch that referenced this pull request May 19, 2026
Summary:

Module::load(LoadBackendOptionsMap&, ...) previously stored a raw
const-pointer to the caller's map (backend_options_), forcing every
caller (and every language binding) to keep the input map and its
backing BackendOption arrays alive past the load() call to keep lazy
load_method invocations safe. That contract is hard to express across
language boundaries (it's the reason the Apple bindings carry an extra
ivar to retain the wrapper -- removed in a follow-up).

Replace the borrowed-pointer with a Module-owned copy:

- Module gains a (storage, owned map, has-flag) triple replacing the
  raw pointer. The storage is a vector-of-vectors that owns the
  BackendOption arrays; the owned map's Spans reference it.
- load(LoadBackendOptionsMap&, ...) deep-copies via the new
  LoadBackendOptionsMap::entry_at(i) accessor into a local
  (storage, map) pair, calls load_internal, and only commits to the
  members on success. Transactional rollback for free.
- load_method's fallback (when called with no explicit options) now
  reads the Module-owned map.

The signature of the public load(LoadBackendOptionsMap&, ...) overload
is unchanged; existing callers (XNNPACK runtime tests, dynamic_shim,
module_test) get the upgrade for free and may now release their
input map immediately after load() returns.

Reviewed By: shoumikhin

Differential Revision: D105100372
@metascroy metascroy force-pushed the export-D105100372 branch from b12afa4 to 1cb79b4 Compare May 19, 2026 17:12
Summary:

Module::load(LoadBackendOptionsMap&, ...) previously stored a raw
const-pointer to the caller's map (backend_options_), forcing every
caller (and every language binding) to keep the input map and its
backing BackendOption arrays alive past the load() call to keep lazy
load_method invocations safe. That contract is hard to express across
language boundaries (it's the reason the Apple bindings carry an extra
ivar to retain the wrapper -- removed in a follow-up).

Replace the borrowed-pointer with a Module-owned copy:

- Module gains a (storage, owned map, has-flag) triple replacing the
  raw pointer. The storage is a vector-of-vectors that owns the
  BackendOption arrays; the owned map's Spans reference it.
- load(LoadBackendOptionsMap&, ...) deep-copies via the new
  LoadBackendOptionsMap::entry_at(i) accessor into a local
  (storage, map) pair, calls load_internal, and only commits to the
  members on success. Transactional rollback for free.
- load_method's fallback (when called with no explicit options) now
  reads the Module-owned map.

The signature of the public load(LoadBackendOptionsMap&, ...) overload
is unchanged; existing callers (XNNPACK runtime tests, dynamic_shim,
module_test) get the upgrade for free and may now release their
input map immediately after load() returns.

Reviewed By: shoumikhin

Differential Revision: D105100372
@metascroy metascroy force-pushed the export-D105100372 branch from 1cb79b4 to cba9369 Compare May 19, 2026 17:15
@meta-codesync meta-codesync Bot merged commit 3d86cc7 into pytorch:main May 19, 2026
182 of 183 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported meta-exported

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants