Skip to documentation
SLOP

tiny.accy.preparation.pipeline

Reference tiny.accy preparation pipeline

Defined in preparation.

API (204)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

No direct callersNo direct callspreparationpipeline
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/accy/src/preparation/execution.zig:63

zig
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

zig
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

zig
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

zig
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

zig
pub const PipelineError = error{    PassFailed,};

Source: lib/accy/src/preparation/execution.zig:135

zig
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

zig
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

zig
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

zig
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

zig
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

zig
/// 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

zig
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

zig
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

zig
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

zig
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

zig
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

zig
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

zig
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);    }};
Called byCallsNo direct callerschoir.ContractJobdeinitpreparation.ContractPreparationResultdeinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerschoir.DispatchJobdeinitpreparation.DispatchPreparationResultdeinit
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerschoir.TensorJobdeinitpreparation.TensorPreparationResultdeinit
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:192

zig
pub fn prepareContractJobFromSemanticModule(    allocator: std.mem.Allocator,    module: *semantic.SemanticModule,    options: BackendPreparationRunOptions,) !*contract.ContractJob {    const result = try prepareContractJobFromSemanticModuleWithRun(        allocator,        module,        options,    );    return result.module;}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles eins...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles thre...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation lowers fused...test sourcelib.accy.src.preparation.pipelinetest: prepareContractJobFromSemanticM...test sourcelib.accy.src.preparation.pipelinetest: prepareDispatchJobFromTensorJob...+7 morepreparationprepareContractJobFromSemanticModuleW...preparationprepareContractJobFromSemanticModule
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:270

zig
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,    };}
Called byCallspreparationprepareContractJobFromSemanticModuleprivate sourcelib.accy.src.preparation.pipelineprepareDispatchResultForContinuationT...private sourcelib.accy.src.preparation.preparedprepareOwnedSemanticModuleForBackendchoir.ContractJobinitprivate sourcelib.accy.src.preparation.executioncountOperationTreeprivate sourcelib.accy.src.preparation.executionnsBetweenprivate sourcelib.accy.src.preparation.executionpreparationPassFailedpreparation.recipeconfigurepreparation.reciperunOptionspreparationprepareContractJobFromSemanticModuleW...
Static calls · unresolved targets: 0 · external targets: 12.

Source: lib/accy/src/preparation/execution.zig:218

zig
pub fn prepareDispatchJobFromTensorJob(    allocator: std.mem.Allocator,    module: *tensor.TensorJob,    options: BackendPreparationRunOptions,) !*dispatch.DispatchJob {    const result = try prepareDispatchJobFromTensorJobWithRun(        allocator,        module,        options,    );    return result.module;}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles eins...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles thre...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation lowers fused...test sourcelib.accy.src.preparation.pipelinetest: prepareDispatchJobFromTensorJob...test sourcelib.accy.src.preparation.pipelinetest: prepareKernelJobFromMemoryJob f...+4 morepreparationprepareDispatchJobFromTensorJobWithRunpreparationprepareDispatchJobFromTensorJob
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:355

zig
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,    };}
Called byCallspreparationprepareDispatchJobFromTensorJobprivate sourcelib.accy.src.preparation.pipelineprepareDispatchResultForContinuationT...test sourcelib.accy.src.preparation.pipelinetest: prepareDispatchJobFromTensorJob...preparationprepareBackendJobFromTensorPreparatio...choir.DispatchJobinitprivate sourcelib.accy.src.preparation.executionnsBetweenprivate sourcelib.accy.src.preparation.executionpreparationPassFailedpreparation.recipeconfigurepreparation.reciperunOptionspreparationprepareDispatchJobFromTensorJobWithRun
Static calls · unresolved targets: 0 · external targets: 10.

Source: lib/accy/src/preparation/execution.zig:244

zig
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;}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles eins...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles thre...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation lowers fused...test sourcelib.accy.src.preparation.pipelinetest: prepareKernelJobFromMemoryJob m...test sourcelib.accy.src.preparation.pipelinetest: prepareTargetJobFromKernelJob m...preparationprepareKernelJobFromMemoryJobWithRunpreparationprepareKernelJobFromMemoryJob
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:437

