Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

Kernel launches are compiled for Vararg{Any} and dispatched at run time

Chiusa
#675 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Una pull request collegata è già stata integrata.

  • #687 di @maleadt — integrata

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
30/100
Tipo di issue
Refactoring
Chiarezza
Abbastanza chiara
Stato di attività
Attiva

Direzione di ricerca

Start with code_typed on a kernel call to confirm the Vararg{Any} specialization in src/oneAPIKernels.jl (around line 119) and src/compiler/execution.jl (around line 403). Then look at zefunction (lines 287-323), device() in src/context.jl, and setindex! in lib/level-zero/module.jl. Done means the changes infer fully and precompile timing drops for a new signature, which needs an Intel GPU to verify launches.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

JuliaGPU/Metal.jl#1014 cut the host-side compilation needed to launch a kernel with a new argument signature by 4-10x on Metal. I checked which of the causes found there also apply to oneAPI.jl; several do, and here they also make every launch go through dynamic dispatch.

I don't have an Intel GPU, so this is based on code_typed and on timing precompile of a function launching a new kernel signature, with the changes below prototyped by redefining the functions.

  • (obj::KA.Kernel{oneAPIBackend})(args...; ndrange, workgroupsize) (src/oneAPIKernels.jl:119) and (kernel::HostKernel)(args...; kwargs...) (src/compiler/execution.jl:403) are compiled for Vararg{Any}, e.g. (..., ::oneArray{Float32,...}, ::Vararg{Any}), even when called from concretely typed code: Julia doesn't specialize a method on varargs it only passes on. That includes the @oneapi macro expansion. Everything after that point is dispatched at run time (map(kernel_convert, ...), zefunction, call, launch_configuration), so each new signature gets compiled piecemeal during its first launch, and every launch pays for the dispatches. Metal.jl fixed this with args::Vararg{Any,N} ... where N.
  • zefunction (src/compiler/execution.jl:287-323) compiles its whole body for every kernel. device() (src/context.jl:74-78) infers as Any, which makes compiler_config, the comparisons, hash and the conversion dynamic. The get!(_kernel_instances, h) do HostKernel{F,tt}(f, fun) end closure has a new type for every kernel, so get! is compiled per kernel as well, even though a HostKernel is only (f, fun) and needs no cache. Splitting it like cufunction and cufunction_link in CUDA.jl, with device()::ZeDevice, leaves no dynamic calls on the @oneapi path.
  • setindex!(::ZeKernelArgumentList, value, i) (lib/level-zero/module.jl:208-211) is compiled per argument type with the @checked zeKernelSetArgumentValue wrapper inlined. Computing the size and address per type and calling an unspecialized @noinline setter saves ~13 ms per new signature.
  • launch_configuration (src/compiler/execution.jl:246) returns Union{Missing,Int}, because checking kernel_props.maxGroupSize !== missing doesn't narrow a later field access. As a result threads_to_workgroupsize returns Tuple{Any}, and the final kernel(ctx, args...; items, groups) in the KernelAbstractions launch is a dynamic call. Binding the field to a local first fixes that.

With the first three changes the whole path is inferred, and precompile puts a new signature at ~50 ms (Julia 1.12) / ~44 ms (1.13) for @oneapi and ~31 ms through KernelAbstractions. I can't give a meaningful number for the current code without a GPU, because most of its launch path is only compiled during the launch itself.

Lingua principale
Julia
Stelle
218
Fork
36
Merge medio
1g 4h
PR unite (30g)
54

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di JuliaGPU/oneAPI.jl

Tutte le issue di JuliaGPU/oneAPI.jl

Issue simili

Altre issue su Julia

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.