Skip to content

[GPU] Support CPU pointers on remote tensor#36539

Merged
p-durandin merged 57 commits into
openvinotoolkit:masterfrom
michal-miotk:mmap
Jul 9, 2026
Merged

[GPU] Support CPU pointers on remote tensor#36539
p-durandin merged 57 commits into
openvinotoolkit:masterfrom
michal-miotk:mmap

Conversation

@michal-miotk

@michal-miotk michal-miotk commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Details:

  • supports pointers created by aligned_alloc and mmap
  • support only on OCL side

Tickets:

  • 189076

@michal-miotk michal-miotk requested review from a team as code owners June 23, 2026 16:04
@michal-miotk michal-miotk requested review from mfhansen and removed request for a team June 23, 2026 16:04
@github-actions github-actions Bot added category: inference OpenVINO Runtime library - Inference category: GPU OpenVINO GPU plugin category: build OpenVINO cmake script / infra category: CPP API OpenVINO CPP API bindings category: docs_snippets OpenVINO docs snippets (docs/snippets) labels Jun 23, 2026
@michal-miotk michal-miotk changed the title Mmap [GPU] Support CPU pointers on remote tensor Jun 23, 2026
@github-actions github-actions Bot removed the category: build OpenVINO cmake script / infra label Jun 23, 2026
@p-durandin p-durandin added this to the 2026.3 milestone Jun 24, 2026

@maxnick maxnick left a comment

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.

LGTM

Comment thread src/plugins/intel_gpu/include/intel_gpu/plugin/remote_tensor.hpp Outdated
Comment on lines +376 to +379
auto tracker = std::make_shared<MemoryTracker>(this,
cpu_address,
data_size,
allocation);

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.

Should this memory tracker be created? I guess there is no additional allocation when CL_MEM_FORCE_HOST_MEMORY_INTEL is used?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

tracker is needed in some places in code, constructed without engine not add allocation to statistic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

should be same pattern made in case of NTHandle ?

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.

Yes, I think we should only track OpenVINO allocations and do not count memory allocated by the user.

Comment thread src/plugins/intel_gpu/src/graph/program.cpp Outdated

@jkoniusz jkoniusz left a comment

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.

Maybe this is gonna be of some use to you:
The checks are failing because (I checked build_win_vs2022_release log):
"
[2026-07-08T09:07:41.198Z] C:\Jenkins\workspace\private-ci\ie\build-windows-vs2022\b\repos\openvino\src\plugins\intel_gpu\tests\functional\remote_tensor_tests\dx11_nthandle.cpp(252): error C3861: 'SharedBufferHandle': identifier not found
[2026-07-08T09:07:41.199Z] C:\Jenkins\workspace\private-ci\ie\build-windows-vs2022\b\repos\openvino\src\plugins\intel_gpu\tests\functional\remote_tensor_tests\dx11_nthandle.cpp(250): error C2668: 'ov::intel_gpu::ocl::ClContext::create_tensor': ambiguous call to overloaded function
"
Theres compile error

Allegedly now dx11_nthandle.cpp / dx12_nthandle.cpp still reference a SharedBufferHandle symbol.

SharedBufferHandle isn't a valid/visible name in those files — either it was never namespace-qualified (ov::intel_gpu::ocl::SharedBufferHandle), or it got renamed/removed when you refactored API.

Because that argument doesn't resolve, the create_tensor(...) call can't pick an overload → error C2668: ambiguous call.

@michal-miotk @maxnick @jkasprza

@michal-miotk

Copy link
Copy Markdown
Contributor Author

Maybe this is gonna be of some use to you: The checks are failing because (I checked build_win_vs2022_release log): " [2026-07-08T09:07:41.198Z] C:\Jenkins\workspace\private-ci\ie\build-windows-vs2022\b\repos\openvino\src\plugins\intel_gpu\tests\functional\remote_tensor_tests\dx11_nthandle.cpp(252): error C3861: 'SharedBufferHandle': identifier not found [2026-07-08T09:07:41.199Z] C:\Jenkins\workspace\private-ci\ie\build-windows-vs2022\b\repos\openvino\src\plugins\intel_gpu\tests\functional\remote_tensor_tests\dx11_nthandle.cpp(250): error C2668: 'ov::intel_gpu::ocl::ClContext::create_tensor': ambiguous call to overloaded function " Theres compile error

