gpumode · 강의 아카이브
《GPU Mode》 L026 2024 · JUL · 06 High priority transcript · available

SYCL Mode (Intel GPU)

CUDA 가 사실상 표준이 된 시대에 Intel GPU 위에서 같은 일을 하는 길은 어떻게 생겼는가 — Patric Zhao 가 GPU Mode 첫 SYCL 강의에서 깐 이종 컴퓨팅 모델, 커널 작성, 메모리 모델, 그리고 LLM inference 에 적용한 fused operator 들의 학습 노트.

SYCL DPC++ oneAPI Intel GPU heterogeneous compute USM · buffer SLM SYCL graph vendor portability
P
Speaker
Patric Zhao
Intel · oneAPI · LLM inference 가속 담당
강의 번호
L026
스피커
Patric Zhao
학습 우선순위
High · 정독
다시 볼 때
SYCL 커널 손으로 짜본다
§ 01강의가 풀려는 문제· CUDA 너머의 GPU 코드

“CUDA mode” 가 사실상 표준이 된 자리에서 SYCL mode 를 다시 묻는다

GPU Mode 시리즈는 이름부터 CUDA mode 로 출발했다. 그런데 25강을 넘어서면서 — Mark 가 이름을 굳이 GPU Mode 로 바꾼 다음 첫 외부 백엔드 강의로 — Intel 의 Patric Zhao 를 불렀다. 강의의 이름이 일부러 “SYCL mode” 다.

강의가 답하려는 질문은 두 줄로 압축된다.

  1. NVIDIA 가 아닌 GPU 위에서 같은 종류의 커널을 짜려면 어떤 모델이 있는가 — 그리고 그 모델이 CUDA 와 정확히 어디가 같고 어디가 다른가.
  2. 그 모델로 LLM inference 같은 실전 워크로드를 어디까지 짜냈는가 — Intel GPU 위에서 fused MHA 와 flash attention 을 어떻게 구현했는지.

그래서 강의의 구조도 정확히 그 두 축이다. 전반부는 SYCL 의 이종 컴퓨팅 모델(host + device, queue, accessor, parallel_for) 을 CUDA 의 친숙한 모델 위에 mapping 한다. 후반부는 Intel oneAPI 위에서 SYCL 로 짠 fused operator 들 — RMSNorm + matmul, flash attention, MHA fusion — 의 실측 결과를 보여준다.

강의의 frame

SYCL 은 “C++ 표준 위에 single-source 로 GPU 커널을 짠다”는 약속의 결과물이다. CUDA 가 NVIDIA 의 독점적 ISA 위에 묶여 있다면, SYCL 은 vendor 가 만든 backend 만 있으면 같은 코드가 NVIDIA · AMD · Intel · CPU 위에서 모두 돈다는 위치에 서 있다. 즉 “이 GPU 의 프로그래밍 모델이 무엇인가” 가 아니라, 모든 가속기를 추상화한 한 layer 가 무엇인가 의 질문에 답한다.

“오늘은 CUDA mode 가 아니라 SYCL mode 입니다. NVIDIA 만이 아니라 Intel GPU, AMD GPU, 심지어 NPU 까지 — 같은 코드 베이스가 어떻게 도는지 보여드리려고 합니다.”Patric Zhao · 04:21

그래서 강의의 끝에 손에 잡혀 있어야 할 것은 — SYCL 의 핵심 개념 4개(queue, parallel_for/handler, USM, accessor), Intel GPU 의 메모리/스레드 모델(EU, slice, SLM), 그리고 이 모델이 CUDA 와 어디서 다른가 의 한 페이지짜리 mapping 이다.

§ 02NVIDIA 너머의 GPU 모델· heterogeneous compute

가속기 ≠ NVIDIA — “이종 컴퓨팅” 이라는 더 큰 frame 안에 GPU 를 다시 위치시킨다

강의의 첫 30분은 의도적으로 “heterogeneous computing” 이라는 더 넓은 단어로 시작한다. host + device 의 분리된 메모리, latency hiding 을 위한 SIMT 모델, async dispatch — 이 다섯 가지는 아키텍처 선택과 무관하게 모든 가속기에 공통이다.