zig
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,    };}
Called byCallspreparationprepareKernelJobFromMemoryJobprivate sourcelib.accy.src.preparation.pipelineprepareKernelResultForContinuationTesttest sourcelib.accy.src.preparation.pipelinetest: prepareKernelJobFromMemoryJob f...preparationprepareBackendJobFromMemoryPreparatio...private sourcelib.accy.src.preparation.executionnsBetweenprivate sourcelib.accy.src.preparation.executionpreparationPassFailedpreparation.recipeapplyTargetOptionspreparation.recipeconfigurepreparation.reciperunOptionspreparationprepareKernelJobFromMemoryJobWithRun
Static calls · unresolved targets: 0 · external targets: 11.

Source: lib/accy/src/preparation/execution.zig:231

zig
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;}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles eins...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles thre...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation lowers fused...test sourcelib.accy.src.preparation.pipelinetest: prepareKernelJobFromMemoryJob f...test sourcelib.accy.src.preparation.pipelinetest: prepareKernelJobFromMemoryJob m...+2 morepreparationprepareMemoryJobFromDispatchJobWithRunpreparationprepareMemoryJobFromDispatchJob
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:396

zig
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,    };}
Called byCallspreparationprepareMemoryJobFromDispatchJobprivate sourcelib.accy.src.preparation.pipelineprepareMemoryResultForContinuationTesttest sourcelib.accy.src.preparation.pipelinetest: prepareMemoryJobFromDispatchJob...preparationprepareBackendJobFromDispatchPreparat...private sourcelib.accy.src.preparation.executionnsBetweenprivate sourcelib.accy.src.preparation.executionpreparationPassFailedpreparation.recipeconfigurepreparation.reciperunOptionspreparationprepareMemoryJobFromDispatchJobWithRun
Static calls · unresolved targets: 0 · external targets: 11.

Source: lib/accy/src/preparation/execution.zig:257

zig
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;}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: prepareTargetJobFromKernelJob m...preparationprepareTargetJobFromKernelJobWithRunpreparationprepareTargetJobFromKernelJob
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:479

zig
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,    };}
Called byCallspreparationprepareTargetJobFromKernelJobprivate sourcelib.accy.src.preparation.pipelineprepareTargetResultForContinuationTestpreparationprepareBackendJobFromKernelPreparatio...private sourcelib.accy.src.preparation.executionprepareTargetProductFromKernelJobWith...preparationprepareTargetJobFromKernelJobWithRun
Static calls · unresolved targets: 0 · external targets: 3.

Source: lib/accy/src/preparation/execution.zig:205

zig
pub fn prepareTensorJobFromContractJob(    allocator: std.mem.Allocator,    module: *contract.ContractJob,    options: BackendPreparationRunOptions,) !*tensor.TensorJob {    const result = try prepareTensorJobFromContractJobWithRun(        allocator,        module,        options,    );    return result.module;}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles eins...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation handles thre...test sourcelib.accy.src.preparation.pipelinetest: kernel preparation lowers fused...test sourcelib.accy.src.preparation.pipelinetest: prepareDispatchJobFromTensorJob...test sourcelib.accy.src.preparation.pipelinetest: prepareDispatchJobFromTensorJob...+6 morepreparationprepareTensorJobFromContractJobWithRunpreparationprepareTensorJobFromContractJob
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:315

zig
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),    };}
Called byCallspreparationprepareTensorJobFromContractJobprivate sourcelib.accy.src.preparation.pipelineprepareDispatchResultForContinuationT...preparationprepareBackendJobFromContractJobpreparationprepareBackendJobFromContractPreparat...choir.TensorJobinitprivate sourcelib.accy.src.preparation.executionnsBetweenprivate sourcelib.accy.src.preparation.executionpreparationPassFailedpreparation.recipeconfigurepreparation.reciperunOptionspreparationprepareTensorJobFromContractJobWithRun
Static calls · unresolved targets: 0 · external targets: 11.

Source: lib/accy/src/preparation/execution.zig:162

