tiny.accy.preparation.pipeline
Defined in preparation.
API (204)
Actions
Public operations.
BackendPreparationFailure.captureBackendPreparationFailure.deinitBackendPreparationTiming.collectsPassIrSizesBackendPreparationTiming.deinitBackendPreparationTiming.getAnalysisCountBackendPreparationTiming.getAnalysisTimeBackendPreparationTiming.getPassAllocBytesBackendPreparationTiming.getPassAllocCountBackendPreparationTiming.getPassCountBackendPreparationTiming.getPassFreeCountBackendPreparationTiming.getPassOpCountAfterBackendPreparationTiming.getPassOpCountBeforeBackendPreparationTiming.getPassOpCountDeltaBackendPreparationTiming.getPassTimeBackendPreparationTiming.initBackendPreparationTiming.initWithOptionsBackendPreparationTiming.setAllocationSnapshotProviderBackendPreparedJob.copyGeneratedKernelSummariesBackendPreparedJob.deinitBackendPreparedJob.generatedKernelCountBackendPreparedJob.generatedKernelProgramBackendPreparedJob.generatedKernelProgramForWorkBackendPreparedJob.generatedKernelSummaryBackendPreparedJob.generatedKernelSummaryForWorkBackendPreparedJob.kernelizationProductBackendPreparedJob.passContextBackendPreparedJob.productStampsBackendPreparedJob.targetModuleBackendPreparedModule.createBackendPreparedModule.deinitBackendPreparedModule.productGraphBackendPreparedModule.productKeysBackendPreparedModule.retainBackendPreparedModule.stage: A caller reads one sealed stage record, for example the final one to emit device code: the call returns the record forselected.ContractPreparationResult.deinitDispatchPreparationResult.deinitKernelPreparationResult.deinitMemoryPreparationResult.deinitTargetPreparationResult.deinitTensorLoweringOptions.eqlTensorPreparationResult.deinitactivationLoweringPassactivationLoweringPassWithOptionsaddContractPipelineaddDispatchPipelineaddKernelPipelineaddMemoryPipelineaddTargetPipelineaddTensorPipelineaddTensorPipelineWithOptionsbackendLegalizationPassbufferizationPlanningPassbuildBackendPreparationContextcanonicalizationPasscanonicalizeModuleconstantFoldingPasscontractAnalysisNamecontractPassNamedispatchAnalysisNamedispatchPassNamedtypeLegalizationPasseinsumLoweringPasseinsumLoweringPassWithOptionsfusionPlanningPassindexingLoweringPassindexingLoweringPassWithOptionskernelAnalysisNamekernelOutliningPlanningPasskernelPassNamekernelizationPasslayoutPlanningPasslossLoweringPasslossLoweringPassWithOptionsmemoryAnalysisNamememoryPassNamememorySpacePlanningPassprepareBackendJobFromContractJobprepareBackendJobFromContractPreparationResultprepareBackendJobFromDispatchPreparationResultprepareBackendJobFromKernelPreparationResultprepareBackendJobFromMemoryPreparationResultprepareBackendJobFromSemanticModuleprepareBackendJobFromTargetPreparationResultprepareBackendJobFromTensorPreparationResultprepareContractJobFromSemanticModuleprepareContractJobFromSemanticModuleWithRunprepareDispatchJobFromTensorJobprepareDispatchJobFromTensorJobWithRunprepareKernelJobFromMemoryJobprepareKernelJobFromMemoryJobWithRunprepareMemoryJobFromDispatchJobprepareMemoryJobFromDispatchJobWithRunprepareTargetJobFromKernelJobprepareTargetJobFromKernelJobWithRunprepareTensorJobFromContractJobprepareTensorJobFromContractJobWithRunreadBackendTargetProfilerunBackendPreparationPipelineFromSemanticModulerunTargetPipelinerunTargetPipelineWithDiagnosticsrunTargetPipelineWithOptionssaturateTensorOperationsschedulePlanningPasssetBackendTargetProfileshapeLayoutPropagationPasstargetAnalysisNametargetPassNametensorAnalysisNametensorPassNametensorSaturationPass
Types and contracts
Public types and contracts.
ActivationLoweringOptionsBackendPreparationFailureBackendPreparationFailureKindBackendPreparationProductKeysBackendPreparationProductStampsBackendPreparationRunBackendPreparationRunOptionsBackendPreparationStageBackendPreparationStatsBackendPreparationTimingBackendPreparationTiming.AllocationSnapshotBackendPreparationTiming.AllocationSnapshotProviderBackendPreparationTiming.TimingOptionsBackendPreparedJobBackendPreparedModule: A caller holds this as the finished result of one compile, to read any stage or to launch the final one: the result holds one sealed stage record for each of the seven stages, and each is checked to belong to its stage and to depend on the stage before it.BackendTargetProfileContractPreparationResultDispatchPreparationResultEinsumLoweringOptionsIndexingLoweringOptionsKernelLibraryLoweringKernelPreparationResultMemoryPreparationResultPipelineErrorTargetPreparationResultTensorLoweringOptionsTensorPreparationResult
Values and defaults
Public values and defaults.
accy_choir_package_extensionaccy_choir_pass_registrationsactivation_lowering_pass_namebackend_legalization_pass_namebufferization_planning_pass_namecanonicalization_pass_nameconstant_folding_pass_namecontract_analysis_countcontract_pass_countcontract_pass_plancontract_pass_registrationscontract_pipeline_descriptioncontract_pipeline_namecontract_pipeline_registrationcontract_stagesdispatch_analysis_countdispatch_pass_countdispatch_pass_plandispatch_pass_registrationsdispatch_pipeline_descriptiondispatch_pipeline_namedispatch_pipeline_registrationdispatch_stagesdtype_legalization_pass_nameeinsum_lowering_pass_namefusion_planning_pass_nameindexing_lowering_pass_namekernel_analysis_countkernel_outlining_planning_pass_namekernel_pass_countkernel_pass_plankernel_pass_registrationskernel_pipeline_descriptionkernel_pipeline_namekernel_pipeline_registrationkernel_stageskernelization_pass_namelayout_planning_pass_nameloss_lowering_pass_namememory_analysis_countmemory_pass_countmemory_pass_planmemory_pass_registrationsmemory_pipeline_descriptionmemory_pipeline_namememory_pipeline_registrationmemory_space_planning_pass_namememory_stagessaturation_pass_nameschedule_planning_pass_nameshape_layout_pass_nametarget_analysis_counttarget_pass_counttarget_pass_plantarget_pass_registrationstarget_pipeline_descriptiontarget_pipeline_nametarget_pipeline_registrationtarget_stagestensor_analysis_counttensor_pass_counttensor_pass_plantensor_pass_registrationstensor_pipeline_descriptiontensor_pipeline_nametensor_pipeline_registrationtensor_stages
Source
Source: lib/accy/src/preparation/execution.zig:63
pub const ContractPreparationResult = struct { module: *contract.ContractJob, elapsed_ns: u64, stats: BackendPreparationStats, initial_choir_ops: u64, semantic_fingerprint: ?u64, started_at: i128, finished_at: i128, pub fn deinit(self: *ContractPreparationResult) void { self.module.deinit(); self.* = undefined; }};Source: lib/accy/src/preparation/execution.zig:89
pub const DispatchPreparationResult = struct { module: *dispatch.DispatchJob, elapsed_ns: u64, stats: BackendPreparationStats, /// A caller reads this field to show whether the dispatch plans of two runs look alike. The /// field holds a 64-bit summary of the plans made by the dispatch stage, for display in a run /// stamp, the per-stage display record built for people reading a run. No product key or reuse /// decision reads it. plan_fingerprint: u64, pub fn deinit(self: *DispatchPreparationResult) void { self.module.deinit(); self.* = undefined; }};Source: lib/accy/src/preparation/execution.zig:120
pub const KernelPreparationResult = struct { module: *kernel_product.KernelJob, elapsed_ns: u64, stats: BackendPreparationStats, /// A caller reads this field to show whether the kernel plans of two runs look alike. The field /// holds a 64-bit summary of the kernel outline and generated kernels made by the kernel stage, /// for display in run stamps. No product key or reuse decision reads it. plan_fingerprint: u64, pub fn deinit(self: *KernelPreparationResult) void { self.module.deinit(); self.* = undefined; }};Source: lib/accy/src/preparation/execution.zig:105
pub const MemoryPreparationResult = struct { module: *memory_product.MemoryJob, elapsed_ns: u64, stats: BackendPreparationStats, /// A caller reads this field to show whether the memory plans of two runs look alike. The field /// holds a 64-bit summary of the buffer, memory-space and layout plans made by the memory /// stage, for display in run stamps. No product key or reuse decision reads it. plan_fingerprint: u64, pub fn deinit(self: *MemoryPreparationResult) void { self.module.deinit(); self.* = undefined; }};Source: lib/accy/src/preparation/execution.zig:22
pub const PipelineError = error{ PassFailed,};Source: lib/accy/src/preparation/execution.zig:135
pub const TargetPreparationResult = struct { module: *target_product.TargetJob, elapsed_ns: u64, stats: BackendPreparationStats, finished_at: i128, pub fn deinit(self: *TargetPreparationResult) void { self.module.deinit(); self.* = undefined; }};Source: lib/accy/src/preparation/execution.zig:78
pub const TensorPreparationResult = struct { module: *tensor.TensorJob, elapsed_ns: u64, stats: BackendPreparationStats, pub fn deinit(self: *TensorPreparationResult) void { self.module.deinit(); self.* = undefined; }};Source: lib/accy/src/preparation/prepared.zig:45
pub const BackendPreparedJob = struct { allocator: std.mem.Allocator, ctx: *ir.Context, choir_module: *ir.Operation, target_module: ?*target_product.TargetJob, run: BackendPreparationRun, pub fn deinit(self: *BackendPreparedJob) void { if (self.target_module) |module| module.deinit(); self.* = undefined; } pub fn passContext(self: *BackendPreparedJob) passes.PassContext { return self.target_module.?.passContext(); } pub fn targetModule(self: *const BackendPreparedJob) !*target_product.TargetJob { return self.target_module orelse error.MissingTargetProduct; } pub fn kernelizationProduct(self: *const BackendPreparedJob) !*const kernelization.KernelizationAnalysis { return (try self.targetModule()).kernelizationProduct(); } pub fn generatedKernelCount(self: *const BackendPreparedJob) !usize { const product = try self.kernelizationProduct(); return product.kernelCount(); } pub fn productStamps(self: *const BackendPreparedJob) !BackendPreparationProductStamps { return product_mod.stampsFromRun(self.run); } pub fn generatedKernelSummary( self: *const BackendPreparedJob, kernel_index: usize, ) !kernelization.GeneratedKernelSummary { const product = try self.kernelizationProduct(); return product.kernelSummary(kernel_index); } pub fn generatedKernelProgram( self: *const BackendPreparedJob, kernel_index: usize, ) !*const kernelization.GeneratedKernelProgram { const product = try self.kernelizationProduct(); return product.kernelProgram(kernel_index); } pub fn generatedKernelSummaryForWork( self: *const BackendPreparedJob, work_item_id: usize, ) !kernelization.GeneratedKernelSummary { const product = try self.kernelizationProduct(); return product.kernelSummaryForWork(work_item_id); } pub fn generatedKernelProgramForWork( self: *const BackendPreparedJob, work_item_id: usize, ) !*const kernelization.GeneratedKernelProgram { const product = try self.kernelizationProduct(); return product.kernelProgramForWork(work_item_id); } pub fn copyGeneratedKernelSummaries( self: *const BackendPreparedJob, result_allocator: std.mem.Allocator, ) !kernelization.GeneratedKernelSummaries { const product = try self.kernelizationProduct(); return product.copyKernelSummaries(result_allocator); }};Source: lib/accy/src/preparation/product.zig:117
pub const BackendPreparationProductKeys = struct { semantic: ?choir.product.incremental.ProductKey = null, contract: choir.product.incremental.ProductKey, tensor: choir.product.incremental.ProductKey, dispatch: choir.product.incremental.ProductKey, memory: choir.product.incremental.ProductKey, kernel: choir.product.incremental.ProductKey, target: choir.product.incremental.ProductKey,};Source: lib/accy/src/preparation/product.zig:107
pub const BackendPreparationProductStamps = struct { semantic: ?choir.product.incremental.ProductStamp = null, contract: choir.product.incremental.ProductStamp, tensor: choir.product.incremental.ProductStamp, dispatch: choir.product.incremental.ProductStamp, memory: choir.product.incremental.ProductStamp, kernel: choir.product.incremental.ProductStamp, target: choir.product.incremental.ProductStamp,};Source: lib/accy/src/preparation/product.zig:22
/// A caller holds this as the finished result of one compile, to read any stage or to launch the/// final one: the result holds one sealed stage record for each of the seven stages, and each is/// checked to belong to its stage and to depend on the stage before it. The result holds no mutable/// compiler job, so nothing can change a stage after the result is made. `retain` returns another/// owner of the same records, and `deinit` releases this owner's references.pub const BackendPreparedModule = opaque { const Data = struct { allocator: std.mem.Allocator, records: [7]*const revision.Revision, }; const stages = [_]publication.Stage{ .semantic, .contract, .tensor, .dispatch, .memory, .kernel, .target, }; pub fn create( allocator: std.mem.Allocator, records: [7]*const revision.Revision, ) !*BackendPreparedModule { inline for (stages, 0..) |selected, index| { const item = records[index]; if (!std.mem.eql(u8, item.address().stage, selected.name())) return error.WrongStage; try item.requireGates(&.{ choir.product.operation.schema_identity, selected.schema() }); if (index != 0) try requirePredecessor(item, records[index - 1]); } const owned = try allocator.create(Data); errdefer allocator.destroy(owned); var retained: usize = 0; errdefer for (records[0..retained]) |item| item.release(); for (records) |item| { _ = try item.retain(); retained += 1; } owned.* = .{ .allocator = allocator, .records = records }; return @ptrCast(owned); } fn requirePredecessor(item: *const revision.Revision, previous: *const revision.Revision) !void { item.requireDependency("source", previous) catch |err| switch (err) { error.UndeclaredProductInput => return error.UnboundProductInput, }; } fn data(self: *const BackendPreparedModule) *const Data { return @ptrCast(@alignCast(self)); } pub fn deinit(self: *BackendPreparedModule) void { const owned = self.data(); for (owned.records) |item| item.release(); owned.allocator.destroy(@constCast(owned)); } pub fn retain( self: *const BackendPreparedModule, allocator: std.mem.Allocator, ) !*BackendPreparedModule { return create(allocator, self.data().records); } /// A caller reads one sealed stage record, for example the final one to emit device code: the /// call returns the record for `selected`. The record is borrowed from this result, and a /// caller that needs it after the result is released retains it. pub fn stage( self: *const BackendPreparedModule, comptime selected: publication.Stage, ) *const revision.Revision { return self.data().records[@backingInt(selected)]; } pub fn productKeys(self: *const BackendPreparedModule) BackendPreparationProductKeys { return .{ .semantic = choir.product.incremental.productKey(self.stage(.semantic).metadata()), .contract = choir.product.incremental.productKey(self.stage(.contract).metadata()), .tensor = choir.product.incremental.productKey(self.stage(.tensor).metadata()), .dispatch = choir.product.incremental.productKey(self.stage(.dispatch).metadata()), .memory = choir.product.incremental.productKey(self.stage(.memory).metadata()), .kernel = choir.product.incremental.productKey(self.stage(.kernel).metadata()), .target = choir.product.incremental.productKey(self.stage(.target).metadata()), }; } pub fn productGraph( self: *const BackendPreparedModule, allocator: std.mem.Allocator, ) !choir.product.incremental.ProductGraph { return graphFromKeys(allocator, self.productKeys()); }};Source: lib/accy/src/preparation/run.zig:21
pub const BackendPreparationFailure = struct { pipeline_name: ?[]const u8 = null, failure_kind: ?BackendPreparationFailureKind = null, pass_name: ?[]const u8 = null, target_op_name: ?[]const u8 = null, target_symbol_name: ?[]const u8 = null, verifier_error_name: ?[]const u8 = null, worker_count: usize = 0, pub fn deinit(self: *BackendPreparationFailure, allocator: std.mem.Allocator) void { if (self.pass_name) |name| allocator.free(name); if (self.target_op_name) |name| allocator.free(name); if (self.target_symbol_name) |name| allocator.free(name); if (self.verifier_error_name) |name| allocator.free(name); self.* = .{}; } pub fn capture( self: *BackendPreparationFailure, allocator: std.mem.Allocator, pipeline_name: []const u8, reproducer: *const passes.PassFailureReproducer, ) !void { self.deinit(allocator); errdefer self.deinit(allocator); self.pipeline_name = pipeline_name; self.failure_kind = reproducer.failure_kind; self.worker_count = reproducer.worker_count; self.pass_name = try dupeOptional(allocator, reproducer.pass_name); self.target_op_name = try dupeOptional(allocator, reproducer.target_op_name); self.target_symbol_name = try dupeOptional(allocator, reproducer.target_symbol_name); self.verifier_error_name = try dupeOptional(allocator, reproducer.verifier_error_name); } fn dupeOptional(allocator: std.mem.Allocator, value: ?[]const u8) !?[]const u8 { if (value) |text| return try allocator.dupe(u8, text); return null; }};Source: lib/accy/src/preparation/run.zig:149
pub const BackendPreparationRun = struct { total_ns: u64, contract_ns: u64 = 0, tensor_ns: u64 = 0, dispatch_ns: u64 = 0, memory_ns: u64 = 0, kernel_ns: u64 = 0, target_ns: u64 = 0, initial_choir_ops: u64, final_choir_ops: u64, semantic_fingerprint: ?u64 = null, contract_fingerprint: u64 = 0, tensor_fingerprint: u64 = 0, /// A caller reads this field to show whether the dispatch plans of two runs look alike. The /// field holds a 64-bit summary of the plans made by the dispatch stage, zero when the stage /// has not run. It is for display, and no product key or reuse decision reads it. dispatch_fingerprint: u64 = 0, /// A caller reads this field to show whether the memory plans of two runs look alike. The field /// holds a 64-bit summary of the buffer, memory-space and layout plans made by the memory /// stage, zero when the stage has not run. It is for display, and no product key or reuse /// decision reads it. memory_fingerprint: u64 = 0, /// A caller reads this field to show whether the kernel plans of two runs look alike. The field /// holds a 64-bit summary of the kernel outline and generated kernels made by the kernel stage, /// zero when the stage has not run. It is for display, and no product key or reuse decision /// reads it. kernel_fingerprint: u64 = 0, target_fingerprint: u64 = 0, contract_stats: BackendPreparationStats = .{}, tensor_stats: BackendPreparationStats = .{}, dispatch_stats: BackendPreparationStats = .{}, memory_stats: BackendPreparationStats = .{}, kernel_stats: BackendPreparationStats = .{}, target_stats: BackendPreparationStats = .{}, target_profile: ?target_profile.BackendTargetProfile = null,};Source: lib/accy/src/preparation/run.zig:139
pub const BackendPreparationRunOptions = struct { timing: ?*BackendPreparationTiming = null, failure: ?*BackendPreparationFailure = null, target_profile: ?target_profile.BackendTargetProfile = null, generated_scan_schedules: []const target_profile.GeneratedScanScheduleDecision = &.{}, generated_row_pipeline_schedules: []const target_profile.GeneratedRowPipelineScheduleDecision = &.{}, tensor: stage.TensorLoweringOptions = .{}, now: *const fn () i128 = sys.time.nanoTimestamp,};Source: lib/accy/src/preparation/run.zig:10
pub const BackendPreparationStats = struct { pass_runs: u64 = 0, pass_failures: u64 = 0, passes_modified: u64 = 0, analysis_hits: u64 = 0, analysis_misses: u64 = 0, analyses_invalidated: u64 = 0,};Source: lib/accy/src/preparation/run.zig:62
pub const BackendPreparationTiming = struct { inner: passes.TimingInstrumentation, pub const TimingOptions: type = passes.PassTimingOptions; pub const AllocationSnapshot: type = passes.PassAllocationSnapshot; pub const AllocationSnapshotProvider: type = passes.PassAllocationSnapshotProvider; pub fn init(allocator: std.mem.Allocator) BackendPreparationTiming { return .{ .inner = passes.TimingInstrumentation.init(allocator) }; } pub fn initWithOptions(allocator: std.mem.Allocator, options: TimingOptions) BackendPreparationTiming { return .{ .inner = passes.TimingInstrumentation.initWithOptions(allocator, options) }; } pub fn deinit(self: *BackendPreparationTiming) void { self.inner.deinit(); self.* = undefined; } fn instrumentation(self: *BackendPreparationTiming) passes.PassInstrumentation { return self.inner.instrumentation(); } pub fn getPassTime(self: *const BackendPreparationTiming, name: []const u8) ?i128 { return self.inner.getPassTime(name); } pub fn getPassCount(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getPassCount(name); } pub fn getPassOpCountBefore(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getPassOpCountBefore(name); } pub fn getPassOpCountAfter(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getPassOpCountAfter(name); } pub fn getPassOpCountDelta(self: *const BackendPreparationTiming, name: []const u8) ?i128 { return self.inner.getPassOpCountDelta(name); } pub fn setAllocationSnapshotProvider( self: *BackendPreparationTiming, provider: ?AllocationSnapshotProvider, ) void { self.inner.setAllocationSnapshotProvider(provider); } pub fn getPassAllocCount(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getPassAllocCount(name); } pub fn getPassFreeCount(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getPassFreeCount(name); } pub fn getPassAllocBytes(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getPassAllocBytes(name); } pub fn getAnalysisTime(self: *const BackendPreparationTiming, name: []const u8) ?i128 { return self.inner.getAnalysisTime(name); } pub fn getAnalysisCount(self: *const BackendPreparationTiming, name: []const u8) ?u64 { return self.inner.getAnalysisCount(name); } pub fn collectsPassIrSizes(self: *const BackendPreparationTiming) bool { return self.inner.collectsPassIrSizes(); }};Source: lib/accy/src/preparation/stage.zig:142
pub const BackendPreparationStage = struct { name: []const u8, description: []const u8, pass: passes.Pass, analysis_name: ?[]const u8 = null, options: []const passes.PassOptionSpec = &.{}, build_with_options: ?passes.PassOptionsBuilderFn = null, fn registration(self: BackendPreparationStage) passes.PassRegistration { return .{ .name = self.name, .description = self.description, .pass = self.pass, .options = self.options, .build_with_options = self.build_with_options, }; }};Source: lib/accy/src/preparation/stage.zig:27
pub const TensorLoweringOptions = struct { activation: activation_lowering.Options = .{}, einsum: einsum_lowering.Options = .{}, indexing: indexing_lowering.Options = .{}, loss: loss_lowering.Options = .{}, pub fn eql(self: TensorLoweringOptions, other: TensorLoweringOptions) bool { return self.activation.eql(other.activation) and self.einsum.eql(other.einsum) and self.indexing.eql(other.indexing) and self.loss.eql(other.loss); }};Source: lib/accy/src/preparation/execution.zig:192
pub fn prepareContractJobFromSemanticModule( allocator: std.mem.Allocator, module: *semantic.SemanticModule, options: BackendPreparationRunOptions,) !*contract.ContractJob { const result = try prepareContractJobFromSemanticModuleWithRun( allocator, module, options, ); return result.module;}Source: lib/accy/src/preparation/execution.zig:270
pub fn prepareContractJobFromSemanticModuleWithRun( allocator: std.mem.Allocator, module: *semantic.SemanticModule, options: BackendPreparationRunOptions,) !ContractPreparationResult { var module_owned = true; errdefer if (module_owned) module.deinit(); try module.verify(); const initial_choir_ops = countOperationTree(module.choir_module); const semantic_fingerprint = try module.fingerprint(allocator); var analysis_cache = passes.AnalysisCache.init(allocator, null); defer analysis_cache.deinit(); var pm = passes.PassManager.init(allocator); defer pm.deinit(); if (options.timing) |timing| try run_mod.addTimingInstrumentation(&pm, timing); try recipe.configure(&pm, .contract, &options); const contract_start = options.now(); if (pm.runWithAnalysisCache( module.choir_module, module.context(), &analysis_cache, recipe.runOptions(), ) == .failure) { return preparationPassFailed(allocator, options, stage_mod.contract_pipeline_name, &pm); } const contract_end = options.now(); const contract_module = try contract.ContractJob.init(allocator, module); module_owned = false; return .{ .module = contract_module, .elapsed_ns = nsBetween(contract_start, contract_end), .stats = run_mod.backendPreparationStats(pm.stats), .initial_choir_ops = initial_choir_ops, .semantic_fingerprint = semantic_fingerprint, .started_at = contract_start, .finished_at = contract_end, };}Source: lib/accy/src/preparation/execution.zig:218
pub fn prepareDispatchJobFromTensorJob( allocator: std.mem.Allocator, module: *tensor.TensorJob, options: BackendPreparationRunOptions,) !*dispatch.DispatchJob { const result = try prepareDispatchJobFromTensorJobWithRun( allocator, module, options, ); return result.module;}Source: lib/accy/src/preparation/execution.zig:355
pub fn prepareDispatchJobFromTensorJobWithRun( allocator: std.mem.Allocator, module: *tensor.TensorJob, options: BackendPreparationRunOptions,) !DispatchPreparationResult { var module_owned = true; errdefer if (module_owned) module.deinit(); try module.verify(); var pm = passes.PassManager.init(allocator); defer pm.deinit(); if (options.timing) |timing| try run_mod.addTimingInstrumentation(&pm, timing); try recipe.configure(&pm, .dispatch, &options); const dispatch_start = options.now(); if (pm.runWithAnalysisCache( module.choir_module, module.context(), &module.analysis_cache, recipe.runOptions(), ) == .failure) { return preparationPassFailed(allocator, options, stage_mod.dispatch_pipeline_name, &pm); } const dispatch_end = options.now(); const plan_fingerprint = try stage_fingerprint.dispatch( allocator, module, stage_mod.dispatch_pipeline_name, ); const dispatch_module = try dispatch.DispatchJob.init(allocator, module); module_owned = false; return .{ .module = dispatch_module, .elapsed_ns = nsBetween(dispatch_start, dispatch_end), .stats = run_mod.backendPreparationStats(pm.stats), .plan_fingerprint = plan_fingerprint, };}Source: lib/accy/src/preparation/execution.zig:244
pub fn prepareKernelJobFromMemoryJob( allocator: std.mem.Allocator, module: *memory_product.MemoryJob, options: BackendPreparationRunOptions,) !*kernel_product.KernelJob { const result = try prepareKernelJobFromMemoryJobWithRun( allocator, module, options, ); return result.module;}Source: lib/accy/src/preparation/execution.zig:437
pub fn prepareKernelJobFromMemoryJobWithRun( allocator: std.mem.Allocator, module: *memory_product.MemoryJob, options: BackendPreparationRunOptions,) !KernelPreparationResult { var module_owned = true; errdefer if (module_owned) module.deinit(); try module.verify(); var pm = passes.PassManager.init(allocator); defer pm.deinit(); if (options.timing) |timing| try run_mod.addTimingInstrumentation(&pm, timing); try recipe.configure(&pm, .kernel, &options); try recipe.applyTargetOptions(allocator, module.choir_module, options); const kernel_start = options.now(); if (pm.runWithAnalysisCache( module.choir_module, module.context(), &module.dispatch_module.tensor_module.analysis_cache, recipe.runOptions(), ) == .failure) { return preparationPassFailed(allocator, options, stage_mod.kernel_pipeline_name, &pm); } const kernel_end = options.now(); const plan_fingerprint = try stage_fingerprint.kernel( allocator, module, stage_mod.kernel_pipeline_name, ); const kernel_module = try kernel_product.KernelJob.init(allocator, module); module_owned = false; return .{ .module = kernel_module, .elapsed_ns = nsBetween(kernel_start, kernel_end), .stats = run_mod.backendPreparationStats(pm.stats), .plan_fingerprint = plan_fingerprint, };}Source: lib/accy/src/preparation/execution.zig:231
pub fn prepareMemoryJobFromDispatchJob( allocator: std.mem.Allocator, module: *dispatch.DispatchJob, options: BackendPreparationRunOptions,) !*memory_product.MemoryJob { const result = try prepareMemoryJobFromDispatchJobWithRun( allocator, module, options, ); return result.module;}Source: lib/accy/src/preparation/execution.zig:396
pub fn prepareMemoryJobFromDispatchJobWithRun( allocator: std.mem.Allocator, module: *dispatch.DispatchJob, options: BackendPreparationRunOptions,) !MemoryPreparationResult { var module_owned = true; errdefer if (module_owned) module.deinit(); try module.verify(); var pm = passes.PassManager.init(allocator); defer pm.deinit(); if (options.timing) |timing| try run_mod.addTimingInstrumentation(&pm, timing); try recipe.configure(&pm, .memory, &options); const memory_start = options.now(); if (pm.runWithAnalysisCache( module.choir_module, module.context(), &module.tensor_module.analysis_cache, recipe.runOptions(), ) == .failure) { return preparationPassFailed(allocator, options, stage_mod.memory_pipeline_name, &pm); } const memory_end = options.now(); const plan_fingerprint = try stage_fingerprint.memory( allocator, module, stage_mod.memory_pipeline_name, ); const memory_module = try memory_product.MemoryJob.init(allocator, module); module_owned = false; return .{ .module = memory_module, .elapsed_ns = nsBetween(memory_start, memory_end), .stats = run_mod.backendPreparationStats(pm.stats), .plan_fingerprint = plan_fingerprint, };}Source: lib/accy/src/preparation/execution.zig:257
pub fn prepareTargetJobFromKernelJob( allocator: std.mem.Allocator, module: *kernel_product.KernelJob, options: BackendPreparationRunOptions,) !*target_product.TargetJob { const result = try prepareTargetJobFromKernelJobWithRun( allocator, module, options, ); return result.module;}Source: lib/accy/src/preparation/execution.zig:479
pub fn prepareTargetJobFromKernelJobWithRun( allocator: std.mem.Allocator, module: *kernel_product.KernelJob, options: BackendPreparationRunOptions,) !TargetPreparationResult { var module_owned = true; errdefer if (module_owned) module.deinit(); var target_result = try prepareTargetProductFromKernelJobWithRun(allocator, module, options); var target_result_owned = true; errdefer if (target_result_owned) target_result.deinit(); const target_module = try target_product.TargetJob.init( allocator, module, target_result.choir_module, target_result.analysis_cache, target_result.kernelization_product, ); target_result_owned = false; module_owned = false; return .{ .module = target_module, .elapsed_ns = target_result.elapsed_ns, .stats = target_result.stats, .finished_at = target_result.finished_at, };}Source: lib/accy/src/preparation/execution.zig:205
pub fn prepareTensorJobFromContractJob( allocator: std.mem.Allocator, module: *contract.ContractJob, options: BackendPreparationRunOptions,) !*tensor.TensorJob { const result = try prepareTensorJobFromContractJobWithRun( allocator, module, options, ); return result.module;}Source: lib/accy/src/preparation/execution.zig:315
pub fn prepareTensorJobFromContractJobWithRun( allocator: std.mem.Allocator, module: *contract.ContractJob, options: BackendPreparationRunOptions,) !TensorPreparationResult { var module_owned = true; errdefer if (module_owned) module.deinit(); try module.verify(); var analysis_cache = passes.AnalysisCache.init(allocator, null); var cache_owned = true; errdefer if (cache_owned) analysis_cache.deinit(); var pm = passes.PassManager.init(allocator); defer pm.deinit(); if (options.timing) |timing| try run_mod.addTimingInstrumentation(&pm, timing); try recipe.configure(&pm, .tensor, &options); const tensor_start = options.now(); if (pm.runWithAnalysisCache( module.choir_module, module.context(), &analysis_cache, recipe.runOptions(), ) == .failure) { return preparationPassFailed(allocator, options, stage_mod.tensor_pipeline_name, &pm); } const tensor_end = options.now(); const tensor_module = try tensor.TensorJob.init(allocator, module, analysis_cache); module_owned = false; cache_owned = false; return .{ .module = tensor_module, .elapsed_ns = nsBetween(tensor_start, tensor_end), .stats = run_mod.backendPreparationStats(pm.stats), };}Source: lib/accy/src/preparation/execution.zig:162
pub fn runTargetPipeline( allocator: std.mem.Allocator, choir_module: *ir.Operation, ctx: *ir.Context,) !void { return try runTargetPipelineWithOptions(allocator, choir_module, ctx, .{});}Source: lib/accy/src/preparation/execution.zig:179
pub fn runTargetPipelineWithDiagnostics( allocator: std.mem.Allocator, choir_module: *ir.Operation, ctx: *ir.Context, options: passes.PassManagerRunOptions, failure: ?*run_mod.BackendPreparationFailure,) !void { var pm = passes.PassManager.init(allocator); defer pm.deinit(); try recipe.configure(&pm, .target, &.{}); if (pm.runWithOptions(choir_module, ctx, options) == .failure) return passFailed(allocator, failure, stage_mod.target_pipeline_name, &pm);}Source: lib/accy/src/preparation/execution.zig:170
pub fn runTargetPipelineWithOptions( allocator: std.mem.Allocator, choir_module: *ir.Operation, ctx: *ir.Context, options: passes.PassManagerRunOptions,) !void { return try runTargetPipelineWithDiagnostics(allocator, choir_module, ctx, options, null);}Source: lib/accy/src/preparation/loss.zig:27
pub const loss_lowering_pass_name = "accy-choir-loss-lower";Source: lib/accy/src/preparation/prepared.zig:142
pub fn prepareBackendJobFromContractJob( allocator: std.mem.Allocator, module: *contract.ContractJob, options: BackendPreparationRunOptions,) !BackendPreparedJob { const initial_choir_ops = countOperationTree(module.choir_module); const total_start = options.now(); const tensor_result = try prepareTensorJobFromContractJobWithRun( allocator, module, options, ); return try prepareBackendJobFromTensorPreparationResult( allocator, tensor_result, options, 0, .{}, initial_choir_ops, null, total_start, );}Source: lib/accy/src/preparation/prepared.zig:176
pub fn prepareBackendJobFromContractPreparationResult( allocator: std.mem.Allocator, result: ContractPreparationResult, options: BackendPreparationRunOptions, total_start: i128,) !BackendPreparedJob { var contract_result = result; var contract_owned = true; errdefer if (contract_owned) contract_result.deinit(); const contract_ns = result.elapsed_ns; const contract_stats = result.stats; const initial_choir_ops = result.initial_choir_ops; const semantic_fingerprint = result.semantic_fingerprint; contract_owned = false; const tensor_result = try prepareTensorJobFromContractJobWithRun( allocator, contract_result.module, options, ); return try prepareBackendJobFromTensorPreparationResult( allocator, tensor_result, options, contract_ns, contract_stats, initial_choir_ops, semantic_fingerprint, total_start, );}Source: lib/accy/src/preparation/prepared.zig:244
pub fn prepareBackendJobFromDispatchPreparationResult( allocator: std.mem.Allocator, result: DispatchPreparationResult, options: BackendPreparationRunOptions, contract_ns: u64, contract_stats: BackendPreparationStats, tensor_ns: u64, tensor_stats: BackendPreparationStats, initial_choir_ops: u64, semantic_fingerprint: ?u64, total_start: i128,) !BackendPreparedJob { var dispatch_result = result; var dispatch_owned = true; errdefer if (dispatch_owned) dispatch_result.deinit(); const dispatch_ns = result.elapsed_ns; const dispatch_stats = result.stats; const dispatch_fingerprint = result.plan_fingerprint; dispatch_owned = false; const memory_result = try prepareMemoryJobFromDispatchJobWithRun( allocator, dispatch_result.module, options, ); return try prepareBackendJobFromMemoryPreparationResult( allocator, memory_result, options, contract_ns, contract_stats, tensor_ns, tensor_stats, dispatch_ns, dispatch_stats, dispatch_fingerprint, initial_choir_ops, semantic_fingerprint, total_start, );}Source: lib/accy/src/preparation/prepared.zig:334
pub fn prepareBackendJobFromKernelPreparationResult( allocator: std.mem.Allocator, result: KernelPreparationResult, options: BackendPreparationRunOptions, contract_ns: u64, contract_stats: BackendPreparationStats, tensor_ns: u64, tensor_stats: BackendPreparationStats, dispatch_ns: u64, dispatch_stats: BackendPreparationStats, dispatch_fingerprint: u64, memory_ns: u64, memory_stats: BackendPreparationStats, memory_fingerprint: u64, initial_choir_ops: u64, semantic_fingerprint: ?u64, total_start: i128,) !BackendPreparedJob { var kernel_result = result; var kernel_owned = true; errdefer if (kernel_owned) kernel_result.deinit(); const kernel_ns = result.elapsed_ns; const kernel_stats = result.stats; const kernel_fingerprint = result.plan_fingerprint; kernel_owned = false; const target_result = try prepareTargetJobFromKernelJobWithRun( allocator, kernel_result.module, options, ); return try prepareBackendJobFromTargetPreparationResult( allocator, target_result, options, contract_ns, contract_stats, tensor_ns, tensor_stats, dispatch_ns, dispatch_stats, dispatch_fingerprint, memory_ns, memory_stats, memory_fingerprint, kernel_ns, kernel_stats, kernel_fingerprint, initial_choir_ops, semantic_fingerprint, total_start, );}Source: lib/accy/src/preparation/prepared.zig:286
pub fn prepareBackendJobFromMemoryPreparationResult( allocator: std.mem.Allocator, result: MemoryPreparationResult, options: BackendPreparationRunOptions, contract_ns: u64, contract_stats: BackendPreparationStats, tensor_ns: u64, tensor_stats: BackendPreparationStats, dispatch_ns: u64, dispatch_stats: BackendPreparationStats, dispatch_fingerprint: u64, initial_choir_ops: u64, semantic_fingerprint: ?u64, total_start: i128,) !BackendPreparedJob { var memory_result = result; var memory_owned = true; errdefer if (memory_owned) memory_result.deinit(); const memory_ns = result.elapsed_ns; const memory_stats = result.stats; const memory_fingerprint = result.plan_fingerprint; memory_owned = false; const kernel_result = try prepareKernelJobFromMemoryJobWithRun( allocator, memory_result.module, options, ); return try prepareBackendJobFromKernelPreparationResult( allocator, kernel_result, options, contract_ns, contract_stats, tensor_ns, tensor_stats, dispatch_ns, dispatch_stats, dispatch_fingerprint, memory_ns, memory_stats, memory_fingerprint, initial_choir_ops, semantic_fingerprint, total_start, );}Source: lib/accy/src/preparation/prepared.zig:129
pub fn prepareBackendJobFromSemanticModule( allocator: std.mem.Allocator, module: *semantic.SemanticModule, options: BackendPreparationRunOptions,) !BackendPreparedJob { return try prepareOwnedSemanticModuleForBackend( allocator, module, options, options.now(), );}Source: lib/accy/src/preparation/prepared.zig:388
pub fn prepareBackendJobFromTargetPreparationResult( allocator: std.mem.Allocator, result: TargetPreparationResult, options: BackendPreparationRunOptions, contract_ns: u64, contract_stats: BackendPreparationStats, tensor_ns: u64, tensor_stats: BackendPreparationStats, dispatch_ns: u64, dispatch_stats: BackendPreparationStats, dispatch_fingerprint: u64, memory_ns: u64, memory_stats: BackendPreparationStats, memory_fingerprint: u64, kernel_ns: u64, kernel_stats: BackendPreparationStats, kernel_fingerprint: u64, initial_choir_ops: u64, semantic_fingerprint: ?u64, total_start: i128,) !BackendPreparedJob { var target_result = result; var target_owned = true; errdefer if (target_owned) target_result.deinit(); target_owned = false; return try prepareOwnedTargetJob( allocator, target_result.module, options, contract_ns, contract_stats, tensor_ns, tensor_stats, dispatch_ns, dispatch_stats, dispatch_fingerprint, memory_ns, memory_stats, memory_fingerprint, kernel_ns, kernel_stats, kernel_fingerprint, result.elapsed_ns, result.stats, initial_choir_ops, semantic_fingerprint, total_start, result.finished_at, );}Source: lib/accy/src/preparation/prepared.zig:208
pub fn prepareBackendJobFromTensorPreparationResult( allocator: std.mem.Allocator, result: TensorPreparationResult, options: BackendPreparationRunOptions, contract_ns: u64, contract_stats: BackendPreparationStats, initial_choir_ops: u64, semantic_fingerprint: ?u64, total_start: i128,) !BackendPreparedJob { var tensor_result = result; var tensor_owned = true; errdefer if (tensor_owned) tensor_result.deinit(); const tensor_ns = result.elapsed_ns; const tensor_stats = result.stats; tensor_owned = false; const dispatch_result = try prepareDispatchJobFromTensorJobWithRun( allocator, tensor_result.module, options, ); return try prepareBackendJobFromDispatchPreparationResult( allocator, dispatch_result, options, contract_ns, contract_stats, tensor_ns, tensor_stats, initial_choir_ops, semantic_fingerprint, total_start, );}Source: lib/accy/src/preparation/prepared.zig:119
pub fn runBackendPreparationPipelineFromSemanticModule( allocator: std.mem.Allocator, module: *semantic.SemanticModule, options: BackendPreparationRunOptions,) !BackendPreparationRun { var prepared = try prepareBackendJobFromSemanticModule(allocator, module, options); defer prepared.deinit(); return prepared.run;}Source: lib/accy/src/preparation/schedule/pass.zig:17
pub const schedule_planning_pass_name = "accy-choir-plan-schedule";Source: lib/accy/src/preparation/shape/pass.zig:13
pub const shape_layout_pass_name = "accy-choir-shape-layout-propagate";Source: lib/accy/src/preparation/stage.zig:427
pub const accy_choir_package_extension = choir.extensions.PackageExtension{ .name = "accy-choir", .passes = &accy_choir_pass_registrations, .pipelines = &.{ contract_pipeline_registration, tensor_pipeline_registration, dispatch_pipeline_registration, memory_pipeline_registration, kernel_pipeline_registration, target_pipeline_registration },};Source: lib/accy/src/preparation/stage.zig:411
pub const accy_choir_pass_registrations = allPassRegistrations();Source: lib/accy/src/preparation/stage.zig:86
pub fn activationLoweringPass() passes.Pass { return activation_lowering.activationLoweringPass();}Source: lib/accy/src/preparation/stage.zig:90
pub fn activationLoweringPassWithOptions(options: *const activation_lowering.Options) passes.Pass { return activation_lowering.activationLoweringPassWithOptions(options);}Source: lib/accy/src/preparation/stage.zig:509
pub fn addContractPipeline(pm: *passes.PassManager) !void { try contract_pipeline_registration.addTo(&pm.root);}Source: lib/accy/src/preparation/stage.zig:524
pub fn addDispatchPipeline(pm: *passes.PassManager) !void { try dispatch_pipeline_registration.addTo(&pm.root);}Source: lib/accy/src/preparation/stage.zig:532
pub fn addKernelPipeline(pm: *passes.PassManager) !void { try kernel_pipeline_registration.addTo(&pm.root);}Source: lib/accy/src/preparation/stage.zig:528
pub fn addMemoryPipeline(pm: *passes.PassManager) !void { try memory_pipeline_registration.addTo(&pm.root);}Source: lib/accy/src/preparation/stage.zig:536
pub fn addTargetPipeline(pm: *passes.PassManager) !void { try target_pipeline_registration.addTo(&pm.root);}Source: lib/accy/src/preparation/stage.zig:513
pub fn addTensorPipeline(pm: *passes.PassManager) !void { try tensor_pipeline_registration.addTo(&pm.root);}Source: lib/accy/src/preparation/stage.zig:517
pub fn addTensorPipelineWithOptions(pm: *passes.PassManager, options: *const TensorLoweringOptions) !void { try pm.addPass(activationLoweringPassWithOptions(&options.activation)); try pm.addPass(einsumLoweringPassWithOptions(&options.einsum)); try pm.addPass(indexingLoweringPassWithOptions(&options.indexing)); try pm.addPass(lossLoweringPassWithOptions(&options.loss));}Source: lib/accy/src/preparation/stage.zig:58
pub fn backendLegalizationPass() passes.Pass { return backend_legalization.backendLegalizationPass();}Source: lib/accy/src/preparation/stage.zig:62
pub fn bufferizationPlanningPass() passes.Pass { return bufferization.bufferizationPlanningPass();}Source: lib/accy/src/preparation/stage.zig:66
pub fn canonicalizationPass() passes.Pass { return canonicalization.canonicalizationPass();}Source: lib/accy/src/preparation/stage.zig:74
pub fn constantFoldingPass() passes.Pass { return constant_folding.constantFoldingPass();}Source: lib/accy/src/preparation/stage.zig:457
pub fn contractAnalysisName(index: usize) []const u8 { return contract_analysis_names[index];}Source: lib/accy/src/preparation/stage.zig:453
pub fn contractPassName(index: usize) []const u8 { return contract_stages[index].name;}Source: lib/accy/src/preparation/stage.zig:420
pub const contract_pass_plan = passes.PassPlan{ .steps = &contract_plan_steps };Source: lib/accy/src/preparation/stage.zig:405
pub const contract_pass_registrations = stagePassRegistrations(contract_stages);Source: lib/accy/src/preparation/stage.zig:162
pub const contract_pipeline_description = "Normalize semantic Accy Choir into the backend contract product";Source: lib/accy/src/preparation/stage.zig:161
pub const contract_pipeline_name = "accy-choir-contract";Source: lib/accy/src/preparation/stage.zig:369
pub const contract_pipeline_registration = passes.PipelineRegistration{ .name = contract_pipeline_name, .description = contract_pipeline_description, .build = buildContractPipeline,};Source: lib/accy/src/preparation/stage.zig:180
pub const contract_stages = [_]BackendPreparationStage{ .{ .name = canonicalization_pass_name, .description = canonicalization.canonicalization_pass_description, .pass = canonicalizationPass(), }, .{ .name = saturation_pass_name, .description = saturation.saturation_pass_description, .pass = tensorSaturationPass(), }, .{ .name = shape_layout_pass_name, .description = shape_analysis.shape_layout_pass_description, .pass = shapeLayoutPropagationPass(), .analysis_name = shape_analysis.shape_layout_analysis_descriptor.name, }, .{ .name = constant_folding_pass_name, .description = constant_folding.constant_folding_pass_description, .pass = constantFoldingPass(), },};Source: lib/accy/src/preparation/stage.zig:481
pub fn dispatchAnalysisName(index: usize) []const u8 { return dispatch_analysis_names[index];}Source: lib/accy/src/preparation/stage.zig:477
pub fn dispatchPassName(index: usize) []const u8 { return dispatch_stages[index].name;}Source: lib/accy/src/preparation/stage.zig:422
pub const dispatch_pass_plan = passes.PassPlan{ .steps = &dispatch_plan_steps };Source: lib/accy/src/preparation/stage.zig:407
pub const dispatch_pass_registrations = stagePassRegistrations(dispatch_stages);Source: lib/accy/src/preparation/stage.zig:168
pub const dispatch_pipeline_description = "Plan Accy Choir dispatch groups and schedules before memory preparation";Source: lib/accy/src/preparation/stage.zig:167
pub const dispatch_pipeline_name = "accy-choir-dispatch";Source: lib/accy/src/preparation/stage.zig:381
pub const dispatch_pipeline_registration = passes.PipelineRegistration{ .name = dispatch_pipeline_name, .description = dispatch_pipeline_description, .build = buildDispatchPipeline,};Source: lib/accy/src/preparation/stage.zig:235
pub const dispatch_stages = [_]BackendPreparationStage{ .{ .name = fusion_planning_pass_name, .description = fusion.fusion_planning_pass_description, .pass = fusionPlanningPass(), .analysis_name = fusion.fusion_plan_analysis_descriptor.name, }, .{ .name = schedule_planning_pass_name, .description = schedule_planning.schedule_planning_pass_description, .pass = schedulePlanningPass(), .analysis_name = schedule_planning.schedule_plan_analysis_descriptor.name, },};Source: lib/accy/src/preparation/stage.zig:82
pub fn dtypeLegalizationPass() passes.Pass { return dtype_legalization.dtypeLegalizationPass();}Source: lib/accy/src/preparation/stage.zig:94
pub fn einsumLoweringPass() passes.Pass { return einsum_lowering.einsumLoweringPass();}Source: lib/accy/src/preparation/stage.zig:98
pub fn einsumLoweringPassWithOptions(options: *const einsum_lowering.Options) passes.Pass { return einsum_lowering.einsumLoweringPassWithOptions(options);}Source: lib/accy/src/preparation/stage.zig:118
pub fn fusionPlanningPass() passes.Pass { return fusion.fusionPlanningPass();}Source: lib/accy/src/preparation/stage.zig:102
pub fn indexingLoweringPass() passes.Pass { return indexing_lowering.indexingLoweringPass();}Source: lib/accy/src/preparation/stage.zig:106
pub fn indexingLoweringPassWithOptions(options: *const indexing_lowering.Options) passes.Pass { return indexing_lowering.indexingLoweringPassWithOptions(options);}Source: lib/accy/src/preparation/stage.zig:497
pub fn kernelAnalysisName(index: usize) []const u8 { return kernel_analysis_names[index];}Source: lib/accy/src/preparation/stage.zig:126
pub fn kernelOutliningPlanningPass() passes.Pass { return kernel_outlining.kernelOutliningPlanningPass();}Source: lib/accy/src/preparation/stage.zig:493
pub fn kernelPassName(index: usize) []const u8 { return kernel_stages[index].name;}Source: lib/accy/src/preparation/stage.zig:424
pub const kernel_pass_plan = passes.PassPlan{ .steps = &kernel_plan_steps };Source: lib/accy/src/preparation/stage.zig:409
pub const kernel_pass_registrations = stagePassRegistrations(kernel_stages);Source: lib/accy/src/preparation/stage.zig:174
pub const kernel_pipeline_description = "Outline and lower Accy Choir dispatches into kernel programs before backend legalization";Source: lib/accy/src/preparation/stage.zig:173
pub const kernel_pipeline_name = "accy-choir-kernel";Source: lib/accy/src/preparation/stage.zig:393
pub const kernel_pipeline_registration = passes.PipelineRegistration{ .name = kernel_pipeline_name, .description = kernel_pipeline_description, .build = buildKernelPipeline,};Source: lib/accy/src/preparation/stage.zig:271
pub const kernel_stages = [_]BackendPreparationStage{ .{ .name = kernel_outlining_planning_pass_name, .description = kernel_outlining.kernel_outlining_planning_pass_description, .pass = kernelOutliningPlanningPass(), .analysis_name = kernel_outlining.kernel_outline_plan_analysis_descriptor.name, }, .{ .name = kernelization_pass_name, .description = kernelization.kernelization_pass_description, .pass = kernelizationPass(), .analysis_name = kernelization.kernelization_analysis_descriptor.name, },};Source: lib/accy/src/preparation/stage.zig:130
pub fn kernelizationPass() passes.Pass { return kernelization.kernelizationPass();}Source: lib/accy/src/preparation/stage.zig:138
pub fn layoutPlanningPass() passes.Pass { return layout_planning.layoutPlanningPass();}Source: lib/accy/src/preparation/stage.zig:110
pub fn lossLoweringPass() passes.Pass { return loss_lowering.lossLoweringPass();}Source: lib/accy/src/preparation/stage.zig:114
pub fn lossLoweringPassWithOptions(options: *const loss_lowering.Options) passes.Pass { return loss_lowering.lossLoweringPassWithOptions(options);}Source: lib/accy/src/preparation/stage.zig:489
pub fn memoryAnalysisName(index: usize) []const u8 { return memory_analysis_names[index];}Source: lib/accy/src/preparation/stage.zig:485
pub fn memoryPassName(index: usize) []const u8 { return memory_stages[index].name;}Source: lib/accy/src/preparation/stage.zig:134
pub fn memorySpacePlanningPass() passes.Pass { return memory_space.memorySpacePlanningPass();}Source: lib/accy/src/preparation/stage.zig:423
pub const memory_pass_plan = passes.PassPlan{ .steps = &memory_plan_steps };Source: lib/accy/src/preparation/stage.zig:408
pub const memory_pass_registrations = stagePassRegistrations(memory_stages);Source: lib/accy/src/preparation/stage.zig:171
pub const memory_pipeline_description = "Plan Accy Choir buffers, memory spaces, and layouts before kernel preparation";Source: lib/accy/src/preparation/stage.zig:170
pub const memory_pipeline_name = "accy-choir-memory";Source: lib/accy/src/preparation/stage.zig:387
pub const memory_pipeline_registration = passes.PipelineRegistration{ .name = memory_pipeline_name, .description = memory_pipeline_description, .build = buildMemoryPipeline,};Source: lib/accy/src/preparation/stage.zig:250
pub const memory_stages = [_]BackendPreparationStage{ .{ .name = bufferization_planning_pass_name, .description = bufferization.bufferization_planning_pass_description, .pass = bufferizationPlanningPass(), .analysis_name = bufferization.buffer_plan_analysis_descriptor.name, }, .{ .name = memory_space_planning_pass_name, .description = memory_space.memory_space_planning_pass_description, .pass = memorySpacePlanningPass(), .analysis_name = memory_space.memory_space_plan_analysis_descriptor.name, }, .{ .name = layout_planning_pass_name, .description = layout_planning.layout_planning_pass_description, .pass = layoutPlanningPass(), .analysis_name = layout_planning.layout_plan_analysis_descriptor.name, },};Source: lib/accy/src/preparation/stage.zig:122
pub fn schedulePlanningPass() passes.Pass { return schedule_planning.schedulePlanningPass();}Source: lib/accy/src/preparation/stage.zig:70
pub fn shapeLayoutPropagationPass() passes.Pass { return shape_analysis.shapeLayoutPropagationPass();}Source: lib/accy/src/preparation/stage.zig:505
pub fn targetAnalysisName(index: usize) []const u8 { return target_analysis_names[index];}Source: lib/accy/src/preparation/stage.zig:501
pub fn targetPassName(index: usize) []const u8 { return target_stages[index].name;}Source: lib/accy/src/preparation/stage.zig:425
pub const target_pass_plan = passes.PassPlan{ .steps = &target_plan_steps };Source: lib/accy/src/preparation/stage.zig:410
pub const target_pass_registrations = stagePassRegistrations(target_stages);Source: lib/accy/src/preparation/stage.zig:177
pub const target_pipeline_description = "Legalize Accy Choir kernels for the selected backend target";Source: lib/accy/src/preparation/stage.zig:176
pub const target_pipeline_name = "accy-choir-target";Source: lib/accy/src/preparation/stage.zig:399
pub const target_pipeline_registration = passes.PipelineRegistration{ .name = target_pipeline_name, .description = target_pipeline_description, .build = buildTargetPipeline,};Source: lib/accy/src/preparation/stage.zig:286
pub const target_stages = [_]BackendPreparationStage{ .{ .name = backend_legalization_pass_name, .description = backend_legalization.backend_legalization_pass_description, .pass = backendLegalizationPass(), .analysis_name = backend_legalization.backend_legalization_analysis_descriptor.name, }, .{ .name = dtype_legalization_pass_name, .description = dtype_legalization.dtype_legalization_pass_description, .pass = dtypeLegalizationPass(), },};Source: lib/accy/src/preparation/stage.zig:469
pub fn tensorAnalysisName(index: usize) []const u8 { if (comptime tensor_analysis_names.len == 0) { unreachable; } else { return tensor_analysis_names[index]; }}Source: lib/accy/src/preparation/stage.zig:461
pub fn tensorPassName(index: usize) []const u8 { if (comptime tensor_stages.len == 0) { unreachable; } else { return tensor_stages[index].name; }}Source: lib/accy/src/preparation/stage.zig:78
pub fn tensorSaturationPass() passes.Pass { return saturation.tensorSaturationPass();}Source: lib/accy/src/preparation/stage.zig:421
pub const tensor_pass_plan = passes.PassPlan{ .steps = &tensor_plan_steps };Source: lib/accy/src/preparation/stage.zig:406
pub const tensor_pass_registrations = stagePassRegistrations(tensor_stages);Source: lib/accy/src/preparation/stage.zig:165
pub const tensor_pipeline_description = "Materialize tensor-level Accy Choir before dispatch grouping";Source: lib/accy/src/preparation/stage.zig:164
pub const tensor_pipeline_name = "accy-choir-tensor";Source: lib/accy/src/preparation/stage.zig:375
pub const tensor_pipeline_registration = passes.PipelineRegistration{ .name = tensor_pipeline_name, .description = tensor_pipeline_description, .build = buildTensorPipeline,};Source: lib/accy/src/preparation/stage.zig:204
pub const tensor_stages = [_]BackendPreparationStage{ .{ .name = activation_lowering_pass_name, .description = activation_lowering.activation_lowering_pass_description, .pass = activationLoweringPass(), .options = &activation_lowering.activation_lowering_pass_options, .build_with_options = activation_lowering.activationLoweringPassFromOptions, }, .{ .name = einsum_lowering_pass_name, .description = einsum_lowering.einsum_lowering_pass_description, .pass = einsumLoweringPass(), .options = &einsum_lowering.einsum_lowering_pass_options, .build_with_options = einsum_lowering.einsumLoweringPassFromOptions, }, .{ .name = indexing_lowering_pass_name, .description = indexing_lowering.indexing_lowering_pass_description, .pass = indexingLoweringPass(), .options = &indexing_lowering.indexing_lowering_pass_options, .build_with_options = indexing_lowering.indexingLoweringPassFromOptions, }, .{ .name = loss_lowering_pass_name, .description = loss_lowering.loss_lowering_pass_description, .pass = lossLoweringPass(), .options = &loss_lowering.loss_lowering_pass_options, .build_with_options = loss_lowering.lossLoweringPassFromOptions, },};Source: lib/accy/src/preparation/pipeline.zig
const std = @import("std");const gpu = @import("gpu");const choir = @import("choir");const backend_legalization = @import("backend.zig");const canonicalization = @import("canonicalization.zig");const saturation = @import("saturation.zig");const accy_choir = @import("../choir/root.zig");const target_product = @import("../target/root.zig");const dialect_mod = accy_choir.dialect;const execution_mod = @import("execution.zig");const library_preparation = @import("library.zig");const kernelization = @import("kernelization/root.zig");const kernel_outlining = @import("outlining/root.zig");const contract = accy_choir.contract;const dispatch = accy_choir.dispatch;const kernel_product = accy_choir.gpu;const memory_product = accy_choir.memory;const semantic = accy_choir.semantic;const tensor = accy_choir.tensor;const schedule_planning = @import("schedule/root.zig");const prepared_mod = @import("prepared.zig");const product_mod = @import("product.zig");const run_mod = @import("run.zig");const stage_mod = @import("stage.zig");const target_profile = @import("target.zig");const accy_root = @import("../root.zig");const ir = choir.ir;const passes = choir.passes;pub const BackendTargetProfile = target_profile.BackendTargetProfile;pub const canonicalizeModule = canonicalization.canonicalizeModule;pub const saturateTensorOperations = saturation.saturateTensorOperations;pub const setBackendTargetProfile = target_profile.setBackendTargetProfile;pub const readBackendTargetProfile = target_profile.readBackendTargetProfile;pub const KernelLibraryLowering = library_preparation.KernelLibraryLowering;pub const ActivationLoweringOptions = stage_mod.ActivationLoweringOptions;pub const EinsumLoweringOptions = stage_mod.EinsumLoweringOptions;pub const IndexingLoweringOptions = stage_mod.IndexingLoweringOptions;pub const TensorLoweringOptions = stage_mod.TensorLoweringOptions;pub const backend_legalization_pass_name = stage_mod.backend_legalization_pass_name;pub const bufferization_planning_pass_name = stage_mod.bufferization_planning_pass_name;pub const canonicalization_pass_name = stage_mod.canonicalization_pass_name;pub const constant_folding_pass_name = stage_mod.constant_folding_pass_name;pub const saturation_pass_name = stage_mod.saturation_pass_name;pub const dtype_legalization_pass_name = stage_mod.dtype_legalization_pass_name;pub const activation_lowering_pass_name = stage_mod.activation_lowering_pass_name;pub const einsum_lowering_pass_name = stage_mod.einsum_lowering_pass_name;pub const indexing_lowering_pass_name = stage_mod.indexing_lowering_pass_name;pub const loss_lowering_pass_name = stage_mod.loss_lowering_pass_name;pub const fusion_planning_pass_name = stage_mod.fusion_planning_pass_name;pub const kernelization_pass_name = stage_mod.kernelization_pass_name;pub const kernel_outlining_planning_pass_name = stage_mod.kernel_outlining_planning_pass_name;pub const layout_planning_pass_name = stage_mod.layout_planning_pass_name;pub const memory_space_planning_pass_name = stage_mod.memory_space_planning_pass_name;pub const schedule_planning_pass_name = stage_mod.schedule_planning_pass_name;pub const shape_layout_pass_name = stage_mod.shape_layout_pass_name;pub const PipelineError = execution_mod.PipelineError;pub const BackendPreparationStats = run_mod.BackendPreparationStats;pub const BackendPreparationFailureKind = run_mod.BackendPreparationFailureKind;pub const BackendPreparationFailure = run_mod.BackendPreparationFailure;pub const BackendPreparationTiming = run_mod.BackendPreparationTiming;pub const BackendPreparationRunOptions = run_mod.BackendPreparationRunOptions;pub const BackendPreparationRun = run_mod.BackendPreparationRun;pub const BackendPreparationProductStamps = product_mod.BackendPreparationProductStamps;pub const BackendPreparationProductKeys = product_mod.BackendPreparationProductKeys;pub const BackendPreparedModule = product_mod.BackendPreparedModule;pub const ContractPreparationResult = execution_mod.ContractPreparationResult;pub const TensorPreparationResult = execution_mod.TensorPreparationResult;pub const DispatchPreparationResult = execution_mod.DispatchPreparationResult;pub const MemoryPreparationResult = execution_mod.MemoryPreparationResult;pub const KernelPreparationResult = execution_mod.KernelPreparationResult;pub const TargetPreparationResult = execution_mod.TargetPreparationResult;pub const BackendPreparedJob = prepared_mod.BackendPreparedJob;pub const backendLegalizationPass = stage_mod.backendLegalizationPass;pub const bufferizationPlanningPass = stage_mod.bufferizationPlanningPass;pub const canonicalizationPass = stage_mod.canonicalizationPass;pub const shapeLayoutPropagationPass = stage_mod.shapeLayoutPropagationPass;pub const constantFoldingPass = stage_mod.constantFoldingPass;pub const tensorSaturationPass = stage_mod.tensorSaturationPass;pub const dtypeLegalizationPass = stage_mod.dtypeLegalizationPass;pub const activationLoweringPass = stage_mod.activationLoweringPass;pub const activationLoweringPassWithOptions = stage_mod.activationLoweringPassWithOptions;pub const einsumLoweringPass = stage_mod.einsumLoweringPass;pub const einsumLoweringPassWithOptions = stage_mod.einsumLoweringPassWithOptions;pub const indexingLoweringPass = stage_mod.indexingLoweringPass;pub const indexingLoweringPassWithOptions = stage_mod.indexingLoweringPassWithOptions;pub const lossLoweringPass = stage_mod.lossLoweringPass;pub const lossLoweringPassWithOptions = stage_mod.lossLoweringPassWithOptions;pub const fusionPlanningPass = stage_mod.fusionPlanningPass;pub const schedulePlanningPass = stage_mod.schedulePlanningPass;pub const kernelOutliningPlanningPass = stage_mod.kernelOutliningPlanningPass;pub const kernelizationPass = stage_mod.kernelizationPass;pub const memorySpacePlanningPass = stage_mod.memorySpacePlanningPass;pub const layoutPlanningPass = stage_mod.layoutPlanningPass;pub const BackendPreparationStage = stage_mod.BackendPreparationStage;pub const contract_pipeline_name = stage_mod.contract_pipeline_name;pub const contract_pipeline_description = stage_mod.contract_pipeline_description;pub const tensor_pipeline_name = stage_mod.tensor_pipeline_name;pub const tensor_pipeline_description = stage_mod.tensor_pipeline_description;pub const dispatch_pipeline_name = stage_mod.dispatch_pipeline_name;pub const dispatch_pipeline_description = stage_mod.dispatch_pipeline_description;pub const memory_pipeline_name = stage_mod.memory_pipeline_name;pub const memory_pipeline_description = stage_mod.memory_pipeline_description;pub const kernel_pipeline_name = stage_mod.kernel_pipeline_name;pub const kernel_pipeline_description = stage_mod.kernel_pipeline_description;pub const target_pipeline_name = stage_mod.target_pipeline_name;pub const target_pipeline_description = stage_mod.target_pipeline_description;pub const contract_stages = stage_mod.contract_stages;pub const tensor_stages = stage_mod.tensor_stages;pub const dispatch_stages = stage_mod.dispatch_stages;pub const memory_stages = stage_mod.memory_stages;pub const kernel_stages = stage_mod.kernel_stages;pub const target_stages = stage_mod.target_stages;pub const contract_pipeline_registration = stage_mod.contract_pipeline_registration;pub const tensor_pipeline_registration = stage_mod.tensor_pipeline_registration;pub const dispatch_pipeline_registration = stage_mod.dispatch_pipeline_registration;pub const memory_pipeline_registration = stage_mod.memory_pipeline_registration;pub const kernel_pipeline_registration = stage_mod.kernel_pipeline_registration;pub const target_pipeline_registration = stage_mod.target_pipeline_registration;pub const contract_pass_registrations = stage_mod.contract_pass_registrations;pub const tensor_pass_registrations = stage_mod.tensor_pass_registrations;pub const dispatch_pass_registrations = stage_mod.dispatch_pass_registrations;pub const memory_pass_registrations = stage_mod.memory_pass_registrations;pub const kernel_pass_registrations = stage_mod.kernel_pass_registrations;pub const target_pass_registrations = stage_mod.target_pass_registrations;pub const accy_choir_pass_registrations = stage_mod.accy_choir_pass_registrations;pub const accy_choir_package_extension = stage_mod.accy_choir_package_extension;pub const contract_pass_plan = stage_mod.contract_pass_plan;pub const tensor_pass_plan = stage_mod.tensor_pass_plan;pub const dispatch_pass_plan = stage_mod.dispatch_pass_plan;pub const memory_pass_plan = stage_mod.memory_pass_plan;pub const kernel_pass_plan = stage_mod.kernel_pass_plan;pub const target_pass_plan = stage_mod.target_pass_plan;pub const contract_pass_count = stage_mod.contract_pass_count;pub const contract_analysis_count = stage_mod.contract_analysis_count;pub const tensor_pass_count = stage_mod.tensor_pass_count;pub const tensor_analysis_count = stage_mod.tensor_analysis_count;pub const dispatch_pass_count = stage_mod.dispatch_pass_count;pub const dispatch_analysis_count = stage_mod.dispatch_analysis_count;pub const memory_pass_count = stage_mod.memory_pass_count;pub const memory_analysis_count = stage_mod.memory_analysis_count;pub const kernel_pass_count = stage_mod.kernel_pass_count;pub const kernel_analysis_count = stage_mod.kernel_analysis_count;pub const target_pass_count = stage_mod.target_pass_count;pub const target_analysis_count = stage_mod.target_analysis_count;pub const contractPassName = stage_mod.contractPassName;pub const contractAnalysisName = stage_mod.contractAnalysisName;pub const tensorPassName = stage_mod.tensorPassName;pub const tensorAnalysisName = stage_mod.tensorAnalysisName;pub const dispatchPassName = stage_mod.dispatchPassName;pub const dispatchAnalysisName = stage_mod.dispatchAnalysisName;pub const memoryPassName = stage_mod.memoryPassName;pub const memoryAnalysisName = stage_mod.memoryAnalysisName;pub const kernelPassName = stage_mod.kernelPassName;pub const kernelAnalysisName = stage_mod.kernelAnalysisName;pub const targetPassName = stage_mod.targetPassName;pub const targetAnalysisName = stage_mod.targetAnalysisName;pub const addContractPipeline = stage_mod.addContractPipeline;pub const addTensorPipeline = stage_mod.addTensorPipeline;pub const addTensorPipelineWithOptions = stage_mod.addTensorPipelineWithOptions;pub const addDispatchPipeline = stage_mod.addDispatchPipeline;pub const addMemoryPipeline = stage_mod.addMemoryPipeline;pub const addKernelPipeline = stage_mod.addKernelPipeline;pub const addTargetPipeline = stage_mod.addTargetPipeline;pub const runTargetPipeline = execution_mod.runTargetPipeline;pub const runTargetPipelineWithOptions = execution_mod.runTargetPipelineWithOptions;pub const runTargetPipelineWithDiagnostics = execution_mod.runTargetPipelineWithDiagnostics;pub const runBackendPreparationPipelineFromSemanticModule = prepared_mod.runBackendPreparationPipelineFromSemanticModule;pub const prepareBackendJobFromSemanticModule = prepared_mod.prepareBackendJobFromSemanticModule;pub const prepareContractJobFromSemanticModule = execution_mod.prepareContractJobFromSemanticModule;pub const prepareTensorJobFromContractJob = execution_mod.prepareTensorJobFromContractJob;pub const prepareDispatchJobFromTensorJob = execution_mod.prepareDispatchJobFromTensorJob;pub const prepareMemoryJobFromDispatchJob = execution_mod.prepareMemoryJobFromDispatchJob;pub const prepareKernelJobFromMemoryJob = execution_mod.prepareKernelJobFromMemoryJob;pub const prepareTargetJobFromKernelJob = execution_mod.prepareTargetJobFromKernelJob;pub const prepareBackendJobFromContractJob = prepared_mod.prepareBackendJobFromContractJob;pub const prepareBackendJobFromContractPreparationResult = prepared_mod.prepareBackendJobFromContractPreparationResult;pub const prepareBackendJobFromTensorPreparationResult = prepared_mod.prepareBackendJobFromTensorPreparationResult;pub const prepareBackendJobFromDispatchPreparationResult = prepared_mod.prepareBackendJobFromDispatchPreparationResult;pub const prepareBackendJobFromMemoryPreparationResult = prepared_mod.prepareBackendJobFromMemoryPreparationResult;pub const prepareBackendJobFromKernelPreparationResult = prepared_mod.prepareBackendJobFromKernelPreparationResult;pub const prepareBackendJobFromTargetPreparationResult = prepared_mod.prepareBackendJobFromTargetPreparationResult;pub const prepareContractJobFromSemanticModuleWithRun = execution_mod.prepareContractJobFromSemanticModuleWithRun;pub const prepareTensorJobFromContractJobWithRun = execution_mod.prepareTensorJobFromContractJobWithRun;pub const prepareDispatchJobFromTensorJobWithRun = execution_mod.prepareDispatchJobFromTensorJobWithRun;pub const prepareMemoryJobFromDispatchJobWithRun = execution_mod.prepareMemoryJobFromDispatchJobWithRun;pub const prepareKernelJobFromMemoryJobWithRun = execution_mod.prepareKernelJobFromMemoryJobWithRun;pub const prepareTargetJobFromKernelJobWithRun = execution_mod.prepareTargetJobFromKernelJobWithRun;const testing = std.testing;pub fn buildBackendPreparationContext( allocator: std.mem.Allocator, context_limits: ir.Context.Limits,) !ir.Context { return try semantic.buildSemanticContext(allocator, context_limits);}const countOperationTree = execution_mod.countOperationTree;fn expectProductStamp(stamp: choir.product.incremental.ProductStamp, name: []const u8, fingerprint: u64) !void { try testing.expectEqualStrings(name, stamp.name); try testing.expectEqual(fingerprint, stamp.fingerprint);}fn readSymbolName(func: *ir.Operation) ?[]const u8 { return ir.SymbolTable.getSymbolName(func);}fn hasFunctionNameSuffix(module_body: *ir.Block, suffix: []const u8) bool { var iter = module_body.operations.head; while (iter) |op_ptr| { const op: *ir.Operation = @ptrCast(@alignCast(op_ptr)); if (std.mem.eql(u8, op.name.name, "func.func")) { if (readSymbolName(op)) |existing_name| { if (std.mem.endsWith(u8, existing_name, suffix)) return true; } } iter = op.next_op; } return false;}fn expectPreparedKernelPlan( allocator: std.mem.Allocator, choir_mod: *ir.Operation, ctx: *ir.Context, expected_kernel_count: usize,) !void { var cache = passes.AnalysisCache.init(allocator, null); defer cache.deinit(); var pass_ctx = passes.PassContext.init(choir_mod, ctx, allocator, &cache); defer pass_ctx.deinit(); const schedule_plan = try schedule_planning.getSchedulePlanAnalysis(&pass_ctx, choir_mod); const outline_plan = try kernel_outlining.getKernelOutlinePlanAnalysis(&pass_ctx, choir_mod); const kernel_plan = try kernelization.getKernelizationAnalysis(&pass_ctx, choir_mod); const legal_plan = try backend_legalization.getBackendLegalizationAnalysis(&pass_ctx, choir_mod); try testing.expectEqual(expected_kernel_count, schedule_plan.workItemCount()); try testing.expectEqual(expected_kernel_count, outline_plan.kernelCount()); try testing.expectEqual(expected_kernel_count, kernel_plan.kernelCount()); try testing.expectEqual(expected_kernel_count, legal_plan.kernelCount()); try testing.expect(legal_plan.isLegal());}fn expectTargetStagePipeline(pm: *const passes.PassManager) !void { try testing.expectEqual(target_pass_count, pm.root.pipeline.items.len); inline for (target_stages, 0..) |stage, index| { switch (pm.root.pipeline.items[index]) { .pass => |pass| try testing.expectEqualStrings(stage.name, pass.name), .nested => try testing.expect(false), } }}fn expectTensorStagePipeline(pm: *const passes.PassManager) !void { try testing.expectEqual(tensor_pass_count, pm.root.pipeline.items.len); inline for (tensor_stages, 0..) |stage, index| { switch (pm.root.pipeline.items[index]) { .pass => |pass| try testing.expectEqualStrings(stage.name, pass.name), .nested => try testing.expect(false), } }}fn expectDispatchStagePipeline(pm: *const passes.PassManager) !void { try testing.expectEqual(dispatch_pass_count, pm.root.pipeline.items.len); inline for (dispatch_stages, 0..) |stage, index| { switch (pm.root.pipeline.items[index]) { .pass => |pass| try testing.expectEqualStrings(stage.name, pass.name), .nested => try testing.expect(false), } }}fn expectMemoryStagePipeline(pm: *const passes.PassManager) !void { try testing.expectEqual(memory_pass_count, pm.root.pipeline.items.len); inline for (memory_stages, 0..) |stage, index| { switch (pm.root.pipeline.items[index]) { .pass => |pass| try testing.expectEqualStrings(stage.name, pass.name), .nested => try testing.expect(false), } }}fn expectKernelStagePipeline(pm: *const passes.PassManager) !void { try testing.expectEqual(kernel_pass_count, pm.root.pipeline.items.len); inline for (kernel_stages, 0..) |stage, index| { switch (pm.root.pipeline.items[index]) { .pass => |pass| try testing.expectEqualStrings(stage.name, pass.name), .nested => try testing.expect(false), } }}fn expectTargetStageText(text: []const u8) !void { var iter = std.mem.splitScalar(u8, text, ','); inline for (target_stages) |stage| { const name = iter.next() orelse return error.MissingTargetStage; try testing.expectEqualStrings(stage.name, name); } try testing.expect(iter.next() == null);}fn expectStagePlanText( allocator: std.mem.Allocator, comptime stages: anytype, pass_plan: passes.PassPlan,) !void { const text = try pass_plan.formatAlloc(allocator); defer allocator.free(text); var iter = std.mem.splitScalar(u8, text, ','); inline for (stages) |stage| { const name = iter.next() orelse return error.MissingStage; try testing.expectEqualStrings(stage.name, name); } try testing.expect(iter.next() == null);}fn buildSemanticAddModule( allocator: std.mem.Allocator, name: []const u8, dims: []const i64,) !*semantic.SemanticModule { var builder = try semantic.Builder.init(allocator, semantic.Builder.ContextLimits.standard); errdefer builder.deinit(); const ty = try builder.tensor(.f32, dims); var fb = try builder.beginFunction(name, &.{ ty, ty }, &.{ty}); const sum = try fb.add(fb.parameter(0), fb.parameter(1)); try fb.return_(&.{sum}); try fb.finish(); return try builder.finish();}fn buildSemanticAddMulModule( allocator: std.mem.Allocator, name: []const u8, dims: []const i64,) !*semantic.SemanticModule { var builder = try semantic.Builder.init(allocator, semantic.Builder.ContextLimits.standard); errdefer builder.deinit(); const ty = try builder.tensor(.f32, dims); var fb = try builder.beginFunction(name, &.{ ty, ty, ty }, &.{ ty, ty }); const sum = try fb.add(fb.parameter(0), fb.parameter(1)); const product = try fb.mul(sum, fb.parameter(2)); try fb.return_(&.{ sum, product }); try fb.finish(); return try builder.finish();}fn prepareDispatchResultForContinuationTest( allocator: std.mem.Allocator, name: []const u8,) !DispatchPreparationResult { const semantic_module = try buildSemanticAddMulModule(allocator, name, &.{4}); var contract_result = try prepareContractJobFromSemanticModuleWithRun(allocator, semantic_module, .{}); var contract_owned = true; errdefer if (contract_owned) contract_result.deinit(); contract_owned = false; var tensor_result = try prepareTensorJobFromContractJobWithRun(allocator, contract_result.module, .{}); var tensor_owned = true; errdefer if (tensor_owned) tensor_result.deinit(); tensor_owned = false; return try prepareDispatchJobFromTensorJobWithRun(allocator, tensor_result.module, .{});}fn prepareMemoryResultForContinuationTest( allocator: std.mem.Allocator, name: []const u8,) !MemoryPreparationResult { var dispatch_result = try prepareDispatchResultForContinuationTest(allocator, name); var dispatch_owned = true; errdefer if (dispatch_owned) dispatch_result.deinit(); dispatch_owned = false; return try prepareMemoryJobFromDispatchJobWithRun(allocator, dispatch_result.module, .{});}fn prepareKernelResultForContinuationTest( allocator: std.mem.Allocator, name: []const u8,) !KernelPreparationResult { var memory_result = try prepareMemoryResultForContinuationTest(allocator, name); var memory_owned = true; errdefer if (memory_owned) memory_result.deinit(); memory_owned = false; return try prepareKernelJobFromMemoryJobWithRun(allocator, memory_result.module, .{});}fn prepareTargetResultForContinuationTest( allocator: std.mem.Allocator, name: []const u8,) !TargetPreparationResult { var kernel_result = try prepareKernelResultForContinuationTest(allocator, name); var kernel_owned = true; errdefer if (kernel_owned) kernel_result.deinit(); kernel_owned = false; return try prepareTargetJobFromKernelJobWithRun(allocator, kernel_result.module, .{});}fn expectPreparedRunFingerprints(prepared: *const BackendPreparedJob) !void { const target_module = try prepared.targetModule(); const tensor_module = target_module.kernel_module.memory_module.dispatch_module.tensor_module; try testing.expectEqual( tensor_module.contract_module.fingerprint(), prepared.run.contract_fingerprint, ); try testing.expectEqual(tensor_module.fingerprint(), prepared.run.tensor_fingerprint); try testing.expectEqual(target_module.fingerprint(), prepared.run.target_fingerprint); try testing.expect(prepared.run.dispatch_fingerprint != prepared.run.tensor_fingerprint); try testing.expect(prepared.run.memory_fingerprint != prepared.run.tensor_fingerprint); try testing.expect(prepared.run.kernel_fingerprint != prepared.run.tensor_fingerprint);}fn buildSemanticAddMulSubMaxModule( allocator: std.mem.Allocator, name: []const u8, dims: []const i64,) !*semantic.SemanticModule { var builder = try semantic.Builder.init(allocator, semantic.Builder.ContextLimits.standard); errdefer builder.deinit(); const ty = try builder.tensor(.f32, dims); var fb = try builder.beginFunction(name, &.{ ty, ty }, &.{ty}); const rhs = fb.parameter(1); var current = try fb.add(fb.parameter(0), rhs); current = try fb.mul(current, rhs); current = try fb.sub(current, rhs); current = try fb.max(current, rhs); try fb.return_(&.{current}); try fb.finish(); return try builder.finish();}test "target pipeline validates kernel candidates without static cloned IR" { const allocator = testing.allocator; const module = try buildSemanticAddModule(allocator, "pass_add4", &.{4}); defer module.deinit(); const choir_mod = module.choir_module; const ctx = module.context(); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try addTargetPipeline(&pm); try testing.expectEqual(passes.PassResult.success, pm.run(choir_mod, ctx)); try testing.expectEqual(@as(u64, target_pass_count), pm.stats.pass_runs); try testing.expect(pm.stats.analysis_misses > 0); const body = choir_mod.getRegion(0).?.getEntryBlock().?; try testing.expect(ir.inspection.functionByNameInBlock(body, "pass_add4") != null); try testing.expect(!hasFunctionNameSuffix(body, "lowered")); try expectPreparedKernelPlan(allocator, choir_mod, ctx, 1);}test "prepareContractJobFromSemanticModule materializes normalized contract job" { const allocator = testing.allocator; var builder = try semantic.Builder.init(allocator, semantic.Builder.ContextLimits.standard); defer builder.deinit(); const ty = try builder.tensor(.f32, &.{1}); var fb = try builder.beginFunction("contract_fold_add", &.{}, &.{ty}); const one: [1]f32 = .{1}; const two: [1]f32 = .{2}; const lhs = try fb.constant(ty, std.mem.sliceAsBytes(one[0..])); const rhs = try fb.constant(ty, std.mem.sliceAsBytes(two[0..])); const sum = try fb.add(lhs, rhs); try fb.return_(&.{sum}); try fb.finish(); const semantic_module = try builder.finish(); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); defer contract_module.deinit(); try testing.expectEqualStrings(contract.product_name, accy_choir.contract_product_name); try contract_module.verify(); try testing.expectEqual(@as(usize, 0), ir.inspection.countOperationsNamed(contract_module.choir_module, dialect_mod.AccyDialect.AddOp.operation_name));}test "prepareTensorJobFromContractJob materializes tensor job" { const allocator = testing.allocator; const semantic_module = try buildSemanticAddMulModule(allocator, "tensor_product_add_mul", &.{4}); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); defer tensor_module.deinit(); try testing.expectEqualStrings(tensor.product_name, accy_choir.tensor_product_name); try tensor_module.verify();}test "prepareDispatchJobFromTensorJob materializes dispatch job" { const allocator = testing.allocator; const semantic_module = try buildSemanticAddMulModule(allocator, "dispatch_product_add_mul", &.{4}); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); defer dispatch_module.deinit(); try testing.expectEqualStrings(dispatch.product_name, accy_choir.dispatch_product_name); try dispatch_module.verify(); try testing.expect(dispatch_module.tensor_module.analysis_cache.entries.count() > 0); var pass_ctx = dispatch_module.passContext(); defer pass_ctx.deinit(); const plan = try schedule_planning.getSchedulePlanAnalysis(&pass_ctx, pass_ctx.op); try testing.expectEqual(@as(usize, 2), plan.workItemCount());}test "prepareDispatchJobFromTensorJob fingerprints dispatch analysis product" { const allocator = testing.allocator; const first_semantic_module = try buildSemanticAddMulModule(allocator, "dispatch_fingerprint_first", &.{4}); const first_contract_module = try prepareContractJobFromSemanticModule(allocator, first_semantic_module, .{}); const first_tensor_module = try prepareTensorJobFromContractJob(allocator, first_contract_module, .{}); var first_dispatch = try prepareDispatchJobFromTensorJobWithRun( allocator, first_tensor_module, .{}, ); defer first_dispatch.deinit(); const second_semantic_module = try buildSemanticAddMulModule(allocator, "dispatch_fingerprint_second", &.{4}); const second_contract_module = try prepareContractJobFromSemanticModule(allocator, second_semantic_module, .{}); const second_tensor_module = try prepareTensorJobFromContractJob(allocator, second_contract_module, .{}); var second_dispatch = try prepareDispatchJobFromTensorJobWithRun( allocator, second_tensor_module, .{}, ); defer second_dispatch.deinit(); const changed_semantic_module = try buildSemanticAddMulSubMaxModule(allocator, "dispatch_fingerprint_changed", &.{4}); const changed_contract_module = try prepareContractJobFromSemanticModule(allocator, changed_semantic_module, .{}); const changed_tensor_module = try prepareTensorJobFromContractJob(allocator, changed_contract_module, .{}); var changed_dispatch = try prepareDispatchJobFromTensorJobWithRun( allocator, changed_tensor_module, .{}, ); defer changed_dispatch.deinit(); try testing.expectEqual(first_dispatch.plan_fingerprint, second_dispatch.plan_fingerprint); try testing.expect(first_dispatch.plan_fingerprint != changed_dispatch.plan_fingerprint);}test "prepareMemoryJobFromDispatchJob materializes memory job" { const allocator = testing.allocator; const semantic_module = try buildSemanticAddMulModule(allocator, "memory_product_add_mul", &.{4}); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); const memory_module = try prepareMemoryJobFromDispatchJob(allocator, dispatch_module, .{}); defer memory_module.deinit(); try testing.expectEqualStrings(memory_product.product_name, accy_choir.memory_product_name); try memory_module.verify(); try testing.expect(memory_module.dispatch_module.tensor_module.analysis_cache.entries.count() > 0); var pass_ctx = memory_module.passContext(); defer pass_ctx.deinit(); const buffers = @import("bufferization/root.zig"); const plan = try buffers.getBufferPlanAnalysis(&pass_ctx, pass_ctx.op); try testing.expectEqual(@as(usize, 5), plan.slotCount());}test "prepareMemoryJobFromDispatchJob fingerprints memory analysis product" { const allocator = testing.allocator; const first_semantic_module = try buildSemanticAddMulModule(allocator, "memory_fingerprint_first", &.{4}); const first_contract_module = try prepareContractJobFromSemanticModule(allocator, first_semantic_module, .{}); const first_tensor_module = try prepareTensorJobFromContractJob(allocator, first_contract_module, .{}); const first_dispatch_module = try prepareDispatchJobFromTensorJob(allocator, first_tensor_module, .{}); var first_memory = try prepareMemoryJobFromDispatchJobWithRun( allocator, first_dispatch_module, .{}, ); defer first_memory.deinit(); const second_semantic_module = try buildSemanticAddMulModule(allocator, "memory_fingerprint_second", &.{4}); const second_contract_module = try prepareContractJobFromSemanticModule(allocator, second_semantic_module, .{}); const second_tensor_module = try prepareTensorJobFromContractJob(allocator, second_contract_module, .{}); const second_dispatch_module = try prepareDispatchJobFromTensorJob(allocator, second_tensor_module, .{}); var second_memory = try prepareMemoryJobFromDispatchJobWithRun( allocator, second_dispatch_module, .{}, ); defer second_memory.deinit(); const changed_semantic_module = try buildSemanticAddMulSubMaxModule(allocator, "memory_fingerprint_changed", &.{4}); const changed_contract_module = try prepareContractJobFromSemanticModule(allocator, changed_semantic_module, .{}); const changed_tensor_module = try prepareTensorJobFromContractJob(allocator, changed_contract_module, .{}); const changed_dispatch_module = try prepareDispatchJobFromTensorJob(allocator, changed_tensor_module, .{}); var changed_memory = try prepareMemoryJobFromDispatchJobWithRun( allocator, changed_dispatch_module, .{}, ); defer changed_memory.deinit(); try testing.expectEqual(first_memory.plan_fingerprint, second_memory.plan_fingerprint); try testing.expect(first_memory.plan_fingerprint != changed_memory.plan_fingerprint);}test "prepareKernelJobFromMemoryJob materializes kernel job" { const allocator = testing.allocator; const semantic_module = try buildSemanticAddMulModule(allocator, "kernel_product_add_mul", &.{4}); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); const memory_module = try prepareMemoryJobFromDispatchJob(allocator, dispatch_module, .{}); const kernel_module = try prepareKernelJobFromMemoryJob(allocator, memory_module, .{}); defer kernel_module.deinit(); try testing.expectEqualStrings(kernel_product.product_name, accy_choir.kernel_product_name); try kernel_module.verify(); try testing.expect(kernel_module.memory_module.dispatch_module.tensor_module.analysis_cache.entries.count() > 0); var pass_ctx = kernel_module.passContext(); defer pass_ctx.deinit(); const kernel_plan = try kernelization.getKernelizationAnalysis(&pass_ctx, kernel_module.choir_module); try testing.expectEqual(@as(usize, 2), kernel_plan.kernelCount());}test "prepareKernelJobFromMemoryJob fingerprints kernel analysis product" { const allocator = testing.allocator; const first_semantic_module = try buildSemanticAddMulModule(allocator, "kernel_fingerprint_first", &.{4}); const first_contract_module = try prepareContractJobFromSemanticModule(allocator, first_semantic_module, .{}); const first_tensor_module = try prepareTensorJobFromContractJob(allocator, first_contract_module, .{}); const first_dispatch_module = try prepareDispatchJobFromTensorJob(allocator, first_tensor_module, .{}); const first_memory_module = try prepareMemoryJobFromDispatchJob(allocator, first_dispatch_module, .{}); var first_kernel = try prepareKernelJobFromMemoryJobWithRun( allocator, first_memory_module, .{}, ); defer first_kernel.deinit(); const second_semantic_module = try buildSemanticAddMulModule(allocator, "kernel_fingerprint_second", &.{4}); const second_contract_module = try prepareContractJobFromSemanticModule(allocator, second_semantic_module, .{}); const second_tensor_module = try prepareTensorJobFromContractJob(allocator, second_contract_module, .{}); const second_dispatch_module = try prepareDispatchJobFromTensorJob(allocator, second_tensor_module, .{}); const second_memory_module = try prepareMemoryJobFromDispatchJob(allocator, second_dispatch_module, .{}); var second_kernel = try prepareKernelJobFromMemoryJobWithRun( allocator, second_memory_module, .{}, ); defer second_kernel.deinit(); const changed_semantic_module = try buildSemanticAddMulSubMaxModule(allocator, "kernel_fingerprint_changed", &.{4}); const changed_contract_module = try prepareContractJobFromSemanticModule(allocator, changed_semantic_module, .{}); const changed_tensor_module = try prepareTensorJobFromContractJob(allocator, changed_contract_module, .{}); const changed_dispatch_module = try prepareDispatchJobFromTensorJob(allocator, changed_tensor_module, .{}); const changed_memory_module = try prepareMemoryJobFromDispatchJob(allocator, changed_dispatch_module, .{}); var changed_kernel = try prepareKernelJobFromMemoryJobWithRun( allocator, changed_memory_module, .{}, ); defer changed_kernel.deinit(); try testing.expectEqual(first_kernel.plan_fingerprint, second_kernel.plan_fingerprint); try testing.expect(first_kernel.plan_fingerprint != changed_kernel.plan_fingerprint);}test "kernel preparation lowers fused elementwise benchmark chain" { const allocator = testing.allocator; const semantic_module = try buildSemanticAddMulSubMaxModule(allocator, "kernel_product_add_mul_sub_max", &.{16}); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); const memory_module = try prepareMemoryJobFromDispatchJob(allocator, dispatch_module, .{}); const kernel_module = try prepareKernelJobFromMemoryJob(allocator, memory_module, .{}); defer kernel_module.deinit(); var pass_ctx = kernel_module.passContext(); defer pass_ctx.deinit(); const kernel_plan = try kernelization.getKernelizationAnalysis(&pass_ctx, kernel_module.choir_module); try testing.expectEqual(@as(usize, 1), kernel_plan.kernelCount()); const kernel = kernel_plan.kernels.items[0]; try testing.expect(std.mem.indexOf(u8, kernel.entry_name, "add") != null); try testing.expect(std.mem.indexOf(u8, kernel.entry_name, "mul") != null); try testing.expect(std.mem.indexOf(u8, kernel.entry_name, "sub") != null); try testing.expect(std.mem.indexOf(u8, kernel.entry_name, "max") != null);}test "kernel preparation handles einsum operand-local reductions" { const allocator = testing.allocator; var builder = try semantic.Builder.init(allocator, semantic.Builder.ContextLimits.standard); defer builder.deinit(); const lhs_ty = try builder.tensor(.f32, &.{ 16, 16 }); const rhs_ty = try builder.tensor(.f32, &.{ 16, 16 }); const out_ty = try builder.tensor(.f32, &.{ 16, 16 }); var fb = try builder.beginFunction("kernel_product_einsum_local_reduction", &.{ lhs_ty, rhs_ty }, &.{out_ty}); const out = try fb.einsum(&.{ fb.parameter(0), fb.parameter(1) }, out_ty, "ab,cd->ac"); try fb.return_(&.{out}); try fb.finish(); const semantic_module = try builder.finish(); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); const memory_module = try prepareMemoryJobFromDispatchJob(allocator, dispatch_module, .{}); const kernel_module = try prepareKernelJobFromMemoryJob(allocator, memory_module, .{}); defer kernel_module.deinit(); try kernel_module.verify(); var pass_ctx = kernel_module.passContext(); defer pass_ctx.deinit(); const kernel_plan = try kernelization.getKernelizationAnalysis(&pass_ctx, kernel_module.choir_module); try testing.expectEqual(@as(usize, 3), kernel_plan.kernelCount());}test "kernel preparation handles three operand einsum contractions" { const allocator = testing.allocator; var builder = try semantic.Builder.init(allocator, semantic.Builder.ContextLimits.standard); defer builder.deinit(); const q_ty = try builder.tensor(.f32, &.{ 2, 16, 16 }); const k_ty = try builder.tensor(.f32, &.{ 2, 16, 16 }); const v_ty = try builder.tensor(.f32, &.{ 2, 16, 16 }); const out_ty = try builder.tensor(.f32, &.{ 2, 16, 16 }); var fb = try builder.beginFunction("kernel_product_einsum_three_operand", &.{ q_ty, k_ty, v_ty }, &.{out_ty}); const out = try fb.einsum(&.{ fb.parameter(0), fb.parameter(1), fb.parameter(2) }, out_ty, "bqd,bkd,bkv->bqv"); try fb.return_(&.{out}); try fb.finish(); const semantic_module = try builder.finish(); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); const memory_module = try prepareMemoryJobFromDispatchJob(allocator, dispatch_module, .{}); const kernel_module = try prepareKernelJobFromMemoryJob(allocator, memory_module, .{}); defer kernel_module.deinit(); try kernel_module.verify(); var pass_ctx = kernel_module.passContext(); defer pass_ctx.deinit(); const kernel_plan = try kernelization.getKernelizationAnalysis(&pass_ctx, kernel_module.choir_module); try testing.expect(kernel_plan.kernelCount() > 0);}test "prepareTargetJobFromKernelJob materializes target job" { const allocator = testing.allocator; const semantic_module = try buildSemanticAddMulModule(allocator, "target_product_add_mul", &.{4}); const contract_module = try prepareContractJobFromSemanticModule(allocator, semantic_module, .{}); const tensor_module = try prepareTensorJobFromContractJob(allocator, contract_module, .{}); const dispatch_module = try prepareDispatchJobFromTensorJob(allocator, tensor_module, .{}); const memory_module = try prepareMemoryJobFromDispatchJob(allocator, dispatch_module, .{}); const kernel_module = try prepareKernelJobFromMemoryJob(allocator, memory_module, .{}); const target_module = try prepareTargetJobFromKernelJob(allocator, kernel_module, .{}); defer target_module.deinit(); try target_module.verify(); try testing.expect(target_module.choir_module != target_module.kernel_module.choir_module); try testing.expect(target_module.kernel_module.memory_module.dispatch_module.tensor_module.analysis_cache.entries.count() > 0); try testing.expect(target_module.analysis_cache.entries.count() > 0); try testing.expectEqual(@as(usize, 2), target_module.kernelizationProduct().kernelCount()); var pass_ctx = target_module.passContext(); defer pass_ctx.deinit(); const legal_plan = try backend_legalization.getBackendLegalizationAnalysis(&pass_ctx, target_module.choir_module); try testing.expectEqual(@as(usize, 2), legal_plan.kernelCount()); try testing.expect(legal_plan.isLegal());}test "prepareBackendJobFromDispatchPreparationResult continues prepared pipeline" { const allocator = testing.allocator; var dispatch_result = try prepareDispatchResultForContinuationTest(allocator, "dispatch_continuation_add_mul"); var dispatch_owned = true; errdefer if (dispatch_owned) dispatch_result.deinit(); const dispatch_ns = dispatch_result.elapsed_ns; const dispatch_stats = dispatch_result.stats; const dispatch_fingerprint = dispatch_result.plan_fingerprint; dispatch_owned = false; var prepared = try prepareBackendJobFromDispatchPreparationResult( allocator, dispatch_result, .{}, 11, .{ .pass_runs = 101, .analysis_hits = 102 }, 13, .{ .pass_runs = 103, .analysis_misses = 104 }, 17, null, 0, ); defer prepared.deinit(); try testing.expectEqual(@as(u64, 11), prepared.run.contract_ns); try testing.expectEqual(@as(u64, 13), prepared.run.tensor_ns); try testing.expectEqual(dispatch_ns, prepared.run.dispatch_ns); try testing.expectEqual(@as(u64, 101), prepared.run.contract_stats.pass_runs); try testing.expectEqual(@as(u64, 102), prepared.run.contract_stats.analysis_hits); try testing.expectEqual(@as(u64, 103), prepared.run.tensor_stats.pass_runs); try testing.expectEqual(@as(u64, 104), prepared.run.tensor_stats.analysis_misses); try testing.expectEqual(dispatch_stats.pass_runs, prepared.run.dispatch_stats.pass_runs); try testing.expectEqual(dispatch_stats.analysis_misses, prepared.run.dispatch_stats.analysis_misses); try testing.expectEqual(@as(u64, memory_pass_count), prepared.run.memory_stats.pass_runs); try testing.expectEqual(@as(u64, kernel_pass_count), prepared.run.kernel_stats.pass_runs); try testing.expectEqual(@as(u64, target_pass_count), prepared.run.target_stats.pass_runs); try testing.expectEqual(@as(u64, 17), prepared.run.initial_choir_ops); try testing.expectEqual(dispatch_fingerprint, prepared.run.dispatch_fingerprint); try expectPreparedRunFingerprints(&prepared); try testing.expectEqual(@as(usize, 2), try prepared.generatedKernelCount());}test "prepareBackendJobFromMemoryPreparationResult continues prepared pipeline" { const allocator = testing.allocator; var memory_result = try prepareMemoryResultForContinuationTest(allocator, "memory_continuation_add_mul"); var memory_owned = true; errdefer if (memory_owned) memory_result.deinit(); const memory_ns = memory_result.elapsed_ns; const memory_stats = memory_result.stats; const memory_fingerprint = memory_result.plan_fingerprint; memory_owned = false; var prepared = try prepareBackendJobFromMemoryPreparationResult( allocator, memory_result, .{}, 19, .{ .pass_runs = 107 }, 23, .{ .pass_runs = 109 }, 29, .{ .pass_runs = 113, .analysis_hits = 114 }, 127, 31, null, 0, ); defer prepared.deinit(); try testing.expectEqual(@as(u64, 19), prepared.run.contract_ns); try testing.expectEqual(@as(u64, 23), prepared.run.tensor_ns); try testing.expectEqual(@as(u64, 29), prepared.run.dispatch_ns); try testing.expectEqual(memory_ns, prepared.run.memory_ns); try testing.expectEqual(@as(u64, 107), prepared.run.contract_stats.pass_runs); try testing.expectEqual(@as(u64, 109), prepared.run.tensor_stats.pass_runs); try testing.expectEqual(@as(u64, 113), prepared.run.dispatch_stats.pass_runs); try testing.expectEqual(@as(u64, 114), prepared.run.dispatch_stats.analysis_hits); try testing.expectEqual(memory_stats.pass_runs, prepared.run.memory_stats.pass_runs); try testing.expectEqual(memory_stats.analysis_misses, prepared.run.memory_stats.analysis_misses); try testing.expectEqual(@as(u64, kernel_pass_count), prepared.run.kernel_stats.pass_runs); try testing.expectEqual(@as(u64, target_pass_count), prepared.run.target_stats.pass_runs); try testing.expectEqual(@as(u64, 31), prepared.run.initial_choir_ops); try testing.expectEqual(@as(u64, 127), prepared.run.dispatch_fingerprint); try testing.expectEqual(memory_fingerprint, prepared.run.memory_fingerprint); try expectPreparedRunFingerprints(&prepared); try testing.expectEqual(@as(usize, 2), try prepared.generatedKernelCount());}test "prepareBackendJobFromKernelPreparationResult continues prepared pipeline" { const allocator = testing.allocator; var kernel_result = try prepareKernelResultForContinuationTest(allocator, "kernel_continuation_add_mul"); var kernel_owned = true; errdefer if (kernel_owned) kernel_result.deinit(); const kernel_ns = kernel_result.elapsed_ns; const kernel_stats = kernel_result.stats; const kernel_fingerprint = kernel_result.plan_fingerprint; kernel_owned = false; var prepared = try prepareBackendJobFromKernelPreparationResult( allocator, kernel_result, .{}, 37, .{ .pass_runs = 127 }, 41, .{ .pass_runs = 131 }, 43, .{ .pass_runs = 137 }, 149, 47, .{ .pass_runs = 139, .analysis_misses = 140 }, 151, 53, null, 0, ); defer prepared.deinit(); try testing.expectEqual(@as(u64, 37), prepared.run.contract_ns); try testing.expectEqual(@as(u64, 41), prepared.run.tensor_ns); try testing.expectEqual(@as(u64, 43), prepared.run.dispatch_ns); try testing.expectEqual(@as(u64, 47), prepared.run.memory_ns); try testing.expectEqual(kernel_ns, prepared.run.kernel_ns); try testing.expectEqual(@as(u64, 139), prepared.run.memory_stats.pass_runs); try testing.expectEqual(@as(u64, 140), prepared.run.memory_stats.analysis_misses); try testing.expectEqual(kernel_stats.pass_runs, prepared.run.kernel_stats.pass_runs); try testing.expectEqual(kernel_stats.analysis_misses, prepared.run.kernel_stats.analysis_misses); try testing.expectEqual(@as(u64, target_pass_count), prepared.run.target_stats.pass_runs); try testing.expectEqual(@as(u64, 53), prepared.run.initial_choir_ops); try testing.expectEqual(@as(u64, 149), prepared.run.dispatch_fingerprint); try testing.expectEqual(@as(u64, 151), prepared.run.memory_fingerprint); try testing.expectEqual(kernel_fingerprint, prepared.run.kernel_fingerprint); try expectPreparedRunFingerprints(&prepared); try testing.expectEqual(@as(usize, 2), try prepared.generatedKernelCount());}test "prepareBackendJobFromTargetPreparationResult owns prepared product" { const allocator = testing.allocator; var target_result = try prepareTargetResultForContinuationTest(allocator, "target_continuation_add_mul"); var target_owned = true; errdefer if (target_owned) target_result.deinit(); const target_ns = target_result.elapsed_ns; const target_stats = target_result.stats; const target_fingerprint = target_result.module.fingerprint(); target_owned = false; var prepared = try prepareBackendJobFromTargetPreparationResult( allocator, target_result, .{}, 59, .{ .pass_runs = 149 }, 61, .{ .pass_runs = 151 }, 67, .{ .pass_runs = 157 }, 173, 71, .{ .pass_runs = 163 }, 179, 73, .{ .pass_runs = 167, .analysis_hits = 168 }, 181, 79, null, 0, ); defer prepared.deinit(); try testing.expectEqual(@as(u64, 59), prepared.run.contract_ns); try testing.expectEqual(@as(u64, 61), prepared.run.tensor_ns); try testing.expectEqual(@as(u64, 67), prepared.run.dispatch_ns); try testing.expectEqual(@as(u64, 71), prepared.run.memory_ns); try testing.expectEqual(@as(u64, 73), prepared.run.kernel_ns); try testing.expectEqual(target_ns, prepared.run.target_ns); try testing.expectEqual(@as(u64, 167), prepared.run.kernel_stats.pass_runs); try testing.expectEqual(@as(u64, 168), prepared.run.kernel_stats.analysis_hits); try testing.expectEqual(target_stats.pass_runs, prepared.run.target_stats.pass_runs); try testing.expectEqual(target_stats.analysis_misses, prepared.run.target_stats.analysis_misses); try testing.expectEqual(@as(u64, 79), prepared.run.initial_choir_ops); try testing.expectEqual(@as(u64, 173), prepared.run.dispatch_fingerprint); try testing.expectEqual(@as(u64, 179), prepared.run.memory_fingerprint); try testing.expectEqual(@as(u64, 181), prepared.run.kernel_fingerprint); try testing.expectEqual(target_fingerprint, prepared.run.target_fingerprint); try expectPreparedRunFingerprints(&prepared); try testing.expectEqual(@as(usize, 2), try prepared.generatedKernelCount());}test "prepareBackendJobFromSemanticModule owns its transient pipeline and diagnostic summaries" { const allocator = testing.allocator; const target = try BackendTargetProfile.init(.{ .identity = .{ .backend = .cuda, .family = .nvidia_cuda, }, .dtypes = gpu.DTypeSet.init(&.{ .f32, .i32 }), .artifact_formats = gpu.ArtifactFormatSet.init(&.{.cuda_ptx}), }, .cuda, .cuda_ptx); const module = try buildSemanticAddModule(allocator, "prepared_product_add4", &.{4}); var prepared = try prepareBackendJobFromSemanticModule(allocator, module, .{ .target_profile = target }); defer prepared.deinit(); try expectPreparedJobState(&prepared, target); try expectPreparedJobProgram(&prepared, target); try expectPreparedJobDiagnostics(&prepared);}fn expectPreparedJobStamps(prepared: *const BackendPreparedJob) !void { const stamps = try prepared.productStamps(); try expectProductStamp(stamps.semantic.?, semantic.product_name, prepared.run.semantic_fingerprint.?); try expectProductStamp(stamps.contract, contract.product_name, prepared.run.contract_fingerprint); try expectProductStamp(stamps.tensor, tensor.product_name, prepared.run.tensor_fingerprint); try expectProductStamp(stamps.dispatch, dispatch.product_name, prepared.run.dispatch_fingerprint); try expectProductStamp(stamps.memory, memory_product.product_name, prepared.run.memory_fingerprint); try expectProductStamp(stamps.kernel, kernel_product.product_name, prepared.run.kernel_fingerprint); try expectProductStamp(stamps.target, target_product.product_name, prepared.run.target_fingerprint);}fn expectPreparedJobState(prepared: *BackendPreparedJob, target: BackendTargetProfile) !void { const allocator = testing.allocator; const target_module = try prepared.targetModule(); const read_target = target_profile.readBackendTargetProfile(prepared.choir_module) orelse return error.MissingTargetProfile; try testing.expectEqual(target.backend_kind, read_target.backend_kind); try testing.expectEqual(target.artifact_format, read_target.artifact_format); try testing.expectEqual(target.math_tier, read_target.math_tier); try testing.expectEqual(target.dtype_bits, read_target.dtype_bits); try testing.expect(prepared.choir_module == target_module.choir_module); try testing.expect(target_module.choir_module != target_module.kernel_module.choir_module); const kernel_stage_target = target_profile.readBackendTargetProfile(target_module.kernel_module.choir_module) orelse return error.MissingTargetProfile; try testing.expectEqual(target.artifact_format, kernel_stage_target.artifact_format); try testing.expectEqual(target.math_tier, kernel_stage_target.math_tier); try testing.expect(target_module.kernel_module.fingerprint() != 0); try testing.expectEqual( try choir.operationFingerprint(allocator, target_module.kernel_module.choir_module), target_module.kernel_module.fingerprint(), ); try testing.expectEqual(target.backend_kind, prepared.run.target_profile.?.backend_kind); try testing.expectEqual(@as(u64, contract_pass_count), prepared.run.contract_stats.pass_runs); try testing.expectEqual(@as(u64, tensor_pass_count), prepared.run.tensor_stats.pass_runs); try testing.expectEqual(@as(u64, dispatch_pass_count), prepared.run.dispatch_stats.pass_runs); try testing.expectEqual(@as(u64, memory_pass_count), prepared.run.memory_stats.pass_runs); try testing.expectEqual(@as(u64, kernel_pass_count), prepared.run.kernel_stats.pass_runs); try testing.expectEqual(@as(u64, target_pass_count), prepared.run.target_stats.pass_runs); try testing.expect(prepared.run.contract_fingerprint != 0); try testing.expect(prepared.run.tensor_fingerprint != 0); try testing.expect(prepared.run.dispatch_fingerprint != 0); try testing.expect(prepared.run.memory_fingerprint != 0); try testing.expect(prepared.run.kernel_fingerprint != 0); try testing.expect(prepared.run.target_fingerprint != 0); try testing.expect(prepared.run.semantic_fingerprint != null); try expectPreparedJobStamps(prepared); try testing.expectEqual(try choir.operationFingerprint(allocator, prepared.choir_module), prepared.run.target_fingerprint); try testing.expect(prepared.run.dispatch_stats.analysis_misses > 0); try testing.expect(prepared.run.memory_stats.analysis_misses > 0); try testing.expect(prepared.run.kernel_stats.analysis_misses > 0); try testing.expect(prepared.run.target_stats.analysis_misses > 0); try testing.expect(prepared.run.initial_choir_ops > 0); try testing.expect(prepared.run.final_choir_ops > 0); try testing.expect(prepared.ctx.isDialectLoaded("memref")); try testing.expect(prepared.ctx.isDialectLoaded("scf"));}fn expectPreparedJobProgram(prepared: *BackendPreparedJob, target: BackendTargetProfile) !void { const allocator = testing.allocator; const body = prepared.choir_module.getRegion(0).?.getEntryBlock().?; try testing.expect(ir.inspection.functionByNameInBlock(body, "prepared_product_add4") != null); try testing.expect(!hasFunctionNameSuffix(body, "lowered")); var pass_ctx = prepared.passContext(); defer pass_ctx.deinit(); const kernel_plan = try prepared.kernelizationProduct(); const legal_plan = try backend_legalization.getBackendLegalizationAnalysis(&pass_ctx, prepared.choir_module); try testing.expectEqual(@as(usize, 1), kernel_plan.kernelCount()); try testing.expectEqual(@as(usize, 1), legal_plan.kernelCount()); try testing.expect(legal_plan.isLegal()); try testing.expectEqual(target.dtype_bits, legal_plan.target.?.dtype_bits); try testing.expectEqual(@as(usize, 1), try prepared.generatedKernelCount()); const summary = try prepared.generatedKernelSummary(0); try testing.expect(summary.entry_name.len > 0); try testing.expectEqualStrings(kernel_plan.kernels.items[0].entry_name, summary.entry_name); try testing.expectEqual(kernel_plan.kernels.items[0].argument_count, summary.argument_count); try testing.expectEqual(kernel_plan.kernels.items[0].body_fingerprint, summary.body_fingerprint); try testing.expectEqual(kernelization.GeneratedScheduleKind.flat, summary.schedule.kind); try testing.expect(summary.launch_geometry != null); const program = try prepared.generatedKernelProgram(0); try testing.expect(prepared.ctx != program.kernelModule().context); try ir.verifyOperation(program.kernelModule(), ir.verify.default_options); const launch = try program.launch(); try testing.expectEqual(launch.block[0], summary.launch_geometry.?.threadgroup[0]); const work_summary = try prepared.generatedKernelSummaryForWork(summary.work_item_id); try testing.expectEqualStrings(summary.entry_name, work_summary.entry_name); try testing.expectEqual(summary.body_fingerprint, work_summary.body_fingerprint); const work_program = try prepared.generatedKernelProgramForWork(summary.work_item_id); const work_launch = try work_program.launch(); try testing.expectEqual(launch.block[0], work_launch.block[0]); var summaries = try prepared.copyGeneratedKernelSummaries(allocator); defer summaries.deinit(); try testing.expectEqual(@as(usize, 1), summaries.len()); const copied_summary = try summaries.summaryForWork(summary.work_item_id); try testing.expectEqualStrings(summary.entry_name, copied_summary.entry_name); try testing.expectEqual(summary.body_fingerprint, copied_summary.body_fingerprint); try testing.expectError(error.InvalidIndex, prepared.generatedKernelSummary(1)); try testing.expectError(error.MissingKernelization, prepared.generatedKernelSummaryForWork(std.math.maxInt(usize))); try testing.expectError(error.MissingKernelization, summaries.summaryForWork(std.math.maxInt(usize)));}fn expectPreparedJobDiagnostics(prepared: *BackendPreparedJob) !void { const target_module = try prepared.targetModule(); prepared.run.semantic_fingerprint.? +%= 13; prepared.run.contract_fingerprint +%= 17; prepared.run.tensor_fingerprint +%= 19; prepared.run.dispatch_fingerprint +%= 23; prepared.run.memory_fingerprint +%= 29; prepared.run.kernel_fingerprint +%= 31; prepared.run.target_fingerprint +%= 37; const live_contract_fingerprint = target_module.kernel_module.memory_module.dispatch_module.tensor_module.contract_module.fingerprint(); try testing.expect(live_contract_fingerprint != prepared.run.contract_fingerprint); try testing.expect(target_module.fingerprint() != prepared.run.target_fingerprint); try expectPreparedJobStamps(prepared);}test "backend preparation target profile constrains backend legalization dtypes" { const allocator = testing.allocator; const target = try BackendTargetProfile.init(.{ .identity = .{ .backend = .vulkan, .family = .vulkan, }, .dtypes = gpu.DTypeSet.init(&.{.i32}), .artifact_formats = gpu.ArtifactFormatSet.init(&.{.vulkan_spirv}), }, .vulkan, .vulkan_spirv); const module = try buildSemanticAddModule(allocator, "target_profile_rejects_f32", &.{4}); var prepared = try prepareBackendJobFromSemanticModule(allocator, module, .{ .target_profile = target }); defer prepared.deinit(); var pass_ctx = prepared.passContext(); defer pass_ctx.deinit(); const legal_plan = try backend_legalization.getBackendLegalizationAnalysis(&pass_ctx, prepared.choir_module); const status = legal_plan.firstIllegalStatus() orelse return error.MissingIllegalKernel; try testing.expect(!legal_plan.isLegal()); try testing.expect(!legal_plan.hasPipelineFailure()); try testing.expectEqual(backend_legalization.BackendKernelStatus.unsupported_dtype, status); try testing.expectEqual(error.CapabilityMismatch, backend_legalization.backendKernelStatusError(status));}test "backend preparation pipelines register through Choir extensions" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pipeline_registry = passes.PipelineRegistry.init(allocator); defer pipeline_registry.deinit(); try extension_registry.registerPipelinesTo(&pipeline_registry); try testing.expect(pipeline_registry.lookup(contract_pipeline_name) != null); try testing.expect(pipeline_registry.lookup(tensor_pipeline_name) != null); try testing.expect(pipeline_registry.lookup(dispatch_pipeline_name) != null); try testing.expect(pipeline_registry.lookup(memory_pipeline_name) != null); try testing.expect(pipeline_registry.lookup(kernel_pipeline_name) != null); try testing.expect(pipeline_registry.lookup(target_pipeline_name) != null); var contract_pm = passes.PassManager.init(allocator); defer contract_pm.deinit(); try pipeline_registry.addPipelineTo(contract_pipeline_name, &contract_pm); try testing.expectEqual(contract_pass_count, contract_pm.root.pipeline.items.len); var tensor_pm = passes.PassManager.init(allocator); defer tensor_pm.deinit(); try pipeline_registry.addPipelineTo(tensor_pipeline_name, &tensor_pm); try expectTensorStagePipeline(&tensor_pm); var dispatch_pm = passes.PassManager.init(allocator); defer dispatch_pm.deinit(); try pipeline_registry.addPipelineTo(dispatch_pipeline_name, &dispatch_pm); try expectDispatchStagePipeline(&dispatch_pm); var memory_pm = passes.PassManager.init(allocator); defer memory_pm.deinit(); try pipeline_registry.addPipelineTo(memory_pipeline_name, &memory_pm); try expectMemoryStagePipeline(&memory_pm); var kernel_pm = passes.PassManager.init(allocator); defer kernel_pm.deinit(); try pipeline_registry.addPipelineTo(kernel_pipeline_name, &kernel_pm); try expectKernelStagePipeline(&kernel_pm); var target_pm = passes.PassManager.init(allocator); defer target_pm.deinit(); try pipeline_registry.addPipelineTo(target_pipeline_name, &target_pm); try expectTargetStagePipeline(&target_pm);}test "individual Accy Choir passes register through Choir extensions" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); try testing.expectEqual( @as(usize, accy_choir_pass_registrations.len), pass_registry.passes.items.len, ); inline for (accy_choir_pass_registrations) |registration| { try testing.expect(pass_registry.lookupPass(registration.name) != null); } var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline( &pass_registry, canonicalization_pass_name ++ "," ++ saturation_pass_name, &pm, ); try testing.expectEqual(@as(usize, 2), pm.root.pipeline.items.len); const text = try passes.formatPassManagerPipelineAlloc(allocator, &pm); defer allocator.free(text); try testing.expectEqualStrings(canonicalization_pass_name ++ "," ++ saturation_pass_name, text);}test "backend preparation stage table defines registries and profiling products" { try testing.expectEqual(contract_stages.len, contract_pass_count); try testing.expectEqual(tensor_stages.len, tensor_pass_count); try testing.expectEqual(dispatch_stages.len, dispatch_pass_count); try testing.expectEqual(memory_stages.len, memory_pass_count); try testing.expectEqual(kernel_stages.len, kernel_pass_count); try testing.expectEqual(target_stages.len, target_pass_count); try testing.expectEqual(contract_stages.len + tensor_stages.len + dispatch_stages.len + memory_stages.len + kernel_stages.len + target_stages.len, accy_choir_pass_registrations.len); try testing.expectEqualStrings(kernelization.kernelization_analysis_descriptor.name, kernel_stages[1].analysis_name.?); try testing.expectEqual(contract_stages.len, contract_pass_plan.steps.len); try testing.expectEqual(tensor_stages.len, tensor_pass_plan.steps.len); try testing.expectEqual(dispatch_stages.len, dispatch_pass_plan.steps.len); try testing.expectEqual(memory_stages.len, memory_pass_plan.steps.len); try testing.expectEqual(kernel_stages.len, kernel_pass_plan.steps.len); try testing.expectEqual(target_stages.len, target_pass_plan.steps.len); var contract_analysis_index: usize = 0; inline for (contract_stages, 0..) |stage, index| { try testing.expectEqualStrings(stage.name, contractPassName(index)); try testing.expectEqualStrings(stage.name, accy_choir_pass_registrations[index].name); try testing.expectEqualStrings(stage.description, accy_choir_pass_registrations[index].description); try testing.expectEqualStrings(stage.pass.name, accy_choir_pass_registrations[index].pass.name); if (stage.analysis_name) |name| { try testing.expectEqualStrings(name, contractAnalysisName(contract_analysis_index)); contract_analysis_index += 1; } } var tensor_analysis_index: usize = 0; inline for (tensor_stages, 0..) |stage, index| { const registration_index = contract_stages.len + index; try testing.expectEqualStrings(stage.name, tensorPassName(index)); try testing.expectEqualStrings(stage.name, accy_choir_pass_registrations[registration_index].name); try testing.expectEqualStrings(stage.description, accy_choir_pass_registrations[registration_index].description); try testing.expectEqualStrings(stage.pass.name, accy_choir_pass_registrations[registration_index].pass.name); try testing.expectEqual(stage.options.len, accy_choir_pass_registrations[registration_index].options.len); try testing.expectEqual(stage.build_with_options != null, accy_choir_pass_registrations[registration_index].build_with_options != null); if (stage.analysis_name) |name| { try testing.expectEqualStrings(name, tensorAnalysisName(tensor_analysis_index)); tensor_analysis_index += 1; } } var dispatch_analysis_index: usize = 0; inline for (dispatch_stages, 0..) |stage, index| { const registration_index = contract_stages.len + tensor_stages.len + index; try testing.expectEqualStrings(stage.name, dispatchPassName(index)); try testing.expectEqualStrings(stage.name, accy_choir_pass_registrations[registration_index].name); try testing.expectEqualStrings(stage.description, accy_choir_pass_registrations[registration_index].description); try testing.expectEqualStrings(stage.pass.name, accy_choir_pass_registrations[registration_index].pass.name); if (stage.analysis_name) |name| { try testing.expectEqualStrings(name, dispatchAnalysisName(dispatch_analysis_index)); dispatch_analysis_index += 1; } } var memory_analysis_index: usize = 0; inline for (memory_stages, 0..) |stage, index| { const registration_index = contract_stages.len + tensor_stages.len + dispatch_stages.len + index; try testing.expectEqualStrings(stage.name, memoryPassName(index)); try testing.expectEqualStrings(stage.name, accy_choir_pass_registrations[registration_index].name); try testing.expectEqualStrings(stage.description, accy_choir_pass_registrations[registration_index].description); try testing.expectEqualStrings(stage.pass.name, accy_choir_pass_registrations[registration_index].pass.name); if (stage.analysis_name) |name| { try testing.expectEqualStrings(name, memoryAnalysisName(memory_analysis_index)); memory_analysis_index += 1; } } var kernel_analysis_index: usize = 0; inline for (kernel_stages, 0..) |stage, index| { const registration_index = contract_stages.len + tensor_stages.len + dispatch_stages.len + memory_stages.len + index; try testing.expectEqualStrings(stage.name, kernelPassName(index)); try testing.expectEqualStrings(stage.name, accy_choir_pass_registrations[registration_index].name); try testing.expectEqualStrings(stage.description, accy_choir_pass_registrations[registration_index].description); try testing.expectEqualStrings(stage.pass.name, accy_choir_pass_registrations[registration_index].pass.name); if (stage.analysis_name) |name| { try testing.expectEqualStrings(name, kernelAnalysisName(kernel_analysis_index)); kernel_analysis_index += 1; } } var target_analysis_index: usize = 0; inline for (target_stages, 0..) |stage, index| { const registration_index = contract_stages.len + tensor_stages.len + dispatch_stages.len + memory_stages.len + kernel_stages.len + index; try testing.expectEqualStrings(stage.name, targetPassName(index)); try testing.expectEqualStrings(stage.name, accy_choir_pass_registrations[registration_index].name); try testing.expectEqualStrings(stage.description, accy_choir_pass_registrations[registration_index].description); try testing.expectEqualStrings(stage.pass.name, accy_choir_pass_registrations[registration_index].pass.name); if (stage.analysis_name) |name| { try testing.expectEqualStrings(name, targetAnalysisName(target_analysis_index)); target_analysis_index += 1; } } try testing.expectEqual(contract_analysis_index, contract_analysis_count); try testing.expectEqual(tensor_analysis_index, tensor_analysis_count); try testing.expectEqual(dispatch_analysis_index, dispatch_analysis_count); try testing.expectEqual(memory_analysis_index, memory_analysis_count); try testing.expectEqual(kernel_analysis_index, kernel_analysis_count); try testing.expectEqual(target_analysis_index, target_analysis_count);}test "backend preparation stage plans materialize through Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); try expectStagePlanText(allocator, contract_stages, contract_pass_plan); try expectStagePlanText(allocator, tensor_stages, tensor_pass_plan); try expectStagePlanText(allocator, dispatch_stages, dispatch_pass_plan); try expectStagePlanText(allocator, memory_stages, memory_pass_plan); try expectStagePlanText(allocator, kernel_stages, kernel_pass_plan); try expectStagePlanText(allocator, target_stages, target_pass_plan); var contract_pm = passes.PassManager.init(allocator); defer contract_pm.deinit(); try contract_pass_plan.addTo(&pass_registry, &contract_pm); try testing.expectEqual(contract_pass_count, contract_pm.root.pipeline.items.len); var tensor_pm = passes.PassManager.init(allocator); defer tensor_pm.deinit(); try tensor_pass_plan.addTo(&pass_registry, &tensor_pm); try expectTensorStagePipeline(&tensor_pm); var dispatch_pm = passes.PassManager.init(allocator); defer dispatch_pm.deinit(); try dispatch_pass_plan.addTo(&pass_registry, &dispatch_pm); try expectDispatchStagePipeline(&dispatch_pm); var memory_pm = passes.PassManager.init(allocator); defer memory_pm.deinit(); try memory_pass_plan.addTo(&pass_registry, &memory_pm); try expectMemoryStagePipeline(&memory_pm); var kernel_pm = passes.PassManager.init(allocator); defer kernel_pm.deinit(); try kernel_pass_plan.addTo(&pass_registry, &kernel_pm); try expectKernelStagePipeline(&kernel_pm); var target_pm = passes.PassManager.init(allocator); defer target_pm.deinit(); try target_pass_plan.addTo(&pass_registry, &target_pm); try expectTargetStagePipeline(&target_pm);}test "backend preparation run options expose product controls only" { inline for ( @typeInfo(BackendPreparationRunOptions).@"struct".field_names, @typeInfo(BackendPreparationRunOptions).@"struct".field_types, @typeInfo(BackendPreparationRunOptions).@"struct".field_attrs, ) |field_name, field_name_type, field_name_attrs| { const field = .{ .name = field_name, .type = field_name_type, .attrs = field_name_attrs }; try testing.expect(!std.mem.eql(u8, field.name, "pass_manager")); try testing.expect(field.type != passes.PassManagerRunOptions); }}test "target pipeline materializes from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, target_pipeline_name, &pm); try expectTargetStagePipeline(&pm); const text = try passes.formatPassManagerPipelineAlloc(allocator, &pm); defer allocator.free(text); try expectTargetStageText(text);}test "contract pipeline materializes from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, contract_pipeline_name, &pm); try testing.expectEqual(contract_pass_count, pm.root.pipeline.items.len); inline for (contract_stages, 0..) |stage, index| { switch (pm.root.pipeline.items[index]) { .pass => |pass| try testing.expectEqualStrings(stage.name, pass.name), .nested => try testing.expect(false), } }}test "tensor pipeline materializes from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, tensor_pipeline_name, &pm); try expectTensorStagePipeline(&pm);}test "tensor lowering pass options materialize from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); const pipeline_text = activation_lowering_pass_name ++ "{kernel-library=enabled}," ++ einsum_lowering_pass_name ++ "{strategy=beam,exact-state-limit=64,beam-width=8,auto-beam-width=16,kernel-library=enabled}," ++ indexing_lowering_pass_name ++ "{kernel-library=enabled,gather-thread-blocks=4,scatter-thread-blocks=5}," ++ loss_lowering_pass_name ++ "{kernel-library=enabled,row-sparse-cross-entropy-thread-blocks=4}"; var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, pipeline_text, &pm); try expectTensorStagePipeline(&pm); const text = try passes.formatPassManagerPipelineAlloc(allocator, &pm); defer allocator.free(text); try testing.expectEqualStrings(pipeline_text, text);}test "dispatch pipeline materializes from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, dispatch_pipeline_name, &pm); try expectDispatchStagePipeline(&pm);}test "memory pipeline materializes from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, memory_pipeline_name, &pm); try expectMemoryStagePipeline(&pm);}test "kernel pipeline materializes from textual Choir registry" { const allocator = testing.allocator; var ctx = try buildBackendPreparationContext(allocator, ir.Context.Limits.testing); defer ctx.deinit(allocator); var extension_registry = choir.extensions.ExtensionRegistry.init(allocator); defer extension_registry.deinit(); try extension_registry.registerPackage(&ctx, accy_choir_package_extension); var pass_registry = passes.PassRegistry.init(allocator); defer pass_registry.deinit(); try extension_registry.registerPassEntriesTo(&pass_registry); var pm = passes.PassManager.init(allocator); defer pm.deinit(); try passes.parsePassPipeline(&pass_registry, kernel_pipeline_name, &pm); try expectKernelStagePipeline(&pm);}test "runTargetPipeline exposes a direct pipeline helper" { const allocator = testing.allocator; const module = try buildSemanticAddModule(allocator, "pass_add3", &.{3}); defer module.deinit(); const choir_mod = module.choir_module; const ctx = module.context(); try runTargetPipeline(allocator, choir_mod, ctx); const body = choir_mod.getRegion(0).?.getEntryBlock().?; try testing.expect(ir.inspection.functionByNameInBlock(body, "pass_add3") != null); try testing.expect(!hasFunctionNameSuffix(body, "lowered")); try expectPreparedKernelPlan(allocator, choir_mod, ctx, 1);}test "runTargetPipelineWithOptions forwards pass manager options" { const allocator = testing.allocator; const module = try buildSemanticAddMulModule(allocator, "pass_threaded_add_mul", &.{4}); defer module.deinit(); const choir_mod = module.choir_module; const ctx = module.context(); var worker_gpa = std.heap.DebugAllocator(.{}){}; defer { const status = worker_gpa.deinit(); testing.expect(status == .ok) catch @panic("target pipeline worker allocator leaked allocations"); } try runTargetPipelineWithOptions(allocator, choir_mod, ctx, .{ .max_threads = 2, .worker_allocator = worker_gpa.allocator(), }); const body = choir_mod.getRegion(0).?.getEntryBlock().?; try testing.expect(ir.inspection.functionByNameInBlock(body, "pass_threaded_add_mul") != null); try testing.expect(!hasFunctionNameSuffix(body, "lowered")); try expectPreparedKernelPlan(allocator, choir_mod, ctx, 2);}Source: lib/accy/src/preparation/root.zig:20
pub const pipeline = @import("pipeline.zig");Source: lib/accy/src/preparation/run.zig:19
pub const BackendPreparationFailureKind = passes.PassFailureKind;Source: lib/accy/src/preparation/stage.zig:441
pub const contract_analysis_count = contract_analysis_names.len;Source: lib/accy/src/preparation/stage.zig:440
pub const contract_pass_count = contract_stages.len;Source: lib/accy/src/preparation/stage.zig:445
pub const dispatch_analysis_count = dispatch_analysis_names.len;Source: lib/accy/src/preparation/stage.zig:444
pub const dispatch_pass_count = dispatch_stages.len;Source: lib/accy/src/preparation/stage.zig:449
pub const kernel_analysis_count = kernel_analysis_names.len;Source: lib/accy/src/preparation/stage.zig:448
pub const kernel_pass_count = kernel_stages.len;Source: lib/accy/src/preparation/stage.zig:447
pub const memory_analysis_count = memory_analysis_names.len;Source: lib/accy/src/preparation/stage.zig:446
pub const memory_pass_count = memory_stages.len;Source: lib/accy/src/preparation/stage.zig:451
pub const target_analysis_count = target_analysis_names.len;Source: lib/accy/src/preparation/stage.zig:450
pub const target_pass_count = target_stages.len;Source: lib/accy/src/preparation/stage.zig:443
pub const tensor_analysis_count = tensor_analysis_names.len;Source: lib/accy/src/preparation/stage.zig:442
pub const tensor_pass_count = tensor_stages.len;Complete caller list for preparation.prepareContractJobFromSemanticModule
12 direct callers.
lib.accy.src.preparation.pipeline.test_kernel_preparation_handles_einsum_operand-local_reductions[function] — test source atlib/accy/src/preparation/pipeline.zig:724in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_handles_three_operand_einsum_contractions[function] — test source atlib/accy/src/preparation/pipeline.zig:752in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_lowers_fused_elementwise_benchmark_chain[function] — test source atlib/accy/src/preparation/pipeline.zig:702in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareContractJobFromSemanticModule_materializes_normalized_contract_job[function] — test source atlib/accy/src/preparation/pipeline.zig:486in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareDispatchJobFromTensorJob_fingerprints_dispatch_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:541in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareDispatchJobFromTensorJob_materializes_dispatch_job[function] — test source atlib/accy/src/preparation/pipeline.zig:523in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_fingerprints_kernel_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:659in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_materializes_kernel_job[function] — test source atlib/accy/src/preparation/pipeline.zig:638in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_fingerprints_memory_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:598in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_materializes_memory_job[function] — test source atlib/accy/src/preparation/pipeline.zig:578in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareTargetJobFromKernelJob_materializes_target_job[function] — test source atlib/accy/src/preparation/pipeline.zig:781in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareTensorJobFromContractJob_materializes_tensor_job[function] — test source atlib/accy/src/preparation/pipeline.zig:511in nearest public ownertiny.accy.preparation.pipeline
Complete caller list for preparation.prepareDispatchJobFromTensorJob
9 direct callers.
lib.accy.src.preparation.pipeline.test_kernel_preparation_handles_einsum_operand-local_reductions[function] — test source atlib/accy/src/preparation/pipeline.zig:724in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_handles_three_operand_einsum_contractions[function] — test source atlib/accy/src/preparation/pipeline.zig:752in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_lowers_fused_elementwise_benchmark_chain[function] — test source atlib/accy/src/preparation/pipeline.zig:702in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareDispatchJobFromTensorJob_materializes_dispatch_job[function] — test source atlib/accy/src/preparation/pipeline.zig:523in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_fingerprints_kernel_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:659in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_materializes_kernel_job[function] — test source atlib/accy/src/preparation/pipeline.zig:638in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_fingerprints_memory_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:598in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_materializes_memory_job[function] — test source atlib/accy/src/preparation/pipeline.zig:578in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareTargetJobFromKernelJob_materializes_target_job[function] — test source atlib/accy/src/preparation/pipeline.zig:781in nearest public ownertiny.accy.preparation.pipeline
Complete caller list for preparation.prepareMemoryJobFromDispatchJob
7 direct callers.
lib.accy.src.preparation.pipeline.test_kernel_preparation_handles_einsum_operand-local_reductions[function] — test source atlib/accy/src/preparation/pipeline.zig:724in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_handles_three_operand_einsum_contractions[function] — test source atlib/accy/src/preparation/pipeline.zig:752in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_lowers_fused_elementwise_benchmark_chain[function] — test source atlib/accy/src/preparation/pipeline.zig:702in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_fingerprints_kernel_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:659in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_materializes_kernel_job[function] — test source atlib/accy/src/preparation/pipeline.zig:638in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_materializes_memory_job[function] — test source atlib/accy/src/preparation/pipeline.zig:578in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareTargetJobFromKernelJob_materializes_target_job[function] — test source atlib/accy/src/preparation/pipeline.zig:781in nearest public ownertiny.accy.preparation.pipeline
Complete caller list for preparation.prepareTensorJobFromContractJob
11 direct callers.
lib.accy.src.preparation.pipeline.test_kernel_preparation_handles_einsum_operand-local_reductions[function] — test source atlib/accy/src/preparation/pipeline.zig:724in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_handles_three_operand_einsum_contractions[function] — test source atlib/accy/src/preparation/pipeline.zig:752in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_preparation_lowers_fused_elementwise_benchmark_chain[function] — test source atlib/accy/src/preparation/pipeline.zig:702in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareDispatchJobFromTensorJob_fingerprints_dispatch_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:541in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareDispatchJobFromTensorJob_materializes_dispatch_job[function] — test source atlib/accy/src/preparation/pipeline.zig:523in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_fingerprints_kernel_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:659in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareKernelJobFromMemoryJob_materializes_kernel_job[function] — test source atlib/accy/src/preparation/pipeline.zig:638in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_fingerprints_memory_analysis_product[function] — test source atlib/accy/src/preparation/pipeline.zig:598in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareMemoryJobFromDispatchJob_materializes_memory_job[function] — test source atlib/accy/src/preparation/pipeline.zig:578in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareTargetJobFromKernelJob_materializes_target_job[function] — test source atlib/accy/src/preparation/pipeline.zig:781in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_prepareTensorJobFromContractJob_materializes_tensor_job[function] — test source atlib/accy/src/preparation/pipeline.zig:511in nearest public ownertiny.accy.preparation.pipeline
Complete caller list for preparation.pipeline.buildBackendPreparationContext
10 direct callers.
lib.accy.src.preparation.pipeline.test_backend_preparation_pipelines_register_through_Choir_extensions[function] — test source atlib/accy/src/preparation/pipeline.zig:1164in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_backend_preparation_stage_plans_materialize_through_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1360in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_contract_pipeline_materializes_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1448in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_dispatch_pipeline_materializes_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1526in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_individual_Accy_Choir_passes_register_through_Choir_extensions[function] — test source atlib/accy/src/preparation/pipeline.zig:1215in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_kernel_pipeline_materializes_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1568in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_memory_pipeline_materializes_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1547in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_target_pipeline_materializes_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1424in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_tensor_lowering_pass_options_materialize_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1496in nearest public ownertiny.accy.preparation.pipelinelib.accy.src.preparation.pipeline.test_tensor_pipeline_materializes_from_textual_Choir_registry[function] — test source atlib/accy/src/preparation/pipeline.zig:1475in nearest public ownertiny.accy.preparation.pipeline
Audit
| Definitions | 182 |
|---|---|
| Public names | 356 |
| Members | 100 |
| Version | 26.7.0 |
| Revision | daab053ee433 |