Purpose: Defines ALL shared names, data structures, function signatures, TypeIds, diagnostic codes, and crate boundaries that every GPU-related crate must agree on. This is the single source of truth for cross-crate contracts.
| Crate | Path | Type | Dependencies |
|---|---|---|---|
magpie_gpu |
crates/magpie_gpu/ |
lib (EXISTING, refactored) | magpie_mpir, magpie_types, magpie_diag |
magpie_gpu_spirv |
crates/magpie_gpu_spirv/ |
lib (NEW) | magpie_gpu, magpie_mpir, magpie_types, magpie_diag |
magpie_gpu_msl |
crates/magpie_gpu_msl/ |
lib (NEW) | magpie_gpu, magpie_mpir, magpie_types, magpie_diag |
magpie_gpu_ptx |
crates/magpie_gpu_ptx/ |
lib (NEW) | magpie_gpu, magpie_mpir, magpie_types, magpie_diag |
magpie_gpu_hip |
crates/magpie_gpu_hip/ |
lib (NEW) | magpie_gpu, magpie_mpir, magpie_types, magpie_diag |
magpie_gpu_wgsl |
crates/magpie_gpu_wgsl/ |
lib (NEW) | magpie_gpu, magpie_mpir, magpie_types, magpie_diag |
magpie_mlx |
crates/magpie_mlx/ |
lib (NEW) | magpie_types, magpie_diag |
| Crate | Changes |
|---|---|
magpie_types |
Add PrimType::Bf16, fixed_type_ids::BF16(16), TypeIds 33-40,50 |
magpie_ast |
Extend AstGpuFnDecl with is_unsafe, workgroup, requires |
magpie_parse |
Parse unsafe gpu fn, workgroup(), requires(), backend ids |
magpie_hir |
Add dim: u8 to GPU intrinsic ops |
magpie_sema |
Propagate GPU metadata through lowering |
magpie_mpir |
Add dim: u8 to GPU intrinsics, gpu_meta: Option<MpirGpuMeta> to MpirFn, 3D GpuLaunch |
magpie_codegen_llvm |
Use dim field, declare new runtime functions |
magpie_driver |
Route to backend emitters, propagate GPU metadata |
magpie_rt |
Unify TypeIds, add gpu.TError, new runtime functions, backend dispatch |
magpie_own |
Update pattern matches for new GPU op fields |
magpie_arc |
Update pattern matches for new GPU op fields |
magpie_mono |
Update pattern matches for new GPU op fields |
magpie_diag |
Support MPG_XXX_NNNN diagnostic code format |
All crates MUST use these exact TypeId values. No crate may allocate its own.
TypeId(0) = unit
TypeId(1) = bool
TypeId(2) = i8
TypeId(3) = i16
TypeId(4) = i32
TypeId(5) = i64
TypeId(6) = i128
TypeId(7) = u8
TypeId(8) = u16
TypeId(9) = u32
TypeId(10) = u64
TypeId(11) = u128
TypeId(12) = u1
TypeId(13) = f16
TypeId(14) = f32
TypeId(15) = f64
TypeId(16) = bf16 ← NEW
TypeId(17-19) = reserved
TypeId(20) = Str
TypeId(21) = StrBuilder
TypeId(22) = Array<?> (base)
TypeId(23) = Map<?,?> (base)
TypeId(24) = TOption<?> (base)
TypeId(25) = TResult<?,?> (base)
TypeId(26) = TCallable<?> (base)
TypeId(27-29) = reserved
TypeId(30) = gpu.TDevice
TypeId(31) = gpu.TBuffer<?> (base)
TypeId(32) = gpu.TFence
TypeId(33) = gpu.TError ← NEW
TypeId(34) = gpu.ErrorKind ← NEW
TypeId(35) = gpu.TProfileSession ← NEW
TypeId(36) = gpu.TProfileEvent ← NEW
TypeId(37) = gpu.TMemoryStats ← NEW
TypeId(38) = mlx.TArray<?> (base) ← NEW
TypeId(39) = mlx.nn.TLayerHandle ← NEW
TypeId(40) = mlx.optim.TOptimizerHandle ← NEW
TypeId(41-49) = reserved
TypeId(50) = gpu.TKernel (runtime-internal) ← MOVED from 9004
TypeId(1000+) = user types
pub const BF16: TypeId = TypeId(16);
pub const GPU_ERROR: TypeId = TypeId(33);
pub const GPU_ERROR_KIND: TypeId = TypeId(34);
pub const GPU_PROFILE_SESSION: TypeId = TypeId(35);
pub const GPU_PROFILE_EVENT: TypeId = TypeId(36);
pub const GPU_MEMORY_STATS: TypeId = TypeId(37);
pub const MLX_ARRAY_BASE: TypeId = TypeId(38);
pub const MLX_LAYER_HANDLE: TypeId = TypeId(39);
pub const MLX_OPTIMIZER_HANDLE: TypeId = TypeId(40);
pub const GPU_KERNEL_INTERNAL: TypeId = TypeId(50);// DEPRECATED — remove these:
// const TYPE_ID_GPU_DEVICE_RT: u32 = 9001; → use 30
// const TYPE_ID_GPU_BUFFER_RT: u32 = 9002; → use 31
// const TYPE_ID_GPU_FENCE_RT: u32 = 9003; → use 32
// const TYPE_ID_GPU_KERNEL_RT: u32 = 9004; → use 50
// NEW canonical constants:
const TYPE_ID_GPU_DEVICE: u32 = 30;
const TYPE_ID_GPU_BUFFER: u32 = 31;
const TYPE_ID_GPU_FENCE: u32 = 32;
const TYPE_ID_GPU_ERROR: u32 = 33;
const TYPE_ID_GPU_ERROR_KIND: u32 = 34;
const TYPE_ID_GPU_PROFILE_SESSION: u32 = 35;
const TYPE_ID_GPU_PROFILE_EVENT: u32 = 36;
const TYPE_ID_GPU_MEMORY_STATS: u32 = 37;
const TYPE_ID_MLX_ARRAY: u32 = 38;
const TYPE_ID_MLX_LAYER_HANDLE: u32 = 39;
const TYPE_ID_MLX_OPTIMIZER_HANDLE: u32 = 40;
const TYPE_ID_GPU_KERNEL: u32 = 50;Defined in magpie_gpu/src/lib.rs, re-exported for all backend crates.
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum GpuBackend {
Spv = 1,
Msl = 2,
Ptx = 3,
Hip = 4,
Wgsl = 5,
}
impl GpuBackend {
pub fn from_str(s: &str) -> Option<Self> {
match s {
"spv" => Some(Self::Spv),
"msl" => Some(Self::Msl),
"ptx" => Some(Self::Ptx),
"hip" => Some(Self::Hip),
"wgsl" => Some(Self::Wgsl),
_ => None,
}
}
pub fn as_str(&self) -> &'static str {
match self {
Self::Spv => "spv",
Self::Msl => "msl",
Self::Ptx => "ptx",
Self::Hip => "hip",
Self::Wgsl => "wgsl",
}
}
pub fn display_name(&self) -> &'static str {
match self {
Self::Spv => "Vulkan/SPIR-V",
Self::Msl => "Metal/MSL",
Self::Ptx => "CUDA/PTX",
Self::Hip => "HIP/HSACO",
Self::Wgsl => "WebGPU/WGSL",
}
}
}Defined in magpie_gpu/src/lib.rs.
use magpie_mpir::{MpirFn, MpirTypeTable};
use magpie_diag::Diagnostic;
pub struct KernelLayout {
pub params: Vec<KernelParam>,
pub num_buffers: u32,
pub push_const_size: u32,
}
pub trait BackendEmitter {
fn backend_id(&self) -> GpuBackend;
fn validate_kernel(&self, kernel: &MpirFn, types: &MpirTypeTable) -> Result<(), Vec<Diagnostic>>;
fn compute_layout(&self, kernel: &MpirFn, types: &MpirTypeTable) -> Result<KernelLayout, String>;
fn emit_kernel(&self, kernel: &MpirFn, types: &MpirTypeTable, layout: &KernelLayout) -> Result<Vec<u8>, String>;
fn artifact_extension(&self) -> &str;
}Defined in magpie_mpir/src/lib.rs.
use magpie_gpu::GpuBackend; // or inline the enum
#[derive(Debug, Clone)]
pub struct MpirGpuMeta {
pub target: GpuBackend,
pub workgroup: [u32; 3],
pub is_unsafe: bool,
pub requires: Vec<String>,
}Added to MpirFn:
pub struct MpirFn {
pub sid: Sid,
pub name: String,
pub params: Vec<(LocalId, TypeId)>,
pub ret_ty: TypeId,
pub blocks: Vec<MpirBlock>,
pub locals: Vec<MpirLocalDecl>,
pub is_async: bool,
pub gpu_meta: Option<MpirGpuMeta>, // NEW
}// CHANGED — add dim: u8 field
GpuThreadId { dim: u8 },
GpuWorkgroupId { dim: u8 },
GpuWorkgroupSize { dim: u8 },
GpuGlobalId { dim: u8 },
// UNCHANGED
GpuBufferLoad { buf: MpirValue, idx: MpirValue },
GpuBufferLen { buf: MpirValue },
GpuShared { ty: TypeId, size: MpirValue },
// CHANGED — 3D grid/block
GpuLaunch {
device: MpirValue,
kernel: Sid,
grid: [MpirValue; 3],
block: [MpirValue; 3],
args: Vec<MpirValue>,
},
GpuLaunchAsync {
device: MpirValue,
kernel: Sid,
grid: [MpirValue; 3],
block: [MpirValue; 3],
args: Vec<MpirValue>,
},GpuBarrier,
GpuBufferStore { buf: MpirValue, idx: MpirValue, val: MpirValue },Same changes as MPIR:
GpuThreadId { dim: u8 },
GpuWorkgroupId { dim: u8 },
GpuWorkgroupSize { dim: u8 },
GpuGlobalId { dim: u8 },
GpuLaunch { device, kernel, grid: [HirValue; 3], block: [HirValue; 3], args },
GpuLaunchAsync { device, kernel, grid: [HirValue; 3], block: [HirValue; 3], args },pub struct AstGpuFnDecl {
pub inner: AstFnDecl,
pub target: String, // "spv", "msl", "ptx", "hip", "wgsl"
pub is_unsafe: bool, // NEW
pub workgroup: Option<[u32; 3]>, // NEW
pub requires: Vec<String>, // NEW
}New keywords to recognize:
unsafe(already exists forunsafe fn)workgroup(NEW keyword)requires(NEW keyword)- Backend identifiers:
spv,msl,ptx,hip,wgsl(parsed as idents)
Parse flow for unsafe gpu fn:
"unsafe" → "gpu" → "fn" → name → "(" params ")" → "->" → type
→ "target" → "(" ident ")"
→ ["workgroup" → "(" int "," int "," int ")"]
→ "requires" → "(" ident {"," ident} ")"
→ block
Parse flow for gpu fn:
"gpu" → "fn" → name → "(" params ")" → "->" → type
→ "target" → "(" ident ")"
→ ["workgroup" → "(" int "," int "," int ")"]
→ block
All runtime GPU functions: mp_rt_gpu_*
All runtime MLX functions: mp_rt_mlx_*
All runtime profile functions: mp_rt_gpu_profile_*
// MpRtGpuError — heap object with TypeId 33
typedef struct MpRtGpuErrorPayload {
int32_t kind; // gpu.ErrorKind discriminant (0-11)
MpRtHeader* backend; // Str handle
MpRtHeader* message; // Str handle
int32_t code; // vendor error code
} MpRtGpuErrorPayload;// Error construction/access
MpRtHeader* mp_rt_gpu_error_new(int32_t kind, const char* backend, const char* message, int32_t code);
void mp_rt_gpu_error_drop(MpRtHeader* err);
int32_t mp_rt_gpu_error_kind(MpRtHeader* err);
MpRtHeader* mp_rt_gpu_error_message(MpRtHeader* err);
MpRtHeader* mp_rt_gpu_error_backend(MpRtHeader* err);
int32_t mp_rt_gpu_error_code(MpRtHeader* err);
// Unified device discovery
uint32_t mp_rt_gpu_device_count_unified(void);
int32_t mp_rt_gpu_device_default_unified(MpRtHeader** out_dev, MpRtHeader** out_err);
int32_t mp_rt_gpu_device_by_index(uint32_t idx, MpRtHeader** out_dev, MpRtHeader** out_err);
MpRtHeader* mp_rt_gpu_device_name(MpRtHeader* dev); // EXISTING — keep
int32_t mp_rt_gpu_device_backends(MpRtHeader* dev, MpRtHeader** out_arr, MpRtHeader** out_err);
// Device capabilities
uint32_t mp_rt_gpu_device_max_workgroup_size(MpRtHeader* dev);
uint32_t mp_rt_gpu_device_max_shared_bytes(MpRtHeader* dev);
uint32_t mp_rt_gpu_device_max_buffers(MpRtHeader* dev);
uint32_t mp_rt_gpu_device_warp_size(MpRtHeader* dev);
uint64_t mp_rt_gpu_device_memory_total(MpRtHeader* dev);
uint64_t mp_rt_gpu_device_memory_available(MpRtHeader* dev);
// Extended buffer with hint
int32_t mp_rt_gpu_buffer_new_hinted(
MpRtHeader* dev, uint32_t elem_type_id, uint32_t elem_size,
uint64_t len, uint32_t usage_flags, uint32_t hint,
MpRtHeader** out_buf, MpRtHeader** out_err);
// EXISTING functions — signature change (out_errmsg → out_err, type changes)
int32_t mp_rt_gpu_buffer_new(MpRtHeader* dev, uint32_t elem_type_id, uint64_t elem_size, uint64_t len, uint32_t usage_flags, MpRtHeader** out_buf, MpRtHeader** out_err);
int32_t mp_rt_gpu_buffer_from_array(MpRtHeader* dev, MpRtHeader* host_arr, uint32_t usage_flags, MpRtHeader** out_buf, MpRtHeader** out_err);
int32_t mp_rt_gpu_buffer_to_array(MpRtHeader* buf, MpRtHeader** out_arr, MpRtHeader** out_err);
int32_t mp_rt_gpu_buffer_copy(MpRtHeader* src, MpRtHeader* dst, MpRtHeader** out_err);
int32_t mp_rt_gpu_launch_sync(MpRtHeader* dev, uint64_t sid_hash, uint32_t gx, uint32_t gy, uint32_t gz, uint32_t bx, uint32_t by, uint32_t bz, const uint8_t* args_blob, uint64_t args_blob_len, MpRtHeader** out_err);
int32_t mp_rt_gpu_launch_async(MpRtHeader* dev, uint64_t sid_hash, uint32_t gx, uint32_t gy, uint32_t gz, uint32_t bx, uint32_t by, uint32_t bz, const uint8_t* args_blob, uint64_t args_blob_len, MpRtHeader** out_fence, MpRtHeader** out_err);
// Profiling
int32_t mp_rt_gpu_profile_begin(MpRtHeader* dev, MpRtHeader** out_session, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_end(MpRtHeader* session, MpRtHeader** out_events, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_mark_begin(MpRtHeader* session, MpRtHeader* name, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_mark_end(MpRtHeader* session, MpRtHeader* name, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_export_chrome(MpRtHeader* events, MpRtHeader* path, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_available_counters(MpRtHeader* dev, MpRtHeader** out_arr);
int32_t mp_rt_gpu_profile_enable_counters(MpRtHeader* session, MpRtHeader* counters, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_read_counters(MpRtHeader* session, MpRtHeader** out_map, MpRtHeader** out_err);
int32_t mp_rt_gpu_profile_memory_stats(MpRtHeader* dev, MpRtHeader** out_stats, MpRtHeader** out_err);
// MLX
int32_t mp_rt_mlx_init(void);
int32_t mp_rt_mlx_array_zeros(uint32_t dtype, const uint64_t* shape, uint32_t ndim, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_ones(uint32_t dtype, const uint64_t* shape, uint32_t ndim, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_full(uint32_t dtype, const uint64_t* shape, uint32_t ndim, const void* value, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_from_buffer(MpRtHeader* buf, const uint64_t* shape, uint32_t ndim, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_to_buffer(MpRtHeader* arr, MpRtHeader* dev, MpRtHeader** out_buf, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_add(MpRtHeader* a, MpRtHeader* b, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_sub(MpRtHeader* a, MpRtHeader* b, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_mul(MpRtHeader* a, MpRtHeader* b, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_div(MpRtHeader* a, MpRtHeader* b, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_matmul(MpRtHeader* a, MpRtHeader* b, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_reshape(MpRtHeader* a, const uint64_t* shape, uint32_t ndim, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_sum(MpRtHeader* a, int32_t axis, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_array_eval(MpRtHeader* a, MpRtHeader** out_err);
void mp_rt_mlx_array_drop(MpRtHeader* arr);
int32_t mp_rt_mlx_nn_linear(uint64_t in_features, uint64_t out_features, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_nn_forward(MpRtHeader* layer, MpRtHeader* input, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_optim_adam(float lr, MpRtHeader** out, MpRtHeader** out_err);
int32_t mp_rt_mlx_optim_step(MpRtHeader* opt, MpRtHeader* params, MpRtHeader* grads, MpRtHeader** out_err);
int32_t mp_rt_mlx_grad(MpRtHeader* fn_callable, MpRtHeader** out_grad_fn, MpRtHeader** out_err);New format: MPG_<BACKEND>_<NUMBER> where:
<BACKEND>∈ {CORE,SPV,MSL,PTX,HIP,WGSL,MLX,PROF}<NUMBER>is a 4-digit code
| Prefix | Range | Owner Crate |
|---|---|---|
MPG_CORE_1100-1107 |
Kernel validation (existing, renamed) | magpie_gpu |
MPG_CORE_1200-1202 |
Capability validation | magpie_gpu |
MPG_CORE_1300-1302 |
Backend/tool errors | magpie_gpu, magpie_driver |
MPG_SPV_2001-2003 |
SPIR-V backend | magpie_gpu_spirv |
MPG_MSL_1001,2001-2003 |
MSL backend | magpie_gpu_msl |
MPG_PTX_2001-2003 |
PTX backend | magpie_gpu_ptx |
MPG_HIP_2001-2002 |
HIP backend | magpie_gpu_hip |
MPG_WGSL_1001-1006 |
WGSL backend | magpie_gpu_wgsl |
MPG_MLX_1001-1004 |
MLX | magpie_mlx |
MPG_PROF_1001-1003 |
Profiling | magpie_rt |
Old MPG1100 → new MPG_CORE_1100 (etc., see SPEC_GPU_UPGRADE.md §13.1).
magpie_diag must accept BOTH formats during transition:
- Legacy:
/^MPG\d{4}$/ - New:
/^MPG_[A-Z]+_\d{4}$/
Generated by magpie_gpu::generate_kernel_registry_ir().
%MpRtGpuKernelBlob = type { i8, ptr, i32 }
; { backend: u8, data: ptr, data_len: u32 }
%MpRtGpuParam = type { i8, i32, i32, i32 }
; { kind: u8, type_id: u32, offset_or_binding: u32, size: u32 }
%MpRtGpuKernelEntry = type { i64, i32, ptr, i32, ptr, i32, i32 }
; { sid_hash: u64, num_blobs: u32, blobs: ptr, num_params: u32, params: ptr, num_buffers: u32, push_const_size: u32 }define void @mp_gpu_register_all_kernels() {
call void @mp_rt_gpu_register_kernels(ptr @mp_gpu_kernel_registry, i32 <count>)
ret void
}Defined in magpie_gpu/src/structurize.rs, consumed by magpie_gpu_msl and magpie_gpu_wgsl.
pub enum StructuredNode {
Block { label: BlockId, instrs: Vec<MpirInstr> },
IfElse { cond: MpirValue, then_branch: Vec<StructuredNode>, else_branch: Vec<StructuredNode> },
Loop { body: Vec<StructuredNode> },
Break { depth: u32 },
Continue { depth: u32 },
Return,
Assign { local: LocalId, value: MpirValue },
}
#[derive(Debug)]
pub struct StructurizeError {
pub message: String,
pub block_id: Option<BlockId>,
}
pub fn structurize_cfg(func: &MpirFn) -> Result<Vec<StructuredNode>, StructurizeError>;| Artifact | Path Pattern |
|---|---|
| SPIR-V blob | <output_dir>/gpu/<sid>.spv |
| MSL source | <output_dir>/gpu/<sid>.metal |
| PTX source | <output_dir>/gpu/<sid>.ptx |
| LLVM IR (PTX) | <output_dir>/gpu/<sid>.nvptx.ll |
| HSACO blob | <output_dir>/gpu/<sid>.hsaco |
| LLVM IR (HIP) | <output_dir>/gpu/<sid>.amdgcn.ll |
| WGSL source | <output_dir>/gpu/<sid>.wgsl |
| Registry IR | <output_dir>/gpu_registry.ll |
New runtime function declarations to add in magpie_codegen_llvm/src/lib.rs:
; Error
declare ptr @mp_rt_gpu_error_new(i32, ptr, ptr, i32)
declare i32 @mp_rt_gpu_error_kind(ptr)
declare ptr @mp_rt_gpu_error_message(ptr)
declare ptr @mp_rt_gpu_error_backend(ptr)
declare i32 @mp_rt_gpu_error_code(ptr)
; Device discovery
declare i32 @mp_rt_gpu_device_count_unified()
declare i32 @mp_rt_gpu_device_default_unified(ptr, ptr)
declare i32 @mp_rt_gpu_device_by_index(i32, ptr, ptr)
declare i32 @mp_rt_gpu_device_backends(ptr, ptr, ptr)
; Device capabilities
declare i32 @mp_rt_gpu_device_max_workgroup_size(ptr)
declare i32 @mp_rt_gpu_device_max_shared_bytes(ptr)
declare i32 @mp_rt_gpu_device_max_buffers(ptr)
declare i32 @mp_rt_gpu_device_warp_size(ptr)
declare i64 @mp_rt_gpu_device_memory_total(ptr)
declare i64 @mp_rt_gpu_device_memory_available(ptr)
; Buffer with hint
declare i32 @mp_rt_gpu_buffer_new_hinted(ptr, i32, i32, i64, i32, i32, ptr, ptr)
; Profiling
declare i32 @mp_rt_gpu_profile_begin(ptr, ptr, ptr)
declare i32 @mp_rt_gpu_profile_end(ptr, ptr, ptr)
declare i32 @mp_rt_gpu_profile_mark_begin(ptr, ptr, ptr)
declare i32 @mp_rt_gpu_profile_mark_end(ptr, ptr, ptr)
declare i32 @mp_rt_gpu_profile_export_chrome(ptr, ptr, ptr)
declare i32 @mp_rt_gpu_profile_memory_stats(ptr, ptr, ptr)| Crate | Change |
|---|---|
magpie_types |
Add PrimType::Bf16, fixed_type_ids::BF16 = TypeId(16), layout {size:2, align:2}, is_float(), is_signed(), bit_width() |
magpie_ast |
AstType::Prim already handles string → PrimType; add "bf16" => Bf16 mapping |
magpie_lex |
Recognize bf16 as keyword/type token |
magpie_parse |
Handle bf16 in type parsing |
magpie_sema |
Lower bf16 type, add explicit conversion ops bf16.to_f32, f32.to_bf16 |
magpie_hir |
Add Bf16ToF32, F32ToBf16 ops |
magpie_mpir |
Add Bf16ToF32, F32ToBf16 ops |
magpie_codegen_llvm |
Map TypeId(16) → "bfloat", codegen for conversion ops |
magpie_rt |
No change needed (bf16 is a value type, no runtime representation) |
#[repr(C)]
pub struct MpRtGpuErrorPayload {
pub kind: i32, // gpu.ErrorKind discriminant (0-11)
pub backend: *mut MpRtHeader, // Str handle ("spv", "msl", etc.)
pub message: *mut MpRtHeader, // Str handle
pub code: i32, // vendor error code
}Registered as:
MpRtTypeInfo {
type_id: TYPE_ID_GPU_ERROR, // 33
flags: FLAG_HEAP | FLAG_HAS_DROP,
payload_size: size_of::<MpRtGpuErrorPayload>(),
payload_align: align_of::<MpRtGpuErrorPayload>(),
drop_fn: Some(mp_rt_gpu_error_drop),
debug_fqn: c"gpu.TError",
}pub const GPU_ERROR_DEVICE_LOST: i32 = 0;
pub const GPU_ERROR_OUT_OF_MEMORY: i32 = 1;
pub const GPU_ERROR_LAUNCH_FAILED: i32 = 2;
pub const GPU_ERROR_INVALID_KERNEL: i32 = 3;
pub const GPU_ERROR_BACKEND_UNAVAILABLE: i32 = 4;
pub const GPU_ERROR_BUFFER_ERROR: i32 = 5;
pub const GPU_ERROR_TIMEOUT_EXPIRED: i32 = 6;
pub const GPU_ERROR_UNSUPPORTED: i32 = 7;
pub const GPU_ERROR_COMPILATION_FAILED: i32 = 8;
pub const GPU_ERROR_DRIVER_ERROR: i32 = 9;
pub const GPU_ERROR_RESOURCE_EXHAUSTED: i32 = 10;
pub const GPU_ERROR_VALIDATION_FAILED: i32 = 11;End of Interoperability Specification