Skip to content

Add native Windows support for Intel SYCL GPUs - #2079

Open
lm902 wants to merge 4 commits into
Niko1221:mainfrom
lm902:windows-intel-native
Open

lm902 wants to merge 4 commits into
Niko1221:mainfrom
lm902:windows-intel-native

Conversation

@lm902

@lm902 lm902 commented Oct 12, 2026

Copy link
Copy Markdown

Summary

Add native Windows support for the Intel SYCL backend, using the existing START-HERE.bat installer entry point. This PR contains only the necessary Windows/Intel compatibility code and installer regression tests. It does not contain models, local configurations, benchmark scripts, logs, dumps, documentation changes, or user backups.

This is a new, independent PR based on upstream main at 7695859aa13afb248bdb4d36f9b2e95707db079d (engine 0.1.43). It does not reuse or modify the earlier conflicted PR.

Changes

  • Route an Intel-only Windows installation to native SYCL; retain the existing NVIDIA/AMD default on mixed-GPU systems and honor an explicit backend choice.
  • Build with Visual Studio C++ and Intel oneAPI using sycl/tools/build_windows.bat; use Windows floating-point/MKL flags and required Windows libraries. Keep Linux flags and paths unchanged.
  • Discover the Intel GPU and 64-bit VRAM size before an engine exists, then use the native engine's JSON device probe. Report PCI device IDs so A-series FP64 emulation settings are retained. Pin a selected Windows GPU through ONEAPI_DEVICE_SELECTOR instead of relying on CUDA_VISIBLE_DEVICES.
  • Use native paths, runtime DLL search directories, the real Windows RAM budget, and the existing Intel server wrapper. Keep GPU device-plan/no-host safeguards enabled on the native streamed path.
  • Replace POSIX GGUF positional reads with independent Win32 overlapped reads and pointer-width file handles. Query available physical RAM with GlobalMemoryStatusEx for the expert-mirror budget.
  • Do not label an ordinary Windows VirtualAlloc arena as registered GPU host memory. Enable the Level Zero host-allocation path only when both its headers and loader library are available.
  • Resolve Windows SDK macro collisions and replace parity-test environment setters with their Windows equivalents. No quantization formats or mathematical kernel algorithms are changed.

Test environment

Measured locally on October 11-12, 2026, using the upstream baseline above plus this Windows port:

Component Environment
OS Windows 11 Pro for Workstations Insider Preview, build 26220, x64
GPU Intel Arc Pro B70, nominal 32 GB; runtime reports 31.159 GiB
Intel graphics driver 32.0.101.9034
CPU Intel Core i9-13900KF; AVX2, no AVX-512
RAM 64 GB installed
Build Visual Studio 2022 17.14.40, MSVC 14.44; Windows SDK 10.0.26100
Intel toolchain oneAPI DPC++/C++ 2026.1.1; oneMKL 2026.1.0
Engine Native x64 SYCL/Level Zero, Release/Ninja, SPIR-V JIT; stateless >4-GiB addressing
Python 3.11.9

No Docker, WSL, or /dev/dxg was used. Tests explicitly selected level_zero:gpu, disabled the persistent SYCL cache, and retained STRATA_VERIFY_DEVICE_PLAN=1 and STRATA_VERIFY_NO_HOST=1. Disabling persistent caching is a recorded test setting, not a new installer default. CUDA/HIP hardware and Linux execution were not validated on this machine.

Build and regression validation

Re-run after the final Windows device-selection/PCI-ID fixes:

  • python -m unittest discover -s tools -p "test_setup*.py": 479 tests passed.
  • sycl\tools\build_windows.bat: all Windows SYCL targets built successfully.
  • Native strata.exe --list-devices: correctly reports the B70, 31.159 GiB, Level Zero, PCI device ID e223.
  • ctest --test-dir build-sycl-win --output-on-failure -E "^(gr_parity|ple_parity|s2_expert_grouped_parity)$": 30/30 passed on the B70. This is not a claim that all 33 tests passed. The exclusions encountered earlier were gr_parity (unsupported QFUSE path), ple_parity (missing external fixture), and s2_expert_grouped_parity (bitwise mismatch); they are not changed or hidden by this PR.
  • The original START-HERE.bat path, model-menu installation, native build/start, and real chat were tested during port validation. Earlier full-model checks passed all 48 expert layers and the resident-cache byte check (0/12288 mismatches).
  • git diff --check: passed.

Local performance measurements

These are functional/capacity measurements, not before/after speedup claims, quality benchmarks, or a general hardware recommendation. Each reported case is one warmed measurement, not a multi-run average. Inputs were identical within each model-comparison test; first-token changes prevented prefix-cache reuse. Successful cases had zero reused prompt tokens and generated exactly 256 new tokens. Expert computation stayed on the GPU, including experts read over PCIe from pinned RAM. The total model size must not be interpreted as all weights fitting in VRAM; the PLE table stays on disk.

Original models and Coder: preallocated 262144-token capacity

