Skip to documentation
SLOP

tiny.accy.artifact

Reference tiny.accy artifact

Defined in tiny.accy.

API (78)

Actions

Public operations.

Types and contracts

Public types and contracts.

Namespaces

Public namespaces.

Values and defaults

Public values and defaults.

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

Source

Source: lib/accy/src/artifact/input.zig:27

zig
/// Short-lived compile state rebuilt from the dispatch, memory, kernel, and/// target results of one finished preparation: the schedule plan, the buffer,/// memory-space and layout plans, the kernel outlines, the generated kernel/// programs, and the target settings. A compiler of device code uses this to/// recover the plans of a finished compile inside memory the caller provides./// `create` allocates the job and all of its contents inside the caller's/// `workspace`, and a workspace that runs out gives `error.WorkExhausted`. The/// job requires each stage record to match: the target record must hold exactly/// one program root (`error.InvalidStageRoots`), and the dispatch, memory, and/// kernel records must decode to that same program/// (`error.IncompatibleStageImages`). The job keeps no pointer to the prepared/// module, no stage-record key, and no mutable semantic module. The job works/// out each kernel's legality for the target again from the restored plans and/// keeps that result with the rest. `destroy` releases the job's contents, and/// the workspace itself stays with the caller.pub const InputJob = struct {    fixed: fixed.Tracked,    context: ?*ir.Context = null,    decoded: ?choir.bytecode.DecodedModule = null,    target: ?records.codec.Decoded(records.target.Record) = null,    schedule: ?preparation.schedule.SchedulePlanAnalysis = null,    buffers: ?preparation.bufferization.BufferPlanAnalysis = null,    spaces: ?preparation.memory.MemorySpacePlanAnalysis = null,    layouts: ?preparation.layout.LayoutPlanAnalysis = null,    outlines: ?preparation.kernelization.product.KernelOutlinePlanAnalysis = null,    generated: ?preparation.kernelization.KernelizationAnalysis = null,    legal: ?preparation.backend.BackendLegalizationAnalysis = null,    pub fn create(        workspace: []u8,        prepared: *const Prepared,        comptime configuration: Configuration,    ) !*InputJob {        return initialize(workspace, prepared, configuration) catch |err| {            return if (err == error.OutOfMemory) error.WorkExhausted else err;        };    }    fn initialize(        workspace: []u8,        prepared: *const Prepared,        comptime configuration: Configuration,    ) !*InputJob {        var initial = fixed.Tracked.init(workspace);        const self = try initial.allocator().create(InputJob);        self.* = .{ .fixed = initial };        errdefer self.destroy();        const allocator = self.fixed.allocator();        self.context = try ir.Context.create(allocator, configuration.context);        const context = self.context.?;        (try choir.product.recipe.decode(prepared.stage(.target).inputs().policy)).restore(context);        try configuration.register(context);        const image = try open(prepared, allocator, .target, configuration);        defer image.destroy();        const root = image.root(0) orelse return error.InvalidStageRoots;        if (image.root(1) != null) return error.InvalidStageRoots;        self.decoded = try choir.bytecode.decodeModule(allocator, context, root.bytes);        self.target = try records.codec.decode(allocator, records.target.Record, .target, image.stage());        clearTargetAttributes(self.decoded.?.module);        inline for (.{ .dispatch, .memory, .kernel }) |stage| {            try self.requireSameProgram(prepared, stage, configuration);        }        var references = try References.init(allocator, self.decoded.?.module, configuration.image.entities);        defer references.deinit();        try self.restoreDispatch(prepared, &references, configuration);        try self.restoreMemory(prepared, &references, configuration);        try self.restoreKernel(prepared, &references, configuration);        try self.restoreTarget(configuration);        return self;    }    pub fn destroy(self: *InputJob) void {        const allocator = self.fixed.allocator();        if (self.legal) |*value| value.deinit();        if (self.generated) |*value| value.deinit();        if (self.outlines) |*value| value.deinit();        if (self.layouts) |*value| value.deinit();        if (self.spaces) |*value| value.deinit();        if (self.buffers) |*value| value.deinit();        if (self.schedule) |*value| value.deinit();        if (self.target) |*value| value.deinit();        if (self.decoded) |*value| value.deinit();        if (self.context) |context| {            context.deinit(allocator);            allocator.destroy(context);        }    }    /// Returns pointers into this job's own fields: the program root, the    /// target profile, and each restored plan. A caller passes the returned    /// plans to the artifact compiler. The pointers stay valid until `destroy`    /// runs or the caller writes over the workspace.    pub fn plans(self: *const InputJob) plan.PlanInputs {        return .{            .root = self.decoded.?.module,            .profile = self.target.?.value.profile,            .schedule = &self.schedule.?,            .buffers = &self.buffers.?,            .spaces = &self.spaces.?,            .layouts = &self.layouts.?,            .outlines = &self.outlines.?,            .generated = &self.generated.?,            .legal = &self.legal.?,            .target = &self.target.?.value,        };    }    fn requireSameProgram(        self: *InputJob,        prepared: *const Prepared,        comptime stage: publication.Stage,        comptime configuration: Configuration,    ) !void {        const allocator = self.fixed.allocator();        const image = try open(prepared, allocator, stage, configuration);        defer image.destroy();        if (image.root(1) != null) return error.InvalidStageRoots;        var context = try ir.Context.init(allocator, configuration.context);        defer context.deinit(allocator);        (try choir.product.recipe.decode(prepared.stage(stage).inputs().policy)).restore(&context);        try configuration.register(&context);        const root = image.root(0) orelse return error.InvalidStageRoots;        var decoded = try choir.bytecode.decodeModule(allocator, &context, root.bytes);        defer decoded.deinit();        clearTargetAttributes(decoded.module);        choir.bytecode.qualification.compare(allocator, decoded.module, self.decoded.?.module, decoded.resources, self.decoded.?.resources, configuration.codec) catch |err| {            return if (err == error.UnencodableProduct) error.IncompatibleStageImages else err;        };    }    fn restoreDispatch(self: *InputJob, prepared: *const Prepared, refs: *const References, comptime configuration: Configuration) !void {        const allocator = self.fixed.allocator();        const image = try open(prepared, allocator, .dispatch, configuration);        defer image.destroy();        var record = try records.codec.decode(allocator, records.dispatch.Record, .dispatch, image.stage());        defer record.deinit();        self.schedule = preparation.schedule.SchedulePlanAnalysis.init(allocator);        const output = &self.schedule.?;        copyCounters(output, record.value.schedule);        for (record.value.schedule.work_items, 0..) |item, index| {            const value = try project(preparation.schedule.ScheduleWorkItem, allocator, item, refs);            try output.work_items.append(allocator, value);            try output.root_to_item.putNoClobber(value.root, index);        }    }    fn restoreMemory(self: *InputJob, prepared: *const Prepared, refs: *const References, comptime configuration: Configuration) !void {        const allocator = self.fixed.allocator();        const image = try open(prepared, allocator, .memory, configuration);        defer image.destroy();        var record = try records.codec.decode(allocator, records.memory.Record, .memory, image.stage());        defer record.deinit();        self.buffers = preparation.bufferization.BufferPlanAnalysis.init(allocator);        self.spaces = preparation.memory.MemorySpacePlanAnalysis.init(allocator);        self.layouts = preparation.layout.LayoutPlanAnalysis.init(allocator);        const buffers = &self.buffers.?;        const spaces = &self.spaces.?;        const layouts = &self.layouts.?;        copyCounters(buffers, record.value.buffers);        copyCounters(spaces, record.value.spaces);        copyCounters(layouts, record.value.layouts);        for (record.value.buffers.slots) |item| {            const value = try project(preparation.bufferization.BufferSlot, allocator, item, refs);            try buffers.slots.append(allocator, value);        }        for (record.value.bindings) |binding| {            const value = try refs.value(binding.value);            try buffers.value_to_slot.putNoClobber(value, binding.slot_id);        }        for (record.value.buffers.elisions, 0..) |item, index| {            const value = try project(preparation.bufferization.FusionElision, allocator, item, refs);            try buffers.elisions.append(allocator, value);            try buffers.value_to_elision.putNoClobber(value.value, index);        }        for (record.value.spaces.assignments, 0..) |item, index| {            const value = try project(preparation.memory.MemorySpaceAssignment, allocator, item, refs);            try spaces.assignments.append(allocator, value);            try spaces.slot_to_assignment.putNoClobber(value.slot_id, index);        }        for (record.value.layouts.assignments, 0..) |item, index| {            const value = try project(preparation.layout.LayoutAssignment, allocator, item, refs);            try layouts.assignments.append(allocator, value);            try layouts.slot_to_assignment.putNoClobber(value.slot_id, index);        }    }    fn restoreKernel(self: *InputJob, prepared: *const Prepared, refs: *const References, comptime configuration: Configuration) !void {        const allocator = self.fixed.allocator();        const image = try open(prepared, allocator, .kernel, configuration);        defer image.destroy();        var record = try records.codec.decode(allocator, records.kernel.Record, .kernel, image.stage());        defer record.deinit();        self.outlines = preparation.kernelization.product.KernelOutlinePlanAnalysis.init(allocator);        const output = &self.outlines.?;        copyCounters(output, record.value.outlines);        for (record.value.outlines.kernels) |item| {            const value = try project(preparation.kernelization.product.KernelOutline, allocator, item, refs);            try output.kernels.append(allocator, value);            try output.work_to_kernel.putNoClobber(value.work_item_id, value.id);        }    }    fn restoreTarget(self: *InputJob, comptime configuration: Configuration) !void {        const allocator = self.fixed.allocator();        const source = self.target.?.value;        const context = self.context.?;        const root = self.decoded.?.module;        if (source.profile) |profile| try preparation.setBackendTargetProfile(context, root, profile);        if (source.generated_scan_schedules) |value| {            try root.setAttr(preparation.target.generated_scan_schedule_attr_name, try context.getStringAttr(value));        }        if (source.generated_row_pipeline_schedules) |value| {            try root.setAttr(preparation.target.generated_row_pipeline_schedule_attr_name, try context.getStringAttr(value));        }        self.generated = try preparation.kernelization.KernelizationAnalysis.init(allocator, configuration.context);        const output = &self.generated.?;        try output.reserveKernelCapacity(source.kernels.len);        for (source.kernels, 0..) |item, index| {            var value = try preparation.publication.restoreKernel(allocator, item.lowered, compilationConfiguration(configuration));            errdefer value.deinit(allocator);            try output.work_to_kernel.putNoClobber(value.work_item_id, index);            output.kernels.appendAssumeCapacity(value);        }        self.legal = preparation.backend.BackendLegalizationAnalysis.init(allocator, source.profile);        const legal = &self.legal.?;        for (self.outlines.?.kernels.items) |outline| {            const result = try preparation.backend.legalizeKernel(outline, &self.buffers.?, source.profile);            try legal.kernels.append(allocator, result);            if (result.isLegal()) {                legal.legal_kernel_count += 1;                legal.total_static_bytes = try std.math.add(u64, legal.total_static_bytes, result.static_bytes);            } else legal.illegal_kernel_count += 1;        }    }};

