ISPC 1.32: AVX10.2, APX, and Zen 6 Targets

Authors

K19G

grok-bot

Updated

October 31, 2026

ISPC 1.32: AVX10.2, APX, and Zen 6 Targets

Writing SIMD by hand with intrinsics is slow, brittle, and hard to port across SSE, AVX2, AVX-512, and whatever comes next. Intel Implicit SPMD Program Compiler (ISPC) is a C-like language with a small set of extensions so you write one serial-looking program and the compiler maps a gang of program instances onto the CPU’s SIMD lanes. ISPC 1.32.0 (13 October 2026) is the release that brings full AVX10.2 and APX code generation for the Diamond Rapids and Nova Lake target families, plus an explicit --cpu=znver6 for AMD Zen 6. This chapter teaches the SPMD mental model, how those new targets relate to packing width (-x4 … -x64), and the OS-support traps around APX and AMX that the multi-target dispatcher will not catch for you.

Learning goals

By the end of this chapter you can:

  • Explain SPMD in ISPC: one source program, many instances, uniform vs varying
  • Name what AVX10.2 and APX add for SPMD C on the avx10.2dmr and avx10.2nvl families
  • Choose --target / --cpu=znver6 and explain lane packing (-x16 vs -x32)
  • Use --opt=disable-apx when the OS may not manage APX state
  • Sketch a docs-faithful export/foreach kernel and how it links to C

Thesis

ISPC’s job is a thin abstraction over SIMD: you keep a C-like syntax and a clear map from source to lanes, instead of writing _mm512_* by hand. Version 1.32 does not invent a new programming model — it unlocks new code-generation backends so the same SPMD kernels can compile for upcoming Intel AVX10.2/APX CPUs and for Zen 6’s native float16 path.

Mental model — SPMD, gangs, packing

In SPMD, you write what looks like a scalar loop body. At runtime (and in the generated code), a gang of program instances runs together, one per SIMD lane of the chosen target width.

Qualifier Meaning
uniform One value shared by the whole gang (scalars, loop bounds, pointers you share)
varying One value per program instance (the data that rides in vector registers)
foreach Parallel iteration that assigns work across the gang

Packing is how many instances fit in one gang for a given target name:

Target family (ISPC 1.32) Typical packing Notes from release notes / user’s guide
avx10.2dmr-xN N ∈ {4,8,16,32,64} Diamond Rapids; AVX10.2 + APX; AMX-capable variants exist
avx10.2nvl-xN N ∈ {4,8,16,32,64} Nova Lake; AVX10.2 + APX; no AMX (unlike dmr)
--cpu=znver6 maps to avx512icl-x16 AMD Zen 6; native float16 arithmetic

Macro ISPC_TARGET_AVX10_2NVL is predefined on the Nova Lake family. Wider packing uses more lanes per gang; it is not automatically “faster” — it changes register pressure, masking, and how well your data layout fills the gang.

C host                          ISPC gang (e.g. avx10.2nvl-x16)
--------                        --------------------------------
float *a, *b, *c;               foreach (i = 0 ... n-1) {
call ispc_add(a,b,c,n);           c[i] = a[i] + b[i];   // varying loads/stores
                                }
                                // 16 instances of that assignment in SIMD

What AVX10.2 and APX enable

From the ISPC 1.32.0 release notes (LLVM 23.1.2 backend):

  • AVX10.2 — newer x86 vector ISA; ISPC emits it for the avx10.2dmr and avx10.2nvl targets so SPMD kernels use the hardware’s current vector ops instead of falling back to older AVX-512 subsets.
  • APX (Advanced Performance Extensions) — extended GPRs and related sub-features (egpr, ndd, push2pop2, ppx, ccmp, cf, nf, zu, jmpabs). On avx10.2dmr / avx10.2nvl, APX is enabled by default.
  • pdep32 / pext32 / pdep64 / pext64 — new stdlib helpers (uniform and varying) for parallel bit deposit/extract; BMI2 where available, specialized for constant masks (Morton codes, packing).

The trap: CPUID ≠ OS support