Protocol: native --kv int8 (64 values per FP16 scale, not strict GGML Q8_0), STRATA_KV_GROW=0, auto expert cache, streamed experts, 2048 MiB VRAM reserve, prefill chunks of 4096, 15 pool workers, 12 stager threads, temperature 0, MTP maximum 4 and --spec-min-p 0.5. The engine also has lookup drafts; the aggregate INFO spec count is 6, so this is not non-speculative decoding. A 4096-input/128-output warmup preceded each run. The 255K tests used 261120 actual input tokens, leaving room within 262144 for 256 output tokens.

KV modes: GPU = all allocated KV in VRAM (--kv-resident 0); stream = full KV in RAM plus a 32768-token VRAM window (--kv-resident 32768). Values below are prefill / decode tokens per second.

Model KV mode 128 input 32768 input 131072 input 261120 input
Coder IQ1_M GPU 180.9 / 44.4 1339.1 / 46.7 1143.8 / 41.6 964.6 / 40.9
Q2_0 GPU 179.5 / 54.3 992.2 / 55.4 1067.8 / 50.8 888.4 / 51.3
Q2_0 stream 210.1 / 65.6 1273.1 / 60.3 1103.4 / 54.0 916.0 / 54.8
IQ2_XS GPU 180.1 / 61.6 1177.4 / 61.4 1018.1 / 57.6 860.7 / 54.8
IQ2_XS stream 189.5 / 76.1 1200.6 / 71.8 1039.9 / 66.8 874.8 / 64.8
IQ3_XXS GPU 141.8 / 40.2 1061.2 / 42.6 936.7 / 40.4 794.8 / 38.7
IQ3_XXS stream 150.6 / 47.2 1086.0 / 49.4 955.0 / 47.2 807.5 / 45.9
IQ3_S GPU 109.9 / 28.0 968.1 / 26.6 863.6 / 32.4 743.0 / 32.1
IQ3_S stream 125.2 / 32.7 996.8 / 31.1 891.3 / 37.7 760.4 / 37.1

Original-model repository revision: ISTA-DASLab/Qwen3.8-Flash-Next-GSQ-RCO-GGUF at ed59f92082b1e93c0e96d60a8b11aab089b52f09. Total GGUF sizes (decimal GB): Coder IQ1_M 58.409; Q2_0 66.424; IQ2_XS 68.026; IQ3_XXS 75.840; IQ3_S 83.618. IQ3_S was the largest original tier actually tested successfully, not a proven absolute capacity limit.

At 261120 input tokens, IQ3_S sampled dedicated GPU memory peaked at approximately 28.48 GiB in both modes; shared GPU memory peaked at 30.31 / 31.05 GiB, engine working set at 32.58 / 33.41 GiB, and minimum available system RAM at 7.73 / 7.15 GiB (GPU / stream). Shared GPU memory overlaps the process working set and must not be added to it; process private commit is not physical RAM usage. Successful paired original-model outputs matched, including the 255K tests.

OrcaRouter IQ3_XXS: independent compatibility-pack check

Local two-shard orcarouter/Qwen3.8-Flash-Next-Uncensored-GGUF, 85.203 GB total, download revision d27c0a15447dd92ae7c90919352c6810496945b1; both SHA256 hashes matched the local download metadata. Prepared an independent --compat-bf16 pack and used this model's own tokenizer/chat template. Converted 459 tensors (96 exact, 363 rounded); 1.22 GiB BF16 conversions and 1.38 GiB packed dense arena. Expert bytes and PLE table were unchanged. This conversion does not recover the original BF16 checkpoint or prove its quality.

Protocol differs from the table above: 32768 capacity, 512-token prefill chunks, full-GPU INT8 KV, original expert profile and original MTP runtime as in docs/ORCA.md, MTP maximum 4, temperature 0, 2048 MiB reserve, native streamed experts/no CPU fallback. Arithmetic returned 2603 for 137*19; translation returned "你好,世界!"; the generated square(x) function passed an AST syntax check (generated code was not executed).

Actual input tokens Prefill tok/s Prefill seconds Decode tok/s Decode seconds
128 33.7 3.80 11.5 22.26
8192 140.4 58.34 20.5 12.48
31744 278.9 113.80 22.5 11.39

All three cases generated 256 tokens, finished at the output-length limit, reused no prefix cache, and did not trigger the RAM guard. GPU log: 11193 resident experts (22.68 GiB), all 13383 remaining experts mirrored (27.12 GiB), resident experts computed on the B70. Sampled peaks: dedicated GPU 28.35 GiB, shared GPU 27.54 GiB, engine working set 29.16 GiB; minimum available system RAM 15.51 GiB. This used the Windows GPU-cache/RAM-mirror path rather than the document's full approximately 49.8-GiB expert arena. HTTP/API, vision, multi-turn/cancellation and 256K Orca operation were not tested in this check.