zig
pub fn runTargetPipeline(    allocator: std.mem.Allocator,    choir_module: *ir.Operation,    ctx: *ir.Context,) !void {    return try runTargetPipelineWithOptions(allocator, choir_module, ctx, .{});}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: runTargetPipeline exposes a dir...preparation.pipelinerunTargetPipelineWithOptionspreparationrunTargetPipeline
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/execution.zig:179

zig
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);}
Called byCallspreparation.pipelinerunTargetPipelineWithOptionsprivate sourcelib.accy.src.preparation.executionpassFailedpreparation.recipeconfigurepreparationrunTargetPipelineWithDiagnostics
Static calls · unresolved targets: 0 · external targets: 3.

Source: lib/accy/src/preparation/execution.zig:170

zig
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);}
Called byCallspreparationrunTargetPipelinetest sourcelib.accy.src.preparation.pipelinetest: runTargetPipelineWithOptions fo...preparationrunTargetPipelineWithDiagnosticspreparation.pipelinerunTargetPipelineWithOptions
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/loss.zig:27

zig
pub const loss_lowering_pass_name = "accy-choir-loss-lower";
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: backend preparation pipelines r...test sourcelib.accy.src.preparation.pipelinetest: backend preparation stage plans...test sourcelib.accy.src.preparation.pipelinetest: contract pipeline materializes ...test sourcelib.accy.src.preparation.pipelinetest: dispatch pipeline materializes ...test sourcelib.accy.src.preparation.pipelinetest: individual Accy Choir passes re...+5 morechoir.semanticbuildSemanticContextpreparation.pipelinebuildBackendPreparationContext
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callerspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobcopyGeneratedKernelSummaries
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobgeneratedKernelCount
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobgeneratedKernelProgram
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobgeneratedKernelProgramForWork
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobgeneratedKernelSummary
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobgeneratedKernelSummaryForWork
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallspreparation.BackendPreparedJobcopyGeneratedKernelSummariespreparation.BackendPreparedJobgeneratedKernelCountpreparation.BackendPreparedJobgeneratedKernelProgrampreparation.BackendPreparedJobgeneratedKernelProgramForWorkpreparation.BackendPreparedJobgeneratedKernelSummarypreparation.BackendPreparedJobgeneratedKernelSummaryForWorkpreparation.BackendPreparedJobtargetModulepreparation.BackendPreparedJobkernelizationProduct
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspreparation.BackendPreparedJobkernelizationProductpreparation.BackendPreparedJobtargetModule
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/prepared.zig:142

zig
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,    );}
Called byCallsNo direct callerspreparationprepareTensorJobFromContractJobWithRunpreparationprepareBackendJobFromTensorPreparatio...preparationprepareBackendJobFromContractJob
Static calls · unresolved targets: 1 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:176

zig
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,    );}
Called byCallsprivate sourcelib.accy.src.preparation.preparedprepareOwnedSemanticModuleForBackendpreparationprepareTensorJobFromContractJobWithRunpreparationprepareBackendJobFromTensorPreparatio...preparationprepareBackendJobFromContractPreparat...
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:244

zig
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,    );}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: prepareBackendJobFromDispatchPr...preparationprepareBackendJobFromTensorPreparatio...preparationprepareMemoryJobFromDispatchJobWithRunpreparationprepareBackendJobFromMemoryPreparatio...preparationprepareBackendJobFromDispatchPreparat...
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:334

zig
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,    );}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: prepareBackendJobFromKernelPrep...preparationprepareBackendJobFromMemoryPreparatio...preparationprepareTargetJobFromKernelJobWithRunpreparationprepareBackendJobFromTargetPreparatio...preparationprepareBackendJobFromKernelPreparatio...
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:286

zig
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,    );}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: prepareBackendJobFromMemoryPrep...preparationprepareBackendJobFromDispatchPreparat...preparationprepareKernelJobFromMemoryJobWithRunpreparationprepareBackendJobFromKernelPreparatio...preparationprepareBackendJobFromMemoryPreparatio...
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:129