Allegedly now dx11_nthandle.cpp / dx12_nthandle.cpp still reference a SharedBufferHandle symbol.

SharedBufferHandle isn't a valid/visible name in those files — either it was never namespace-qualified (ov::intel_gpu::ocl::SharedBufferHandle), or it got renamed/removed when you refactored API.

Because that argument doesn't resolve, the create_tensor(...) call can't pick an overload → error C2668: ambiguous call.

@michal-miotk @maxnick @jkasprza

probably need add ov::intel_gpu:: before SharedBufferHandle

Copilot AI left a comment

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.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 4 comments.

createHeap(byte_size);

auto remote_tensor = context.create_tensor(ov::element::f32, tensor.get_shape(), shared_mem, ov::intel_gpu::MemType::SHARED_BUF);
auto remote_tensor = context.create_tensor(ov::element::f32, tensor.get_shape(), SharedBufferHandle(shared_mem));
Comment on lines +379 to +386
#ifdef CL_MEM_FORCE_HOST_MEMORY_INTEL
const size_t minimal_alignment = static_cast<size_t>(get_device_info().cacheline_size);
OPENVINO_ASSERT((reinterpret_cast<std::uintptr_t>(cpu_address) % minimal_alignment) == 0,
"[GPU] shared buffer pointer must be ", minimal_alignment, "-byte aligned");
OPENVINO_ASSERT((data_size % minimal_alignment) == 0,
"[GPU] shared buffer size must be a multiple of ", minimal_alignment, " bytes");
flags |= CL_MEM_FORCE_HOST_MEMORY_INTEL;
#endif

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@jkasprza should I add this ?

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.

I would prefer 1 additional check over risking undefined behavior. Even if we expect that cacheline_size is more than 0.

Comment on lines +394 to +405
std::shared_ptr<MemoryTracker> tracker = nullptr;
#ifdef CL_MEM_FORCE_HOST_MEMORY_INTEL
tracker = std::make_shared<MemoryTracker>(nullptr,
cpu_address,
data_size,
allocation);
#else
tracker = std::make_shared<MemoryTracker>(this,
cpu_address,
data_size,
allocation);
#endif

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this is my intention to not count this in statistic

Comment on lines +2957 to +2964
uint32_t cacheline_size = core.get_property(target_device, ov::intel_gpu::cacheline_size);
const size_t float_size = sizeof(float);
const ov::Shape shape{cacheline_size/float_size};
const size_t element_count = ov::shape_size(shape);
const size_t byte_size = element_count * sizeof(float);
auto ctx = core.get_default_context(target_device).as<ov::intel_gpu::ocl::ClContext>();
void* input_ptr = ov::util::aligned_alloc(byte_size, byte_size);
void* output_ptr = ov::util::aligned_alloc(byte_size, byte_size);

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

partially applied, proposed change: const ov::Shape shape{static_cast<size_t>(cacheline_size)}; not check bound case

@p-durandin p-durandin dismissed isanghao’s stale review July 8, 2026 14:47

Typo was fixed. So, I dismiss review to respect @isanghao time zone. I will put my approve