Failures and limits disclosed

  • Coder with streamed KV was not stable. An initial short/32K run completed, but 128K prefill hit the 60-second stall watchdog. A same-parameter retry stalled during 32K. No RAM guard triggered; the cause is not established. It is intentionally omitted from the successful-performance table and was not tested at 255K.
  • Unsloth UD-IQ4_XS and UD-Q4_K_XL did not complete benchmarks on this 32-GB GPU/64-GB RAM machine with 262144 preallocated INT8 KV. At 4096-token chunks, the no-host coverage guard rejected both KV modes: IQ4_XS had 377/163 uncovered experts; Q4_K_XL had 5574/5572 (GPU/stream).
  • An isolated IQ4_XS 2048-token chunk retry reached READY in both modes, but the 4096-token warmup was canceled after 2048 input tokens with zero output: available RAM fell to 1.54/1.84 GiB, below the 2-GiB test guard. Those canceled requests have no valid performance result. No guard was disabled or context capacity reduced to force success. This is a tested configuration limit, not a universal statement that the formats cannot run.
  • Performance varies with prompt, draft acceptance, current desktop VRAM use, and I/O. The Orca 512-chunk protocol is not directly comparable with the original-model 4096-chunk protocol or the document's RTX 5090/Linux example.

All local models, configs, raw measurements and test artifacts are preserved outside the commit. No existing PR has been edited or closed.

@demetree

Copy link
Copy Markdown
Contributor

Same card as yours, different driver, and Level Zero does not load — data point for the test request

I read this PR with interest because you have Level Zero working on a B70, and I have one where it does not. Both are 32 GB Arc Pro B70 cards. The difference that looks meaningful is the driver:

yours mine
GPU Arc Pro B70, 32 GB (31.159 GiB) Arc Pro B70, 32 GB
OS Windows 11 Pro for Workstations 26220 (Insider) Windows 11 24H2
Driver 32.0.101.9034 — Level Zero loads 32.0.101.8976 — Level Zero does not load
Backend native SYCL / Level Zero OpenCL (UR adapters fall back)

With my driver the Level Zero loader fails (a V2 loader against a V1-only ICD). Pointing ZEL_LIBRARY_PATH at the driver store's ze_loader.dll does not fix it, and both ur_adapter_level_zero.dll and ur_adapter_level_zero_v2.dll report nothing. The UR adapters then fall back to OpenCL, and that is where it gets hard: on this backend oneMKL SYCL BLAS is not usable, the SYCL Graph extension does not exist, and ext_intel_free_memory answers "not supported" so get_memory_info returns 0.

If 8976 vs 9034 is the whole story then this is narrowly a driver-version problem and your PR is the right fix — people upgrade and it just works. But I cannot tell from one machine whether that is the case, which is what I am asking for in #2103.

The failure mode worth fixing regardless of backend. When the free-VRAM query answers 0, the engine sizes its expert cache to zero slots and then refuses with:

REFUSED: N experts are neither in VRAM nor mirrored; with STRATA_VERIFY_NO_HOST the
device plan cannot run them and generation would lack a safe host fallback

That message points at the mirror, which is a red herring — the real cause is two steps earlier, where the VRAM figure this backend cannot provide was 0 and nothing said so. The engine computes "0 bytes free" and then reports a problem about experts. That is a diagnosability bug that would bite any backend whose free-memory query stops answering, and I would fix it independently of which backend it happens on.

Two things I am specifically curious about, since you have the working end of this:

  1. Does your installer check which adapter it got? If an Intel-only Windows install lands on a machine where Level Zero is absent, the UR adapters silently fall back to OpenCL and the engine then dies as above — with nothing in the install path saying so. Detecting it at install time (sycl-ls, or the probe you already use for the device and VRAM size) and refusing with "this driver has no Level Zero adapter; upgrade to X" would have saved me a long evening.

  2. Your STRATA_SYCL_JIT_STATELESS note — I carried the same IGC >4 GiB surface-offset fix on an A770 (an expert cache's last 0.46 GiB dequantizing to NaN, every prompt answering !!!!) in sycl: Windows/OpenCL support for the merged port, and a live free-VRAM figure for the expert cache (#1549) #1890. Worth knowing we both hit it; you may have a better shape for it on a newer oneAPI.

For reference, if it is useful to anyone: #2103 is the test-request row for exactly this question, and #1890 is the OpenCL-fallback port that covers my end (a plain-SYCL fallback GEMM, the eager commit path, and a live DXGI free-VRAM figure). #2106 completes STRATA_VERIFY_EAGER for the commit path, which is backend-independent — your tests run with level_zero:gpu so you may not need it, but the flag is half-built in verify.cpp on main and mtp.cpp's prepare_chain() already documents the gap.

Happy to measure anything specific on the broken-LZ machine if it would help you decide what to do about the fallback path.

@demetree

Copy link
Copy Markdown
Contributor

Correction: the driver version is not the difference — please disregard that hypothesis

I owe a correction to the analysis above. I suggested the split between your working Level Zero and my broken one was the graphics driver version (your 32.0.101.9034 vs my 32.0.101.8976). That is wrong, and I should not have posted it as a hypothesis without checking.

The disproof is your own project's neighbourhood: PR #1940 reports a working Level Zero B70 on driver 32.0.101.8976 — the exact driver on my machine — with decode 50-76 tok/s at 262K context, SYCL_UR_USE_LEVEL_ZERO_V2=1 and ZES_ENABLE_SYSMAN=1. Same driver, opposite outcome. So the version is not the discriminator and I withdraw that part.

What I can actually show, now that I looked properly

On this box, sycl-ls segfaults (0xC0000005) unless ZEL_LIBRARY_PATH points at ...\iigd_dch.inf_amd64_a34e85e556ccdec6\ze_loader.dll, which is a Level Zero v1 loader, version 1.2.3. With that forced, the enumeration is:

[opencl:gpu]  Intel(R) Arc(TM) Pro B70 Graphics  OpenCL 3.0 NEO  [32.0.101.8976]
[opencl:cpu]  Intel(R) Core(TM) i9-9900 CPU

No Level Zero device appears at all — not filtered out, absent. I also tried pointing ZEL_LIBRARY_PATH at the 1.32.0 v2 loader that ships inside the conda oneAPI environment I build with, and the result was identical: OpenCL only, no level_zero:*. So on this machine the Level Zero UR adapter enumerates zero devices regardless of which loader I hand it.

That is a loader/ICD combination problem on my end, not a property of Windows or of the driver. #1940's note that 2026.1.1's Level Zero v2 adapter "crashes on its first use" matches my first symptom exactly, and they avoided it by building on oneAPI 2026.0.0 where I use 2026.1.1 — so my current best guess is a toolchain/loader mismatch rather than a driver one. That is a guess too, and I am labelling it as one.

What this changes for the thread

My #2103 test-request row asked whether a Windows Arc can lack Level Zero permanently. Given #1940, the honest answer is probably not — the likely case is a broken local install like mine, exactly what your setup.py routing would catch if it verified which adapter it got rather than assuming. My original question to you stands and is now sharper: does your install path check that level_zero:gpu actually enumerated? If an Intel-only Windows machine lands on OpenCL the way mine did, it dies with a confusing VRAM figure rather than a "your Level Zero is broken" message.

I'll stop asking the driver question and go fix my loader. If I get level_zero:gpu enumerating I'll come back and say so, because it will mean my #1890 — the OpenCL fallback port — is unnecessary rather than merely overlapping with yours.

Nothing in the rest of my first comment changes: the STRATA_SYCL_JIT_STATELESS overlap between our two PRs is real, and the "engine computes 0 bytes of free VRAM, then blames the expert mirror" failure mode is a diagnosability bug worth fixing on any backend.

@K8-and-a-half-1000

Copy link
Copy Markdown

#1940 enumerates the level_zero:gpu using strata-devices.exe 👆
start there

@demetree

Copy link
Copy Markdown
Contributor

Root cause found on my machine: the Level Zero driver is fine, the ICD is not — and a driver update looks like the fix

I installed the standalone oneAPI 2026.0.0 and chased this to a conclusion. Short version: Level Zero on this box is healthy at the driver level and blocked above it, by an ICD that predates every current SYCL Level Zero adapter. That makes it a driver-version problem, which is different from what I suggested earlier and closer to your original read.

The driver is fine

Calling Level Zero directly, with no SYCL and no UR in the way, through the v1 loader the driver ships:

zeInit(0)             -> 0x0
drivers               -> 1
zeDeviceGet(count)    -> 0x0, devices=1
zeDriverGetProperties -> 0x0, driverVersion 17013007 (1.15.39183+7)
zeDeviceGetProperties -> 0x0
    type                  -> TYPE_GPU (1)
    vendorId / deviceId   -> 0x8086 / 0xe223          (Arc Pro B70, BMG-G31)
    maxMemAllocSize       -> 31.2 GiB

That is within one build of the driver version you report on your working B70. So the card, the driver and the ICD all answer correctly.

The loaders and adapters above it do not

SYCL_UR_TRACE=1 is what finally made this legible. From conda's oneAPI, the UR loader loads all three adapters, including both Level Zero ones:

loaded adapter ...ur_adapter_level_zero.dll
loaded adapter ...ur_adapter_level_zero_v2.dll
loaded adapter ...ur_adapter_opencl.dll

and then sycl-ls crashes with 0xC0000005 before listing anything. Every Level Zero adapter I have access to does the same against this ICD:

adapter source against this ICD
2026.1.0.0 conda dpcpp_win-64=2026.1.1 crashes 0xC0000005
2026.0.0.0 conda dpcpp_win-64=2026.0.0 adapter never even loads (no ze_loader.dll)
2026.0.0.0 standalone oneAPI 2026.0.0 install crashes 0xC0000005

Two related measurements, since they narrow it further:

  • Registering the ICD in the registry the way OpenCL ICDs are registered turns the modern loader's ZE_RESULT_ERROR_UNINITIALIZED into a straight 0xC0000005 — so "the loader cannot find the ICD" was never the whole story; once it finds it, it crashes. I reverted that test.
  • Neither the standalone install nor conda's 2026.0.0 ships a ze_loader.dll at all; both expect the driver's, which is a v1-era loader. The driver ships its own matching loader precisely because it must.

So the ICD shipped with graphics driver 32.0.101.8976 is too old for every Level Zero adapter that exists today. The remaining fix is a newer graphics driver, for a newer ze_intel_gpu64.dll.

One result I cannot explain, and I would rather flag than paper over

PR #1940 reports a working Level Zero B70 on the same driver as mine (32.0.101.8976) with SYCL_UR_USE_LEVEL_ZERO_V2=1 and ZES_ENABLE_SYSMAN=1, built on standalone oneAPI 2026.0.0. I have now tested that combination here and it crashes. Something is different between those two machines that my measurements do not capture — most likely a different ze_intel_gpu64.dll, since this box has two Intel driver packages installed (iigd_dch.inf and iigd_dch_d.inf) and I may have been exercising the wrong one.

If anyone reading has a Windows Arc that does enumerate level_zero:gpu, the single most useful thing you could post is the output of sycl-ls --ignore-device-selectors together with the version of ze_intel_gpu64.dll your SYCL runtime is actually binding to. That would settle whether this is a driver-version issue or a per-machine one, which is the difference between "upgrade your driver" and "this is broken in general".

Where that leaves my OpenCL port

As a workaround for exactly this, on exactly one driver version. That is still what #1890 is, and I would rather say so plainly than present it as support for a platform. If the driver catches up, the plain-SYCL fallback GEMM and the STRATA_VERIFY_EAGER commit path both become unnecessary, and I would happily delete them from that PR.

The full measurement log is in LEVEL_ZERO_FINDINGS.md if it is useful to anyone.

@K8-and-a-half-1000

Copy link
Copy Markdown

#1940 works as-is for me, this is my device info as requested

C:>sycl-ls --ignore-device-selectors
[level_zero:gpu][level_zero:0] Intel(R) oneAPI Unified Runtime over Level-Zero V2, Intel(R) Arc(TM) Pro B70 Graphics 20.2.0 [1.15.39183+4]
[opencl:cpu][opencl:0] Intel(R) OpenCL, 12th Gen Intel(R) Core(TM) i5-12600K OpenCL 3.0 (Build 0) [2026.21.3.0.31_160000]
[opencl:gpu][opencl:1] Intel(R) OpenCL Graphics, Intel(R) Arc(TM) Pro B70 Graphics OpenCL 3.0 NEO [32.0.101.8976]

C:>sycl-ls --verbose
[INFO]: loaded adapter 0x00007FFAC5930000: C:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin\ur_adapter_level_zero.dll
[INFO]: loaded adapter 0x00007FFAC5790000: C:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin\ur_adapter_level_zero_v2.dll
[INFO]: loaded adapter 0x00007FFB19520000: C:\Program Files (x86)\Intel\oneAPI\compiler\latest\bin\ur_adapter_opencl.dll
[level_zero:gpu][level_zero:0] Intel(R) oneAPI Unified Runtime over Level-Zero V2, Intel(R) Arc(TM) Pro B70 Graphics 20.2.0 [1.15.39183+4]
[opencl:cpu][opencl:0] Intel(R) OpenCL, 12th Gen Intel(R) Core(TM) i5-12600K OpenCL 3.0 (Build 0) [2026.21.3.0.31_160000]
[opencl:gpu][opencl:1] Intel(R) OpenCL Graphics, Intel(R) Arc(TM) Pro B70 Graphics OpenCL 3.0 NEO [32.0.101.8976]

Platforms: 3
Platform [#1]:
Version : 1.15
Name : Intel(R) oneAPI Unified Runtime over Level-Zero V2
Vendor : Intel(R) Corporation
Devices : 1
Device [#0]:
Type : gpu
Version : 20.2.0
Name : Intel(R) Arc(TM) Pro B70 Graphics
Vendor : Intel(R) Corporation
Driver : 1.15.39183+4
UUID : 868023e2-0000-0000-0300-000000000000
DeviceID : 57891
Num SubDevices : 0
Num SubSubDevices : 0
Aspects : gpu fp16 fp64 online_compiler online_linker queue_profiling usm_device_allocations usm_host_allocations usm_shared_allocations ext_intel_pci_address ext_intel_gpu_eu_count ext_intel_gpu_eu_simd_width ext_intel_gpu_slices ext_intel_gpu_subslices_per_slice ext_intel_gpu_eu_count_per_subslice atomic64 ext_intel_device_info_uuid ext_oneapi_native_assert ext_intel_gpu_hw_threads_per_eu ext_intel_free_memory ext_intel_device_id ext_intel_memory_clock_rate ext_intel_memory_bus_width ext_intel_legacy_image ext_oneapi_bindless_images ext_oneapi_bindless_images_1d_usm ext_oneapi_bindless_images_2d_usm ext_oneapi_external_memory_import ext_oneapi_external_semaphore_import ext_intel_esimd ext_oneapi_fragment ext_oneapi_chunk ext_oneapi_tangle ext_intel_matrix ext_oneapi_graph ext_oneapi_limited_graph ext_oneapi_private_alloca ext_oneapi_bindless_sampled_image_fetch_1d_usm ext_oneapi_bindless_sampled_image_fetch_1d ext_oneapi_bindless_sampled_image_fetch_2d_usm ext_oneapi_bindless_sampled_image_fetch_2d ext_oneapi_bindless_sampled_image_fetch_3d ext_oneapi_queue_profiling_tag ext_oneapi_virtual_mem ext_oneapi_image_array ext_oneapi_virtual_functions ext_intel_spill_memory_size ext_intel_current_clock_throttle_reasons ext_intel_fan_speed ext_intel_power_limits ext_oneapi_async_memory_alloc ext_intel_device_info_luid ext_intel_device_info_node_mask ext_oneapi_exportable_device_mem ext_oneapi_clock_sub_group ext_oneapi_device_wait
info::device::sub_group_sizes: 16 32
Architecture: intel_gpu_bmg_g31
Platform [#2]:
Version : OpenCL 3.0 WINDOWS
Name : Intel(R) OpenCL
Vendor : Intel(R) Corporation
Devices : 1
Device [#0]:
Type : cpu
Version : OpenCL 3.0 (Build 0)
Name : 12th Gen Intel(R) Core(TM) i5-12600K
Vendor : Intel(R) Corporation
Driver : 2026.21.3.0.31_160000
UUID : 86807206-0900-8bf3-daff-fffbcbbf0000
DeviceID : 591474
Num SubDevices : 0
Num SubSubDevices : 0
Aspects : cpu fp16 fp64 online_compiler online_linker queue_profiling usm_device_allocations usm_host_allocations usm_shared_allocations usm_system_allocations ext_intel_gpu_slices ext_intel_gpu_subslices_per_slice ext_intel_gpu_eu_count_per_subslice usm_atomic_host_allocations usm_atomic_shared_allocations atomic64 ext_intel_device_info_uuid ext_oneapi_srgb ext_oneapi_native_assert ext_intel_gpu_hw_threads_per_eu ext_intel_device_id ext_intel_legacy_image ext_oneapi_fragment ext_oneapi_chunk ext_oneapi_tangle ext_oneapi_limited_graph ext_oneapi_private_alloca ext_oneapi_atomic16 ext_oneapi_virtual_functions ext_intel_device_info_node_mask ext_oneapi_clock_sub_group ext_oneapi_clock_work_group ext_oneapi_clock_device
info::device::sub_group_sizes: 4 8 16 32 64
Architecture: x86_64
Platform [#3]:
Version : OpenCL 3.0
Name : Intel(R) OpenCL Graphics
Vendor : Intel(R) Corporation
Devices : 1
Device [#1]:
Type : gpu
Version : OpenCL 3.0 NEO
Name : Intel(R) Arc(TM) Pro B70 Graphics
Vendor : Intel(R) Corporation
Driver : 32.0.101.8976
UUID : 868023e2-0000-0000-0300-000000000000
DeviceID : 57891
Num SubDevices : 0
Num SubSubDevices : 0
Aspects : gpu fp16 fp64 online_compiler online_linker queue_profiling usm_device_allocations usm_host_allocations usm_shared_allocations ext_intel_pci_address ext_intel_gpu_eu_count ext_intel_gpu_slices ext_intel_gpu_subslices_per_slice ext_intel_gpu_eu_count_per_subslice atomic64 ext_intel_device_info_uuid ext_oneapi_srgb ext_intel_gpu_hw_threads_per_eu ext_intel_device_id ext_intel_legacy_image ext_intel_esimd ext_oneapi_fragment ext_oneapi_chunk ext_oneapi_tangle ext_intel_matrix ext_oneapi_private_alloca ext_oneapi_atomic16 ext_oneapi_virtual_functions ext_intel_device_info_luid ext_intel_device_info_node_mask
info::device::sub_group_sizes: 16 32
Architecture: intel_gpu_bmg_g31
default_selector() : gpu, Intel(R) oneAPI Unified Runtime over Level-Zero V2, Intel(R) Arc(TM) Pro B70 Graphics 20.2.0 [1.15.39183+4]
accelerator_selector() : No device of requested type available. Please chec...
cpu_selector() : cpu, Intel(R) OpenCL, 12th Gen Intel(R) Core(TM) i5-12600K OpenCL 3.0 (Build 0) [2026.21.3.0.31_160000]
gpu_selector() : gpu, Intel(R) oneAPI Unified Runtime over Level-Zero V2, Intel(R) Arc(TM) Pro B70 Graphics 20.2.0 [1.15.39183+4]
custom_selector(gpu) : gpu, Intel(R) oneAPI Unified Runtime over Level-Zero V2, Intel(R) Arc(TM) Pro B70 Graphics 20.2.0 [1.15.39183+4]
custom_selector(cpu) : cpu, Intel(R) OpenCL, 12th Gen Intel(R) Core(TM) i5-12600K OpenCL 3.0 (Build 0) [2026.21.3.0.31_160000]
custom_selector(acc) : No device of requested type available. Please chec...
[INFO]: unloaded adapter 0x00007FFAC5930000
[INFO]: unloaded adapter 0x00007FFAC5790000
[INFO]: unloaded adapter 0x00007FFB19520000
[INFO]: ---> urLoaderTearDown() -> UR_RESULT_SUCCESS

@lm902

lm902 commented Oct 12, 2026

Copy link
Copy Markdown
Author

Thanks @demetree and @K8-and-a-half-1000. Pushed 795acb3 with the following Windows-only follow-up.

1. Fixes

  • --list-devices now reports the actual SYCL backend and free-memory/command-graph capabilities instead of hardcoding level_zero; pre-build hardware detection reports unknown.
  • The Windows installer and inference entry reject unsupported backends or missing capabilities explicitly, before model loading, instead of proceeding with an unavailable free-memory query represented as zero.
  • Runtime discovery now includes tcm/latest/bin, which supplies the missing hwloc dependency.

2. Troubleshooting

I reproduced OpenCL-only enumeration on my B70 in a fresh PowerShell session. The dependency chain was Level Zero adapter → UMF.dll → libhwloc-15.dll. The compiler directory contained UMF but not hwloc; adding only the TCM directory restored Level Zero without changing the driver or registry:

$env:PATH = "C:\Program Files (x86)\Intel\oneAPI\tcm\latest\bin;$env:PATH"
.\sycl-ls.exe --ignore-device-selectors

ZEL_LIBRARY_PATH takes a directory, not a DLL filename; using a DLL path independently reproduced OpenCL-only enumeration here. Leave it unset for a baseline comparison. This does not establish the cause of your 0xC0000005; please compare actual loaded DLL paths/versions and capture the crash stack if it persists. The working 8976 report also rules out a blanket "8976 cannot run Level Zero" conclusion.

STRATA_SYCL_JIT_STATELESS remains enabled by default and unchanged. This update neither completes the EAGER paths nor adds OpenCL inference support.

3. Verified environment

Windows 11 Pro for Workstations Insider, build 26220; i9-13900KF, 64 GB RAM, Arc Pro B70 32 GB; graphics driver 32.0.101.9034, SYCL-reported L0 driver 1.17.39500+2. Native build compiler: DPC++ 2026.1.1, build 20260724.

Actual loaded DLL file versions, collected during successful Level Zero probes:

DLL Standalone 2026.0 Standalone latest / Strata bundled
sycl9.dll 2026.0.0.0 2026.1.0.0
ur_adapter_level_zero.dll 2026.0.0.0 2026.1.0.0
ur_adapter_level_zero_v2.dll 2026.0.0.0 2026.1.0.0
ur_loader.dll 0.12.0 0.12.0
UMF.dll 1.1.0 1.1.0
ze_loader.dll / ze_tracing_layer.dll 1.32.0 1.32.0
ze_intel_gpu64.dll 32.0.101.9034 32.0.101.9034
MSVC runtime (MSVCP140, VCRUNTIME140, VCRUNTIME140_1) 14.51.36247.0 14.51.36247.0

The loader/tracing DLLs came from System32, and the Intel GPU ICD from the iigd_dch_d DriverStore package. Independent hwloc loaded from TCM; bundled hwloc loaded from Library/bin. It has no file/product version resource, but all three copies had the same SHA-256:
40C3CC41B7EE4181569A9EB253581E3A0C9751B3124CB6524AA9422ADE21FB0E.

Validation: native build passed; 482 installer tests passed, 30/30 supported GPU tests passed (unchanged exclusions: gr_parity, ple_parity, s2_expert_grouped_parity); real OpenCL enumeration is now correctly labeled and inference is refused with an explicit error.

jielin99 added a commit to jielin99/Strata-codex that referenced this pull request Oct 13, 2026
…p reports

The NPU plugin returns EXECUTION_DEVICES as the plain string "NPU" (CPU and
GPU return a list), so the probe split it into ['N', 'P', 'U'] and rejected a
valid placement. Wrap a string in a list first; a CPU fallback or an empty
list still fails. Rerun on the laptop: the 64x64 FP32 MatMul passes on NPU
(max abs error 4.9e-05). This only shows the NPU runs a small graph; it is not
Strata on the NPU.

The handoff doc gains the Ubuntu dev machine inventory (no NPU, 15 GiB RAM:
no real model baseline possible there), the review of upstream PRs Niko1221#2079,
Niko1221#2110, Niko1221#2114 and Niko1221#2115 against this branch, and the laptop's hardware and
OpenVINO reports (Core Ultra 9 285H, Arc 140T, Intel AI Boost, 63.5 GiB).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
jielin99 added a commit to jielin99/Strata-codex that referenced this pull request Oct 13, 2026
probe_sycl.cpp reports, per SYCL device, what the native Windows engine
(PR Niko1221#2079) gates on - ext_intel_free_memory and ext_oneapi_graph - plus
host_unified_memory, memory sizes, the largest allocation, sub-group sizes
and fp16/fp64, and runs one 32-wide sub-group kernel per GPU. Read-only, no
large allocation. PROBE_SYCL.bat builds it with icx and runs it three ways
(no switches, ZES_ENABLE_SYSMAN=1, plus UR_L0_ENABLE_RELAXED_ALLOCATION_LIMITS=1).

Built with icpx 2025.3.2 (intel/oneapi-basekit image) and run on a UHD 730
over Level Zero: valid JSON, sub-group kernel ok in all three. There the iGPU
reports ~270 MiB free with ~13 GiB MemAvailable, and no ext_oneapi_graph.
The Windows build and the Arc 140T are not tested.

The handoff doc records the laptop toolchain, the cherry-picked upstream PRs
(Niko1221#2114, Niko1221#2110, Niko1221#2079; Niko1221#2115 left out), the setup test results and the probe run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
jielin99 added a commit to jielin99/Strata-codex that referenced this pull request Oct 13, 2026
The laptop's Arc 140T on Windows reports ext_oneapi_graph=false, which PR
Niko1221#2079's setup and engine gates refuse. The engine never updates an executable
graph (no update() or dynamic parameters anywhere in sycl/), so per the
sycl_ext_oneapi_graph spec ext_oneapi_limited_graph should be enough. The
probe now reports that aspect and records two kernels on an in-order queue,
finalizes and replays the graph twice and checks the result.

On the UHD 730 over Level Zero (oneAPI 2025.3.2 image): ext_oneapi_graph
false, ext_oneapi_limited_graph true, record/replay ok; on OpenCL the check
reports the runtime's exception. Also rename the probe's quoted() to
json_str(): with a non-const std::string, ADL picked std::quoted.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@marcelloc

Copy link
Copy Markdown

We have an independent native Windows/SYCL implementation validated on Windows 10 with an Arc Pro B70, now based on Strata 0.1.44.1 (296b59d2). Sharing the code and results here because this PR already covers much of the same portability work.

Our contribution commit: marcelloc@60d2db74

After comparing your current file changes, these are the pieces that may be useful to reuse or adapt:

  1. A host-only regression test for positioned GGUF reads. Your implementation already uses independent OVERLAPPED requests and per-request events, so this is mainly additional test coverage: eight threads reading a shared handle, offsets above 4 GiB, short reads, EOF, invalid handles and missing files. The fixture is sparse and does not require a model or a GPU. Our implementation extracts the reader into a small platform header so the test exercises the same helper as GgufExpertSource.

    • Test
    • Reader
    • One detail to consider when adopting the test: our helper maps ERROR_HANDLE_EOF to zero bytes and retries POSIX pread on EINTR. Your read_at returns -1 for a failed Windows read, including EOF. The current GGUF callers reject both zero and negative returns, so this is a helper-contract/testability suggestion, not a claim of an observed inference bug in your PR.
  2. Additional Windows 10 / 0.1.44.1 validation evidence. On our branch, the full Windows SYCL build with parity targets completed using VS 2022, oneAPI 2026.1.1, Level Zero SDK 1.32.0 and JIT. Seven GPU tests passed: sampler, rope, quantize_act, elementwise, bf16_gemv, kv_q8 and prefill_gdn. IQ3_XXS with MTP and a 131072-token context served a 127009-token prompt with all three requested targets recovered; SSE and a subsequent arithmetic request worked, and server unload exited with code zero. Validation summary.

  3. Optional IGCL monitoring, submitted separately as Add Intel GPU monitoring on Windows via IGCL #2429. This supplies supported activity, memory allocation, GPU/memory temperature, chip power and PCIe link readings to the Windows SYCL server. It uses the installed Intel driver; it does not modify or bundle a driver. Chip power is not board power, and PCIe generation/width is not traffic throughput. This can complement the native engine work without coupling the two patches.

The local user also reports reviewing code with a context configured to 128K and leaving the server up since the previous day. That is practical usage evidence, not an instrumented soak test or proof that the conversation filled 128K.

These results apply to our branch, not a test of this PR's head. We have not validated Linux regressions, Windows 11 or multi-GPU operation on our machine. An older standalone CLI shutdown failure has not been rechecked on 0.1.44.1; successful server unload is a separate result. Our branch provides a manual build path, whereas your PR also covers installer integration, so it is offered as complementary code and evidence rather than a replacement. No controlled performance improvement is claimed.

@qiuzan2001

Copy link
Copy Markdown

Docs gap on this branch: docs/INTEL_ARC.md:166-168 still says "There is no Windows path yet. setup --backend sycl on Windows stops and points here ... Nobody has tried it", and the PR changes no docs, while the new setup errors (ensure_windows_engine in sycl/setup_intel.py, build_windows.bat) send users to that file for the tools to install. A Windows section there listing the prerequisites the build needs (Visual Studio C++ workload, oneAPI DPC++/oneMKL, the Level Zero SDK) and what was measured on which card would close the loop. Python side checked on Linux: tools/test_setup_sycl.py 37 OK, the other setup tests as on main; the SYCL C++ was not built here (no Intel GPU).

@lm902

lm902 commented Oct 15, 2026

Copy link
Copy Markdown
Author

Updated docs/INTEL_ARC.md in 0a2cc38: Windows prerequisites and build/run steps, Level Zero requirements (SDK optional), and the B70 validation results and limits. I initially left docs unchanged to keep this PR minimal; the review highlighted that setup errors point users to an outdated Windows section, so this focused docs-only update closes that gap. No runtime changes.

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.

5 participants