zig
pub fn prepareBackendJobFromSemanticModule(    allocator: std.mem.Allocator,    module: *semantic.SemanticModule,    options: BackendPreparationRunOptions,) !BackendPreparedJob {    return try prepareOwnedSemanticModuleForBackend(        allocator,        module,        options,        options.now(),    );}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: backend preparation target prof...test sourcelib.accy.src.preparation.pipelinetest: prepareBackendJobFromSemanticMo...preparationrunBackendPreparationPipelineFromSema...private sourcelib.accy.src.preparation.preparedprepareOwnedSemanticModuleForBackendpreparationprepareBackendJobFromSemanticModule
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:388

zig
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,    );}
Called byCallstest sourcelib.accy.src.preparation.pipelinetest: prepareBackendJobFromTargetPrep...preparationprepareBackendJobFromKernelPreparatio...private sourcelib.accy.src.preparation.preparedprepareOwnedTargetJobpreparationprepareBackendJobFromTargetPreparatio...
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:208

zig
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,    );}
Called byCallspreparationprepareBackendJobFromContractJobpreparationprepareBackendJobFromContractPreparat...preparationprepareDispatchJobFromTensorJobWithRunpreparationprepareBackendJobFromDispatchPreparat...preparationprepareBackendJobFromTensorPreparatio...
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/prepared.zig:119

zig
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;}
Called byCallsNo direct callerspreparationprepareBackendJobFromSemanticModulepreparationrunBackendPreparationPipelineFromSema...
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallspreparation.pipeline.BackendPreparedModuleretainprivate sourcelib.accy.src.preparation.product.BackendPrepa...requirePredecessorpreparation.pipeline.BackendPreparedModulecreate
Static calls · unresolved targets: 0 · external targets: 8.
Called byCallsNo direct callersprivate sourcelib.accy.src.preparation.productgraphFromKeyspreparation.pipeline.BackendPreparedModuleproductGraph
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.pipeline.BackendPreparedModulecreatepreparation.pipeline.BackendPreparedModuleretain
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callerspreparation.BackendPreparationFailuredeinitprivate sourcelib.accy.src.preparation.run.BackendPreparati...dupeOptionalpreparation.BackendPreparationFailurecapture
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callspreparation.BackendPreparationFailurecapturepreparation.BackendPreparationFailuredeinit
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/schedule/pass.zig:17

zig
pub const schedule_planning_pass_name = "accy-choir-plan-schedule";

Source: lib/accy/src/preparation/shape/pass.zig:13

zig
pub const shape_layout_pass_name = "accy-choir-shape-layout-propagate";

Source: lib/accy/src/preparation/stage.zig:427

zig
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

zig
pub const accy_choir_pass_registrations = allPassRegistrations();

Source: lib/accy/src/preparation/stage.zig:86

zig
pub fn activationLoweringPass() passes.Pass {    return activation_lowering.activationLoweringPass();}

Source: lib/accy/src/preparation/stage.zig:90

zig
pub fn activationLoweringPassWithOptions(options: *const activation_lowering.Options) passes.Pass {    return activation_lowering.activationLoweringPassWithOptions(options);}
Called byCallsNo direct callspreparationaddTensorPipelineWithOptionspreparationactivationLoweringPassWithOptions
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/stage.zig:509

zig
pub fn addContractPipeline(pm: *passes.PassManager) !void {    try contract_pipeline_registration.addTo(&pm.root);}

Source: lib/accy/src/preparation/stage.zig:524

zig
pub fn addDispatchPipeline(pm: *passes.PassManager) !void {    try dispatch_pipeline_registration.addTo(&pm.root);}

Source: lib/accy/src/preparation/stage.zig:532

zig
pub fn addKernelPipeline(pm: *passes.PassManager) !void {    try kernel_pipeline_registration.addTo(&pm.root);}

Source: lib/accy/src/preparation/stage.zig:528

zig
pub fn addMemoryPipeline(pm: *passes.PassManager) !void {    try memory_pipeline_registration.addTo(&pm.root);}

Source: lib/accy/src/preparation/stage.zig:536

zig
pub fn addTargetPipeline(pm: *passes.PassManager) !void {    try target_pipeline_registration.addTo(&pm.root);}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: target pipeline validates kerne...preparationaddTargetPipeline
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/stage.zig:513