@p-durandin p-durandin enabled auto-merge July 8, 2026 14:48
@p-durandin p-durandin added this pull request to the merge queue Jul 9, 2026
Merged via the queue into openvinotoolkit:master with commit d64394f Jul 9, 2026
206 of 207 checks passed
Prithviraj-R added a commit to Prithviraj-R/openvino that referenced this pull request Jul 15, 2026
#### Details:
Description of the issue (symptom, root-cause, how it was resolved)
- Zero-copy handling for `usm_host` and `usm_shared` was already implemented in
  earlier PRs (openvinotoolkit#34494, openvinotoolkit#36539); this PR focuses on closing the `usm_device` gap.
- Previously, for `usm_device` allocations, a separate GPU `usm_device` buffer
  was allocated and filled from mapped host buffer data during cache load,
  causing duplicate allocation/copy overhead and increasing inference memory
  footprint.
- This change enables zero-copy subbuffer usage for supported XE2+ iGPUs in the
  `usm_device` flow, removing extra staging/copy in applicable cases.
- Blob offset alignment handling in deserialization is kept correct for
  subbuffer creation.

Implementation changes:
- Extend zero-copy eligibility in `data.hpp` to include `usm_device` while
  preserving existing `usm_host`/`usm_shared` behavior.
- Add/use helper check for zero-copy-capable device (XE2+ integrated GPU).
- Use `seek_current_ptr()` for padding skip during deserialization alignment.
- Refine zero-copy condition naming/readability in load path.

Changed files:
src/plugins/intel_gpu/include/intel_gpu/graph/serialization/binary_buffer.hpp
src/plugins/intel_gpu/include/intel_gpu/primitives/data.hpp
src/plugins/intel_gpu/include/intel_gpu/runtime/device_info.hpp
src/plugins/intel_gpu/src/graph/program.cpp
src/plugins/intel_gpu/src/runtime/ocl/ocl_device.cpp
src/plugins/intel_gpu/src/runtime/ocl/ocl_engine.cpp
src/plugins/intel_gpu/tests/unit/test_cases/cache_serialization_test.cpp

Reproduction step and snapshot (if applicable. Do not attach for customer model)
NA

Problematic graph
NA

#### Checklist
- [x] Is it a proper fix? Yes (removes duplicate `usm_device` staging/copy in
      supported zero-copy cases)
- [x] Did you include test case for this fix, if necessary? NA
- [x] Did you review existing test that can be extended to cover this scenario?
      NA

#### Tickets:
 - CVS-176160

#### AI Assistance:
 - AI assistance used: yes
 - AI was used for wording refinement and commit message cleanup.
Prithviraj-R added a commit to Prithviraj-R/openvino that referenced this pull request Jul 15, 2026
#### Details:
Description of the issue (symptom, root-cause, how it was resolved)
- Zero-copy handling for `usm_host` and `usm_shared` was already implemented in
  earlier PRs (openvinotoolkit#34494, openvinotoolkit#36539); this PR focuses on closing the `usm_device` gap.
- Previously, for `usm_device` allocations, a separate GPU `usm_device` buffer
  was allocated and filled from mapped host buffer data during cache load,
  causing duplicate allocation/copy overhead and increasing inference memory
  footprint.
- This change enables zero-copy subbuffer usage for supported XE2+ iGPUs in the
  `usm_device` flow, removing extra staging/copy in applicable cases.
- Blob offset alignment handling in deserialization is kept correct for
  subbuffer creation.

Implementation changes:
- Extend zero-copy eligibility in `data.hpp` to include `usm_device` while
  preserving existing `usm_host`/`usm_shared` behavior.
- Add/use helper check for zero-copy-capable device (XE2+ integrated GPU).
- Use `seek_current_ptr()` for padding skip during deserialization alignment.
- Refine zero-copy condition naming/readability in load path.

Changed files:
src/plugins/intel_gpu/include/intel_gpu/graph/serialization/binary_buffer.hpp
src/plugins/intel_gpu/include/intel_gpu/primitives/data.hpp
src/plugins/intel_gpu/include/intel_gpu/runtime/device_info.hpp
src/plugins/intel_gpu/src/graph/program.cpp
src/plugins/intel_gpu/src/runtime/ocl/ocl_device.cpp
src/plugins/intel_gpu/src/runtime/ocl/ocl_engine.cpp
src/plugins/intel_gpu/tests/unit/test_cases/cache_serialization_test.cpp

Reproduction step and snapshot (if applicable. Do not attach for customer model)
NA

Problematic graph
NA

#### Checklist
- [x] Is it a proper fix? Yes (removes duplicate `usm_device` staging/copy in
      supported zero-copy cases)
- [x] Did you include test case for this fix, if necessary? NA
- [x] Did you review existing test that can be extended to cover this scenario?
      NA

#### Tickets:
 - CVS-176160

#### AI Assistance:
 - AI assistance used: yes
 - AI was used for wording refinement and commit message cleanup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

category: CPP API OpenVINO CPP API bindings category: docs_snippets OpenVINO docs snippets (docs/snippets) category: GPU OpenVINO GPU plugin category: inference OpenVINO Runtime library - Inference Code Freeze

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants