Skip to content

fix: Do not mutate external TensorInfo in import_memory()#1270

Open
morgolock wants to merge 1 commit intomainfrom
pr/tinfo_soft_init
Open

fix: Do not mutate external TensorInfo in import_memory()#1270
morgolock wants to merge 1 commit intomainfrom
pr/tinfo_soft_init

Conversation

@morgolock
Copy link
Copy Markdown
Contributor

When a TensorInfo is shared with a Tensor via allocator()->soft_init(), the allocator stores a reference to the caller-provided TensorInfo. If import_memory() is later called, the allocator currently sets TensorInfo::is_resizable(false). Because the TensorInfo is shared, this mutates the caller-owned metadata. Subsequent operations that expect the TensorInfo to remain resizable (e.g. extend_padding()) can fail.

This is observable in multi-threaded or reused inference paths (for example multi-threaded CpuGemmConv2d), where the same TensorInfo is reused across runs. In such cases import_memory() unexpectedly changes the caller-visible TensorInfo state. Fix this by distinguishing between allocator-owned and external TensorInfo instances:

  • Track ownership with _owns_info.
  • Track imported buffers with _is_imported.
  • soft_init() marks the TensorInfo as externally owned.
  • import_memory() only mutates TensorInfo::is_resizable() when the allocator owns the TensorInfo.
  • When referencing external TensorInfo, allocator logic relies on the internal _is_imported state instead of mutating the caller metadata.

This preserves existing behaviour for allocator-owned TensorInfo while avoiding unexpected mutations of caller-provided metadata.

The change is minimal and does not modify public APIs.

Test:

  • Add/enable UNIT test ImportMemoryDoesNotMutateExternalInfo.
  • Verify that shared_info.is_resizable() remains true after import_memory() and that extend_padding() succeeds.

Change-Id: Iac9d5807789a8ed74205cdee098b36d0f5269d59

Copy link
Copy Markdown
Contributor

@gunes-arm gunes-arm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, these were comments from last week. I forgot to post. Feel free to take it with another reviewer. If not, I'll prioritize this when I get back.

…soft_init

When a TensorInfo is shared with a Tensor via allocator()->soft_init(), the allocator stores a reference to the caller-provided TensorInfo. If import_memory() is later called, the allocator currently sets TensorInfo::is_resizable(false). Because the TensorInfo is shared, this mutates the caller-owned metadata. Subsequent operations that expect the TensorInfo to remain resizable (e.g. extend_padding()) can fail.

This is observable in multi-threaded or reused inference paths (for example multi-threaded CpuGemmConv2d), where the same TensorInfo is reused across runs. In such cases import_memory() unexpectedly changes the caller-visible TensorInfo state.
Fix this by distinguishing between allocator-owned and external TensorInfo instances:

- Track ownership with `_owns_info`.
- Track imported buffers with `_is_imported`.
- `soft_init()` marks the TensorInfo as externally owned.
- `import_memory()` only mutates `TensorInfo::is_resizable()` when the
  allocator owns the TensorInfo.
- When referencing external TensorInfo, allocator logic relies on the
  internal `_is_imported` state instead of mutating the caller metadata.

This preserves existing behaviour for allocator-owned TensorInfo while avoiding unexpected mutations of caller-provided metadata.

The change is minimal and does not modify public APIs.

Test:
- Add/enable UNIT test `ImportMemoryDoesNotMutateExternalInfo`.
- Verify that `shared_info.is_resizable()` remains true after
  import_memory() and that `extend_padding()` succeeds.

Change-Id: Iac9d5807789a8ed74205cdee098b36d0f5269d59
Signed-off-by: Pablo Marquez Tello <pablo.tello@arm.com>
@morgolock morgolock force-pushed the pr/tinfo_soft_init branch from fb2d829 to 70794ba Compare March 23, 2026 16:45
@walidbr walidbr requested review from walidbr and removed request for walidbr March 25, 2026 17:45
TensorInfo _info_owned{}; /**< Tensor's metadata. */
TensorInfo *_info_external{nullptr}; /**< External Tensor's metadata */
size_t _alignment{}; /**< Tensor's alignment in bytes */
bool _owns_info{true}; /**< True when allocator owns metadata; false for soft_init(). */
Copy link
Copy Markdown
Contributor

@gunes-arm gunes-arm Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this field is extra. From other places, I can see that _info_external is checked against nullptr to decide if the info is owned or not. It seems like having a member function with owns_info checking _info_external != nullptr is the best way if we need convenience.

For example, info is returned based on this check, not the member _owns_info.

TensorInfo &ITensorAllocator::info()
{
    return (_info_external != nullptr) ? *_info_external : _info_owned;
}

_is_imported = imported;
}

bool ITensorAllocator::allocator_considers_resizable() const
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no usage of this. Do we need it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants