Sarek_execute.Fusion_horizontalHorizontal fusion of independent kernels (specs/launch-window.md, FR-011).
Members M_0 .. M_{n-1} with the same block shape become one kernel whose grid x is the sum of theirs. Work-group b with off_k <= b < off_k + gx_k runs member k's body unchanged, except that the work-group position it observes is rewritten back to its own: block_idx_x reads b - off_k, grid_dim_x reads gx_k, and the global index and size intrinsics follow. No value flows between members and no arithmetic is added to a member's data path, so the result is bit-identical to running the members one after the other, on every backend.
The dispatch condition depends only on block_idx_x, so it is uniform per work-group: barriers inside a member stay legal.
Every name of member k (parameters, locals, shared arrays, loop and pattern variables) is prefixed m<k>_ and its var ids are offset, so members cannot capture each other's names. The fused kernel's parameters are the members' parameters in order, followed by hf<k>_off and hf<k>_gdx (int32) for each member, a namespace no renamed member name can enter.
val int32_var :
stride:int ->
members:int ->
int ->
string ->
Sarek_ir_types.varval gpu : string -> Sarek_ir_types.exprval member_block : ctx -> Sarek_ir_types.exprval position : ctx -> string -> Sarek_ir_types.expr optionval renaming : ctx -> Ir_rename.ctxval expr : ctx -> Sarek_ir_types.expr -> Sarek_ir_types.exprval stmt : ctx -> Sarek_ir_types.stmt -> Sarek_ir_types.stmtval decl : ctx -> Sarek_ir_types.decl -> Sarek_ir_types.decltype member_parts = {binds : (Sarek_ir_types.var * Sarek_ir_types.expr) list;hoisted shared arrays, renamed
*)body : Sarek_ir_types.stmt;renamed and rewritten
*)params : Sarek_ir_types.decl list;locals : Sarek_ir_types.decl list;off_var : Sarek_ir_types.var;gdx_var : Sarek_ir_types.var;}val member_parts :
stride:int ->
members:int ->
int ->
Sarek_ir_types.kernel ->
member_partsval dispatch : member_parts list -> Sarek_ir_types.stmtval scalar_param : Sarek_ir_types.var -> Sarek_ir_types.declval fuse : name:string -> Sarek_ir_types.kernel list -> Sarek_ir_types.kernelFuse members (at least two, each with Kernel_access.horizontal_verdict = Ok) into one kernel named name. Raises Incompatible when two members define the same type or helper name differently.
val content_named :
prefix:string ->
Sarek_ir_types.kernel ->
Sarek_ir_types.kernel optionk renamed prefix ^ digest, the digest of everything in k but its name: the same fusion gets the same name in every process, so a device compiler's on-disk cache keyed on name and source serves it, and two fused kernels whose IR differs get different names short of an MD5 collision; nothing relies on that, as every compile cache also keys on the source. None when k holds a function value (inline native code), whose bytes have no stable digest.