Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

zeVirtualMemMap of one physical object into a second VA range returns SUCCESS, then access through it gives ZE_RESULT_ERROR_DEVICE_LOST (Arc Pro B60)

オープン
#536 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
18/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
c, cpp
領域
devtools

調査の方向性

The repro is a single file, l0_alias_repro.cpp, built against the Level Zero loader (-lze_loader). Start by running it on an Intel GPU to see whether the second zeVirtualMemMap read fails with ZE_RESULT_ERROR_DEVICE_LOST, then look at the compute-runtime handling of physical memory mapped into multiple virtual ranges. Done means the aliased read returns the written bytes or the second map returns an error.

索引モデルが issue の本文から書いたものです。

説明

Summary
Mapping the same ze_physical_mem_handle_t into two reserved virtual ranges succeeds (both zeVirtualMemMap calls return ZE_RESULT_SUCCESS). A write through the first range completes, but the first access through the second range fails with ZE_RESULT_ERROR_DEVICE_LOST (0x70000001). From SYCL/PyTorch kernels the same access hangs instead. The spec does not say a physical object may be mapped only once, so either the second map should fail, or the alias should work.

Repro (single file, l0_alias_repro.cpp):

l0_alias_repro.cpp
// Level Zero: one physical memory object mapped into two virtual ranges.
// Writes through range A, then reads through range B with an immediate command list.
// Build: g++ -O1 l0_alias_repro.cpp -I/usr/local/include -L/usr/local/lib -lze_loader -o l0_alias_repro
#include <level_zero/ze_api.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>

#define CHECK(call)                                                       \
  do {                                                                    \
    ze_result_t r = (call);                                               \
    if (r != ZE_RESULT_SUCCESS) {                                         \
      std::printf("%s failed: 0x%x\n", #call, (unsigned)r);              \
      std::exit(1);                                                       \
    }                                                                     \
  } while (0)

int main() {
  CHECK(zeInit(ZE_INIT_FLAG_GPU_ONLY));
  uint32_t n = 1;
  ze_driver_handle_t driver;
  CHECK(zeDriverGet(&n, &driver));
  n = 1;
  ze_device_handle_t device;
  CHECK(zeDeviceGet(driver, &n, &device));
  ze_context_desc_t ctx_desc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
  ze_context_handle_t ctx;
  CHECK(zeContextCreate(driver, &ctx_desc, &ctx));

  size_t page = 0;
  CHECK(zeVirtualMemQueryPageSize(ctx, device, 2 << 20, &page));
  ze_physical_mem_desc_t pdesc = {ZE_STRUCTURE_TYPE_PHYSICAL_MEM_DESC, nullptr, 0, page};
  ze_physical_mem_handle_t phys;
  CHECK(zePhysicalMemCreate(ctx, device, &pdesc, &phys));

  void *va_a = nullptr, *va_b = nullptr;
  CHECK(zeVirtualMemReserve(ctx, nullptr, page, &va_a));
  CHECK(zeVirtualMemReserve(ctx, nullptr, page, &va_b));
  CHECK(zeVirtualMemMap(ctx, va_a, page, phys, 0, ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE));
  CHECK(zeVirtualMemMap(ctx, va_b, page, phys, 0, ZE_MEMORY_ACCESS_ATTRIBUTE_READWRITE));
  std::printf("page=%zu va_a=%p va_b=%p: both maps returned SUCCESS\n", page, va_a, va_b);

  ze_command_queue_desc_t qdesc = {ZE_STRUCTURE_TYPE_COMMAND_QUEUE_DESC, nullptr, 0, 0, 0,
                                   ZE_COMMAND_QUEUE_MODE_ASYNCHRONOUS, ZE_COMMAND_QUEUE_PRIORITY_NORMAL};
  ze_command_list_handle_t list;
  CHECK(zeCommandListCreateImmediate(ctx, device, &qdesc, &list));

  std::vector<unsigned char> src(page, 0x5a), dst(page, 0);
  CHECK(zeCommandListAppendMemoryCopy(list, va_a, src.data(), page, nullptr, 0, nullptr));
  CHECK(zeCommandListHostSynchronize(list, UINT64_MAX));
  std::printf("write through va_a: done\n");
  std::fflush(stdout);

  CHECK(zeCommandListAppendMemoryCopy(list, dst.data(), va_b, page, nullptr, 0, nullptr));
  // 10 s timeout: on Arc Pro B60 this read never completes
  ze_result_t r = zeCommandListHostSynchronize(list, 10ull * 1000 * 1000 * 1000);
  std::printf("read through va_b: result=0x%x, data %s\n", (unsigned)r,
              r == ZE_RESULT_SUCCESS ? (std::memcmp(src.data(), dst.data(), page) ? "WRONG" : "ok")
                                     : "not available");
  return r == ZE_RESULT_SUCCESS ? 0 : 2;
}
g++ -O1 l0_alias_repro.cpp -I/usr/local/include -L/usr/local/lib -lze_loader -o l0_alias_repro
ZE_AFFINITY_MASK=0 ./l0_alias_repro

Output:

page=2097152 va_a=0x7af6a2000000 va_b=0x7af6a1c00000: both maps returned SUCCESS
write through va_a: done
zeCommandListAppendMemoryCopy(list, dst.data(), va_b, page, nullptr, 0, nullptr) failed: 0x70000001

Expected: the read through va_b returns the bytes written through va_a (as cuMemMap allows on CUDA), or the second zeVirtualMemMap returns an error.

Environment

  • GPU: Intel Arc Pro B60 (Battlemage G21), xe kernel driver, kernel 6.14.0-37-generic
  • compute-runtime (libze-intel-gpu1): 26.18.38308.1
  • Level Zero loader: 1.28.0
  • OS: Ubuntu 25.04

Impact: SGLang's DWDP (expert-weight prefetch for MoE) has to unmap and remap pool pages before every layer on Level Zero instead of aliasing them, which costs a host synchronisation per layer (sgl-project/sglang#40763).

主要言語
C++
スター
337
フォーク
140
平均マージ
9時間 25分
マージ済み PR(30日)
13

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

oneapi-src/level-zero のほかの issue

oneapi-src/level-zero の issue をすべて見る

似ている issue

C++ の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。