Patric 의 출발점은 — “GPU 라는 단어가 NVIDIA 와 동의어처럼 쓰이지만, 그 안에는 더 일반적인 모델이 있다” 는 것. 그 모델을 명시적으로 깐다.

  • Host 와 device 의 분리 — CPU 가 control flow 와 memory transfer 를 결정하고, device 는 dispatched kernel 을 SIMT 로 돈다.
  • 대량 병렬 + latency hiding — work-item(스레드)이 메모리에서 막히면 SM/EU 가 다른 work-item 으로 swap. occupancy 라는 단어의 일반화.
  • 비동기 디스패치 — host 는 kernel 을 enqueue 하고 즉시 돌아온다. dependency 는 queue 가 추적.
  • 메모리 계층 — register → on-chip SRAM(NVIDIA: shared mem · Intel: SLM) → device global(HBM/GDDR) → host RAM. 단어만 다르다.
  • Tensor 가속 — 각 vendor 가 자체 matrix 명령 (NVIDIA Tensor Core · Intel XMX · AMD Matrix Core). 모양은 같다.
FIG · 같은 추상이 vendor 별로 어떤 단어로 구체화되는가4 vendors · 5 axes
NVIDIA
SM · warp(32) · shared memory · CUDA core / Tensor Core · CUDA stream
Intel GPU
slice · EU · sub-group(8/16) · SLM · XMX · SYCL queue
AMD
CU · wavefront(32/64) · LDS · Matrix Core · HIP stream
강의에서 Patric 이 강조한 mapping. 단어가 달라도 같은 위치에서 같은 일을 한다. 이 mapping 만 손에 박아두면 이름 전환이 빠르다.

이 frame 위에서 SYCL 이 등장하는 위치가 자연스러워진다 — 이 mapping 자체를 한 번에 묶는 single-source C++ layer. 같은 parallel_for 가 NVIDIA · Intel · AMD · CPU 위에서 backend 만 바꿔 돈다는 약속.

§ 03SYCL 의 추상· queue · accessor · USM

네 개의 단어로 끝나는 SYCL — queue, handler, accessor/USM, parallel_for

SYCL 의 spec 자체는 두꺼운 문서지만, 강의에서 Patric 이 잡은 진입점은 네 개의 추상이다. 이 넷만 알면 vector add 부터 GEMM 까지 다 짤 수 있다.

queue
device 와 연결되는 비동기 실행 채널. CUDA 의 stream 에 대응. sycl::queue q{gpu_selector_v}.
handler · cgh
q.submit([&](handler& cgh){ ... }) 안에서 한 dispatch 의 dependency 와 launch 를 묶는다. command group.
USM (Unified Shared Memory)
malloc_device · malloc_shared · malloc_host. CUDA 의 cudaMalloc / managed memory 와 같은 자리.
accessor
buffer-based 코드의 메모리 핸들. read/write/RW mode 가 dependency tracking 의 단서가 된다.
parallel_for + nd_range
SIMT 본체. nd_range<3>(global, local) 의 (global, local) 이 CUDA 의 (grid×block, block) 과 동치.
item · nd_item
커널 안에서 자기 좌표를 읽는다. item.get_global_id(0) · item.get_local_id(0). CUDA 의 blockIdx · threadIdx.
// SYCL vector add — 강의의 첫 코드
#include <sycl/sycl.hpp>
using namespace sycl;

int main(){
  constexpr int N = 1024;
  queue q{gpu_selector_v};

  // 1. USM 으로 device 메모리 할당
  float* a = malloc_shared<float>(N, q);
  float* b = malloc_shared<float>(N, q);
  float* c = malloc_shared<float>(N, q);

  // 2. submit + parallel_for
  q.submit([&](handler& cgh){
    cgh.parallel_for(range<1>{N}, [=](id<1> i){
      c[i] = a[i] + b[i];
    });
  }).wait();

  free(a, q); free(b, q); free(c, q);
}

CUDA 와 비교했을 때 — cudaMalloc 대신 malloc_shared, kernel<<<...>>> 대신 q.submit + parallel_for, cudaDeviceSynchronize() 대신 .wait(). 모양은 다른데 역할은 정확히 같은 자리를 차지한다.