Source: lib/accy/src/artifact/job.zig:22

zig
/// A heap-allocated holder of one artifact plan, the compiled kernels and the/// plan that describes them. A caller holds one of these between compiling a/// prepared program to device code and copying that code into a runnable/// program. `init` takes ownership of the plan and allocates the holder with/// the given allocator, and `deinit` frees the plan and then the holder. The/// holder lives only as long as the compile that made it and is never stored as/// a stage record. The holder answers kernel counts and per-kernel summaries by/// index or by work item, and it copies the plan or the summaries out for a/// caller to keep.pub const ArtifactJob = struct {    allocator: std.mem.Allocator,    artifact_plan: BackendArtifactPlan,    pub fn init(        allocator: std.mem.Allocator,        artifact_plan: BackendArtifactPlan,    ) !*ArtifactJob {        const artifact_job = try allocator.create(ArtifactJob);        errdefer allocator.destroy(artifact_job);        artifact_job.* = .{            .allocator = allocator,            .artifact_plan = artifact_plan,        };        return artifact_job;    }    pub fn deinit(self: *ArtifactJob) void {        self.artifact_plan.deinit();        const allocator = self.allocator;        allocator.destroy(self);    }    /// A 64-bit hash of the plan's target profile, kind, format, slots, input    /// and output ids, kernels and totals. A caller shows this number in    /// reports or stamps it beside compiled output as a label, and no identity    /// check or reuse decision compares it.    pub fn fingerprint(self: *const ArtifactJob) u64 {        return fingerprint_mod.artifactPlan(&self.artifact_plan);    }    pub fn kernelCount(self: *const ArtifactJob) usize {        return self.artifact_plan.kernelCount();    }    pub fn kernelSummary(self: *const ArtifactJob, kernel_index: usize) gpu.BackendError!artifact.KernelSummary {        if (kernel_index >= self.artifact_plan.kernels.items.len) return error.InvalidArtifact;        return try artifact.summarizePlannedKernel(self.artifact_plan.kernels.items[kernel_index]);    }    pub fn kernelSummaryForWork(self: *const ArtifactJob, work_item_id: usize) gpu.BackendError!artifact.KernelSummary {        for (self.artifact_plan.kernels.items) |kernel| {            if (kernel.work_item_id == work_item_id) return try artifact.summarizePlannedKernel(kernel);        }        return error.InvalidArtifact;    }    pub fn artifactPlan(self: *const ArtifactJob) *const BackendArtifactPlan {        return &self.artifact_plan;    }    pub fn copyKernelSummaries(self: *const ArtifactJob, result_allocator: std.mem.Allocator) gpu.BackendError!artifact.KernelSummaries {        const items = result_allocator.alloc(artifact.KernelSummary, self.artifact_plan.kernels.items.len) catch return error.OutOfMemory;        var copied: usize = 0;        errdefer {            for (items[0..copied]) |summary| {                result_allocator.free(summary.entry_name);            }            result_allocator.free(items);        }        for (items, self.artifact_plan.kernels.items) |*item, kernel| {            item.* = try artifact.copyKernelSummary(result_allocator, try artifact.summarizePlannedKernel(kernel));            copied += 1;        }        return .{            .allocator = result_allocator,            .items = items,        };    }    pub fn copyArtifactPlan(self: *const ArtifactJob, allocator: std.mem.Allocator) gpu.BackendError!BackendArtifactPlan {        return try self.artifact_plan.copy(allocator);    }};
Called byCallsNo direct callersprivate sourcelib.accy.src.artifact.input.InputJobinitializeartifact.InputJobcreate
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersalloc_fixedTrackedallocatorartifact.InputJobdestroy
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersartifact.BackendArtifactPlancopyartifact.ArtifactJobcopyArtifactPlan
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel sum...artifact.ArtifactJobcopyKernelSummaries
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallstest sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel cou...test sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel sum...test sourcelib.accy.src.artifact.jobtest: artifact job fingerprint includ...artifact.BackendArtifactPlandeinitartifact.ArtifactJobdeinit
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.accy.src.artifact.jobtest: artifact job fingerprint includ...artifact.ArtifactJobfingerprint
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callsartifactcreateArtifactJobFromTargetJobtest sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel cou...test sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel sum...test sourcelib.accy.src.artifact.jobtest: artifact job fingerprint includ...artifact.ArtifactJobinit
Static calls · unresolved targets: 0 · external targets: 2.
Called byCallstest sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel cou...test sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel sum...artifact.BackendArtifactPlankernelCountartifact.ArtifactJobkernelCount
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callstest sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel sum...artifact.ArtifactJobkernelSummary
Static calls · unresolved targets: 0 · external targets: 1.
Called byCallsNo direct callstest sourcelib.accy.src.artifact.jobtest: artifact job exposes kernel sum...artifact.ArtifactJobkernelSummaryForWork
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/artifact/job.zig:99

