diff --git a/Cargo.lock b/Cargo.lock index ca0b7d7ad7..156ca2c807 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -498,8 +498,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-core/Cargo.toml b/cuda-core/Cargo.toml index 98bf503077..5dd40ecf84 100644 --- a/cuda-core/Cargo.toml +++ b/cuda-core/Cargo.toml @@ -17,7 +17,7 @@ cuda-bindings = { version = "=0.5.0", path = "../cuda-bindings" } cuda-core-derive = { version = "=0.5.0", path = "../cuda-core-derive" } anyhow = "1" half = { version = "2" } -oxide-artifacts = { version = "0.2.1", features = ["object-read"] } +oxide-artifacts = { version = "0.2.1", path = "../cuda-oxide/crates/oxide-artifacts", features = ["object-read"] } [dev-dependencies] trybuild = "1" diff --git a/cuda-core/src/simt/embedded.rs b/cuda-core/src/simt/embedded.rs index c146f58753..d63fed04c4 100644 --- a/cuda-core/src/simt/embedded.rs +++ b/cuda-core/src/simt/embedded.rs @@ -46,8 +46,19 @@ impl EmbeddedModule { pub fn load(&self, ctx: &Arc) -> Result, EmbeddedModuleError> { let image = loadable_payload(&self.bundle).expect("EmbeddedModule always has a loadable payload"); - ctx.load_module_from_image(image) - .map_err(EmbeddedModuleError::Driver) + ctx.load_module_from_image_with_launch_facts( + image, + self.bundle + .entries + .iter() + .filter_map(|entry| { + entry + .launch_facts + .map(|facts| (entry.symbol.clone(), facts)) + }) + .collect(), + ) + .map_err(EmbeddedModuleError::Driver) } } diff --git a/cuda-core/src/simt/launch.rs b/cuda-core/src/simt/launch.rs index ff1f37684b..49503c2974 100644 --- a/cuda-core/src/simt/launch.rs +++ b/cuda-core/src/simt/launch.rs @@ -64,6 +64,9 @@ mod sealed { pub trait KernelLaunchConfig: sealed::Sealed + Copy { #[doc(hidden)] fn __raw(self) -> LaunchConfig; + + #[doc(hidden)] + fn __auto_shared(self) -> bool; } /// A one-dimensional launch configuration. @@ -73,10 +76,20 @@ pub trait KernelLaunchConfig: sealed::Sealed + Copy { pub struct LaunchConfig1D { grid_x: u32, block_x: u32, - shared_mem_bytes: u32, + shared_mem_bytes: Option, } impl LaunchConfig1D { + /// Uses the kernel's prepared resource requirement for dynamic shared memory. + /// A range contract selects its minimum, raised by compiled facts if present. + pub const fn auto_shared(grid_x: u32, block_x: u32) -> Self { + Self { + grid_x, + block_x, + shared_mem_bytes: None, + } + } + /// Creates a one-dimensional launch configuration. /// /// Zero dimensions are reported when the configuration is prepared for a @@ -85,7 +98,7 @@ impl LaunchConfig1D { Self { grid_x, block_x, - shared_mem_bytes, + shared_mem_bytes: Some(shared_mem_bytes), } } } @@ -93,11 +106,15 @@ impl LaunchConfig1D { impl sealed::Sealed for LaunchConfig1D {} impl KernelLaunchConfig for LaunchConfig1D { + fn __auto_shared(self) -> bool { + self.shared_mem_bytes.is_none() + } + fn __raw(self) -> LaunchConfig { LaunchConfig { grid_dim: (self.grid_x, 1, 1), block_dim: (self.block_x, 1, 1), - shared_mem_bytes: self.shared_mem_bytes, + shared_mem_bytes: self.shared_mem_bytes.unwrap_or(0), } } } @@ -109,16 +126,26 @@ impl KernelLaunchConfig for LaunchConfig1D { pub struct LaunchConfig2D { grid: (u32, u32), block: (u32, u32), - shared_mem_bytes: u32, + shared_mem_bytes: Option, } impl LaunchConfig2D { + /// Uses the kernel's prepared resource requirement for dynamic shared memory. + /// A range contract selects its minimum, raised by compiled facts if present. + pub const fn auto_shared(grid: (u32, u32), block: (u32, u32)) -> Self { + Self { + grid, + block, + shared_mem_bytes: None, + } + } + /// Creates a two-dimensional launch configuration. pub const fn new(grid: (u32, u32), block: (u32, u32), shared_mem_bytes: u32) -> Self { Self { grid, block, - shared_mem_bytes, + shared_mem_bytes: Some(shared_mem_bytes), } } } @@ -126,11 +153,15 @@ impl LaunchConfig2D { impl sealed::Sealed for LaunchConfig2D {} impl KernelLaunchConfig for LaunchConfig2D { + fn __auto_shared(self) -> bool { + self.shared_mem_bytes.is_none() + } + fn __raw(self) -> LaunchConfig { LaunchConfig { grid_dim: (self.grid.0, self.grid.1, 1), block_dim: (self.block.0, self.block.1, 1), - shared_mem_bytes: self.shared_mem_bytes, + shared_mem_bytes: self.shared_mem_bytes.unwrap_or(0), } } } @@ -140,16 +171,26 @@ impl KernelLaunchConfig for LaunchConfig2D { pub struct LaunchConfig3D { grid: (u32, u32, u32), block: (u32, u32, u32), - shared_mem_bytes: u32, + shared_mem_bytes: Option, } impl LaunchConfig3D { + /// Uses the kernel's prepared resource requirement for dynamic shared memory. + /// A range contract selects its minimum, raised by compiled facts if present. + pub const fn auto_shared(grid: (u32, u32, u32), block: (u32, u32, u32)) -> Self { + Self { + grid, + block, + shared_mem_bytes: None, + } + } + /// Creates a three-dimensional launch configuration. pub const fn new(grid: (u32, u32, u32), block: (u32, u32, u32), shared_mem_bytes: u32) -> Self { Self { grid, block, - shared_mem_bytes, + shared_mem_bytes: Some(shared_mem_bytes), } } } @@ -157,11 +198,15 @@ impl LaunchConfig3D { impl sealed::Sealed for LaunchConfig3D {} impl KernelLaunchConfig for LaunchConfig3D { + fn __auto_shared(self) -> bool { + self.shared_mem_bytes.is_none() + } + fn __raw(self) -> LaunchConfig { LaunchConfig { grid_dim: self.grid, block_dim: self.block, - shared_mem_bytes: self.shared_mem_bytes, + shared_mem_bytes: self.shared_mem_bytes.unwrap_or(0), } } } @@ -188,6 +233,9 @@ pub enum BlockRequirement { /// The dynamic shared-memory sizes accepted by a kernel. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum DynamicSharedMemoryRequirement { + /// Use the finalized allocation and alignment from this concrete kernel's + /// compiled artifact. Preparation fails when those facts are absent. + Inferred, /// The launch must allocate exactly `bytes` bytes. Exact { /// Required bytes per block. @@ -429,6 +477,11 @@ pub enum LaunchContractError { /// Number of coordinate values required on this axis. positions: u64, }, + /// An inferred contract was loaded without compiled resource facts. + MissingCompiledLaunchFacts { + /// Kernel being prepared. + kernel: &'static str, + }, /// A shared-memory alignment was not a nonzero power of two. InvalidSharedMemoryAlignment { /// Kernel being prepared. @@ -671,6 +724,8 @@ impl Display for LaunchContractError { f, "{kernel}: Grid.{axis:?} {grid} * Block.{axis:?} {block} requires {positions} coordinates, exceeding the u32 range" ), + Self::MissingCompiledLaunchFacts { kernel } => write!(f, + "{kernel}: compiled launch facts are missing; rebuild this kernel with the CUDA compiler"), Self::InvalidSharedMemoryAlignment { kernel, alignment } => write!( f, "{kernel}: dynamic shared-memory alignment {alignment} is not a nonzero power of two" @@ -893,15 +948,25 @@ impl PreparedLaunch { /// /// `C::SPEC` must truthfully describe the compiled device function, /// including its rank, fixed block assumptions, shared-memory layout, and - /// launch mode. cuda-oxide's macros generate that marker and uphold this - /// relationship. + /// launch mode. Any `function.launch_facts()` must truthfully describe this + /// exact loaded image and entry; inferred contracts obtain their allocation + /// from those facts. cuda-oxide's macros and matching artifact loader uphold + /// this relationship. #[doc(hidden)] pub unsafe fn __prepare( function: CudaFunction, config: C::Config, ) -> Result { - let raw = config.__raw(); - validate_static(C::SPEC, raw)?; + let spec = resolve_compiled_spec(C::SPEC, function.launch_facts())?; + let mut raw = config.__raw(); + if config.__auto_shared() { + raw.shared_mem_bytes = match spec.dynamic_shared_memory { + DynamicSharedMemoryRequirement::Exact { bytes, .. } => bytes, + DynamicSharedMemoryRequirement::Range { min_bytes, .. } => min_bytes, + DynamicSharedMemoryRequirement::Inferred => unreachable!("resolved above"), + }; + } + validate_static(spec, raw)?; let context = function.context(); let limits = context.launch_limits()?; @@ -909,17 +974,17 @@ impl PreparedLaunch { let static_shared = function.static_shared_memory_bytes()?; let function_max_dynamic = function.max_dynamic_shared_memory_bytes()?; - validate_live_shape(C::SPEC, raw, limits, function_max_threads)?; + validate_live_shape(spec, raw, limits, function_max_threads)?; // Configure the immutable contract maximum, not this particular // launch's chosen size. Concurrent preparations of two range values // therefore write the same function attribute and cannot lower the // maximum underneath an already prepared launch. - let contract_dynamic_max = dynamic_shared_memory_max(C::SPEC.dynamic_shared_memory); + let contract_dynamic_max = dynamic_shared_memory_max(spec.dynamic_shared_memory); let total_shared = - shared_memory_total(C::SPEC.kernel_name, static_shared, contract_dynamic_max)?; + shared_memory_total(spec.kernel_name, static_shared, contract_dynamic_max)?; if validate_shared_memory_limit( - C::SPEC.kernel_name, + spec.kernel_name, total_shared, limits.max_shared_memory_per_block, false, @@ -927,10 +992,10 @@ impl PreparedLaunch { .is_err() { let opt_in_max = context.max_opt_in_shared_memory_per_block()?; - validate_shared_memory_limit(C::SPEC.kernel_name, total_shared, opt_in_max, true)?; + validate_shared_memory_limit(spec.kernel_name, total_shared, opt_in_max, true)?; } - if let Some(required) = C::SPEC.min_compute_capability { + if let Some(required) = spec.min_compute_capability { let (major, minor) = context.compute_capability()?; let actual = ( u32::try_from(major).map_err(|_| { @@ -940,23 +1005,20 @@ impl PreparedLaunch { DriverError(cuda_bindings::cudaError_enum_CUDA_ERROR_INVALID_VALUE) })?, ); - validate_compute_capability(C::SPEC.kernel_name, required, actual)?; + validate_compute_capability(spec.kernel_name, required, actual)?; } - if let Some(cluster) = C::SPEC.cluster { - validate_cluster_support(C::SPEC.kernel_name, context.supports_cluster_launch()?)?; + if let Some(cluster) = spec.cluster { + validate_cluster_support(spec.kernel_name, context.supports_cluster_launch()?)?; validate_required_cluster( - C::SPEC.kernel_name, + spec.kernel_name, cluster, function.required_cluster_dimensions()?, )?; } - if C::SPEC.cooperative { - validate_cooperative_support( - C::SPEC.kernel_name, - context.supports_cooperative_launch()?, - )?; + if spec.cooperative { + validate_cooperative_support(spec.kernel_name, context.supports_cooperative_launch()?)?; } // Perform the only persistent function mutation after all checks that @@ -973,15 +1035,15 @@ impl PreparedLaunch { // `cuOccupancyMaxActiveClusters`. let mut clustered_resident_blocks: Option = None; - if let Some(cluster) = C::SPEC.cluster { + if let Some(cluster) = spec.cluster { let max_cluster_size = function.max_potential_cluster_size( raw.grid_dim, raw.block_dim, raw.shared_mem_bytes, )?; let cluster_blocks = - shape_product(C::SPEC.kernel_name, LaunchDimension::Cluster, cluster)?; - validate_cluster_size(C::SPEC.kernel_name, cluster_blocks, max_cluster_size)?; + shape_product(spec.kernel_name, LaunchDimension::Cluster, cluster)?; + validate_cluster_size(spec.kernel_name, cluster_blocks, max_cluster_size)?; let active_clusters = match function.max_active_clusters( raw.grid_dim, @@ -994,13 +1056,13 @@ impl PreparedLaunch { if error.0 == cuda_bindings::cudaError_enum_CUDA_ERROR_INVALID_CLUSTER_SIZE => { return Err(LaunchContractError::ClusterShapeUnsupported { - kernel: C::SPEC.kernel_name, + kernel: spec.kernel_name, cluster, }); } Err(error) => return Err(error.into()), }; - validate_cluster_residency(C::SPEC.kernel_name, cluster, active_clusters)?; + validate_cluster_residency(spec.kernel_name, cluster, active_clusters)?; // Deliberate error reuse: `active_clusters * cluster_blocks` is a // device-capacity product over the cluster dimension, and // `DimensionProductOverflow { Cluster }` is the closest existing @@ -1012,19 +1074,19 @@ impl PreparedLaunch { u64::from(active_clusters) .checked_mul(cluster_blocks) .ok_or(LaunchContractError::DimensionProductOverflow { - kernel: C::SPEC.kernel_name, + kernel: spec.kernel_name, dimension: LaunchDimension::Cluster, })?, ); } - if C::SPEC.cooperative { - let blocks = shape_product(C::SPEC.kernel_name, LaunchDimension::Grid, raw.grid_dim)?; + if spec.cooperative { + let blocks = shape_product(spec.kernel_name, LaunchDimension::Grid, raw.grid_dim)?; let resident_capacity = if let Some(capacity) = clustered_resident_blocks { capacity } else { let block_threads = - shape_product(C::SPEC.kernel_name, LaunchDimension::Block, raw.block_dim)?; + shape_product(spec.kernel_name, LaunchDimension::Block, raw.block_dim)?; let active_per_sm = function.max_active_blocks_per_multiprocessor( block_threads as u32, raw.shared_mem_bytes, @@ -1032,7 +1094,7 @@ impl PreparedLaunch { let multiprocessors = context.multiprocessor_count()?; u64::from(active_per_sm) * u64::from(multiprocessors) }; - validate_cooperative_residency(C::SPEC.kernel_name, blocks, resident_capacity)?; + validate_cooperative_residency(spec.kernel_name, blocks, resident_capacity)?; } Ok(Self { @@ -1072,6 +1134,85 @@ impl PreparedLaunch { } } +fn resolve_compiled_spec( + mut spec: LaunchContractSpec, + facts: Option, +) -> Result { + let Some(facts) = facts else { + return if spec.dynamic_shared_memory == DynamicSharedMemoryRequirement::Inferred { + Err(LaunchContractError::MissingCompiledLaunchFacts { + kernel: spec.kernel_name, + }) + } else { + Ok(spec) + }; + }; + if let Some(required) = facts.exact_block { + match spec.block { + BlockRequirement::Exact(declared) if declared != required => { + return Err(LaunchContractError::BlockShapeMismatch { + kernel: spec.kernel_name, + required, + actual: declared, + }); + } + BlockRequirement::MaxThreads(max) => { + let actual = shape_product(spec.kernel_name, LaunchDimension::Block, required)?; + if actual > u64::from(max) { + return Err(LaunchContractError::BlockThreadsExceedContract { + kernel: spec.kernel_name, + actual, + max, + }); + } + } + _ => {} + } + spec.block = BlockRequirement::Exact(required); + } + spec.dynamic_shared_memory = match spec.dynamic_shared_memory { + DynamicSharedMemoryRequirement::Inferred => DynamicSharedMemoryRequirement::Exact { + bytes: facts.dynamic_shared_bytes, + min_alignment: facts.dynamic_shared_alignment, + }, + DynamicSharedMemoryRequirement::Exact { + bytes, + min_alignment, + } => { + if bytes < facts.dynamic_shared_bytes { + return Err(LaunchContractError::DynamicSharedMemoryExactMismatch { + kernel: spec.kernel_name, + required: facts.dynamic_shared_bytes, + actual: bytes, + }); + } + DynamicSharedMemoryRequirement::Exact { + bytes, + min_alignment: min_alignment.max(facts.dynamic_shared_alignment), + } + } + DynamicSharedMemoryRequirement::Range { + min_bytes, + max_bytes, + min_alignment, + } => { + if max_bytes < facts.dynamic_shared_bytes { + return Err(LaunchContractError::DynamicSharedMemoryExactMismatch { + kernel: spec.kernel_name, + required: facts.dynamic_shared_bytes, + actual: max_bytes, + }); + } + DynamicSharedMemoryRequirement::Range { + min_bytes: min_bytes.max(facts.dynamic_shared_bytes), + max_bytes, + min_alignment: min_alignment.max(facts.dynamic_shared_alignment), + } + } + }; + Ok(spec) +} + fn validate_static( spec: LaunchContractSpec, config: LaunchConfig, @@ -1111,6 +1252,11 @@ fn validate_static( } match spec.dynamic_shared_memory { + DynamicSharedMemoryRequirement::Inferred => { + return Err(LaunchContractError::MissingCompiledLaunchFacts { + kernel: spec.kernel_name, + }) + } DynamicSharedMemoryRequirement::Exact { bytes, min_alignment, @@ -1250,6 +1396,9 @@ fn shared_memory_total( const fn dynamic_shared_memory_max(requirement: DynamicSharedMemoryRequirement) -> u32 { match requirement { + DynamicSharedMemoryRequirement::Inferred => { + panic!("inferred requirements must be resolved before validation") + } DynamicSharedMemoryRequirement::Exact { bytes, .. } => bytes, DynamicSharedMemoryRequirement::Range { max_bytes, .. } => max_bytes, } @@ -1482,6 +1631,120 @@ mod tests { } } + #[test] + fn compiled_facts_resolve_inference_and_enforce_shape_and_size() { + let source = LaunchContractSpec::new( + "fixed", + BlockRequirement::MaxThreads(32), + DynamicSharedMemoryRequirement::Inferred, + ); + assert!(matches!( + resolve_compiled_spec(source, None), + Err(LaunchContractError::MissingCompiledLaunchFacts { .. }) + )); + let facts = oxide_artifacts::KernelLaunchFacts { + exact_block: Some((8, 4, 1)), + dynamic_shared_bytes: 512, + dynamic_shared_alignment: 64, + }; + let effective = resolve_compiled_spec(source, Some(facts)).unwrap(); + let config = LaunchConfig { + grid_dim: (1, 1, 1), + block_dim: (8, 4, 1), + shared_mem_bytes: 512, + }; + assert!(validate_static(effective, config).is_ok()); + assert!(matches!( + validate_static( + effective, + LaunchConfig { + block_dim: (32, 1, 1), + ..config + } + ), + Err(LaunchContractError::BlockShapeMismatch { .. }) + )); + assert!(matches!( + validate_static( + effective, + LaunchConfig { + shared_mem_bytes: 511, + ..config + } + ), + Err(LaunchContractError::DynamicSharedMemoryExactMismatch { .. }) + )); + let empty = resolve_compiled_spec( + source, + Some(oxide_artifacts::KernelLaunchFacts { + dynamic_shared_bytes: 0, + ..facts + }), + ) + .unwrap(); + assert!(validate_static( + empty, + LaunchConfig { + shared_mem_bytes: 0, + ..config + } + ) + .is_ok()); + assert!(LaunchConfig2D::auto_shared((1, 1), (8, 4)).__auto_shared()); + assert!(!LaunchConfig2D::new((1, 1), (8, 4), 0).__auto_shared()); + } + + #[test] + fn compiled_facts_strengthen_explicit_contracts() { + let facts = oxide_artifacts::KernelLaunchFacts { + exact_block: Some((8, 4, 1)), + dynamic_shared_bytes: 128, + dynamic_shared_alignment: 64, + }; + let resolve = |block, memory| { + resolve_compiled_spec(LaunchContractSpec::new("fixed", block, memory), Some(facts)) + }; + let block = BlockRequirement::MaxThreads(32); + let exact = |bytes| DynamicSharedMemoryRequirement::Exact { + bytes, + min_alignment: 16, + }; + for bytes in [0, 127] { + assert!(matches!( + resolve(block, exact(bytes)), + Err(LaunchContractError::DynamicSharedMemoryExactMismatch { .. }) + )); + } + assert_eq!( + resolve(block, exact(256)).unwrap().dynamic_shared_memory, + DynamicSharedMemoryRequirement::Exact { + bytes: 256, + min_alignment: 64, + } + ); + let range = |max_bytes| DynamicSharedMemoryRequirement::Range { + min_bytes: 32, + max_bytes, + min_alignment: 16, + }; + assert!(matches!( + resolve(block, range(127)), + Err(LaunchContractError::DynamicSharedMemoryExactMismatch { .. }) + )); + assert_eq!( + resolve(block, range(256)).unwrap().dynamic_shared_memory, + DynamicSharedMemoryRequirement::Range { + min_bytes: 128, + max_bytes: 256, + min_alignment: 64, + } + ); + assert!(matches!( + resolve(BlockRequirement::MaxThreads(16), exact(128)), + Err(LaunchContractError::BlockThreadsExceedContract { .. }) + )); + } + #[test] fn typed_configs_fix_trailing_dimensions() { let one = LaunchConfig1D::new(7, 64, 16).__raw(); diff --git a/cuda-core/src/simt/mod.rs b/cuda-core/src/simt/mod.rs index 7f07b4c361..7921737eb7 100644 --- a/cuda-core/src/simt/mod.rs +++ b/cuda-core/src/simt/mod.rs @@ -67,7 +67,7 @@ pub use crate::error::{DriverError, IntoResult}; pub use crate::init; pub use crate::launch_kernel; pub use cuda_bindings as sys; -/// Artifact-bundle metadata, from the published crate cuda-oxide releases. +/// Artifact-bundle metadata shared with the CUDA compiler and loaders. pub use oxide_artifacts as artifacts; /// Launches a CUDA kernel on a specific [`CudaStream`], binding its context first. diff --git a/cuda-core/src/simt/module.rs b/cuda-core/src/simt/module.rs index a2b4cb646f..4ec96999fc 100644 --- a/cuda-core/src/simt/module.rs +++ b/cuda-core/src/simt/module.rs @@ -29,7 +29,9 @@ use crate::error::{DriverError, IntoResult}; use crate::simt::context::CudaContext; +use oxide_artifacts::KernelLaunchFacts; use std::borrow::Cow; +use std::collections::BTreeMap; use std::ffi::{c_void, CString}; use std::mem::MaybeUninit; use std::sync::Arc; @@ -44,6 +46,7 @@ pub struct CudaModule { pub(crate) cu_module: cuda_bindings::CUmodule, /// Owning context. Kept alive for the lifetime of this module. pub(crate) ctx: Arc, + kernel_launch_facts: BTreeMap, } /// # Safety @@ -92,6 +95,7 @@ impl CudaContext { Ok(Arc::new(CudaModule { cu_module, ctx: self.clone(), + kernel_launch_facts: BTreeMap::new(), })) } @@ -104,6 +108,22 @@ impl CudaContext { pub fn load_module_from_image( self: &Arc, image: &[u8], + ) -> Result, DriverError> { + self.load_module_from_image_with_launch_facts(image, BTreeMap::new()) + } + + /// Loads an image together with its compiler-produced per-entry facts. + /// + /// The facts must come from the same artifact bundle as `image`. This is + /// intended for artifact loaders; raw image loading leaves facts absent. + /// Loading does not validate the facts against device instructions. Binding + /// this module to a checked launch API is unsafe and requires truthful facts + /// for the exact loaded image and entry. + #[doc(hidden)] + pub fn load_module_from_image_with_launch_facts( + self: &Arc, + image: &[u8], + kernel_launch_facts: BTreeMap, ) -> Result, DriverError> { self.bind_to_thread()?; let image = null_terminated_image(image); @@ -116,6 +136,7 @@ impl CudaContext { Ok(Arc::new(CudaModule { cu_module, ctx: self.clone(), + kernel_launch_facts, })) } @@ -141,6 +162,7 @@ impl CudaContext { Ok(Arc::new(CudaModule { cu_module, ctx: self.clone(), + kernel_launch_facts: BTreeMap::new(), })) } } @@ -168,6 +190,7 @@ pub struct CudaFunction { /// Owning module. Prevents unloading while this function handle exists. #[allow(unused)] pub(crate) module: Arc, + launch_facts: Option, } /// # Safety @@ -254,6 +277,7 @@ impl CudaModule { Ok(CudaFunction { cu_function, module: self.clone(), + launch_facts: self.kernel_launch_facts.get(fn_name).copied(), }) } } @@ -445,6 +469,11 @@ impl CudaModule { } impl CudaFunction { + /// Returns finalized requirements attached to this concrete kernel artifact. + pub fn launch_facts(&self) -> Option { + self.launch_facts + } + fn attribute( &self, attribute: cuda_bindings::CUfunction_attribute, diff --git a/cuda-oxide/Cargo.lock b/cuda-oxide/Cargo.lock index adf2d64339..6829a60f57 100644 --- a/cuda-oxide/Cargo.lock +++ b/cuda-oxide/Cargo.lock @@ -211,7 +211,7 @@ dependencies = [ "cuda-artifact-finalizer", "libnvvm-sys", "nvjitlink-sys", - "oxide-artifacts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "oxide-artifacts", "oxide-tile-export", "oxide-tilebc", "ptx-parse", @@ -417,7 +417,7 @@ dependencies = [ "cuda-bindings", "cuda-core-derive", "half", - "oxide-artifacts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "oxide-artifacts", ] [[package]] @@ -449,7 +449,7 @@ dependencies = [ "half", "libc", "libloading", - "oxide-artifacts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "oxide-artifacts", "ptx-parse", "sha2", "thiserror 2.0.21", @@ -484,6 +484,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn 2.0.117", "trybuild", ] @@ -1065,7 +1067,7 @@ dependencies = [ "llvm-export", "mir-lower", "once_cell", - "oxide-artifacts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "oxide-artifacts", "pliron", "pliron-derive", "reserved-oxide-symbols", @@ -1164,15 +1166,6 @@ dependencies = [ "object", ] -[[package]] -name = "oxide-artifacts" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" -dependencies = [ - "object", -] - [[package]] name = "oxide-tile-export" version = "0.2.1" @@ -1303,7 +1296,7 @@ version = "0.1.0" dependencies = [ "clap", "dialect-ptx", - "oxide-artifacts 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "oxide-artifacts", "ptx-parse", "serde", "serde_json", diff --git a/cuda-oxide/Cargo.toml b/cuda-oxide/Cargo.toml index 0854cb991d..752d4d4de6 100644 --- a/cuda-oxide/Cargo.toml +++ b/cuda-oxide/Cargo.toml @@ -105,13 +105,10 @@ cuda-async = { path = "../cuda-async" } libnvvm-sys = { path = "crates/libnvvm-sys" } nvjitlink-sys = { path = "crates/nvjitlink-sys" } reserved-oxide-symbols = { path = "crates/reserved-oxide-symbols" } -# The crates.io release, not the in-tree path: the shared cuda-core (cutile-rs) -# reads artifact bundles through crates.io oxide-artifacts, and a path copy of -# the same version is a second crate to rustc. crates/oxide-artifacts -# stays in the workspace as the source this release is published from; bump, -# publish, then move this line. -# scripts/check-oxide-artifacts-parity.sh keeps them equal. -oxide-artifacts = "0.2.1" +# Keep the compiler, shared host runtime, and tools on the same artifact +# implementation. The shared runtime and isolated backend use this path too; +# scripts/check-oxide-artifacts-parity.sh verifies the source and version. +oxide-artifacts = { version = "0.2.1", path = "crates/oxide-artifacts" } # Tile export descriptions shared by `#[tile_export]`, the backend, and # `cargo oxide tilelib`. oxide-tile-export = { path = "crates/oxide-tile-export" } diff --git a/cuda-oxide/crates/cargo-oxide/README.md b/cuda-oxide/crates/cargo-oxide/README.md index f9158e3c39..748ea851b7 100644 --- a/cuda-oxide/crates/cargo-oxide/README.md +++ b/cuda-oxide/crates/cargo-oxide/README.md @@ -52,6 +52,7 @@ cargo oxide update --force # inside the workspace, run setup via update | Flag | Applies to | Description | |------------------------------|----------------------------------|-------------------------------------------------| +| `--link-ltoir ` | run, sanitize, build, test, pipeline, debug | Add an ordered external LTO-IR file to `--materialize-cubin` (repeatable) | | `--materialize-cubin` | run, sanitize, build, test, pipeline, debug | Finalize and embed target-specific native GPU code during the host build | | `--emit-nvvm-ir` | run, build, pipeline | Generate NVVM IR for libNVVM | | `--arch ` | run, sanitize, build, test, pipeline, emit-ltoir, tilelib, inspect, debug | Target architecture override | @@ -121,9 +122,32 @@ rechecks them inside the backend; use the wrapper flag instead of setting `CUDA_OXIDE_MATERIALIZE_CUBIN` around raw Cargo. That variable is an internal wrapper/backend signal, not a supported user interface: raw Cargo may reuse a previous artifact without running the backend, and a backend invocation without -the wrapper's fingerprint is rejected. Generic `#[cuda_module]` kernels and -`#[device] extern` declarations are rejected because their run-time -multi-artifact linking is not yet represented by this single-cubin path. +the wrapper's fingerprint is rejected. Generic `#[cuda_module]` kernels remain +unsupported by this single-cubin path because they merge PTX bundles at run time. + +For non-generic kernels calling `#[device] extern` functions, pass the definitions +as ordered, repeatable `--link-ltoir ` inputs alongside `--materialize-cubin`. +Inputs must be raw CUDA LTO-IR, not object files or fatbins. Each supplied file +is linked into every materialized device artifact in that Cargo invocation. +Keep these inputs separate from generated artifact paths; an overlap is rejected +before cleanup or device output emission. +Paths are relative to the invocation directory. The wrapper fingerprints their +canonical names and contents, and the backend verifies and owns those bytes +before linking. Changing an input rebuilds the device artifact; a change during +the wrapper/backend handoff is an error. The Rust module is linked first, followed +by the supplied files in command-line order. CUDA reports unresolved symbols, +invalid LTO-IR, and unsupported toolkit/target combinations during the build. +Use compatible CUDA compiler and linker versions when generating the inputs. + +```bash +cargo oxide run --materialize-cubin --arch sm_120 \ + --link-ltoir build/device-libs/scale.ltoir --link-ltoir build/device-libs/add.ltoir +``` + +The [`external_ltoir` example](../rustc-codegen-cuda/examples/external_ltoir/README.md) +includes C++ sources and commands to generate these files and run the ordinary +embedded-artifact loader. Generated binaries are not source dependencies. + Metadata-interop projects keep rejecting this global flag; they can instead request one independently finalized cubin per declared device crate with `artifact-kind = "cubin"`, as described below. Materialization is also a @@ -326,6 +350,18 @@ links against. It builds the crate in NVVM IR mode, then runs the emitted `compute_XX`, or a bare `XX`. The default output path is `/.ltoir`; `-o/--output` overrides it. +For a standalone project, omit `` to use its Cargo target name. The +directory name may differ from the package name, and hyphens in the target name +become underscores in artifact filenames. A package-named target is preferred; +otherwise the package must have one binary or library target, or its target name +must be supplied explicitly. The positional `` is this Cargo target name; +`default-run` does not select artifacts. This also applies when invoked from a +member of a user Cargo workspace: that member supplies the target, and the IR +and default LTO-IR output are placed in the invocation directory. An explicit +`CUDA_OXIDE_PTX_DIR` selects the intermediate IR directory for both writing and +reading; relative values are resolved from the Cargo workspace root. The process +environment takes precedence over project configuration. + ```bash cargo oxide emit-ltoir standalone_device_fn --arch sm_100 cargo oxide emit-ltoir my_simt_crate --arch sm_120 -o build/simt.ltoir diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/artifacts.rs b/cuda-oxide/crates/cargo-oxide/src/commands/artifacts.rs index 94e2caaa36..37b49a0072 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/artifacts.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/artifacts.rs @@ -134,12 +134,25 @@ pub(super) fn generated_artifact_paths(project_dir: &Path, package_name: &str) - /// Remove stale generated artifacts (`.ptx`, `.ll`, `.ltoir`, `.cubin`) from a /// previous run so we can verify the build produces fresh output. -pub(super) fn clean_generated_files(example_dir: &Path, example: &str) { - for file in generated_artifact_paths(example_dir, example) { +pub(super) fn clean_generated_files( + example_dir: &Path, + example: &str, + external_inputs: &[PathBuf], +) -> Result<(), String> { + let outputs = generated_artifact_paths(example_dir, example); + // Check the whole deletion set before removing even the first file. + for output in &outputs { + for input in external_inputs { + cuda_artifact_finalizer::check_ltoir_input_output(input, output) + .map_err(|error| error.to_string())?; + } + } + for file in outputs { if file.exists() { let _ = std::fs::remove_file(file); } } + Ok(()) } /// Human-readable label for the selected output format. diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/build_run.rs b/cuda-oxide/crates/cargo-oxide/src/commands/build_run.rs index 27e7640d2b..0b74d36daf 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/build_run.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/build_run.rs @@ -87,7 +87,10 @@ pub fn codegen_run( std::process::exit(2); } - clean_generated_files(&example_dir, example); + clean_generated_files(&example_dir, example, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); println!("========================================="); println!("RUSTC-CODEGEN-CUDA: {}", example); @@ -256,7 +259,10 @@ pub fn codegen_sanitize( return; } - clean_generated_files(&example_dir, example); + clean_generated_files(&example_dir, example, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); println!("========================================="); println!("RUSTC-CODEGEN-CUDA SANITIZE: {}", example); @@ -381,7 +387,10 @@ pub fn codegen_build( std::process::exit(2); } - clean_generated_files(&example_dir, example); + clean_generated_files(&example_dir, example, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); println!("========================================="); println!("RUSTC-CODEGEN-CUDA BUILD: {}", example); diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/context.rs b/cuda-oxide/crates/cargo-oxide/src/commands/context.rs index 2e45a019bc..67df45fb83 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/context.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/context.rs @@ -25,6 +25,7 @@ pub struct OxideConfig { /// /// Built once at startup by [`resolve_context`] and passed by reference to /// every command handler. Avoids repeated filesystem walks and backend builds. +#[derive(Clone)] pub struct Context { /// Absolute path to the workspace root (contains top-level `Cargo.toml`). pub workspace_root: PathBuf, @@ -39,6 +40,8 @@ pub struct Context { pub is_workspace: bool, /// Project-local cuda-oxide defaults. pub config: OxideConfig, + /// Ordered external LTO-IR inputs from the command line. + pub link_ltoir: Vec, } impl Context { @@ -74,6 +77,7 @@ pub fn resolve_context() -> Context { let config = load_oxide_config(&workspace_root); let backend_so = backend::find_or_build_backend(&workspace_root, config.backend.as_deref()); return Context { + link_ltoir: Vec::new(), workspace_root, codegen_crate, examples_dir, @@ -92,6 +96,7 @@ pub fn resolve_context() -> Context { let config = load_oxide_config(&cwd); let backend_so = backend::find_or_build_backend(&cwd, config.backend.as_deref()); return Context { + link_ltoir: Vec::new(), workspace_root: cwd.clone(), codegen_crate: cwd.clone(), examples_dir: cwd.clone(), @@ -124,6 +129,7 @@ pub fn resolve_passive_context() -> Context { let config = load_oxide_config_lenient(&workspace_root); let backend_so = backend::backend_so_candidate(&workspace_root, config.backend.as_deref()); return Context { + link_ltoir: Vec::new(), workspace_root, codegen_crate, examples_dir, @@ -142,6 +148,7 @@ pub fn resolve_passive_context() -> Context { let config = load_oxide_config_lenient(&cwd); let backend_so = backend::backend_so_candidate(&cwd, config.backend.as_deref()); return Context { + link_ltoir: Vec::new(), workspace_root: cwd.clone(), codegen_crate: cwd.clone(), examples_dir: cwd.clone(), diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/fingerprint.rs b/cuda-oxide/crates/cargo-oxide/src/commands/fingerprint.rs index c37e7c3435..3c00510b3b 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/fingerprint.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/fingerprint.rs @@ -78,6 +78,7 @@ pub(super) fn passthrough_codegen_fingerprint_with_env( // Descriptor identity only accelerates verification; artifact identity is // already represented by the content-derived provenance above. effective_env.remove(MATERIALIZER_HANDSHAKE_ENV); + effective_env.remove(EXTERNAL_LTOIR_ENV); if opts.verbose { effective_env.insert("CUDA_OXIDE_VERBOSE".to_string(), b"1".to_vec()); @@ -95,6 +96,10 @@ pub(super) fn passthrough_codegen_fingerprint_with_env( effective_env.insert("CUDA_OXIDE_EMIT_NVVM_IR".to_string(), b"1".to_vec()); } if let Some(prepared) = &materialization.prepared { + effective_env.insert( + EXTERNAL_LTOIR_ENV.to_string(), + prepared.external_ltoir_json.as_bytes().to_vec(), + ); effective_env.insert(MATERIALIZE_ENV.to_string(), b"1".to_vec()); effective_env.insert( EXPECTED_PROVENANCE_ENV.to_string(), diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/host_cargo.rs b/cuda-oxide/crates/cargo-oxide/src/commands/host_cargo.rs index 179ad7bb6f..2bf3bd2e28 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/host_cargo.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/host_cargo.rs @@ -268,6 +268,62 @@ pub(super) struct CargoExecutableArtifact { pub(super) path: PathBuf, } +/// Infer the artifact stem for a standalone project from Cargo's targets. +/// Keep the package-named target when present, as for workspace examples; +/// otherwise a sole binary or library target supplies its own crate name. +pub fn standalone_crate_name(manifest_dir: &Path) -> Result { + let metadata = cargo_metadata(manifest_dir)?; + let manifest_path = manifest_dir.join("Cargo.toml"); + let manifest_path = manifest_path + .canonicalize() + .map_err(|error| format!("could not resolve {}: {error}", manifest_path.display()))?; + let packages = metadata + .get("packages") + .and_then(|packages| packages.as_array()) + .ok_or_else(|| "Cargo metadata did not include packages".to_string())?; + let selected = cargo_selected_packages(&metadata, packages, &manifest_path)?; + let [package] = selected.as_slice() else { + return Err("run from a single Cargo package to select its device artifact".to_string()); + }; + let package_name = cargo_package_name(package)?; + let targets = package + .get("targets") + .and_then(|targets| targets.as_array()) + .ok_or_else(|| "Cargo metadata did not include package targets".to_string())?; + let mut names: Vec<_> = targets + .iter() + .filter(|target| { + target + .get("kind") + .and_then(|kind| kind.as_array()) + .is_some_and(|kinds| { + kinds.iter().any(|kind| { + matches!( + kind.as_str(), + Some("bin" | "lib" | "rlib" | "staticlib" | "cdylib" | "dylib") + ) + }) + }) + }) + .filter_map(|target| target.get("name").and_then(|name| name.as_str())) + .map(artifact_stem) + .collect(); + names.sort(); + names.dedup(); + let package_stem = artifact_stem(package_name); + if names.contains(&package_stem) { + return Ok(package_stem); + } + if let [name] = names.as_slice() { + return Ok(name.clone()); + } + Err(format!( + "could not choose a device artifact for package `{package_name}`; \ + pass the binary or library target name explicitly (available: {})", + names.join(", ") + )) +} + pub(super) fn cargo_executable_selection( manifest_dir: &Path, explicit_bin: Option<&str>, @@ -365,7 +421,7 @@ fn cargo_package_manifest_matches(package: &serde_json::Value, manifest_path: &P .is_some_and(|path| path == manifest_path) } -fn cargo_metadata(manifest_dir: &Path) -> Result { +pub(super) fn cargo_metadata(manifest_dir: &Path) -> Result { let output = Command::new("cargo") .env("RUSTC_BOOTSTRAP", "1") .args(["metadata", "--format-version=1", "--no-deps"]) diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/interop.rs b/cuda-oxide/crates/cargo-oxide/src/commands/interop.rs index 13d8c532ec..4ea4603dbd 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/interop.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/interop.rs @@ -573,7 +573,10 @@ fn build_interop_device_crate( } let artifact_name = interop_device_artifact_name(&manifest_path, device_crate); - clean_generated_files(&artifact_dir, &artifact_name); + clean_generated_files(&artifact_dir, &artifact_name, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); if let Some(target) = &binary_target { touch_source_file(&target.source_path); } else { diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/ltoir.rs b/cuda-oxide/crates/cargo-oxide/src/commands/ltoir.rs index feecbef80e..de1f612339 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/ltoir.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/ltoir.rs @@ -3,7 +3,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -use std::path::Path; +use std::path::{Path, PathBuf}; use super::*; @@ -56,12 +56,26 @@ pub fn emit_ltoir( }); let sm_arch = parsed_arch.sm(); + // Cargo invokes rustc from its workspace root even when the selected + // package is a member. Pin this command's IR directory explicitly instead + // of deriving it from the compiler's working directory. + let (build_ctx, ir_dir) = + ltoir_build_context(ctx, &example_dir, std::env::var_os("CUDA_OXIDE_PTX_DIR")) + .unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(1); + }); + clean_generated_files(&ir_dir, example, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); + // Step 1: build in NVVM IR mode so the backend writes `.ll` as // libNVVM-ready NVVM IR. codegen_build exits on build failure. Pass // quiet=true so the intermediate "✓ Build succeeded" line is suppressed; // emit_ltoir prints its own unified summary at the end. codegen_build( - ctx, + &build_ctx, example, verbose, true, @@ -76,7 +90,7 @@ pub fn emit_ltoir( ); // Step 2: compile that NVVM IR to LTOIR via libNVVM -gen-lto. - let ll_path = emitted_ll_path(&example_dir, example); + let ll_path = emitted_ll_path(&ir_dir, example); let ir = std::fs::read(&ll_path).unwrap_or_else(|e| { eprintln!( "Error: could not read emitted NVVM IR at {}: {e}", @@ -165,6 +179,51 @@ pub fn emit_ltoir( ); } +/// Select the same IR directory for the build and subsequent reader. Keep an +/// inherited override strongest, followed by project config. Relative explicit +/// paths are relative to rustc's Cargo workspace cwd, matching existing backend +/// semantics. Without an override, emit-ltoir owns its invocation directory. +pub(super) fn ltoir_build_context( + ctx: &Context, + example_dir: &Path, + inherited_dir: Option, +) -> Result<(Context, PathBuf), String> { + let configured = inherited_dir + .or_else(|| project_config_env(ctx, "CUDA_OXIDE_PTX_DIR").map(std::ffi::OsString::from)); + let ir_dir = match configured { + None => example_dir.to_path_buf(), + Some(path) => { + let path = PathBuf::from(path); + if path.is_absolute() { + path + } else { + let metadata = cargo_metadata(example_dir)?; + let root = metadata + .get("workspace_root") + .and_then(|path| path.as_str()) + .ok_or_else(|| "Cargo metadata did not include workspace_root".to_string())?; + Path::new(root).join(path) + } + } + }; + let value = ir_dir.to_str().ok_or_else(|| { + format!( + "NVVM IR output directory is not Unicode: {}", + ir_dir.display() + ) + })?; + let mut build_ctx = ctx.clone(); + build_ctx + .config + .env + .retain(|(key, _)| key != "CUDA_OXIDE_PTX_DIR"); + build_ctx + .config + .env + .push(("CUDA_OXIDE_PTX_DIR".into(), value.into())); + Ok((build_ctx, ir_dir)) +} + /// Normalize a target architecture to libNVVM's `compute_XX` form. /// /// Accepts `sm_XX` (the form `--arch` and the rest of cargo-oxide use), diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/materialize.rs b/cuda-oxide/crates/cargo-oxide/src/commands/materialize.rs index 80dee3ee40..6b3b5beb56 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/materialize.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/materialize.rs @@ -9,6 +9,7 @@ use std::process::Command; use super::*; +pub(super) const EXTERNAL_LTOIR_ENV: &str = reserved_oxide_symbols::EXTERNAL_LTOIR_ENV; pub(super) const MATERIALIZE_ENV: &str = reserved_oxide_symbols::MATERIALIZE_CUBIN_ENV; pub(super) const EXPECTED_PROVENANCE_ENV: &str = reserved_oxide_symbols::MATERIALIZER_PROVENANCE_ENV; @@ -31,6 +32,7 @@ pub(super) struct MaterializationMode { pub(super) struct PreparedMaterialization { pub(super) provenance_sha256_hex: String, pub(super) tool_identity_handshake_json: String, + pub(super) external_ltoir_json: String, } impl MaterializationMode { @@ -39,10 +41,13 @@ impl MaterializationMode { } pub(super) fn apply(&self, cmd: &mut Command) { + // Never honor an inherited internal external-input list. + cmd.env_remove(EXTERNAL_LTOIR_ENV); if let Some(prepared) = &self.prepared { // These override inherited/project values: they are a single // wrapper-generated handshake tied to this Cargo invocation. - cmd.env(MATERIALIZE_ENV, "1") + cmd.env(EXTERNAL_LTOIR_ENV, &prepared.external_ltoir_json) + .env(MATERIALIZE_ENV, "1") .env(EXPECTED_PROVENANCE_ENV, &prepared.provenance_sha256_hex) .env( MATERIALIZER_HANDSHAKE_ENV, @@ -205,6 +210,14 @@ fn prepare_materialization_result_with_env( .parse() .map_err(|error| format!("invalid materialization target {arch:?}: {error}"))?; + let external_inputs = ctx + .link_ltoir + .iter() + .map(|path| cuda_artifact_finalizer::LtoirFile::capture(path)) + .collect::, _>>() + .map_err(|error| format!("could not capture external LTO-IR: {error}"))?; + let external_ltoir_json = serde_json::to_string(&external_inputs) + .map_err(|error| format!("could not encode external LTO-IR inputs: {error}"))?; let handshake = discover_materializer_handshake(ctx)?; let handshake_json = serde_json::to_string(&handshake) .map_err(|error| format!("could not encode materializer handshake: {error}"))?; @@ -212,6 +225,7 @@ fn prepare_materialization_result_with_env( prepared: Some(PreparedMaterialization { provenance_sha256_hex: digest_hex(&handshake.provenance_sha256), tool_identity_handshake_json: handshake_json, + external_ltoir_json, }), }) } diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/mod.rs b/cuda-oxide/crates/cargo-oxide/src/commands/mod.rs index 10bc374ee6..81e29f322a 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/mod.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/mod.rs @@ -40,6 +40,7 @@ pub use doctor::*; pub use examples_list::*; use fingerprint::*; pub use fmt::*; +pub use host_cargo::standalone_crate_name; use host_cargo::*; use interop::*; pub use ltoir::*; diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/pipeline_debug.rs b/cuda-oxide/crates/cargo-oxide/src/commands/pipeline_debug.rs index f84a54f918..43543c2436 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/pipeline_debug.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/pipeline_debug.rs @@ -41,7 +41,10 @@ pub fn codegen_show_pipeline( reject_interop_output_mode(emit_nvvm_ir, &materialization); } - clean_generated_files(&example_dir, example); + clean_generated_files(&example_dir, example, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); println!("========================================="); println!("RUSTC-CODEGEN-CUDA PIPELINE: {}", example); @@ -196,7 +199,10 @@ pub fn codegen_debug( println!("Detected GPU arch: {dev} (via nvidia-smi)"); } - clean_generated_files(&example_dir, example); + clean_generated_files(&example_dir, example, &ctx.link_ltoir).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(2); + }); touch_main_rs(&example_dir); diff --git a/cuda-oxide/crates/cargo-oxide/src/commands/tests.rs b/cuda-oxide/crates/cargo-oxide/src/commands/tests.rs index 2ddcaeb911..7324ac290c 100644 --- a/cuda-oxide/crates/cargo-oxide/src/commands/tests.rs +++ b/cuda-oxide/crates/cargo-oxide/src/commands/tests.rs @@ -177,6 +177,7 @@ fn cargo_artifact_freshness( fn test_context(config: OxideConfig) -> Context { Context { + link_ltoir: Vec::new(), workspace_root: PathBuf::from("/tmp/cargo-oxide-test-workspace"), codegen_crate: PathBuf::from("/tmp/cargo-oxide-test-codegen"), examples_dir: PathBuf::from("/tmp/cargo-oxide-test-examples"), @@ -463,6 +464,127 @@ fn emit_ltoir_paths_use_normalized_crate_stem() { assert_eq!(default_ltoir_path(dir, "vecadd"), dir.join("vecadd.ltoir")); } +#[test] +fn standalone_artifact_name_comes_from_cargo_targets() { + for (target, source, expected) in [ + ("", "src/main.rs", "device_export"), + ( + "[[bin]]\nname = \"custom-bin\"\npath = \"src/main.rs\"\n", + "src/main.rs", + "custom_bin", + ), + ( + "[lib]\nname = \"custom_library\"\n", + "src/lib.rs", + "custom_library", + ), + ] { + let root = unique_temp_dir("directory_unrelated_to_package"); + std::fs::create_dir_all(root.join("src")).unwrap(); + std::fs::write( + root.join("Cargo.toml"), + format!( + "[package]\nname = \"device-export\"\nversion = \"0.1.0\"\n\ + edition = \"2024\"\n[workspace]\n{target}" + ), + ) + .unwrap(); + std::fs::write(root.join(source), "fn main() {}\n").unwrap(); + + let name = standalone_crate_name(&root).unwrap(); + assert_eq!(name, expected); + assert_eq!( + emitted_ll_path(&root, &name), + root.join(format!("{expected}.ll")) + ); + assert_eq!( + default_ltoir_path(&root, &name), + root.join(format!("{expected}.ltoir")) + ); + std::fs::remove_dir_all(root).unwrap(); + } +} + +#[test] +fn standalone_artifact_name_preserves_package_target_and_rejects_ambiguity() { + let root = unique_temp_dir("cargo_oxide_artifact_multi_target"); + std::fs::create_dir_all(root.join("src")).unwrap(); + std::fs::write(root.join("src/main.rs"), "fn main() {}\n").unwrap(); + std::fs::write(root.join("src/other.rs"), "fn main() {}\n").unwrap(); + for name in ["device-export", "other-package"] { + std::fs::write( + root.join("Cargo.toml"), + format!( + "[package]\nname = \"{name}\"\nversion = \"0.1.0\"\n\ + edition = \"2024\"\ndefault-run = \"other\"\n[workspace]\n\ + [[bin]]\nname = \"device-export\"\npath = \"src/main.rs\"\n\ + [[bin]]\nname = \"other\"\npath = \"src/other.rs\"\n" + ), + ) + .unwrap(); + let result = standalone_crate_name(&root); + if name == "device-export" { + // `cargo build` builds both bins; default-run does not select the IR. + assert_eq!(result.unwrap(), "device_export"); + } else { + let error = result.unwrap_err(); + assert!( + error.contains("pass the binary or library target name explicitly"), + "{error}" + ); + } + } + std::fs::remove_dir_all(root).unwrap(); +} + +#[test] +fn standalone_artifact_name_uses_workspace_package_selection() { + let root = unique_temp_dir("cargo_oxide_artifact_workspace"); + std::fs::create_dir_all(&root).unwrap(); + std::fs::write( + root.join("Cargo.toml"), + "[workspace]\nmembers = [\"first\", \"second\"]\ndefault-members = [\"first\"]\nresolver = \"3\"\n", + ) + .unwrap(); + for member in ["first", "second"] { + let dir = root.join(member); + std::fs::create_dir_all(dir.join("src")).unwrap(); + std::fs::write( + dir.join("Cargo.toml"), + format!( + "[package]\nname = \"{member}-package\"\nversion = \"0.1.0\"\nedition = \"2024\"\n" + ), + ) + .unwrap(); + std::fs::write(dir.join("src/main.rs"), "fn main() {}\n").unwrap(); + } + assert_eq!(standalone_crate_name(&root).unwrap(), "first_package"); + let member = root.join("second"); + assert_eq!(standalone_crate_name(&member).unwrap(), "second_package"); + let ctx = test_context(OxideConfig::default()); + let (build_ctx, ir_dir) = ltoir_build_context(&ctx, &member, None).unwrap(); + assert_eq!(ir_dir, member); + assert_eq!( + project_config_env(&build_ctx, "CUDA_OXIDE_PTX_DIR"), + member.to_str() + ); + + // An explicit relative backend override retains Cargo workspace semantics, + // even though this command was invoked from a different selected member. + let mut ctx = ctx; + ctx.config + .env + .push(("CUDA_OXIDE_PTX_DIR".into(), "configured-ir".into())); + let (_, configured) = ltoir_build_context(&ctx, &member, None).unwrap(); + assert_eq!( + configured, + root.canonicalize().unwrap().join("configured-ir") + ); + let (_, inherited) = ltoir_build_context(&ctx, &member, Some("inherited-ir".into())).unwrap(); + assert_eq!(inherited, root.canonicalize().unwrap().join("inherited-ir")); + std::fs::remove_dir_all(root).unwrap(); +} + #[test] fn generated_file_cleanup_preserves_ltoir_cubin_cache() { let unique = std::time::SystemTime::now() @@ -482,7 +604,7 @@ fn generated_file_cleanup_preserves_ltoir_cubin_cache() { std::fs::create_dir_all(cached_cubin.parent().unwrap()).unwrap(); std::fs::write(&cached_cubin, b"persistent cache entry").unwrap(); - clean_generated_files(&root, "my-kernel"); + clean_generated_files(&root, "my-kernel", &[]).unwrap(); for extension in ["ptx", "ll", "ltoir", "cubin", "target"] { assert!(!root.join(format!("my_kernel.{extension}")).exists()); @@ -522,6 +644,7 @@ edition = "2024" std::fs::write(&cached_cubin, b"persistent cache").unwrap(); let ctx = Context { + link_ltoir: Vec::new(), workspace_root: root.clone(), codegen_crate: root.clone(), examples_dir: root.clone(), @@ -584,6 +707,7 @@ fn workspace_clean_covers_example_and_model_roots_in_flat_and_nested_layouts() { std::fs::write(model_dir.join("decoder.cubin"), b"generated").unwrap(); std::fs::write(cute_dir.join("other.cubin"), b"preserve").unwrap(); let ctx = Context { + link_ltoir: Vec::new(), workspace_root: root.clone(), codegen_crate: codegen_crate.clone(), examples_dir, @@ -642,6 +766,7 @@ edition = "2024" symlink(&external, root.join("target")).unwrap(); let ctx = Context { + link_ltoir: Vec::new(), workspace_root: root.clone(), codegen_crate: root.clone(), examples_dir: root.clone(), @@ -3153,6 +3278,7 @@ device-owner = { path = "../device-owner" } .unwrap(); let ctx = Context { + link_ltoir: Vec::new(), workspace_root: root.clone(), codegen_crate: root.join("unused-codegen-source"), examples_dir: root.join("unused-examples"), @@ -3316,6 +3442,7 @@ shared-dep = { path = "../shared-dep" } fn scratch_workspace_context(root: &Path) -> Context { Context { + link_ltoir: Vec::new(), workspace_root: root.to_path_buf(), codegen_crate: root.join("unused-codegen-source"), examples_dir: root.join("unused-examples"), @@ -3595,6 +3722,7 @@ fn passthrough_fingerprint_tracks_output_affecting_settings() { let materialized = MaterializationMode { prepared: Some(PreparedMaterialization { provenance_sha256_hex: "ab".repeat(32), + external_ltoir_json: "[]".to_string(), tool_identity_handshake_json: "{\"version\":1}".to_string(), }), }; @@ -3612,6 +3740,96 @@ fn passthrough_fingerprint_tracks_output_affecting_settings() { ); } +#[test] +fn cleanup_preserves_all_artifacts_when_a_link_input_overlaps() { + let root = unique_temp_dir("cargo_oxide_input_output_overlap"); + fs::create_dir_all(&root).unwrap(); + let first_output = root.join("my_kernel.ptx"); + let input = root.join("my_kernel.ltoir"); + fs::write(&first_output, b"previous output").unwrap(); + fs::write(&input, b"external input").unwrap(); + + let error = + clean_generated_files(&root, "my-kernel", std::slice::from_ref(&input)).unwrap_err(); + assert!(error.contains("move the external input"), "{error}"); + assert_eq!(fs::read(&input).unwrap(), b"external input"); + assert_eq!(fs::read(&first_output).unwrap(), b"previous output"); + + #[cfg(unix)] + for hard_link in [false, true] { + let alias = root.join("external.ltoir"); + if hard_link { + fs::hard_link(&input, &alias).unwrap(); + } else { + std::os::unix::fs::symlink(&input, &alias).unwrap(); + } + assert!(clean_generated_files(&root, "my-kernel", std::slice::from_ref(&alias)).is_err()); + assert_eq!(fs::read(&alias).unwrap(), b"external input"); + assert_eq!(fs::read(&first_output).unwrap(), b"previous output"); + fs::remove_file(alias).unwrap(); + } + + let separate = root.join("separate.ltoir"); + fs::rename(&input, &separate).unwrap(); + clean_generated_files(&root, "my-kernel", std::slice::from_ref(&separate)).unwrap(); + assert!(!first_output.exists()); + assert_eq!(fs::read(&separate).unwrap(), b"external input"); + fs::remove_dir_all(root).unwrap(); +} + +#[test] +fn external_ltoir_order_and_contents_change_the_codegen_fingerprint() { + let ctx = test_context(OxideConfig::default()); + let opts = CargoPassthroughOptions { + verbose: false, + emit_nvvm_ir: false, + arch: Some("sm_120"), + features: None, + cargo_target_dir: None, + device_codegen_crate: None, + device_cfgs: &[], + no_fmad: false, + unchecked_indexing: false, + materialize_cubin: true, + device_debug: DeviceDebug::Off, + debug_assertions: false, + }; + let root = unique_temp_dir("cargo_oxide_external_ltoir"); + fs::create_dir_all(&root).unwrap(); + let first = root.join("first.ltoir"); + let second = root.join("second.ltoir"); + fs::write(&first, b"first").unwrap(); + fs::write(&second, b"other").unwrap(); + let fingerprint = |paths: &[&Path]| { + let inputs: Vec<_> = paths + .iter() + .map(|path| cuda_artifact_finalizer::LtoirFile::capture(path).unwrap()) + .collect(); + let mode = MaterializationMode { + prepared: Some(PreparedMaterialization { + provenance_sha256_hex: "ab".repeat(32), + tool_identity_handshake_json: "{}".into(), + external_ltoir_json: serde_json::to_string(&inputs).unwrap(), + }), + }; + passthrough_codegen_fingerprint_with_env( + &ctx, + &opts, + None, + Some("sm_120"), + &mode, + &BTreeMap::new(), + ) + }; + let original = fingerprint(&[&first, &second]); + assert_eq!(original, fingerprint(&[&first, &second])); + assert_ne!(original, fingerprint(&[&second, &first])); + fs::write(&first, b"later").unwrap(); + assert_ne!(original, fingerprint(&[&first, &second])); + assert_ne!(original, fingerprint(&[&second])); + fs::remove_dir_all(root).unwrap(); +} + #[test] fn passthrough_fingerprint_tracks_the_managed_cutlass_library_digest() { let ctx = test_context(OxideConfig::default()); @@ -3937,6 +4155,7 @@ fn materialization_forces_nvvm_ir_and_exact_provenance_handshake() { let materialization = MaterializationMode { prepared: Some(PreparedMaterialization { provenance_sha256_hex: "42".repeat(32), + external_ltoir_json: "[]".to_string(), tool_identity_handshake_json: "{\"version\":1}".to_string(), }), }; @@ -5474,6 +5693,7 @@ fn read_ptx_artifact_reports_missing_file() { #[test] fn nvvm_ir_requested_reads_project_configuration() { let ctx = Context { + link_ltoir: Vec::new(), workspace_root: PathBuf::from("/tmp/project"), codegen_crate: PathBuf::from("/tmp/project"), examples_dir: PathBuf::from("/tmp/project"), @@ -5491,6 +5711,7 @@ fn nvvm_ir_requested_reads_project_configuration() { #[test] fn nvvm_ir_requested_accepts_disabled_project_configuration() { let ctx = Context { + link_ltoir: Vec::new(), workspace_root: PathBuf::from("/tmp/project"), codegen_crate: PathBuf::from("/tmp/project"), examples_dir: PathBuf::from("/tmp/project"), @@ -5508,6 +5729,7 @@ fn nvvm_ir_requested_accepts_disabled_project_configuration() { #[test] fn nvvm_ir_requested_env_disable_overrides_enabled_project_configuration() { let ctx = Context { + link_ltoir: Vec::new(), workspace_root: PathBuf::from("/tmp/project"), codegen_crate: PathBuf::from("/tmp/project"), examples_dir: PathBuf::from("/tmp/project"), @@ -6643,7 +6865,7 @@ fn tilelib_artifacts_are_cleaned_between_builds() { for file in &files { std::fs::write(file, b"stale").unwrap(); } - clean_generated_files(&root, "my-lib"); + clean_generated_files(&root, "my-lib", &[]).unwrap(); for file in &files { assert!(!file.exists(), "{} survived the clean", file.display()); } diff --git a/cuda-oxide/crates/cargo-oxide/src/main.rs b/cuda-oxide/crates/cargo-oxide/src/main.rs index bfd4524b61..fddc102931 100644 --- a/cuda-oxide/crates/cargo-oxide/src/main.rs +++ b/cuda-oxide/crates/cargo-oxide/src/main.rs @@ -77,6 +77,10 @@ enum Commands { DebugPolicy, /// Build and run an example, model, or project Run { + /// Link an external LTO-IR file, in argument order (repeatable). + /// Requires --materialize-cubin; paths are relative to the invocation directory. + #[arg(long)] + link_ltoir: Vec, /// Example or model name (required in workspace, optional for standalone projects) example: Option, /// Generate NVVM IR (use with libNVVM -gen-lto) @@ -128,6 +132,10 @@ enum Commands { }, /// Build and run an example or project under NVIDIA Compute Sanitizer Sanitize { + /// Link an external LTO-IR file, in argument order (repeatable). + /// Requires --materialize-cubin; paths are relative to the invocation directory. + #[arg(long)] + link_ltoir: Vec, /// Example name (required in workspace, optional for standalone projects) example: Option, /// Compute Sanitizer tool to run @@ -173,6 +181,10 @@ enum Commands { }, /// Build an example or project (compile only, don't run) Build { + /// Link an external LTO-IR file, in argument order (repeatable). + /// Requires --materialize-cubin; paths are relative to the invocation directory. + #[arg(long)] + link_ltoir: Vec, /// Example name (required in workspace, optional for standalone projects) example: Option, /// Generate NVVM IR (use with libNVVM -gen-lto) @@ -267,6 +279,10 @@ enum Commands { }, /// Run Cargo tests through the cuda-oxide backend Test { + /// Link an external LTO-IR file, in argument order (repeatable). + /// Requires --materialize-cubin; paths are relative to the invocation directory. + #[arg(long)] + link_ltoir: Vec, /// Target architecture (e.g., sm_90, sm_100, sm_120) #[arg(long)] arch: Option, @@ -406,6 +422,10 @@ enum Commands { }, /// Show the full compilation pipeline (MIR -> PTX/NVVM IR) with verbose output Pipeline { + /// Link an external LTO-IR file, in argument order (repeatable). + /// Requires --materialize-cubin; paths are relative to the invocation directory. + #[arg(long)] + link_ltoir: Vec, /// Example name (required in workspace, optional for standalone projects) example: Option, /// Generate NVVM IR (use with libNVVM -gen-lto) @@ -436,6 +456,10 @@ enum Commands { }, /// Build with debug info and launch cuda-gdb Debug { + /// Link an external LTO-IR file, in argument order (repeatable). + /// Requires --materialize-cubin; paths are relative to the invocation directory. + #[arg(long)] + link_ltoir: Vec, /// Example name (required in workspace, optional for standalone projects) example: Option, /// Target architecture (e.g., sm_90, sm_100, sm_120). When omitted, @@ -626,7 +650,22 @@ fn build_passthrough_trigger( } } +fn external_ltoir_inputs(command: &Commands) -> &[PathBuf] { + match command { + Commands::Run { link_ltoir, .. } + | Commands::Sanitize { link_ltoir, .. } + | Commands::Build { link_ltoir, .. } + | Commands::Test { link_ltoir, .. } + | Commands::Pipeline { link_ltoir, .. } + | Commands::Debug { link_ltoir, .. } => link_ltoir, + _ => &[], + } +} + fn validate_materialization_cli(cli: &Cli) -> Result<(), String> { + if !external_ltoir_inputs(&cli.command).is_empty() && !cli.materialize_cubin { + return Err("--link-ltoir requires --materialize-cubin".to_string()); + } if !cli.materialize_cubin { return Ok(()); } @@ -757,6 +796,12 @@ fn main() { .exit(); } let materialize_cubin = cli.materialize_cubin; + let link_ltoir = external_ltoir_inputs(&cli.command).to_vec(); + let resolve_context = || { + let mut ctx = commands::resolve_context(); + ctx.link_ltoir = link_ltoir.clone(); + ctx + }; match cli.command { Commands::MaterializerHandshake => { @@ -766,6 +811,7 @@ fn main() { commands::print_debug_policy(); } Commands::Run { + link_ltoir: _, example, emit_nvvm_ir, arch, @@ -779,7 +825,7 @@ fn main() { device_debug, app_args, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "run"); validate_output_arch( &ctx, @@ -805,6 +851,7 @@ fn main() { ); } Commands::Sanitize { + link_ltoir: _, example, tool, arch, @@ -817,7 +864,7 @@ fn main() { device_debug, sanitizer_args, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "sanitize"); validate_output_arch(&ctx, &example, false, materialize_cubin, arch.as_deref()); let (sanitizer_args, application_args) = @@ -839,6 +886,7 @@ fn main() { ); } Commands::Build { + link_ltoir: _, example, emit_nvvm_ir, arch, @@ -855,7 +903,7 @@ fn main() { device_cfgs, cargo_args, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let passthrough = use_build_passthrough( explicit_passthrough, cargo_target_dir.is_some(), @@ -945,7 +993,7 @@ fn main() { keep_going, fail_on_finding, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let (seed_start, seed_end) = ptx_schedule::campaign::parse_seed_range(&seeds) .unwrap_or_else(|error| { eprintln!("Error: {error}"); @@ -1009,6 +1057,7 @@ fn main() { } } Commands::Test { + link_ltoir: _, arch, cargo_target_dir, device_codegen_crate, @@ -1020,7 +1069,7 @@ fn main() { device_debug, cargo_args, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); validate_output_arch( &ctx, "cargo test", @@ -1059,7 +1108,7 @@ fn main() { lineinfo, device_debug, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "emit-ltoir"); commands::emit_ltoir( &ctx, @@ -1086,7 +1135,7 @@ fn main() { lineinfo, device_debug, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "tilelib"); commands::tilelib( &ctx, @@ -1103,6 +1152,7 @@ fn main() { ); } Commands::Pipeline { + link_ltoir: _, example, emit_nvvm_ir, arch, @@ -1111,7 +1161,7 @@ fn main() { lineinfo, device_debug, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "pipeline"); validate_output_arch( &ctx, @@ -1141,7 +1191,7 @@ fn main() { lineinfo, device_debug, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "inspect"); commands::codegen_inspect_ptx( &ctx, @@ -1155,6 +1205,7 @@ fn main() { ); } Commands::Debug { + link_ltoir: _, example, arch, features, @@ -1162,7 +1213,7 @@ fn main() { cgdb, tui, } => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); let example = resolve_example_name(example, &ctx, "debug"); validate_output_arch(&ctx, &example, false, materialize_cubin, arch.as_deref()); commands::codegen_debug( @@ -1203,7 +1254,7 @@ fn main() { commands::doctor(&ctx); } Commands::Setup => { - let ctx = commands::resolve_context(); + let ctx = resolve_context(); commands::setup(&ctx); } Commands::Update { force } => { @@ -1240,6 +1291,12 @@ fn resolve_example_name(name: Option, ctx: &commands::Context, subcomman return n; } if !ctx.is_workspace { + if subcommand == "emit-ltoir" { + return commands::standalone_crate_name(&ctx.workspace_root).unwrap_or_else(|error| { + eprintln!("Error: {error}"); + std::process::exit(1); + }); + } return std::env::current_dir() .ok() .and_then(|p| p.file_name().map(|n| n.to_string_lossy().into_owned())) @@ -1427,6 +1484,47 @@ mod tests { assert_eq!(device_features.as_deref(), Some("tensor-cores")); } + #[test] + fn external_ltoir_requires_materialization_and_preserves_order() { + let unmaterialized = + Cli::try_parse_from(["cargo-oxide", "build", "--link-ltoir", "one"]).unwrap(); + assert!(validate_materialization_cli(&unmaterialized).is_err()); + let cli = Cli::try_parse_from([ + "cargo-oxide", + "build", + "--link-ltoir", + "one", + "--materialize-cubin", + "--link-ltoir", + "two", + ]) + .unwrap(); + assert_eq!( + external_ltoir_inputs(&cli.command), + [ + std::path::PathBuf::from("one"), + std::path::PathBuf::from("two") + ] + ); + validate_materialization_cli(&cli).unwrap(); + + let run = Cli::try_parse_from([ + "cargo-oxide", + "run", + "--link-ltoir", + "one", + "external_ltoir", + "--materialize-cubin", + ]) + .unwrap(); + validate_materialization_cli(&run).unwrap(); + assert_eq!(external_ltoir_inputs(&run.command), [PathBuf::from("one")]); + let Commands::Run { example, .. } = run.command else { + panic!("expected run command"); + }; + assert_eq!(example.as_deref(), Some("external_ltoir")); + } + #[test] fn materialize_cubin_is_a_global_codegen_option() { let after_subcommand = Cli::try_parse_from([ diff --git a/cuda-oxide/crates/cuda-artifact-finalizer/src/lib.rs b/cuda-oxide/crates/cuda-artifact-finalizer/src/lib.rs index 6a014422de..6e02f0c34b 100644 --- a/cuda-oxide/crates/cuda-artifact-finalizer/src/lib.rs +++ b/cuda-oxide/crates/cuda-artifact-finalizer/src/lib.rs @@ -12,6 +12,7 @@ mod diagnostics; mod link; +mod ltoir_file; mod nvvm; mod options; mod provenance; @@ -21,6 +22,7 @@ mod validation; pub use diagnostics::KernelResourceUsage; pub use libnvvm_sys::{CudaArch, CudaArchParseError, LibdeviceNotFound, NvvmError, find_libdevice}; pub use link::{LinkReport, LtoLinker}; +pub use ltoir_file::{LtoirFile, check_ltoir_input_output}; pub use nvjitlink_sys::NvJitLinkError; pub use nvvm::NvvmCompiler; pub use options::{DebugPolicy, FinalizationOptions, FinalizerOutput, NamedInput}; @@ -37,6 +39,20 @@ use thiserror::Error; /// Failures while compiling or linking CUDA artifacts. #[derive(Debug, Error)] pub enum FinalizerError { + /// A file path cannot be transported losslessly to the CUDA linker. + #[error("external LTO-IR path is not Unicode: {path:?}")] + InvalidLtoirPath { path: PathBuf }, + + /// A link input changed after the wrapper computed Cargo's fingerprint. + #[error("external LTO-IR input changed after Cargo fingerprinting: {path}; rerun cargo oxide")] + LtoirInputChanged { path: PathBuf }, + + /// An output would delete or overwrite an explicitly supplied link input. + #[error( + "external LTO-IR input {input} overlaps generated artifact {output}; move the external input to a separate directory" + )] + LtoirInputOutputOverlap { input: PathBuf, output: PathBuf }, + /// libNVVM failed to load, validate, or compile. #[error("libnvvm: {0}")] Nvvm(#[from] libnvvm_sys::NvvmError), diff --git a/cuda-oxide/crates/cuda-artifact-finalizer/src/ltoir_file.rs b/cuda-oxide/crates/cuda-artifact-finalizer/src/ltoir_file.rs new file mode 100644 index 0000000000..92aff18147 --- /dev/null +++ b/cuda-oxide/crates/cuda-artifact-finalizer/src/ltoir_file.rs @@ -0,0 +1,163 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +//! Content-bound external inputs shared by Cargo fingerprinting and finalization. + +use std::path::{Path, PathBuf}; + +use serde::{Deserialize, Serialize}; +use sha2::{Digest, Sha256}; + +use crate::FinalizerError; + +/// Identity of an external LTO-IR file captured before Cargo decides freshness. +/// +/// The absolute path is also the linker's diagnostic input name. Preserve the +/// order of these records when fingerprinting and linking a list of inputs. +/// [`Self::read_verified`] returns owned bytes so a later file change cannot +/// alter the data submitted to the linker. +#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct LtoirFile { + path: PathBuf, + sha256: [u8; 32], +} + +impl LtoirFile { + /// Capture the canonical path and SHA-256 of a nonempty input file. + /// + /// Input paths must be Unicode so the same name can reach nvJitLink and + /// the compiler process without lossy conversion. CUDA validates the + /// LTO-IR format and target compatibility during finalization. + pub fn capture(path: &Path) -> Result { + let path = path.canonicalize().map_err(|source| FinalizerError::Io { + path: path.to_owned(), + source, + })?; + if path.to_str().is_none() { + return Err(FinalizerError::InvalidLtoirPath { path }); + } + let bytes = read(&path)?; + Ok(Self { + path, + sha256: Sha256::digest(&bytes).into(), + }) + } + + /// Diagnostic name included in the ordered compilation identity. + pub fn name(&self) -> Result<&str, FinalizerError> { + self.path + .to_str() + .ok_or_else(|| FinalizerError::InvalidLtoirPath { + path: self.path.clone(), + }) + } + + /// Read the exact captured content or fail if it changed before codegen. + pub fn read_verified(&self) -> Result, FinalizerError> { + let bytes = read(&self.path)?; + let actual: [u8; 32] = Sha256::digest(&bytes).into(); + if actual != self.sha256 { + return Err(FinalizerError::LtoirInputChanged { + path: self.path.clone(), + }); + } + Ok(bytes) + } +} + +/// Reject a generated output that aliases an existing external link input. +/// +/// Call before deleting or writing outputs. Canonical paths cover symlinks; +/// Unix file identity also covers hard links with different canonical paths. +pub fn check_ltoir_input_output(input: &Path, output: &Path) -> Result<(), FinalizerError> { + let input_path = input.canonicalize().map_err(|source| FinalizerError::Io { + path: input.to_owned(), + source, + })?; + let output_path = match output.canonicalize() { + Ok(path) => path, + Err(error) if error.kind() == std::io::ErrorKind::NotFound => return Ok(()), + Err(source) => { + return Err(FinalizerError::Io { + path: output.to_owned(), + source, + }); + } + }; + if input_path == output_path || same_file(&input_path, &output_path) { + return Err(FinalizerError::LtoirInputOutputOverlap { + input: input.to_owned(), + output: output.to_owned(), + }); + } + Ok(()) +} + +#[cfg(unix)] +fn same_file(a: &Path, b: &Path) -> bool { + use std::os::unix::fs::MetadataExt; + match (std::fs::metadata(a), std::fs::metadata(b)) { + (Ok(a), Ok(b)) => a.dev() == b.dev() && a.ino() == b.ino(), + _ => false, + } +} + +#[cfg(not(unix))] +fn same_file(_a: &Path, _b: &Path) -> bool { + false +} + +fn read(path: &Path) -> Result, FinalizerError> { + let bytes = std::fs::read(path).map_err(|source| FinalizerError::Io { + path: path.to_owned(), + source, + })?; + if bytes.is_empty() { + return Err(FinalizerError::EmptyInput { + name: path.display().to_string(), + }); + } + Ok(bytes) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn captured_input_checks_content_and_owns_verified_bytes() { + let path = std::env::temp_dir().join(format!( + "oxide-ltoir-{}-{}.test", + std::process::id(), + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() + )); + std::fs::write(&path, b"first").unwrap(); + let identity = LtoirFile::capture(&path).unwrap(); + let json = serde_json::to_string(&identity).unwrap(); + let restored: LtoirFile = serde_json::from_str(&json).unwrap(); + let owned = restored.read_verified().unwrap(); + std::fs::write(&path, b"other").unwrap(); + assert_eq!(owned, b"first"); + assert!(matches!( + restored.read_verified(), + Err(FinalizerError::LtoirInputChanged { .. }) + )); + assert_ne!(identity, LtoirFile::capture(&path).unwrap()); + std::fs::write(&path, []).unwrap(); + assert!(matches!( + LtoirFile::capture(&path), + Err(FinalizerError::EmptyInput { .. }) + )); + std::fs::remove_file(&path).unwrap(); + assert!(matches!( + restored.read_verified(), + Err(FinalizerError::Io { .. }) + )); + } +} diff --git a/cuda-oxide/crates/cuda-device/src/lib.rs b/cuda-oxide/crates/cuda-device/src/lib.rs index 67ee46790e..bdc255bb12 100644 --- a/cuda-oxide/crates/cuda-device/src/lib.rs +++ b/cuda-oxide/crates/cuda-device/src/lib.rs @@ -41,6 +41,8 @@ pub mod grid; pub mod i16x2; pub mod iket; pub mod int; +#[doc(hidden)] +pub mod library; pub mod mma_frag; pub mod prmt; pub mod ptx; diff --git a/cuda-oxide/crates/cuda-device/src/library.rs b/cuda-oxide/crates/cuda-device/src/library.rs new file mode 100644 index 0000000000..fb20b5ec78 --- /dev/null +++ b/cuda-oxide/crates/cuda-device/src/library.rs @@ -0,0 +1,58 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Internal, versioned boundary for native device library calls. +//! +//! This module is an unsafe compiler integration point, not a collective API. + +/// Read a Cargo-provided registration and track its native build dependencies. +/// +/// Pass the environment variable name as a string literal inside the registration +/// getter. Materialized builds query the provider for file, directory and +/// environment dependencies before rustc emits dep-info. Host checks and rustdoc +/// do not query CUDA inputs. Cargo's timestamp freshness rules still apply; +/// replacements with unchanged or older timestamps may not be detected. +/// +/// This snippet requires a build script to set `MY_LIBRARY_REGISTRATION`; the +/// `native_library` example compiles and runs the same registration pattern. +/// +/// ```ignore +/// fn registration() -> &'static str { +/// cuda_device::library::registration!("MY_LIBRARY_REGISTRATION") +/// } +/// ``` +pub use cuda_macros::library_registration as registration; + +/// Invoke a library recipe identified by a constant registration getter. +/// +/// Call this marker directly inside a wrapper; the marker itself is not a +/// device function pointer or callable-trait value. +/// +/// `Registration` must be a function item returning one constant UTF-8 JSON +/// string. The compiler reads its MIR without calling it. `Args` must be a +/// tuple of the exact scalar and raw-pointer types the provider declares. +/// `T` supplies the scalar type, and the const parameters supply the exact +/// one-dimensional block shape `[BLOCK_THREADS, 1, 1]` and per-thread extent. +/// +/// # Safety +/// +/// The caller must meet the provider's pointer, lifetime, initialization, +/// participation, and launch-geometry requirements. Library scratch views in +/// one kernel alias one dynamic shared base; the caller must synchronize before +/// reusing it. This version does not permit mixing native dynamic +/// shared views with library calls. It returns no allocation or ownership token. +#[inline(never)] +pub unsafe fn cuda_oxide_library_v1_246e25db_call< + T: Copy, + Registration: Fn() -> &'static str + Copy, + Args: Copy, + const BLOCK_THREADS: usize, + const ITEMS_PER_THREAD: usize, +>( + _registration: Registration, + _args: Args, +) { + panic!("library::call_v1 called outside device compilation"); +} + +pub use cuda_oxide_library_v1_246e25db_call as call_v1; diff --git a/cuda-oxide/crates/cuda-device/src/shared.rs b/cuda-oxide/crates/cuda-device/src/shared.rs index a6a7ed0c66..7ea7e73128 100644 --- a/cuda-oxide/crates/cuda-device/src/shared.rs +++ b/cuda-oxide/crates/cuda-device/src/shared.rs @@ -496,6 +496,28 @@ impl DynamicSharedArray { unreachable!("DynamicSharedArray::get called outside CUDA kernel context") } + /// Gets the block's dynamic shared-memory base with a fixed `T` extent. + /// + /// The compiler records `size_of::()` and the stronger of `ALIGN` and + /// `align_of::()` for checked launch preparation. Use an array or a + /// structure to describe the complete region. Every call returns the same + /// base address: multiple views share storage, they do not allocate separate + /// regions. Their required extents and alignments combine by maximum. + /// Inference follows Rust views through direct calls. Dynamic-base use in + /// external code, indirect calls, or inline assembly must fit a fixed view + /// declared on that path; the compiler does not inspect those accesses. + /// + /// # Safety + /// + /// Access only the declared `T` region, initialize values before reading, + /// and synchronize conflicting accesses across threads. Concurrent views + /// alias; this function establishes neither exclusive ownership nor a + /// synchronization barrier. Raw launches must allocate sufficient memory. + #[inline(never)] + pub unsafe fn get_fixed() -> *mut T { + unreachable!("DynamicSharedArray::get_fixed called outside CUDA kernel context") + } + /// Get a raw byte pointer to the start of dynamic shared memory. /// /// This is useful for manual memory management or when working @@ -766,3 +788,9 @@ impl SharedPtr { } include!("generated/shared_sreg.rs"); + +/// Selects compiler-produced dynamic shared-memory requirements. +/// Emitted by `#[launch_contract(dynamic_shared = inferred)]`. +#[doc(hidden)] +#[inline(never)] +pub fn __dynamic_shared_inferred() {} diff --git a/cuda-oxide/crates/cuda-host/Cargo.toml b/cuda-oxide/crates/cuda-host/Cargo.toml index 3906514968..f29218e7c9 100644 --- a/cuda-oxide/crates/cuda-host/Cargo.toml +++ b/cuda-oxide/crates/cuda-host/Cargo.toml @@ -33,6 +33,7 @@ async = ["dep:cuda-async", "cuda-macros/async"] [dev-dependencies] libloading = { workspace = true } -# The crates.io release cuda-core re-exports bundle types from; tests -# construct payloads with it so they use the same crate instance. +cuda-device = { workspace = true } +# The same artifact implementation cuda-core re-exports; tests construct +# payloads with it so they use the same crate instance. oxide-artifacts = { workspace = true } diff --git a/cuda-oxide/crates/cuda-host/src/embedded.rs b/cuda-oxide/crates/cuda-host/src/embedded.rs index 48776448f2..fcc25227fd 100644 --- a/cuda-oxide/crates/cuda-host/src/embedded.rs +++ b/cuda-oxide/crates/cuda-host/src/embedded.rs @@ -12,6 +12,7 @@ pub use cuda_core::embedded::{ embedded_modules_from_current_exe, }; use cuda_core::{CudaContext, CudaModule, DriverError}; +use std::collections::BTreeMap; use std::sync::Arc; use thiserror::Error; @@ -45,6 +46,10 @@ pub enum EmbeddedModuleError { #[error("embedded CUDA module '{name}' contains invalid PTX: {reason}")] InvalidPtx { name: String, reason: String }, + /// Bundles disagree about the requirements of the same concrete entry. + #[error("conflicting compiled launch facts for kernel '{symbol}'")] + ConflictingLaunchFacts { symbol: String }, + /// NVVM IR or LTOIR payload compilation failed. #[error("failed to build embedded CUDA module: {0}")] Ltoir(#[from] ltoir::LtoirError), @@ -137,7 +142,12 @@ pub fn load_all_ptx_bundles_merged( let bundles = artifact_bundles_from_current_exe()?; let merged = merge_ptx_bundles(&bundles)?; - let module = ctx.load_module_from_image(merged.as_bytes())?; + let facts = merged_launch_facts( + bundles + .iter() + .filter(|bundle| bundle.payload(ArtifactPayloadKind::Ptx).is_some()), + )?; + let module = ctx.load_module_from_image_with_launch_facts(merged.as_bytes(), facts)?; // Retain the merged module's `.entry` names (a few dozen bytes per // kernel). If a later `_TID_` generic-kernel lookup misses while a // same-base entry exists under a different hash, the launch paths can @@ -147,6 +157,32 @@ pub fn load_all_ptx_bundles_merged( Ok(module) } +fn merged_launch_facts<'a>( + bundles: impl IntoIterator, +) -> Result, EmbeddedModuleError> { + // Keep None in the comparison: absent facts must not silently replace a + // known zero-size plan, or inherit another bundle's contract. + let mut entries = BTreeMap::new(); + for bundle in bundles { + for entry in &bundle.entries { + if entry.kind != oxide_artifacts::ArtifactEntryKind::Kernel { + continue; + } + if let Some(previous) = entries.insert(entry.symbol.clone(), entry.launch_facts) + && previous != entry.launch_facts + { + return Err(EmbeddedModuleError::ConflictingLaunchFacts { + symbol: entry.symbol.clone(), + }); + } + } + } + Ok(entries + .into_iter() + .filter_map(|(symbol, facts)| facts.map(|facts| (symbol, facts))) + .collect()) +} + /// Merge the PTX payloads of `bundles`, in iteration order, into one PTX /// module string: the first PTX bundle keeps its `.version` / `.target` / /// `.address_size` header directives, every later one contributes its body @@ -297,12 +333,13 @@ fn load_bundle( ctx: &Arc, bundle: &OwnedArtifactBundle, ) -> Result, EmbeddedModuleError> { + let facts = merged_launch_facts([bundle])?; if let Some(cubin) = bundle.payload(ArtifactPayloadKind::Cubin) { - return Ok(ctx.load_module_from_image(cubin)?); + return Ok(ctx.load_module_from_image_with_launch_facts(cubin, facts)?); } if let Some(ptx) = bundle.payload(ArtifactPayloadKind::Ptx) { - return Ok(ctx.load_module_from_image(ptx)?); + return Ok(ctx.load_module_from_image_with_launch_facts(ptx, facts)?); } if let Some(nvvm_ir) = bundle.payload(ArtifactPayloadKind::NvvmIr) { @@ -322,7 +359,7 @@ fn load_bundle( bundle.compile_options, )?, }; - return Ok(ctx.load_module_from_image(&image)?); + return Ok(ctx.load_module_from_image_with_launch_facts(&image, facts)?); } if let Some(ltoir) = bundle.payload(ArtifactPayloadKind::Ltoir) { @@ -342,7 +379,7 @@ fn load_bundle( bundle.compile_options, )?, }; - return Ok(ctx.load_module_from_image(&image)?); + return Ok(ctx.load_module_from_image_with_launch_facts(&image, facts)?); } Err(EmbeddedModuleError::UnsupportedPayload { @@ -389,6 +426,59 @@ mod tests { } } + #[test] + fn merged_kernel_facts_preserve_identity_and_reject_conflicts() { + use oxide_artifacts::{ + ArtifactBundleSpec, ArtifactEntryKind, ArtifactEntrySpec, ArtifactPayloadSpec, + KernelLaunchFacts, + }; + let facts = KernelLaunchFacts { + exact_block: Some((32, 1, 1)), + dynamic_shared_bytes: 0, + dynamic_shared_alignment: 16, + }; + let bundle = |symbol: &str, facts| { + let mut entry = ArtifactEntrySpec::new(symbol, ArtifactEntryKind::Kernel); + entry.launch_facts = facts; + let spec = ArtifactBundleSpec::new("test", "sm_120") + .with_payload(ArtifactPayloadSpec::new( + ArtifactPayloadKind::Ptx, + "test.ptx", + b"ptx", + )) + .with_entry(entry); + let bytes = oxide_artifacts::build_artifact_blob(&spec).unwrap(); + OwnedArtifactBundle::from(oxide_artifacts::parse_artifact_blob(&bytes).unwrap()) + }; + let first = bundle("apply_items_1", Some(facts)); + let second = bundle( + "apply_items_4", + Some(KernelLaunchFacts { + dynamic_shared_bytes: 512, + ..facts + }), + ); + let merged = merged_launch_facts([&first, &second]).unwrap(); + assert_eq!(merged["apply_items_1"].dynamic_shared_bytes, 0); + assert_eq!(merged["apply_items_4"].dynamic_shared_bytes, 512); + for conflict in [ + bundle("apply_items_1", None), + bundle( + "apply_items_1", + Some(KernelLaunchFacts { + dynamic_shared_bytes: 128, + ..facts + }), + ), + ] { + assert!(matches!( + merged_launch_facts([&first, &conflict]), + Err(EmbeddedModuleError::ConflictingLaunchFacts { .. }) + )); + } + assert_eq!(merged_launch_facts([&first, &first]).unwrap().len(), 1); + } + #[test] fn target_arch_uses_bundle_sm_target() { assert_eq!( diff --git a/cuda-oxide/crates/cuda-macros/Cargo.toml b/cuda-oxide/crates/cuda-macros/Cargo.toml index 440290c02a..7d0a4a8b0f 100644 --- a/cuda-oxide/crates/cuda-macros/Cargo.toml +++ b/cuda-oxide/crates/cuda-macros/Cargo.toml @@ -38,6 +38,8 @@ host = [] [dependencies] quote = { workspace = true } syn = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } proc-macro2 = { workspace = true } reserved-oxide-symbols = { workspace = true } # `#[tile_export]` builds its description with the shared vocabulary and embeds diff --git a/cuda-oxide/crates/cuda-macros/src/cuda_module/contract.rs b/cuda-oxide/crates/cuda-macros/src/cuda_module/contract.rs index 1281fd70d9..b243f8ff3c 100644 --- a/cuda-oxide/crates/cuda-macros/src/cuda_module/contract.rs +++ b/cuda-oxide/crates/cuda-macros/src/cuda_module/contract.rs @@ -22,6 +22,7 @@ use syn::{ #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) enum DynamicSharedContract { + Inferred, Exact(u32), Range { min_bytes: u32, max_bytes: u32 }, } @@ -95,8 +96,19 @@ impl Parse for LaunchContractArgs { } "dynamic_shared" => { reject_duplicate(&key, dynamic_shared.is_some())?; - let value: syn::LitInt = input.parse()?; - dynamic_shared = Some(value.base10_parse::()?); + dynamic_shared = Some(if input.peek(syn::LitInt) { + let value: syn::LitInt = input.parse()?; + DynamicSharedContract::Exact(value.base10_parse::()?) + } else { + let value: Ident = input.parse()?; + if value != "inferred" { + return Err(syn::Error::new( + value.span(), + "dynamic_shared expects a byte count or `inferred`", + )); + } + DynamicSharedContract::Inferred + }); } "dynamic_shared_range" => { reject_duplicate(&key, dynamic_shared_range.is_some())?; @@ -149,7 +161,7 @@ impl Parse for LaunchContractArgs { )); } let dynamic_shared = match (dynamic_shared, dynamic_shared_range) { - (Some(bytes), None) => DynamicSharedContract::Exact(bytes), + (Some(requirement), None) => requirement, (None, Some((min_bytes, max_bytes))) if min_bytes <= max_bytes => { DynamicSharedContract::Range { min_bytes, @@ -165,6 +177,12 @@ impl Parse for LaunchContractArgs { (None, None) => DynamicSharedContract::Exact(0), (Some(_), Some(_)) => unreachable!(), }; + if dynamic_shared == DynamicSharedContract::Inferred && dynamic_shared_alignment.is_some() { + return Err(syn::Error::new( + input.span(), + "inferred dynamic shared memory obtains alignment from the compiled layout", + )); + } let dynamic_shared_alignment = dynamic_shared_alignment.unwrap_or_else(|| { if dynamic_shared_max(dynamic_shared) == 0 { 1 @@ -216,6 +234,7 @@ fn parse_requires_relations(input: ParseStream) -> syn::Result> { pub(crate) fn dynamic_shared_max(contract: DynamicSharedContract) -> u32 { match contract { + DynamicSharedContract::Inferred => 0, DynamicSharedContract::Exact(bytes) => bytes, DynamicSharedContract::Range { max_bytes, .. } => max_bytes, } diff --git a/cuda-oxide/crates/cuda-macros/src/cuda_module/launchers.rs b/cuda-oxide/crates/cuda-macros/src/cuda_module/launchers.rs index 279a15cce4..5a15350100 100644 --- a/cuda-oxide/crates/cuda-macros/src/cuda_module/launchers.rs +++ b/cuda-oxide/crates/cuda-macros/src/cuda_module/launchers.rs @@ -239,6 +239,9 @@ pub(super) fn generate_cuda_module_launch_contract_impl( }); let alignment = contract.dynamic_shared_alignment; let dynamic_shared = match contract.dynamic_shared { + DynamicSharedContract::Inferred => { + quote! { ::cuda_core::DynamicSharedMemoryRequirement::Inferred } + } DynamicSharedContract::Exact(bytes) => quote! { ::cuda_core::DynamicSharedMemoryRequirement::Exact { bytes: #bytes, diff --git a/cuda-oxide/crates/cuda-macros/src/cuda_module/mod.rs b/cuda-oxide/crates/cuda-macros/src/cuda_module/mod.rs index 58d0902427..469da973a1 100644 --- a/cuda-oxide/crates/cuda-macros/src/cuda_module/mod.rs +++ b/cuda-oxide/crates/cuda-macros/src/cuda_module/mod.rs @@ -342,7 +342,8 @@ pub(crate) fn expand_cuda_module_inner( /// /// Every loaded kernel must have the exact ABI and resource /// semantics declared by this `cuda_module`. A matching symbol - /// name alone is not sufficient. + /// name alone is not sufficient. Any attached compiled launch facts + /// must truthfully describe that exact loaded image and entry. pub unsafe fn from_module( module: ::std::sync::Arc<::cuda_core::CudaModule>, ) -> ::core::result::Result { diff --git a/cuda-oxide/crates/cuda-macros/src/kernel/scope.rs b/cuda-oxide/crates/cuda-macros/src/kernel/scope.rs index 872e34848a..8fc20d7391 100644 --- a/cuda-oxide/crates/cuda-macros/src/kernel/scope.rs +++ b/cuda-oxide/crates/cuda-macros/src/kernel/scope.rs @@ -584,13 +584,18 @@ pub(crate) fn is_kernel_configuration_marker(statement: &Stmt) -> bool { || segments[0].ident != "cuda_device" || !matches!(segments[0].arguments, PathArguments::None) || !matches!(segments[1].arguments, PathArguments::None) - || !matches!(segments[2].arguments, PathArguments::AngleBracketed(_)) { return false; } let module = &segments[1].ident; let marker = &segments[2].ident; + if module == "shared" && marker == "__dynamic_shared_inferred" { + return !unsafe_wrapped && matches!(segments[2].arguments, PathArguments::None); + } + if !matches!(segments[2].arguments, PathArguments::AngleBracketed(_)) { + return false; + } if unsafe_wrapped { module == "thread" && (marker == "__launch_contract_config" || marker == "__grid_constant_config") diff --git a/cuda-oxide/crates/cuda-macros/src/launch_attrs.rs b/cuda-oxide/crates/cuda-macros/src/launch_attrs.rs index b10f4cd455..411ef20210 100644 --- a/cuda-oxide/crates/cuda-macros/src/launch_attrs.rs +++ b/cuda-oxide/crates/cuda-macros/src/launch_attrs.rs @@ -181,7 +181,14 @@ pub(crate) fn inject_launch_contract_markers(args: &LaunchContractArgs, input: & next += 1; } - if dynamic_shared_max(args.dynamic_shared) != 0 { + if args.dynamic_shared == crate::cuda_module::contract::DynamicSharedContract::Inferred { + input.block.stmts.insert( + next, + parse_quote! { + ::cuda_device::shared::__dynamic_shared_inferred(); + }, + ); + } else if dynamic_shared_max(args.dynamic_shared) != 0 { let alignment = args.dynamic_shared_alignment as usize; let alignment_marker: syn::Stmt = parse_quote! { ::cuda_device::shared::__dynamic_shared_alignment::<#alignment>(); diff --git a/cuda-oxide/crates/cuda-macros/src/lib.rs b/cuda-oxide/crates/cuda-macros/src/lib.rs index 0a3d738b55..3e91b80752 100644 --- a/cuda-oxide/crates/cuda-macros/src/lib.rs +++ b/cuda-oxide/crates/cuda-macros/src/lib.rs @@ -29,7 +29,7 @@ //! so the same switch that turns host emission on also adds the `cuda-host` //! dependency that resolves it. -#![feature(proc_macro_def_site, proc_macro_tracked_env)] +#![feature(proc_macro_def_site, proc_macro_tracked_env, proc_macro_tracked_path)] mod common; mod cuda_module; @@ -37,6 +37,7 @@ mod device; mod kernel; mod launch; mod launch_attrs; +mod library; mod printf; mod ptx_asm; mod tile_export; @@ -649,8 +650,23 @@ pub fn launch_bounds(attr: TokenStream, item: TokenStream) -> TokenStream { /// the rest of the declared contract without preparation. /// /// Dynamic shared memory may be fixed with `dynamic_shared = BYTES` or bounded -/// with `dynamic_shared_range = (MIN, MAX)`. The byte extent remains an author -/// contract because arbitrary pointer arithmetic cannot be inferred. When the +/// with `dynamic_shared_range = (MIN, MAX)`. With `dynamic_shared = inferred`, +/// the compiler records the complete byte extent and alignment of unsafe +/// `DynamicSharedArray::get_fixed` views, including calls through helpers. +/// These views alias one dynamic base region; their extents combine by maximum, +/// not by addition. Mixing inferred views with unconstrained `get`, `get_raw`, +/// or `offset` access is rejected. Prepared launches require the matching +/// compiled artifact facts; `LaunchConfig1D::auto_shared` (and its 2D/3D +/// counterparts) selects the recorded byte count. An explicit byte count is +/// still checked before launch. Inferred alignment comes from the compiled +/// layouts, so it cannot be combined with `dynamic_shared_alignment`. +/// Inference follows Rust views through direct calls. Unsafe external code, +/// indirect calls and inline assembly may use the dynamic base only within a +/// fixed view declared on that path; their accesses are not analyzed. An inferred +/// kernel with no declared views records zero bytes. +/// +/// For raw dynamic pointers, the byte extent remains an author contract because +/// arbitrary pointer arithmetic cannot be inferred. When the /// maximum is non-zero, the macro injects a compiler marker whose call is /// removed before code generation. The declared `dynamic_shared_alignment` /// therefore becomes a minimum alignment in generated PTX without adding @@ -1015,10 +1031,14 @@ pub fn tile_export(attr: TokenStream, item: TokenStream) -> TokenStream { // NVVM Attributes for Device FFI // ============================================================================ -/// Marks a device function as convergent. +/// Marks an external device function declaration as convergent. /// -/// Convergent functions must be called by all threads in a warp/block together. -/// This prevents the optimizer from moving calls across control flow boundaries. +/// LLVM forbids transformations that add control dependencies to the call, +/// including before external device definitions are linked. The annotation +/// does not make threads reach the call or guarantee reconvergence. Callers +/// must satisfy the function's warp or block participation requirements. +/// Every declaration of the same symbol reachable in a device module must +/// agree on this annotation; conflicting declarations are rejected. /// /// # When to Use /// @@ -1039,77 +1059,32 @@ pub fn tile_export(attr: TokenStream, item: TokenStream) -> TokenStream { /// # Generated LLVM IR /// /// ```llvm -/// declare float @cub_block_reduce_sum(float, ptr) #0 -/// attributes #0 = { convergent nounwind } +/// declare float @cub_block_reduce_sum(float, ptr) convergent /// ``` #[proc_macro_attribute] pub fn convergent(_attr: TokenStream, item: TokenStream) -> TokenStream { - // This is a marker attribute - just pass through the item unchanged. - // The collector will read this attribute and apply the LLVM convergent attribute. - item + // The procedural attribute disappears during expansion. A doc alias is + // retained in metadata even for private foreign items, unlike doc comments. + let marker = reserved_oxide_symbols::DEVICE_EXTERN_CONVERGENT_MARKER; + let item = proc_macro2::TokenStream::from(item); + quote::quote!(#[doc(alias = #marker)] #item).into() } -/// Marks a device function as pure (no side effects). -/// -/// Pure functions only depend on their inputs and have no side effects. -/// This enables aggressive optimizations like CSE and dead code elimination. -/// -/// # When to Use -/// -/// - Math functions that don't access memory -/// - Functions that compute results purely from input arguments +/// Compatibility annotation for a pure device function. /// -/// # Example -/// -/// ```ignore -/// #[device] -/// extern "C" { -/// #[pure] -/// fn fast_rsqrt(x: f32) -> f32; -/// } -/// ``` -/// -/// # Generated LLVM IR -/// -/// ```llvm -/// declare float @fast_rsqrt(float) #0 -/// attributes #0 = { nounwind readnone } -/// ``` +/// This annotation is currently inactive: it records no compiler effect and +/// emits no LLVM memory-effect attributes. #[proc_macro_attribute] pub fn pure(_attr: TokenStream, item: TokenStream) -> TokenStream { - // Marker attribute - collector will read and apply LLVM readnone attribute item } -/// Marks a device function as read-only. +/// Compatibility annotation for a read-only device function. /// -/// Read-only functions may read memory but never write to it. -/// This enables optimizations like load hoisting and caching. -/// -/// # When to Use -/// -/// - Lookup table functions -/// - Functions that only read from input arrays -/// -/// # Example -/// -/// ```ignore -/// #[device] -/// extern "C" { -/// #[readonly] -/// fn lookup_table(table: *const f32, idx: i32) -> f32; -/// } -/// ``` -/// -/// # Generated LLVM IR -/// -/// ```llvm -/// declare float @lookup_table(ptr, i32) #0 -/// attributes #0 = { nounwind readonly } -/// ``` +/// This annotation is currently inactive: it records no compiler effect and +/// emits no LLVM memory-effect attributes. #[proc_macro_attribute] pub fn readonly(_attr: TokenStream, item: TokenStream) -> TokenStream { - // Marker attribute - collector will read and apply LLVM readonly attribute item } @@ -1275,3 +1250,16 @@ pub fn cuda_launch_async(input: TokenStream) -> TokenStream { let input = parse_macro_input!(input as CudaLaunchAsyncInput); expand_cuda_launch_async(input).into() } + +/// Embed a native library registration from a tracked environment variable. +/// +/// Re-exported as `cuda_device::library::registration!`. Tracks the provider +/// executable and, during CUBIN materialization, its declared native inputs. +/// Ordinary host and documentation builds do not query CUDA toolkit inputs. +#[proc_macro] +pub fn library_registration(input: TokenStream) -> TokenStream { + let variable = parse_macro_input!(input as syn::LitStr); + library::expand(&variable) + .unwrap_or_else(|error| syn::Error::new(variable.span(), error).to_compile_error()) + .into() +} diff --git a/cuda-oxide/crates/cuda-macros/src/library.rs b/cuda-oxide/crates/cuda-macros/src/library.rs new file mode 100644 index 0000000000..3de32d7759 --- /dev/null +++ b/cuda-oxide/crates/cuda-macros/src/library.rs @@ -0,0 +1,239 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Register native inputs during expansion, before rustc writes dep-info. + +use serde::{Deserialize, Serialize}; +use std::collections::BTreeSet; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::process::{Command, Stdio}; + +const MAX_JSON: usize = 1024 * 1024; + +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct Registration { + version: u32, + provider: String, + executable: PathBuf, + operation: String, + algorithm: String, +} + +#[derive(Serialize)] +struct InputRequest { + version: u32, + cuda_root: PathBuf, + target: String, +} + +#[derive(Deserialize)] +#[serde(deny_unknown_fields)] +struct InputResponse { + version: u32, + paths: Vec, + environment: Vec, +} + +fn environment(name: &str) -> Result, String> { + match proc_macro::tracked::env_var(name) { + Ok(value) => Ok(Some(value)), + Err(std::env::VarError::NotPresent) => Ok(None), + Err(error) => Err(format!("cannot read {name}: {error}")), + } +} + +fn registration(value: &str) -> Result { + if value.len() > MAX_JSON { + return Err("native library registration exceeds 1 MiB".into()); + } + let registration: Registration = serde_json::from_str(value) + .map_err(|error| format!("invalid native library registration: {error}"))?; + if registration.version != 1 + || registration.provider.is_empty() + || registration.operation.is_empty() + || registration.algorithm.is_empty() + || !registration.executable.is_absolute() + { + return Err("native library registration requires version 1, nonempty names and an absolute executable path".into()); + } + Ok(registration) +} + +fn response(bytes: &[u8]) -> Result { + if bytes.len() > MAX_JSON { + return Err("native library input response exceeds 1 MiB".into()); + } + let response: InputResponse = serde_json::from_slice(bytes) + .map_err(|error| format!("invalid native library input response: {error}"))?; + if response.version != 1 { + return Err("native library input response requires version 1".into()); + } + if response.paths.iter().any(|path| !path.is_absolute()) { + return Err("native library input paths must be absolute".into()); + } + if response + .environment + .iter() + .any(|name| name.is_empty() || name.as_bytes().iter().any(|byte| matches!(byte, b'=' | 0))) + { + return Err( + "native library input response has an invalid environment variable name".into(), + ); + } + Ok(response) +} + +fn query(executable: &Path, request: &InputRequest) -> Result { + let bytes = serde_json::to_vec(request).map_err(|error| error.to_string())?; + if bytes.len() > MAX_JSON { + return Err("native library input request exceeds 1 MiB".into()); + } + let mut child = Command::new(executable) + .arg("--oxide-library-inputs-v1") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .map_err(|error| { + format!( + "cannot query native library {}: {error}", + executable.display() + ) + })?; + let read = (|| { + child.stdin.take().unwrap().write_all(&bytes)?; + let mut output = Vec::new(); + child + .stdout + .take() + .unwrap() + .take((MAX_JSON + 1) as u64) + .read_to_end(&mut output)?; + Ok::<_, std::io::Error>(output) + })(); + let output = match read { + Ok(output) if output.len() <= MAX_JSON => output, + other => { + let _ = child.kill(); + let _ = child.wait(); + return Err(match other { + Err(error) => format!("native library input query failed: {error}"), + _ => "native library input response exceeds 1 MiB".into(), + }); + } + }; + let status = child.wait().map_err(|error| error.to_string())?; + if !status.success() { + return Err(format!("native library input query exited with {status}")); + } + response(&output) +} + +fn track_tree( + path: &Path, + directories: &mut BTreeSet, + track: &mut impl FnMut(&Path), +) -> Result<(), String> { + let metadata = path.metadata().map_err(|error| { + format!( + "cannot track native library input {}: {error}", + path.display() + ) + })?; + if !metadata.is_file() && !metadata.is_dir() { + return Err(format!( + "native library input is not a file or directory: {}", + path.display() + )); + } + track(path); + let canonical = path.canonicalize().map_err(|error| error.to_string())?; + if canonical != path { + track(&canonical); + } + if metadata.is_dir() && directories.insert(canonical) { + for entry in std::fs::read_dir(path).map_err(|error| error.to_string())? { + track_tree( + &entry.map_err(|error| error.to_string())?.path(), + directories, + track, + )?; + } + } + Ok(()) +} + +pub(crate) fn expand(variable: &syn::LitStr) -> Result { + crate::common::track_codegen_environment(); + let value = environment(&variable.value())?.ok_or_else(|| { + format!( + "native library registration variable {} is not set", + variable.value() + ) + })?; + let registration = registration(&value)?; + if !registration.executable.is_file() { + return Err(format!( + "native library provider is not a file: {}", + registration.executable.display() + )); + } + let mut directories = BTreeSet::new(); + let mut track = |path: &Path| proc_macro::tracked::path(path); + track_tree(®istration.executable, &mut directories, &mut track)?; + let cuda_home = environment("CUDA_HOME")?; + let cuda_path = environment("CUDA_PATH")?; + let target = environment("CUDA_OXIDE_TARGET")?; + if environment(reserved_oxide_symbols::MATERIALIZE_CUBIN_ENV)? + .is_some_and(|value| matches!(value.as_str(), "1" | "true")) + { + let cuda_root = cuda_home + .or(cuda_path) + .ok_or("native library inputs require CUDA_HOME or CUDA_PATH")?; + let cuda_root = std::path::absolute(cuda_root) + .map_err(|error| format!("cannot resolve CUDA toolkit path: {error}"))?; + let target = target.ok_or("native library inputs require CUDA_OXIDE_TARGET")?; + let target = target + .strip_prefix("sm_") + .map(|value| format!("compute_{value}")) + .unwrap_or(target); + let inputs = query( + ®istration.executable, + &InputRequest { + version: 1, + cuda_root, + target, + }, + )?; + for name in inputs.environment { + environment(&name)?; + } + for path in inputs.paths { + track_tree(&path, &mut directories, &mut track)?; + } + } + let literal = syn::LitStr::new(&value, variable.span()); + Ok(quote::quote!(#literal)) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn input_response_rejects_invalid_contracts() { + for value in [ + r#"{"version":2,"paths":[],"environment":[]}"#, + r#"{"version":1,"paths":["relative"],"environment":[]}"#, + r#"{"version":1,"paths":[],"environment":["A=B"]}"#, + r#"{"version":1,"paths":[],"environment":[],"extra":1}"#, + r#"{"version":1,"paths":[],"environment":[]} trailing"#, + ] { + assert!(response(value.as_bytes()).is_err(), "{value}"); + } + assert!(response(&vec![b' '; MAX_JSON + 1]).is_err()); + assert!(response(br#"{"version":1,"paths":[],"environment":[]}"#).is_ok()); + } +} diff --git a/cuda-oxide/crates/cuda-macros/src/tests/cuda_module.rs b/cuda-oxide/crates/cuda-macros/src/tests/cuda_module.rs index be7a69ac79..22f732b83e 100644 --- a/cuda-oxide/crates/cuda-macros/src/tests/cuda_module.rs +++ b/cuda-oxide/crates/cuda-macros/src/tests/cuda_module.rs @@ -1493,3 +1493,18 @@ fn non_generic_kernel_lookups_never_consult_the_divergence_diagnosis() { "non-generic lookups must keep the ordinary error path: {expanded}" ); } + +#[test] +fn inferred_shared_contract_rejects_a_separate_alignment_promise() { + let module: ItemMod = parse_quote! { + mod kernels { + #[kernel] + #[launch_contract(domain = 1, block = (32, 1, 1), dynamic_shared = inferred, + dynamic_shared_alignment = 128)] + pub fn map() {} + } + }; + let error = + expand_cuda_module(module).expect_err("inferred alignment belongs to the compiler layout"); + assert!(error.to_string().contains("inferred")); +} diff --git a/cuda-oxide/crates/cuda-macros/src/tests/kernel.rs b/cuda-oxide/crates/cuda-macros/src/tests/kernel.rs index caaf588b90..3e13600e74 100644 --- a/cuda-oxide/crates/cuda-macros/src/tests/kernel.rs +++ b/cuda-oxide/crates/cuda-macros/src/tests/kernel.rs @@ -689,6 +689,7 @@ fn generic_kernel_forwards_only_exact_top_level_configuration_markers() { ::cuda_device::thread::__launch_contract_block_config::<64, 1, 1>(); ::cuda_device::cluster::__cluster_config::<2, 1, 1>(); ::cuda_device::shared::__dynamic_shared_alignment::<128>(); + ::cuda_device::shared::__dynamic_shared_inferred(); cuda_device::thread::__launch_bounds_config::<4, 1>(); unrelated(); other::cuda_device::thread::__launch_bounds_config::<32, 1>(); @@ -702,12 +703,13 @@ fn generic_kernel_forwards_only_exact_top_level_configuration_markers() { let markers = top_level_kernel_configuration_markers(&kernel); let forwarded = quote!(#(#markers)*).to_string().replace(' ', ""); - assert_eq!(markers.len(), 5); + assert_eq!(markers.len(), 6); assert!(forwarded.contains("__launch_bounds_config::<64,2>()")); assert!(forwarded.contains("__launch_contract_config::<1,true>()")); assert!(forwarded.contains("__launch_contract_block_config::<64,1,1>()")); assert!(forwarded.contains("__cluster_config::<2,1,1>()")); assert!(forwarded.contains("__dynamic_shared_alignment::<128>()")); + assert!(forwarded.contains("__dynamic_shared_inferred()")); assert!(!forwarded.contains("unrelated")); assert!(!forwarded.contains("::<4,1>()")); assert!(!forwarded.contains("other::cuda_device")); diff --git a/cuda-oxide/crates/cuda-macros/tests/device-only/Cargo.lock b/cuda-oxide/crates/cuda-macros/tests/device-only/Cargo.lock index 4a78f429b9..6b95509d84 100644 --- a/cuda-oxide/crates/cuda-macros/tests/device-only/Cargo.lock +++ b/cuda-oxide/crates/cuda-macros/tests/device-only/Cargo.lock @@ -17,6 +17,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn 2.0.119", ] diff --git a/cuda-oxide/crates/cuda-macros/tests/library_registration.rs b/cuda-oxide/crates/cuda-macros/tests/library_registration.rs new file mode 100644 index 0000000000..4388dc66cb --- /dev/null +++ b/cuda-oxide/crates/cuda-macros/tests/library_registration.rs @@ -0,0 +1,157 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Ordinary Cargo freshness across a dependency registration and its consumer. +//! The fake provider is a shell process; no CUDA toolkit or GPU is used. +#![cfg(unix)] + +use std::fs; +use std::os::unix::fs::PermissionsExt; +use std::path::{Path, PathBuf}; +use std::process::Command; + +fn build(root: &Path, materialize: bool, option: Option<&str>, expected: Option<&str>) -> String { + let mut command = Command::new(env!("CARGO")); + command + .args(["build", "-vv", "--offline"]) + .current_dir(root) + .env("CARGO_TARGET_DIR", root.join("target")) + .env("CUDA_HOME", root.join("toolkit")) + .env("CUDA_OXIDE_TARGET", "sm_120") + .env_remove("CARGO_ENCODED_RUSTFLAGS") + .env_remove("RUSTFLAGS"); + if let Some(option) = option { + command.env("NATIVE_INPUT_OPTION", option); + } else { + command.env_remove("NATIVE_INPUT_OPTION"); + } + if materialize { + command.env("CUDA_OXIDE_MATERIALIZE_CUBIN", "1"); + } else { + command.env_remove("CUDA_OXIDE_MATERIALIZE_CUBIN"); + } + let output = command.output().unwrap(); + let log = String::from_utf8_lossy(&output.stderr).into_owned(); + if let Some(error) = expected { + assert!(!output.status.success(), "{log}"); + assert!(log.contains(error), "{log}"); + } else { + assert!(output.status.success(), "{log}"); + } + log +} + +fn provider(root: &Path, response: &str) { + fs::write( + root.join("provider"), + format!("#!/bin/sh\ncat >/dev/null\nprintf '%s' '{response}'\n"), + ) + .unwrap(); + fs::set_permissions(root.join("provider"), fs::Permissions::from_mode(0o755)).unwrap(); +} + +#[test] +fn tracks_native_inputs_before_cargo_dep_info() { + let root = std::env::temp_dir().join(format!( + "oxide-library-inputs-{}-{}", + std::process::id(), + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() + )); + let device = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join("../cuda-device") + .canonicalize() + .unwrap(); + fs::create_dir_all(root.join("api/src")).unwrap(); + fs::create_dir_all(root.join("consumer/src")).unwrap(); + fs::create_dir_all(root.join("headers")).unwrap(); + fs::write(root.join("headers/value.h"), "initial").unwrap(); + fs::write( + root.join("Cargo.toml"), + "[workspace]\nmembers=['api','consumer']\ndefault-members=['consumer']\nresolver='3'\n", + ) + .unwrap(); + fs::write(root.join("api/Cargo.toml"), format!( + "[package]\nname='native-input-api'\nversion='0.0.0'\nedition='2024'\n[dependencies]\ncuda-device={{path={:?}}}\n", device.to_str().unwrap() + )).unwrap(); + fs::write(root.join("consumer/Cargo.toml"), + "[package]\nname='native-input-consumer'\nversion='0.0.0'\nedition='2024'\n[dependencies]\nnative-input-api={path='../api'}\n").unwrap(); + let registration = serde_json::json!({ + "version":1,"provider":"fixture","executable":root.join("provider"), + "operation":"test","algorithm":"direct" + }) + .to_string(); + fs::write(root.join("api/build.rs"), format!( + "fn main() {{ println!(\"cargo::rerun-if-changed=build.rs\"); println!(\"cargo::rustc-env=REG={{}}\", {registration:?}); }}" + )).unwrap(); + fs::write( + root.join("api/src/lib.rs"), + "pub fn registration() -> &'static str { cuda_device::library::registration!(\"REG\") }\n", + ) + .unwrap(); + fs::write( + root.join("consumer/src/main.rs"), + "fn main() { assert!(native_input_api::registration().contains(\"fixture\")); }\n", + ) + .unwrap(); + let response = serde_json::json!({ + "version":1,"paths":[root.join("headers")],"environment":["NATIVE_INPUT_OPTION"] + }) + .to_string(); + provider(&root, &response); + build(&root, true, None, None); + let warm = build(&root, true, None, None); + assert!(warm.contains("Fresh native-input-api"), "{warm}"); + assert!(warm.contains("Fresh native-input-consumer"), "{warm}"); + + fs::write(root.join("headers/value.h"), "changed").unwrap(); + let changed = build(&root, true, None, None); + assert!(changed.contains("Compiling native-input-api"), "{changed}"); + assert!( + changed.contains("Compiling native-input-consumer"), + "{changed}" + ); + fs::write(root.join("headers/new.h"), "added").unwrap(); + let added = build(&root, true, None, None); + assert!(added.contains("Compiling native-input-api"), "{added}"); + + let option = build(&root, true, Some("changed"), None); + assert!(option.contains("Compiling native-input-api"), "{option}"); + assert!( + option.contains("Compiling native-input-consumer"), + "{option}" + ); + let warm = build(&root, true, Some("changed"), None); + assert!(warm.contains("Fresh native-input-api"), "{warm}"); + + provider(&root, r#"{"version":2,"paths":[],"environment":[]}"#); + build( + &root, + true, + Some("changed"), + Some("input response requires version 1"), + ); + provider( + &root, + r#"{"version":1,"paths":["relative"],"environment":[]}"#, + ); + build( + &root, + true, + Some("changed"), + Some("input paths must be absolute"), + ); + provider(&root, "malformed"); + build( + &root, + true, + Some("changed"), + Some("invalid native library input response"), + ); + // A normal host build expands the registration without querying CUDA or + // attempting to consume the deliberately invalid native response. + build(&root, false, None, None); + fs::remove_dir_all(root).unwrap(); +} diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs index 12fe5ecda2..fc1b5521db 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs @@ -44,25 +44,19 @@ pub struct DeviceExternDecl { /// NVVM attributes for device extern declarations. /// -/// NOTE: These attributes are currently **not emitted** to the LLVM IR output. -/// When linking LTOIR via nvJitLink, the external library's LTOIR already contains -/// proper attributes (convergent, nounwind, memory, etc.) on the function DEFINITIONS. -/// nvJitLink uses the definition's attributes during LTO, making attributes on our -/// declarations redundant. -/// -/// This struct is retained for the pipeline API but values are not used in code generation. +/// Convergence is emitted on each marked declaration before libNVVM optimization. +/// Memory-effect annotations remain inactive. #[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] pub struct DeviceExternAttrs { - /// Function is convergent (all threads must execute together). - /// NOTE: Not currently emitted to LLVM IR. + /// Function has convergence requirements for its participating threads. pub is_convergent: bool, /// Function is pure (no side effects, result depends only on inputs). - /// NOTE: Not currently emitted to LLVM IR. + /// Inactive; not emitted to LLVM IR. pub is_pure: bool, /// Function is read-only (only reads memory, doesn't write). - /// NOTE: Not currently emitted to LLVM IR. + /// Inactive; not emitted to LLVM IR. pub is_readonly: bool, } diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/lower.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/lower.rs index 05011e5e58..d08f68f8d5 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/lower.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/lower.rs @@ -84,7 +84,7 @@ pub fn add_device_extern_declarations( region.iter(ctx).next().expect("Module should have a block") }; - let declared_symbols: HashMap<_, _> = block + let mut declared_symbols: HashMap<_, _> = block .deref(ctx) .iter(ctx) .filter_map(|op| { @@ -140,6 +140,7 @@ pub fn add_device_extern_declarations( // Insert at the front of the module (declarations come before definitions) func_op.get_operation().insert_at_front(block, ctx); + declared_symbols.insert(decl.export_name.clone(), func_type); } Ok(()) @@ -196,3 +197,62 @@ fn device_extern_type_to_pliron( } }) } + +#[cfg(test)] +mod tests { + use super::*; + use crate::export::DeviceExternAttrs; + use llvm_export::export::{NvvmExportConfig, export_module_with_externs}; + use pliron::builtin::ops::ModuleOp; + use pliron::common_traits::Verify; + + #[test] + fn repeated_externs_keep_one_operation_and_preserve_conflict_checks() { + let mut ctx = Context::new(); + let module = ModuleOp::new(&mut ctx, "externs".try_into().unwrap()); + let declaration = DeviceExternDecl { + export_name: "external".to_string(), + param_types: vec![DeviceExternType::Integer(32)], + return_type: DeviceExternType::Void, + attrs: DeviceExternAttrs::default(), + }; + let mut externs = [declaration.clone(), declaration]; + add_device_extern_declarations(&mut ctx, module.get_operation(), &externs).unwrap(); + let declarations = { + let region = module.get_operation().deref(&ctx).get_region(0).deref(&ctx); + let block = region.iter(&ctx).next().unwrap(); + block + .deref(&ctx) + .iter(&ctx) + .filter(|&op| { + Operation::get_op::(op, &ctx).is_some_and( + |function| function.get_symbol_name(&ctx).to_string() == "external", + ) + }) + .count() + }; + assert_eq!(declarations, 1); + module.get_operation().deref(&ctx).verify(&ctx).unwrap(); + let ir = export_module_with_externs(&ctx, &module, &externs, &NvvmExportConfig::default()) + .unwrap(); + assert_eq!(ir.matches("declare void @external(i32)").count(), 1); + + // Lowering shares only the FuncOp. The complete declarations still + // reach export, where differing convergence requirements are rejected. + externs[1].attrs.is_convergent = true; + add_device_extern_declarations(&mut ctx, module.get_operation(), &externs).unwrap(); + let error = + export_module_with_externs(&ctx, &module, &externs, &NvvmExportConfig::default()) + .unwrap_err(); + assert!(error.contains("convergent is false versus true"), "{error}"); + + externs[1].param_types[0] = DeviceExternType::Float32; + let error = + add_device_extern_declarations(&mut ctx, module.get_operation(), &externs).unwrap_err(); + assert!( + error + .to_string() + .contains("conflicts with the call-site declaration") + ); + } +} diff --git a/cuda-oxide/crates/llvm-export/src/export/debug.rs b/cuda-oxide/crates/llvm-export/src/export/debug.rs index ca0bfcfc31..4feb86212a 100644 --- a/cuda-oxide/crates/llvm-export/src/export/debug.rs +++ b/cuda-oxide/crates/llvm-export/src/export/debug.rs @@ -177,9 +177,12 @@ impl<'a> ModuleExportState<'a> { "!{dwarf_version_id} = !{{i32 2, !\"Dwarf Version\", i32 2}}" ) .unwrap(); + // NVVM requires Error (1), including when linking native CUDA LTO-IR. + // Ordinary LLVM debug metadata keeps its Warning (2) merge behavior. + let debug_version_behavior = if self.nvvm_ir_dialect.is_some() { 1 } else { 2 }; writeln!( output, - "!{debug_info_version_id} = !{{i32 2, !\"Debug Info Version\", i32 3}}" + "!{debug_info_version_id} = !{{i32 {debug_version_behavior}, !\"Debug Info Version\", i32 3}}" ) .unwrap(); diff --git a/cuda-oxide/crates/llvm-export/src/export/externs.rs b/cuda-oxide/crates/llvm-export/src/export/externs.rs index ceeab494f0..2cea5a5fc0 100644 --- a/cuda-oxide/crates/llvm-export/src/export/externs.rs +++ b/cuda-oxide/crates/llvm-export/src/export/externs.rs @@ -225,22 +225,18 @@ pub struct DeviceExternDecl { /// NVVM attributes for device extern declarations. /// -/// NOTE: These attributes are currently **not emitted** to the LLVM IR output. -/// When linking LTOIR via nvJitLink, the external library's LTOIR already contains -/// proper attributes (convergent, nounwind, memory, etc.) on the function DEFINITIONS. -/// nvJitLink uses the definition's attributes during LTO, making attributes on -/// declarations redundant. -/// -/// This struct is retained for potential future use or for debugging/inspection. +/// Convergence is emitted on the declaration before libNVVM optimization. +/// Memory-effect annotations remain inactive; they are not inferred from external +/// definitions that become available only during LTO. #[derive(Debug, Clone, Default, PartialEq, Eq, Hash)] pub struct DeviceExternAttrs { - /// Function is convergent (all threads must execute together). + /// Function has convergence requirements for its participating threads. pub is_convergent: bool, - /// Function is pure (no side effects). Maps to LLVM `readnone`. + /// Function is pure (no side effects). Inactive for Rust source annotations. pub is_pure: bool, - /// Function is read-only (only reads memory). Maps to LLVM `readonly`. + /// Function is read-only (only reads memory). Inactive for Rust source annotations. pub is_readonly: bool, } diff --git a/cuda-oxide/crates/llvm-export/src/export/module.rs b/cuda-oxide/crates/llvm-export/src/export/module.rs index 1a9e934851..9d425d54c4 100644 --- a/cuda-oxide/crates/llvm-export/src/export/module.rs +++ b/cuda-oxide/crates/llvm-export/src/export/module.rs @@ -487,10 +487,17 @@ fn index_device_externs( validate_device_extern_function_shape(state, decl)?; if let Some(previous) = state.device_externs.get(&decl.export_name) { if previous != decl { - return Err(format!( + let conflict = format!( "conflicting device-extern declarations for `@{}`", decl.export_name - )); + ); + if previous.attrs.is_convergent != decl.attrs.is_convergent { + return Err(format!( + "{conflict}: convergent is {} versus {}", + previous.attrs.is_convergent, decl.attrs.is_convergent + )); + } + return Err(conflict); } continue; } @@ -610,12 +617,9 @@ pub(super) fn export_module_with_externs_impl( // 2. Device extern declarations (before function definitions) // - // NOTE: We intentionally do NOT emit LLVM attributes on these declarations. - // The external LTOIR (from nvcc -dc -dlto) already contains proper attributes - // (convergent, nounwind, memory, etc.) on the function DEFINITIONS. - // When nvJitLink performs LTO linking, it uses the definition's attributes. - // Attributes on declarations are redundant and were causing issues where - // all externs incorrectly got the same attribute group. + // Convergence must be visible before libNVVM optimizes this module, not + // only when external definitions arrive at LTO. Emit it per declaration + // so unrelated externs do not inherit a shared attribute group. if !device_externs.is_empty() { writeln!( &mut output, @@ -643,7 +647,11 @@ pub(super) fn export_module_with_externs_impl( } param.write_llvm_with_attr(&mut output, state.legacy_typed_pointers())?; } - writeln!(&mut output, ")").unwrap(); + write!(&mut output, ")").unwrap(); + if decl.attrs.is_convergent { + write!(&mut output, " convergent").unwrap(); + } + writeln!(&mut output).unwrap(); } writeln!(&mut output).unwrap(); } @@ -711,7 +719,7 @@ pub(super) fn export_module_with_externs_impl( } // 6. Emit attribute groups for convergent intrinsics used by module functions - // Note: Device extern declarations no longer get attribute groups - see section 2 comment. + // Device extern convergence is emitted inline, independently of this group. if state.convergent_used { writeln!(&mut output).unwrap(); writeln!(&mut output, "attributes #0 = {{ convergent }}").unwrap(); diff --git a/cuda-oxide/crates/llvm-export/tests/export_test/debug_info.rs b/cuda-oxide/crates/llvm-export/tests/export_test/debug_info.rs index abc11b7af6..bbb601856c 100644 --- a/cuda-oxide/crates/llvm-export/tests/export_test/debug_info.rs +++ b/cuda-oxide/crates/llvm-export/tests/export_test/debug_info.rs @@ -90,6 +90,20 @@ fn line_table_debug_metadata_emits_function_scope_and_instruction_locations() { let ir = export_module_to_string_with_config(&ctx, &module, &config).expect("debug export succeeds"); + assert!(ir.contains("!{i32 2, !\"Debug Info Version\", i32 3}")); + for debug_kind in [DebugKind::LineTables, DebugKind::Full] { + let nvvm_config = DebugConfig { + inner: NvvmExportConfig::new(NvvmIrDialect::Modern), + debug_kind, + }; + let nvvm_ir = export_module_to_string_with_config(&ctx, &module, &nvvm_config) + .expect("NVVM debug export succeeds"); + assert!( + nvvm_ir.contains("!{i32 1, !\"Debug Info Version\", i32 3}"), + "NVVM requires Error merge behavior for native LTO linkage:\n{nvvm_ir}" + ); + } + let define_line = ir .lines() .find(|line| line.starts_with("define ")) diff --git a/cuda-oxide/crates/llvm-export/tests/export_test/device_externs.rs b/cuda-oxide/crates/llvm-export/tests/export_test/device_externs.rs index ee928c3819..f68a227611 100644 --- a/cuda-oxide/crates/llvm-export/tests/export_test/device_externs.rs +++ b/cuda-oxide/crates/llvm-export/tests/export_test/device_externs.rs @@ -23,6 +23,113 @@ use pliron::{ use crate::common::module_top_block; +fn mixed_convergence_module(ctx: &mut Context) -> (ModuleOp, Vec) { + let module = ModuleOp::new(ctx, "mixed_convergence".try_into().unwrap()); + let module_block = module_top_block(ctx, &module); + let ptr_ty = PointerType::get(ctx, 0); + let void_ty = VoidType::get(ctx); + let external_ty = FuncType::get(ctx, void_ty.into(), vec![ptr_ty.into()], false); + let caller = FuncOp::new(ctx, "caller".try_into().unwrap(), external_ty); + let entry = caller.get_or_create_entry_block(ctx); + let pointer = entry.deref(ctx).get_argument(0); + let mut externs = Vec::new(); + for (name, is_convergent) in [("collective", true), ("ordinary", false)] { + FuncOp::new(ctx, name.try_into().unwrap(), external_ty) + .get_operation() + .insert_at_back(module_block, ctx); + CallOp::new( + ctx, + CallOpCallable::Direct(name.try_into().unwrap()), + external_ty, + vec![pointer], + ) + .get_operation() + .insert_at_back(entry, ctx); + externs.push(DeviceExternDecl { + export_name: name.to_string(), + param_types: vec![DeviceExternType::pointer_to( + DeviceExternType::Integer(32), + 0, + )], + return_type: DeviceExternType::Void, + attrs: DeviceExternAttrs { + is_convergent, + ..DeviceExternAttrs::default() + }, + }); + } + ReturnOp::new(ctx, None) + .get_operation() + .insert_at_back(entry, ctx); + caller.get_operation().insert_at_back(module_block, ctx); + (module, externs) +} + +#[test] +fn device_extern_convergence_is_per_declaration_in_both_dialects() { + let mut ctx = Context::new(); + let (module, mut externs) = mixed_convergence_module(&mut ctx); + // Repeated identical declarations are still emitted exactly once. + externs.push(externs[0].clone()); + for (dialect, pointer) in [ + (NvvmIrDialect::Modern, "ptr"), + (NvvmIrDialect::LegacyLlvm7, "i32*"), + ] { + let ir = + export_module_with_externs(&ctx, &module, &externs, &NvvmExportConfig::new(dialect)) + .unwrap(); + let declarations: Vec<_> = ir + .lines() + .filter(|line| line.starts_with("declare ")) + .collect(); + assert_eq!( + declarations, + [ + format!("declare void @collective({pointer}) convergent"), + format!("declare void @ordinary({pointer})"), + ], + "{ir}" + ); + assert!( + ir.lines().any(|line| { + line.contains(&format!("call void @collective({pointer} ")) && line.ends_with(" #0") + }), + "{ir}" + ); + if dialect == NvvmIrDialect::LegacyLlvm7 { + assert!(ir.contains("bitcast i8* %v0 to i32*"), "{ir}"); + } + } + + externs[2].attrs.is_convergent = false; + let error = export_module_with_externs(&ctx, &module, &externs, &NvvmExportConfig::default()) + .expect_err("conflicting convergence requirements must fail"); + assert!( + error.contains("conflicting device-extern declarations for `@collective`: convergent is true versus false"), + "{error}" + ); +} + +#[test] +#[ignore = "requires an installed CUDA Toolkit with modern and legacy libNVVM"] +fn device_extern_convergence_compiles_with_libnvvm_in_both_dialects() { + let nvvm = libnvvm_sys::LibNvvm::load().expect("CUDA Toolkit with libNVVM required"); + let mut ctx = Context::new(); + let (module, externs) = mixed_convergence_module(&mut ctx); + for (dialect, arch) in [ + (NvvmIrDialect::Modern, "-arch=compute_120"), + (NvvmIrDialect::LegacyLlvm7, "-arch=compute_80"), + ] { + let ir = + export_module_with_externs(&ctx, &module, &externs, &NvvmExportConfig::new(dialect)) + .unwrap(); + let mut program = libnvvm_sys::Program::new(&nvvm).unwrap(); + program.add_module(ir.as_bytes(), "convergence.ll").unwrap(); + let lto = program.compile(&[arch, "-gen-lto"]).unwrap(); + assert!(!lto.is_empty()); + } +} + #[test] fn legacy_device_extern_adapts_exact_pointer_arguments_and_results() { let mut ctx = Context::new(); diff --git a/cuda-oxide/crates/mir-importer/src/kernel_resources.rs b/cuda-oxide/crates/mir-importer/src/kernel_resources.rs new file mode 100644 index 0000000000..5a0c049772 --- /dev/null +++ b/cuda-oxide/crates/mir-importer/src/kernel_resources.rs @@ -0,0 +1,185 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +//! Finalized requirements for fixed views of the dynamic shared-memory base. +//! This is not an allocator: fixed views alias and combine by maximum extent. + +use dialect_mir::ops::{MirCallOp, MirExternSharedOp, MirFuncOp}; +use oxide_artifacts::KernelLaunchFacts; +use pliron::builtin::{attributes::IntegerAttr, op_interfaces::SymbolOpInterface}; +use pliron::context::{Context, Ptr}; +use pliron::linked_list::ContainsLinkedList; +use pliron::operation::Operation; +use std::collections::{BTreeMap, BTreeSet}; + +pub(crate) const FIXED_SHARED_BYTES: &str = "cuda_oxide_fixed_shared_bytes"; +pub(crate) const INFERRED_SHARED: &str = "cuda_oxide_inferred_shared"; + +fn integer_attr(ctx: &Context, op: Ptr, name: &str) -> Option { + let key: pliron::identifier::Identifier = name.try_into().unwrap(); + op.deref(ctx) + .attributes + .get::(&key) + .map(|value| value.value().to_u64()) +} + +/// Apply the exact geometry required by reachable native library operations. +/// Scratch extents are recorded on their actual shared-memory accesses and +/// collected together with ordinary Rust views below. +pub(crate) fn apply_library_block( + ctx: &mut Context, + entry: Ptr, + plan: &KernelLaunchFacts, +) -> Result<(), String> { + use pliron::builtin::types::{IntegerType, Signedness}; + use pliron::utils::apint::APInt; + + let Some((x, y, z)) = plan.exact_block else { + return Err("native library root is missing its exact block shape".into()); + }; + let required = u64::from(x) * u64::from(y) * u64::from(z); + if let Some(maximum) = integer_attr(ctx, entry, "maxntid") + && required > maximum + { + return Err(format!( + "native library exact block ({x}, {y}, {z}) exceeds launch_bounds maximum {maximum}" + )); + } + let axes = [("reqntid_x", x), ("reqntid_y", y), ("reqntid_z", z)]; + for (name, dimension) in axes { + if let Some(existing) = integer_attr(ctx, entry, name) + && existing != u64::from(dimension) + { + return Err(format!( + "native library exact block ({x}, {y}, {z}) conflicts with kernel launch contract" + )); + } + } + let ty = IntegerType::get(ctx, 64, Signedness::Unsigned); + for (name, dimension) in axes { + entry.deref_mut(ctx).attributes.set( + name.try_into().unwrap(), + IntegerAttr::new( + ty, + APInt::from_u64( + u64::from(dimension), + std::num::NonZeroUsize::new(64).unwrap(), + ), + ), + ); + } + Ok(()) +} + +#[derive(Default)] +struct FunctionResources { + inferred: bool, + fixed: bool, + unconstrained: bool, + bytes: u64, + alignment: u64, + callees: Vec, +} + +fn scan(ctx: &Context, op: Ptr, resources: &mut FunctionResources) { + if let Some(shared) = Operation::get_op::(op, ctx) { + match integer_attr(ctx, op, FIXED_SHARED_BYTES) { + Some(bytes) => { + resources.fixed = true; + resources.bytes = resources.bytes.max(bytes); + resources.alignment = resources.alignment.max(shared.get_alignment_value(ctx)); + } + None => resources.unconstrained = true, + } + } + if let Some(call) = Operation::get_op::(op, ctx) + && let Some(callee) = call.get_attr_callee(ctx) + { + resources.callees.push(String::from((*callee).clone())); + } + for region in op.deref(ctx).regions() { + for block in region.deref(ctx).iter(ctx) { + for child in block.deref(ctx).iter(ctx) { + scan(ctx, child, resources); + } + } + } +} + +pub(crate) fn collect( + ctx: &Context, + module: Ptr, + kernels: impl IntoIterator, +) -> Result, String> { + let mut functions = BTreeMap::new(); + for region in module.deref(ctx).regions() { + for block in region.deref(ctx).iter(ctx) { + for op in block.deref(ctx).iter(ctx) { + if let Some(function) = MirFuncOp::wrap(ctx, op) { + let mut resources = FunctionResources { + inferred: integer_attr(ctx, op, INFERRED_SHARED).is_some(), + alignment: integer_attr(ctx, op, "dynamic_shared_alignment").unwrap_or(1), + ..Default::default() + }; + scan(ctx, op, &mut resources); + functions.insert(function.get_symbol_name(ctx).to_string(), (op, resources)); + } + } + } + } + let mut facts = BTreeMap::new(); + for kernel in kernels { + let Some((entry, _)) = functions.get(&kernel) else { + continue; + }; + let mut visited = BTreeSet::new(); + let mut pending = vec![kernel.clone()]; + let mut combined = FunctionResources { + alignment: 1, + ..Default::default() + }; + while let Some(name) = pending.pop() { + if !visited.insert(name.clone()) { + continue; + } + let Some((_, local)) = functions.get(&name) else { + continue; + }; + combined.inferred |= local.inferred; + combined.fixed |= local.fixed; + combined.unconstrained |= local.unconstrained; + combined.bytes = combined.bytes.max(local.bytes); + combined.alignment = combined.alignment.max(local.alignment); + pending.extend(local.callees.iter().cloned()); + } + if combined.inferred && combined.unconstrained { + return Err(format!( + "{kernel}: inferred dynamic shared memory cannot include unconstrained get/get_raw/offset accesses; describe the complete base region with DynamicSharedArray::get_fixed or declare an explicit launch contract" + )); + } + if combined.unconstrained || !(combined.inferred || combined.fixed) { + continue; + } + let narrow = |value| { + u32::try_from(value) + .map_err(|_| format!("{kernel}: compiled shared-memory layout exceeds u32")) + }; + let exact_block = match ( + integer_attr(ctx, *entry, "reqntid_x"), + integer_attr(ctx, *entry, "reqntid_y"), + integer_attr(ctx, *entry, "reqntid_z"), + ) { + (Some(x), Some(y), Some(z)) => Some((narrow(x)?, narrow(y)?, narrow(z)?)), + _ => None, + }; + let layout = KernelLaunchFacts { + exact_block, + dynamic_shared_bytes: narrow(combined.bytes)?, + dynamic_shared_alignment: narrow(combined.alignment)?, + }; + facts.insert(kernel, layout); + } + Ok(facts) +} diff --git a/cuda-oxide/crates/mir-importer/src/lib.rs b/cuda-oxide/crates/mir-importer/src/lib.rs index 796f34e5cc..d0faedc12a 100644 --- a/cuda-oxide/crates/mir-importer/src/lib.rs +++ b/cuda-oxide/crates/mir-importer/src/lib.rs @@ -95,6 +95,7 @@ extern crate rustc_target; pub const DEVICE_RUNTIME_CHECKS_VALUE: bool = false; pub mod error; +mod kernel_resources; pub mod pipeline; // Crate-internal: every caller reaches the translator through `pipeline`, and // the handful of predicates outsiders need are re-exported below. Keeping the @@ -115,3 +116,7 @@ pub use translator::cute::is_cute_compiler_hook_path; pub use translator::facts::KnownDefs; pub use translator::terminator::drop_glue::{drop_glue_is_noop, drop_instance_is_noop}; pub use translator::terminator::is_panic_entry_path; + +mod library; +pub use library::LibraryCallPlan; +pub use pipeline::run_pipeline_with_libraries; diff --git a/cuda-oxide/crates/mir-importer/src/library.rs b/cuda-oxide/crates/mir-importer/src/library.rs new file mode 100644 index 0000000000..e9c7a3362a --- /dev/null +++ b/cuda-oxide/crates/mir-importer/src/library.rs @@ -0,0 +1,182 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Lower compiler-validated library calls at an explicit scalar/pointer ABI. + +use std::cell::RefCell; +use std::collections::BTreeMap; + +use crate::error::{TranslationErr, TranslationResult}; +use crate::translator::terminator::helpers; +use crate::translator::values::{ValueMap, establish_declared_pointer_type}; +use crate::translator::{facts, rvalue, types}; +use dialect_mir::attributes::{FieldIndexAttr, MirPointerKindAuthorityAttr}; +use dialect_mir::ops::{MirExternSharedOp, MirExtractFieldOp}; +use dialect_mir::types::{MirPtrType, MirTupleType}; +use pliron::basic_block::BasicBlock; +use pliron::builtin::attributes::IntegerAttr; +use pliron::builtin::types::{FunctionType, IntegerType, Signedness}; +use pliron::context::{Context, Ptr}; +use pliron::input_err; +use pliron::location::Location; +use pliron::op::Op; +use pliron::operation::Operation; +use pliron::r#type::Typed; +use pliron::utils::apint::APInt; +use rustc_public::mir; + +/// One monomorphized call whose Rust tuple and provider ABI already agree. +#[derive(Clone, Debug)] +pub struct LibraryCallPlan { + /// Exact external symbol emitted by the native provider. + pub symbol: String, + /// Size of the assigned shared scratch view in bytes. + pub scratch_bytes: u32, + /// Required alignment of the shared scratch base. + pub scratch_alignment: u32, +} + +thread_local! { + static CALLS: RefCell> = const { RefCell::new(BTreeMap::new()) }; +} + +pub(crate) fn set_calls(calls: BTreeMap) { + CALLS.with(|current| *current.borrow_mut() = calls); +} + +pub(crate) fn get_call(instance: &str) -> Option { + CALLS.with(|calls| calls.borrow().get(instance).cloned()) +} + +#[allow(clippy::too_many_arguments)] +pub(crate) fn translate_call( + ctx: &mut Context, + body: &mir::Body, + plan: &LibraryCallPlan, + args: &[mir::Operand], + destination: &mir::Place, + target: &Option, + block: Ptr, + previous: Option>, + values: &mut ValueMap, + blocks: &[Ptr], + loc: Location, +) -> TranslationResult> { + let [_, tuple] = args else { + return input_err!( + loc, + TranslationErr::unsupported( + "library marker requires a registration and argument tuple" + ) + ); + }; + let tuple_ty = match tuple.ty(body.locals()) { + Ok(ty) => ty, + Err(e) => { + return input_err!( + loc, + TranslationErr::unsupported(format!("invalid library argument tuple: {e:?}")) + ); + } + }; + let rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::Tuple(fields)) = + tuple_ty.kind() + else { + return input_err!( + loc, + TranslationErr::unsupported("library arguments must be a tuple") + ); + }; + let mut declared = fields + .iter() + .map(|ty| types::translate_type(ctx, ty)) + .collect::>>()?; + let (tuple_value, mut last) = + rvalue::translate_operand(ctx, body, tuple, values, block, previous, loc.clone())?; + let tuple_handle = tuple_value.get_type(ctx); + let field_types = tuple_handle + .deref(ctx) + .downcast_ref::() + .expect("validated library tuple") + .get_types() + .to_vec(); + let mut arguments = Vec::new(); + for (index, ty) in field_types.into_iter().enumerate() { + let op = Operation::new( + ctx, + MirExtractFieldOp::get_concrete_op_info(), + vec![ty], + vec![tuple_value], + vec![], + 0, + ); + op.deref_mut(ctx).set_loc(loc.clone()); + MirExtractFieldOp::new(op).set_attr_index(ctx, FieldIndexAttr(index as u32)); + helpers::insert_op(ctx, op, block, last); + last = Some(op); + arguments.push(op.deref(ctx).get_result(0)); + } + // The unsafe marker grants a raw scratch address. Keep the internal shared + // pointer through construction, then adapt only its address space at the + // declared generic-pointer ABI boundary, using the ordinary foreign-call path. + let byte = IntegerType::get(ctx, 8, Signedness::Unsigned).into(); + let shared = MirPtrType::get_shared(ctx, byte, true).into(); + let op = Operation::new( + ctx, + MirExternSharedOp::get_concrete_op_info(), + vec![shared], + vec![], + vec![], + 0, + ); + op.deref_mut(ctx).set_loc(loc.clone()); + let scratch = MirExternSharedOp::new(op); + scratch.set_byte_offset_value(ctx, 0); + scratch.set_alignment_value(ctx, u64::from(plan.scratch_alignment)); + let layout_ty = IntegerType::get(ctx, 64, Signedness::Unsigned); + op.deref_mut(ctx).attributes.set( + crate::kernel_resources::FIXED_SHARED_BYTES + .try_into() + .unwrap(), + IntegerAttr::new( + layout_ty, + APInt::from_u64( + u64::from(plan.scratch_bytes), + std::num::NonZeroUsize::new(64).unwrap(), + ), + ), + ); + helpers::insert_op(ctx, op, block, last); + let internal_scratch = op.deref(ctx).get_result(0); + let raw_shared = facts::mint_shared_ptr_type(ctx, byte, facts::abi_library_scratch()).into(); + let (scratch_value, last) = establish_declared_pointer_type( + ctx, + internal_scratch, + raw_shared, + block, + Some(op), + MirPointerKindAuthorityAttr::RawAddress, + ); + arguments.insert(2, scratch_value); + declared.insert( + 2, + facts::mint_generic_ptr_type(ctx, byte, facts::abi_library_scratch()).into(), + ); + let signature = FunctionType::get(ctx, declared, vec![]).into(); + let unit = MirTupleType::get(ctx, vec![]).into(); + helpers::emit_function_call_values( + ctx, + body, + &plan.symbol, + arguments, + destination, + unit, + Some(signature), + target, + block, + last, + values, + blocks, + loc, + ) +} diff --git a/cuda-oxide/crates/mir-importer/src/pipeline.rs b/cuda-oxide/crates/mir-importer/src/pipeline.rs index 9b587d233e..c55d4bcd50 100644 --- a/cuda-oxide/crates/mir-importer/src/pipeline.rs +++ b/cuda-oxide/crates/mir-importer/src/pipeline.rs @@ -181,6 +181,8 @@ pub struct CompilationResult { pub allow_fma_contraction: bool, /// Per-kernel source launch bounds preserved for post-link diagnostics. pub kernel_launch_bounds: BTreeMap, + /// Finalized resource requirements, keyed by concrete exported kernel name. + pub kernel_launch_facts: BTreeMap, } /// Configuration for the compilation pipeline. @@ -501,6 +503,27 @@ pub fn run_pipeline( config: &PipelineConfig, known_defs: crate::translator::facts::KnownDefs, ) -> Result { + run_pipeline_with_libraries( + functions, + device_externs, + config, + known_defs, + BTreeMap::new(), + &BTreeMap::new(), + ) +} + +/// Run the pipeline with compiler-validated, monomorphized library calls. +/// The map keys are resolved instance mangled names, not source spellings. +pub fn run_pipeline_with_libraries( + functions: &[CollectedFunction], + device_externs: &[DeviceExternDecl], + config: &PipelineConfig, + known_defs: crate::translator::facts::KnownDefs, + libraries: BTreeMap, + library_roots: &BTreeMap, +) -> Result { + crate::library::set_calls(libraries); // Install the driver-resolved lang-item ids and emitted-function identities // for this run. Replace (rather than merge) both thread-local sets so // stale state from a previous run on this thread cannot survive. @@ -570,6 +593,12 @@ pub fn run_pipeline( PipelineError::Translation(format!("{}: {}", func.export_name, e.disp(&ctx))) })?; + if let Some(plan) = library_roots.get(&func.export_name) { + crate::kernel_resources::apply_library_block(&mut ctx, func_op_ptr, plan).map_err( + |error| PipelineError::Translation(format!("{}: {error}", func.export_name)), + )?; + } + if config.debug_kind.variables_enabled() { attach_debug_global_variables(&mut ctx, func_op_ptr, &config.debug_global_variables); } @@ -601,6 +630,19 @@ pub fn run_pipeline( append_to_module(&ctx, module_op_ptr, func_op_ptr); } + // Facts need the same helper alignment as lowering. This max-only call-graph + // propagation is idempotent; lowering also runs it for its other callers. + mir_lower::propagate_kernel_dynamic_shared_alignments(&mut ctx, module_op_ptr); + let kernel_launch_facts = crate::kernel_resources::collect( + &ctx, + module_op_ptr, + functions + .iter() + .filter(|function| function.is_kernel) + .map(|function| function.export_name.clone()), + ) + .map_err(PipelineError::Translation)?; + let ll_path = config.output_dir.join(format!("{}.ll", config.output_name)); let ptx_path = config .output_dir @@ -657,6 +699,7 @@ pub fn run_pipeline( target: generated.target, allow_fma_contraction: config.allow_fma_contraction, kernel_launch_bounds, + kernel_launch_facts, }) } ModuleArtifactKind::Ptx => Ok(CompilationResult { @@ -667,6 +710,7 @@ pub fn run_pipeline( target: generated.target, allow_fma_contraction: config.allow_fma_contraction, kernel_launch_bounds, + kernel_launch_facts, }), ModuleArtifactKind::Cubin => Ok(CompilationResult { artifact_path: cubin_path, @@ -676,6 +720,7 @@ pub fn run_pipeline( target: generated.target, allow_fma_contraction: config.allow_fma_contraction, kernel_launch_bounds, + kernel_launch_facts, }), } } @@ -770,7 +815,9 @@ fn write_nvvm_compile_options_sidecar( }) } -fn stale_compilation_artifact_paths( +/// Paths the pipeline may remove or replace when compiling one module. +/// Callers can preflight these before compilation to protect external inputs. +pub fn stale_compilation_artifact_paths( output_dir: &Path, output_name: &str, ) -> Vec { diff --git a/cuda-oxide/crates/mir-importer/src/translator/body.rs b/cuda-oxide/crates/mir-importer/src/translator/body.rs index 2af4b2c883..3249cf7701 100644 --- a/cuda-oxide/crates/mir-importer/src/translator/body.rs +++ b/cuda-oxide/crates/mir-importer/src/translator/body.rs @@ -527,6 +527,27 @@ fn detect_dynamic_shared_alignment( None } +fn has_inferred_dynamic_shared( + body: &mir::Body, + reachable: &std::collections::BTreeSet, +) -> bool { + reachable.iter().any(|&index| { + let mir::TerminatorKind::Call { + func: mir::Operand::Constant(constant), + .. + } = &body.blocks[index].terminator.kind + else { + return false; + }; + let TyKind::RigidTy(RigidTy::FnDef(def_id, _)) = constant.const_.ty().kind() else { + return false; + }; + def_id.krate().name.as_str() == "cuda_device" + && (def_id.name() == "__dynamic_shared_inferred" + || def_id.name().ends_with("::__dynamic_shared_inferred")) + }) +} + /// Return the non-unwind successors of a block's terminator. /// /// [`mir::Terminator::successors`] includes unwind cleanup blocks alongside @@ -2348,6 +2369,22 @@ pub fn translate_body( } } + if has_inferred_dynamic_shared(body, &reachable) { + use pliron::builtin::{ + attributes::IntegerAttr, + types::{IntegerType, Signedness}, + }; + use pliron::utils::apint::APInt; + let ty = IntegerType::get(ctx, 32, Signedness::Unsigned); + mir_func_op.get_operation().deref_mut(ctx).attributes.set( + crate::kernel_resources::INFERRED_SHARED.try_into().unwrap(), + IntegerAttr::new( + ty, + APInt::from_u32(1, std::num::NonZeroUsize::new(32).unwrap()), + ), + ); + } + // Attribute macros may run before `#[kernel]`. Generic expansion forwards // that marker to the entry but also keeps the original in its helper, so // record markers on any function. mir-lower treats every marked local diff --git a/cuda-oxide/crates/mir-importer/src/translator/facts.rs b/cuda-oxide/crates/mir-importer/src/translator/facts.rs index a6b24ac367..2504a5565e 100644 --- a/cuda-oxide/crates/mir-importer/src/translator/facts.rs +++ b/cuda-oxide/crates/mir-importer/src/translator/facts.rs @@ -417,6 +417,15 @@ mod pointer_origin { } } + /// ABI RULE: the unsafe native library marker supplies scratch as `*mut u8`. + /// Only this declared call boundary turns its internal shared base into RawMut. + pub(crate) fn abi_library_scratch() -> PointerOrigin { + PointerOrigin { + kind: MirPointerKind::RawMut, + mutable: true, + } + } + /// ABI RULE: `cuda_device::SharedPtr` stores a `*mut SharedSlot`, so /// the shared pointer it lowers to is always `RawMut`. pub(crate) fn abi_shared_ptr_field() -> PointerOrigin { diff --git a/cuda-oxide/crates/mir-importer/src/translator/terminator/helpers.rs b/cuda-oxide/crates/mir-importer/src/translator/terminator/helpers.rs index 78012fbfe0..0f73b9f01d 100644 --- a/cuda-oxide/crates/mir-importer/src/translator/terminator/helpers.rs +++ b/cuda-oxide/crates/mir-importer/src/translator/terminator/helpers.rs @@ -350,39 +350,6 @@ pub fn emit_function_call( last_op = arg_last_op; } - // A Rust foreign declaration uses generic pointers at its ABI surface, - // while an argument may retain a concrete GPU address space internally - // (for example, `*mut T` in shared memory). Adapt that representation at - // the frozen declaration boundary, but only when pointee, mutability, and - // source pointer kind already agree exactly. This is not authority to turn - // a raw pointer into a reference or otherwise manufacture provenance. - if let Some(signature) = external_callee_type { - let expected_arguments = { - let signature_ref = signature.deref(ctx); - let signature = signature_ref - .downcast_ref::() - .expect("foreign callee type must be a builtin FunctionType"); - signature.arg_types() - }; - - // Variadic declarations are rejected before this point, so unequal - // arity is invalid and must remain visible to MirCallOp verification. - if arg_values.len() == expected_arguments.len() { - for (argument, expected) in arg_values.iter_mut().zip(expected_arguments) { - let (normalized, normalized_last_op) = normalize_call_pointer_argument( - ctx, - *argument, - expected, - block_ptr, - last_op, - loc.clone(), - ); - *argument = normalized; - last_op = normalized_last_op; - } - } - } - // Ordinary Rust helper signatures also expose generic pointers. Resolve // the monomorphized operand type (not an unresolved trait signature), and // adapt only address space. All other type/provenance mismatches still @@ -422,6 +389,73 @@ pub fn emit_function_call( } } + emit_function_call_values( + ctx, + body, + callee_name, + arg_values, + destination, + return_type, + external_callee_type, + target, + block_ptr, + last_op, + value_map, + block_map, + loc, + ) +} + +/// Emit already translated arguments at an explicit foreign ABI boundary. +#[allow(clippy::too_many_arguments)] +pub(crate) fn emit_function_call_values( + ctx: &mut Context, + body: &mir::Body, + callee_name: &str, + mut arg_values: Vec, + destination: &mir::Place, + return_type: TypeHandle, + external_callee_type: Option, + target: &Option, + block_ptr: Ptr, + mut last_op: Option>, + value_map: &mut ValueMap, + block_map: &[Ptr], + loc: Location, +) -> TranslationResult> { + // A Rust foreign declaration uses generic pointers at its ABI surface, + // while an argument may retain a concrete GPU address space internally + // (for example, `*mut T` in shared memory). Adapt that representation at + // the frozen declaration boundary, but only when pointee, mutability, and + // source pointer kind already agree exactly. This is not authority to turn + // a raw pointer into a reference or otherwise manufacture provenance. + if let Some(signature) = external_callee_type { + let expected_arguments = { + let signature_ref = signature.deref(ctx); + let signature = signature_ref + .downcast_ref::() + .expect("foreign callee type must be a builtin FunctionType"); + signature.arg_types() + }; + + // Variadic declarations are rejected before this point, so unequal + // arity is invalid and must remain visible to MirCallOp verification. + if arg_values.len() == expected_arguments.len() { + for (argument, expected) in arg_values.iter_mut().zip(expected_arguments) { + let (normalized, normalized_last_op) = normalize_call_pointer_argument( + ctx, + *argument, + expected, + block_ptr, + last_op, + loc.clone(), + ); + *argument = normalized; + last_op = normalized_last_op; + } + } + } + let prepared_destination = if target.is_some() { let (prepared, prepared_last_op) = prepare_destination_write( ctx, diff --git a/cuda-oxide/crates/mir-importer/src/translator/terminator/intrinsics/memory.rs b/cuda-oxide/crates/mir-importer/src/translator/terminator/intrinsics/memory.rs index 9de8b59a6f..aeb119c206 100644 --- a/cuda-oxide/crates/mir-importer/src/translator/terminator/intrinsics/memory.rs +++ b/cuda-oxide/crates/mir-importer/src/translator/terminator/intrinsics/memory.rs @@ -1010,6 +1010,7 @@ pub fn emit_dynamic_shared_get( loc: Location, byte_offset: u64, alignment: u64, + fixed_extent: bool, ) -> TranslationResult> { use dialect_mir::ops::MirExternSharedOp; // Get the destination type to determine the pointer element type @@ -1041,6 +1042,32 @@ pub fn emit_dynamic_shared_get( } }; + let layout = if fixed_extent { + Some( + pointee_ty + .layout() + .map_err(|error| { + pliron::input_error!( + loc.clone(), + TranslationErr::unsupported(format!( + "cannot determine fixed shared layout: {error:?}" + )) + ) + })? + .shape(), + ) + } else { + None + }; + let alignment = layout + .as_ref() + .map_or(alignment, |layout| alignment.max(layout.abi_align)); + if fixed_extent && !alignment.is_power_of_two() { + return input_err!( + loc.clone(), + TranslationErr::invalid_op("fixed shared alignment must be a nonzero power of two") + ); + } let elem_ty = crate::translator::types::translate_type(ctx, &pointee_ty)?; // Create a shared memory pointer type (addrspace 3) @@ -1067,6 +1094,27 @@ pub fn emit_dynamic_shared_get( 0, ); op.deref_mut(ctx).set_loc(loc.clone()); + if let Some(layout) = layout { + use pliron::builtin::attributes::IntegerAttr; + use pliron::utils::apint::APInt; + let ty = pliron::builtin::types::IntegerType::get( + ctx, + 64, + pliron::builtin::types::Signedness::Unsigned, + ); + op.deref_mut(ctx).attributes.set( + crate::kernel_resources::FIXED_SHARED_BYTES + .try_into() + .unwrap(), + IntegerAttr::new( + ty, + APInt::from_u64( + layout.size.bytes() as u64, + std::num::NonZeroUsize::new(64).unwrap(), + ), + ), + ); + } let extern_shared = MirExternSharedOp::new(op); diff --git a/cuda-oxide/crates/mir-importer/src/translator/terminator/mod.rs b/cuda-oxide/crates/mir-importer/src/translator/terminator/mod.rs index 524771dea8..b36b13de42 100644 --- a/cuda-oxide/crates/mir-importer/src/translator/terminator/mod.rs +++ b/cuda-oxide/crates/mir-importer/src/translator/terminator/mod.rs @@ -968,6 +968,27 @@ fn translate_call( let (pattern_name, call_name, substs_args, type_substs) = extract_func_info(func, &loc)?; let loc = call_debug_location(pattern_name.as_deref(), loc); + if let mir::Operand::Constant(constant) = func + && let rustc_public::ty::TyKind::RigidTy(rustc_public::ty::RigidTy::FnDef(def, substs)) = + constant.const_.ty().kind() + && let Ok(instance) = rustc_public::mir::mono::Instance::resolve(def, &substs) + && let Some(plan) = crate::library::get_call(instance.mangled_name().as_str()) + { + return crate::library::translate_call( + ctx, + body, + &plan, + args, + destination, + &target_usize, + block_ptr, + prev_op, + value_map, + block_map, + loc, + ); + } + // Keep CuTe calls as CuTe operations while their tensor and layout // meaning is still visible. Ordinary source helpers continue through the // normal Rust-body path. @@ -1169,6 +1190,7 @@ fn translate_call( loc, 0, // byte_offset = 0 for get() and get_raw() alignment, // User-specified or default alignment + name.contains("::get_fixed"), ); } else if name.contains("::offset") { // DynamicSharedArray::offset(byte_offset) - get pointer at byte offset @@ -1496,6 +1518,7 @@ const KERNEL_METADATA_MARKERS: &[&str] = &[ "cuda_device::thread::__unchecked_indexing_config", "cuda_device::cluster::__cluster_config", "cuda_device::shared::__dynamic_shared_alignment", + "cuda_device::shared::__dynamic_shared_inferred", ]; /// Keep the macro-injected launch-context constructor out of user line tables. @@ -3197,7 +3220,8 @@ fn try_dispatch_intrinsic( loc, ))) } - "cuda_device::shared::__dynamic_shared_alignment" => { + "cuda_device::shared::__dynamic_shared_alignment" + | "cuda_device::shared::__dynamic_shared_inferred" => { // Zero-cost marker injected by #[launch_contract]. body.rs records // the const alignment on the kernel; no runtime call survives. let actual_prev_op = match prev_op { diff --git a/cuda-oxide/crates/mir-lower/src/lib.rs b/cuda-oxide/crates/mir-lower/src/lib.rs index 82fa281c4b..0e34ac7ce7 100644 --- a/cuda-oxide/crates/mir-lower/src/lib.rs +++ b/cuda-oxide/crates/mir-lower/src/lib.rs @@ -128,6 +128,7 @@ pub mod conversion_interface; pub mod convert; pub mod helpers; pub mod lowering; +pub use lowering::propagate_kernel_dynamic_shared_alignments; mod packed_shared_local_storage; pub mod scalarize_block_args; pub mod type_conversion_interface; diff --git a/cuda-oxide/crates/mir-lower/src/lowering.rs b/cuda-oxide/crates/mir-lower/src/lowering.rs index b0877b5b7e..f709627221 100644 --- a/cuda-oxide/crates/mir-lower/src/lowering.rs +++ b/cuda-oxide/crates/mir-lower/src/lowering.rs @@ -78,10 +78,7 @@ const RETURN_ABI_ALIGN_ATTR: &str = "cuda_oxide_return_abi_align"; /// shared-memory access can also live in a deeper ordinary helper. Shared /// helpers receive the maximum requirement from every marked root that can /// reach them. -pub(crate) fn propagate_kernel_dynamic_shared_alignments( - ctx: &mut Context, - module_op: Ptr, -) { +pub fn propagate_kernel_dynamic_shared_alignments(ctx: &mut Context, module_op: Ptr) { let mut functions = FxHashMap::default(); for region in module_op.deref(ctx).regions() { for block in region.deref(ctx).iter(ctx) { diff --git a/cuda-oxide/crates/oxide-artifacts/README.md b/cuda-oxide/crates/oxide-artifacts/README.md index d51f218699..98b9c6598f 100644 --- a/cuda-oxide/crates/oxide-artifacts/README.md +++ b/cuda-oxide/crates/oxide-artifacts/README.md @@ -56,7 +56,7 @@ Artifact Blob +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Payload Count | Entry Count | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | Compile Options (v2) / Reserved Zero (v1) | + | Compile Options (v2/v3) / Reserved Zero (v1) | | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Bundle Name ... / @@ -74,14 +74,14 @@ Artifact Blob Header size is currently 32 bytes. The final field occupies bytes 24 through 31 (the half-open range `[24, 32)`) and is a 64-bit compile-options bitset in -version 2. Bit 0 disables FMA contraction; unknown option bits are rejected. +versions 2 and 3. Bit 0 disables FMA contraction; unknown option bits are rejected. Version-1 bundles define the same bytes as reserved zero and use the historical default policy, where FMA contraction is allowed. -Version 2 is the latest supported format. For backward compatibility, the -writer still emits version 1 when the compile-options bitset is zero. It emits -version 2 only when a bundle carries a non-default compile policy, ensuring -that an older reader rejects policy it would otherwise silently ignore. +Version 3 carries finalized kernel launch facts. Bundles without launch facts +retain their existing encoding: version 1 for default compile policy and version +2 for non-default compile policy. A reader that does not support version 3 +rejects those bundles before loading code with unknown launch requirements. ```text Payload Record (24 bytes) @@ -111,7 +111,7 @@ Payload kind values: - `0x0200`: cubin ```text -Entry Record (24 bytes) +Entry Record (24 bytes in v1/v2; 48 bytes in v3) 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -135,8 +135,31 @@ Entry kind values: - `2`: device function If bit 0 of `Flags` is set, `Metadata` is present and interpreted by the -consumer for that entry kind. No metadata interpretation is currently required -for PTX kernel loading. +consumer for that entry kind. This opaque metadata is independent of typed +launch facts. + +Version 3 adds the following fields to every entry record: + +| Byte offset | Field | Type | +| --- | --- | --- | +| 24 | Exact block X | u32 | +| 28 | Exact block Y | u32 | +| 32 | Exact block Z | u32 | +| 36 | Finalized dynamic shared-memory bytes per block | u32 | +| 40 | Dynamic shared-memory alignment | u32 | +| 44 | Reserved zero | u32 | + +Flag bit 1 indicates that launch facts are present; bit 2 indicates an exact +block shape and requires bit 1. Facts are valid only for kernel entries. Exact +block dimensions must be nonzero and alignment must be a nonzero power of two. +Unknown version-3 entry flags are rejected. Absent fields are written as zero. + +Each record describes its concrete entry symbol, including separate generic +monomorphizations. A zero-byte allocation is distinct from absent facts. The +byte count excludes static shared memory and driver-reserved memory. The +producer supplies a finalized allocation and a matching generated alignment; +the container validates their representation but does not derive requirements +from device code or prove that the producer's claims are true. ## Object Storage @@ -154,11 +177,11 @@ cubin from embedded NVVM IR/LTOIR before loading. ## Constraints -- The latest supported format version is `2`; default-policy bundles are still - emitted as version `1` for backward compatibility. +- The latest supported format version is `3`; bundles without launch facts + retain their version `1` or `2` encoding. - All numeric fields are little-endian. - The blob header is fixed at 32 bytes. -- Payload and entry records are fixed at 24 bytes each. +- Payload records are 24 bytes; entry records are 24 bytes in v1/v2 and 48 in v3. - String and payload offsets are 32-bit, so a single blob must fit in `u32::MAX` bytes. - String lengths and record counts are 16-bit. diff --git a/cuda-oxide/crates/oxide-artifacts/src/lib.rs b/cuda-oxide/crates/oxide-artifacts/src/lib.rs index 99ef56fea2..7f0fc9ae5d 100644 --- a/cuda-oxide/crates/oxide-artifacts/src/lib.rs +++ b/cuda-oxide/crates/oxide-artifacts/src/lib.rs @@ -15,12 +15,20 @@ pub const ARTIFACT_SECTION_NAME: &str = ".oxart"; #[cfg(feature = "object-write")] const ARTIFACT_ANCHOR_SECTION_NAME: &str = ".oxlink"; pub const ARTIFACT_MAGIC: [u8; 8] = *b"OXIDEART"; -pub const ARTIFACT_VERSION: u16 = 2; +pub const ARTIFACT_VERSION: u16 = 3; +const COMPILE_OPTIONS_ARTIFACT_VERSION: u16 = 2; const LEGACY_ARTIFACT_VERSION: u16 = 1; const HEADER_BYTES: usize = 32; const PAYLOAD_RECORD_BYTES: usize = 24; -const ENTRY_RECORD_BYTES: usize = 24; +const LEGACY_ENTRY_RECORD_BYTES: usize = 24; +const ENTRY_RECORD_BYTES: usize = 48; + +const ENTRY_METADATA_PRESENT: u16 = 1; +const ENTRY_LAUNCH_FACTS_PRESENT: u16 = 1 << 1; +const ENTRY_EXACT_BLOCK_PRESENT: u16 = 1 << 2; +const KNOWN_ENTRY_FLAGS: u16 = + ENTRY_METADATA_PRESENT | ENTRY_LAUNCH_FACTS_PRESENT | ENTRY_EXACT_BLOCK_PRESENT; const OPTION_NO_FMA_CONTRACTION: u64 = 1 << 0; const OPTION_DEBUG_LINE_TABLES: u64 = 1 << 1; @@ -223,11 +231,28 @@ impl<'a> ArtifactPayloadSpec<'a> { } } +/// Finalized launch requirements for one concrete kernel entry. +/// +/// These facts describe the allocation selected by the compiler. They do not +/// include static shared memory or driver-reserved memory. An absent record +/// means that the producer did not provide finalized requirements; it is +/// distinct from a record requiring zero dynamic bytes. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct KernelLaunchFacts { + /// Required `(x, y, z)` block dimensions, when the kernel needs an exact shape. + pub exact_block: Option<(u32, u32, u32)>, + /// Finalized dynamic shared-memory allocation in bytes per block. + pub dynamic_shared_bytes: u32, + /// Alignment required by the generated dynamic shared-memory declaration. + pub dynamic_shared_alignment: u32, +} + #[derive(Clone, Debug, PartialEq, Eq)] pub struct ArtifactEntrySpec<'a> { pub symbol: &'a str, pub kind: ArtifactEntryKind, pub metadata: Option, + pub launch_facts: Option, } impl<'a> ArtifactEntrySpec<'a> { @@ -236,6 +261,7 @@ impl<'a> ArtifactEntrySpec<'a> { symbol, kind, metadata: None, + launch_facts: None, } } @@ -243,6 +269,11 @@ impl<'a> ArtifactEntrySpec<'a> { self.metadata = Some(metadata); self } + + pub const fn with_launch_facts(mut self, facts: KernelLaunchFacts) -> Self { + self.launch_facts = Some(facts); + self + } } #[derive(Clone, Debug, PartialEq, Eq)] @@ -293,6 +324,7 @@ pub struct ArtifactEntry<'a> { pub symbol: &'a str, pub kind: ArtifactEntryKind, pub metadata: Option, + pub launch_facts: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -329,6 +361,7 @@ pub struct OwnedArtifactEntry { pub symbol: String, pub kind: ArtifactEntryKind, pub metadata: Option, + pub launch_facts: Option, } #[derive(Clone, Debug, PartialEq, Eq)] @@ -375,6 +408,7 @@ impl<'a> From> for OwnedArtifactBundle { symbol: entry.symbol.to_string(), kind: entry.kind, metadata: entry.metadata, + launch_facts: entry.launch_facts, }) .collect(), } @@ -445,6 +479,15 @@ impl std::error::Error for ArtifactError {} pub fn build_artifact_blob(spec: &ArtifactBundleSpec<'_>) -> Result, ArtifactError> { validate_spec(spec)?; + let has_launch_facts = spec + .entries + .iter() + .any(|entry| entry.launch_facts.is_some()); + let entry_record_bytes = if has_launch_facts { + ENTRY_RECORD_BYTES + } else { + LEGACY_ENTRY_RECORD_BYTES + }; let mut out = vec![0; HEADER_BYTES]; push_bytes(&mut out, spec.name.as_bytes()); push_bytes(&mut out, spec.target.as_bytes()); @@ -452,7 +495,7 @@ pub fn build_artifact_blob(spec: &ArtifactBundleSpec<'_>) -> Result, Art let payload_record_start = out.len(); out.resize(out.len() + spec.payloads.len() * PAYLOAD_RECORD_BYTES, 0); let entry_record_start = out.len(); - out.resize(out.len() + spec.entries.len() * ENTRY_RECORD_BYTES, 0); + out.resize(out.len() + spec.entries.len() * entry_record_bytes, 0); for (index, payload) in spec.payloads.iter().enumerate() { let name_offset = checked_u32(out.len(), "payload name offset")?; @@ -484,9 +527,21 @@ pub fn build_artifact_blob(spec: &ArtifactBundleSpec<'_>) -> Result, Art push_bytes(&mut out, entry.symbol.as_bytes()); align_vec(&mut out, 8); - let record = entry_record_start + index * ENTRY_RECORD_BYTES; + let record = entry_record_start + index * entry_record_bytes; write_u16(&mut out, record, entry.kind.to_u16()); - write_u16(&mut out, record + 2, u16::from(entry.metadata.is_some())); + let mut flags = u16::from(entry.metadata.is_some()); + if let Some(facts) = entry.launch_facts { + flags |= ENTRY_LAUNCH_FACTS_PRESENT; + if let Some((x, y, z)) = facts.exact_block { + flags |= ENTRY_EXACT_BLOCK_PRESENT; + write_u32(&mut out, record + 24, x); + write_u32(&mut out, record + 28, y); + write_u32(&mut out, record + 32, z); + } + write_u32(&mut out, record + 36, facts.dynamic_shared_bytes); + write_u32(&mut out, record + 40, facts.dynamic_shared_alignment); + } + write_u16(&mut out, record + 2, flags); write_u64(&mut out, record + 4, entry.metadata.unwrap_or(0)); write_u32(&mut out, record + 12, symbol_offset); write_u16( @@ -498,13 +553,15 @@ pub fn build_artifact_blob(spec: &ArtifactBundleSpec<'_>) -> Result, Art let total_len = checked_u32(out.len(), "total length")?; out[0..8].copy_from_slice(&ARTIFACT_MAGIC); - // Keep default-policy bundles on v1 for backward compatibility. A bundle - // that carries required compile policy uses v2 so an older reader rejects - // it instead of silently ignoring the semantic flag. - let version = if spec.compile_options == ArtifactCompileOptions::new() { + // Preserve the legacy bytes when no launch facts are supplied. Required + // launch facts use v3 so older readers reject them instead of silently + // ignoring the kernel's resource requirements. + let version = if has_launch_facts { + ARTIFACT_VERSION + } else if spec.compile_options == ArtifactCompileOptions::new() { LEGACY_ARTIFACT_VERSION } else { - ARTIFACT_VERSION + COMPILE_OPTIONS_ARTIFACT_VERSION }; write_u16(&mut out, 8, version); write_u16(&mut out, 10, HEADER_BYTES as u16); @@ -550,7 +607,10 @@ pub fn parse_artifact_blob(bytes: &[u8]) -> Result, ArtifactE return Err(ArtifactError::BadMagic); } let version = read_u16(bytes, 8)?; - if !matches!(version, LEGACY_ARTIFACT_VERSION | ARTIFACT_VERSION) { + if !matches!( + version, + LEGACY_ARTIFACT_VERSION | COMPILE_OPTIONS_ARTIFACT_VERSION | ARTIFACT_VERSION + ) { return Err(ArtifactError::UnsupportedVersion(version)); } let header_len = read_u16(bytes, 10)? as usize; @@ -591,8 +651,13 @@ pub fn parse_artifact_blob(bytes: &[u8]) -> Result, ArtifactE .ok_or(ArtifactError::TooLarge("payload records"))?; require_len(bytes, cursor, "payload records")?; let entry_records = cursor; + let entry_record_bytes = if version == ARTIFACT_VERSION { + ENTRY_RECORD_BYTES + } else { + LEGACY_ENTRY_RECORD_BYTES + }; cursor = cursor - .checked_add(entry_count * ENTRY_RECORD_BYTES) + .checked_add(entry_count * entry_record_bytes) .ok_or(ArtifactError::TooLarge("entry records"))?; require_len(bytes, cursor, "entry records")?; @@ -617,12 +682,12 @@ pub fn parse_artifact_blob(bytes: &[u8]) -> Result, ArtifactE let mut entries = Vec::with_capacity(entry_count); for index in 0..entry_count { - let record = entry_records + index * ENTRY_RECORD_BYTES; + let record = entry_records + index * entry_record_bytes; let kind_raw = read_u16(bytes, record)?; let kind = ArtifactEntryKind::from_u16(kind_raw) .ok_or(ArtifactError::UnsupportedEntryKind(kind_raw))?; let flags = read_u16(bytes, record + 2)?; - let metadata = if flags & 1 != 0 { + let metadata = if flags & ENTRY_METADATA_PRESENT != 0 { Some(read_u64(bytes, record + 4)?) } else { None @@ -630,10 +695,40 @@ pub fn parse_artifact_blob(bytes: &[u8]) -> Result, ArtifactE let symbol_offset = read_u32(bytes, record + 12)? as usize; let symbol_len = read_u16(bytes, record + 16)? as usize; let symbol = read_str(bytes, symbol_offset, symbol_len, "entry symbol")?; + let launch_facts = if version == ARTIFACT_VERSION { + if flags & !KNOWN_ENTRY_FLAGS != 0 + || flags & ENTRY_EXACT_BLOCK_PRESENT != 0 && flags & ENTRY_LAUNCH_FACTS_PRESENT == 0 + { + return Err(ArtifactError::Malformed(format!( + "invalid launch-facts flags {flags:#x} for entry '{symbol}'" + ))); + } + if flags & ENTRY_LAUNCH_FACTS_PRESENT != 0 { + Some(KernelLaunchFacts { + exact_block: if flags & ENTRY_EXACT_BLOCK_PRESENT != 0 { + Some(( + read_u32(bytes, record + 24)?, + read_u32(bytes, record + 28)?, + read_u32(bytes, record + 32)?, + )) + } else { + None + }, + dynamic_shared_bytes: read_u32(bytes, record + 36)?, + dynamic_shared_alignment: read_u32(bytes, record + 40)?, + }) + } else { + None + } + } else { + None + }; + validate_launch_facts(symbol, kind, launch_facts)?; entries.push(ArtifactEntry { symbol, kind, metadata, + launch_facts, }); } @@ -880,10 +975,39 @@ fn validate_spec(spec: &ArtifactBundleSpec<'_>) -> Result<(), ArtifactError> { if entry.symbol.is_empty() { return Err(ArtifactError::EmptyEntrySymbol); } + validate_launch_facts(entry.symbol, entry.kind, entry.launch_facts)?; } Ok(()) } +fn validate_launch_facts( + symbol: &str, + kind: ArtifactEntryKind, + facts: Option, +) -> Result<(), ArtifactError> { + let Some(facts) = facts else { + return Ok(()); + }; + let reason = if kind != ArtifactEntryKind::Kernel { + Some("launch facts require a kernel entry") + } else if facts + .exact_block + .is_some_and(|(x, y, z)| x == 0 || y == 0 || z == 0) + { + Some("exact block dimensions must be nonzero") + } else if !facts.dynamic_shared_alignment.is_power_of_two() { + Some("dynamic shared-memory alignment must be a nonzero power of two") + } else { + None + }; + match reason { + Some(reason) => Err(ArtifactError::Malformed(format!( + "invalid launch facts for entry '{symbol}': {reason}" + ))), + None => Ok(()), + } +} + fn checked_u16(value: usize, field: &'static str) -> Result { u16::try_from(value).map_err(|_| ArtifactError::TooLarge(field)) } @@ -1005,6 +1129,160 @@ mod tests { ); } + #[test] + fn concrete_kernel_launch_facts_survive_borrowed_and_owned_bundles() { + let first = KernelLaunchFacts { + exact_block: Some((32, 1, 1)), + dynamic_shared_bytes: 128, + dynamic_shared_alignment: 16, + }; + let second = KernelLaunchFacts { + exact_block: Some((8, 4, 1)), + dynamic_shared_bytes: 512, + dynamic_shared_alignment: 64, + }; + let empty = KernelLaunchFacts { + exact_block: None, + dynamic_shared_bytes: 0, + dynamic_shared_alignment: 1, + }; + let blob = build_artifact_blob( + &ArtifactBundleSpec::new("demo", "sm_90") + .with_compile_options(ArtifactCompileOptions::new().with_fma_contraction(false)) + .with_payload(ArtifactPayloadSpec::new( + ArtifactPayloadKind::Cubin, + "demo.cubin", + b"cubin", + )) + .with_entry( + ArtifactEntrySpec::new("apply_items_1", ArtifactEntryKind::Kernel) + .with_metadata(7) + .with_launch_facts(first), + ) + .with_entry( + ArtifactEntrySpec::new("apply_items_4", ArtifactEntryKind::Kernel) + .with_launch_facts(second), + ) + .with_entry( + ArtifactEntrySpec::new("no_scratch", ArtifactEntryKind::Kernel) + .with_launch_facts(empty), + ) + .with_entry(ArtifactEntrySpec::new( + "helper", + ArtifactEntryKind::DeviceFunction, + )), + ) + .unwrap(); + assert_eq!(read_u16(&blob, 8).unwrap(), ARTIFACT_VERSION); + let borrowed = parse_artifact_blob(&blob).unwrap(); + assert!(!borrowed.compile_options.fma_contraction_enabled()); + assert_eq!(borrowed.entry("apply_items_1").unwrap().metadata, Some(7)); + assert_eq!( + borrowed.entry("apply_items_1").unwrap().launch_facts, + Some(first) + ); + assert_eq!( + borrowed.entry("apply_items_4").unwrap().launch_facts, + Some(second) + ); + assert_eq!( + borrowed.entry("no_scratch").unwrap().launch_facts, + Some(empty) + ); + assert_eq!(borrowed.entry("helper").unwrap().launch_facts, None); + let owned = OwnedArtifactBundle::from(borrowed.clone()); + for entry in borrowed.entries { + assert_eq!( + owned.entry(entry.symbol).unwrap().launch_facts, + entry.launch_facts + ); + } + } + + #[test] + fn launch_facts_reject_invalid_shape_alignment_and_entry_kind() { + let valid = KernelLaunchFacts { + exact_block: Some((32, 1, 1)), + dynamic_shared_bytes: 128, + dynamic_shared_alignment: 16, + }; + let spec = |kind, facts| { + ArtifactBundleSpec::new("demo", "sm_90") + .with_payload(ArtifactPayloadSpec::new( + ArtifactPayloadKind::Ptx, + "demo.ptx", + b"ptx", + )) + .with_entry(ArtifactEntrySpec::new("hello", kind).with_launch_facts(facts)) + }; + for (kind, facts) in [ + (ArtifactEntryKind::DeviceFunction, valid), + ( + ArtifactEntryKind::Kernel, + KernelLaunchFacts { + exact_block: Some((32, 0, 1)), + ..valid + }, + ), + ( + ArtifactEntryKind::Kernel, + KernelLaunchFacts { + dynamic_shared_alignment: 0, + ..valid + }, + ), + ( + ArtifactEntryKind::Kernel, + KernelLaunchFacts { + dynamic_shared_alignment: 3, + ..valid + }, + ), + ] { + assert!(matches!( + build_artifact_blob(&spec(kind, facts)), + Err(ArtifactError::Malformed(_)) + )); + } + + let blob = build_artifact_blob(&spec(ArtifactEntryKind::Kernel, valid)).unwrap(); + let record = sample_payload_record_start() + PAYLOAD_RECORD_BYTES; + for (offset, value) in [(28, 0), (40, 3)] { + let mut corrupt = blob.clone(); + write_u32(&mut corrupt, record + offset, value); + assert!(matches!( + parse_artifact_blob(&corrupt), + Err(ArtifactError::Malformed(_)) + )); + } + let mut wrong_kind = blob.clone(); + write_u16( + &mut wrong_kind, + record, + ArtifactEntryKind::DeviceFunction.to_u16(), + ); + assert!(matches!( + parse_artifact_blob(&wrong_kind), + Err(ArtifactError::Malformed(_)) + )); + for flags in [ENTRY_EXACT_BLOCK_PRESENT, KNOWN_ENTRY_FLAGS | (1 << 3)] { + let mut corrupt = blob.clone(); + write_u16(&mut corrupt, record + 2, flags); + assert!(matches!( + parse_artifact_blob(&corrupt), + Err(ArtifactError::Malformed(_)) + )); + } + + let mut truncated = blob[..record + ENTRY_RECORD_BYTES - 1].to_vec(); + let len = truncated.len() as u32; + write_u32(&mut truncated, 12, len); + assert_eq!( + parse_artifact_blob(&truncated), + Err(ArtifactError::Truncated("entry records")) + ); + } + #[test] fn artifact_blob_round_trips_non_ptx_payload_kinds() { let blob = build_artifact_blob( @@ -1027,7 +1305,10 @@ mod tests { )), ) .unwrap(); - assert_eq!(read_u16(&blob, 8).unwrap(), ARTIFACT_VERSION); + assert_eq!( + read_u16(&blob, 8).unwrap(), + COMPILE_OPTIONS_ARTIFACT_VERSION + ); let bundles = parse_artifact_section(&blob).unwrap(); assert_eq!(bundles.len(), 1); @@ -1065,7 +1346,7 @@ mod tests { #[test] fn version_2_rejects_unknown_compile_option_bits() { let mut blob = sample_blob(); - write_u16(&mut blob, 8, ARTIFACT_VERSION); + write_u16(&mut blob, 8, COMPILE_OPTIONS_ARTIFACT_VERSION); write_u64(&mut blob, 24, 1 << 63); assert!(matches!( @@ -1110,7 +1391,10 @@ mod tests { ) .unwrap(); - assert_eq!(read_u16(&blob, 8).unwrap(), ARTIFACT_VERSION); + assert_eq!( + read_u16(&blob, 8).unwrap(), + COMPILE_OPTIONS_ARTIFACT_VERSION + ); assert_eq!( parse_artifact_blob(&blob).unwrap().compile_options, expected @@ -1121,7 +1405,7 @@ mod tests { #[test] fn version_2_rejects_conflicting_debug_bits() { let mut blob = sample_blob(); - write_u16(&mut blob, 8, ARTIFACT_VERSION); + write_u16(&mut blob, 8, COMPILE_OPTIONS_ARTIFACT_VERSION); write_u64(&mut blob, 24, OPTION_DEBUG_MASK); assert!(matches!( diff --git a/cuda-oxide/crates/reserved-oxide-symbols/src/lib.rs b/cuda-oxide/crates/reserved-oxide-symbols/src/lib.rs index 010bc715d2..2b0a27b1d4 100644 --- a/cuda-oxide/crates/reserved-oxide-symbols/src/lib.rs +++ b/cuda-oxide/crates/reserved-oxide-symbols/src/lib.rs @@ -72,6 +72,12 @@ pub const MATERIALIZER_PROVENANCE_ENV: &str = "CUDA_OXIDE_INTERNAL_MATERIALIZER_ /// code remains keyed by the content-derived provenance digest. pub const MATERIALIZER_HANDSHAKE_ENV: &str = "CUDA_OXIDE_INTERNAL_MATERIALIZER_HANDSHAKE"; +/// Ordered, content-bound external LTO-IR files supplied by cargo-oxide. +pub const EXTERNAL_LTOIR_ENV: &str = "CUDA_OXIDE_INTERNAL_EXTERNAL_LTOIR_V1"; + +/// Definition name in `cuda_device::library`; consumers resolve its actual DefId. +pub const LIBRARY_CALL_V1: &str = "cuda_oxide_library_v1_246e25db_call"; + /// Optional comma-separated filter selecting crates that may own device code. pub const DEVICE_CODEGEN_CRATE_ENV: &str = "CUDA_OXIDE_DEVICE_CODEGEN_CRATE"; @@ -143,6 +149,11 @@ pub const LEGACY_DEVICE_PREFIX: &str = "cuda_oxide_device_246e25db_"; /// linker resolves against the original (unprefixed) external symbol. pub const DEVICE_EXTERN_PREFIX: &str = "cuda_oxide_device_extern_246e25db_"; +/// Doc-alias marker retained after `#[convergent]` macro expansion. +/// Unlike doc comments, aliases survive dependency metadata even for private +/// externs reached through a downstream generic instantiation. +pub const DEVICE_EXTERN_CONVERGENT_MARKER: &str = "cuda_oxide_device_extern_convergent_246e25db"; + /// Prefix added to closure-monomorphization helper functions generated /// by `#[kernel]` for kernels that take a closure parameter. /// diff --git a/cuda-oxide/crates/rustc-codegen-cuda/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/Cargo.lock index 512dd99178..5dc34b674a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/Cargo.lock @@ -627,8 +627,6 @@ checksum = "0b61fbf7ec37342ce171d9f5e3b82be74bda6c4e84e3b28338a03d553913e6aa" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] @@ -815,6 +813,7 @@ dependencies = [ "pliron", "pliron-derive", "reserved-oxide-symbols", + "serde", "serde_json", "thiserror", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/Cargo.toml index c20211c939..d1c3fb3598 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/Cargo.toml +++ b/cuda-oxide/crates/rustc-codegen-cuda/Cargo.toml @@ -26,7 +26,7 @@ dialect-nvvm = { path = "../dialect-nvvm" } reserved-oxide-symbols = { path = "../reserved-oxide-symbols" } # `#[tile_export]` descriptions, read back out of the metadata functions' MIR. oxide-tile-export = { path = "../oxide-tile-export" } -oxide-artifacts = { version = "0.2.1", features = ["object-write"] } +oxide-artifacts = { version = "0.2.1", path = "../oxide-artifacts", features = ["object-write"] } # Shared driver-independent libNVVM + nvJitLink finalization policy. This # crate loads CUDA compiler libraries at run time and never links libcuda. cuda-artifact-finalizer = { path = "../cuda-artifact-finalizer" } @@ -42,6 +42,7 @@ combine = "4.6.8" # must match workspace; Pliron needs SourcePosition: H once_cell = "1.18" # must match workspace thiserror = "2" # must match workspace serde_json = "1" # must match workspace +serde = { version = "1", features = ["derive"] } # Note: rustc internal crates are NOT listed here. # They're accessed via `extern crate` with #![feature(rustc_private)] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/abi_hmm/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/abi_hmm/Cargo.lock index 894c5bdc74..b61cbb25eb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/abi_hmm/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/abi_hmm/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/addressof_sharedarray/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/addressof_sharedarray/Cargo.lock index aec55dddd1..e5ee0008af 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/addressof_sharedarray/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/addressof_sharedarray/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_loads/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_loads/Cargo.lock index 66d6f345c4..921af297cc 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_loads/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_loads/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_stores/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_stores/Cargo.lock index d3a69ad842..5e318116b9 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_stores/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/aligned_field_stores/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_constants/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_constants/Cargo.lock index 2ace543695..9010ea761f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_constants/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_constants/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_for_loop/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_for_loop/Cargo.lock index 50e069c917..bd29bc2233 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_for_loop/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_for_loop/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_index/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_index/Cargo.lock index 9aacc03b6a..0df32917f3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_index/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_index/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_init/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_init/Cargo.lock index 23873c746e..0be3348c82 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/array_init/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/array_init/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/asin_acos_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/asin_acos_smoke/Cargo.lock index 11978cf8c3..8c98074f13 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/asin_acos_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/asin_acos_smoke/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/assume_init_uninhabited_trap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/assume_init_uninhabited_trap/Cargo.lock index 57c5ac3626..0e6d47b26e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/assume_init_uninhabited_trap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/assume_init_uninhabited_trap/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/async_mlp/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/async_mlp/Cargo.lock index 61356c7cf0..e984e1885d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/async_mlp/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/async_mlp/Cargo.lock @@ -222,6 +222,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -560,8 +562,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/async_vecadd/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/async_vecadd/Cargo.lock index 0f89847696..0e6aaa990b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/async_vecadd/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/async_vecadd/Cargo.lock @@ -222,6 +222,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -560,8 +562,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/atomic_f16/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/atomic_f16/Cargo.lock index 2eedfa7f06..4b444b32b3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/atomic_f16/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/atomic_f16/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/atomics/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/atomics/Cargo.lock index e62f2b5116..cbaf8353f0 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/atomics/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/atomics/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/barrier/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/barrier/Cargo.lock index 167540b149..dfa6ec6f08 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/barrier/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/barrier/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_arith/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_arith/Cargo.lock index 21784a78d9..64f35c4938 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_arith/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_arith/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_fma/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_fma/Cargo.lock index 02c07a415e..e73b06b0fd 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_fma/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/bf16x2_fma/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/bool_phi_cmp/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/bool_phi_cmp/Cargo.lock index dd5b1d27f2..9c01cf23e8 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/bool_phi_cmp/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/bool_phi_cmp/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/carrying_mul_add/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/carrying_mul_add/Cargo.lock index 4029312b7b..468dd3ee25 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/carrying_mul_add/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/carrying_mul_add/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_chunks/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_chunks/Cargo.lock index 23b2870e9f..03f8bb969e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_chunks/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_chunks/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_tests/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_tests/Cargo.lock index 3b2f05431c..1b718bc114 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_tests/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cast_tests/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cbrt_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cbrt_smoke/Cargo.lock index ed4913c237..39b1636454 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cbrt_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cbrt_smoke/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/checked_arith/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/checked_arith/Cargo.lock index 68c6a15821..617f7f152b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/checked_arith/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/checked_arith/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/clc/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/clc/Cargo.lock index e47f313cfc..5d86097f9e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/clc/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/clc/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cluster/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cluster/Cargo.lock index 5d785dbfe8..6678cfdb87 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cluster/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cluster/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/Cargo.lock new file mode 100644 index 0000000000..c1dd14428b --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/Cargo.lock @@ -0,0 +1,966 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "compiled_launch_facts" +version = "0.1.0" +dependencies = [ + "cuda-async", + "cuda-core", + "cuda-device", + "cuda-host", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cuda-artifact-finalizer" +version = "0.2.1" +dependencies = [ + "libnvvm-sys", + "nvjitlink-sys", + "serde", + "sha2", + "thiserror 2.0.18", +] + +[[package]] +name = "cuda-async" +version = "0.5.0" +dependencies = [ + "anyhow", + "cuda-bindings", + "cuda-core", + "dashmap", + "futures", + "half", + "once_cell", + "rustc-hash 2.1.2", + "thiserror 1.0.69", +] + +[[package]] +name = "cuda-bindings" +version = "0.5.0" +dependencies = [ + "bindgen", + "libloading", + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cuda-core" +version = "0.5.0" +dependencies = [ + "anyhow", + "cuda-bindings", + "cuda-core-derive", + "half", + "oxide-artifacts", +] + +[[package]] +name = "cuda-core-derive" +version = "0.5.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cuda-device" +version = "0.2.1" +dependencies = [ + "cuda-macros", +] + +[[package]] +name = "cuda-host" +version = "0.2.1" +dependencies = [ + "cuda-artifact-finalizer", + "cuda-async", + "cuda-core", + "cuda-device", + "cuda-macros", + "half", + "libc", + "oxide-artifacts", + "ptx-parse", + "sha2", + "thiserror 2.0.18", +] + +[[package]] +name = "cuda-macros" +version = "0.2.1" +dependencies = [ + "oxide-tile-export", + "proc-macro2", + "quote", + "reserved-oxide-symbols", + "serde", + "serde_json", + "syn", +] + +[[package]] +name = "cuda-target-spec" +version = "0.1.0" + +[[package]] +name = "dashmap" +version = "6.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6361d5c062261c78a176addb82d4c821ae42bed6089de0e12603cd25de2059c" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-executor" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libnvvm-sys" +version = "0.2.1" +dependencies = [ + "cuda-target-spec", + "libloading", + "thiserror 2.0.18", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nvjitlink-sys" +version = "0.2.1" +dependencies = [ + "libloading", + "thiserror 2.0.18", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "crc32fast", + "hashbrown 0.15.5", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "oxide-artifacts" +version = "0.2.1" +dependencies = [ + "object", +] + +[[package]] +name = "oxide-tile-export" +version = "0.2.1" +dependencies = [ + "serde", + "serde_json", + "thiserror 2.0.18", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptx-parse" +version = "0.1.0" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reserved-oxide-symbols" +version = "0.2.1" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/Cargo.toml new file mode 100644 index 0000000000..5d4e02b884 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "compiled_launch_facts" +version = "0.1.0" +edition = "2024" +license = "Apache-2.0" + +[workspace] + +[features] +generic = [] +invalid-raw = [] + +[dependencies] +cuda-device = { path = "../../../cuda-device" } +cuda-host = { path = "../../../cuda-host", features = ["async"] } +cuda-core = { path = "../../../../../cuda-core" } +cuda-async = { path = "../../../../../cuda-async" } diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/README.md b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/README.md new file mode 100644 index 0000000000..ae1d619f01 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/README.md @@ -0,0 +1,34 @@ +# Compiled launch facts + +This example uses `dynamic_shared = inferred` with unsafe fixed views of the +CUDA dynamic shared-memory base. `Scratch<1>` and `Scratch<4>` have different +compiler layouts, reached through the same generic helper. A second view aliases +the base and raises its alignment to 128 bytes. The views combine by maximum +extent and alignment; they do not allocate separate regions. The helper writes +one slot per lane and explicitly synchronizes before reading neighboring slots. + +The generated prepared launch methods read the facts from the selected embedded +artifact. `LaunchConfig2D::auto_shared` selects 128 or 512 bytes. Preparation +rejects an explicit 511-byte allocation for the larger kernel and rejects a +32-by-1 block even though it has the same thread count as the required 8-by-4 +block. The example also checks known-zero scratch and returns an owned output +buffer only after asynchronous launch completion. + +From `cuda-oxide/`, run with an architecture supported by your device: + +```sh +cargo oxide run compiled_launch_facts --arch sm_120 +cargo oxide run compiled_launch_facts --arch sm_120 --features generic +cargo oxide run compiled_launch_facts --arch sm_120 --materialize-cubin +scripts/check-compiled-launch-facts.sh sm_120 +``` + +The script also checks that an inferred kernel containing an unconstrained raw +dynamic view fails to compile. Generic kernels use the existing PTX loader; +generic materialization remains unsupported. Explicit raw pointer access, +initialization, bounds, aliasing, and synchronization remain the responsibility +of the unsafe device code. No synchronization is inserted by `get_fixed`. +Inference follows Rust views through direct calls. Dynamic-base accesses in +external code, indirect calls or inline assembly must fit a fixed view declared +on that path; they are not analyzed. Without declared views, inference records +zero bytes. diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/src/main.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/src/main.rs new file mode 100644 index 0000000000..fcd6049324 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiled_launch_facts/src/main.rs @@ -0,0 +1,162 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +use cuda_device::{DisjointSlice, kernel, launch_contract, shared::DynamicSharedArray, thread}; +use cuda_host::cuda_module; + +#[repr(C, align(64))] +struct Scratch { + slots: [[u32; 32]; ITEMS], +} + +#[cuda_module] +mod kernels { + use super::*; + + #[inline(never)] + fn exchange() -> u32 { + let lane = (thread::threadIdx_y() * 8 + thread::threadIdx_x()) as usize; + // Both views alias the same base. Every lane writes its own slots; + // the explicit barrier completes those writes before neighbor reads. + unsafe { + let scratch = DynamicSharedArray::, 16>::get_fixed().cast::(); + let alias = DynamicSharedArray::<[u32; 32], 128>::get_fixed().cast::(); + for item in 0..ITEMS { + scratch + .add(item * 32 + lane) + .write_volatile((item * 100 + lane) as u32); + } + thread::sync_threads(); + let neighbor = (lane + 1) % 32; + scratch.add((ITEMS - 1) * 32 + neighbor).read_volatile() + + alias.add(neighbor).read_volatile() + } + } + + #[kernel] + #[launch_contract(domain = 2, block = (8, 4, 1), dynamic_shared = inferred)] + pub fn fixed_one(mut output: DisjointSlice>) { + let value = exchange::<1>(); + if let Some(index) = thread::index_2d::<8>() + && let Some(out) = output.get_mut(index) + { + *out = value; + } + } + + #[kernel] + #[launch_contract(domain = 2, block = (8, 4, 1), dynamic_shared = inferred)] + pub fn fixed_four(mut output: DisjointSlice>) { + let value = exchange::<4>(); + if let Some(index) = thread::index_2d::<8>() + && let Some(out) = output.get_mut(index) + { + *out = value; + } + } + + #[kernel] + #[launch_contract(domain = 2, block = (8, 4, 1), dynamic_shared = inferred)] + pub fn zero() {} + + #[cfg(feature = "generic")] + #[launch_contract(domain = 2, block = (8, 4, 1), dynamic_shared = inferred)] + #[kernel] + pub fn generic(mut output: DisjointSlice>) { + let value = exchange::(); + if let Some(index) = thread::index_2d::<8>() + && let Some(out) = output.get_mut(index) + { + *out = value; + } + } + + #[cfg(feature = "invalid-raw")] + #[kernel] + #[launch_contract(domain = 2, block = (8, 4, 1), dynamic_shared = inferred)] + pub fn incomplete() { + unsafe { + DynamicSharedArray::<[u32; 32], 16>::get_fixed() + .cast::() + .write_volatile(1); + DynamicSharedArray::::get() + .add(64) + .write_volatile(2); + } + } +} + +fn verify(buffer: &cuda_core::DeviceBuffer, stream: &cuda_core::CudaStream, items: u32) { + let mut values = [0; 32]; + buffer.copy_to_host(stream, &mut values).unwrap(); + stream.synchronize().unwrap(); + for (lane, value) in values.into_iter().enumerate() { + assert_eq!(value, (items - 1) * 100 + 2 * ((lane as u32 + 1) % 32)); + } +} + +fn main() -> Result<(), Box> { + use cuda_async::simt::device_context::{init_device_contexts, with_cuda_context}; + use cuda_async::simt::device_operation::DeviceOperation; + use cuda_core::{DeviceBuffer, LaunchConfig2D}; + + init_device_contexts(0, 1)?; + let ctx = with_cuda_context(0, |ctx| ctx.clone())?; + let stream = ctx.default_stream(); + // SAFETY: the embedded module is compiled from these kernel declarations. + let module = unsafe { kernels::load_async(0)? }; + let config = LaunchConfig2D::auto_shared((1, 1), (8, 4)); + let one = module.prepare_fixed_one(config)?; + let four = module.prepare_fixed_four(config)?; + let zero = module.prepare_zero(config)?; + assert_eq!(one.__raw_config().shared_mem_bytes, 128); + assert_eq!(four.__raw_config().shared_mem_bytes, 512); + assert_eq!(zero.__raw_config().shared_mem_bytes, 0); + for prepared_facts in [ + one.function().launch_facts(), + four.function().launch_facts(), + ] { + let facts = prepared_facts.unwrap(); + assert_eq!(facts.exact_block, Some((8, 4, 1))); + assert_eq!(facts.dynamic_shared_alignment, 128); + } + assert_eq!( + zero.function().launch_facts().unwrap().dynamic_shared_bytes, + 0 + ); + assert!(matches!( + module.prepare_fixed_four(LaunchConfig2D::auto_shared((1, 1), (32, 1))), + Err(cuda_core::LaunchContractError::BlockShapeMismatch { .. }) + )); + assert!(matches!( + module.prepare_fixed_four(LaunchConfig2D::new((1, 1), (8, 4), 511)), + Err(cuda_core::LaunchContractError::DynamicSharedMemoryExactMismatch { .. }) + )); + let explicit = module.prepare_fixed_four(LaunchConfig2D::new((1, 1), (8, 4), 512))?; + + let output = DeviceBuffer::from_host(&stream, &[0u32; 32])?; + let output = module.fixed_one_async_owned(&one, output).sync()?; + verify(&output, &stream, 1); + let output = module.fixed_four_async_owned(&explicit, output).sync()?; + verify(&output, &stream, 4); + let output = module.fixed_four_async_owned(&four, output).sync()?; + verify(&output, &stream, 4); + + #[cfg(feature = "generic")] + { + let one = module.prepare_generic::<1>(config)?; + let four = module.prepare_generic::<4>(config)?; + assert_eq!(one.__raw_config().shared_mem_bytes, 128); + assert_eq!(four.__raw_config().shared_mem_bytes, 512); + let output = module.generic_async_owned::<1, _>(&one, output).sync()?; + verify(&output, &stream, 1); + let output = module.generic_async_owned::<4, _>(&four, output).sync()?; + verify(&output, &stream, 4); + } + println!( + "PASS: compiled launch facts: helper layouts, exact shape, explicit/automatic bytes, zero, and owned async passed" + ); + Ok(()) +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/compiler_features/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiler_features/Cargo.lock index f74d2527f8..56be2f9157 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/compiler_features/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/compiler_features/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/complex_mul/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/complex_mul/Cargo.lock index 8e9267dce6..b120f7d4ba 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/complex_mul/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/complex_mul/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_aggregate/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_aggregate/Cargo.lock index 1b55fe2102..11f4a52ad8 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_aggregate/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_aggregate/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_bool_dead_branch/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_bool_dead_branch/Cargo.lock index 1624a6b9f9..d0129db5b8 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_bool_dead_branch/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_bool_dead_branch/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_generic/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_generic/Cargo.lock index 59af5b4d4c..3722835bef 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_generic/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_generic/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_table_lookup/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_table_lookup/Cargo.lock index 6378ac770e..b392b08c49 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_table_lookup/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_table_lookup/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_tuple_table_lookup/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_tuple_table_lookup/Cargo.lock index e5bb7b77b8..d8e511de7e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/const_tuple_table_lookup/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/const_tuple_table_lookup/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_index_from_end/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_index_from_end/Cargo.lock index 4a5ddfcbfc..4c4cc03681 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_index_from_end/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_index_from_end/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory/Cargo.lock index ec1b311b82..d7a2fdc0fb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_coeffs/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_coeffs/Cargo.lock index 254f6e1446..dd05a21911 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_coeffs/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_coeffs/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_simple/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_simple/Cargo.lock index 0290d6b02d..f1119f8ece 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_simple/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_simple/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_table/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_table/Cargo.lock index 5ee35f9f49..6361c87d93 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_table/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/constant_memory_table/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_demo/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_demo/Cargo.lock index 1929b90d68..0892c097ec 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_demo/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_demo/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_aggregate_borrow/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_aggregate_borrow/Cargo.lock index 861cd541fa..a6f836ffd2 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_aggregate_borrow/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_aggregate_borrow/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_nonoverlapping/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_nonoverlapping/Cargo.lock index e0ad2e575b..69fa7aa0e7 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_nonoverlapping/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/copy_nonoverlapping/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/counted_barrier/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/counted_barrier/Cargo.lock index 670a99a5a0..5d37a68a90 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/counted_barrier/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/counted_barrier/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_small/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_small/Cargo.lock index e2b60b35e4..6ec9a630ff 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_small/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_small/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_zfill/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_zfill/Cargo.lock index 554696b9a9..1841b399ca 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_zfill/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cp_async_zfill/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cpp_consumes_rust_device/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cpp_consumes_rust_device/Cargo.lock index 65b1237134..08e3c5ad23 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cpp_consumes_rust_device/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cpp_consumes_rust_device/Cargo.lock @@ -197,6 +197,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -418,8 +420,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_embedded/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_embedded/Cargo.lock index 86fd1896bc..384be6d492 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_embedded/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_embedded/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -429,8 +431,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_kernel/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_kernel/Cargo.lock index 93b3a02f35..549a3770b7 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_kernel/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_kernel/Cargo.lock @@ -200,6 +200,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -430,8 +432,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_merged_symbols/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_merged_symbols/Cargo.lock index 65317d8b2c..015244beff 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_merged_symbols/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_merged_symbols/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -429,8 +431,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_recursion/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_recursion/Cargo.lock index 02fa70fa98..af5245187e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_recursion/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cross_crate_recursion/Cargo.lock @@ -199,6 +199,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_contract/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_contract/Cargo.lock index 4265107f33..d6e13e508a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_contract/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_contract/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_in_lib/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_in_lib/Cargo.lock index e21415db54..f2e91266b5 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_in_lib/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_in_lib/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -429,8 +431,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_nested/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_nested/Cargo.lock index 9cffb5991d..2c608c0120 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_nested/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cuda_module_nested/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/Cargo.lock index 3469a4e1aa..a193b9e820 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/Cargo.lock @@ -713,8 +713,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object 0.36.7", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/simt/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/simt/Cargo.lock index 5b1b40426e..1c16db6d5b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/simt/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cutile_inter_kernel/simt/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_f16x2/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_f16x2/Cargo.lock index 310b4cd386..75090d956c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_f16x2/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_f16x2/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_packed/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_packed/Cargo.lock index a26fc79858..fa83571c17 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_packed/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cvt_packed/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug-tests/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug-tests/Cargo.lock index 896adc4fe1..412c98d7da 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug-tests/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug-tests/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug/Cargo.lock index a9b382b282..b3f053a6bb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug_pointer_locals/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug_pointer_locals/Cargo.lock index c6fcff1155..a4bed0209c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug_pointer_locals/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug_pointer_locals/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_closures/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_closures/Cargo.lock index cd74327ba3..656a35c2c4 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_closures/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_closures/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.lock index 547e2d265c..b1d85005e6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -196,6 +198,13 @@ dependencies = [ name = "cuda-target-spec" version = "0.1.0" +[[package]] +name = "device-ffi-collectives" +version = "0.1.0" +dependencies = [ + "cuda-device", +] + [[package]] name = "device_ffi_test" version = "0.1.0" @@ -203,6 +212,7 @@ dependencies = [ "cuda-core", "cuda-device", "cuda-host", + "device-ffi-collectives", ] [[package]] @@ -419,8 +429,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.toml index 28ace2a1d4..3c7fef7608 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.toml +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/Cargo.toml @@ -11,3 +11,4 @@ license = "Apache-2.0" cuda-device = { path = "../../../cuda-device" } cuda-host = { path = "../../../cuda-host" } cuda-core = { path = "../../../../../cuda-core" } +device-ffi-collectives = { path = "convergence-helper" } diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/README.md b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/README.md index d02e6056cd..b71a620120 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/README.md +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/README.md @@ -125,16 +125,17 @@ device_ffi_test/ ## How It Works -### 1. Rust Kernel Code (`src/main.rs`) +### 1. Rust Kernel Code (simplified) ```rust -use cuda_device::{device, kernel}; +use cuda_device::{convergent, device, kernel}; // Declare external device functions from CUDA C++ -// Note: No NVVM attributes needed - see "Why No NVVM Attributes?" below +// Mark collectives before the Rust device module is optimized. #[device] unsafe extern "C" { fn magnitude_squared(x: f32, y: f32) -> f32; + #[convergent] fn warp_reduce_sum(val: f32) -> f32; } @@ -205,46 +206,27 @@ callers that deliberately use this mapping may allow that lint on the extern. --- -## Why No NVVM Attributes on Extern Declarations? +## Convergence on Extern Declarations -When using LTOIR linking, **NVVM attributes (`#[convergent]`, `#[pure]`, `#[readonly]`) -are not needed on Rust extern function declarations**. Here's why: +Mark external warp and block collective declarations with `#[convergent]`. +cuda-oxide emits LLVM's `convergent` attribute on each marked declaration before +libNVVM optimizes the Rust device module. Attributes on external definitions +arrive later during LTO and cannot protect earlier optimization. -### The LTOIR Already Has Proper Attributes +The annotation forbids transformations that add control dependencies to the +call. It does not make threads reach the call or guarantee reconvergence; +callers must satisfy the collective's warp or block participation requirements. +Reachable declarations of the same symbol must agree on the annotation. Ordinary +scalar helpers and storage-size queries do not need this annotation. -External CUDA C++ compiled with `nvcc -dc -dlto` produces LTOIR with complete -attribute specifications on the function **definitions**: +The `convergence-helper` dependency declares `warp_reduce_sum` privately and +calls it through a public generic device helper. `verify-code-shape.sh` checks +that this declaration retains convergence in the consuming module, alongside +local collective declarations and unmarked scalar declarations. -```llvm -; From cccl_wrappers_text.ltoir -attributes #0 = { convergent inlinehint mustprogress willreturn } -attributes #7 = { convergent nounwind } -``` - -### nvJitLink Uses Definition Attributes - -During LTO linking: -1. cuda-oxide LTOIR has **declarations** (no function body) -2. External LTOIR has **definitions** with proper attributes -3. nvJitLink resolves symbols and uses the **definition's attributes** for optimization - -### Attributes on Declarations Are Redundant - -Since the linker uses the definition's attributes: -- Attributes on declarations don't affect the final code -- The external library authors already set correct attributes -- User-specified attributes could be incorrect or misleading - -### What About cuda-oxide Built-in Intrinsics? - -For cuda-oxide's own intrinsics (like `sync_threads()`, `shuffle()`, etc.), the -compiler handles convergent semantics internally. Users don't need to annotate these. - -### Historical Note - -Earlier versions of this example used `#[convergent]`, `#[pure]`, and `#[readonly]` -attributes. These have been removed as they provided no benefit with LTOIR linking -and could mislead users into thinking they were necessary. +Built-in intrinsics such as `sync_threads()` and warp shuffles already carry +convergence information. `#[pure]` and `#[readonly]` do not currently emit LLVM +memory-effect attributes. --- diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/convergence-helper/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/convergence-helper/Cargo.toml new file mode 100644 index 0000000000..a5a148e40d --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/convergence-helper/Cargo.toml @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "device-ffi-collectives" +version = "0.1.0" +edition = "2024" +license = "Apache-2.0" +publish = false + +[dependencies] +cuda-device = { path = "../../../../cuda-device" } diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/convergence-helper/src/lib.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/convergence-helper/src/lib.rs new file mode 100644 index 0000000000..52c17256c0 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/convergence-helper/src/lib.rs @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#[cuda_device::device] +unsafe extern "C" { + // Deliberately private: the downstream generic instantiation must recover + // convergence from dependency metadata without an exported declaration. + #[cuda_device::convergent] + fn warp_reduce_sum(value: f32) -> f32; +} + +/// Reduce a warp and scale its sum in a downstream device instantiation. +/// +/// # Safety +/// +/// All lanes in a full warp must participate in the reduction. +#[cuda_device::device] +pub unsafe fn scaled_warp_sum(value: f32) -> f32 { + unsafe { warp_reduce_sum(value) * SCALE as f32 } +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/src/main.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/src/main.rs index 0deb545121..02b51e9cdb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/src/main.rs +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/src/main.rs @@ -20,16 +20,15 @@ //! cargo run --release //! ``` -use cuda_device::{device, gpu_printf, kernel, shared::DynamicSharedArray}; +use cuda_device::{convergent, device, gpu_printf, kernel, shared::DynamicSharedArray}; use cuda_host::cuda_module; +use device_ffi_collectives::scaled_warp_sum; // ============================================================================= // External device functions from external_device_funcs.cu // -// NOTE: No NVVM attributes (#[convergent], #[pure], #[readonly]) are needed here. -// The external LTOIR already contains proper attributes on the function definitions. -// When nvJitLink performs LTO linking, it uses the definition's attributes. -// See README.md "Why No NVVM Attributes?" for details. +// Collective declarations carry convergence before libNVVM optimization. +// See README.md "Convergence on Extern Declarations" for details. // ============================================================================= #[device] @@ -37,7 +36,7 @@ unsafe extern "C" { fn magnitude_squared(x: f32, y: f32) -> f32; fn fast_rsqrt(x: f32) -> f32; fn dot_product(a: *const f32, b: *const f32, n: i32) -> f32; - fn warp_reduce_sum(val: f32) -> f32; + #[convergent] fn warp_ballot(predicate: i32) -> u32; fn simple_add(a: f32, b: f32) -> f32; // `char` is a plain 32-bit device-extern slot. Rust still warns because C @@ -56,13 +55,16 @@ unsafe extern "C" { // CCCL (CUB) wrapper functions from cccl_wrappers.cu // // These wrap CUB template functions as extern "C" for FFI. -// The CCCL LTOIR already has proper convergent/nounwind attributes. +// Mark collectives so their participation requirements survive prelink optimization. // ============================================================================= #[device] unsafe extern "C" { + #[convergent] fn cub_block_reduce_sum_f32_256(input: f32, temp: *mut u8) -> f32; + #[convergent] fn cub_block_reduce_max_f32_256(input: f32, temp: *mut u8) -> f32; + #[convergent] fn cub_warp_reduce_sum_f32(input: f32) -> f32; fn cub_get_block_reduce_temp_size_256() -> i32; } @@ -88,7 +90,7 @@ mod kernels { let added = unsafe { simple_add(mag, 1.0) }; // Test convergent function (all threads participate) - let sum = unsafe { warp_reduce_sum(added) }; + let sum = unsafe { scaled_warp_sum::<1>(added) }; // Lane 0 writes result if tid.is_multiple_of(32) { diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/verify-code-shape.sh b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/verify-code-shape.sh index 66bd4fcaf1..e61bf5750d 100755 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/verify-code-shape.sh +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_ffi_test/verify-code-shape.sh @@ -4,12 +4,14 @@ # A runtime q -> Q check cannot distinguish a plain i32 ABI from the plausible # but wrong `zeroext i32` mapping: both reach the same PTX and hardware result. -# Pin the declaration and calls in the emitted LLVM IR before LTO. +# Pin the declaration and calls in the emitted LLVM IR before LTO. Also check +# that a private extern reached through a dependency's generic helper retains +# convergence, while the ordinary char declarations remain unmarked. set -euo pipefail root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ll="${root}/device_ffi_test.ll" +ll="${1:-${root}/device_ffi_test.ll}" test -s "${ll}" @@ -46,4 +48,19 @@ if grep -Eq '\b(signext|zeroext)\b' <<<"${char_lines}"; then exit 1 fi -echo "device_ffi_test char ABI shape: PASS" +# Calls retain the existing conservative convergence group; only these ordinary +# declarations must be unmarked. The anchored declaration patterns above also +# reject an unexpected attribute trailer. +if grep -E '^declare .*@(char_to_upper|char_store)\(' "${ll}" | grep -qw convergent; then + echo "error: ordinary char declarations must not be convergent" >&2 + exit 1 +fi + +for symbol in warp_reduce_sum cub_warp_reduce_sum_f32; do + require_count "convergent ${symbol} declaration" 1 \ + "^declare float @${symbol}\(float\) convergent$" +done +require_count "convergent warp_ballot declaration" 1 \ + '^declare i32 @warp_ballot\(i32\) convergent$' + +echo "device_ffi_test char ABI and convergence shape: PASS (${ll})" diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_global/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_global/Cargo.lock index cb70f208f9..4a7e666ede 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_global/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_global/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_panic_trap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_panic_trap/Cargo.lock index 940b241f11..f50248d787 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/device_panic_trap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/device_panic_trap/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_from_raw_parts/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_from_raw_parts/Cargo.lock index 047a387564..8340bf2461 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_from_raw_parts/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_from_raw_parts/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_slice_len/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_slice_len/Cargo.lock index 6489cf91da..6cea94045c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_slice_len/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/disjoint_slice_len/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/dotprod/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/dotprod/Cargo.lock index 476fdafb8c..8e3110d87d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/dotprod/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/dotprod/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/dpx_minmax_chains/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/dpx_minmax_chains/Cargo.lock index a813d9446e..add2787035 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/dpx_minmax_chains/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/dpx_minmax_chains/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/drop_glue/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/drop_glue/Cargo.lock index f5e4bf7171..4bcbb56860 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/drop_glue/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/drop_glue/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/dst_metadata/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/dst_metadata/Cargo.lock index 818e5fb563..d3a4fb76da 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/dst_metadata/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/dst_metadata/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/dynamic_smem/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/dynamic_smem/Cargo.lock index d7a2d13df3..e0d8226027 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/dynamic_smem/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/dynamic_smem/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/elect_leader/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/elect_leader/Cargo.lock index af1b7f3494..b880a5af0a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/elect_leader/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/elect_leader/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_abi_multi_payload/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_abi_multi_payload/Cargo.lock index cf9ff9bcf6..05b09c89a4 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_abi_multi_payload/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_abi_multi_payload/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_array_match/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_array_match/Cargo.lock index bfd23bfe27..d03c010422 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_array_match/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_array_match/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_constant_provenance/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_constant_provenance/Cargo.lock index f504b4ccae..076c9aa099 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_constant_provenance/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_constant_provenance/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_payload_addr/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_payload_addr/Cargo.lock index df0cc37f42..2c811e274c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_payload_addr/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_payload_addr/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_state_transitions/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_state_transitions/Cargo.lock index f7235d4900..8cbdef629e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_state_transitions/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_state_transitions/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_table_lookup/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_table_lookup/Cargo.lock index a3895bfdff..0961cc5b95 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_table_lookup/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/enum_table_lookup/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error/Cargo.lock index d1c009dd04..7efbea2d92 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_bool_payload_addr/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_bool_payload_addr/Cargo.lock index 5621f9b7d5..f8e93156fb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_bool_payload_addr/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_bool_payload_addr/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_pointer_overlap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_pointer_overlap/Cargo.lock index b6a117690d..1a7be90510 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_pointer_overlap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_pointer_overlap/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_shared_pointer_layout/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_shared_pointer_layout/Cargo.lock index 78af316b92..919eac4a5d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_shared_pointer_layout/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_enum_shared_pointer_layout/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_abi/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_abi/Cargo.lock index cf79f57d10..9f53ae799d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_abi/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_abi/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -423,8 +425,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_callable/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_callable/Cargo.lock index f1e4b65bca..4b3088bc15 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_callable/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_callable/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -423,8 +425,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_fn_pointer/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_fn_pointer/Cargo.lock index 8f8b5bd07b..4595100adf 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_fn_pointer/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_fn_pointer/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -423,8 +425,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_unknown_id/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_unknown_id/Cargo.lock index 7c1967e280..8743f0cef1 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_unknown_id/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_generated_intrinsic_unknown_id/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -423,8 +425,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_heap_alloc/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_heap_alloc/Cargo.lock index 4b145cbb9b..3b8e718f17 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_heap_alloc/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_heap_alloc/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_arch_intrinsic/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_arch_intrinsic/Cargo.lock index f13ccddf3d..ac6aa4a39c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_arch_intrinsic/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_arch_intrinsic/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_target_feature/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_target_feature/Cargo.lock index 896397563a..917616d1a2 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_target_feature/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_host_target_feature/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_param/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_param/Cargo.lock index 288baa5927..88f0339df3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_param/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_param/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_ptr_param/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_ptr_param/Cargo.lock index e526285811..bbcf96364c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_ptr_param/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_kernel_shared_ptr_param/Cargo.lock @@ -188,6 +188,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -418,8 +420,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_missing_device_attr/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_missing_device_attr/Cargo.lock index 73495fc325..9a7c04854e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_missing_device_attr/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_missing_device_attr/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_set_discriminant_uninhabited/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_set_discriminant_uninhabited/Cargo.lock index 80b0290a9c..5c8d249189 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_set_discriminant_uninhabited/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_set_discriminant_uninhabited/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_addr/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_addr/Cargo.lock index b07deb9457..ec303531b0 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_addr/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_addr/Cargo.lock @@ -188,6 +188,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -418,8 +420,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_layout/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_layout/Cargo.lock index e6c274596d..a9ea669032 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_layout/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error_union_shared_pointer_layout/Cargo.lock @@ -188,6 +188,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -418,8 +420,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ex2_approx_f16/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ex2_approx_f16/Cargo.lock index a305299bef..4f21d05493 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ex2_approx_f16/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ex2_approx_f16/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/exact_div_chunks/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/exact_div_chunks/Cargo.lock index 7a093f77e0..8e95fc8c41 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/exact_div_chunks/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/exact_div_chunks/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/export_name_policy/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/export_name_policy/Cargo.lock index d19a8f5d96..0641a2487b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/export_name_policy/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/export_name_policy/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_crate_closure/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_crate_closure/Cargo.lock index f63c2d7694..e2cd44e9ae 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_crate_closure/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_crate_closure/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -424,8 +426,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_libdevice/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_libdevice/Cargo.lock index 3ccac81def..2d79555010 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_libdevice/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/extern_libdevice/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/Cargo.lock new file mode 100644 index 0000000000..8098cf08c5 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/Cargo.lock @@ -0,0 +1,754 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cuda-artifact-finalizer" +version = "0.2.1" +dependencies = [ + "libnvvm-sys", + "nvjitlink-sys", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "cuda-bindings" +version = "0.5.0" +dependencies = [ + "bindgen", + "libloading", + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cuda-core" +version = "0.5.0" +dependencies = [ + "anyhow", + "cuda-bindings", + "cuda-core-derive", + "half", + "oxide-artifacts", +] + +[[package]] +name = "cuda-core-derive" +version = "0.5.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cuda-device" +version = "0.2.1" +dependencies = [ + "cuda-macros", +] + +[[package]] +name = "cuda-host" +version = "0.2.1" +dependencies = [ + "cuda-artifact-finalizer", + "cuda-core", + "cuda-device", + "cuda-macros", + "half", + "libc", + "oxide-artifacts", + "ptx-parse", + "sha2", + "thiserror", +] + +[[package]] +name = "cuda-macros" +version = "0.2.1" +dependencies = [ + "oxide-tile-export", + "proc-macro2", + "quote", + "reserved-oxide-symbols", + "serde", + "serde_json", + "syn", +] + +[[package]] +name = "cuda-target-spec" +version = "0.1.0" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "external_ltoir" +version = "0.1.0" +dependencies = [ + "cuda-core", + "cuda-device", + "cuda-host", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libnvvm-sys" +version = "0.2.1" +dependencies = [ + "cuda-target-spec", + "libloading", + "thiserror", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nvjitlink-sys" +version = "0.2.1" +dependencies = [ + "libloading", + "thiserror", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "crc32fast", + "hashbrown 0.15.5", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "oxide-artifacts" +version = "0.2.1" +dependencies = [ + "object", +] + +[[package]] +name = "oxide-tile-export" +version = "0.2.1" +dependencies = [ + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptx-parse" +version = "0.1.0" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reserved-oxide-symbols" +version = "0.2.1" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/Cargo.toml new file mode 100644 index 0000000000..0daa15796f --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/Cargo.toml @@ -0,0 +1,15 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +[package] +name = "external_ltoir" +version = "0.1.0" +edition = "2024" +license = "Apache-2.0" +publish = false + +[workspace] + +[dependencies] +cuda-device = { path = "../../../cuda-device" } +cuda-host = { path = "../../../cuda-host" } +cuda-core = { path = "../../../../../cuda-core" } diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/README.md b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/README.md new file mode 100644 index 0000000000..a81f51b014 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/README.md @@ -0,0 +1,36 @@ +# External device LTO-IR + +This example calls a CUDA C++ device function from a Rust kernel. The C++ +function calls another function in a second LTO-IR file. `cargo oxide` links +both files into the embedded cubin during the build, and the program uses the +ordinary `kernels::load` API. It checks `output[i] = 2 * input[i] + 3` on the GPU. + +From `cuda-oxide/`, with the CUDA Toolkit and a matching GPU available: + +```bash +example=crates/rustc-codegen-cuda/examples/external_ltoir +mkdir -p build/device-libs +nvcc --ltoir -dlto -arch=sm_120 \ + "$example/scale.cu" -o build/device-libs/scale.ltoir +nvcc --ltoir -dlto -arch=sm_120 \ + "$example/add.cu" -o build/device-libs/add.ltoir +cargo oxide run external_ltoir --arch sm_120 --materialize-cubin \ + --link-ltoir build/device-libs/scale.ltoir \ + --link-ltoir build/device-libs/add.ltoir +``` + +Use the same architecture for both compilers. Each `--link-ltoir` adds one +file in argument order; paths are relative to the command's working directory. +The inputs must be raw LTO-IR, not object files or fatbins. `--ltoir -dlto` +writes the explicit output path, including with architecture names such as +`sm_90a`. All supplied files are linked into each materialized device artifact +in the Cargo invocation. The executable contains the finished cubin and needs no external `.ltoir` files +or runtime link step. + +`scripts/check-external-ltoir.sh sm_120` exercises run, build and test, repeated +build freshness, content changes at the same path, a missing transitive symbol, +execution with the link inputs removed, corrupt LTO-IR, and rejection of an +input/output collision without changing either file. It prints the +temporary directory containing its logs and generated inputs; it uses the +same nvcc commands with those temporary output paths. The check requires a GPU +matching the requested architecture. diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/add.cu b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/add.cu new file mode 100644 index 0000000000..d74d9bd981 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/add.cu @@ -0,0 +1,12 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef EXTERNAL_ADDEND +#define EXTERNAL_ADDEND 3 +#endif + +extern "C" __device__ int external_add(int value) { + return value + EXTERNAL_ADDEND; +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/scale.cu b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/scale.cu new file mode 100644 index 0000000000..ea5be973c4 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/scale.cu @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +extern "C" __device__ int external_add(int value); + +extern "C" __device__ int external_scale_add(int value) { + return external_add(value * 2); +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/src/main.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/src/main.rs new file mode 100644 index 0000000000..04efbfab78 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/external_ltoir/src/main.rs @@ -0,0 +1,73 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +//! Link two CUDA C++ device libraries during compilation and load the embedded cubin. + +use cuda_core::simt::LaunchConfig; +use cuda_core::{CudaContext, DeviceBuffer}; +use cuda_device::{DisjointSlice, device, kernel, thread}; +use cuda_host::cuda_module; + +#[device] +unsafe extern "C" { + fn external_scale_add(value: i32) -> i32; +} + +#[cuda_module] +mod kernels { + use super::*; + + #[kernel] + pub fn scale_add(input: &[i32], mut output: DisjointSlice) { + let index = thread::index_1d(); + let offset = index.get(); + if let Some(value) = output.get_mut(index) { + // SAFETY: the C++ definition takes and returns an int32 scalar; + // it accesses no pointers and has no participation requirement. + *value = unsafe { external_scale_add(input[offset]) }; + } + } +} + +fn verify(expected_addend: i32) -> Result<(), Box> { + let context = CudaContext::new(0)?; + let stream = context.default_stream(); + let input: Vec = (-128..129).collect(); + let device_input = DeviceBuffer::from_host(&stream, &input)?; + let mut device_output = DeviceBuffer::::zeroed(&stream, input.len())?; + let module = kernels::load(&context)?; + // SAFETY: the equal-length buffers cover every access, the bounds check + // handles the partial last block, and the kernel needs no shared memory. + unsafe { + module.scale_add( + &stream, + LaunchConfig::for_num_elems(input.len() as u32), + &device_input, + &mut device_output, + )?; + } + let actual = device_output.to_host_vec(&stream)?; + let expected: Vec = input + .iter() + .map(|value| value * 2 + expected_addend) + .collect(); + assert_eq!(actual, expected); + println!("PASS external LTO-IR: 257 values, addend={expected_addend}"); + Ok(()) +} + +fn main() -> Result<(), Box> { + let expected_addend = std::env::args() + .nth(1) + .map(|value| value.parse()) + .transpose()? + .unwrap_or(3); + verify(expected_addend) +} + +#[test] +fn linked_device_libraries_execute() { + verify(3).unwrap(); +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/f16_stress/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/f16_stress/Cargo.lock index 0ccebcd50f..52750f2137 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/f16_stress/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/f16_stress/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/f16x2_arith/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/f16x2_arith/Cargo.lock index 5a89dfb53e..9a211989d2 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/f16x2_arith/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/f16x2_arith/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/f32x2_arith/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/f32x2_arith/Cargo.lock index 1fef632193..316a55bb37 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/f32x2_arith/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/f32x2_arith/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/fcmp_ne_nan_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/fcmp_ne_nan_smoke/Cargo.lock index 5495cc6174..d3ab30b326 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/fcmp_ne_nan_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/fcmp_ne_nan_smoke/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/field_array_assign/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/field_array_assign/Cargo.lock index df607fcf01..e7fd2f8011 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/field_array_assign/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/field_array_assign/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/float_rounding/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/float_rounding/Cargo.lock index 0b6f57b623..fe69542aed 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/float_rounding/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/float_rounding/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/fmaxmin_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/fmaxmin_smoke/Cargo.lock index 4458b7ec54..c365d9ba1f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/fmaxmin_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/fmaxmin_smoke/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/fn_ptr_naming/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/fn_ptr_naming/Cargo.lock index 92d4321798..b582ea8179 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/fn_ptr_naming/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/fn_ptr_naming/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/fp_special_literal_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/fp_special_literal_smoke/Cargo.lock index 7507547040..43304c2bf6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/fp_special_literal_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/fp_special_literal_smoke/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/function_item_call/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/function_item_call/Cargo.lock index d21991bc5c..df36e9b073 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/function_item_call/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/function_item_call/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/future_apis/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/future_apis/Cargo.lock index 767da36ce7..a3d096539c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/future_apis/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/future_apis/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm/Cargo.lock index a16799a41f..9202cb8fa0 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol/Cargo.lock index e634080e85..6f1cd70de5 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol_final/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol_final/Cargo.lock index 5704e7e7e2..7b15463812 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol_final/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_sol_final/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -421,8 +423,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_views/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_views/Cargo.lock index d0a28e8c3a..827bd4141f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_views/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm_views/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -420,8 +422,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics/Cargo.lock index ab18e3fc3d..282ce54481 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -424,8 +426,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics_blackwell/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics_blackwell/Cargo.lock index adc7c6e4f4..edc7e4cfdb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics_blackwell/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_intrinsics_blackwell/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -424,8 +426,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_ldmatrix/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_ldmatrix/Cargo.lock index 2bd5d7e1ee..1cdc62eeb9 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_ldmatrix/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/generated_ldmatrix/Cargo.lock @@ -193,6 +193,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -424,8 +426,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/generic/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/generic/Cargo.lock index ec5339be09..18695069fd 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/generic/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/generic/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap/Cargo.lock index 751a0a2687..d96c56fa6b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v2/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v2/Cargo.lock index 2646cae85d..ebbe469e48 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v2/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v2/Cargo.lock @@ -220,6 +220,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -454,8 +456,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v3/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v3/Cargo.lock index b834c90e43..91e60e181a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v3/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap_v3/Cargo.lock @@ -220,6 +220,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -454,8 +456,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/hello_constant/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/hello_constant/Cargo.lock index 1f7d33ddd1..b1b1ac3e53 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/hello_constant/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/hello_constant/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/helper_fn/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/helper_fn/Cargo.lock index 9bd0891bc8..51f934948a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/helper_fn/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/helper_fn/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure/Cargo.lock index dc0217c032..5b880cebf5 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure/Cargo.lock @@ -211,6 +211,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -559,8 +561,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure_target_feature/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure_target_feature/Cargo.lock index cb58b6ab38..a38841fc30 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure_target_feature/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/host_closure_target_feature/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/iket_trace/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/iket_trace/Cargo.lock index 879811c20f..38ea4c1863 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/iket_trace/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/iket_trace/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/image_convolution/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/image_convolution/Cargo.lock index 00cd57c087..505715ae60 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/image_convolution/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/image_convolution/Cargo.lock @@ -201,6 +201,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -472,8 +474,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/index2d_const/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/index2d_const/Cargo.lock index 87f3c88f76..1ce9174b25 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/index2d_const/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/index2d_const/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/index_field_assign/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/index_field_assign/Cargo.lock index f6b0a95cd1..d88c1a3899 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/index_field_assign/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/index_field_assign/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_intent/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_intent/Cargo.lock index 5a05446079..903a76259a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_intent/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_intent/Cargo.lock @@ -188,6 +188,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -418,8 +420,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_ptx/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_ptx/Cargo.lock index 9800de80bd..5b307a85eb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_ptx/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/inline_ptx/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/integer_minmax/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/integer_minmax/Cargo.lock index 38a2e99ccf..d3ae3b4e48 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/integer_minmax/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/integer_minmax/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/interior_mutability/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/interior_mutability/Cargo.lock index 87d0c79a58..7bd9235a96 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/interior_mutability/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/interior_mutability/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/Cargo.lock index 61cff5801b..2d6cd89720 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/Cargo.lock @@ -346,8 +346,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/device/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/device/Cargo.lock index 0671dfd50c..b7b2fe63e1 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/device/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/interop_cubin_identity/device/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/kernel_reference_validity/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/kernel_reference_validity/Cargo.lock index 15c94ec2a7..0dd18c25e8 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/kernel_reference_validity/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/kernel_reference_validity/Cargo.lock @@ -211,6 +211,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -558,8 +560,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/lanemask_scan/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/lanemask_scan/Cargo.lock index 940f65d37c..f87706e7db 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/lanemask_scan/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/lanemask_scan/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_fadd/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_fadd/Cargo.lock index fd96ea2f4b..7d0be82721 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_fadd/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_fadd/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_rmw_cas/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_rmw_cas/Cargo.lock index 38e6fc926f..30e3bae681 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_rmw_cas/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_atomic_rmw_cas/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_nvvm_pointer_shapes/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_nvvm_pointer_shapes/Cargo.lock index 6a7f571741..1e13fc5c4e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_nvvm_pointer_shapes/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/legacy_nvvm_pointer_shapes/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/libdevice_math/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/libdevice_math/Cargo.lock index 4be2167e8e..89d99163ad 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/libdevice_math/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/libdevice_math/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/libm_math/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/libm_math/Cargo.lock index 7838394dfe..42a9ae0801 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/libm_math/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/libm_math/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -426,8 +428,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_generic/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_generic/Cargo.lock index 4e99d341bd..0edc6e587c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_generic/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_generic/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_libdevice/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_libdevice/Cargo.lock index 4a2c19c285..cf6b477d56 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_libdevice/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/manual_launch_libdevice/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/map_sum/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/map_sum/Cargo.lock index 236e1a127f..d3fbea2769 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/map_sum/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/map_sum/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_atan/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_atan/Cargo.lock index 2e0d065824..2ead75795b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_atan/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_atan/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_hyperbolic/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_hyperbolic/Cargo.lock index 51267d64d2..4c6d0d95be 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_hyperbolic/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_hyperbolic/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_no_mir_inline/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_no_mir_inline/Cargo.lock index 5c67e8bc57..8fdf93f4cf 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_no_mir_inline/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_no_mir_inline/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_tan/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_tan/Cargo.lock index c8bddba41d..3c355ac7ee 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_tan/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_tan/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/mathdx_ffi_test/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/mathdx_ffi_test/Cargo.lock index 3b045b0c04..87ff45758a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/mathdx_ffi_test/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/mathdx_ffi_test/Cargo.lock @@ -209,6 +209,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -456,8 +458,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/mcast_barrier_test/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/mcast_barrier_test/Cargo.lock index 1c558ad854..e42b67543b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/mcast_barrier_test/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/mcast_barrier_test/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/mem_swap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/mem_swap/Cargo.lock index a126752583..f18cbf447f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/mem_swap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/mem_swap/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/mir_projected_call_destination/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/mir_projected_call_destination/Cargo.lock index af4602c219..b66ae5731f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/mir_projected_call_destination/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/mir_projected_call_destination/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -426,8 +428,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/mma_mxf8f6f4/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/mma_mxf8f6f4/Cargo.lock index 0070effb36..62ccba04ed 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/mma_mxf8f6f4/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/mma_mxf8f6f4/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/Cargo.lock new file mode 100644 index 0000000000..ce2730ffc8 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/Cargo.lock @@ -0,0 +1,756 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "bindgen" +version = "0.69.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "itertools", + "lazy_static", + "lazycell", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn", + "which", +] + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cuda-artifact-finalizer" +version = "0.2.1" +dependencies = [ + "libnvvm-sys", + "nvjitlink-sys", + "serde", + "sha2", + "thiserror", +] + +[[package]] +name = "cuda-bindings" +version = "0.5.0" +dependencies = [ + "bindgen", + "libloading", + "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cuda-core" +version = "0.5.0" +dependencies = [ + "anyhow", + "cuda-bindings", + "cuda-core-derive", + "half", + "oxide-artifacts", +] + +[[package]] +name = "cuda-core-derive" +version = "0.5.0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cuda-device" +version = "0.2.1" +dependencies = [ + "cuda-macros", +] + +[[package]] +name = "cuda-host" +version = "0.2.1" +dependencies = [ + "cuda-artifact-finalizer", + "cuda-core", + "cuda-device", + "cuda-macros", + "half", + "libc", + "oxide-artifacts", + "ptx-parse", + "sha2", + "thiserror", +] + +[[package]] +name = "cuda-macros" +version = "0.2.1" +dependencies = [ + "oxide-tile-export", + "proc-macro2", + "quote", + "reserved-oxide-symbols", + "serde", + "serde_json", + "syn", +] + +[[package]] +name = "cuda-target-spec" +version = "0.1.0" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "libnvvm-sys" +version = "0.2.1" +dependencies = [ + "cuda-target-spec", + "libloading", + "thiserror", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "native_library" +version = "0.1.0" +dependencies = [ + "cuda-core", + "cuda-device", + "cuda-host", + "serde_json", + "sha2", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nvjitlink-sys" +version = "0.2.1" +dependencies = [ + "libloading", + "thiserror", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "crc32fast", + "hashbrown 0.15.5", + "indexmap", + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "oxide-artifacts" +version = "0.2.1" +dependencies = [ + "object", +] + +[[package]] +name = "oxide-tile-export" +version = "0.2.1" +dependencies = [ + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptx-parse" +version = "0.1.0" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reserved-oxide-symbols" +version = "0.2.1" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e9cc8b1b85264074fbcc02a88680c4096b1e47df8f739dceb03bf482f04bd6" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/Cargo.toml new file mode 100644 index 0000000000..0c085d9f98 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/Cargo.toml @@ -0,0 +1,20 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +[package] +name = "native_library" +version = "0.1.0" +edition = "2024" +license = "Apache-2.0" +publish = false + +[workspace] + +[dependencies] +cuda-device = { path = "../../../cuda-device" } +cuda-host = { path = "../../../cuda-host" } +cuda-core = { path = "../../../../../cuda-core" } + +[build-dependencies] +serde_json = "1" +sha2 = "0.10" diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/README.md b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/README.md new file mode 100644 index 0000000000..6dafcc085e --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/README.md @@ -0,0 +1,36 @@ +# Native library discovery + +This unsafe compiler fixture loads an i32 tile and adds seven through a native +CUDA implementation. Its generic dependency helper is instantiated with one +and four items per thread. The build script registers itself as the provider; +the compiler sends concrete requests and links the returned LTO-IR. No CUB +checkout, hand-written extern declaration or external artifact list is needed. + +From `cuda-oxide/`, with a CUDA toolkit and matching GPU: + +```sh +cargo oxide run native_library --arch sm_120 --materialize-cubin +cargo oxide test native_library --arch sm_120 --materialize-cubin +``` + +The provider invokes the selected toolkit's `nvcc`; `CUDAHOSTCXX` may select +its host compiler. Launch preparation uses inferred shared-memory facts and +rejects an equal-product wrong block shape. Both kernels run three blocks and +check every output. The raw helper requires full input/output tiles and exact +participation; this fixture does not claim a safe collective API. + +The smoke script supplies materialization and the target in each lane: + +```sh +scripts/smoketest.sh --only '^native_library$' +scripts/smoketest.sh --only '^native_library$' --compile-only +scripts/smoketest.sh --only '^native_library$' --full-debug +``` + +The artifact-only lanes run the fixture's `--check-artifact TARGET OUTPUT` +mode without creating a CUDA context. It verifies the embedded CUBIN and +both kernels' launch facts, then extracts the image to `OUTPUT`. Full debug +adds `--full-debug`, requires the recorded full-debug policy, and uses +`readelf` or `llvm-readelf` to check both kernels' DWARF. That lane uses the +modern libNVVM target (the host target on Blackwell or newer, otherwise +`sm_100`) and launches no kernels. diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/build.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/build.rs new file mode 100644 index 0000000000..2c5d5d075b --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/build.rs @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +use serde_json::{Value, json}; +use sha2::{Digest, Sha256}; +use std::io::{Read, Write}; + +fn serve() -> Result<(), Box> { + let mut input = String::new(); + std::io::stdin() + .take(1024 * 1024 + 1) + .read_to_string(&mut input)?; + assert!(input.len() <= 1024 * 1024); + let request: Value = serde_json::from_str(&input)?; + assert_eq!(request["version"], 1); + let target = request["target"].as_str().ok_or("missing target")?; + // nvcc emits PTX for -arch=compute_XX even with --ltoir. Select its + // matching real architecture to obtain raw LTO-IR for nvJitLink. + let nvcc_target = format!( + "sm_{}", + target.strip_prefix("compute_").ok_or("invalid target")? + ); + let cuda = request["cuda_root"].as_str().ok_or("missing toolkit")?; + let mut source = String::new(); + let mut entries = Vec::new(); + let scalar = json!({"kind":"signed", "bits":32}); + for (index, item) in request["requests"] + .as_array() + .ok_or("missing requests")? + .iter() + .enumerate() + { + assert_eq!(item["operation"], "load_add"); + assert_eq!(item["algorithm"], "direct"); + assert_eq!(item["dtype"], scalar); + let block = item["block"].as_array().ok_or("missing block")?; + assert_eq!(&block[1..], &[json!(1), json!(1)]); + let threads = block[0].as_u64().ok_or("invalid block")?; + let items = item["items_per_thread"].as_u64().ok_or("invalid extent")?; + assert!((1..=1024).contains(&threads) && (1..=16).contains(&items)); + let symbol = format!("fixture_load_b{threads}_i{items}"); + source.push_str(&format!( + "extern \"C\" __device__ void {symbol}(const int* memory, int* values, unsigned char*, int add) {{\n#pragma unroll\nfor (int i=0; i<{items}; ++i) values[i]=memory[threadIdx.x*{items}+i]+add;\n}}\n" + )); + entries.push(json!({ + "request_index": index, + "identity": Sha256::digest(symbol.as_bytes()).to_vec(), + "symbol": symbol, + "arguments": [ + {"kind":"const_pointer", "scalar":scalar}, + {"kind":"mut_pointer", "scalar":scalar}, + {"kind":"value", "scalar":scalar} + ], + "cub_layout": {"size":0,"alignment":1}, + "scratch": {"size":0,"alignment":1}, + "scratch_free": true, "mutates_payload": true + })); + } + // This fixture compiles a tiny native implementation without a CUB dependency. + // Each invocation owns its temporary files, including simultaneous consumers. + let directory = + std::env::temp_dir().join(format!("oxide-library-fixture-{}", std::process::id())); + std::fs::create_dir(&directory)?; + let result = (|| -> Result, Box> { + let cpp = directory.join("provider.cu"); + let lto = directory.join("provider.ltoir"); + std::fs::write(&cpp, source)?; + let mut command = std::process::Command::new(std::path::Path::new(cuda).join("bin/nvcc")); + command.args(["--ltoir", "-dlto", "-arch", &nvcc_target]); + if let Some(host) = std::env::var_os("CUDAHOSTCXX") { + command.arg("-ccbin").arg(host); + } + let status = command.arg(&cpp).arg("-o").arg(<o).status()?; + if !status.success() { + return Err("fixture native compilation failed".into()); + } + Ok(std::fs::read(lto)?) + })(); + std::fs::remove_dir_all(&directory)?; + let lto = result?; + let header = serde_json::to_vec(&json!({ + "version":1, "batch_identity":Sha256::digest(<o).to_vec(), + "specializations":entries + }))?; + let mut output = std::io::stdout().lock(); + output.write_all(b"OXDLIB01")?; + output.write_all(&(header.len() as u64).to_le_bytes())?; + output.write_all(&(lto.len() as u64).to_le_bytes())?; + output.write_all(&header)?; + output.write_all(<o)?; + Ok(()) +} + +fn serve_inputs() -> Result<(), Box> { + let mut bytes = Vec::new(); + std::io::stdin() + .take(1024 * 1024 + 1) + .read_to_end(&mut bytes)?; + assert!(bytes.len() <= 1024 * 1024); + let request: Value = serde_json::from_slice(&bytes)?; + assert_eq!(request["version"], 1); + let cuda = std::path::Path::new(request["cuda_root"].as_str().ok_or("missing toolkit")?); + let host = std::env::var_os("CUDAHOSTCXX").unwrap_or_else(|| "g++".into()); + let host = std::path::PathBuf::from(host); + let host = if host.is_absolute() { + host + } else { + std::env::split_paths(&std::env::var_os("PATH").unwrap_or_default()) + .map(|directory| directory.join(&host)) + .find(|path| path.is_file()) + .ok_or("cannot locate native host compiler")? + }; + // The example tracks CUDA tools/headers and the host compiler driver. + // The host compiler's installed system headers/libraries are assumed stable. + serde_json::to_writer( + std::io::stdout().lock(), + &json!({ + "version":1, + "paths":[cuda.join("bin"), cuda.join("nvvm"), cuda.join("include"), host], + "environment":["CUDAHOSTCXX", "PATH", "NVCC_PREPEND_FLAGS", "NVCC_APPEND_FLAGS", + "CPATH", "CPLUS_INCLUDE_PATH", "GCC_EXEC_PREFIX", "COMPILER_PATH"] + }), + )?; + Ok(()) +} + +fn main() -> Result<(), Box> { + match std::env::args().nth(1).as_deref() { + Some("--oxide-library-request-v1") => return serve(), + Some("--oxide-library-inputs-v1") => return serve_inputs(), + _ => {} + } + println!("cargo::rerun-if-changed=build.rs"); + let registration = json!({ + "version":1, "provider":"native_library_fixture", + "executable":std::env::current_exe()?, + "operation":"load_add", "algorithm":"direct" + }); + println!("cargo::rustc-env=FIXTURE_REGISTRATION={registration}"); + Ok(()) +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/src/lib.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/src/lib.rs new file mode 100644 index 0000000000..781dc7fa65 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/src/lib.rs @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +#![no_std] + +trait Recipe { + const REGISTRATION: &'static str; +} + +struct LoadAddRecipe; + +impl Recipe for LoadAddRecipe { + const REGISTRATION: &'static str = cuda_device::library::registration!("FIXTURE_REGISTRATION"); +} + +fn registration, const ITEMS: usize>() -> &'static str { + R::REGISTRATION +} + +/// Load a complete block tile through a native provider in a dependency crate. +/// +/// # Safety +/// +/// Launch 128-thread one-dimensional blocks. Input/output must cover every +/// block's complete tile; input stays immutable and output tiles are disjoint. +#[inline(never)] +pub unsafe fn load_add(input: *const i32, output: *mut i32) { + let lane = cuda_device::thread::threadIdx_x() as usize; + let origin = cuda_device::thread::blockIdx_x() as usize * 128 * ITEMS; + let mut values = [0_i32; ITEMS]; + // SAFETY: each thread owns its initialized local array, and the caller + // supplies the full input tile and required geometry. This recipe uses no scratch. + unsafe { + cuda_device::library::call_v1::( + registration::, + (input.add(origin), values.as_mut_ptr(), 7_i32), + ); + for (item, value) in values.iter().enumerate() { + output.add(origin + lane * ITEMS + item).write(*value); + } + } +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/src/main.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/src/main.rs new file mode 100644 index 0000000000..c7302dba27 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/native_library/src/main.rs @@ -0,0 +1,134 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +use cuda_core::embedded::{ + ArtifactDebugPolicy, ArtifactPayloadKind, artifact_bundles_from_current_exe, +}; +use cuda_core::{CudaContext, DeviceBuffer, LaunchConfig3D}; +use cuda_device::{kernel, launch_bounds, launch_contract}; +use cuda_host::cuda_module; + +#[cuda_module] +mod kernels { + use super::*; + + #[kernel] + #[launch_bounds(256)] + #[launch_contract(domain = 3, dynamic_shared = inferred)] + pub unsafe fn one(input: *const i32, output: *mut i32) { + unsafe { + native_library::load_add::<1>(input, output); + } + } + + #[kernel] + #[launch_bounds(256)] + #[launch_contract(domain = 3, dynamic_shared = inferred)] + pub unsafe fn four(input: *const i32, output: *mut i32) { + unsafe { + native_library::load_add::<4>(input, output); + } + } +} + +fn verify() -> Result<(), Box> { + let context = CudaContext::new(0)?; + let stream = context.default_stream(); + // SAFETY: the embedded image was produced from this module's declarations. + let module = unsafe { kernels::load(&context)? }; + for items in [1, 4] { + let input: Vec = (0..3 * 128 * items).map(|i| i * 3 - 11).collect(); + let device_input = DeviceBuffer::from_host(&stream, &input)?; + let device_output = DeviceBuffer::::zeroed(&stream, input.len())?; + let config = LaunchConfig3D::auto_shared((3, 1, 1), (128, 1, 1)); + macro_rules! launch { + ($prepare:ident, $kernel:ident) => {{ + let prepared = module.$prepare(config)?; + let facts = prepared.function().launch_facts().unwrap(); + assert_eq!(facts.exact_block, Some((128, 1, 1))); + assert_eq!(facts.dynamic_shared_bytes, 0); + assert!( + module + .$prepare(LaunchConfig3D::auto_shared((3, 1, 1), (64, 2, 1))) + .is_err() + ); + // SAFETY: complete, immutable input and disjoint output tiles + // outlive execution. Preparation enforces exact geometry. + unsafe { + module.$kernel( + &stream, + &prepared, + device_input.cu_deviceptr() as *const i32, + device_output.cu_deviceptr() as *mut i32, + )?; + } + }}; + } + if items == 1 { + launch!(prepare_one, one); + } else { + launch!(prepare_four, four); + } + assert_eq!( + device_output.to_host_vec(&stream)?, + input.iter().map(|value| value + 7).collect::>() + ); + println!("PASS native library: items={items}, {} values", input.len()); + } + Ok(()) +} + +// Artifact-only smoke lanes call this before creating any CUDA context. Read +// the executable's actual bundle, including its launch facts and debug policy. +fn check_artifact( + target: &str, + output: &std::path::Path, + full_debug: bool, +) -> Result<(), Box> { + let bundles = artifact_bundles_from_current_exe()?; + let [bundle] = bundles.as_slice() else { + return Err("expected exactly one embedded device bundle".into()); + }; + assert_eq!(bundle.target, target); + for symbol in ["one", "four"] { + let facts = bundle.entry(symbol).unwrap().launch_facts.unwrap(); + assert_eq!(facts.exact_block, Some((128, 1, 1))); + assert_eq!(facts.dynamic_shared_bytes, 0); + } + if full_debug { + assert_eq!( + bundle.compile_options.debug_policy(), + ArtifactDebugPolicy::Full + ); + } + let cubin = bundle + .payload(ArtifactPayloadKind::Cubin) + .ok_or("missing embedded CUBIN")?; + assert!(cubin.starts_with(b"\x7fELF")); + std::fs::write(output, cubin)?; + println!("PASS embedded CUBIN: target={target}, kernels=one,four"); + Ok(()) +} + +fn main() -> Result<(), Box> { + let args: Vec<_> = std::env::args_os().skip(1).collect(); + if args.first().is_some_and(|arg| arg == "--check-artifact") { + if !(args.len() == 3 || (args.len() == 4 && args[3] == "--full-debug")) { + return Err("expected --check-artifact TARGET OUTPUT [--full-debug]".into()); + } + return check_artifact( + args[1].to_str().ok_or("invalid target")?, + std::path::Path::new(&args[2]), + args.len() == 4, + ); + } + if !args.is_empty() { + return Err("unexpected fixture argument".into()); + } + verify() +} + +#[test] +fn native_provider_executes() { + verify().unwrap(); +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ne_bytes_transmute/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ne_bytes_transmute/Cargo.lock index 8d1dc68f4f..b59a96ef27 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ne_bytes_transmute/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ne_bytes_transmute/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/nested_index_assignment/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/nested_index_assignment/Cargo.lock index d82c25246e..0232109d4d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/nested_index_assignment/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/nested_index_assignment/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/numeric_stress/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/numeric_stress/Cargo.lock index 68d17a62ae..9df4737241 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/numeric_stress/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/numeric_stress/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/nvls_all_reduce/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/nvls_all_reduce/Cargo.lock index 58ef040c46..4bb000aca7 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/nvls_all_reduce/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/nvls_all_reduce/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_transmute/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_transmute/Cargo.lock index d6ccc1e244..6300b46811 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_transmute/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_transmute/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ dependencies = [ [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_unwrap_or/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_unwrap_or/Cargo.lock index 91de9b410d..8aba53327c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_unwrap_or/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/option_ref_unwrap_or/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ dependencies = [ [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/option_unwrap_trap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/option_unwrap_trap/Cargo.lock index d164620488..a145596b88 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/option_unwrap_trap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/option_unwrap_trap/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ dependencies = [ [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ord_cmp/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ord_cmp/Cargo.lock index 44d05c995d..4dbe7e5b9a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ord_cmp/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ord_cmp/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -419,8 +421,6 @@ dependencies = [ [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_aggregate_abi/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_aggregate_abi/Cargo.lock index 972c6cd402..5ed992549c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_aggregate_abi/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_aggregate_abi/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_atomic_add/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_atomic_add/Cargo.lock index af832aba00..5e09d86471 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_atomic_add/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/packed_atomic_add/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/padded_constants/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/padded_constants/Cargo.lock index 41a23e648d..1544f3a081 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/padded_constants/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/padded_constants/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/partial_warp_reduce/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/partial_warp_reduce/Cargo.lock index 7e0a385ee1..a5b5c6744e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/partial_warp_reduce/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/partial_warp_reduce/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/pinned_overlap/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/pinned_overlap/Cargo.lock index 41c7b64525..bf0f428e20 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/pinned_overlap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/pinned_overlap/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/place_read_fallbacks/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/place_read_fallbacks/Cargo.lock index fdd244e8ef..f0dcce1daa 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/place_read_fallbacks/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/place_read_fallbacks/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/policy_config/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/policy_config/Cargo.lock index 9cf6c64802..f3dde14485 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/policy_config/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/policy_config/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/primitive_stress/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/primitive_stress/Cargo.lock index 84929b541d..704e6e48c6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/primitive_stress/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/primitive_stress/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/printf/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/printf/Cargo.lock index 9db04a93c7..f2892e1d78 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/printf/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/printf/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/projected_place_read/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/projected_place_read/Cargo.lock index 17642ea7b6..185d143ee6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/projected_place_read/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/projected_place_read/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/proof_carrying_views/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/proof_carrying_views/Cargo.lock index 46bf7cfb6b..ef215039ff 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/proof_carrying_views/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/proof_carrying_views/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_copy/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_copy/Cargo.lock index 5b05e017c5..61edbb886d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_copy/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_copy/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_offset_from/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_offset_from/Cargo.lock index 3fa6d7132f..67d53497ee 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_offset_from/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_offset_from/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_without_provenance/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_without_provenance/Cargo.lock index 04e6a57cd5..0711022587 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_without_provenance/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ptr_without_provenance/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/reborrow/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/reborrow/Cargo.lock index 73188db112..e961c3139f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/reborrow/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/reborrow/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_f32/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_f32/Cargo.lock index d7a8c23a4e..80b585365d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_f32/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_f32/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_minmax/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_minmax/Cargo.lock index 7b05be8590..d9422958e3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_minmax/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_minmax/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_sum/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_sum/Cargo.lock index 3cc9bb1335..10ce5670dc 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_sum/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/redux_sum/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_index_projections/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_index_projections/Cargo.lock index 51d1860828..25a8ebc750 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_index_projections/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_index_projections/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_operand_mul/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_operand_mul/Cargo.lock index c4a0a8bf84..ef404cdb50 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_operand_mul/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/ref_operand_mul/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_align_block_args/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_align_block_args/Cargo.lock index ad83d723f6..c9d929e986 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_align_block_args/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_align_block_args/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_transparent_abi/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_transparent_abi/Cargo.lock index 07ce1da2d0..cf1e50bad1 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_transparent_abi/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_transparent_abi/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_u32_enum_stride/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_u32_enum_stride/Cargo.lock index 79224818e2..09fe88dad6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_u32_enum_stride/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/repr_u32_enum_stride/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/row_width_slice/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/row_width_slice/Cargo.lock index 1ed21433b6..68fc88597f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/row_width_slice/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/row_width_slice/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/rustlantis-smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/rustlantis-smoke/Cargo.lock index 322099605b..8c4e70dfe3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/rustlantis-smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/rustlantis-smoke/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -414,8 +416,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/scoped_atomic_load_store/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/scoped_atomic_load_store/Cargo.lock index 683cadeb40..289425b07c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/scoped_atomic_load_store/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/scoped_atomic_load_store/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/select_unpredictable/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/select_unpredictable/Cargo.lock index 87763b5b63..09d09926ae 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/select_unpredictable/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/select_unpredictable/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant/Cargo.lock index 72726e3e91..25ac8303dc 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant_niche/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant_niche/Cargo.lock index 5fbc5179e4..2b797afd8b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant_niche/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/set_discriminant_niche/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_debug/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_debug/Cargo.lock index c1225ffb45..907dde20ae 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_debug/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_debug/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_memory_helper/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_memory_helper/Cargo.lock index 989f46f684..8af4a40440 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_memory_helper/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_memory_helper/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_api/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_api/Cargo.lock index 35539d8e2b..5a54d8be1d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_api/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_api/Cargo.lock @@ -188,6 +188,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -409,8 +411,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_transmute/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_transmute/Cargo.lock index 098e6fa943..00e90aee48 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_transmute/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_ptr_transmute/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_slice_unsize/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_slice_unsize/Cargo.lock index fd1d381de4..2daacc2c46 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_slice_unsize/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_slice_unsize/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_stage_select/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_stage_select/Cargo.lock index 5ac0486dc4..3fffbaaa53 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_stage_select/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shared_stage_select/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/sharedmem/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/sharedmem/Cargo.lock index 2bee1e9097..013dd15032 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/sharedmem/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/sharedmem/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/shuffle_64/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/shuffle_64/Cargo.lock index 9c58993282..5d79c66b44 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/shuffle_64/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/shuffle_64/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_from_raw_parts_cast/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_from_raw_parts_cast/Cargo.lock index dcfee5f6a1..885a44d6b1 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_from_raw_parts_cast/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_from_raw_parts_cast/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_get_mut/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_get_mut/Cargo.lock index c94c1a3938..e7ca05fc38 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_get_mut/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_get_mut/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_index_bounds_check/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_index_bounds_check/Cargo.lock index a4045435e3..eb465ca60c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_index_bounds_check/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_index_bounds_check/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_iterators/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_iterators/Cargo.lock index 6483648ff7..c92e737f43 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_iterators/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_iterators/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_reslice/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_reslice/Cargo.lock index 44e93548de..829fd73c5f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_reslice/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/slice_reslice/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/small_type_ffi_test/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/small_type_ffi_test/Cargo.lock index 20196ba508..b3eb37a0cb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/small_type_ffi_test/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/small_type_ffi_test/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_fp8/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_fp8/Cargo.lock index 8b7f279ddd..c5e7a160d3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_fp8/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_fp8/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_ordered_float/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_ordered_float/Cargo.lock index 218f65f807..4e4ec9634c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_ordered_float/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/sparse_mma_ordered_float/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/split_at_mut/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/split_at_mut/Cargo.lock index 4fa006d2b4..ce440f9c15 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/split_at_mut/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/split_at_mut/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/standalone_device_fn/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/standalone_device_fn/Cargo.lock index 4870b6e0d2..c3f5164164 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/standalone_device_fn/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/standalone_device_fn/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_addend/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_addend/Cargo.lock index 260515c3a0..e95f858218 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_addend/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_addend/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_unsize/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_unsize/Cargo.lock index d24fdb64fe..9c097cf19a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_unsize/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/static_slice_unsize/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/step_by/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/step_by/Cargo.lock index 1b1df6b95f..05a567fbc9 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/step_by/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/step_by/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_constant_provenance/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_constant_provenance/Cargo.lock index 481d2d5496..cc2442a84a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_constant_provenance/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_constant_provenance/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_field_layout/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_field_layout/Cargo.lock index 6e0c3e8691..8f0b4d2e3b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_field_layout/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/struct_field_layout/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/subslice_projection/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/subslice_projection/Cargo.lock index e32ae7b8bf..e8feb9de44 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/subslice_projection/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/subslice_projection/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/switchint_128bit/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/switchint_128bit/Cargo.lock index 1702573ea1..9a2370e300 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/switchint_128bit/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/switchint_128bit/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/swizzle_smem/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/swizzle_smem/Cargo.lock index 95370fb238..e9f58ecd23 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/swizzle_smem/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/swizzle_smem/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05/Cargo.lock index 83d5191784..539b769f66 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05_matmul/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05_matmul/Cargo.lock index b25fb143ad..a99548a870 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05_matmul/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05_matmul/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/thread_runs/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/thread_runs/Cargo.lock index 608a68f483..3938401f83 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/thread_runs/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/thread_runs/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tiled_gemm/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tiled_gemm/Cargo.lock index 1686557131..86f799e7ff 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tiled_gemm/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tiled_gemm/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tilelib_relu/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tilelib_relu/Cargo.lock index 7696b70a7f..120b22c268 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tilelib_relu/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tilelib_relu/Cargo.lock @@ -173,6 +173,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -394,8 +396,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_copy/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_copy/Cargo.lock index 0162d17bb3..c60e5878f6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_copy/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_copy/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_multicast/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_multicast/Cargo.lock index 41c5da3d69..0fc9b3c124 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_multicast/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tma_multicast/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/toolchain_pairing_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/toolchain_pairing_smoke/Cargo.lock index fa8576a5c6..a884c86124 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/toolchain_pairing_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/toolchain_pairing_smoke/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/transmute_scalar_struct/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/transmute_scalar_struct/Cargo.lock index b153af1014..a6f4838ad0 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/transmute_scalar_struct/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/transmute_scalar_struct/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_array_provenance/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_array_provenance/Cargo.lock index ad1c253f8c..3c3b725a9f 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_array_provenance/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_array_provenance/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_constant_provenance/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_constant_provenance/Cargo.lock index 161953c941..2cb93a51c8 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_constant_provenance/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_constant_provenance/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_field_lookup/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_field_lookup/Cargo.lock index 7bd6be0875..065332ffb6 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_field_lookup/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_field_lookup/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_return/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_return/Cargo.lock index fa83d0f633..f8d987e5d3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_return/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tuple_return/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/unaligned_memory/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/unaligned_memory/Cargo.lock index 1ffae9df91..1a8cd3a9f0 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/unaligned_memory/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/unaligned_memory/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/unchecked_indexing/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/unchecked_indexing/Cargo.lock index e7e441bcc4..91f1cd812c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/unchecked_indexing/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/unchecked_indexing/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/uninit_const/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/uninit_const/Cargo.lock index be29bf5921..94ad1a674e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/uninit_const/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/uninit_const/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/union_aggregate/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/union_aggregate/Cargo.lock index 12fc11b53d..86b4e8f8b9 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/union_aggregate/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/union_aggregate/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_bounds_check/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_bounds_check/Cargo.lock index 9583827edc..e25d3c8100 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_bounds_check/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_bounds_check/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_smoke/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_smoke/Cargo.lock index a234aff07b..f57b9af485 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_smoke/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/unroll_smoke/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/vecadd/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/vecadd/Cargo.lock index 2e6d5cb154..c5bbde3ed3 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/vecadd/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/vecadd/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/vectorization/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/vectorization/Cargo.lock index ecc9160ea6..ca881cf6cd 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/vectorization/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/vectorization/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/volatile_memory/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/volatile_memory/Cargo.lock index 8d9e203b9d..cf7d0bf28a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/volatile_memory/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/volatile_memory/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce/Cargo.lock index 2dc4af0e91..740456d5dd 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_sums/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_sums/Cargo.lock index 45f571902d..22bcd8eadb 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_sums/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_sums/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma/Cargo.lock index f0236ae67e..c3d17fd85e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma_mma_bf16/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma_mma_bf16/Cargo.lock index e54e6354c7..4e4d008677 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma_mma_bf16/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma_mma_bf16/Cargo.lock @@ -189,6 +189,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -410,8 +412,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/src/collector.rs b/cuda-oxide/crates/rustc-codegen-cuda/src/collector.rs index 078099ebaf..14d92cf012 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/src/collector.rs +++ b/cuda-oxide/crates/rustc-codegen-cuda/src/collector.rs @@ -493,27 +493,20 @@ pub struct DeviceExternDecl { /// NVVM attributes for device extern declarations. /// -/// NOTE: These attributes are currently **not emitted** to the LLVM IR output. -/// When linking LTOIR via nvJitLink, the external library's LTOIR already contains -/// proper attributes (convergent, nounwind, memory, etc.) on the function DEFINITIONS. -/// nvJitLink uses the definition's attributes during LTO, making attributes on our -/// declarations redundant. -/// -/// The `#[convergent]`, `#[pure]`, and `#[readonly]` Rust attributes are still parsed -/// but their values are not used in code generation. This struct is retained for -/// potential future use or debugging. +/// Convergence is emitted on the declaration before libNVVM optimization. +/// Memory-effect annotations remain inactive; they are not inferred from external +/// definitions that become available only during LTO. #[derive(Debug, Clone, Default)] pub struct DeviceExternAttrs { - /// Function is convergent (all threads must execute together). - /// NOTE: Not currently emitted - external LTOIR has proper convergent attrs. + /// Function has convergence requirements for its participating threads. pub is_convergent: bool, /// Function is pure (no side effects, result depends only on inputs). - /// NOTE: Not currently emitted - external LTOIR has proper memory attrs. + /// Inactive for Rust source annotations. pub is_pure: bool, /// Function is read-only (only reads memory, doesn't write). - /// NOTE: Not currently emitted - external LTOIR has proper memory attrs. + /// Inactive for Rust source annotations. pub is_readonly: bool, } @@ -523,6 +516,10 @@ pub struct DeviceExternAttrs { /// declarations (for FFI with external LTOIR). #[derive(Debug)] pub struct CollectionResult<'tcx> { + /// Calls to the exact compiler library marker, before body deduplication. + pub library_calls: Vec>, + /// Every resolved edge, retaining all kernel contexts of shared helpers. + pub call_edges: Vec<(Instance<'tcx>, Instance<'tcx>)>, /// Functions to compile (kernels and device helpers with MIR bodies). pub functions: Vec>, @@ -954,7 +951,10 @@ fn rust_alloc_shim_name(fn_path: &str) -> Option<&str> { /// fat-pointer string constants are inspected; everything else returns /// `None`. Evaluation failures (e.g. a constant in still-generic MIR) /// also return `None`, which simply means "no message found". -fn const_str_text<'tcx>(tcx: TyCtxt<'tcx>, constant: &ConstOperand<'tcx>) -> Option { +pub(crate) fn const_str_text<'tcx>( + tcx: TyCtxt<'tcx>, + constant: &ConstOperand<'tcx>, +) -> Option { let ty = constant.const_.ty(); let TyKind::Ref(_, pointee, _) = ty.kind() else { return None; @@ -1420,6 +1420,9 @@ struct DeviceCollector<'tcx> { /// once per program — the message is procedural advice about the /// kernel-launch contract, not anything per-call. warned_dynamic_shared_array: bool, + library_defs: HashSet, + library_calls: Vec>, + call_edges: Vec<(Instance<'tcx>, Instance<'tcx>)>, /// Print progress to stderr. verbose: bool, } @@ -1436,6 +1439,9 @@ impl<'tcx> DeviceCollector<'tcx> { device_externs: Vec::new(), seen_device_externs: HashSet::new(), warned_dynamic_shared_array: false, + library_defs: crate::library::marker_definitions(tcx), + library_calls: Vec::new(), + call_edges: Vec::new(), verbose, } } @@ -1598,6 +1604,8 @@ impl<'tcx> DeviceCollector<'tcx> { } CollectionResult { + library_calls: self.library_calls, + call_edges: self.call_edges, functions: self.result, device_externs: self.device_externs, requires_ptx_bundle_merge: false, @@ -1648,7 +1656,12 @@ impl<'tcx> DeviceCollector<'tcx> { .next() .is_some() }; - attrs.is_convergent = check("convergent"); + attrs.is_convergent = rustc_attr_ir::find_attr!( + self.tcx, def_id, Doc(doc) + if doc.aliases.contains_key(&Symbol::intern( + reserved_oxide_symbols::DEVICE_EXTERN_CONVERGENT_MARKER + )) + ); attrs.is_pure = check("pure"); attrs.is_readonly = check("readonly"); @@ -1733,6 +1746,7 @@ impl<'tcx> DeviceCollector<'tcx> { return; } + self.call_edges.push((caller.instance, drop_instance)); let mangled = self.tcx.symbol_name(drop_instance).name.to_string(); if self.seen.contains(&mangled) { return; @@ -2029,6 +2043,17 @@ impl<'tcx> DeviceCollector<'tcx> { return; }; + // Preserve edges before deduplicating bodies: the same helper can be + // reached from several kernels with distinct resource requirements. + self.call_edges.push((caller.instance, resolved)); + if self.library_defs.contains(&resolved.def_id()) { + self.library_calls.push(crate::library::LibraryCall { + instance: resolved, + span: call_span, + }); + return; + } + // Skip already-seen monomorphizations (use mangled name as unique key) let mangled = self.tcx.symbol_name(resolved).name.to_string(); if self.seen.contains(&mangled) { @@ -2267,6 +2292,13 @@ impl<'tcx> DeviceCollector<'tcx> { _ => return, }; + if self.library_defs.contains(&instance.def_id()) { + self.tcx.dcx().span_fatal( + call_span, + "the native library marker requires a direct call; pass a wrapper helper instead", + ); + } + self.call_edges.push((caller.instance, instance)); let target = self.tcx.def_path_str(instance.def_id()); let crate_name = self.tcx.crate_name(instance.def_id().krate); if self.is_generated_intrinsic_placeholder_or_report_mismatch( diff --git a/cuda-oxide/crates/rustc-codegen-cuda/src/device_codegen.rs b/cuda-oxide/crates/rustc-codegen-cuda/src/device_codegen.rs index f22d0937d9..c58c8b8acd 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/src/device_codegen.rs +++ b/cuda-oxide/crates/rustc-codegen-cuda/src/device_codegen.rs @@ -325,6 +325,8 @@ pub struct DeviceCodegenResult { pub debug_kind: llvm_export::export::DebugKind, /// Source launch bounds for kernel entries, keyed by exported kernel name. pub kernel_launch_bounds: BTreeMap, + /// Finalized resource requirements for each concrete kernel export. + pub kernel_launch_facts: BTreeMap, } #[derive(Clone, Copy, Debug, PartialEq, Eq)] @@ -919,6 +921,7 @@ pub fn generate_device_code<'tcx>( tcx: TyCtxt<'tcx>, functions: &[CollectedFunction<'tcx>], device_externs: &[DeviceExternDecl], + libraries: &crate::library::FinalizedLibraries<'tcx>, config: &DeviceCodegenConfig, ) -> Result { use rustc_public::rustc_internal; @@ -964,7 +967,7 @@ pub fn generate_device_code<'tcx>( // Convert device externs to mir-importer format // We extract signature info from rustc here since we have access to TyCtxt - let stable_device_externs: Vec = device_externs + let mut stable_device_externs: Vec = device_externs .iter() .map(|decl| { // Get function signature from rustc @@ -1024,6 +1027,8 @@ pub fn generate_device_code<'tcx>( }) .collect::>()?; + stable_device_externs.extend(libraries.declarations.clone()); + let output_dir = config.output_dir.clone(); let output_name = config.output_name.clone(); let mlir_output = config.mlir_output.clone(); @@ -1285,11 +1290,21 @@ pub fn generate_device_code<'tcx>( // Run the cuda-oxide pipeline! // Rust MIR → `dialect-mir` → mem2reg → unroll → LLVM dialect → LLVM IR → PTX. // Device externs are emitted as `declare` statements in LLVM IR - mir_importer::run_pipeline( + let library_calls = libraries + .calls + .iter() + .map(|(instance, plan)| { + let instance: rustc_public::mir::mono::Instance = rustc_internal::stable(*instance); + (instance.mangled_name().to_string(), plan.clone()) + }) + .collect(); + mir_importer::run_pipeline_with_libraries( &stable_functions, &stable_device_externs, &pipeline_config, known_defs, + library_calls, + &libraries.roots, ) }); @@ -1334,6 +1349,7 @@ pub fn generate_device_code<'tcx>( allow_fma_contraction: compilation_result.allow_fma_contraction, debug_kind, kernel_launch_bounds: compilation_result.kernel_launch_bounds, + kernel_launch_facts: compilation_result.kernel_launch_facts, }) } Err(pipeline_err) => Err(DeviceCodegenError::PtxGeneration(format!( @@ -1477,6 +1493,7 @@ mod tests { target: "sm_90".to_string(), allow_fma_contraction: false, kernel_launch_bounds: BTreeMap::new(), + kernel_launch_facts: BTreeMap::new(), }; let artifact = read_compilation_artifact(&result).unwrap().unwrap(); @@ -1504,6 +1521,7 @@ mod tests { target: "sm_90".to_string(), allow_fma_contraction: true, kernel_launch_bounds: BTreeMap::new(), + kernel_launch_facts: BTreeMap::new(), }; let artifact = read_compilation_artifact(&result).unwrap().unwrap(); diff --git a/cuda-oxide/crates/rustc-codegen-cuda/src/lib.rs b/cuda-oxide/crates/rustc-codegen-cuda/src/lib.rs index 8564f84dbe..aca70a413d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/src/lib.rs +++ b/cuda-oxide/crates/rustc-codegen-cuda/src/lib.rs @@ -332,6 +332,7 @@ extern crate rustc_codegen_llvm; mod collector; mod device_codegen; mod generated_intrinsics; +mod library; mod materialize; use rustc_codegen_ssa::traits::CodegenBackend; @@ -715,7 +716,7 @@ impl CodegenBackend for CudaCodegenBackend { // Step 2: If device code exists, compile via cuda-oxide let _device_result = if has_device_code { - let materialization_request = + let mut materialization_request = materialize::request_from_env().unwrap_or_else(|error| { tcx.dcx().fatal(format!( "[rustc_codegen_cuda] Invalid cubin materialization request: {error}" @@ -740,8 +741,35 @@ impl CodegenBackend for CudaCodegenBackend { self.config.verbose, ); + if !collection_result.library_calls.is_empty() && materialization_request.is_none() + { + tcx.dcx().fatal( + "native library calls require `cargo oxide build --materialize-cubin`", + ); + } + let mut libraries = + library::finalize(tcx, &collection_result).unwrap_or_else(|error| { + tcx.dcx().fatal(format!("native device library: {error}")) + }); + if self.config.verbose { + for (kernel, plan) in &libraries.roots { + eprintln!( + "[library] {kernel}: exact block {:?}, scratch {} bytes aligned {}", + plan.exact_block, + plan.dynamic_shared_bytes, + plan.dynamic_shared_alignment + ); + } + } + // The provider returns owned bytes. No consumer-created artifact + // list or path is needed, and output-path checks still apply to + // the file inputs received from cargo-oxide. + if let Some(request) = &mut materialization_request { + request.add_library_inputs(std::mem::take(&mut libraries.inputs)); + } + materialize::validate_collection( - materialization_request, + materialization_request.as_ref(), !collection_result.device_externs.is_empty(), collection_result.requires_ptx_bundle_merge, ) @@ -779,6 +807,16 @@ impl CodegenBackend for CudaCodegenBackend { dump_mir_dialect: self.config.dump_mir_dialect, dump_llvm_dialect: self.config.dump_llvm_dialect, }; + materialize::validate_output_paths( + materialization_request.as_ref(), + &device_config.output_dir, + &device_config.output_name, + ) + .unwrap_or_else(|error| { + tcx.dcx().fatal(format!( + "[rustc_codegen_cuda] Cannot write device artifacts: {error}" + )) + }); // Run the cuda-oxide pipeline, catching backend panics and // re-emitting them as a cuda-oxide diagnostic. A panic @@ -815,6 +853,7 @@ impl CodegenBackend for CudaCodegenBackend { tcx, device_functions, &collection_result.device_externs, + &libraries, &device_config, ) })); @@ -1069,10 +1108,11 @@ fn write_device_artifact_object( } else { oxide_artifacts::ArtifactEntryKind::DeviceFunction }; - spec = spec.with_entry(oxide_artifacts::ArtifactEntrySpec::new( - &function.export_name, - kind, - )); + let mut entry = oxide_artifacts::ArtifactEntrySpec::new(&function.export_name, kind); + if let Some(facts) = result.kernel_launch_facts.get(&function.export_name) { + entry = entry.with_launch_facts(*facts); + } + spec = spec.with_entry(entry); } let blob = oxide_artifacts::build_artifact_blob(&spec)?; diff --git a/cuda-oxide/crates/rustc-codegen-cuda/src/library.rs b/cuda-oxide/crates/rustc-codegen-cuda/src/library.rs new file mode 100644 index 0000000000..57e476aef6 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/src/library.rs @@ -0,0 +1,697 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +//! Resolve typed library markers and finalize one batch per native provider. + +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::io::{Read, Write}; +use std::path::PathBuf; +use std::process::{Command, Stdio}; + +use oxide_artifacts::KernelLaunchFacts; +use rustc_hir::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc_middle::mir::{Operand, RETURN_PLACE, Rvalue, StatementKind, TerminatorKind}; +use rustc_middle::ty::{Instance, Ty, TyCtxt, TyKind, TypingEnv}; +use rustc_span::Span; +use serde::{Deserialize, Serialize}; + +use crate::collector::CollectionResult; + +const MAX_HEADER: usize = 1024 * 1024; +const MAX_LTO: usize = 256 * 1024 * 1024; + +#[derive(Debug)] +pub(crate) struct LibraryCall<'tcx> { + pub instance: Instance<'tcx>, + pub span: Span, +} + +/// Resolve definitions through the actual dependency module, then compare DefIds +/// at call sites. A user function with the same spelling is an ordinary function. +pub(crate) fn marker_definitions(tcx: TyCtxt<'_>) -> HashSet { + let mut definitions = HashSet::new(); + for &krate in tcx.crates(()) { + if tcx.crate_name(krate).as_str() != "cuda_device" { + continue; + } + let root = DefId { + krate, + index: CRATE_DEF_INDEX, + }; + for module in tcx.module_children(root) { + if module.ident.name.as_str() != "library" { + continue; + } + let Some(module) = module.res.opt_def_id() else { + continue; + }; + for item in tcx.module_children(module) { + if item.ident.name.as_str() == reserved_oxide_symbols::LIBRARY_CALL_V1 + && let Some(def) = item.res.opt_def_id() + { + definitions.insert(def); + } + } + } + } + definitions +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +struct Registration { + version: u32, + provider: String, + executable: PathBuf, + operation: String, + algorithm: String, +} + +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)] +#[serde( + tag = "kind", + content = "bits", + rename_all = "snake_case", + deny_unknown_fields +)] +enum Scalar { + Signed(u16), + Unsigned(u16), + Float(u16), +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq)] +#[serde( + tag = "kind", + content = "scalar", + rename_all = "snake_case", + deny_unknown_fields +)] +enum Argument { + ConstPointer(Scalar), + MutPointer(Scalar), + Value(Scalar), +} + +#[derive(Debug, Serialize)] +struct BatchRequest<'a> { + version: u32, + target: &'a str, + cuda_root: PathBuf, + requests: &'a [Request], +} + +#[derive(Clone, Debug, Serialize, PartialEq, Eq, Hash)] +struct Request { + operation: String, + algorithm: String, + dtype: Scalar, + block: [u32; 3], + items_per_thread: u32, +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +struct Layout { + size: u64, + alignment: u64, +} + +impl Layout { + fn checked(&self) -> Result<(u32, u32), String> { + let size = u32::try_from(self.size).map_err(|_| "library layout exceeds u32")?; + let align = u32::try_from(self.alignment).map_err(|_| "library alignment exceeds u32")?; + if !align.is_power_of_two() { + return Err("library alignment must be a nonzero power of two".into()); + } + Ok((size, align)) + } +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +struct Specialization { + request_index: u32, + identity: [u8; 32], + symbol: String, + arguments: Vec, + cub_layout: Layout, + scratch: Layout, + scratch_free: bool, + mutates_payload: bool, +} + +#[derive(Debug, Deserialize)] +#[serde(deny_unknown_fields)] +struct BatchResponse { + version: u32, + batch_identity: [u8; 32], + specializations: Vec, +} + +#[derive(Default)] +pub(crate) struct FinalizedLibraries<'tcx> { + pub calls: Vec<(Instance<'tcx>, mir_importer::LibraryCallPlan)>, + pub declarations: Vec, + pub inputs: Vec<(String, Vec)>, + pub roots: BTreeMap, +} + +fn scalar(ty: Ty<'_>) -> Result { + use rustc_middle::ty::{FloatTy, IntTy, UintTy}; + match ty.kind() { + TyKind::Int(kind) => match kind { + IntTy::I8 => Ok(Scalar::Signed(8)), + IntTy::I16 => Ok(Scalar::Signed(16)), + IntTy::I32 => Ok(Scalar::Signed(32)), + IntTy::I64 => Ok(Scalar::Signed(64)), + _ => Err(format!("unsupported library scalar `{ty}`")), + }, + TyKind::Uint(kind) => match kind { + UintTy::U8 => Ok(Scalar::Unsigned(8)), + UintTy::U16 => Ok(Scalar::Unsigned(16)), + UintTy::U32 => Ok(Scalar::Unsigned(32)), + UintTy::U64 => Ok(Scalar::Unsigned(64)), + _ => Err(format!("unsupported library scalar `{ty}`")), + }, + TyKind::Float(FloatTy::F16) => Ok(Scalar::Float(16)), + TyKind::Float(FloatTy::F32) => Ok(Scalar::Float(32)), + TyKind::Float(FloatTy::F64) => Ok(Scalar::Float(64)), + _ => Err(format!( + "unsupported library scalar `{ty}`; use a fixed-width numeric scalar" + )), + } +} + +fn argument(ty: Ty<'_>) -> Result { + match ty.kind() { + TyKind::RawPtr(pointee, mutability) => Ok(if mutability.is_mut() { + Argument::MutPointer(scalar(*pointee)?) + } else { + Argument::ConstPointer(scalar(*pointee)?) + }), + _ => Ok(Argument::Value(scalar(ty)?)), + } +} + +fn read_registration<'tcx>(tcx: TyCtxt<'tcx>, witness: Ty<'tcx>) -> Result { + let TyKind::FnDef(def, args) = witness.kind() else { + return Err( + "library registration must be a function item, not a closure or function pointer" + .into(), + ); + }; + let args = args + .no_bound_vars() + .ok_or("registration has unresolved bound arguments")?; + let instance = Instance::try_resolve(tcx, TypingEnv::fully_monomorphized(), *def, args) + .map_err(|_| "cannot resolve library registration")? + .ok_or("cannot resolve library registration")?; + let body = tcx.instance_mir(instance.def); + // Deliberately accept only the constant getter contract. Do not evaluate + // arbitrary target code or search a more complicated body for a JSON string. + if body.basic_blocks.len() != 1 { + return Err("registration getter must return one constant string".into()); + } + if !matches!( + body.basic_blocks.iter().next().unwrap().terminator().kind, + TerminatorKind::Return + ) { + return Err("registration getter must return one constant string".into()); + } + let mut text = None; + for statement in &body.basic_blocks.iter().next().unwrap().statements { + if let StatementKind::Assign(assign) = &statement.kind { + let (place, value) = &**assign; + if place.as_local() != Some(RETURN_PLACE) { + return Err("registration getter must return one constant string".into()); + } + let Rvalue::Use(Operand::Constant(constant), _) = value else { + return Err("registration getter must return one constant string".into()); + }; + if text.is_some() { + return Err("registration getter writes its result more than once".into()); + } + // The getter body still contains its generic parameters. Resolve + // associated constants using this concrete function-item instance. + let constant = rustc_middle::mir::ConstOperand { + const_: instance.instantiate_mir_and_normalize_erasing_regions( + tcx, + TypingEnv::fully_monomorphized(), + rustc_middle::ty::EarlyBinder::bind(tcx, constant.const_), + ), + ..**constant + }; + text = crate::collector::const_str_text(tcx, &constant); + } + } + let text = text.ok_or("registration getter must return one constant UTF-8 string")?; + let registration: Registration = + serde_json::from_str(&text).map_err(|e| format!("invalid library registration: {e}"))?; + if registration.version != 1 + || registration.provider.is_empty() + || !registration.executable.is_absolute() + { + return Err("library registration requires version 1, a provider name, and an absolute executable path".into()); + } + Ok(registration) +} + +fn decode_response( + bytes: &[u8], + expected_count: usize, +) -> Result<(BatchResponse, Vec), String> { + if bytes.len() < 24 || &bytes[..8] != b"OXDLIB01" { + return Err("invalid or truncated library response frame".into()); + } + let header_len = u64::from_le_bytes(bytes[8..16].try_into().unwrap()); + let lto_len = u64::from_le_bytes(bytes[16..24].try_into().unwrap()); + if header_len > MAX_HEADER as u64 || lto_len == 0 || lto_len > MAX_LTO as u64 { + return Err("library response length is out of bounds".into()); + } + let header_end = 24 + header_len as usize; + if bytes.len() != header_end + lto_len as usize { + return Err("library response is truncated or has trailing bytes".into()); + } + let response: BatchResponse = serde_json::from_slice(&bytes[24..header_end]) + .map_err(|e| format!("invalid library response JSON: {e}"))?; + if response.version != 1 || response.specializations.len() != expected_count { + return Err( + "library response version or specialization count does not match request".into(), + ); + } + let mut symbols = HashSet::new(); + let mut identities = HashSet::new(); + for (index, spec) in response.specializations.iter().enumerate() { + if usize::try_from(spec.request_index).ok() != Some(index) + || !symbols.insert(&spec.symbol) + || !identities.insert(spec.identity) + || spec.symbol.is_empty() + || !spec + .symbol + .bytes() + .enumerate() + .all(|(i, b)| b == b'_' || b.is_ascii_alphabetic() || (i > 0 && b.is_ascii_digit())) + { + return Err( + "library response has an invalid index, symbol, or duplicate identity".into(), + ); + } + spec.cub_layout.checked()?; + let (size, _) = spec.scratch.checked()?; + if spec.scratch_free != (size == 0) { + return Err("library scratch-free flag disagrees with its layout".into()); + } + if !matches!( + spec.arguments.first(), + Some(Argument::ConstPointer(_) | Argument::MutPointer(_)) + ) || !matches!(spec.arguments.get(1), Some(Argument::MutPointer(_))) + { + return Err( + "library ABI requires memory and mutable payload pointers before scratch slot 2" + .into(), + ); + } + for argument in &spec.arguments { + let (Argument::ConstPointer(scalar) + | Argument::MutPointer(scalar) + | Argument::Value(scalar)) = argument; + if !matches!( + scalar, + Scalar::Signed(8 | 16 | 32 | 64) + | Scalar::Unsigned(8 | 16 | 32 | 64) + | Scalar::Float(16 | 32 | 64) + ) { + return Err("library response contains an unsupported scalar width".into()); + } + } + } + Ok((response, bytes[header_end..].to_vec())) +} + +fn invoke( + executable: &PathBuf, + request: &BatchRequest<'_>, +) -> Result<(BatchResponse, Vec), String> { + let json = serde_json::to_vec(request).map_err(|e| e.to_string())?; + if json.len() > MAX_HEADER { + return Err("library request exceeds 1 MiB".into()); + } + let mut child = Command::new(executable) + .arg("--oxide-library-request-v1") + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .spawn() + .map_err(|e| { + format!( + "cannot execute native library provider {}: {e}", + executable.display() + ) + })?; + child + .stdin + .take() + .unwrap() + .write_all(&json) + .map_err(|e| format!("cannot send library request: {e}"))?; + let mut bytes = Vec::new(); + child + .stdout + .take() + .unwrap() + .take((24 + MAX_HEADER + MAX_LTO + 1) as u64) + .read_to_end(&mut bytes) + .map_err(|e| format!("cannot read library response: {e}"))?; + if bytes.len() > 24 + MAX_HEADER + MAX_LTO { + let _ = child.kill(); + } + let status = child + .wait() + .map_err(|e| format!("cannot wait for library provider: {e}"))?; + if !status.success() { + return Err(format!( + "native library provider failed with {status}; see its stderr diagnostics" + )); + } + decode_response(&bytes, request.requests.len()) +} + +fn extern_scalar(scalar: &Scalar) -> mir_importer::DeviceExternType { + use mir_importer::DeviceExternType as E; + match *scalar { + Scalar::Signed(bits) | Scalar::Unsigned(bits) => E::Integer(u32::from(bits)), + Scalar::Float(16) => E::Float16, + Scalar::Float(32) => E::Float32, + Scalar::Float(64) => E::Float64, + _ => unreachable!("validated scalar type"), + } +} + +fn extern_argument(argument: &Argument) -> mir_importer::DeviceExternType { + use mir_importer::DeviceExternType as E; + match argument { + Argument::Value(Scalar::Signed(bits)) if *bits < 32 => E::SignExtInteger(u32::from(*bits)), + Argument::Value(Scalar::Unsigned(bits)) if *bits < 32 => { + E::ZeroExtInteger(u32::from(*bits)) + } + Argument::Value(s) => extern_scalar(s), + Argument::ConstPointer(s) | Argument::MutPointer(s) => E::pointer_to(extern_scalar(s), 0), + } +} + +/// Finalize all call identities once, while retaining every root's reachability. +pub(crate) fn finalize<'tcx>( + tcx: TyCtxt<'tcx>, + collection: &CollectionResult<'tcx>, +) -> Result, String> { + let mut result = FinalizedLibraries::default(); + if collection.library_calls.is_empty() { + return Ok(result); + } + let target = std::env::var("CUDA_OXIDE_TARGET") + .map_err(|_| "library calls require an explicit CUDA target")?; + let target = target + .strip_prefix("sm_") + .map(|v| format!("compute_{v}")) + .unwrap_or(target); + let cuda_root = std::env::var_os("CUDA_HOME") + .or_else(|| std::env::var_os("CUDA_PATH")) + .map(PathBuf::from) + .ok_or("library calls require CUDA_HOME or CUDA_PATH")?; + // BTreeMap gives deterministic invocation order. Request order is first + // encounter order, and the response explicitly carries each request index. + type ProviderBatch<'a, 'tcx> = Vec<(Request, Vec<&'a LibraryCall<'tcx>>)>; + let mut batches: BTreeMap<(String, PathBuf), ProviderBatch<'_, 'tcx>> = BTreeMap::new(); + for call in &collection.library_calls { + let args = call.instance.args; + let report = |error: String| -> ! { + tcx.dcx() + .span_fatal(call.span, format!("native device library: {error}")) + }; + let registration = + read_registration(tcx, args.type_at(1)).unwrap_or_else(|error| report(error)); + let positive = |index| { + let value = args + .const_at(index) + .try_to_target_usize(tcx) + .ok_or("library extent is not a concrete usize")?; + u32::try_from(value) + .ok() + .filter(|v| *v != 0) + .ok_or("library extent must fit nonzero u32") + }; + let request = Request { + operation: registration.operation, + algorithm: registration.algorithm, + dtype: scalar(args.type_at(0)).unwrap_or_else(|error| report(error)), + block: [ + positive(3) + .map_err(str::to_owned) + .unwrap_or_else(|error| report(error)), + 1, + 1, + ], + items_per_thread: positive(4) + .map_err(str::to_owned) + .unwrap_or_else(|error| report(error)), + }; + let batch = batches + .entry((registration.provider, registration.executable)) + .or_default(); + if let Some((_, calls)) = batch.iter_mut().find(|(existing, _)| *existing == request) { + calls.push(call); + } else { + batch.push((request, vec![call])); + } + } + let mut finalized = HashMap::new(); + let mut all_symbols = HashSet::new(); + for ((provider, executable), batch) in batches { + let requests: Vec<_> = batch.iter().map(|(request, _)| request.clone()).collect(); + let batch_span = batch[0].1[0].span; + let (response, lto) = invoke( + &executable, + &BatchRequest { + version: 1, + target: &target, + cuda_root: cuda_root.clone(), + requests: &requests, + }, + ) + .unwrap_or_else(|error| { + tcx.dcx() + .span_fatal(batch_span, format!("native device library: {error}")) + }); + let identity: String = response + .batch_identity + .iter() + .map(|b| format!("{b:02x}")) + .collect(); + result + .inputs + .push((format!("library-{provider}-{identity}.ltoir"), lto)); + for ((request, calls), spec) in batch.into_iter().zip(response.specializations) { + if !all_symbols.insert(spec.symbol.clone()) { + return Err(format!( + "different provider batches returned the same symbol {}", + spec.symbol + )); + } + let (scratch_bytes, scratch_alignment) = spec.scratch.checked()?; + let mut params: Vec<_> = spec.arguments.iter().map(extern_argument).collect(); + params.insert( + 2, + mir_importer::DeviceExternType::pointer_to( + mir_importer::DeviceExternType::Integer(8), + 0, + ), + ); + result.declarations.push(mir_importer::DeviceExternDecl { + export_name: spec.symbol.clone(), + param_types: params, + return_type: mir_importer::DeviceExternType::Void, + attrs: mir_importer::DeviceExternAttrs { + is_convergent: true, + is_pure: false, + is_readonly: false, + }, + }); + for call in calls { + let TyKind::Tuple(fields) = call.instance.args.type_at(2).kind() else { + tcx.dcx().span_fatal( + call.span, + "library Args must be a tuple of scalars and raw pointers", + ); + }; + let actual = fields + .iter() + .map(argument) + .collect::, _>>() + .unwrap_or_else(|error| tcx.dcx().span_fatal(call.span, error)); + if actual != spec.arguments { + tcx.dcx().span_fatal(call.span, format!( + "library runtime tuple for {} disagrees with provider ABI: actual {actual:?}, expected {:?}", + spec.symbol, spec.arguments + )); + } + let _ = spec.mutates_payload; // Metadata, not permission to read payload. + let plan = mir_importer::LibraryCallPlan { + symbol: spec.symbol.clone(), + scratch_bytes, + scratch_alignment, + }; + if finalized + .insert( + call.instance, + KernelLaunchFacts { + exact_block: Some(( + request.block[0], + request.block[1], + request.block[2], + )), + dynamic_shared_bytes: scratch_bytes, + dynamic_shared_alignment: scratch_alignment, + }, + ) + .is_none() + { + result.calls.push((call.instance, plan)); + } + } + } + } + for root in collection.functions.iter().filter(|f| f.is_kernel) { + let mut visited = HashSet::new(); + let mut pending = vec![root.instance]; + let mut root_plan: Option = None; + while let Some(instance) = pending.pop() { + if !visited.insert(instance) { + continue; + } + if let Some(plan) = finalized.get(&instance) { + if let Some(current) = &mut root_plan { + if current.exact_block != plan.exact_block { + tcx.dcx().span_fatal( + tcx.def_span(root.instance.def_id()), + format!( + "kernel {} has conflicting exact library block shapes", + root.export_name + ), + ); + } + current.dynamic_shared_bytes = + current.dynamic_shared_bytes.max(plan.dynamic_shared_bytes); + current.dynamic_shared_alignment = current + .dynamic_shared_alignment + .max(plan.dynamic_shared_alignment); + } else { + root_plan = Some(*plan); + } + } + pending.extend( + collection + .call_edges + .iter() + .filter(|(caller, _)| *caller == instance) + .map(|(_, callee)| *callee), + ); + } + if let Some(plan) = root_plan { + for instance in visited { + let path = tcx.def_path_str(instance.def_id()); + if tcx.crate_name(instance.def_id().krate).as_str() == "cuda_device" + && path.contains("DynamicSharedArray") + { + return Err(format!( + "kernel {} mixes library scratch with a native dynamic shared view", + root.export_name + )); + } + } + result.roots.insert(root.export_name.clone(), plan); + } + } + Ok(result) +} + +#[cfg(test)] +mod tests { + use super::*; + + fn response() -> serde_json::Value { + let scalar = serde_json::json!({"kind": "signed", "bits": 32}); + serde_json::json!({ + "version": 1, "batch_identity": vec![0; 32], + "specializations": [{ + "request_index": 0, "identity": vec![1; 32], "symbol": "library_i32", + "arguments": [ + {"kind": "const_pointer", "scalar": scalar}, + {"kind": "mut_pointer", "scalar": scalar} + ], + "cub_layout": {"size": 1, "alignment": 1}, + "scratch": {"size": 0, "alignment": 1}, + "scratch_free": true, "mutates_payload": true + }] + }) + } + + fn frame(response: &serde_json::Value) -> Vec { + let json = serde_json::to_vec(response).unwrap(); + let mut bytes = b"OXDLIB01".to_vec(); + bytes.extend((json.len() as u64).to_le_bytes()); + bytes.extend(3_u64.to_le_bytes()); + bytes.extend(json); + bytes.extend([1, 2, 3]); + bytes + } + + #[test] + fn response_frame_retains_bytes_and_rejects_truncation_or_trailing_data() { + let bytes = frame(&response()); + assert_eq!(decode_response(&bytes, 1).unwrap().1, [1, 2, 3]); + for end in [0, 8, 16, 23, bytes.len() - 1] { + assert!(decode_response(&bytes[..end], 1).is_err()); + } + let mut trailing = bytes.clone(); + trailing.push(0); + assert!(decode_response(&trailing, 1).is_err()); + let mut empty_lto = bytes; + empty_lto[16..24].copy_from_slice(&0_u64.to_le_bytes()); + assert!(decode_response(&empty_lto, 1).is_err()); + } + + #[test] + fn response_rejects_inconsistent_identity_layout_and_abi() { + for (field, value) in [ + ("request_index", serde_json::json!(1)), + ("symbol", serde_json::json!("not a symbol")), + ("scratch_free", serde_json::json!(false)), + ("scratch", serde_json::json!({"size": 0, "alignment": 3})), + ( + "cub_layout", + serde_json::json!({"size": 4294967296_u64, "alignment": 1}), + ), + ("arguments", serde_json::json!([])), + ] { + let mut value_response = response(); + value_response["specializations"][0][field] = value; + assert!( + decode_response(&frame(&value_response), 1).is_err(), + "{field}" + ); + } + let mut duplicate = response(); + let mut second = duplicate["specializations"][0].clone(); + second["request_index"] = 1.into(); + duplicate["specializations"] + .as_array_mut() + .unwrap() + .push(second); + assert!(decode_response(&frame(&duplicate), 2).is_err()); + assert!(decode_response(&frame(&response()), 2).is_err()); + let mut version = response(); + version["version"] = 2.into(); + assert!(decode_response(&frame(&version), 1).is_err()); + } +} diff --git a/cuda-oxide/crates/rustc-codegen-cuda/src/materialize.rs b/cuda-oxide/crates/rustc-codegen-cuda/src/materialize.rs index 387c4ce4f6..a661bf5a4c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/src/materialize.rs +++ b/cuda-oxide/crates/rustc-codegen-cuda/src/materialize.rs @@ -27,10 +27,18 @@ pub(crate) const MATERIALIZER_HANDSHAKE_ENV: &str = reserved_oxide_symbols::MATERIALIZER_HANDSHAKE_ENV; pub(crate) const CODEGEN_FINGERPRINT_ENV: &str = reserved_oxide_symbols::CODEGEN_FINGERPRINT_ENV; -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Debug)] pub(crate) struct MaterializationRequest { expected_provenance: [u8; 32], tool_identity_handshake: cuda_artifact_finalizer::MaterializerHandshakeV1, + external_inputs: Vec<(String, Vec)>, + library_inputs: Vec<(String, Vec)>, +} + +impl MaterializationRequest { + pub(crate) fn add_library_inputs(&mut self, inputs: Vec<(String, Vec)>) { + self.library_inputs.extend(inputs); + } } /// Cubin bytes plus ptxas resource diagnostics from the final link. @@ -97,10 +105,13 @@ pub(crate) enum MaterializeError { RequiresPtxBundleMerge, #[error( - "build-time cubin materialization does not yet support #[device] extern declarations because their ordered external link inputs are not available to the backend" + "build-time cubin materialization of #[device] extern declarations requires their definitions; supply ordered --link-ltoir inputs" )] HasDeviceExterns, + #[error("invalid cargo-oxide external LTO-IR input list: {reason}")] + InvalidExternalInputs { reason: String }, + #[error( "build-time cubin materialization requires an NVVM IR or LTOIR artifact, but codegen produced PTX; use cargo-oxide so materialization can force NVVM IR emission" )] @@ -147,12 +158,38 @@ pub(crate) fn request_from_env() -> Result, Mater })?; validate_tool_identity_handshake(expected_provenance, &handshake)?; validate_codegen_fingerprint()?; + let external_inputs = external_inputs_from_env()?; Ok(Some(MaterializationRequest { expected_provenance, tool_identity_handshake: handshake, + external_inputs, + library_inputs: Vec::new(), })) } +fn external_inputs_from_env() -> Result)>, MaterializeError> { + let value = match std::env::var(reserved_oxide_symbols::EXTERNAL_LTOIR_ENV) { + Ok(value) => value, + Err(std::env::VarError::NotPresent) => return Ok(Vec::new()), + Err(error) => { + return Err(MaterializeError::InvalidExternalInputs { + reason: error.to_string(), + }); + } + }; + let files: Vec = + serde_json::from_str(&value).map_err(|error| MaterializeError::InvalidExternalInputs { + reason: error.to_string(), + })?; + files + .into_iter() + .map(|file| { + let bytes = file.read_verified()?; + Ok((file.name()?.to_owned(), bytes)) + }) + .collect() +} + fn validate_tool_identity_handshake( expected_provenance: [u8; 32], handshake: &cuda_artifact_finalizer::MaterializerHandshakeV1, @@ -174,22 +211,47 @@ fn validate_tool_identity_handshake( /// Reject artifact-loading models the finalizer cannot reproduce, before any /// CUDA compiler library is discovered or loaded. pub(crate) fn validate_collection( - request: Option, + request: Option<&MaterializationRequest>, has_device_externs: bool, requires_ptx_bundle_merge: bool, ) -> Result<(), MaterializeError> { - if request.is_none() { + let Some(request) = request else { return Ok(()); - } + }; if requires_ptx_bundle_merge { return Err(MaterializeError::RequiresPtxBundleMerge); } - if has_device_externs { + if has_device_externs && request.external_inputs.is_empty() && request.library_inputs.is_empty() + { return Err(MaterializeError::HasDeviceExterns); } Ok(()) } +/// Use the actual rustc crate name and configured output directory, including +/// for Cargo passthrough builds whose working directory differs from the CLI's. +pub(crate) fn validate_output_paths( + request: Option<&MaterializationRequest>, + output_dir: &std::path::Path, + output_name: &str, +) -> Result<(), MaterializeError> { + let Some(request) = request else { + return Ok(()); + }; + let mut outputs = + mir_importer::pipeline::stale_compilation_artifact_paths(output_dir, output_name); + outputs.push(output_dir.join(format!( + "{output_name}.{}", + oxide_tile_export::DESCRIPTIONS_SUFFIX + ))); + for (input, _) in &request.external_inputs { + for output in &outputs { + cuda_artifact_finalizer::check_ltoir_input_output(std::path::Path::new(input), output)?; + } + } + Ok(()) +} + pub(crate) fn nvvm_ir_to_cubin( request: MaterializationRequest, nvvm_ir: &[u8], @@ -199,8 +261,13 @@ pub(crate) fn nvvm_ir_to_cubin( debug_policy: DebugPolicy, ) -> Result { let options = options(target, allow_fma_contraction, debug_policy)?; - let finalizer = checked_finalizer(request)?; - let report = finalizer.materialize_nvvm_ir_with_report(module_name, nvvm_ir, &options)?; + let finalizer = checked_finalizer(&request)?; + let ltoir = finalizer + .compiler() + .compile_nvvm_ir_to_ltoir(module_name, nvvm_ir, &options)?; + let name = format!("{module_name}.ltoir"); + let inputs = link_inputs(&request, &name, <oir); + let report = finalizer.link_ltoir_with_report(&inputs, &options, FinalizerOutput::Cubin)?; Ok(MaterializedCubin { bytes: report.image, resource_usage: report.resource_usage, @@ -216,18 +283,31 @@ pub(crate) fn ltoir_to_cubin( debug_policy: DebugPolicy, ) -> Result { let options = options(target, allow_fma_contraction, debug_policy)?; - let finalizer = checked_finalizer(request)?; - let report = finalizer.link_ltoir_with_report( - &[NamedInput::new(module_name, ltoir)], - &options, - FinalizerOutput::Cubin, - )?; + let finalizer = checked_finalizer(&request)?; + let inputs = link_inputs(&request, module_name, ltoir); + let report = finalizer.link_ltoir_with_report(&inputs, &options, FinalizerOutput::Cubin)?; Ok(MaterializedCubin { bytes: report.image, resource_usage: report.resource_usage, }) } +fn link_inputs<'a>( + request: &'a MaterializationRequest, + name: &'a str, + bytes: &'a [u8], +) -> Vec> { + std::iter::once(NamedInput::new(name, bytes)) + .chain( + request + .external_inputs + .iter() + .chain(&request.library_inputs) + .map(|(name, bytes)| NamedInput::new(name, bytes)), + ) + .collect() +} + fn options( target: &str, allow_fma_contraction: bool, @@ -239,7 +319,7 @@ fn options( .with_debug_policy(debug_policy)) } -fn checked_finalizer(request: MaterializationRequest) -> Result { +fn checked_finalizer(request: &MaterializationRequest) -> Result { let finalizer = Finalizer::discover_with_handshake(&request.tool_identity_handshake)?; let actual = finalizer .provenance_digest() @@ -384,22 +464,66 @@ mod tests { )); } + #[test] + fn output_overlap_uses_the_actual_crate_and_output_directory() { + let root = std::env::temp_dir().join(format!( + "oxide-materialize-overlap-{}-{}", + std::process::id(), + std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_nanos() + )); + std::fs::create_dir_all(&root).unwrap(); + let input = root.join("custom_target.ll"); + std::fs::write(&input, b"external input").unwrap(); + let handshake = test_handshake(); + let request = MaterializationRequest { + expected_provenance: handshake.provenance_sha256, + tool_identity_handshake: handshake, + library_inputs: Vec::new(), + external_inputs: vec![( + input.to_str().unwrap().to_owned(), + b"external input".to_vec(), + )], + }; + assert!(validate_output_paths(Some(&request), &root, "package_name").is_ok()); + assert!(matches!( + validate_output_paths(Some(&request), &root, "custom_target"), + Err(MaterializeError::Finalizer( + FinalizerError::LtoirInputOutputOverlap { .. } + )) + )); + assert_eq!(std::fs::read(&input).unwrap(), b"external input"); + std::fs::remove_dir_all(root).unwrap(); + } + #[test] fn unsupported_collection_models_fail_without_tools() { let handshake = test_handshake(); - let request = Some(MaterializationRequest { + let mut request = MaterializationRequest { expected_provenance: handshake.provenance_sha256, tool_identity_handshake: handshake, - }); + library_inputs: Vec::new(), + external_inputs: Vec::new(), + }; assert!(matches!( - validate_collection(request, false, true), + validate_collection(Some(&request), false, true), Err(MaterializeError::RequiresPtxBundleMerge) )); assert!(matches!( - validate_collection(request, true, false), + validate_collection(Some(&request), true, false), Err(MaterializeError::HasDeviceExterns) )); assert!(validate_collection(None, true, true).is_ok()); + request + .external_inputs + .push(("definition.ltoir".into(), vec![1])); + assert!(validate_collection(Some(&request), true, false).is_ok()); + assert!(matches!( + validate_collection(Some(&request), true, true), + Err(MaterializeError::RequiresPtxBundleMerge) + )); } #[test] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/tests/fixtures/primitives_api_compile/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/tests/fixtures/primitives_api_compile/Cargo.lock index 939d7756c3..0c593e8cd0 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/tests/fixtures/primitives_api_compile/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/tests/fixtures/primitives_api_compile/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn 2.0.119", ] @@ -417,8 +419,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cuda-oxide-book/compiler/native-library-calls.md b/cuda-oxide/cuda-oxide-book/compiler/native-library-calls.md new file mode 100644 index 0000000000..de53f516c6 --- /dev/null +++ b/cuda-oxide/cuda-oxide-book/compiler/native-library-calls.md @@ -0,0 +1,177 @@ +# Native library calls + +`cuda_device::library::call_v1` is an unsafe integration point for library +authors. It specializes native device implementations from concrete Rust +calls, then supplies their LTO-IR to ordinary CUBIN materialization. The +compiler owns discovery and linking; the library owns its operation semantics, +native code, ABI and scratch requirements. + +Use `cargo oxide build`, `run` or `test` with `--materialize-cubin`. The compiler +recognizes the actual marker definition, including calls reached through +generic dependency helpers. A same-named user function remains ordinary Rust. +The marker must be called directly; pass a wrapper helper rather than the +marker itself as a callable value. + +The `native_library` example is an executable provider with no CUB dependency. +Its dependency helper is instantiated at one and four items per thread, and +two concrete kernel roots run through the embedded module loader: + +```sh +cargo oxide run native_library --arch sm_120 --materialize-cubin +``` + +## Registration and call ABI + +The marker's generic parameters are `T`, `Registration`, `Args`, +`const BLOCK_THREADS: usize` and `const ITEMS_PER_THREAD: usize`. +Both extents must fit positive `u32`. It accepts a registration function item +and one tuple of scalar/raw-pointer arguments; it returns unit. + +The registration getter returns one constant UTF-8 JSON string. Its MIR must +contain one return block and one assignment of that constant to its result. +Closures, function pointers and computed getters are rejected. The compiler +reads the constant without running Rust device code. A Cargo build script can +embed the string with `cargo::rustc-env` and serve as the already-built native +provider. Read it through the registration macro so Cargo tracks native inputs: + +```rust +fn registration() -> &'static str { + cuda_device::library::registration!("MY_LIBRARY_REGISTRATION") +} +``` + +Generic getters may return an associated constant selected by concrete type +and const arguments. The compiler applies those arguments before reading the +string; the one-block constant-return restriction still applies. The raw calls +in `native_library` exercise this with one and four items per thread. + +The macro requires nonempty provider, operation and algorithm names and expands +to the same constant string. The provider executable must +recognize its protocol arguments before its ordinary Cargo build-script behavior. + +Registration fields are: + +| Field | Meaning | +| --- | --- | +| `version` | Integer `1` | +| `provider` | Nonempty library identifier | +| `executable` | Absolute path to the built host provider | +| `operation`, `algorithm` | Opaque recipe names interpreted by that provider | + +The runtime tuple starts with a const or mutable memory pointer and a mutable +payload pointer. Remaining fields are supported fixed-width numeric values or +raw pointers. The provider declares the exact ordered types and pointer +mutability; the compiler compares them with the Rust tuple. It inserts a +generic `unsigned char*` scratch parameter at native argument index two. +Small signed and unsigned integer values retain their native extension rules. +The native function returns `void`. + +## Host request and response + +For each `(provider, executable)` pair, the compiler invokes the executable +once with `--oxide-library-request-v1`. Stdin is one JSON object with `version: 1`, +`target`, `cuda_root`, and an ordered `requests` array. Each request contains +`operation`, `algorithm`, `dtype`, `block: [B,1,1]`, and `items_per_thread`. +Repeated concrete requests are deduplicated across roots. Scalar descriptions +use `{"kind":"signed|unsigned|float", "bits":N}`; integer widths are +8/16/32/64 and float widths are 16/32/64. A provider may support a narrower set +and must diagnose unsupported requests. + +Stdout contains only a binary response: eight bytes `OXDLIB01`, little-endian +u64 JSON-header length, little-endian u64 LTO-IR length, then the header and raw +LTO-IR. Diagnostics go to stderr; failure exits nonzero. Requests and response +headers are limited to 1 MiB, and the nonempty LTO-IR buffer to 256 MiB. + +The header has `version: 1`, a 32-byte `batch_identity` array, and one +`specializations` entry per request, in the same order: + +| Field | Meaning | +| --- | --- | +| `request_index` | Zero-based request position | +| `identity`, `symbol` | Unique 32-byte specialization identity and native link symbol | +| `arguments` | Ordered runtime tuple ABI, excluding the inserted scratch pointer | +| `cub_layout`, `scratch` | Native temporary-layout and required scratch `{size, alignment}` | +| `scratch_free` | Must agree with `scratch.size == 0` | +| `mutates_payload` | Semantic information; never permission to read an undefined value | + +Argument descriptions use `kind: "const_pointer"`, `"mut_pointer"` or +`"value"`, with a `scalar` description. Layout fields must fit `u32`, and +alignment must be a positive power of two. Symbol names use letters, digits +and underscores and cannot start with a digit. Different batches must not +return the same symbol. Truncated/trailing frames, mismatched versions, duplicate +identities and ABI mismatches fail compilation. + +The production provider is responsible for truthful layouts and identities +covering its sources, headers, recipes and toolchain. Returning owned bytes +avoids a second read of a mutable LTO file during finalization. The registration +macro tracks native inputs before rustc emits dep-info; +manual registration getters must arrange equivalent dependency tracking. + +## Native input dependencies + +The registration macro tracks its environment variable, the provider executable, +CUDA_HOME/CUDA_PATH selection, and the device compilation settings. During CUBIN +materialization it invokes the provider with `--oxide-library-inputs-v1`. Ordinary +host builds and rustdoc do not query toolkit inputs or require installed CUDA. + +The input query reads stdin through EOF. Its JSON request is +`{"version":1,"cuda_root":"/selected/toolkit","target":"compute_120"}`. +Stdout is one JSON response with `version: 1`, `paths` (absolute file or directory +paths) and `environment` (additional environment variable names). Requests and +responses are limited to 1 MiB. Diagnostics go to stderr; failures exit nonzero. +Unknown fields, invalid versions, relative/missing paths and invalid environment +names are errors. The query declares dependencies without compiling native code. + +The library owns this inventory, including sources, headers, compiler tools and +any environment affecting their selection or behavior. Directories are tracked +recursively so adding a header also causes recompilation. The macro records +these dependencies in the library crate; Cargo propagates its rebuild to +consumers and concrete generic kernel instantiations. The compiler has no +library-specific header layout or native cache. + +Cargo's timestamp freshness rules apply. Replacements with unchanged or older +timestamps can remain undetected, including restored files or a symlink switched +to an older installation at the same path. Clean/rebuild affected crates after +such external changes. +The `native_library` example tracks its provider, CUDA tools/headers, host compiler +driver and relevant environment. It assumes the host compiler's installed system +headers and libraries remain unchanged during a build; its declarations are not +a general inventory of an arbitrary C++ toolchain. + +## Debug information + +Providers choose the debug information in their LTO-IR; the compiler preserves +it during linking. With CUDA 13.3, Rust `--lineinfo` and native nvcc +`--generate-line-info` can be combined, retaining both source line tables. +Rust `--device-debug` also works with a provider built without debug information, +as exercised by the `native_library` full-debug smoke route. + +CUDA 13.3 rejects nvcc `-G` with `-dlto`. Linking Rust full debug with native line +information also fails in nvJitLink when it sees more than one debug compilation +unit. Select a supported combination explicitly; provider metadata is not +silently stripped to make these combinations link. + +## Resources and unsafe obligations + +Every reachable library call contributes its exact block shape and required +scratch to its kernel root. Conflicting shapes and incompatible declared launch +contracts or maximum bounds are errors. The compiled artifact carries the +resulting facts to launch preparation; `dynamic_shared = inferred` with +`LaunchConfig3D::auto_shared` uses the compiled byte count. + +This version aliases all library scratch views at the dynamic shared base, +using the maximum required size and alignment. The caller must complete each +use before conflicting reuse. Mixing native dynamic shared views +with library calls is rejected. No barrier, allocation token or borrow-based +completion is supplied by the marker. + +The library wrapper must enforce pointer validity, alignment, capacity, +initialization, nonaliasing, collective participation and resource reuse for +its native implementation. Convergent declarations preserve optimization +constraints; they do not prove participation or make the wrapper safe. The +marker is an unsafe compiler boundary, not a safe collective operation. + +The provider reads the complete request through stdin EOF before writing its +response. Reserve stdout for the binary response frame and use stderr for +diagnostics. The compiler waits for provider completion; provider execution has +the same trust boundary as a dependency's Cargo build script. diff --git a/cuda-oxide/cuda-oxide-book/getting-started/installation.md b/cuda-oxide/cuda-oxide-book/getting-started/installation.md index f8114dcc48..71913ef589 100644 --- a/cuda-oxide/cuda-oxide-book/getting-started/installation.md +++ b/cuda-oxide/cuda-oxide-book/getting-started/installation.md @@ -398,6 +398,22 @@ cargo oxide emit-ltoir my_kernels --arch sm_90 Every command takes `--help`, which lists the flags each one accepts. +For non-generic kernels that call external device functions, `--materialize-cubin` +links their CUDA LTO-IR definitions during the ordinary Cargo build. Pass each +input with `--link-ltoir` after the subcommand, in link order: + +```bash +cargo oxide run --materialize-cubin --arch sm_120 \ + --link-ltoir build/device-libs/scale.ltoir --link-ltoir build/device-libs/add.ltoir +``` + +Inputs must be raw CUDA LTO-IR, not object files or fatbins. Every supplied +file is linked into each materialized device artifact in the Cargo invocation. +This requires a build-host CUDA Toolkit compatible with the external inputs. +The resulting executable embeds the final cubin. Input names and contents are +part of Cargo's device-code fingerprint, so a changed definition rebuilds the +artifact. See the `external_ltoir` example for C++ sources and generation commands. + --- ## Verifying your installation diff --git a/cuda-oxide/cuda-oxide-book/index.md b/cuda-oxide/cuda-oxide-book/index.md index 92579e7d96..9869b926e6 100644 --- a/cuda-oxide/cuda-oxide-book/index.md +++ b/cuda-oxide/cuda-oxide-book/index.md @@ -212,6 +212,7 @@ compiler/compiler-optimizations compiler/mlir-dialects compiler/lowering-pipeline compiler/adding-new-intrinsics +compiler/native-library-calls compiler/catalog-generated-intrinsics compiler/fuzzing-and-differential-testing ``` diff --git a/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_ctm/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_ctm/Cargo.lock index b53df69613..d68b7d2be6 100644 --- a/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_ctm/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_ctm/Cargo.lock @@ -209,6 +209,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -430,8 +432,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_cute/Cargo.lock index d1c4551376..67cdab33f1 100644 --- a/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/blockscale_gemm_cute/Cargo.lock @@ -207,6 +207,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -442,8 +444,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/elementwise_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/elementwise_cute/Cargo.lock index f9407efb1d..34cb4ddd5a 100644 --- a/cuda-oxide/cute-rs-preview/examples/elementwise_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/elementwise_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -441,8 +443,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/ffn_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/ffn_cute/Cargo.lock index 1bcc8c3ca2..0a1102d198 100644 --- a/cuda-oxide/cute-rs-preview/examples/ffn_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/ffn_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -442,8 +444,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/fmha_decode_sm120a_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/fmha_decode_sm120a_cute/Cargo.lock index fd61d454c1..20a5003b2c 100644 --- a/cuda-oxide/cute-rs-preview/examples/fmha_decode_sm120a_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/fmha_decode_sm120a_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -442,8 +444,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/fmha_prefill_sm120a_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/fmha_prefill_sm120a_cute/Cargo.lock index 5cf93cc223..c04df3b2ba 100644 --- a/cuda-oxide/cute-rs-preview/examples/fmha_prefill_sm120a_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/fmha_prefill_sm120a_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -442,8 +444,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_ctm/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_ctm/Cargo.lock index c1474dc66d..4909f6a12e 100644 --- a/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_ctm/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_ctm/Cargo.lock @@ -198,6 +198,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -430,8 +432,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_cute/Cargo.lock index 5343fc92cb..e1531db6c5 100644 --- a/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/fp16_gemm_256x352_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -443,8 +445,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/nvfp4_gemv_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/nvfp4_gemv_cute/Cargo.lock index 8b256732c0..3ef5561201 100644 --- a/cuda-oxide/cute-rs-preview/examples/nvfp4_gemv_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/nvfp4_gemv_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -441,8 +443,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/rmsnorm_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/rmsnorm_cute/Cargo.lock index 89b1344256..a634e1da49 100644 --- a/cuda-oxide/cute-rs-preview/examples/rmsnorm_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/rmsnorm_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -431,8 +433,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/rope_cache_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/rope_cache_cute/Cargo.lock index 451bd568f8..721bb975e2 100644 --- a/cuda-oxide/cute-rs-preview/examples/rope_cache_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/rope_cache_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -431,8 +433,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/sm100_fmha_prefill_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/sm100_fmha_prefill_cute/Cargo.lock index ac93a53faa..c9584e5390 100644 --- a/cuda-oxide/cute-rs-preview/examples/sm100_fmha_prefill_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/sm100_fmha_prefill_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -431,8 +433,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/sm100_mla_decode_fp16_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/sm100_mla_decode_fp16_cute/Cargo.lock index 502c15a11c..dd63c84814 100644 --- a/cuda-oxide/cute-rs-preview/examples/sm100_mla_decode_fp16_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/sm100_mla_decode_fp16_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -431,8 +433,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/examples/swiglu_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/examples/swiglu_cute/Cargo.lock index 305d0f5d55..3bb4bb4760 100644 --- a/cuda-oxide/cute-rs-preview/examples/swiglu_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/swiglu_cute/Cargo.lock @@ -196,6 +196,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -430,8 +432,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/models/qwen3_8b_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/models/qwen3_8b_cute/Cargo.lock index cb0a22c8bc..74d0467d29 100644 --- a/cuda-oxide/cute-rs-preview/models/qwen3_8b_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/models/qwen3_8b_cute/Cargo.lock @@ -202,6 +202,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -456,8 +458,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/cute-rs-preview/models/qwen_decoder_cute/Cargo.lock b/cuda-oxide/cute-rs-preview/models/qwen_decoder_cute/Cargo.lock index 5f28dd3f25..b52ddfeba9 100644 --- a/cuda-oxide/cute-rs-preview/models/qwen_decoder_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/models/qwen_decoder_cute/Cargo.lock @@ -202,6 +202,8 @@ dependencies = [ "proc-macro2", "quote", "reserved-oxide-symbols", + "serde", + "serde_json", "syn", ] @@ -456,8 +458,6 @@ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object", ] diff --git a/cuda-oxide/scripts/check-compiled-launch-facts.sh b/cuda-oxide/scripts/check-compiled-launch-facts.sh new file mode 100755 index 0000000000..8c01488ea4 --- /dev/null +++ b/cuda-oxide/scripts/check-compiled-launch-facts.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +arch="${1:-sm_120}" +oxide=(cargo oxide) +if [[ -n "${CARGO_OXIDE_BIN:-}" ]]; then + oxide=("$CARGO_OXIDE_BIN") +fi +log=$(mktemp) +trap 'rm -f "$log"' EXIT + +"${oxide[@]}" run compiled_launch_facts --arch "$arch" +"${oxide[@]}" run compiled_launch_facts --arch "$arch" --features generic +"${oxide[@]}" run compiled_launch_facts --arch "$arch" --materialize-cubin + +if "${oxide[@]}" run compiled_launch_facts --arch "$arch" --features invalid-raw >"$log" 2>&1; then + echo "error: inferred scratch accepted an unconstrained raw dynamic view" >&2 + exit 1 +fi +grep -F 'inferred dynamic shared memory cannot include unconstrained' "$log" + +# Generic materialization remains unsupported; do not silently change loaders. +if "${oxide[@]}" run compiled_launch_facts --arch "$arch" --features generic --materialize-cubin >"$log" 2>&1; then + echo "error: generic materialization unexpectedly succeeded" >&2 + exit 1 +fi +grep -E 'generic.*materializ|materializ.*generic' "$log" +echo 'PASS: compiled launch facts and incomplete-plan rejection' diff --git a/cuda-oxide/scripts/check-example-smoketest-contract.sh b/cuda-oxide/scripts/check-example-smoketest-contract.sh index 710032d4e8..d48e017fa0 100644 --- a/cuda-oxide/scripts/check-example-smoketest-contract.sh +++ b/cuda-oxide/scripts/check-example-smoketest-contract.sh @@ -228,7 +228,7 @@ if not re.search( r'\[\[ \$\{FULL_DEBUG\} -eq 0 \]\] && verify_nvvm_in_compile_only', source ): sys.exit("full-debug verdict contract missing: libNVVM artifact branch is not excluded") -if "FULL_DEBUG_CONFIGURED_ROUTE_EXAMPLES=(interop_cubin_identity)" not in source: +if "FULL_DEBUG_CONFIGURED_ROUTE_EXAMPLES=(interop_cubin_identity native_library)" not in source: sys.exit("full-debug route contract missing: explicit cubin-project accommodation") if "Full-debug configured route: %d / %d passed" not in source: sys.exit("full-debug route contract missing: configured-route summary") diff --git a/cuda-oxide/scripts/check-external-ltoir.sh b/cuda-oxide/scripts/check-external-ltoir.sh new file mode 100755 index 0000000000..ff2f87dbc5 --- /dev/null +++ b/cuda-oxide/scripts/check-external-ltoir.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# Run with a CUDA Toolkit and GPU matching the requested architecture. +set -euo pipefail + +cd "$(dirname "$0")/.." +arch="${1:-sm_120}" +example="$PWD/crates/rustc-codegen-cuda/examples/external_ltoir" +artifacts="$(mktemp -d "${TMPDIR:-/tmp}/oxide-external-ltoir.XXXXXX")" +echo "External LTO-IR regression artifacts: $artifacts" +# Keep the example's executable location independent of the caller's Cargo cache. +unset CARGO_TARGET_DIR +oxide=(cargo oxide) +if [[ -n "${CARGO_OXIDE_BIN:-}" ]]; then + oxide=("$CARGO_OXIDE_BIN") +fi + +nvcc_flags=(--ltoir -dlto -arch="$arch") +if [[ -n "${NVCC_CCBIN:-${CUDAHOSTCXX:-}}" ]]; then + nvcc_flags+=(-ccbin="${NVCC_CCBIN:-$CUDAHOSTCXX}") +fi +nvcc "${nvcc_flags[@]}" "$example/scale.cu" -o "$artifacts/scale.ltoir" +nvcc "${nvcc_flags[@]}" -DEXTERNAL_ADDEND=3 "$example/add.cu" -o "$artifacts/add.ltoir" + +flags=(--arch "$arch" --materialize-cubin + --link-ltoir "$artifacts/scale.ltoir" --link-ltoir "$artifacts/add.ltoir") +cargo_args=(--manifest-path "$example/Cargo.toml" --release) + +run() { + local label="$1" + shift + if ! "$@" >"$artifacts/$label.log" 2>&1; then + cat "$artifacts/$label.log" >&2 + return 1 + fi + echo "PASS $label" +} + +run run "${oxide[@]}" run external_ltoir "${flags[@]}" +run test "${oxide[@]}" test "${flags[@]}" -- "${cargo_args[@]}" -- --nocapture +run build "${oxide[@]}" build "${flags[@]}" -- "${cargo_args[@]}" -v +run fresh "${oxide[@]}" build "${flags[@]}" -- "${cargo_args[@]}" -v +grep -q 'Fresh external_ltoir ' "$artifacts/fresh.log" + +# Change just the library content, retaining its path, size and modification +# time. The next passthrough build must invalidate Cargo's cached device code. +cp -p "$artifacts/add.ltoir" "$artifacts/add-original.ltoir" +nvcc "${nvcc_flags[@]}" -DEXTERNAL_ADDEND=1 "$example/add.cu" -o "$artifacts/add.ltoir" +if [[ "$(wc -c < "$artifacts/add-original.ltoir")" != "$(wc -c < "$artifacts/add.ltoir")" ]]; then + echo "error: this nvcc did not produce equal-sized addend variants" >&2 + exit 1 +fi +if cmp -s "$artifacts/add-original.ltoir" "$artifacts/add.ltoir"; then + echo "error: the addend variants have identical bytes" >&2 + exit 1 +fi +touch -r "$artifacts/add-original.ltoir" "$artifacts/add.ltoir" +run content-change "${oxide[@]}" build "${flags[@]}" -- "${cargo_args[@]}" -v +mv "$artifacts/scale.ltoir" "$artifacts/scale.saved" +mv "$artifacts/add.ltoir" "$artifacts/add.saved" +run changed-result "$example/target/release/external_ltoir" 1 +mv "$artifacts/scale.saved" "$artifacts/scale.ltoir" +mv "$artifacts/add.saved" "$artifacts/add.ltoir" + +if "${oxide[@]}" build --arch "$arch" --materialize-cubin \ + --link-ltoir "$artifacts/scale.ltoir" -- "${cargo_args[@]}" \ + >"$artifacts/missing-symbol.log" 2>&1; then + echo "error: a missing transitive device definition unexpectedly linked" >&2 + exit 1 +fi +grep -q 'external_add' "$artifacts/missing-symbol.log" +grep -qi 'nvJitLink' "$artifacts/missing-symbol.log" +echo "PASS missing-symbol" + +printf 'not an LTO-IR module\n' >"$artifacts/corrupt.ltoir" +if "${oxide[@]}" build --arch "$arch" --materialize-cubin \ + --link-ltoir "$artifacts/scale.ltoir" --link-ltoir "$artifacts/corrupt.ltoir" \ + -- "${cargo_args[@]}" >"$artifacts/corrupt-input.log" 2>&1; then + echo "error: corrupt LTO-IR unexpectedly linked" >&2 + exit 1 +fi +grep -qi 'nvJitLink' "$artifacts/corrupt-input.log" +grep -q 'corrupt.ltoir' "$artifacts/corrupt-input.log" +echo "PASS corrupt-input" + +# Exercise the backend guard using a disposable output directory. The supplied +# input and a previous output must both survive rejection before codegen writes. +collision="$artifacts/collision" +mkdir -p "$collision" +cp "$artifacts/scale.ltoir" "$collision/external_ltoir.ll" +printf 'previous output sentinel\n' >"$artifacts/previous-output" +cp "$artifacts/previous-output" "$collision/external_ltoir.ptx" +if CUDA_OXIDE_PTX_DIR="$collision" "${oxide[@]}" build --arch "$arch" --materialize-cubin \ + --link-ltoir "$collision/external_ltoir.ll" --link-ltoir "$artifacts/add.ltoir" \ + -- "${cargo_args[@]}" >"$artifacts/input-output-overlap.log" 2>&1; then + echo "error: an external input overlapping generated output was accepted" >&2 + exit 1 +fi +grep -q 'overlaps generated artifact' "$artifacts/input-output-overlap.log" +cmp "$artifacts/scale.ltoir" "$collision/external_ltoir.ll" +cmp "$artifacts/previous-output" "$collision/external_ltoir.ptx" +echo "PASS input-output-overlap" + +cp -p "$artifacts/add-original.ltoir" "$artifacts/add.ltoir" +run restored "${oxide[@]}" run external_ltoir "${flags[@]}" diff --git a/cuda-oxide/scripts/check-oxide-artifacts-parity.sh b/cuda-oxide/scripts/check-oxide-artifacts-parity.sh index 3d3d713239..8a0a4eacda 100755 --- a/cuda-oxide/scripts/check-oxide-artifacts-parity.sh +++ b/cuda-oxide/scripts/check-oxide-artifacts-parity.sh @@ -1,61 +1,61 @@ #!/usr/bin/env bash # SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 -# Verify the in-tree oxide-artifacts crate and the crates.io release everyone -# consumes are the same version. -# -# crates/oxide-artifacts is the source the release is published from, but no -# workspace consumes it by path any more: the backend writes artifact bundles -# and the shared cuda-core (cutile-rs) reads them, both through crates.io -# oxide-artifacts, so writer and reader are one crate. The in-tree copy can -# still drift ahead of the release; if it does, an edit to the format lands in -# git without reaching any consumer, and the next publish silently changes -# what every reader accepts. This guard fails as soon as the in-tree version, -# the workspace dependency requirements, and the versions resolved in every -# lock file disagree. -# -# Format changes therefore go: bump crates/oxide-artifacts, publish, then move -# the requirement in the SIMT and backend manifests and relock. +# Keep artifact writers and readers on one in-tree implementation and version. set -euo pipefail export LC_ALL=C cd "$(dirname "$0")/.." GIT_ROOT="$(git rev-parse --show-toplevel)" -in_tree="$(sed -n -E 's/^version = "([^"]+)"/\1/p' crates/oxide-artifacts/Cargo.toml | head -1)" -[ -n "${in_tree}" ] || { echo "error: crates/oxide-artifacts/Cargo.toml has no version" >&2; exit 1; } -echo "in-tree oxide-artifacts: ${in_tree}" +python3 - "${GIT_ROOT}" <<'PYTHON' +import pathlib +import subprocess +import sys +import tomllib -status=0 -req_of() { # req_of FILE -> the version requirement on the oxide-artifacts line - local line - line="$(grep -E '^oxide-artifacts[[:space:]]*=' "$1" | head -1 || true)" - if [[ "${line}" =~ version[[:space:]]*=[[:space:]]*\"([^\"]+)\" ]] || [[ "${line}" =~ ^oxide-artifacts[[:space:]]*=[[:space:]]*\"([^\"]+)\" ]]; then - echo "${BASH_REMATCH[1]}" - elif [[ "${line}" =~ path[[:space:]]*= ]]; then - echo "path" - else - echo "missing" - fi -} -for manifest in Cargo.toml crates/rustc-codegen-cuda/Cargo.toml; do - req="$(req_of "${manifest}")" - if [ "${req}" != "${in_tree}" ]; then - echo "error: ${manifest}: oxide-artifacts requirement is '${req}', in-tree version is ${in_tree}" >&2; status=1 - fi -done +root = pathlib.Path(sys.argv[1]) +artifact_dir = root / "cuda-oxide/crates/oxide-artifacts" -# Every lock that resolves oxide-artifacts must resolve exactly the in-tree -# version, from the registry (the SIMT lock also lists the in-tree member). -while IFS= read -r lock; do - versions="$(awk '/^name = "oxide-artifacts"$/{getline; print $3}' "${lock}" | tr -d '"' | sort -u)" - [ -n "${versions}" ] || continue - if [ "${versions}" != "${in_tree}" ]; then - echo "error: ${lock}: oxide-artifacts resolves to ${versions//$'\n'/, }, in-tree version is ${in_tree}" >&2; status=1 - fi - if ! grep -A3 '^name = "oxide-artifacts"$' "${lock}" | grep -q 'source = "registry+'; then - echo "error: ${lock}: oxide-artifacts is not consumed from crates.io" >&2; status=1 - fi -done < <(git -C "${GIT_ROOT}" ls-files 'Cargo.lock' '*/Cargo.lock' '**/Cargo.lock' | while read -r lock; do echo "${GIT_ROOT}/${lock}"; done) +def read_toml(path): + with path.open("rb") as source: + return tomllib.load(source) -[ "${status}" -eq 0 ] && echo "OK: oxide-artifacts is ${in_tree} in the tree, in both manifests, and in every lock (from crates.io)." -exit "${status}" +version = read_toml(artifact_dir / "Cargo.toml")["package"]["version"] +errors = [] +for relative, workspace in [ + ("cuda-core/Cargo.toml", False), + ("cuda-oxide/Cargo.toml", True), + ("cuda-oxide/crates/rustc-codegen-cuda/Cargo.toml", False), +]: + manifest = root / relative + data = read_toml(manifest) + dependencies = data["workspace"]["dependencies"] if workspace else data["dependencies"] + dependency = dependencies["oxide-artifacts"] + if not isinstance(dependency, dict) or dependency.get("version") != version: + errors.append(f"{relative}: oxide-artifacts must declare version {version}") + continue + path = dependency.get("path") + if path is None or (manifest.parent / path).resolve() != artifact_dir.resolve(): + errors.append(f"{relative}: oxide-artifacts must use {artifact_dir}") + +lockfiles = subprocess.check_output( + ["git", "-C", str(root), "ls-files", "-z", "*Cargo.lock"] +).decode().split("\0") +checked = 0 +for relative in filter(None, lockfiles): + packages = [ + package for package in read_toml(root / relative).get("package", []) + if package["name"] == "oxide-artifacts" + ] + if not packages: + continue + checked += 1 + if len(packages) != 1 or packages[0]["version"] != version or "source" in packages[0]: + errors.append(f"{relative}: oxide-artifacts must resolve once to the in-tree version {version}") + +for error in errors: + print(f"error: {error}", file=sys.stderr) +if errors: + sys.exit(1) +print(f"OK: oxide-artifacts {version} uses one in-tree source in all three manifests and {checked} locks.") +PYTHON diff --git a/cuda-oxide/scripts/smoketest.sh b/cuda-oxide/scripts/smoketest.sh index 35d8eb57a2..e6f75e64bb 100755 --- a/cuda-oxide/scripts/smoketest.sh +++ b/cuda-oxide/scripts/smoketest.sh @@ -90,7 +90,7 @@ set -uo pipefail TCGEN05_EXAMPLES=(gemm_sol gemm_sol_final tcgen05 tcgen05_matmul) WGMMA_EXAMPLES=(wgmma) BLACKWELL_MMA_EXAMPLES=(mma_mxf8f6f4) -LTOIR_EXAMPLES=(addressof_sharedarray constant_memory cpp_consumes_rust_device device_ffi_test legacy_atomic_fadd legacy_atomic_rmw_cas legacy_nvvm_pointer_shapes manual_launch_libdevice mathdx_ffi_test primitive_stress) +LTOIR_EXAMPLES=(addressof_sharedarray constant_memory cpp_consumes_rust_device device_ffi_test external_ltoir legacy_atomic_fadd legacy_atomic_rmw_cas legacy_nvvm_pointer_shapes manual_launch_libdevice mathdx_ffi_test primitive_stress) LTOIR_MODERN_EXAMPLES=(small_type_ffi_test) TILELIB_EXAMPLES=(tilelib_relu) AUTO_NVVM_EXAMPLES=(libdevice_math) @@ -127,13 +127,13 @@ NO_LAUNCH_EXAMPLES=(wgmma_mma_bf16) # afterwards purely to produce the artifacts the shape check reads. NO_OPT_SHAPE_EXAMPLES=(const_bool_dead_branch shared_memory_helper) -# This example intentionally configures a cubin artifact in Cargo metadata. -# Its supported project route necessarily includes NVVM IR + libNVVM + +# These examples require cubin artifacts, through Cargo metadata or native +# library materialization. Their supported route includes NVVM IR + libNVVM + # nvJitLink; the full-debug census must exercise that reality rather than # silently rewriting the project to PTX. It is reported separately from the -# direct-LLVM census so the one accommodation cannot be mistaken for direct +# direct-LLVM census so these accommodations cannot be mistaken for direct # backend coverage. -FULL_DEBUG_CONFIGURED_ROUTE_EXAMPLES=(interop_cubin_identity) +FULL_DEBUG_CONFIGURED_ROUTE_EXAMPLES=(interop_cubin_identity native_library) classify() { local ex="$1" cat @@ -263,14 +263,14 @@ OPTIONS is missing or too old). Error examples must still fail. Works on GPU-less CI. --full-debug Compile selected examples through the normal LLVM - `cargo oxide build --device-debug` route (except an - explicitly configured cubin project, reported as a + `cargo oxide build --device-debug` route (except the + configured cubin projects, reported as a separate configured-route accommodation). Validates fresh artifacts, ptxas assembly, permanent verify-debug-info.sh contracts, and intentional error diagnostics, but skips libNVVM and optimized code-shape gates because those do not accept/describe full-debug - output. Nothing is executed. Cannot be combined with + output. No kernels execute. Cannot be combined with --compile-only. -x, --fail-fast Stop at the first failure. -v, --verbose Stream cargo output live (instead of capturing to @@ -539,9 +539,9 @@ printf "%scuda-oxide smoketest%s @ %s%s%s (%s)\n" "${C_BOLD}" "${C_RESET}" "${C_ printf "GPU: %s\n" "${gpu_info}" printf "LTOIR arch: %s (modern: %s)\n" "${LTOIR_ARCH}" "${LTOIR_MODERN_ARCH}" if [[ ${COMPILE_ONLY} -eq 1 ]]; then - printf "Mode: compile-only (device artifacts only; nothing is executed)\n" + printf "Mode: compile-only (device artifacts only; no kernels execute)\n" elif [[ ${FULL_DEBUG} -eq 1 ]]; then - printf "Mode: full-debug compile census (direct LLVM plus explicit configured routes; nothing is executed)\n" + printf "Mode: full-debug compile census (direct LLVM plus explicit configured routes; no kernels execute)\n" fi if [[ -n "${ONLY}" ]]; then printf "Filter --only: %s\n" "${ONLY}"; fi if [[ -n "${SKIP}" ]]; then printf "Filter --skip: %s\n" "${SKIP}"; fi @@ -1026,6 +1026,10 @@ verdict_compile() { local artifact="${ex//-/_}" if [[ ${ec} -gt 128 ]]; then echo "FAIL (crashed, signal $((ec - 128)))"; return 1; fi if [[ ${ec} -ne 0 ]]; then echo "FAIL (exit=${ec})"; return 1; fi + if [[ "${ex}" == "native_library" ]]; then + native_library_cubin_verdict "${log}" + return + fi if [[ ${FULL_DEBUG} -eq 1 ]]; then case "${ex}" in device_ffi_test|mathdx_ffi_test|small_type_ffi_test) @@ -1038,6 +1042,11 @@ verdict_compile() { "${ex}" "${ex_dir}/${artifact}.ptx" return ;; + external_ltoir) + full_debug_relocatable_ffi_verdict \ + "${ex}" "${ex_dir}/${artifact}.ptx" + return + ;; cutile_inter_kernel) full_debug_ptx_verdict \ "${ex_dir}/simt/cutile_inter_kernel_simt.ptx" \ @@ -1180,6 +1189,9 @@ full_debug_relocatable_ffi_verdict() { mathdx_ffi_test) expected_undefined=$'cublasdx_gemm_32x32x32_block_dim_x\ncublasdx_gemm_32x32x32_block_dim_y\ncublasdx_gemm_32x32x32_block_dim_z\ncublasdx_gemm_32x32x32_f32\ncublasdx_gemm_32x32x32_f32_alphabeta\ncublasdx_gemm_32x32x32_smem_size\ncublasdx_gemm_32x32x32_smem_size_ab\ncufftdx_fft_16_c2c_f32_forward\ncufftdx_fft_16_c2c_f32_inverse\ncufftdx_fft_16_elements_per_thread\ncufftdx_fft_16_storage_size\ncufftdx_fft_32_storage_size\ncufftdx_fft_8_c2c_f32_forward\ncufftdx_fft_8_c2c_f32_inverse\ncufftdx_fft_8_elements_per_thread\ncufftdx_fft_8_storage_size\ndebug_extern_double_array' ;; + external_ltoir) + expected_undefined='external_scale_add' + ;; small_type_ffi_test) expected_undefined=$'small_add_u16\nsmall_add_u8\nsmall_half_add\nsmall_not_bool\nsmall_scale_i16\nsmall_scale_i8\nsmall_widen_i8\nsmall_widen_u16' ;; @@ -1266,6 +1278,56 @@ full_debug_relocatable_ffi_verdict() { echo "PASS (full-debug FFI PTX assembled relocatably for ${arch}; DWARF and undefined interface verified)" } +# The native-library fixture embeds its final image in the host executable. +# Its host-only check extracts that exact CUBIN without loading the CUDA driver. +native_library_cubin_verdict() { + local log="$1" target="${LTOIR_ARCH}" cubin elf_reader sections dwarf symbol + local binary="${CARGO_TARGET_DIR}/release/native_library" + # cargo oxide builds with the example as cwd; Cargo resolves relative + # target directories there, while this verdict runs from the repo root. + if [[ "${CARGO_TARGET_DIR}" != /* ]]; then + binary="${repo_root}/crates/rustc-codegen-cuda/examples/native_library/${binary}" + fi + local -a args=("--check-artifact") + if [[ ${FULL_DEBUG} -eq 1 ]]; then target="${LTOIR_MODERN_ARCH}"; fi + cubin="$(mktemp "${TMPDIR:-/tmp}/native-library.XXXXXX.cubin")" || return 1 + args+=("${target}" "${cubin}") + if [[ ${FULL_DEBUG} -eq 1 ]]; then args+=("--full-debug"); fi + if ! "${binary}" "${args[@]}" >>"${log}" 2>&1; then + rm -f "${cubin}" + echo "FAIL (native library embedded CUBIN check failed)" + return 1 + fi + if [[ ${FULL_DEBUG} -eq 1 ]]; then + elf_reader="$(command -v readelf || command -v llvm-readelf || true)" + if [[ -z "${elf_reader}" ]] \ + || ! sections="$("${elf_reader}" -W -S "${cubin}" 2>>"${log}")" \ + || ! dwarf="$("${elf_reader}" --debug-dump=info "${cubin}" 2>>"${log}")"; then + rm -f "${cubin}" + echo "FAIL (could not inspect native library CUBIN DWARF with readelf)" + return 1 + fi + rm -f "${cubin}" + if ! grep -q '[.]debug_info' <<<"${sections}" \ + || ! grep -q '[.]debug_line' <<<"${sections}" \ + || ! grep -q 'DW_TAG_compile_unit' <<<"${dwarf}" \ + || ! grep -q 'DW_TAG_subprogram' <<<"${dwarf}"; then + echo "FAIL (native library CUBIN is missing consumable DWARF)" + return 1 + fi + for symbol in one four; do + if ! grep -Eq "DW_AT_name.*: ${symbol}$" <<<"${dwarf}"; then + echo "FAIL (native library CUBIN is missing ${symbol} DWARF)" + return 1 + fi + done + echo "PASS (embedded CUBIN recorded debug=full and contains consumable DWARF)" + else + rm -f "${cubin}" + echo "PASS (embedded CUBIN and launch facts verified for ${target})" + fi +} + # The one configured cubin project cannot be judged through the root PTX # convention. Verify its complete versioned sidecar handshake and consume the # linked cubin's DWARF so a silently ignored interop debug policy cannot pass. @@ -1362,11 +1424,12 @@ run_full_debug_build() { # Full debug is unsupported by the legacy LLVM 7 NVVM dialect. Keep # the project's configured cubin path, but use the supported modern # dialect at the host target or its GPU-less sm_100 floor. - interop_cubin_identity) arch="${LTOIR_MODERN_ARCH}" ;; + interop_cubin_identity|native_library) arch="${LTOIR_MODERN_ARCH}" ;; esac if [[ -n "${arch}" ]]; then args+=("--arch=${arch}") fi + if [[ "${ex}" == "native_library" ]]; then args+=("--materialize-cubin"); fi if [[ ${VERBOSE} -eq 1 ]]; then cargo oxide "${args[@]}" 2>&1 | tee "${log}" @@ -1405,6 +1468,15 @@ run_cargo() { run_full_debug_build "${ex}" "${log}" "${cat}" return fi + # This fixture exercises compile-time linking of external device libraries. + # Its script supplies those inputs and verifies the embedded executable. + # Compile-only and full-debug retain the ordinary artifact-only FFI routes. + if [[ ${COMPILE_ONLY} -eq 0 && "${ex}" == "external_ltoir" ]]; then + bash scripts/check-external-ltoir.sh "${LTOIR_ARCH}" >"${log}" 2>&1 + CARGO_EC=$? + if [[ ${VERBOSE} -eq 1 ]]; then cat "${log}"; fi + return + fi # Rust `char` must remain plain i32 in both NVVM dialects. A runtime # round-trip cannot distinguish it from an incorrect zeroext i32 ABI. if [[ ${COMPILE_ONLY} -eq 1 && "${ex}" == "device_ffi_test" ]]; then @@ -2192,6 +2264,9 @@ run_cargo() { local verb="run" if [[ ${COMPILE_ONLY} -eq 1 ]]; then verb="build"; fi local -a args=("${verb}" "${ex}") + if [[ "${ex}" == "native_library" ]]; then + args+=("--materialize-cubin" "--arch=${LTOIR_ARCH}") + fi if [[ ${COMPILE_ONLY} -eq 0 && "${ex}" == "ex2_approx_f16" \ && "${host_cc}" =~ ^[0-9]+\.[0-9]+$ \ && $((10#${host_cc//./})) -lt 75 ]]; then diff --git a/cutile-rs/Cargo.lock b/cutile-rs/Cargo.lock index add95613f8..8e19022b97 100644 --- a/cutile-rs/Cargo.lock +++ b/cutile-rs/Cargo.lock @@ -1251,8 +1251,6 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "oxide-artifacts" version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" dependencies = [ "object 0.36.7", ]