USM 의 핵심 변종 3

malloc_device = device 만 접근 (cudaMalloc 동치). malloc_shared = host/device 양쪽 가시 (managed memory). malloc_host = pinned host (zero-copy 후보). 강의에서 Patric 이 첫 데모는 malloc_shared 로 깔끔하게 시작 — 그 다음 GEMM 같은 perf 코드는 malloc_device + 명시적 memcpy 로 옮겨간다.

“CUDA 에 익숙한 사람이 SYCL 코드를 처음 봤을 때 가장 헷갈리는 건 kernel 호출이 lambda 안에 박혀 있다는 것. 그게 single-source 의 출발점입니다.”Patric Zhao · 14:55
§ 04Intel GPU 백엔드· Xe · slice · EU · SLM

Intel GPU 가 SM/warp 의 자리에 박는 단어들 — slice, EU, sub-group, SLM

SYCL 자체는 vendor 중립이지만, Intel GPU(Arc, Data Center GPU Max, Ponte Vecchio) 위에서는 Xe architecture 의 단어들을 다시 만난다. 이 자리에 익숙해져야 SYCL 커널의 launch 설정이 직관적으로 잡힌다.

FIG · NVIDIA 와 Intel GPU 의 메모리/스레드 모델 mapping두 vendor · 같은 위치
EXEC unit SM (Streaming Multiprocessor) slice / sub-slice 안의 EU(Execution Unit)
WARP warp = 32 threads sub-group = 8 / 16 / 32 (Xe-HPC 는 16)
BLOCK CTA / thread block work-group
on-chip SRAM shared memory (per-block) SLM (Shared Local Memory) — work-group 단위
tensor 가속 Tensor Core (mma · wgmma) XMX (Xe Matrix Extension)
DEVICE memory HBM (A100/H100) HBM2e (Data Center GPU Max) · GDDR6 (Arc)
강의에서 Patric 이 강조 — SLM 은 NVIDIA shared memory 와 똑같이 program-managed. flash attention 의 K/V tile 을 SLM 에 올리는 것이 fused MHA 의 핵심.

Xe 아키텍처의 한 단계 더 — Data Center GPU Max(Ponte Vecchio) 의 단위 분해.

  • Stack — 칩렛 단위. 한 칩이 여러 stack 으로 나뉘고 internal interconnect 으로 묶임.
  • Slice — stack 안에 여러 slice. 각 slice 가 sub-slice 들을 묶고 L1/L2 를 공유.
  • EU (Execution Unit) — sub-slice 안의 단일 SIMT 실행 단위. SM 의 한 partition 에 대응.
  • Thread per EU — 7~8 hardware thread. 각 thread 가 SIMD 8 / 16 work-item 을 동시에 실행.

NVIDIA SM = (Intel slice 안 sub-slice 의 EU 묶음) 으로 대략 끼워 맞을 수 있다. 정확한 ratio 는 chip 별로 다르지만, occupancy 를 결정하는 단위가 EU 의 active hardware thread 수라는 게 가장 중요하다.

// sub-group 사용 — Intel GPU 의 native warp 폭 활용
q.submit([&](handler& cgh){
  cgh.parallel_for(
    nd_range<1>{global, local},
    [=](nd_item<1> it)
      [[intel::reqd_sub_group_size(16)]] {
        auto sg = it.get_sub_group();
        int id  = sg.get_local_id();
        // sub-group 내 reduce — CUDA shfl_xor 동치
        float v   = data[it.get_global_id(0)];
        float sum = reduce_over_group(sg, v, plus<>{});
        if (id == 0) atomic_ref(out[0])
          .fetch_add(sum);
      });
});

reqd_sub_group_size(16) 이 Xe-HPC 의 native sub-group 폭. 이 attribute 가 빠지면 컴파일러가 8 / 16 / 32 사이에서 자동 선택하는데, perf 코드에서는 항상 명시한다.

§ 05oneAPI 와의 관계· DPC++ · MKL · oneDNN

SYCL 의 Intel 구현 = DPC++ — 그 위에 라이브러리 stack 이 한 층