zig
pub fn addTensorPipeline(pm: *passes.PassManager) !void {    try tensor_pipeline_registration.addTo(&pm.root);}

Source: lib/accy/src/preparation/stage.zig:517

zig
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));}
Called byCallsNo direct callerspreparationactivationLoweringPassWithOptionspreparationeinsumLoweringPassWithOptionspreparationindexingLoweringPassWithOptionspreparationlossLoweringPassWithOptionspreparationaddTensorPipelineWithOptions
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/stage.zig:58

zig
pub fn backendLegalizationPass() passes.Pass {    return backend_legalization.backendLegalizationPass();}

Source: lib/accy/src/preparation/stage.zig:62

zig
pub fn bufferizationPlanningPass() passes.Pass {    return bufferization.bufferizationPlanningPass();}

Source: lib/accy/src/preparation/stage.zig:66

zig
pub fn canonicalizationPass() passes.Pass {    return canonicalization.canonicalizationPass();}
Called byCallsNo direct callerspreparation.canonicalizationcanonicalizationPasspreparationcanonicalizationPass
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:74

zig
pub fn constantFoldingPass() passes.Pass {    return constant_folding.constantFoldingPass();}

Source: lib/accy/src/preparation/stage.zig:457

zig
pub fn contractAnalysisName(index: usize) []const u8 {    return contract_analysis_names[index];}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationcontractAnalysisName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:453

zig
pub fn contractPassName(index: usize) []const u8 {    return contract_stages[index].name;}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationcontractPassName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:420

zig
pub const contract_pass_plan = passes.PassPlan{ .steps = &contract_plan_steps };

Source: lib/accy/src/preparation/stage.zig:405

zig
pub const contract_pass_registrations = stagePassRegistrations(contract_stages);

Source: lib/accy/src/preparation/stage.zig:162

zig
pub const contract_pipeline_description =    "Normalize semantic Accy Choir into the backend contract product";

Source: lib/accy/src/preparation/stage.zig:161

zig
pub const contract_pipeline_name = "accy-choir-contract";

Source: lib/accy/src/preparation/stage.zig:369

zig
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

zig
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

zig
pub fn dispatchAnalysisName(index: usize) []const u8 {    return dispatch_analysis_names[index];}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationdispatchAnalysisName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:477

zig
pub fn dispatchPassName(index: usize) []const u8 {    return dispatch_stages[index].name;}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationdispatchPassName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:422

zig
pub const dispatch_pass_plan = passes.PassPlan{ .steps = &dispatch_plan_steps };

Source: lib/accy/src/preparation/stage.zig:407

zig
pub const dispatch_pass_registrations = stagePassRegistrations(dispatch_stages);

Source: lib/accy/src/preparation/stage.zig:168

zig
pub const dispatch_pipeline_description =    "Plan Accy Choir dispatch groups and schedules before memory preparation";

Source: lib/accy/src/preparation/stage.zig:167

zig
pub const dispatch_pipeline_name = "accy-choir-dispatch";

Source: lib/accy/src/preparation/stage.zig:381

zig
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

zig
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

zig
pub fn dtypeLegalizationPass() passes.Pass {    return dtype_legalization.dtypeLegalizationPass();}

Source: lib/accy/src/preparation/stage.zig:94

zig
pub fn einsumLoweringPass() passes.Pass {    return einsum_lowering.einsumLoweringPass();}

Source: lib/accy/src/preparation/stage.zig:98

zig
pub fn einsumLoweringPassWithOptions(options: *const einsum_lowering.Options) passes.Pass {    return einsum_lowering.einsumLoweringPassWithOptions(options);}
Called byCallsNo direct callspreparationaddTensorPipelineWithOptionspreparationeinsumLoweringPassWithOptions
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/stage.zig:118

zig
pub fn fusionPlanningPass() passes.Pass {    return fusion.fusionPlanningPass();}

Source: lib/accy/src/preparation/stage.zig:102

zig
pub fn indexingLoweringPass() passes.Pass {    return indexing_lowering.indexingLoweringPass();}