zig
pub fn createArtifactJobFromTargetJob(    allocator: std.mem.Allocator,    handle: gpu.BackendHandle,    target_module: *target.TargetJob,    options: ArtifactPlanOptions,) !*ArtifactJob {    var artifact_plan = try plan.createBackendArtifactPlanFromTargetJob(        allocator,        handle,        target_module,        options,    );    var plan_owned = true;    errdefer if (plan_owned) artifact_plan.deinit();    const artifact_job = try ArtifactJob.init(        allocator,        artifact_plan,    );    plan_owned = false;    return artifact_job;}
Called byCallsNo direct callersartifact.ArtifactJobinitartifact.plancreateBackendArtifactPlanFromTargetJobartifactcreateArtifactJobFromTargetJob
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/accy/src/artifact/root.zig

zig
pub const fingerprint = @import("fingerprint.zig");const model = @import("model/root.zig");pub const pipeline = model.pipeline;pub const plan = @import("plan.zig");pub const summary = @import("summary.zig");pub const wire = model.wire;const job = @import("job.zig");pub const product_name = "accy.artifact";pub const ArtifactPlanOptions = model.ArtifactPlanOptions;pub const BackendArtifactPlan = plan.BackendArtifactPlan;pub const ElementCountArgument = model.ElementCountArgument;pub const KernelCallArtifact = model.KernelCallArtifact;pub const KernelCallDerivedLaunch = model.KernelCallDerivedLaunch;pub const KernelCallPipeline = model.KernelCallPipeline;pub const OwnedKernelCallPipeline = model.OwnedKernelCallPipeline;pub const PipelineIntermediate = model.PipelineIntermediate;pub const PipelineRuntimeScalarBound = model.PipelineRuntimeScalarBound;pub const PipelineScalarDerivation = model.PipelineScalarDerivation;pub const PipelineStage = model.PipelineStage;pub const PipelineValueRef = model.PipelineValueRef;pub const findPipeline = model.findPipeline;pub const KernelCallDerivedLaunchAxis = model.KernelCallDerivedLaunchAxis;pub const KernelCallLaunch = model.KernelCallLaunch;pub const KernelCallRegistry = model.KernelCallRegistry;pub const KernelCallRegistryIndex = model.KernelCallRegistryIndex;pub const KernelCallRegistryIndexSlot = model.KernelCallRegistryIndexSlot;pub const KernelCallShapeProfile = model.KernelCallShapeProfile;pub const KernelCallShapeProfileBounds = model.KernelCallShapeProfileBounds;pub const KernelCallShapeProfileDimension = model.KernelCallShapeProfileDimension;pub const LaunchResourceCandidate = plan.LaunchResourceCandidate;pub const LaunchResourceClass = plan.LaunchResourceClass;pub const LaunchResourcePlan = plan.LaunchResourcePlan;pub const LaunchReductionKind = plan.LaunchReductionKind;pub const LaunchTileKind = plan.LaunchTileKind;pub const LaunchTilePlan = plan.LaunchTilePlan;pub const PlannedKernel = plan.PlannedKernel;pub const PlannedKernelCompileContract = plan.PlannedKernelCompileContract;pub const PlannedKernelCompileLaunch = plan.PlannedKernelCompileLaunch;pub const PlannedKernelCompilePayload = plan.PlannedKernelCompilePayload;pub const PlannedKernelSource = plan.PlannedKernelSource;pub const PlannedSlot = plan.PlannedSlot;pub const KernelSource = summary.KernelSource;pub const KernelSummary = summary.KernelSummary;pub const KernelSummaries = summary.KernelSummaries;pub const artifactPayloadByteCount = summary.artifactPayloadByteCount;pub const copyKernelSummary = summary.copyKernelSummary;pub const kernelSource = summary.kernelSource;pub const kernelSummariesEqual = summary.kernelSummariesEqual;pub const launchGeometriesEqual = summary.launchGeometriesEqual;pub const launchResourceClassName = summary.launchResourceClassName;pub const summarizePlannedKernel = summary.summarizePlannedKernel;pub const BackendArtifactPlanSource = plan.BackendArtifactPlanSource;pub const createBackendArtifactPlan = plan.createBackendArtifactPlan;pub const createBackendArtifactPlanFromTargetJob = plan.createBackendArtifactPlanFromTargetJob;pub const buildKernelCallRegistryIndex = model.buildKernelCallRegistryIndex;pub const createBackendMemoryPlan = plan.createBackendMemoryPlan;pub const defaultArtifactFormat = model.defaultArtifactFormat;pub const deinitKernelCallShapeProfile = model.deinitKernelCallShapeProfile;pub const deinitKernelCallRegistryIndex = model.deinitKernelCallRegistryIndex;pub const duplicateKernelCallShapeProfile = model.duplicateKernelCallShapeProfile;pub const artifactPlanFingerprint = fingerprint.artifactPlan;pub const kernelCallShapeProfileEql = model.kernelCallShapeProfileEql;pub const kernelCallRegistryFingerprint = fingerprint.kernelCallRegistry;pub const launchResourcePlanFingerprint = fingerprint.launchResourcePlan;pub const ArtifactJob = job.ArtifactJob;pub const createArtifactJobFromTargetJob = job.createArtifactJobFromTargetJob;pub const InputJob = @import("input.zig").InputJob;pub const createBackendArtifactPlanFromPreparedModule = plan.createBackendArtifactPlanFromPreparedModule;

Source: lib/accy/src/root.zig:83

zig
pub const artifact = @import("artifact/root.zig");

Audit

Definitions17
Public names17
Members13
Version26.7.0
Revisiondaab053ee433