SYCL 은 Khronos 표준이고, DPC++ (Data Parallel C++) 는 Intel 이 그 표준을 구현한 컴파일러 + 확장이다. oneAPI 는 DPC++ 위에 쌓인 vendor 라이브러리 묶음 — 정확히 CUDA 위의 cuBLAS / cuDNN / NCCL 자리다.

FIG · oneAPI 스택 — SYCL 부터 LLM 까지NVIDIA stack 과 한 행씩 비교
L4 · FrameworkPyTorch (XPU backend) · IPEX · TensorFlow · DeepSpeed≡ PyTorch CUDA
L3 · NN libraryoneDNN — conv · attention · norm · GEMM 의 vendor 커널≡ cuDNN
L2 · Math · CCLoneMKL (BLAS · LAPACK · FFT) · oneCCL (collective · all-reduce)≡ cuBLAS / NCCL
L1 · DPC++SYCL spec 의 Intel 구현체. extension 으로 sub-group · ESIMD · joint_matrix 추가≡ nvcc · CUDA C++
L0 · Level Zerolow-level vendor driver API. SYCL runtime 이 그 위에 얹힘≡ CUDA driver API
한 행씩 NVIDIA stack 에 거의 일대일로 맞물린다. oneDNN 의 attention 커널이 강의 후반의 fused MHA 의 베이스 — Intel 입장에서 cuDNN 같은 “튜닝된 vendor 커널” 이 있어야 PyTorch 가 의미 있게 빠르게 돈다.

중요한 분리

SYCL 은 vendor 중립의 spec이고, DPC++ 는 그 spec 의 Intel 구현이다. NVIDIA GPU 위에서도 SYCL 코드를 돌릴 수 있는데, 그 경로는 보통 — DPC++ → SPIR-V → CUDA backend (Codeplay / oneAPI plugin) — 으로 깔린다. 즉 최종적으로는 PTX 가 나온다. AMD 도 비슷하게 ROCm 위에 plugin.

“NVIDIA gpus 에서도 SYCL 은 결국 LLVM 을 거쳐 PTX 로 나갑니다 — interface 는 SYCL 이지만 머신 코드는 같은 자리에 도착합니다.”Patric Zhao · 38:12
§ 06PyTorch 위 SYCL· XPU backend · IPEX

PyTorch 안에서 Intel GPU 를 부르는 두 길 — torch.xpu 와 IPEX

2024 년 후반부터 PyTorch 본체에 XPU backend 가 합류했다. CUDA 의 torch.cuda 처럼 torch.xpu.is_available() 가 동작한다. 그 이전 길은 IPEX (Intel Extension for PyTorch) — 같은 작업을 plug-in 형태로 했다.

# PyTorch XPU backend (≥ 2.4)
import torch

assert torch.xpu.is_available()
device = "xpu:0"

x = torch.randn(8192, 8192, device=device)
y = torch.randn(8192, 8192, device=device)
z = x @ y                       # oneDNN GEMM 호출됨
torch.xpu.synchronize()
# IPEX 로 inference 가속 — fused op 자동 매칭
import intel_extension_for_pytorch as ipex
model = ipex.optimize(model, dtype=torch.float16)
out   = model(x.to("xpu"))

강의에서 Patric 이 데모로 보여준 작업 순서.

  1. Vanilla PyTorch + XPU — 정확도 검증의 기준선. device="xpu" 만 바꾸고 모델이 도는지 본다.
  2. IPEX optimize — fused linear+gelu, fused attention, fp16/bf16 자동 캐스팅을 한 번에. inference latency 가 보통 1.5–3× 빨라진다.
  3. SYCL kernel 직접 끼워넣기 — 모델의 hot path 를 oneDNN 도 IPEX 도 못 잡으면 직접 SYCL 로. torch.utils.cpp_extension 의 SYCL 변형이 등장 (DPC++ 기반).

이 셋의 관계는 CUDA 쪽 torch.cuda + torch.compile + load_inline 의 관계와 정확히 평행한다. 강의의 한 메시지 — “CUDA 코드 쓰는 마음으로 SYCL 을 쓸 수 있다” 는 게 인지적 frame.