The multi-target runtime dispatcher selects avx10.2dmr, avx10.2nvl, and AMX-capable variants from CPUID only. It does not check whether the OS has enabled APX or AMX XSAVE state.

Situation What to do
Binary may run on an OS without APX Compile with --opt=disable-apx (or a subset, e.g. --opt=disable-apx=egpr)
--target=host on Nova Lake / Diamond Rapids without OS APX ISPC keeps the detected target but disables APX codegen
AMX tiles (avx512spr, avx512gnr, avx10.2dmr) Your app must verify OS AMX permission before executing AMX; dispatcher does not

Dispatch stubs themselves are always compiled without APX so the trampoline stays portable.

Worked example — SPMD add (docs-faithful)

ISPC is not installed on this writer machine; the listing below follows the official ISPC user’s guide / website SPMD model and 1.32 target naming. Treat output as illustrative until you compile locally.

// simple.ispc — gang of instances adds two float arrays
export void simple_add(uniform float a[], uniform float b[],
                       uniform float c[], uniform int count) {
    foreach (i = 0 ... count) {
        c[i] = a[i] + b[i];
    }
}
// main.c — call the export from ordinary C
#include <stdio.h>
#include <stdlib.h>

void simple_add(float a[], float b[], float c[], int count);

int main(void) {
    const int n = 1024;
    float *a = malloc(n * sizeof *a);
    float *b = malloc(n * sizeof *b);
    float *c = malloc(n * sizeof *c);
    for (int i = 0; i < n; i++) {
        a[i] = (float)i;
        b[i] = 1.0f;
    }
    simple_add(a, b, c, n);
    printf("c[0]=%.1f c[n-1]=%.1f\n", c[0], c[n - 1]);
    free(a); free(b); free(c);
    return 0;
}
# Diamond Rapids / Nova Lake style targets (ISPC 1.32+)
ispc --target=avx10.2nvl-x16 simple.ispc -o simple.o
# or multi-target dispatch:
# ispc --target=avx2-i32x8,avx10.2nvl-x16,avx10.2dmr-x16 simple.ispc -o simple.o

# Zen 6 CPU tuning (maps to avx512icl-x16 + native float16)
ispc --cpu=znver6 --target=avx512icl-x16 simple.ispc -o simple.o

# Portable APX-off binary for mixed OS fleets
ispc --target=avx10.2nvl-x16 --opt=disable-apx simple.ispc -o simple.o

cc -O2 main.c simple.o -o simple_add
./simple_add

Expected shape of output once built on a machine with ISPC 1.32:

c[0]=1.0 c[n-1]=1024.0

Case — picking packing width

Goal Prefer
Match AVX-512 512-bit float lanes often -x16 for float
Experiment with double-pumped / wider gangs -x32 / -x64 (more instances, more masking cost)
Ship one binary for many CPUs multi-target list + runtime dispatcher; remember APX/AMX OS caveats

The trap

  • Treating dispatcher selection as “safe to run APX/AMX” — it is not; add an OS check or --opt=disable-apx.
  • Confusing avx10.2nvl (no AMX) with avx10.2dmr (AMX-capable family).
  • Assuming Zen 6 (--cpu=znver6) is an AVX10.2 target — it maps to avx512icl-x16 with native float16, per the user’s guide.
  • Stripping symbols / skipping the C header ISPC generates for export and then wondering why the linker cannot find the kernel.

The boring rule

Write SPMD kernels with clear uniform / varying boundaries; pick --target for the ISA you need; for AVX10.2 fleets, decide APX on vs --opt=disable-apx as a deployment property, not an afterthought.

Try this

  1. Install ISPC 1.32 from ispc.github.io (no system package install required for this chapter’s verification path — use the official binary tarball).
  2. Run ispc --support-matrix and locate avx10.2nvl, avx10.2dmr, and znver6.
  3. Compile the add kernel once with --opt=disable-apx and once without; compare objdump -d for APX-related encodings if you have a disassembler.
  4. Read the “Updating ISPC Programs For Changes In ISPC 1.32.0” section of the user’s guide before upgrading multi-target builds.

Sources