Skip to content

[CVS-182698] Fix tensor import failure caused by read-only blob tensor#971

Merged
n1harika merged 3 commits intoovep-developfrom
niharika/mutable_tensor
Mar 20, 2026
Merged

[CVS-182698] Fix tensor import failure caused by read-only blob tensor#971
n1harika merged 3 commits intoovep-developfrom
niharika/mutable_tensor

Conversation

@n1harika
Copy link

Fix tensor import failure in OVEP caused by blob tensors being created as read-only views.
Construct the tensor as a mutable pointer so OV core.import_model() can access the blob for file-mapped behavior.

Copy link

@MayureshV1 MayureshV1 left a comment

Choose a reason for hiding this comment

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

The failing scenario passes !

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes OpenVINO EP compiled-model blob import failures by changing how native blob tensors are constructed so ov::Core::import_model() can access the underlying blob bytes when the blob comes from a file-mapped tensor.

Changes:

  • Build native blob tensors from an explicit u8 pointer + shape instead of creating a sub-tensor view into the mapped file tensor.
  • Use const_cast to pass a mutable pointer to OpenVINO tensor construction for both mapped-file blobs and embedded-vector blobs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 176 to +183
auto blob_offset = blob_container.serialized_info.file_offset;
auto blob_size = blob_container.serialized_info.size;
ov::Coordinate begin{blob_offset};
ov::Coordinate end{blob_offset + blob_size};
blob_container.tensor = ov::Tensor(mapped_bin_, begin, end);
const uint8_t* src = mapped_bin_.data<const uint8_t>() + blob_offset;

blob_container.tensor = ov::Tensor(
ov::element::u8,
ov::Shape{blob_size},
const_cast<uint8_t*>(src));
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

src is computed via pointer arithmetic without validating that blob_offset + blob_size stays within the mapped file tensor. If the BSON metadata is corrupt/mismatched (or a truncated external .bin is used), this can create an out-of-bounds pointer and later crash/UB when OpenVINO reads it. Add an ORT_ENFORCE range check against mapped_bin_.get_byte_size() (and also guard against integer overflow) before forming the pointer / tensor.

Copilot uses AI. Check for mistakes.
Comment on lines +178 to +189
const uint8_t* src = mapped_bin_.data<const uint8_t>() + blob_offset;

blob_container.tensor = ov::Tensor(
ov::element::u8,
ov::Shape{blob_size},
const_cast<uint8_t*>(src));
} else {
// Create a tensor from embedded data vector
blob_container.tensor = ov::Tensor(
ov::element::u8,
ov::Shape{blob_container.data.size()},
blob_container.data.data());
const_cast<uint8_t*>(blob_container.data.data()));
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

This introduces const_cast<uint8_t*>(...) to satisfy ov::Tensor's mutable-pointer constructor, but it drops const-safety for memory that may be genuinely read-only (mmap) and makes the intent unclear. Consider matching the existing pattern in ov_shared_context.cc by using a read-only ov::Tensor constructor when OPENVINO_VERSION_AT_LEAST(2026, 0) is available, and only using const_cast on older OpenVINO versions (with an explicit comment that the buffer must not be written).

Copilot uses AI. Check for mistakes.
ov::element::u8,
ov::Shape{blob_container.data.size()},
blob_container.data.data());
const_cast<uint8_t*>(blob_container.data.data()));
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

blob_container.data.data() is already a mutable uint8_t* here, so the const_cast is unnecessary and makes it harder to reason about where const is being removed. Prefer passing blob_container.data.data() directly.

Suggested change
const_cast<uint8_t*>(blob_container.data.data()));
blob_container.data.data());

Copilot uses AI. Check for mistakes.
Copy link

@MayureshV1 MayureshV1 left a comment

Choose a reason for hiding this comment

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

@n1harika , Can you please look into CoPilot suggestions and if you prefer to make an implementation change,

@n1harika n1harika force-pushed the niharika/mutable_tensor branch from b2052b7 to 94eca74 Compare March 20, 2026 04:15
@n1harika n1harika merged commit e47ea73 into ovep-develop Mar 20, 2026
7 of 8 checks passed
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