PyTorch device dispatch 의 실제

PyTorch 안에서 x.to("xpu") 를 부르면 — ATen op 의 XPU dispatch 키가 호출되고, oneDNN 또는 oneMKL 의 vendor 커널이 실행된다. 즉 같은 torch.matmul 한 줄이 device 키에 따라 cuBLAS / oneMKL / Apple MPS / ROCm 으로 갈린다. Frontend 는 같고, dispatch 가 갈라진다.

§ 07CUDA 와 비교· stream · launch · sync

CUDA 사용자가 SYCL 코드를 읽을 때 손에 들고 가야 할 mapping 표

강의의 큰 지렛대 중 하나는 — Patric 이 청중을 “CUDA 알고 있다” 로 가정한다는 것. 그래서 곳곳에서 CUDA → SYCL 직역 을 던진다. 한 페이지로 정리해두면 코드 읽기가 즉시 빨라진다.

cudaStream_t
sycl::queue. 둘 다 비동기 실행 채널. queue 가 dependency 추적까지 한다는 점이 다르다.
cudaMalloc / cudaMemcpy
malloc_device + q.memcpy(...). 또는 malloc_shared 로 한 번에.
__global__ void kernel(...)
cgh.parallel_for(range, [=](id i){ ... }). lambda body 가 device code.
kernel<<<grid,block>>>(...)
q.submit + parallel_for(nd_range<N>{global,local}, ...)
__shared__ float s[N]
local_accessor<float, 1> s({N}, cgh) — handler 안에서 선언, work-group 내 공유.
__syncthreads()
it.barrier() — work-group barrier.
__shfl_xor_sync
shift_group_left/right, permute_group_by_xor — sub-group level shuffle.
cudaDeviceSynchronize
q.wait() 또는 q.wait_and_throw().
cudaGraph
sycl::ext::oneapi::experimental::command_graph — 강의의 Q&A 에서 명시적으로 언급됨.
CUDA event
sycl::event. q.submit(...) 의 반환값. dependency wiring 에 직접 쓴다.

이 mapping 위에서 한 줄로 더 짚어야 하는 점 — SYCL 은 dependency 를 queue 가 자동 추적한다. CUDA 에서 stream 위 같은 work 는 자동 직렬화되지만, 다른 stream 으로 분리하면 이벤트로 동기화를 사용자가 한다. SYCL 은 같은 buffer/USM 에 대한 read/write 의존을 보고 알아서 묶는다 — “잘못된 동기화로 race 가 나는 일이 줄어든다” 가 강의의 작은 메시지.

“SYCL queue 는 dependency 를 압니다. 같은 메모리에 대한 read 와 write 를 보고 알아서 직렬화합니다 — CUDA 에서 stream 을 분리해서 직접 동기화 짜는 패턴의 부담이 줄어듭니다.”Patric Zhao · 51:40
§ 08성능 사례 — fused LLM ops· flash attention · MHA

“같은 모델이 Intel GPU 위에서도 빠른가” 의 답 — fused MHA 와 flash attention

강의 후반부의 본론 — Intel GPU 위에서 LLM inference 의 hot path 를 SYCL 로 다시 짠 사례. fused RMSNorm + matmul, flash attention v2, MHA fusion. CUDA 쪽의 같은 개념과 같은 자리에 박힌다.

FIG · LLM decoder block 의 SYCL fused 커널 매핑4 fused regions
F1
RMSNorm + QKV proj
norm · scale · GEMM 융합
F2
Flash Attention v2
SLM 위 K/V tile · online softmax
F3
Out proj + residual
GEMM + add 융합
F4
RMSNorm + MLP
SwiGLU + GEMM 융합
강의에서 Patric 이 실제 측정값까지 제시 — fused MHA 가 unfused vs ~3.2× 빠름 (LLaMA-7B, Data Center GPU Max). HBM traffic 이 줄어드는 효과가 dominant.

fused MHA 의 구조는 NVIDIA flash attention 과 정확히 같다.

  1. Q tile 한 row 를 register 에 stage.
  2. K tile 을 SLM 으로 load — DPAS / XMX 가 GEMM 처리.
  3. online softmax 가 max · exp_sum 을 register 에 유지하면서 V tile 과 곱한다.
  4. O 는 register 에서 누적되고 마지막에만 HBM 으로 store.

코드의 outer 루프와 inner 루프가 CUDA 코드와 거의 1:1. 다른 점은 단어와 dispatch 만load_2d_block(Intel ESIMD intrinsic)와 joint_matrix_mad(XMX) 가 CUDA 의 cp.asyncmma.sync 자리.

강의에서 인용된 측정 — Data Center GPU Max

LLaMA-7B inference, batch 1, seq 2048. baseline (oneDNN unfused) 대비 SYCL fused MHA 가 토큰당 latency 1/2.8. HBM traffic 이 거의 한 자리수로 감소. 같은 칩 위 cuBLAS 같은 dense math 라이브러리만 부르는 코드 대비 큰 polynomial 차이가 아니라, kernel fusion 자체로 따 내는 것이 절반 이상이라는 점이 중요.

FIG · HBM traffic 의 감소 — fused vs unfusedLLaMA-7B prefill
unfused (eager)
1.00 ×
RMSNorm + QKV fused
0.77 ×
+ flash attention v2
0.44 ×
+ MHA fully fused
0.31 ×
+ MLP SwiGLU fused
0.23 ×
강의에서 보여준 표를 재구성한 그래프. 커널 한 단계씩 fusion이 HBM 왕복을 절반 이하로 줄인다. memory-bound 워크로드에서 throughput 이 거의 그대로 따라온다.
§ 09SYCL 의 portability 약속· NVIDIA · AMD · Intel

“한 번 짜면 여러 vendor 위에서 도는가” — 약속과 실제의 갭

SYCL 의 가장 큰 마케팅은 vendor portability다. Intel · NVIDIA · AMD · 일부 NPU. 그런데 “portable 하지만 portable performance 는 보장 안된다” 는 갭이 늘 따라온다. 강의에서 Patric 이 이 갭을 명시적으로 인정한다.

  • SYCL 코드가 NVIDIA 위에서 도는 길 — DPC++ 의 CUDA backend (Codeplay plugin). LLVM 을 거쳐 PTX 까지 내려간다.
  • AMD 위에서 도는 길 — ROCm backend (마찬가지로 plugin). HIP 으로 mapping.
  • 실제로 portable 한가 — 기본 spec 만 쓰면 portable. vendor extension을 쓰는 순간 portability 가 갈린다 — Intel 의 joint_matrix(XMX), esimd, NVIDIA 의 mma intrinsic 같은 것.
  • portable performance 의 현실 — vendor 별로 sub-group 폭, SLM 크기, tensor core 모양이 모두 다르다. 같은 SYCL 코드가 N vendor 위에서 모두 적당히 돌지만, 가장 빠른 코드는 vendor 별 분기를 넣는다.
FIG · 같은 SYCL 코드의 vendor backend한 단어 → 세 머신 코드
SRC
SYCL C++
parallel_for(...)
IR
SPIR-V
LLVM-based
A
Intel
Xe ISA
B
NVIDIA
PTX → SASS
C
AMD
GCN / RDNA
SPIR-V 가 portability 의 hub. 그 위에서 vendor backend 가 각자의 ISA 로 lower 한다.
현실 점검

“portability” 는 코드가 빌드되고 정답을 낸다는 의미. 가장 빠른 코드를 원한다면 vendor specific intrinsic(XMX, mma, mfma)을 직접 부르게 된다. SYCL 의 가치는 — fallback 코드가 한 벌, hot path 만 vendor 분기 — 라는 작은 표면적이다. “같은 파일 안에서 #ifdef 으로 vendor 갈라낸다” 가 실전 패턴.

“코드가 도는 것과 빠르게 도는 것은 다른 차원입니다. SYCL 은 도는 것의 표면적을 거의 한 코드 베이스로 줄여줍니다 — 그 다음은 여전히 vendor specific tuning 입니다.”Patric Zhao · 1:08:22
§ 10기억할 메모와 코드· key takeaways

다시 열었을 때 5분 안에 손에 잡혀야 하는 것

강의에서 6개월 뒤 돌아왔을 때 가장 빨리 복원해야 하는 사실들과 — 직접 손에 박아야 하는 코드 자료들.

SYCL 의 4 추상
queue, handler, USM/accessor, parallel_for + nd_range. 이 넷이 vector add 부터 GEMM 까지 다 짠다.
CUDA mapping 표
stream→queue · cudaMalloc→malloc_device · __global__→parallel_for · __shared__→local_accessor · __syncthreads→barrier.
Intel GPU 단위
stack > slice > sub-slice > EU > hardware thread > SIMD work-item. SLM 은 work-group 단위 SRAM.
sub-group
NVIDIA warp 의 자리. Xe-HPC 는 보통 16. reqd_sub_group_size attribute 로 명시 권장.
oneAPI stack
Level Zero → DPC++ → oneMKL/oneDNN/oneCCL → IPEX/PyTorch XPU. 각 행이 NVIDIA 쪽과 정확히 평행.
USM 변종 3
malloc_device / malloc_shared / malloc_host. 첫 데모에는 shared, perf 코드에는 device + memcpy.
PyTorch XPU
device="xpu". torch.xpu.synchronize(). IPEX optimize 로 fused op 자동 적용.
portability vs perf
SYCL 은 portable. 가장 빠른 코드는 vendor extension. “fallback 한 벌 + hot path vendor 분기” 가 실전 패턴.
Slides Google Slides
oneAPI Intel oneAPI · oneDNN · IPEX
Code 강의 자체에는 별도 GitHub repo 없음 — slide 안의 코드 캡처만

손에 새기기 — 실습 시퀀스

  1. SYCL vector add 를 한 번 빌드 — Intel oneAPI 또는 Codeplay CUDA plugin 으로. icpx -fsycl vector_add.cpp -o vec. 같은 코드를 NVIDIA backend 로 빌드해서 두 device 위에서 같은 결과를 얻는다.
  2. CUDA → SYCL 직역 — 자기가 가지고 있는 CUDA 커널 한 개를 골라 SYCL 로 옮긴다. __shared__local_accessor, __syncthreadsbarrier mapping 을 직접 손에 박는다.
  3. PyTorch XPU 베이스라인 — Arc GPU 또는 cloud Intel GPU 위에서 torch.xpu 로 LLaMA-2 7B inference 를 돌린다. fp16 / bf16 으로 토큰당 latency 측정.
  4. IPEX optimize 적용 — 같은 모델에 ipex.optimize 한 줄. fused op 가 켜졌을 때의 차이를 본다.
  5. SLM 사용한 reductionlocal_accessor<float> 로 work-group 내 reduction 을 직접 짠다. reduce_over_group 빌트인과 손으로 짠 버전의 perf 비교.
  6. sub-group shuffle — XOR 패턴으로 warp-level reduction 의 SYCL 변형을 짠다. permute_group_by_xor.
  7. flash attention 의 SYCL 버전 살펴보기 — oneDNN 또는 IPEX 의 attention 구현을 git clone 해서 SLM 사용 패턴, sub-group 폭 결정, K/V tile 크기를 직접 읽는다.
§ 11다른 강의로 이어지는 길· connections

이 강의의 도구가 다른 강의에 어떻게 다시 등장하는지

SYCL 자체는 GPU Mode 시리즈에서 외로운 강의지만, 그 안의 개념들 — fused kernel, flash attention, vendor portability — 은 시리즈 전체와 연결된다.

§ 12열린 질문· open questions

다음에 다시 들었을 때 직접 검증해야 할 것들

학습 노트로 정리하면서 비워둔 자리들 — 강의 안에서 부분적으로만 등장한 주제, 또는 후속 검증이 필요한 주제.

검증 메모

이 노트의 측정 수치(fused MHA 2.8×, HBM traffic 0.23×)는 강의에서 Patric 이 보여준 슬라이드 값을 재구성한 예시다. 자기 환경(Arc / Data Center GPU Max / Habana)에서 직접 baseline 을 떠봐야 vendor 간 비교가 의미를 가진다.

← Lecture 025 이전 강의로 Lecture 027 → gpu.cpp — Austin Huang 의 WebGPU 위 portable GPU compute