tiny.accy.preparation.fusion
Defined in preparation.
API (30)
Actions
Public operations.
FusionCluster.lenFusionCluster.rootFusionPlanAnalysis.clusterCountFusionPlanAnalysis.deinitFusionPlanAnalysis.initbroadcastLeafSourcefusionPlanningPassgetFusionPlanAnalysisisFlatGatherOpisFusableElementwiseOpisSeeThroughShapeOpregionsAreOpaque
Types and contracts
Public types and contracts.
Values and defaults
Public values and defaults.
flash_attention_dimflash_attention_min_seqfusion_plan_analysis_descriptorfusion_plan_analysis_namefusion_planning_pass_descriptionfusion_planning_pass_namemax_concat_reduction_groupmax_dot_epilogue_opsmax_reduction_prologue_opsmax_row_pipeline_colsmax_row_pipeline_opsmax_row_pipeline_reducesrow_pipeline_threads
Source
Source: lib/accy/src/preparation/fusion/pass.zig:17
pub const ClaimKind = enum { recompute, slot,};Source: lib/accy/src/preparation/fusion/pass.zig:26
pub const FusionCluster = struct { ops: []*ir.Operation, kind: FusionClusterKind = .elementwise, pub fn len(self: FusionCluster) usize { return self.ops.len; } pub fn root(self: FusionCluster) ?*ir.Operation { if (self.ops.len == 0) return null; return self.ops[self.ops.len - 1]; } fn deinit(self: *FusionCluster, allocator: std.mem.Allocator) void { allocator.free(self.ops); self.* = undefined; }};Source: lib/accy/src/preparation/fusion/pass.zig:45
pub const FusionPlanAnalysis = struct { allocator: std.mem.Allocator, clusters: std.ArrayListUnmanaged(FusionCluster), elided: std.ArrayListUnmanaged(*ir.Operation), fused_op_count: usize = 0, max_cluster_len: usize = 0, pub fn init(allocator: std.mem.Allocator) FusionPlanAnalysis { return .{ .allocator = allocator, .clusters = .empty, .elided = .empty, }; } pub fn deinit(self: *FusionPlanAnalysis) void { for (self.clusters.items) |*cluster| { cluster.deinit(self.allocator); } self.clusters.deinit(self.allocator); self.elided.deinit(self.allocator); self.* = undefined; } pub fn clusterCount(self: FusionPlanAnalysis) usize { return self.clusters.items.len; } fn addCluster(self: *FusionPlanAnalysis, ops: []const *ir.Operation) !void { try self.addClusterOfKind(ops, .elementwise); } fn addClusterOfKind(self: *FusionPlanAnalysis, ops: []const *ir.Operation, kind: FusionClusterKind) !void { if (ops.len < 2) return; try self.addOwnedCluster(ops, kind); } fn addReductionCluster(self: *FusionPlanAnalysis, ops: []const *ir.Operation) !void { if (ops.len == 0) return; try self.addOwnedCluster(ops, .reduction_input); } fn addOwnedCluster(self: *FusionPlanAnalysis, ops: []const *ir.Operation, kind: FusionClusterKind) !void { const owned = try self.allocator.alloc(*ir.Operation, ops.len); @memcpy(owned, ops); errdefer self.allocator.free(owned); try self.clusters.append(self.allocator, .{ .ops = owned, .kind = kind }); self.fused_op_count += owned.len; self.max_cluster_len = @max(self.max_cluster_len, owned.len); }};Source: lib/accy/src/preparation/fusion/pass.zig:22
pub const ClaimMap = std.AutoHashMap(*ir.Operation, ClaimKind);Source: lib/accy/src/preparation/fusion/pass.zig:1512
pub fn broadcastLeafSource(operand: *ir.Value) ?*ir.Value { const def_any = operand.getDefiningOp() orelse return null; const def_op: *ir.Operation = @ptrCast(@alignCast(def_any)); if (!isName(def_op.name.name, dialect_mod.AccyDialect.BroadcastInDimOp.operation_name)) return null; const operands = def_op.getOperandValues(); if (operands.len != 1) return null; if (operands[0].getDefiningOp() != null) return null; return operands[0];}Source: lib/accy/src/preparation/fusion/pass.zig:663
pub const flash_attention_dim = 64;Source: lib/accy/src/preparation/fusion/pass.zig:664
pub const flash_attention_min_seq = 128;Source: lib/accy/src/preparation/fusion/pass.zig:208
pub fn fusionPlanningPass() passes.Pass { return .{ .name = fusion_planning_pass_name, .description = fusion_planning_pass_description, .run_fn = runFusionPlanningPass, .work_contract = .{ .identity = .{ .name = fusion_planning_pass_name, .version = 1 }, .estimate = fusionPassWork, }, };}Source: lib/accy/src/preparation/fusion/pass.zig:186
pub const fusion_plan_analysis_descriptor = passes.AnalysisDescriptor{ .id = passes.analysisId(fusion_plan_analysis_name), .name = fusion_plan_analysis_name, .work_contract = .{ .identity = .{ .name = fusion_plan_analysis_name, .version = 1 }, .estimate = fusionAnalysisWork, },};Source: lib/accy/src/preparation/fusion/pass.zig:12
pub const fusion_plan_analysis_name = "accy-choir-fusion-plan";Source: lib/accy/src/preparation/fusion/pass.zig:14
pub const fusion_planning_pass_description = "Plan block-local Accy Choir elementwise fusion clusters";Source: lib/accy/src/preparation/fusion/pass.zig:13
pub const fusion_planning_pass_name = "accy-choir-plan-fusion";Source: lib/accy/src/preparation/fusion/pass.zig:195
pub fn getFusionPlanAnalysis( pass_ctx: *passes.PassContext, op: *ir.Operation,) !*FusionPlanAnalysis { const ptr = try pass_ctx.getAnalysis( op, &fusion_plan_analysis_descriptor, computeFusionPlanAnalysis, cleanupFusionPlanAnalysis, ); return @ptrCast(@alignCast(ptr));}Source: lib/accy/src/preparation/fusion/pass.zig:492
pub fn isFlatGatherOp(op: *ir.Operation) bool { if (!isName(op.name.name, dialect_mod.AccyDialect.GatherOp.operation_name)) return false; if (op.getNumResults() != 1) return false; const operands = op.getOperandValues(); if (operands.len != 2) return false; const attr = op.getAttr("axis") orelse return false; const int_attr = attr.cast(ir.Attribute.IntegerAttr) orelse return false; if (int_attr.getValue() != 0) return false; var arena_buffer: [256]u8 = undefined; var arena = alloc_fixed.FixedBuffer.init(arena_buffer[0..]); const src_type = dialect_mod.decodeTensorType(arena.allocator(), operands[0].type) catch return false; return src_type.dims.len == 1;}Source: lib/accy/src/preparation/fusion/pass.zig:1526
pub fn isFusableElementwiseOp(op: *ir.Operation) bool { if (op.regions.items.len > 0) return false; if (op.getNumResults() != 1) return false; const name = op.name.name; return std.mem.eql(u8, name, dialect_mod.AccyDialect.AddOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.SubOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.MulOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.DivOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.MaxOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.MinOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.PowOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.Atan2Op.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.NegOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.ExpOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.LogOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.TanhOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.SqrtOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.AbsOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.SinOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.CosOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.TanOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.FloorOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.RoundOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.TruncOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.CompareOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.ConvertOp.operation_name) or std.mem.eql(u8, name, dialect_mod.AccyDialect.SelectOp.operation_name);}Source: lib/accy/src/preparation/fusion/pass.zig:618
pub fn isSeeThroughShapeOp(op: *ir.Operation) bool { if (op.getNumResults() != 1) return false; if (isName(op.name.name, dialect_mod.AccyDialect.SliceOp.operation_name)) return true; if (isName(op.name.name, dialect_mod.AccyDialect.PadOp.operation_name)) { return padHasZeroInterior(op); } return false;}Source: lib/accy/src/preparation/fusion/pass.zig:1226
pub const max_concat_reduction_group = 8;Source: lib/accy/src/preparation/fusion/pass.zig:1128
pub const max_dot_epilogue_ops = 6;Source: lib/accy/src/preparation/fusion/pass.zig:1129
pub const max_reduction_prologue_ops = 48;Source: lib/accy/src/preparation/fusion/pass.zig:819
pub const max_row_pipeline_cols = 8192;Source: lib/accy/src/preparation/fusion/pass.zig:817
pub const max_row_pipeline_ops = 24;Source: lib/accy/src/preparation/fusion/pass.zig:818
pub const max_row_pipeline_reduces = 4;Source: lib/accy/src/preparation/fusion/pass.zig:614
pub fn regionsAreOpaque(op: *ir.Operation) bool { return isName(op.name.name, dialect_mod.AccyDialect.IterateOp.operation_name);}Source: lib/accy/src/preparation/fusion/pass.zig:816
pub const row_pipeline_threads = 256;Source: lib/accy/src/preparation/fusion/pass.zig:24
pub const FusionClusterKind = accy_choir.record.dispatch.FusionClusterKind;Source: lib/accy/src/preparation/fusion/root.zig
const pass = @import("pass.zig");pub const fusion_plan_analysis_name = pass.fusion_plan_analysis_name;pub const fusion_planning_pass_name = pass.fusion_planning_pass_name;pub const fusion_planning_pass_description = pass.fusion_planning_pass_description;pub const ClaimKind = pass.ClaimKind;pub const ClaimMap = pass.ClaimMap;pub const FusionClusterKind = pass.FusionClusterKind;pub const FusionCluster = pass.FusionCluster;pub const FusionPlanAnalysis = pass.FusionPlanAnalysis;pub const fusion_plan_analysis_descriptor = pass.fusion_plan_analysis_descriptor;pub const getFusionPlanAnalysis = pass.getFusionPlanAnalysis;pub const fusionPlanningPass = pass.fusionPlanningPass;pub const isFlatGatherOp = pass.isFlatGatherOp;pub const regionsAreOpaque = pass.regionsAreOpaque;pub const isSeeThroughShapeOp = pass.isSeeThroughShapeOp;pub const flash_attention_dim = pass.flash_attention_dim;pub const flash_attention_min_seq = pass.flash_attention_min_seq;pub const row_pipeline_threads = pass.row_pipeline_threads;pub const max_row_pipeline_ops = pass.max_row_pipeline_ops;pub const max_row_pipeline_reduces = pass.max_row_pipeline_reduces;pub const max_row_pipeline_cols = pass.max_row_pipeline_cols;pub const max_dot_epilogue_ops = pass.max_dot_epilogue_ops;pub const max_reduction_prologue_ops = pass.max_reduction_prologue_ops;pub const max_concat_reduction_group = pass.max_concat_reduction_group;pub const broadcastLeafSource = pass.broadcastLeafSource;pub const isFusableElementwiseOp = pass.isFusableElementwiseOp;Source: lib/accy/src/preparation/root.zig:12
pub const fusion = @import("fusion/root.zig");Complete caller list for preparation.fusion.fusionPlanningPass
10 direct callers.
lib.accy.src.preparation.fusion.pass.checkFusionAdmission[function] — private source atlib/accy/src/preparation/fusion/pass.zig:1941in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.checkFusionChain[function] — private source atlib/accy/src/preparation/fusion/pass.zig:1916in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_claims_reduction_prologues_with_shared_recompute[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1693in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_claims_slices_and_pads_as_see-through_members[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1660in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_claims_softmax_as_one_row_pipeline[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1726in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_elides_producer_shared_by_sibling_roots[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1801in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_finds_single-use_elementwise_producer_DAG[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1630in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_finds_straight-line_elementwise_chain[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1600in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_keeps_narrow_softmax_on_sibling_recompute[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1764in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.test_fusion_planning_rejects_producer_with_escaping_use[function] — test source atlib/accy/src/preparation/fusion/pass.zig:1830in nearest public ownerlib.accy.src.preparation.fusion.pass
Complete caller list for preparation.fusion.isFusableElementwiseOp
10 direct callers.
lib.accy.src.preparation.fusion.pass.collectBlockFlashAttentionPlans[function] — private source atlib/accy/src/preparation/fusion/pass.zig:689in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.collectBlockIterateElisions[function] — private source atlib/accy/src/preparation/fusion/pass.zig:541in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.collectFusionPlansInRegions[function] — private source atlib/accy/src/preparation/fusion/pass.zig:256in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.collectReductionProducerDAG[function] — private source atlib/accy/src/preparation/fusion/pass.zig:1326in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.fusableProducerForOperand[function] — private source atlib/accy/src/preparation/fusion/pass.zig:462in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.hasFusableOutputUser[function] — private source atlib/accy/src/preparation/fusion/pass.zig:314in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.isDotEpilogueOp[function] — private source atlib/accy/src/preparation/fusion/pass.zig:1473in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.rowPipelineQueryOk[function] — private source atlib/accy/src/preparation/fusion/pass.zig:957in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.rowPipelineTerminalCandidate[function] — private source atlib/accy/src/preparation/fusion/pass.zig:917in nearest public ownerlib.accy.src.preparation.fusion.passlib.accy.src.preparation.fusion.pass.userCanRecompute[function] — private source atlib/accy/src/preparation/fusion/pass.zig:409in nearest public ownerlib.accy.src.preparation.fusion.pass
Audit
| Definitions | 31 |
|---|---|
| Public names | 33 |
| Members | 9 |
| Version | 26.7.0 |
| Revision | daab053ee433 |