Sarek_execute.Launch_epilogueEpilogue fusion in the launch window (specs/epilogue-fusion.md).
When an element-wise launch C arrives, it is merged into a pending launch P that writes the one vector I it consumes, if all of the following hold. The merged launch replaces P in its group and can itself host a further epilogue or join a horizontal group. The rewrite is Fusion_epilogue.
Conditions (vectors compared by identity, on one device).
decide_pair): not switched off (set_backend_enabled), and exact (HIP, Metal) or granted Cross_kernel_contraction for both P and C (CUDA, OpenCL, Vulkan).Fusion_epilogue.consumer). C is 1-D with no dynamic shared memory.Coverage_affine when the indices are affine, else by enumerating both launches with Index_slice, within max_enumerated threads.The coverage verdict is cached by (P, the producer array, C, their dimensions, the values of the scalars the evaluation read).
module LW = Launch_windowinclude module type of struct include Epilogue_policy endSwitch epilogue fusion off (false) or back on (true) for one backend. Switching on is not a grant: on CUDA, OpenCL and Vulkan fusion still needs Sarek_policy.deviation.Cross_kernel_contraction for both kernels.
val pair_cache :
(string * string * string, int * Sarek_policy.decision) Stdlib.Hashtbl.tval policy_decision :
backend:string ->
producer:string ->
consumer:string ->
Sarek_policy.decisionval decide_pair :
backend:string ->
producer:string ->
consumer:string ->
Sarek_policy.decisionWhether the epilogue of consumer may be merged into producer on backend: the backend is not switched off or inexact, and Sarek_policy.decide allows Sarek_policy.optimisation.Epilogue_fusion for the meet of both kernels' budgets.
Whether fusion can run on backend under the process grants alone: not switched off, exact, and allowed by Sarek_policy.decide for the process budget (HIP and Metal; the others once Cross_kernel_contraction is granted at process scope). Kernel-scoped grants are not seen: the decision per pair is decide_pair.
val dims_of : 'a LW.launch -> Index_slice.dimsval shapes :
(int, (Fusion_epilogue.consumer, string) Stdlib.result) Stdlib.Hashtbl.tval shape_of :
'a LW.t ->
'b LW.launch ->
(Fusion_epilogue.consumer, string) Stdlib.resultHow coverage verdicts were reached, since start-up: by the affine proof (Coverage_affine), by enumeration, or refused as over the enumeration bound.
val proof_counts : unit -> proof_countsval threads : 'a LW.launch -> intval slice :
'a LW.launch ->
is_target:(string -> bool) ->
record:(int32 -> unit) ->
scalars:(string * int32) list ->
string listval enumerate :
p:'a LW.launch ->
p_array:Stdlib.String.t ->
p_scalars:(string * int32) list ->
c:'b LW.launch ->
shape:Fusion_epilogue.consumer ->
c_scalars:(string * int32) list ->
bool * (string * string) listval covers :
p:'a LW.launch ->
p_array:Stdlib.String.t ->
p_scalars:(string * int32) list ->
c:'b LW.launch ->
shape:Fusion_epilogue.consumer ->
c_scalars:(string * int32) list ->
bool * (string * string) listval coverage_cache :
(int * string * int * Index_slice.dims * Index_slice.dims, verdict list)
Stdlib.Hashtbl.tval cached_covers :
p:'a LW.launch ->
p_array:Stdlib.String.t ->
p_scalars:(string * int32) list ->
c:'b LW.launch ->
shape:Fusion_epilogue.consumer ->
c_scalars:(string * int32) list ->
boolval fused_cache :
(int * string * int * (string * string) list, Sarek_ir_types.kernel option)
Stdlib.Hashtbl.tval fused_ir :
p:'a LW.launch ->
p_array:string ->
c:'b LW.launch ->
shared:(string * string) list ->
Sarek_ir_types.kernel optionval merged :
'arg LW.t ->
'arg LW.launch ->
'arg LW.launch ->
fused:Sarek_ir_types.kernel ->
p_array:string ->
shared:(string * string) list ->
tc:int ->
'arg LW.launchval merge_point :
'a LW.t ->
'a LW.group ->
'a LW.launch ->
'a LW.launch ->
Fusion_epilogue.consumer ->
int ->
(string * (string * string) list) optionval one_dimensional : 'a LW.launch -> bool