Skip to content

Add Arc native Windows support - #1940

Closed
K8-and-a-half-1000 wants to merge 1 commit into
Niko1221:mainfrom
K8-and-a-half-1000:intel-windows
Closed

K8-and-a-half-1000 wants to merge 1 commit into
Niko1221:mainfrom
K8-and-a-half-1000:intel-windows

Conversation

@K8-and-a-half-1000

Copy link
Copy Markdown

Author's note:

This PR adds support for running Strata on Arc on Windows natively, tested on a Pro B70. No WSL2, no docker.
This work was done over the course of a week in an offshoot project at first, but I've decided to contribute upstream based on the project activity and direction.

In short: I like what I see, so here's a contribution to help support the project.

AI disclaimer

Fable 5.1 ultracode and max used heavily throughout.
I've been critical and culled as many temp files, tools and journey notes that are not relevant for this project.

Summary

The SYCL port builds and runs natively on Windows 11 with the Intel oneAPI compiler (icx), the Visual Studio Build
Tools and the Intel Arc driver. Written for and measured on an Arc Pro B70 (32 GB) dedicated to the model. The Linux
build is unchanged: everything lives in sycl/ under #if defined(_WIN32) or in new Windows scripts.

Full description, measurements and open questions: docs/INTEL_WINDOWS.md.

What it adds

  • Build: sycl\tools\build_windows.bat finds Visual Studio and oneAPI, configures sycl\CMakeLists.txt with
    Ninja, builds the engine, strata-device and the probes, and packages engine\ with the oneAPI runtime DLLs and a
    BUILD.json (sycl\tools\package_windows.py). CMake: MSVC-style flags for icx, /Qmkl:sequential, the dynamic
    CRT, the AVX flags.
  • Install and serve: sycl\setup_intel.py and sycl\serve\server_intel.py on Windows (cards numbered by
    strata-device --list-devices, the engine's environment, Sysman telemetry through ctypes in
    sycl\serve\xe_telemetry.py); setup.py hands --backend sycl over on Windows. Tests without a GPU:
    tools\test_setup_sycl_windows.py.
  • Engine: the card choice and capability gate (device.dp.cpp); a chunked VRAM arena that tries one allocation
    first (core/device.hpp); the DXGI video-memory budget folded into the free-VRAM figure (sycl_mem.hpp); a VRAM
    heartbeat against WDDM eviction on a card that drives no display (sycl_heartbeat.hpp); prepare_for_device_copy
    on the pinned expert arena; overlapped ReadFile for --stream-experts; the windows.h macros that collide with
    identifiers in the kernels (IN, OUT, near, far, small, hyper) dropped after the dpct headers;
    _putenv_s in the two parity programs that call setenv.
  • Probes (sycl/probe/): doorbell, allocation, bandwidth and graph probes, each ending in a VERDICT line that
    names the engine setting it decides. All under Strata's MIT license (the two that derived from XeStrata's LGPL files
    were rewritten from their descriptions).
  • Tools: report_windows.py (a one-shot bug-report bundle) and benchy_windows.bat / .py (the Linux port's
    benchy on Windows; not yet run).

What ran

Arc Pro B70, driver 32.0.101.8976, oneAPI 2026.0.0, AOT bmg-g31, 2026-10-10 and 11: the build (0 errors), the
probes, and Swift 1.5 IQ3_XXS at --max-context 262144 with INT8 KV and 32,768 resident cells, used from qwen-code for
an evening: prompts read at 630-890 tok/s, decode 50-76 tok/s, 97-99.3% of the KV block reads from VRAM, 2.1 GiB of
VRAM free with everything loaded. On the 0.1.38 base before this: Coder IQ1_M at 60 tok/s sampled, and Swift served
for several days.

Two things worth knowing upstream

  1. sycl/src/kernels/cuda/qsa_decode_attn.dp.cpp is the 0.1.38 migration, kept in place of the 0.1.41 one. The
    0.1.41 copy adds the opt-in lane-cell scoring variant (STRATA_ATTN_LANECELL) as a second template parameter of
    attn_chunk_kernel. Compiled that way by icx 2026.0.0 for bmg-g31, the INT8 instantiation's batched output is
    inf and NaN (qsa_prompt_attn_parity, "vs FP64 old": 78.5 on an output scale of 3.7) while the fp16 instantiation
    is exact; the 0.1.38 copy, otherwise the same code, measures 2e-6 in both. Since 0.1.41 routes SYCL prompts
    through this kernel, every reply on Windows was token 0 until the swap. kv_stream_parity cannot catch this
    class of defect: it compares the kernel's streamed output with its resident output, both through the same kernel.
    Whether the Linux build is affected was not measured.
  2. The opt-in XMX prompt attention (STRATA_PROMPT_ATTN_XMX=1) measures 2e-3 absolute (5e-4 of scale) on this
    Windows build, where docs/INTEL.md reports 1e-6 of scale on Linux. Off by default; not understood.

Known limits

One card per model on Windows (--gpus / --layer-split is refused); images are not wired on Intel; only the Arc Pro
B70 has run this (other Battlemage cards need STRATA_SYCL_AOT=bmg-g21 or a JIT build); the greedy benchmark and the
heartbeat's idle test have not been run. Details in docs/INTEL_WINDOWS.md, "Known limits and open questions".

Extra Notes

On Windows there is a RAM eviction on idle timeout that affects Intel Arc cards, which will happen if the card is not driving any displays. This can be avoided by adding a small heartbeat every 10 seconds to poke the card. Check the heartbeat files for more info.

This commit adds support for running Strata on Arc Intel, tested on a B70 pro.

This work was done over the course of a week in a different project at first, but I've decided to contribute upstream based on the project activity and direction.

So, in short: I like what I see, so here's a contribution to support the project.
demetree pushed a commit to demetree/Strata that referenced this pull request Oct 12, 2026
Two things that came out of measuring the port on an Arc Pro B70 on Windows.

**1. `strata-sycl.bat` gains `STRATA_SYCL_LEVEL_ZERO=1`, off by default.**

The port assumed the OpenCL backend because `sycl-ls` never listed a Level Zero device on this
card. That turned out to be a graphics-driver version, not the card: the Intel Arc **Pro** line's
newest (32.0.101.8976) does not expose Level Zero through any SYCL adapter at all, while the
**generic** Arc line's 32.0.101.9034 does. With it, `ext_intel_free_memory` and
`ext_oneapi_graph` both appear, which is exactly what the OpenCL workarounds existed for.

The settings it turns on, all measured on that card, 2047-token prompt, coder-IQ1_M:

| | OpenCL (eager) | LZ v2 | LZ v1 |
|---|---|---|---|
| decode, 128 tokens | 66.6 tok/s | 87.9 tok/s | **108.8 tok/s** |
| prefill, 2047 tokens | 81.1 tok/s | 64.5 tok/s | 81.1 tok/s |
| verify graph capture | skipped | 9,495 ms | **276 ms** |

`SYCL_UR_USE_LEVEL_ZERO_V2=0` is the v1 adapter: +24% decode over v2 and 34x faster graph capture.
Niko1221#1940 pins v2 on for graph replay (intel/llvm#23073); on this card that trade is the wrong one.

It stays opt-in and off by default because it is not reliable yet: through the serve request path
the device-plan verify window occasionally never gets its doorbell and the engine stalls
("waiting for the GPU to finish the window; the GPU rang 0"). The engine itself is stable in the
CLI and through the launcher (512 decode tokens at 74.5 tok/s, prefill 121.4 tok/s against
OpenCL's 81.1), so the trigger is narrower than "Level Zero is broken", but it is not fixed, and a
default that stalls after a few requests is worse than a default that is merely slower.

**2. `LEVEL_ZERO_FINDINGS.md` records how that was established**, including the parts that turned
out to be wrong. The two most useful entries for anyone reading this PR:

- The Level Zero **driver** on this card was never broken. Walking the Level Zero API directly, with
  no SYCL or UR in the way, gives a driver handle, a device handle and full device properties
  (`TYPE_GPU`, `0x8086`/`0xe223`, 31.2 GiB). The failure was entirely in the loader and adapter
  above it.
- `ur_adapter_level_zero.dll` imports `UMF.dll` and the `VCRUNTIME140*` set, and
  `sycl/CMakeLists.txt` stages neither beside `strata.exe`. The adapter therefore fails to load, the
  UR loader reports only OpenCL, and `ONEAPI_DEVICE_SELECTOR=level_zero:0` kills the process with
  `0xC0000409` before `main` prints anything. That is a real gap in the copy list, and the silence
  is what makes it expensive: every Level Zero adapter failure looks like "there is no Level Zero
  here". **This is the piece of the PR I would most want reviewed.**

## What this leaves alone

The default path is untouched — `STRATA_SYCL_LEVEL_ZERO` unset is exactly the previous behaviour,
including `ONEAPI_DEVICE_SELECTOR`, `SYCL_UR_USE_LEVEL_ZERO_V2` and `ZES_ENABLE_SYSMAN` staying
unset. Every variable is only written when it is not already defined, so an explicit
`ONEAPI_DEVICE_SELECTOR` for a two-card split or an OpenCL run still wins. No engine source
changed.

Built and run on SYCL/Windows only; I have no CUDA, HIP or Linux toolchain here.
@Niko1221

Copy link
Copy Markdown
Owner

Thanks for the contribution. It is Windows platform support that we cannot test, so it is not part of the speed round.

@Niko1221

Copy link
Copy Markdown
Owner

Thanks for the pull request.

We're resetting the tracker for 0.2.0-beta. There are more than 1,300 open issues and pull requests, too many for us to review properly, so we're closing everything that isn't being worked on right now. Closed here does not mean rejected.

To reopen it takes about two minutes:

  1. Rebase on main if it no longer applies, and re-run your checks on 0.2.0-beta.
  2. Start the title with its area: [Engine], [GUI], [TUI], [Benchmark], [Docs] or [Other].
  3. Fill in the pull request template: the problem and result, and the validation (what you ran, on which revision, what you saw).
  4. Comment /reopen. A check runs and either reopens the pull request or lists what is still missing.

The rules are in CONTRIBUTING.md.

@Niko1221 Niko1221 closed this Oct 19, 2026
@FeliciaFiction

Copy link
Copy Markdown

Author's note:

This PR adds support for running Strata on Arc on Windows natively, tested on a Pro B70. No WSL2, no docker. This work was done over the course of a week in an offshoot project at first, but I've decided to contribute upstream based on the project activity and direction.

In short: I like what I see, so here's a contribution to help support the project.

AI disclaimer

Fable 5.1 ultracode and max used heavily throughout. I've been critical and culled as many temp files, tools and journey notes that are not relevant for this project.

Summary

The SYCL port builds and runs natively on Windows 11 with the Intel oneAPI compiler (icx), the Visual Studio Build Tools and the Intel Arc driver. Written for and measured on an Arc Pro B70 (32 GB) dedicated to the model. The Linux build is unchanged: everything lives in sycl/ under #if defined(_WIN32) or in new Windows scripts.

Would you mind sharing the compiled version?

Also, the PR got closed but my B70 is begging for this PR to be merged :D

@K8-and-a-half-1000

K8-and-a-half-1000 commented Oct 23, 2026 via email

Copy link
Copy Markdown
Author

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