Source: lib/accy/src/preparation/stage.zig:106

zig
pub fn indexingLoweringPassWithOptions(options: *const indexing_lowering.Options) passes.Pass {    return indexing_lowering.indexingLoweringPassWithOptions(options);}
Called byCallsNo direct callspreparationaddTensorPipelineWithOptionspreparationindexingLoweringPassWithOptions
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/stage.zig:497

zig
pub fn kernelAnalysisName(index: usize) []const u8 {    return kernel_analysis_names[index];}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationkernelAnalysisName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:126

zig
pub fn kernelOutliningPlanningPass() passes.Pass {    return kernel_outlining.kernelOutliningPlanningPass();}

Source: lib/accy/src/preparation/stage.zig:493

zig
pub fn kernelPassName(index: usize) []const u8 {    return kernel_stages[index].name;}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationkernelPassName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:424

zig
pub const kernel_pass_plan = passes.PassPlan{ .steps = &kernel_plan_steps };

Source: lib/accy/src/preparation/stage.zig:409

zig
pub const kernel_pass_registrations = stagePassRegistrations(kernel_stages);

Source: lib/accy/src/preparation/stage.zig:174

zig
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

zig
pub const kernel_pipeline_name = "accy-choir-kernel";

Source: lib/accy/src/preparation/stage.zig:393

zig
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

zig
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

zig
pub fn kernelizationPass() passes.Pass {    return kernelization.kernelizationPass();}

Source: lib/accy/src/preparation/stage.zig:138

zig
pub fn layoutPlanningPass() passes.Pass {    return layout_planning.layoutPlanningPass();}

Source: lib/accy/src/preparation/stage.zig:110

zig
pub fn lossLoweringPass() passes.Pass {    return loss_lowering.lossLoweringPass();}

Source: lib/accy/src/preparation/stage.zig:114

zig
pub fn lossLoweringPassWithOptions(options: *const loss_lowering.Options) passes.Pass {    return loss_lowering.lossLoweringPassWithOptions(options);}
Called byCallsNo direct callspreparationaddTensorPipelineWithOptionspreparationlossLoweringPassWithOptions
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/preparation/stage.zig:489

zig
pub fn memoryAnalysisName(index: usize) []const u8 {    return memory_analysis_names[index];}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationmemoryAnalysisName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:485

zig
pub fn memoryPassName(index: usize) []const u8 {    return memory_stages[index].name;}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationmemoryPassName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:134

zig
pub fn memorySpacePlanningPass() passes.Pass {    return memory_space.memorySpacePlanningPass();}

Source: lib/accy/src/preparation/stage.zig:423

zig
pub const memory_pass_plan = passes.PassPlan{ .steps = &memory_plan_steps };

Source: lib/accy/src/preparation/stage.zig:408

zig
pub const memory_pass_registrations = stagePassRegistrations(memory_stages);

Source: lib/accy/src/preparation/stage.zig:171

zig
pub const memory_pipeline_description =    "Plan Accy Choir buffers, memory spaces, and layouts before kernel preparation";

Source: lib/accy/src/preparation/stage.zig:170

zig
pub const memory_pipeline_name = "accy-choir-memory";

Source: lib/accy/src/preparation/stage.zig:387

zig
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

zig
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

zig
pub fn schedulePlanningPass() passes.Pass {    return schedule_planning.schedulePlanningPass();}

Source: lib/accy/src/preparation/stage.zig:70

zig
pub fn shapeLayoutPropagationPass() passes.Pass {    return shape_analysis.shapeLayoutPropagationPass();}

Source: lib/accy/src/preparation/stage.zig:505

zig
pub fn targetAnalysisName(index: usize) []const u8 {    return target_analysis_names[index];}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationtargetAnalysisName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:501

zig
pub fn targetPassName(index: usize) []const u8 {    return target_stages[index].name;}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationtargetPassName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:425

zig
pub const target_pass_plan = passes.PassPlan{ .steps = &target_plan_steps };

Source: lib/accy/src/preparation/stage.zig:410

zig
pub const target_pass_registrations = stagePassRegistrations(target_stages);

Source: lib/accy/src/preparation/stage.zig:177

zig
pub const target_pipeline_description =    "Legalize Accy Choir kernels for the selected backend target";

Source: lib/accy/src/preparation/stage.zig:176

zig
pub const target_pipeline_name = "accy-choir-target";

Source: lib/accy/src/preparation/stage.zig:399

zig
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

zig
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

zig
pub fn tensorAnalysisName(index: usize) []const u8 {    if (comptime tensor_analysis_names.len == 0) {        unreachable;    } else {        return tensor_analysis_names[index];    }}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationtensorAnalysisName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:461

zig
pub fn tensorPassName(index: usize) []const u8 {    if (comptime tensor_stages.len == 0) {        unreachable;    } else {        return tensor_stages[index].name;    }}
Called byCallsNo direct callstest sourcelib.accy.src.preparation.pipelinetest: backend preparation stage table...preparationtensorPassName
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:78

zig
pub fn tensorSaturationPass() passes.Pass {    return saturation.tensorSaturationPass();}
Called byCallsNo direct callerspreparation.saturationtensorSaturationPasspreparationtensorSaturationPass
Static calls · unresolved targets: 0 · external targets: 0.

Source: lib/accy/src/preparation/stage.zig:421

zig
pub const tensor_pass_plan = passes.PassPlan{ .steps = &tensor_plan_steps };

Source: lib/accy/src/preparation/stage.zig:406

zig
pub const tensor_pass_registrations = stagePassRegistrations(tensor_stages);

Source: lib/accy/src/preparation/stage.zig:165

zig
pub const tensor_pipeline_description =    "Materialize tensor-level Accy Choir before dispatch grouping";

Source: lib/accy/src/preparation/stage.zig:164

zig
pub const tensor_pipeline_name = "accy-choir-tensor";

Source: lib/accy/src/preparation/stage.zig:375

zig
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

zig
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

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

zig
pub const pipeline = @import("pipeline.zig");

Source: lib/accy/src/preparation/run.zig:19

zig
pub const BackendPreparationFailureKind = passes.PassFailureKind;

Source: lib/accy/src/preparation/stage.zig:441

zig
pub const contract_analysis_count = contract_analysis_names.len;

Source: lib/accy/src/preparation/stage.zig:440

zig
pub const contract_pass_count = contract_stages.len;

Source: lib/accy/src/preparation/stage.zig:445

zig
pub const dispatch_analysis_count = dispatch_analysis_names.len;

Source: lib/accy/src/preparation/stage.zig:444

zig
pub const dispatch_pass_count = dispatch_stages.len;

Source: lib/accy/src/preparation/stage.zig:449

zig
pub const kernel_analysis_count = kernel_analysis_names.len;

Source: lib/accy/src/preparation/stage.zig:448

zig
pub const kernel_pass_count = kernel_stages.len;

Source: lib/accy/src/preparation/stage.zig:447

zig
pub const memory_analysis_count = memory_analysis_names.len;

Source: lib/accy/src/preparation/stage.zig:446

zig
pub const memory_pass_count = memory_stages.len;

Source: lib/accy/src/preparation/stage.zig:451

zig
pub const target_analysis_count = target_analysis_names.len;

Source: lib/accy/src/preparation/stage.zig:450

zig
pub const target_pass_count = target_stages.len;

Source: lib/accy/src/preparation/stage.zig:443

zig
pub const tensor_analysis_count = tensor_analysis_names.len;

Source: lib/accy/src/preparation/stage.zig:442

zig
pub const tensor_pass_count = tensor_stages.len;

Complete caller list for preparation.prepareContractJobFromSemanticModule

12 direct callers.

Complete caller list for preparation.prepareDispatchJobFromTensorJob

9 direct callers.

Complete caller list for preparation.prepareMemoryJobFromDispatchJob

7 direct callers.

Complete caller list for preparation.prepareTensorJobFromContractJob

11 direct callers.

Complete caller list for preparation.pipeline.buildBackendPreparationContext

10 direct callers.

Audit

Definitions182
Public names356
Members100
Version26.7.0
Revisiondaab053ee433