From e0ead85e785cc24cea73cb534bf8b04adbe5de3b Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Sat, 19 Sep 2026 08:13:32 +0700 Subject: [PATCH 01/10] fix(codegen): match redux.sync's f32 form on the instruction, not on nearby text `contains_redux_f32_features` asked whether `redux.sync` and `.f32` both appeared in one `;`-delimited piece of the LLVM IR. `;` starts a comment in IR, so that piece is usually the whole module: a module reducing integers with any unrelated `.f32` was pushed from sm_80 to sm_100a. The integer `warp_reduce` fast path in #811 is such a module. The predicate now decides on tokens. The IR is lexed with quoted text consumed whole and comments dropped, and two things count: * a global symbol, quoting decoded, named `llvm.nvvm.redux.sync.` followed by a float operation -- the ones beginning with `f`, since the float callees carry no type suffix; * a `redux` opcode whose modifiers, in an inline-asm template, start with `.sync` and include `.f32`. The template is the string after `LLParser`'s `asm [sideeffect] [alignstack] [inteldialect] [unwind]`, decoded as `llvm::UnEscapeLexed` does, then lexed as PTX: whitespace and `//` and `/* */` comments separate tokens without ending a modifier run, a number consumes its whole run, and a string literal -- in which a backslash is literal -- is skipped as data. So text that only mentions the instruction or the callee -- in a comment, a data or metadata string, a `.file` path, or another symbol's quoted name -- no longer counts, and the quoted, escaped, `unwind`, spaced and comment-separated spellings of a real one do. Thirty-one controls across four tests, each a line from a module `llvm-as` from the pinned toolchain accepts. All but one also lower through `llc`; the exception is a global whose quoted name contains a space and `@`, which is valid IR that NVPTX cannot emit, and which tests the lexer rather than lowering. The PTX controls are also checked with ptxas, where the float cases assemble at sm_100a and are refused at sm_80 as `redux.f32`. Twelve mutations of the lexers each fail a test. The float intrinsic spelling was never matched by the old predicate, but that is not a live mis-target: those are catalog intrinsics, and `select_target_with_generated` takes sm_100a from their recorded requirements regardless -- `redux_f32` selects sm_100a with nothing pinned under either version. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../cuda-oxide-codegen/src/target/detect.rs | 253 +++++++++++++++++- .../target/tests/detection_async_memory.rs | 184 +++++++++++++ 2 files changed, 433 insertions(+), 4 deletions(-) diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs index 20ce82e87a..4cf1b75345 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs @@ -5,6 +5,7 @@ use super::features::{DetectedFeatures, ModuleRequirements, PtxIsaRequirement}; use crate::error::PipelineError; +use std::borrow::Cow; use std::path::Path; pub(super) fn contains_wgmma_features(contents: &str) -> bool { @@ -95,11 +96,255 @@ fn contains_multimem_blackwell_features(contents: &str) -> bool { }) } -/// Checks the PTX 8.6 floating-point extension to `redux.sync`. +/// Checks the PTX 8.6 floating-point extension to `redux.sync`: a call to a +/// float NVVM redux intrinsic, or a `redux.sync ... .f32` instruction in +/// inline PTX. Decided on tokens, so text that only mentions either -- in a +/// comment, a string or another symbol's name -- does not count. fn contains_redux_f32_features(contents: &str) -> bool { - contents - .split(';') - .any(|statement| statement.contains("redux.sync") && statement.contains(".f32")) + let tokens = lex_llvm_ir(contents); + tokens.iter().enumerate().any(|(index, token)| match token { + IrToken::Global(name) => is_float_redux_callee(name), + IrToken::Word(word) if *word == "asm" => inline_asm_template(&tokens[index + 1..]) + .is_some_and(|template| ptx_contains_float_redux(&unescape_llvm_string(template))), + // A raw PTX fragment rather than IR, which is how tests pass PTX. + IrToken::Word(word) => ptx_contains_float_redux(word), + IrToken::Label(_) | IrToken::String(_) => false, + }) +} + +/// `llvm.nvvm.redux.sync.` followed by a float operation. Those are the ones +/// beginning with `f` (`fmin`, `fmax`, each with optional `.abs` and `.NaN`); +/// no integer operation does. +fn is_float_redux_callee(name: &str) -> bool { + name.strip_prefix("llvm.nvvm.redux.sync.") + .is_some_and(|operation| operation.starts_with('f')) +} + +/// Does this PTX contain a `redux.sync` instruction with an `.f32` modifier? +/// +/// An opcode's modifiers are the run of `.name` tokens after it, so +/// `redux.sync.min.f32`, `redux .sync .min .f32` and a comment between two +/// modifiers are the same instruction. +fn ptx_contains_float_redux(ptx: &str) -> bool { + if !ptx.contains("redux") { + return false; + } + let tokens = lex_ptx(ptx); + tokens.iter().enumerate().any(|(index, token)| { + let mut modifiers = tokens[index + 1..].iter().map_while(|token| match token { + PtxToken::Modifier(modifier) => Some(*modifier), + _ => None, + }); + *token == PtxToken::Identifier("redux") + && modifiers.next() == Some(".sync") + && modifiers.any(|modifier| modifier == ".f32") + }) +} + +/// A PTX token. Whitespace, comments and string literals produce none. +#[derive(Debug, PartialEq)] +enum PtxToken<'a> { + /// An opcode or other identifier: `redux`, `%r1`, `$0`. + Identifier(&'a str), + /// A `.name` token: an instruction modifier or a directive. + Modifier(&'a str), + /// Punctuation or a number. + Other, +} + +/// Split PTX into [`PtxToken`]s, dropping whitespace, `//` and `/* */` +/// comments, and string literals such as a `.file` path. +fn lex_ptx(ptx: &str) -> Vec> { + fn is_identifier(byte: u8) -> bool { + byte.is_ascii_alphanumeric() || matches!(byte, b'_' | b'$') + } + + let bytes = ptx.as_bytes(); + let run_end = |from: usize| { + bytes[from..] + .iter() + .position(|&byte| !is_identifier(byte)) + .map_or(bytes.len(), |offset| from + offset) + }; + + let mut tokens = Vec::new(); + let mut index = 0; + while index < bytes.len() { + let rest = &bytes[index..]; + if rest.starts_with(b"//") { + index += rest + .iter() + .position(|&byte| byte == b'\n') + .unwrap_or(rest.len()); + } else if rest.starts_with(b"/*") { + index += rest[2..] + .windows(2) + .position(|pair| pair == b"*/") + .map_or(rest.len(), |offset| offset + 4); + } else if rest[0] == b'"' { + // A backslash is literal in a PTX string -- ptxas accepts + // `.file 1 "C:\dir\"` -- so the next quote always closes it. + index += rest[1..] + .iter() + .position(|&byte| byte == b'"') + .map_or(rest.len(), |offset| offset + 2); + } else if rest[0] == b'.' && rest.get(1).is_some_and(|&byte| is_identifier(byte)) { + let end = run_end(index + 1); + tokens.push(PtxToken::Modifier(&ptx[index..end])); + index = end; + } else if rest[0].is_ascii_digit() { + // A number consumes its whole run -- `0f3F800000`, `0x1F`, `123U` -- + // so an identifier is never read out of its tail. + index = run_end(index + 1); + tokens.push(PtxToken::Other); + } else if rest[0].is_ascii_alphabetic() || matches!(rest[0], b'_' | b'$' | b'%') { + let end = run_end(index + 1); + tokens.push(PtxToken::Identifier(&ptx[index..end])); + index = end; + } else { + if !rest[0].is_ascii_whitespace() { + tokens.push(PtxToken::Other); + } + index += 1; + } + } + tokens +} + +/// The template of an inline-asm expression, given the tokens after `asm`: +/// the string after `[sideeffect] [alignstack] [inteldialect] [unwind]`, +/// each optional and in that order, as `LLParser` accepts them. Also covers +/// `module asm`. +fn inline_asm_template<'a>(after_asm: &[IrToken<'a>]) -> Option<&'a str> { + const MODIFIERS: [&str; 4] = ["sideeffect", "alignstack", "inteldialect", "unwind"]; + let mut tokens = after_asm.iter(); + let mut next = tokens.next(); + for modifier in MODIFIERS { + if matches!(next, Some(IrToken::Word(word)) if *word == modifier) { + next = tokens.next(); + } + } + match next { + Some(IrToken::String(template)) => Some(template), + _ => None, + } +} + +/// An LLVM IR token. Comments, punctuation, local and metadata names and +/// attribute groups produce none. +#[derive(Debug, PartialEq)] +enum IrToken<'a> { + /// A bare keyword, type or identifier. + Word(&'a str), + /// A basic-block label, `name:`. + Label(&'a str), + /// A global symbol with the sigil removed and quoting decoded, so + /// `@name` and `@"quoted name"` both yield the name. + Global(Cow<'a, str>), + /// A string literal between its quotes, still escaped. + String(&'a str), +} + +/// Split LLVM IR into [`IrToken`]s. Quoted text is consumed whole before +/// anything inside it is read, so a `;` in a string is not a comment and a +/// `@` in a quoted name does not start another symbol. +fn lex_llvm_ir(contents: &str) -> Vec> { + fn is_identifier(byte: u8) -> bool { + byte.is_ascii_alphanumeric() || matches!(byte, b'-' | b'$' | b'.' | b'_') + } + + let bytes = contents.as_bytes(); + // LLVM writes a quote inside quoted text as `\22`, so the next `"` closes it. + let closing_quote = |from: usize| { + bytes[from..] + .iter() + .position(|&byte| byte == b'"') + .map_or(bytes.len(), |offset| from + offset) + }; + let identifier_end = |from: usize| { + bytes[from..] + .iter() + .position(|&byte| !is_identifier(byte)) + .map_or(bytes.len(), |offset| from + offset) + }; + + let mut tokens = Vec::new(); + let mut index = 0; + while index < bytes.len() { + match bytes[index] { + b';' => { + index = bytes[index..] + .iter() + .position(|&byte| byte == b'\n') + .map_or(bytes.len(), |offset| index + offset); + } + b'"' => { + let close = closing_quote(index + 1); + tokens.push(IrToken::String(&contents[index + 1..close])); + index = bytes.len().min(close + 1); + } + sigil @ (b'@' | b'%' | b'!' | b'#') => { + let (name, next) = if bytes.get(index + 1) == Some(&b'"') { + let close = closing_quote(index + 2); + ( + unescape_llvm_string(&contents[index + 2..close]), + bytes.len().min(close + 1), + ) + } else { + let end = identifier_end(index + 1); + (Cow::Borrowed(&contents[index + 1..end]), end) + }; + if sigil == b'@' { + tokens.push(IrToken::Global(name)); + } + index = next; + } + byte if is_identifier(byte) => { + let end = identifier_end(index); + let word = &contents[index..end]; + if bytes.get(end) == Some(&b':') { + tokens.push(IrToken::Label(word)); + index = end + 1; + } else { + tokens.push(IrToken::Word(word)); + index = end; + } + } + _ => index += 1, + } + } + tokens +} + +/// Decode LLVM quoted text as `llvm::UnEscapeLexed` does: `\\` is one +/// backslash, `\XX` is the byte with that hex value, and any other backslash +/// stands for itself. +fn unescape_llvm_string(text: &str) -> Cow<'_, str> { + if !text.contains('\\') { + return Cow::Borrowed(text); + } + let hex = |byte: Option<&u8>| byte.and_then(|&byte| (byte as char).to_digit(16)); + let bytes = text.as_bytes(); + let mut decoded = Vec::with_capacity(bytes.len()); + let mut index = 0; + while index < bytes.len() { + if bytes[index] == b'\\' { + if bytes.get(index + 1) == Some(&b'\\') { + decoded.push(b'\\'); + index += 2; + continue; + } + if let (Some(high), Some(low)) = (hex(bytes.get(index + 1)), hex(bytes.get(index + 2))) + { + decoded.push((high * 16 + low) as u8); + index += 3; + continue; + } + } + decoded.push(bytes[index]); + index += 1; + } + Cow::Owned(String::from_utf8_lossy(&decoded).into_owned()) } /// Checks for forward-compatible instructions whose minimum target is sm_90. diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs index 9c644810bb..5887318067 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs @@ -586,3 +586,187 @@ fn test_tma_multicast_detection_requires_cta_mask() { ); assert!(!contains_tma_cta_group_features(unrelated_i32)); } + +/// `redux.sync` is f32 by its own token, never by an `.f32` sitting nearby +/// (#1303). +#[test] +fn test_redux_f32_detection_is_scoped_to_the_instruction() { + // The shape that found this: integer reductions in one kernel and + // ordinary float work in another. In the module that was rejected, the + // two matches were 547 lines apart. + let integer_redux_and_distant_f32 = r#" + declare i32 @llvm.nvvm.redux.sync.add(i32, i32) #0 + declare float @llvm.nvvm.shfl.sync.bfly.f32(i32, float, i32, i32) #0 + "#; + // LLVM does not require a newline between declarations, so scoping to a + // line is not enough either. + let same_line = "declare i32 @llvm.nvvm.redux.sync.add(i32, i32) declare float @llvm.nvvm.shfl.sync.bfly.f32(i32, float, i32, i32)"; + // An SSA name may end in `.f32` and says nothing about the callee. + let unrelated_ssa_name = "%acc.f32 = call i32 @llvm.nvvm.redux.sync.umax(i32 -1, i32 %v)"; + + for text in [integer_redux_and_distant_f32, same_line, unrelated_ssa_name] { + assert!( + !detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "an integer reduction must not select the f32 extension: {text}" + ); + } + + // The intrinsic spelling has no type suffix -- the `f`-prefixed operation + // is what makes it float. These were detected before only when some + // unrelated `.f32` happened to sit nearby. + let float_intrinsic = "%r = call float @llvm.nvvm.redux.sync.fmin(float %v, i32 -1)"; + let float_intrinsic_qualified = + "%r = call float @llvm.nvvm.redux.sync.fmax.abs.NaN(float %v, i32 -1)"; + // Inline PTX carries the type as a modifier of the opcode token. + let float_asm = r#"call float asm sideeffect "redux.sync.min.abs.NaN.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + + for text in [float_intrinsic, float_intrinsic_qualified, float_asm] { + assert!( + detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "a float reduction must select the f32 extension: {text}" + ); + } +} + +/// Mentioning an intrinsic is not using one, and a real call may be spelled +/// with a quoted identifier (#1303). +#[test] +fn test_redux_f32_detection_reads_code_and_not_prose() { + // Text that names the callee without calling it. + let in_a_comment = + "%r = call i32 @llvm.nvvm.redux.sync.add(i32 -1, i32 %v) ; @llvm.nvvm.redux.sync.fmin"; + let in_a_data_string = r#"@.msg = private constant [27 x i8] c"@llvm.nvvm.redux.sync.fmin\00""#; + let in_metadata = r#"!0 = !{!"@llvm.nvvm.redux.sync.fmin"}"#; + // The same for the inline-PTX spelling: a comment and a data constant are + // not instructions. + let ptx_in_a_comment = " ; redux.sync.min.abs.NaN.f32 $0, $1, $2;"; + let ptx_in_a_data_string = r#"@.msg = private constant [25 x i8] c"redux.sync.min.f32 a,b,c;""#; + + for text in [ + in_a_comment, + in_a_data_string, + in_metadata, + ptx_in_a_comment, + ptx_in_a_data_string, + ] { + assert!( + !detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "text that only mentions the f32 reduction must not select it: {text}" + ); + } + + // A real call, spelled with a quoted identifier and with one of its + // characters escaped -- `\66` is `f`, so both name `fmin`. + let quoted = r#"%r = call float @"llvm.nvvm.redux.sync.fmin"(float %v, i32 -1)"#; + let quoted_escaped = r#"%r = call float @"llvm.nvvm.redux.sync.\66min"(float %v, i32 -1)"#; + // And the constraint string beside an asm template is data, while the + // template itself is code. + let asm_template = r#"call float asm sideeffect "redux.sync.min.abs.NaN.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + + for text in [quoted, quoted_escaped, asm_template] { + assert!( + detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "a float reduction must select the f32 extension: {text}" + ); + } +} + +/// Token identity at the edges the flattened search lost (#1303). +/// +/// Each input is a line from a module `llvm-as` from the pinned toolchain +/// accepts, so none of these is a shape valid IR cannot produce. The escape +/// cases were also round-tripped through `llvm-dis` to confirm what LLVM +/// itself decodes them to. +#[test] +fn test_redux_f32_detection_keeps_token_identity() { + // `unwind` is the last of the four modifiers `asm` may carry, in order: + // sideeffect, alignstack, inteldialect, unwind. + let unwind = r#"%r = call float asm sideeffect unwind "redux.sync.min.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // `\72` is `r`: LLVM decodes the template before the backend sees it. + let escaped_opcode = r#"%r = call float asm sideeffect "\72edux.sync.min.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // A PTX comment ended by an *escaped* newline, then a real instruction. + // Only decoding before stripping comments finds it: the raw template is + // one line, so a `//` there would appear to run to its end. + let after_escaped_newline = r#"%r = call float asm sideeffect "// scale first\0Aredux.sync.min.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // Module-level inline asm has the same grammar and reaches the same PTX. + let module_asm = r#"module asm "redux.sync.min.f32 %f1, %f2, %r3;""#; + + for text in [unwind, escaped_opcode, after_escaped_newline, module_asm] { + assert!( + detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "a float reduction must select the f32 extension: {text}" + ); + } + + // PTX comments inside a template are prose, in either comment form. + let ptx_line_comment = r#"%r = call float asm sideeffect "// redux.sync.min.f32 $0, $1, $2;\0Amov.f32 $0, $1;", "=f,f,r"(float %v, i32 %m)"#; + let ptx_block_comment = r#"%r = call float asm sideeffect "/* redux.sync.min.f32 $0, $1, $2; */ mov.f32 $0, $1;", "=f,f,r"(float %v, i32 %m)"#; + // `\\` is one backslash and the hex digits after it are plain text: `llc` + // emits this template as `\20redux.sync.min.f32 ...`, which is not an + // instruction. A decoder that skipped the `\\` rule would read `\20` as a + // space instead and find a `redux.sync.min.f32` that is not there. + let escaped_backslash = r#"%r = call float asm sideeffect "\\20redux.sync.min.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // One symbol whose quoted name happens to contain another's spelling. + let embedded_in_a_name = r#"@"unused @llvm.nvvm.redux.sync.fmin" = global i32 0"#; + // A basic block may be named like an instruction without being one. + let label = "redux.sync.min.f32:\n ret void"; + + for text in [ + ptx_line_comment, + ptx_block_comment, + escaped_backslash, + embedded_in_a_name, + label, + ] { + assert!( + !detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "no float reduction is executed here: {text}" + ); + } +} + +/// PTX lexical rules inside an asm template (#1303). +/// +/// Every input is a complete module accepted by `llvm-as` and `llc` from the +/// pinned toolchain and by ptxas at sm_100a. The float cases are the ones +/// ptxas then refuses at sm_80 as `redux.f32`; the others assemble there. +#[test] +fn test_redux_f32_detection_reads_ptx_as_ptx() { + // Whitespace, a newline or a comment may separate an opcode from its + // modifiers; it is still one instruction. + let spaced_type = r#"%r = call float asm sideeffect "redux.sync.min .f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + let comment_between = r#"%r = call float asm sideeffect "redux.sync.min/* qualifier */.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + let fully_spaced = r#"%r = call float asm sideeffect "redux .sync .min .f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + let newline_between = r#"%r = call float asm sideeffect "redux.sync.min\0A.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // A backslash is literal inside a PTX string, so `"nounroll\"` closes at + // its last quote and the instruction after it is real. + let after_trailing_backslash = r#"%r = call float asm sideeffect ".pragma \22nounroll\5C\22;\0Aredux.sync.min.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + + for text in [ + spaced_type, + comment_between, + fully_spaced, + newline_between, + after_trailing_backslash, + ] { + assert!( + detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "a float reduction must select the f32 extension: {text}" + ); + } + + // A directive's quoted data is not an instruction. + let file_path = r#"module asm ".file 1 \22name redux.sync.min.f32 label.cu\22""#; + // Spacing does not make an integer reduction float. + let spaced_integer = r#"%r = call i32 asm sideeffect "redux .sync .min .u32 $0, $1, $2;", "=r,r,r"(i32 %v, i32 %m)"#; + // Nor does float work beside it in the same template: `.f32` counts only + // as a modifier of the `redux` opcode itself. + let integer_beside_f32 = r#"%r = call i32 asm sideeffect "{ .reg .f32 t; redux.sync.min.u32 $0, $1, $2; mov.f32 t, 0f3F800000; }", "=r,r,r"(i32 %v, i32 %m)"#; + + for text in [file_path, spaced_integer, integer_beside_f32] { + assert!( + !detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), + "no float reduction is executed here: {text}" + ); + } +} From 1c1cb27119c7a4d946a57da579b488a76275c986 Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:21:54 +0700 Subject: [PATCH 02/10] fix(codegen): end a PTX token at an asm operand, and accept any modifier order `lex_ptx` read `$` as an identifier byte, so a template that glues an operand to the type -- `redux.sync.min.f32$0, $1, $2;` -- produced the modifier `.f32$0` and the float form went undetected. The module then selected sm_80, where ptxas refuses `redux.f32`. In an asm template a bare `$` starts an operand and `$$` is a literal dollar, so a bare `$` now ends the identifier or modifier before it. The scan also required `.sync` to be the first modifier. ptxas accepts the modifiers in any order -- `redux.min.sync.f32` and `redux.f32.sync.min` assemble at sm_100a and are refused at sm_80 like the canonical spelling -- so that rule missed real float reductions. It is gone: `.sync` is mandatory on every `redux`, so the opcode plus an `.f32` anywhere in its modifier run decides. Five controls, each checked through llvm-as, llc and ptxas at sm_100a and sm_80: the glued and both reordered float forms, which ptxas refuses at sm_80, and the glued and reordered integer forms, which it assembles there. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../cuda-oxide-codegen/src/target/detect.rs | 39 ++++++++++++------- .../target/tests/detection_async_memory.rs | 24 +++++++++++- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs index 4cf1b75345..2bfff0af70 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/detect.rs @@ -120,24 +120,26 @@ fn is_float_redux_callee(name: &str) -> bool { .is_some_and(|operation| operation.starts_with('f')) } -/// Does this PTX contain a `redux.sync` instruction with an `.f32` modifier? +/// Does this PTX contain a `redux` instruction with an `.f32` modifier? /// -/// An opcode's modifiers are the run of `.name` tokens after it, so -/// `redux.sync.min.f32`, `redux .sync .min .f32` and a comment between two -/// modifiers are the same instruction. +/// An opcode's modifiers are the run of `.name` tokens after it, in any +/// order, so `redux.sync.min.f32`, `redux.f32.sync.min` and +/// `redux .sync .min .f32` are the same instruction. ptxas requires `.sync` +/// on every `redux`, so it is not checked. fn ptx_contains_float_redux(ptx: &str) -> bool { if !ptx.contains("redux") { return false; } let tokens = lex_ptx(ptx); tokens.iter().enumerate().any(|(index, token)| { - let mut modifiers = tokens[index + 1..].iter().map_while(|token| match token { - PtxToken::Modifier(modifier) => Some(*modifier), - _ => None, - }); *token == PtxToken::Identifier("redux") - && modifiers.next() == Some(".sync") - && modifiers.any(|modifier| modifier == ".f32") + && tokens[index + 1..] + .iter() + .map_while(|token| match token { + PtxToken::Modifier(modifier) => Some(*modifier), + _ => None, + }) + .any(|modifier| modifier == ".f32") }) } @@ -160,11 +162,20 @@ fn lex_ptx(ptx: &str) -> Vec> { } let bytes = ptx.as_bytes(); + // In an asm template a bare `$` starts an operand and `$$` is a literal + // dollar, so `.f32$0` is the modifier `.f32` followed by `$0`. let run_end = |from: usize| { - bytes[from..] - .iter() - .position(|&byte| !is_identifier(byte)) - .map_or(bytes.len(), |offset| from + offset) + let mut end = from; + while end < bytes.len() && is_identifier(bytes[end]) { + if bytes[end] == b'$' { + if bytes.get(end + 1) != Some(&b'$') { + break; + } + end += 1; + } + end += 1; + } + end }; let mut tokens = Vec::new(); diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs index 5887318067..9f24089ec6 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_async_memory.rs @@ -741,6 +741,14 @@ fn test_redux_f32_detection_reads_ptx_as_ptx() { // A backslash is literal inside a PTX string, so `"nounroll\"` closes at // its last quote and the instruction after it is real. let after_trailing_backslash = r#"%r = call float asm sideeffect ".pragma \22nounroll\5C\22;\0Aredux.sync.min.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // A bare `$` starts an operand, so it ends the modifier before it. llc + // emits `redux.sync.min.f32%r1, %r2, %r3;`, which ptxas assembles at + // sm_100a and refuses at sm_80 with `Instruction 'redux.f32' not supported`. + let glued_operand = r#"%r = call float asm sideeffect "redux.sync.min.f32$0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + // Modifiers may come in any order; ptxas gives both of these the same + // two results as the glued form. + let sync_after_operation = r#"%r = call float asm sideeffect "redux.min.sync.f32 $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; + let type_first = r#"%r = call float asm sideeffect "redux.f32.sync.min $0, $1, $2;", "=f,f,r"(float %v, i32 %m)"#; for text in [ spaced_type, @@ -748,6 +756,9 @@ fn test_redux_f32_detection_reads_ptx_as_ptx() { fully_spaced, newline_between, after_trailing_backslash, + glued_operand, + sync_after_operation, + type_first, ] { assert!( detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), @@ -762,8 +773,19 @@ fn test_redux_f32_detection_reads_ptx_as_ptx() { // Nor does float work beside it in the same template: `.f32` counts only // as a modifier of the `redux` opcode itself. let integer_beside_f32 = r#"%r = call i32 asm sideeffect "{ .reg .f32 t; redux.sync.min.u32 $0, $1, $2; mov.f32 t, 0f3F800000; }", "=r,r,r"(i32 %v, i32 %m)"#; + // The integer forms of the glued and reordered inputs above; ptxas + // assembles both at sm_80. + let glued_integer = + r#"%r = call i32 asm sideeffect "redux.sync.min.u32$0, $1, $2;", "=r,r,r"(i32 %v, i32 %m)"#; + let reordered_integer = r#"%r = call i32 asm sideeffect "redux.min.sync.u32 $0, $1, $2;", "=r,r,r"(i32 %v, i32 %m)"#; - for text in [file_path, spaced_integer, integer_beside_f32] { + for text in [ + file_path, + spaced_integer, + integer_beside_f32, + glued_integer, + reordered_integer, + ] { assert!( !detect_features_in_llvm_text(text).contains(DetectedFeatures::ReduxF32), "no float reduction is executed here: {text}" From 1ef7d6ee1f06b3803fff1777592f0d628b4281ba Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Sat, 5 Sep 2026 18:13:04 +0700 Subject: [PATCH 03/10] feat(cuda-device): derive an SM floor cfg and use redux.sync in warp_reduce Device code had no way to ask what target it was being compiled for, so `warp_reduce` could not take the one-instruction `redux.sync` form even when the build was certain to be Ampere or newer: a full warp always paid five shuffles plus five combines. Measured on an A10G over 1M threads reducing 64 times each, that is 159.4 us per launch against 33.6 us, 4.74x, for bit-identical results. A cfg is the mechanism that works here. It is decided before rustc runs, so rustc drops the branch that does not apply and the requirement scan never sees an instruction the target cannot run -- unlike a `__CUDA_ARCH__`-style intrinsic folded at lowering, where the scan reads `redux.sync` out of the dead branch and raises the module floor before anything folds. `cuda-device` gains a build script that resolves the floor and emits `cuda_oxide_sm_at_least = "XY"` for every rung at or below it. `cfg` compares strings rather than numbers, so the rungs are cumulative and device code tests the one its instruction needs. The floor rule lives in `cuda-target-spec`, shared with the backend rather than restated, and follows the backend's own precedence: `CUDA_OXIDE_TARGET`, else `CUDA_OXIDE_DEVICE_ARCH`, else sm_80. Because both sides read the same two variables through the same function, the cfg floor and the selected target cannot disagree. The hint is read with the `DeviceArch` grammar the backend validates it with; one that does not parse is left out, because the backend rejects it before selecting a target. A named target that does not parse fails the build instead of falling back: guessing high emits instructions the target cannot run, guessing low silently drops the faster form. Rust has no specialization, so the reduction reaches a form that exists for only some `(Op, T)` pairs through a provided `ReduceOp::reduce_full_warp` hook, `None` by default. Nine integer pairs override it under the Ampere rung; `f32` keeps the butterfly, since there is no `f32` `redux` before sm_100. Only `N == 32` consults it, leaving the sub-warp path and its out-of-tile lane substitution untouched. One behaviour change: with no explicit target the floor is sm_80, so an integer `warp_reduce` now emits `redux.sync` and its module requires Ampere. Building with `--arch sm_75` keeps the portable form. The `warp_reduce` rustdoc and the warp-level-programming chapter both said this selection did not happen and pointed at this issue; both now describe what it does. Adding the build-dependency puts the first `cuda-device` -> `cuda-target-spec` edge in the graph, and `cuda-device` is in every kernel crate's. So 257 example and model locks, the SIMT workspace lock and two test-fixture locks each gain that one line; `check-example-license-policy.sh` and `check-device-only-build.sh` fail on a stale lock, so the churn is mandatory rather than cosmetic. No version moves. Three of the example locks (`inline_intent` and the two `error_union_shared_pointer_*`) also gain the `cuda-host` -> `cuda-device` edge they lack on main, because cargo rewrites the whole resolution; #1667 adds the same line. A build-dependency reaches only the host side of the build, so no kernel graph changes. The floor is a lower bound on target selection, and the backend now enforces it. It did not before: `resolve_sm_floor` was consulted only by the build script, so with nothing pinned the ladder advertised sm_80 while a module whose features need only sm_75 -- `ldmatrix` alone -- was built for sm_75, below the capability device code had been compiled against. Both resolvers, native PTX and NVVM, now raise such a selection to the floor, which every architecture at or above it can host. A floor that cannot host the module at all is reported rather than resolved to something else; no path reaches that today, and it is there so a future floor cannot select an architecture family silently. The hint rule is the other half, and it is a correction to the design sketched on the issue. A detected device cannot raise the floor. `CUDA_OXIDE_DEVICE_ARCH` is advisory by contract -- the backend "builds for the detected GPU only when that GPU can actually run the kernel", and otherwise for the arch the kernel requires -- so it says nothing about how high selection will go: a detected sm_120 with a WGMMA module lands on sm_90a, and a floor of 120 taken from it would be a bound the backend is documented to break. What the hint does bound is how low selection may go, since a device that can run the kernel is selected as-is. So it lowers the floor and never raises it: running on Turing still produces sm_75 rather than PTX that device cannot load, and device code is told it has only the rungs that PTX will have. One behaviour change falls out, stated because it reaches builds that never use this cfg: with nothing pinned, a module whose features ask only for sm_75 is now built for sm_80. That is the documented Ampere+ minimum and the same default a featureless module already got; `--arch sm_75` still selects sm_75. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- cuda-oxide/Cargo.lock | 1 + cuda-oxide/crates/cuda-device/Cargo.toml | 6 + cuda-oxide/crates/cuda-device/build.rs | 58 ++++++ .../cuda-device/src/cooperative_groups.rs | 186 +++++++++++++++++- .../cuda-macros/tests/device-only/Cargo.lock | 5 + .../crates/cuda-oxide-codegen/src/export.rs | 28 ++- .../cuda-oxide-codegen/src/target/mod.rs | 4 +- .../cuda-oxide-codegen/src/target/select.rs | 55 +++++- .../src/target/tests/detection_matrix.rs | 20 +- .../src/target/tests/selection.rs | 147 ++++++++++++++ cuda-oxide/crates/cuda-target-spec/src/lib.rs | 161 +++++++++++++++ .../examples/abi_hmm/Cargo.lock | 1 + .../examples/addressof_sharedarray/Cargo.lock | 1 + .../examples/aligned_field_loads/Cargo.lock | 1 + .../examples/aligned_field_stores/Cargo.lock | 1 + .../examples/array_constants/Cargo.lock | 1 + .../examples/array_for_loop/Cargo.lock | 1 + .../examples/array_index/Cargo.lock | 1 + .../examples/array_init/Cargo.lock | 1 + .../examples/asin_acos_smoke/Cargo.lock | 1 + .../assume_init_uninhabited_trap/Cargo.lock | 1 + .../examples/async_mlp/Cargo.lock | 1 + .../examples/async_vecadd/Cargo.lock | 1 + .../examples/atomic_f16/Cargo.lock | 1 + .../examples/atomics/Cargo.lock | 1 + .../examples/barrier/Cargo.lock | 1 + .../examples/bf16x2_arith/Cargo.lock | 1 + .../examples/bf16x2_fma/Cargo.lock | 1 + .../examples/bool_phi_cmp/Cargo.lock | 1 + .../examples/carrying_mul_add/Cargo.lock | 1 + .../examples/cast_chunks/Cargo.lock | 1 + .../examples/cast_tests/Cargo.lock | 1 + .../examples/cbrt_smoke/Cargo.lock | 1 + .../examples/checked_arith/Cargo.lock | 1 + .../examples/clc/Cargo.lock | 1 + .../examples/cluster/Cargo.lock | 1 + .../examples/compiler_features/Cargo.lock | 1 + .../examples/complex_mul/Cargo.lock | 1 + .../examples/const_aggregate/Cargo.lock | 1 + .../const_bool_dead_branch/Cargo.lock | 1 + .../examples/const_generic/Cargo.lock | 1 + .../examples/const_table_lookup/Cargo.lock | 1 + .../const_tuple_table_lookup/Cargo.lock | 1 + .../constant_index_from_end/Cargo.lock | 1 + .../examples/constant_memory/Cargo.lock | 1 + .../constant_memory_coeffs/Cargo.lock | 1 + .../constant_memory_simple/Cargo.lock | 1 + .../examples/constant_memory_table/Cargo.lock | 1 + .../examples/coop_groups_demo/Cargo.lock | 1 + .../examples/coop_groups_u64/Cargo.lock | 1 + .../examples/copy_aggregate_borrow/Cargo.lock | 1 + .../examples/copy_nonoverlapping/Cargo.lock | 1 + .../examples/counted_barrier/Cargo.lock | 1 + .../examples/cp_async_small/Cargo.lock | 1 + .../examples/cp_async_zfill/Cargo.lock | 1 + .../cpp_consumes_rust_device/Cargo.lock | 1 + .../examples/cross_crate_embedded/Cargo.lock | 1 + .../examples/cross_crate_kernel/Cargo.lock | 1 + .../cross_crate_merged_symbols/Cargo.lock | 1 + .../examples/cross_crate_recursion/Cargo.lock | 1 + .../examples/cuda_module_contract/Cargo.lock | 1 + .../examples/cuda_module_in_lib/Cargo.lock | 1 + .../examples/cuda_module_nested/Cargo.lock | 1 + .../cutile_inter_kernel/simt/Cargo.lock | 1 + .../examples/cvt_f16x2/Cargo.lock | 1 + .../examples/cvt_packed/Cargo.lock | 1 + .../examples/debug-tests/Cargo.lock | 1 + .../examples/debug/Cargo.lock | 1 + .../examples/debug_pointer_locals/Cargo.lock | 1 + .../examples/device_closures/Cargo.lock | 1 + .../examples/device_ffi_test/Cargo.lock | 1 + .../examples/device_global/Cargo.lock | 1 + .../examples/device_panic_trap/Cargo.lock | 1 + .../disjoint_from_raw_parts/Cargo.lock | 1 + .../examples/disjoint_slice_len/Cargo.lock | 1 + .../examples/dotprod/Cargo.lock | 1 + .../examples/dpx_minmax_chains/Cargo.lock | 1 + .../examples/drop_glue/Cargo.lock | 1 + .../examples/dst_metadata/Cargo.lock | 1 + .../examples/dynamic_smem/Cargo.lock | 1 + .../examples/elect_leader/Cargo.lock | 1 + .../enum_abi_multi_payload/Cargo.lock | 1 + .../examples/enum_array_match/Cargo.lock | 1 + .../enum_constant_provenance/Cargo.lock | 1 + .../examples/enum_payload_addr/Cargo.lock | 1 + .../enum_state_transitions/Cargo.lock | 1 + .../examples/enum_table_lookup/Cargo.lock | 1 + .../examples/error/Cargo.lock | 1 + .../error_enum_bool_payload_addr/Cargo.lock | 1 + .../error_enum_pointer_overlap/Cargo.lock | 1 + .../Cargo.lock | 1 + .../error_generated_intrinsic_abi/Cargo.lock | 1 + .../Cargo.lock | 1 + .../Cargo.lock | 1 + .../Cargo.lock | 1 + .../examples/error_heap_alloc/Cargo.lock | 1 + .../error_host_arch_intrinsic/Cargo.lock | 1 + .../error_host_target_feature/Cargo.lock | 1 + .../error_kernel_shared_param/Cargo.lock | 1 + .../error_missing_device_attr/Cargo.lock | 1 + .../Cargo.lock | 1 + .../Cargo.lock | 2 + .../Cargo.lock | 2 + .../examples/ex2_approx_f16/Cargo.lock | 1 + .../examples/exact_div_chunks/Cargo.lock | 1 + .../examples/export_name_policy/Cargo.lock | 1 + .../examples/extern_crate_closure/Cargo.lock | 1 + .../examples/extern_libdevice/Cargo.lock | 1 + .../examples/f16_stress/Cargo.lock | 1 + .../examples/f16x2_arith/Cargo.lock | 1 + .../examples/f32x2_arith/Cargo.lock | 1 + .../examples/fcmp_ne_nan_smoke/Cargo.lock | 1 + .../examples/field_array_assign/Cargo.lock | 1 + .../examples/float_rounding/Cargo.lock | 1 + .../examples/fmaxmin_smoke/Cargo.lock | 1 + .../examples/fn_ptr_naming/Cargo.lock | 1 + .../fp_special_literal_smoke/Cargo.lock | 1 + .../examples/function_item_call/Cargo.lock | 1 + .../examples/future_apis/Cargo.lock | 1 + .../examples/gemm/Cargo.lock | 1 + .../examples/gemm_sol/Cargo.lock | 1 + .../examples/gemm_sol_final/Cargo.lock | 1 + .../examples/gemm_views/Cargo.lock | 1 + .../examples/generated_intrinsics/Cargo.lock | 1 + .../generated_intrinsics_blackwell/Cargo.lock | 1 + .../examples/generated_ldmatrix/Cargo.lock | 1 + .../examples/generic/Cargo.lock | 1 + .../examples/hashmap/Cargo.lock | 1 + .../examples/hashmap_v2/Cargo.lock | 1 + .../examples/hashmap_v3/Cargo.lock | 1 + .../examples/hello_constant/Cargo.lock | 1 + .../examples/helper_fn/Cargo.lock | 1 + .../examples/host_closure/Cargo.lock | 1 + .../host_closure_target_feature/Cargo.lock | 1 + .../examples/iket_trace/Cargo.lock | 1 + .../examples/image_convolution/Cargo.lock | 1 + .../examples/index2d_const/Cargo.lock | 1 + .../examples/index_field_assign/Cargo.lock | 1 + .../examples/inline_intent/Cargo.lock | 2 + .../examples/inline_ptx/Cargo.lock | 1 + .../examples/integer_minmax/Cargo.lock | 1 + .../examples/interior_mutability/Cargo.lock | 1 + .../interop_cubin_identity/device/Cargo.lock | 1 + .../kernel_reference_validity/Cargo.lock | 1 + .../examples/lanemask_scan/Cargo.lock | 1 + .../examples/legacy_atomic_fadd/Cargo.lock | 1 + .../examples/legacy_atomic_rmw_cas/Cargo.lock | 1 + .../legacy_nvvm_pointer_shapes/Cargo.lock | 1 + .../examples/libdevice_math/Cargo.lock | 1 + .../examples/libm_math/Cargo.lock | 1 + .../examples/manual_launch_generic/Cargo.lock | 1 + .../manual_launch_libdevice/Cargo.lock | 1 + .../examples/map_sum/Cargo.lock | 1 + .../examples/math_atan/Cargo.lock | 1 + .../examples/math_hyperbolic/Cargo.lock | 1 + .../examples/math_no_mir_inline/Cargo.lock | 1 + .../examples/math_special/Cargo.lock | 1 + .../examples/math_tan/Cargo.lock | 1 + .../examples/mathdx_ffi_test/Cargo.lock | 1 + .../examples/mcast_barrier_test/Cargo.lock | 1 + .../examples/mem_swap/Cargo.lock | 1 + .../mir_projected_call_destination/Cargo.lock | 1 + .../examples/mma_mxf8f6f4/Cargo.lock | 1 + .../examples/ne_bytes_transmute/Cargo.lock | 1 + .../nested_index_assignment/Cargo.lock | 1 + .../examples/nounroll/Cargo.lock | 1 + .../examples/numeric_stress/Cargo.lock | 1 + .../examples/nvls_all_reduce/Cargo.lock | 1 + .../examples/option_ref_transmute/Cargo.lock | 1 + .../examples/option_ref_unwrap_or/Cargo.lock | 1 + .../examples/option_unwrap_trap/Cargo.lock | 1 + .../examples/ord_cmp/Cargo.lock | 1 + .../examples/packed_aggregate_abi/Cargo.lock | 1 + .../examples/packed_atomic_add/Cargo.lock | 1 + .../examples/padded_constants/Cargo.lock | 1 + .../examples/partial_warp_reduce/Cargo.lock | 1 + .../examples/pinned_overlap/Cargo.lock | 1 + .../examples/place_read_fallbacks/Cargo.lock | 1 + .../examples/policy_config/Cargo.lock | 1 + .../examples/primitive_stress/Cargo.lock | 1 + .../examples/printf/Cargo.lock | 1 + .../examples/projected_place_read/Cargo.lock | 1 + .../examples/proof_carrying_views/Cargo.lock | 1 + .../examples/ptr_copy/Cargo.lock | 1 + .../examples/ptr_offset_from/Cargo.lock | 1 + .../ptr_without_provenance/Cargo.lock | 1 + .../examples/reborrow/Cargo.lock | 1 + .../examples/redux_f32/Cargo.lock | 1 + .../examples/redux_minmax/Cargo.lock | 1 + .../examples/redux_sum/Cargo.lock | 1 + .../examples/ref_index_projections/Cargo.lock | 1 + .../examples/ref_operand_mul/Cargo.lock | 1 + .../examples/repr_align_block_args/Cargo.lock | 1 + .../examples/repr_transparent_abi/Cargo.lock | 1 + .../examples/repr_u32_enum_stride/Cargo.lock | 1 + .../examples/row_width_slice/Cargo.lock | 1 + .../examples/rustlantis-smoke/Cargo.lock | 1 + .../scoped_atomic_load_store/Cargo.lock | 1 + .../examples/select_unpredictable/Cargo.lock | 1 + .../examples/set_discriminant/Cargo.lock | 1 + .../set_discriminant_niche/Cargo.lock | 1 + .../examples/shared_debug/Cargo.lock | 1 + .../examples/shared_memory_helper/Cargo.lock | 1 + .../examples/shared_ptr_transmute/Cargo.lock | 1 + .../examples/shared_slice_unsize/Cargo.lock | 1 + .../examples/shared_stage_select/Cargo.lock | 1 + .../examples/sharedmem/Cargo.lock | 1 + .../examples/shuffle_64/Cargo.lock | 1 + .../slice_from_raw_parts_cast/Cargo.lock | 1 + .../examples/slice_get_mut/Cargo.lock | 1 + .../slice_index_bounds_check/Cargo.lock | 1 + .../examples/slice_iterators/Cargo.lock | 1 + .../examples/slice_reslice/Cargo.lock | 1 + .../examples/small_type_ffi_test/Cargo.lock | 1 + .../examples/sparse_mma_fp8/Cargo.lock | 1 + .../sparse_mma_ordered_float/Cargo.lock | 1 + .../examples/split_at_mut/Cargo.lock | 1 + .../examples/standalone_device_fn/Cargo.lock | 1 + .../examples/static_slice_addend/Cargo.lock | 1 + .../examples/static_slice_unsize/Cargo.lock | 1 + .../examples/step_by/Cargo.lock | 1 + .../struct_constant_provenance/Cargo.lock | 1 + .../examples/struct_field_layout/Cargo.lock | 1 + .../examples/subslice_projection/Cargo.lock | 1 + .../examples/switchint_128bit/Cargo.lock | 1 + .../examples/swizzle_smem/Cargo.lock | 1 + .../examples/tcgen05/Cargo.lock | 1 + .../examples/tcgen05_matmul/Cargo.lock | 1 + .../examples/thread_runs/Cargo.lock | 1 + .../examples/tiled_gemm/Cargo.lock | 1 + .../examples/tilelib_relu/Cargo.lock | 1 + .../examples/tma_copy/Cargo.lock | 1 + .../examples/tma_multicast/Cargo.lock | 1 + .../toolchain_pairing_smoke/Cargo.lock | 1 + .../transmute_scalar_struct/Cargo.lock | 1 + .../tuple_array_provenance/Cargo.lock | 1 + .../tuple_constant_provenance/Cargo.lock | 1 + .../examples/tuple_field_lookup/Cargo.lock | 1 + .../examples/tuple_return/Cargo.lock | 1 + .../examples/unaligned_memory/Cargo.lock | 1 + .../examples/unchecked_indexing/Cargo.lock | 1 + .../examples/uninit_const/Cargo.lock | 1 + .../examples/union_aggregate/Cargo.lock | 1 + .../examples/unroll_bounds_check/Cargo.lock | 1 + .../examples/unroll_smoke/Cargo.lock | 1 + .../examples/vecadd/Cargo.lock | 1 + .../examples/vectorization/Cargo.lock | 1 + .../examples/volatile_memory/Cargo.lock | 1 + .../examples/warp_reduce/Cargo.lock | 1 + .../examples/warp_sums/Cargo.lock | 1 + .../examples/wgmma/Cargo.lock | 1 + .../examples/wgmma_mma_bf16/Cargo.lock | 1 + .../primitives_api_compile/Cargo.lock | 1 + .../advanced/warp-level-programming.md | 15 +- .../examples/blockscale_gemm_ctm/Cargo.lock | 1 + .../examples/blockscale_gemm_cute/Cargo.lock | 1 + .../examples/elementwise_cute/Cargo.lock | 1 + .../examples/ffn_cute/Cargo.lock | 1 + .../fmha_decode_sm120a_cute/Cargo.lock | 1 + .../fmha_prefill_sm120a_cute/Cargo.lock | 1 + .../examples/fp16_gemm_256x352_ctm/Cargo.lock | 1 + .../fp16_gemm_256x352_cute/Cargo.lock | 1 + .../examples/nvfp4_gemv_cute/Cargo.lock | 1 + .../examples/rmsnorm_cute/Cargo.lock | 1 + .../examples/rope_cache_cute/Cargo.lock | 1 + .../sm100_fmha_prefill_cute/Cargo.lock | 1 + .../sm100_mla_decode_fp16_cute/Cargo.lock | 1 + .../examples/swiglu_cute/Cargo.lock | 1 + .../models/qwen3_8b_cute/Cargo.lock | 1 + .../models/qwen_decoder_cute/Cargo.lock | 1 + 270 files changed, 931 insertions(+), 16 deletions(-) create mode 100644 cuda-oxide/crates/cuda-device/build.rs diff --git a/cuda-oxide/Cargo.lock b/cuda-oxide/Cargo.lock index adf2d64339..091f8c7fd5 100644 --- a/cuda-oxide/Cargo.lock +++ b/cuda-oxide/Cargo.lock @@ -434,6 +434,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", "trybuild", ] diff --git a/cuda-oxide/crates/cuda-device/Cargo.toml b/cuda-oxide/crates/cuda-device/Cargo.toml index 00c2a1b1f0..14145ee9a4 100644 --- a/cuda-oxide/crates/cuda-device/Cargo.toml +++ b/cuda-oxide/crates/cuda-device/Cargo.toml @@ -16,6 +16,12 @@ readme = "README.md" # `host` explicitly, so any build that loads or launches a module still has it. cuda-macros = { workspace = true } +[build-dependencies] +# Shares one arch parser and one floor rule with the backend, so the cfg +# ladder cannot drift from the target the PTX is actually built for. This +# crate has no dependencies of its own, so it costs the kernel graph nothing. +cuda-target-spec = { workspace = true } + [dev-dependencies] trybuild = "1" diff --git a/cuda-oxide/crates/cuda-device/build.rs b/cuda-oxide/crates/cuda-device/build.rs new file mode 100644 index 0000000000..34141176d1 --- /dev/null +++ b/cuda-oxide/crates/cuda-device/build.rs @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +//! Expose the compute-capability floor to device code as `cfg`s. +//! +//! Device code has no way to ask what target it is being compiled for, so an +//! API with a faster form on newer hardware -- `redux.sync` in place of a +//! shuffle tree, for one -- either always pays for the portable form or asks +//! every caller to gate the choice by hand. A `cfg` is decided before rustc +//! runs, so rustc drops the branch that does not apply and the requirement +//! scan never sees an instruction the target cannot run. +//! +//! Because a `cfg` is fixed before compilation it can only carry a *lower* +//! bound: the floor is the lowest capability the resulting PTX will be built +//! for, never the exact device. `CUDA_OXIDE_TARGET` sets it exactly, since +//! that is what gets built. `CUDA_OXIDE_DEVICE_ARCH` can only lower it: the +//! backend builds for the detected device when that device can run the kernel +//! and otherwise for the arch the kernel requires, so it bounds how low +//! selection may go, not how high. The rule lives in `cuda-target-spec` and is +//! shared with the backend's own target selection rather than restated here, +//! so the two cannot disagree about what the floor is. + +fn main() { + // The two variables the backend already reads to pick a target. + println!("cargo::rerun-if-env-changed=CUDA_OXIDE_TARGET"); + println!("cargo::rerun-if-env-changed=CUDA_OXIDE_DEVICE_ARCH"); + + // Declare the whole ladder, not just the rungs set for this build, so an + // unset rung is a false `cfg` rather than an `unexpected_cfgs` warning. + let values = cuda_target_spec::SM_FLOOR_LADDER + .iter() + .map(|floor| format!("\"{floor}\"")) + .collect::>() + .join(", "); + println!("cargo::rustc-check-cfg=cfg(cuda_oxide_sm_at_least, values({values}))"); + + let target = std::env::var("CUDA_OXIDE_TARGET").ok(); + // Read the hint with the backend's grammar. One that does not parse is + // left out: the backend rejects it, so nothing is built against it. + let device_arch = std::env::var("CUDA_OXIDE_DEVICE_ARCH") + .ok() + .and_then(|value| value.parse::().ok()); + match cuda_target_spec::resolve_sm_floor( + target.as_deref(), + device_arch.as_ref().map(AsRef::as_ref), + ) { + Ok(floor) => { + for rung in cuda_target_spec::sm_floors_at_most(floor) { + println!("cargo::rustc-cfg=cuda_oxide_sm_at_least=\"{rung}\""); + } + } + // Fail the build rather than guess. Guessing high emits instructions + // the target cannot run; guessing low silently drops the faster form. + Err(error) => println!("cargo::error={error}"), + } +} diff --git a/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs b/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs index c6c1de84a3..b441c7bed3 100644 --- a/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs +++ b/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs @@ -909,6 +909,68 @@ pub mod ops { fn identity() -> T; /// Binary combiner. Must be associative and commutative. fn combine(a: T, b: T) -> T; + + /// Whether this `(Op, T)` pair reduces a full warp in one instruction + /// on the target being compiled for. + /// + /// `false` by default, which is what keeps the choice sound: an + /// operation with no single-instruction form, and every operation at + /// all when the floor is below `sm_80`, falls through to the + /// butterfly. Rust has no specialization, so this pair of items is how + /// a reduction generic over `T` and `Op` reaches a form that exists + /// for only some pairs. + /// + /// A `const` rather than an `Option` return, and not for style: an + /// `Option` crossing this boundary is an enum with a signed + /// payload, which device lowering rejects with `enum payload storage + /// type mismatch: si32 cannot be adapted to i32`. A `const` leaves no + /// enum to lower and folds the branch before codegen. + const HAS_FULL_WARP_FORM: bool = false; + + /// The whole full-warp reduction as one instruction. + /// + /// Only reached when [`Self::HAS_FULL_WARP_FORM`] is true, so the + /// default is unreachable. It returns the input rather than panicking + /// because a device panic would pull formatting machinery into every + /// kernel that instantiates it. + /// + /// `mask` is the tile's participation mask. Only + /// [`super::warp_reduce`] calls this, and only at `N == 32`, where + /// that mask is `u32::MAX`. + #[inline(always)] + fn reduce_full_warp(_mask: u32, value: T) -> T { + value + } + } + + /// Give one integer `(Op, T)` pair its `redux.sync` form. + /// + /// The `cfg` is what makes this safe to write unconditionally: below the + /// Ampere floor the body is not compiled at all, so `redux.sync` never + /// reaches the requirement scan and cannot raise a module's target. + macro_rules! redux_full_warp { + ($ty:ty, |$mask:ident, $value:ident| $call:expr) => { + const HAS_FULL_WARP_FORM: bool = cfg!(cuda_oxide_sm_at_least = "80"); + + // Two whole definitions rather than one body with a `cfg` inside: + // the body has to be a single expression that hands back the + // intrinsic's result, which is the shape `WarpShuffle::shfl_xor_via` + // already uses for the shuffle stubs. Wrapping the call in a block + // bound to a local instead makes device lowering reject the + // function with `ReturnOp operand type does not match the + // function's result type`. + #[cfg(cuda_oxide_sm_at_least = "80")] + #[inline(always)] + fn reduce_full_warp($mask: u32, $value: $ty) -> $ty { + $call + } + + #[cfg(not(cuda_oxide_sm_at_least = "80"))] + #[inline(always)] + fn reduce_full_warp(_mask: u32, value: $ty) -> $ty { + value + } + }; } /// Sum: wrapping integer addition; IEEE-754 add for floats. @@ -945,6 +1007,7 @@ pub mod ops { fn combine(a: u32, b: u32) -> u32 { a.wrapping_add(b) } + redux_full_warp!(u32, |m, v| crate::warp::redux_sync_add(m, v)); } impl ReduceOp for Min { #[inline(always)] @@ -955,6 +1018,7 @@ pub mod ops { fn combine(a: u32, b: u32) -> u32 { if a < b { a } else { b } } + redux_full_warp!(u32, |m, v| crate::warp::redux_sync_min_u32(m, v)); } impl ReduceOp for Max { #[inline(always)] @@ -965,6 +1029,7 @@ pub mod ops { fn combine(a: u32, b: u32) -> u32 { if a > b { a } else { b } } + redux_full_warp!(u32, |m, v| crate::warp::redux_sync_max_u32(m, v)); } impl ReduceOp for BitAnd { #[inline(always)] @@ -975,6 +1040,7 @@ pub mod ops { fn combine(a: u32, b: u32) -> u32 { a & b } + redux_full_warp!(u32, |m, v| crate::warp::redux_sync_and(m, v)); } impl ReduceOp for BitOr { #[inline(always)] @@ -985,6 +1051,7 @@ pub mod ops { fn combine(a: u32, b: u32) -> u32 { a | b } + redux_full_warp!(u32, |m, v| crate::warp::redux_sync_or(m, v)); } impl ReduceOp for BitXor { #[inline(always)] @@ -995,6 +1062,7 @@ pub mod ops { fn combine(a: u32, b: u32) -> u32 { a ^ b } + redux_full_warp!(u32, |m, v| crate::warp::redux_sync_xor(m, v)); } // --- i32 --- @@ -1007,6 +1075,7 @@ pub mod ops { fn combine(a: i32, b: i32) -> i32 { a.wrapping_add(b) } + redux_full_warp!(i32, |m, v| crate::warp::redux_sync_add(m, v as u32) as i32); } impl ReduceOp for Min { #[inline(always)] @@ -1017,6 +1086,7 @@ pub mod ops { fn combine(a: i32, b: i32) -> i32 { if a < b { a } else { b } } + redux_full_warp!(i32, |m, v| crate::warp::redux_sync_min_i32(m, v)); } impl ReduceOp for Max { #[inline(always)] @@ -1027,6 +1097,7 @@ pub mod ops { fn combine(a: i32, b: i32) -> i32 { if a > b { a } else { b } } + redux_full_warp!(i32, |m, v| crate::warp::redux_sync_max_i32(m, v)); } // --- f32 --- @@ -1256,13 +1327,25 @@ impl WarpShuffle for i64 { /// bit-identical results. That is the primitive in isolation — a kernel that /// reduces once after a memory-bound pass will see far less. /// -/// This function does not select that form for you: `redux.sync` will not -/// assemble below `sm_80`, and device code has no way to ask what target it is -/// being compiled for (see -/// [#811](https://github.com/NVlabs/cuda-oxide/issues/811)). Call it directly -/// when you know the target is Ampere+, gating on -/// `CudaContext::compute_capability` as the `redux_sum` example does. Floats -/// keep this butterfly — there is no `f32` `redux` before `sm_100`. +/// **This function now selects that form for you**, for integer `T` on a full +/// warp (`N == 32`), whenever the compiled-for floor is `sm_80` or newer. +/// `cuda-device`'s build script derives that floor from the same environment +/// the backend reads to pick a target — `CUDA_OXIDE_TARGET`, else +/// `CUDA_OXIDE_DEVICE_ARCH`, else `sm_80` — and exposes it as the +/// `cuda_oxide_sm_at_least` cfg. Because a cfg is decided before rustc runs, +/// the branch that does not apply is dropped before MIR exists, so a target +/// below the floor never sees a `redux.sync` it cannot assemble. +/// +/// Three things keep the butterfly, all of them for a reason rather than an +/// omission: floats (there is no `f32` `redux` before `sm_100`), sub-warp +/// tiles (`redux.sync` reduces over whatever lanes are in `membermask`, but +/// the sub-warp wrapper's out-of-tile lane substitution needs its own check +/// first), and any build whose floor is below `sm_80`. +/// +/// One consequence worth knowing: with no explicit target the floor is +/// `sm_80`, so an integer `warp_reduce` emits `redux.sync` and the module +/// requires Ampere. Build with `--arch sm_75` (or `CUDA_OXIDE_TARGET=sm_75`) +/// to keep the portable form. /// /// `N` is the tile size (1, 2, 4, 8, 16, or 32) — already validated by /// [`ThreadBlock::tiled_partition`] at construction time. @@ -1290,6 +1373,14 @@ where T: WarpShuffle, Op: ops::ReduceOp, { + // A full warp with a one-instruction form takes it. `N` is a const + // generic and `reduce_full_warp` is `None` at compile time for every pair + // without one, so this collapses to the butterfly with nothing left + // behind for the sub-warp and float paths. + if N == 32 && Op::HAS_FULL_WARP_FORM { + return Op::reduce_full_warp(tile.mask(), value); + } + let mut acc = value; let mut delta: u32 = N >> 1; while delta > 0 { @@ -1748,6 +1839,7 @@ where #[cfg(test)] mod tests { use super::CoalescedThreads; + use super::ops::{BitAnd, BitOr, BitXor, Max, Min, ReduceOp, Sum}; #[test] fn pack_lanes_uses_group_relative_bit_positions() { @@ -1774,4 +1866,84 @@ mod tests { ); } } + + /// Every integer pair `warp_reduce` can be asked for, and whether the + /// Ampere rung should give it a single-instruction form. + /// + /// A `const` hook makes this checkable from the host with no device call, + /// which matters because the crate is `no_std` and the `redux_sync_*` + /// stubs are device functions. + const INTEGER_PAIRS: [(&str, bool); 9] = [ + ("u32 Sum", >::HAS_FULL_WARP_FORM), + ("u32 Min", >::HAS_FULL_WARP_FORM), + ("u32 Max", >::HAS_FULL_WARP_FORM), + ("u32 BitAnd", >::HAS_FULL_WARP_FORM), + ("u32 BitOr", >::HAS_FULL_WARP_FORM), + ("u32 BitXor", >::HAS_FULL_WARP_FORM), + ("i32 Sum", >::HAS_FULL_WARP_FORM), + ("i32 Min", >::HAS_FULL_WARP_FORM), + ("i32 Max", >::HAS_FULL_WARP_FORM), + ]; + + /// All nine are wired, not just the one that happened to get tested. + #[cfg(cuda_oxide_sm_at_least = "80")] + #[test] + fn every_integer_reduction_has_the_single_instruction_form_at_the_ampere_floor() { + for (name, wired) in INTEGER_PAIRS { + assert!(wired, "{name} lost its redux.sync form"); + } + } + + /// Below the floor every one of them goes dark, so nothing can emit + /// `redux.sync` into a module that cannot assemble it. + #[cfg(not(cuda_oxide_sm_at_least = "80"))] + #[test] + fn no_integer_reduction_claims_the_form_below_the_ampere_floor() { + for (name, wired) in INTEGER_PAIRS { + assert!(!wired, "{name} claims redux.sync below sm_80"); + } + } + + /// There is no `f32` `redux` before `sm_100`, so floats keep the butterfly + /// at every floor. The control a broadened hook would break: claiming the + /// form here would name an instruction that does not exist for the type. + #[test] + fn floats_never_claim_the_single_instruction_form() { + // `const` blocks: these are compile-time facts, so a regression is a + // build failure rather than a test failure. + const { + assert!(!>::HAS_FULL_WARP_FORM); + assert!(!>::HAS_FULL_WARP_FORM); + assert!(!>::HAS_FULL_WARP_FORM); + } + } + + /// The default hook must stay inert: it is reached only when the `const` + /// is false, and must not be mistaken for a reduction. + #[test] + fn the_default_hook_is_the_identity_on_its_input() { + assert_eq!(>::reduce_full_warp(u32::MAX, 3.5), 3.5); + } + + /// The build script sets every rung at or below the resolved capability, + /// and device code relies on that: an `sm_86` build must still answer yes + /// to "at least sm_80". + #[test] + fn the_floor_ladder_reaching_this_crate_is_cumulative() { + let rungs = [ + cfg!(cuda_oxide_sm_at_least = "70"), + cfg!(cuda_oxide_sm_at_least = "75"), + cfg!(cuda_oxide_sm_at_least = "80"), + cfg!(cuda_oxide_sm_at_least = "86"), + cfg!(cuda_oxide_sm_at_least = "90"), + cfg!(cuda_oxide_sm_at_least = "100"), + cfg!(cuda_oxide_sm_at_least = "120"), + ]; + // Once false, every higher rung is false: no gaps in the ladder. + let first_unset = rungs.iter().position(|set| !set).unwrap_or(rungs.len()); + assert!( + rungs[first_unset..].iter().all(|set| !set), + "floor ladder has a gap: {rungs:?}" + ); + } } 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..ed8b75b3fc 100644 --- a/cuda-oxide/crates/cuda-macros/tests/device-only/Cargo.lock +++ b/cuda-oxide/crates/cuda-macros/tests/device-only/Cargo.lock @@ -7,6 +7,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] @@ -20,6 +21,10 @@ dependencies = [ "syn 2.0.119", ] +[[package]] +name = "cuda-target-spec" +version = "0.1.0" + [[package]] name = "device-only-kernels" version = "0.0.0" diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs index 12fe5ecda2..7a4311db1c 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs @@ -7,8 +7,10 @@ use crate::error::PipelineError; use crate::generated::GeneratedModuleRequirements; use crate::target::{ DetectedFeatures, arch_satisfies, generated_ptx_isa_requirement, generated_target_satisfied, - select_target_with_generated, validate_generated_target, validate_target_features, + honour_sm_floor, select_target_with_generated, validate_generated_target, + validate_target_features, }; +use cuda_target_spec::resolve_sm_floor; use libnvvm_sys::CudaArch; use llvm_export::export::{ DebugKind, DeviceExternType, ExportBackendConfig, FunctionLocalStaticPlacement, NvvmIrDialect, @@ -82,6 +84,21 @@ impl llvm_export::export::AsDeviceExtern for DeviceExternDecl { } } +/// The floor device code was compiled against, for the paths where selection +/// is free to choose. Those are reached only without an explicit target, so +/// only the detected-device hint can move it -- downwards, per +/// [`resolve_sm_floor`]. Taken from that one function rather than written out, +/// so `cuda-device`'s `cuda_oxide_sm_at_least` ladder and the target selected +/// here have a single definition between them. +fn sm_floor_for_selection(device_arch_hint: Option<&CudaArch>) -> Result { + resolve_sm_floor(None, device_arch_hint).map_err(|error| PipelineError::TargetSelection { + target: String::new(), + reason: format!( + "cannot resolve the compute-capability floor device code is compiled against: {error}" + ), + }) +} + // mir-importer pipeline plumbing; not part of the frontend contract. #[doc(hidden)] #[cfg(test)] @@ -153,6 +170,12 @@ pub(crate) fn resolve_nvvm_target_with_generated( } let target = select_target_with_generated(features, generated).map_err(PipelineError::Export)?; + // No explicit target reaches here, so this is the shared default + // floor; it is resolved rather than restated so the ladder device + // code was built against and the target selected here cannot drift. + let floor = sm_floor_for_selection(device_arch_hint)?; + let target = + honour_sm_floor(target, floor, features, generated).map_err(PipelineError::Export)?; return Ok(target); } @@ -166,6 +189,9 @@ pub(crate) fn resolve_nvvm_target_with_generated( if !generated.is_empty() { let target = select_target_with_generated(DetectedFeatures::Basic, generated) .map_err(PipelineError::Export)?; + let floor = sm_floor_for_selection(device_arch_hint)?; + let target = honour_sm_floor(target, floor, DetectedFeatures::Basic, generated) + .map_err(PipelineError::Export)?; return Ok(target); } diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/mod.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/mod.rs index 97ce92d883..d77ba264fb 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/mod.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/mod.rs @@ -25,11 +25,11 @@ pub(crate) use generated_requirements::{ generated_ptx_isa_requirement, generated_target_satisfied, merge_generated_module_requirements, merge_generated_module_requirements_for_target, validate_generated_target, }; -pub use select::{required_ptx_feature, validate_target_features, validate_target_for_llvm_major}; pub(crate) use select::{ - resolve_ptx_target_with_generated, select_target_with_generated, + honour_sm_floor, resolve_ptx_target_with_generated, select_target_with_generated, validate_ptx_isa_for_llvm_major, }; +pub use select::{required_ptx_feature, validate_target_features, validate_target_for_llvm_major}; // The re-exports below preserve the module's pre-split surface. In-crate // consumers currently reach these names only from test code (or straight diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs index efee412907..5772bc963c 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs @@ -11,7 +11,7 @@ use super::generated_requirements::{ }; use crate::error::PipelineError; use crate::generated::GeneratedModuleRequirements; -use cuda_target_spec::{CudaArch, RECORDED_PTX_FLOORS, recorded_ptx_floor}; +use cuda_target_spec::{CudaArch, RECORDED_PTX_FLOORS, recorded_ptx_floor, resolve_sm_floor}; /// Select a concrete architecture that satisfies every detected feature. /// @@ -167,6 +167,46 @@ pub fn resolve_ptx_target( ) } +/// Raise a feature-selected target to the floor device code was compiled +/// against, or say why the two cannot both be satisfied. +/// +/// `cuda-device`'s build script fixes its `cuda_oxide_sm_at_least` ladder +/// before rustc runs, from the same [`resolve_sm_floor`] the callers below +/// use, so the two cannot drift. Selection then runs with something the build +/// script could not have: the module's own features. A module whose features +/// need less than the floor -- `ldmatrix` alone asks only for `sm_75` -- would +/// otherwise be built below the capability device code was told to assume. +/// +/// Raising is the repair whenever the floor can still run the module, which +/// is every case reachable today: the floor is only ever the default when +/// this is called, and every feature below it is forward compatible. The +/// error arm is not decoration -- it is what keeps a future floor from +/// silently selecting an architecture family that cannot host the module. +pub(crate) fn honour_sm_floor( + selected: CudaArch, + floor: u32, + features: DetectedFeatures, + generated: &GeneratedModuleRequirements, +) -> Result { + if selected.capability() >= floor { + return Ok(selected); + } + + let at_floor = CudaArch::new(floor, None).map_err(|error| { + format!("compute capability {floor} is not a CUDA target this compiler knows: {error}") + })?; + if arch_satisfies(&at_floor, features) && generated_target_satisfied(&at_floor, generated) { + return Ok(at_floor); + } + + Err(format!( + "device code is compiled against compute capability {floor} or newer, but this module's \ + features run only on {}, which that floor cannot host. Pin the architecture you mean to \ + build for with `--arch` (or CUDA_OXIDE_TARGET), so device code and the emitted PTX agree.", + selected.sm() + )) +} + pub(crate) fn resolve_ptx_target_with_generated( explicit_override: Option<&str>, explicit_override_source: &'static str, @@ -206,8 +246,21 @@ pub(crate) fn resolve_ptx_target_with_generated( return Ok((device.clone(), "detected GPU")); } + // Reached only with no explicit target, so only the detected-device hint + // can move the floor -- downwards. Resolved through the same function the + // build script uses rather than restated here. + let floor = resolve_sm_floor(explicit_override, device_hint).map_err(|error| { + PipelineError::TargetSelection { + target: String::new(), + reason: format!( + "cannot resolve the compute-capability floor device code is compiled against: {error}" + ), + } + })?; let target = select_target_with_generated(detected, generated).map_err(PipelineError::PtxGeneration)?; + let target = honour_sm_floor(target, floor, detected, generated) + .map_err(PipelineError::PtxGeneration)?; Ok((target, "feature requirement")) } diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_matrix.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_matrix.rs index 5ee2a970f1..036169666c 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_matrix.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/detection_matrix.rs @@ -1112,9 +1112,27 @@ fn m8n8k16_int8_mma_detection_applies_exact_sm75_and_ptx65_floors() { "{$0, $1}, {$4}, {$5}, {$2, $3};" ); let requirements = detect_module_requirements_in_llvm_text(representative); + // The feature's own floor is sm_75 and stays there. + assert_eq!( + select_target(requirements.features) + .expect("feature floor") + .sm(), + "sm_75" + ); + // Selection does not land below the capability device code was compiled + // against (#811). With nothing pinned that is the sm_80 default, which + // runs everything sm_75 does; pinning `--arch sm_75` selects sm_75. let (target, _) = resolve_ptx_target(None, "CUDA_OXIDE_TARGET", None, requirements.features) .expect("auto-resolve"); - assert_eq!(target.sm(), "sm_75"); + assert_eq!(target.sm(), "sm_80"); + let (pinned, _) = resolve_ptx_target( + Some("sm_75"), + "CUDA_OXIDE_TARGET", + None, + requirements.features, + ) + .expect("pinned"); + assert_eq!(pinned.sm(), "sm_75"); assert_eq!( required_ptx_feature(&"sm_75".parse().unwrap(), requirements.ptx_isa).unwrap(), Some("+ptx65") diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs index 54d0cc026f..e11bcfd9a7 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs @@ -518,3 +518,150 @@ fn malformed_low_width_targets_keep_override_errors() { assert_eq!(explicit.to_string(), expected_reason); } } + +/// The property `cuda-device`'s `cuda_oxide_sm_at_least` ladder depends on: +/// selection never lands below the floor device code was compiled against +/// (#811). +/// +/// The build script fixes that ladder before rustc runs, from the same +/// [`resolve_sm_floor`] both resolvers below consult, so this asserts the +/// property end to end rather than re-checking that one helper's table. Both +/// stages are covered because a module reaches PTX through one or the other. +#[test] +fn selection_never_lands_below_the_floor_device_code_assumes() { + let generated = crate::generated::GeneratedModuleRequirements::default(); + let [sm_75, sm_86, sm_120a] = ["sm_75", "sm_86", "sm_120a"] + .map(|raw| raw.parse::().unwrap()); + for explicit in [None, Some("sm_75"), Some("sm_86"), Some("sm_90a")] { + for hint in [None, Some(&sm_75), Some(&sm_86), Some(&sm_120a)] { + let floor = cuda_target_spec::resolve_sm_floor(explicit, hint.map(AsRef::as_ref)) + .expect("floor"); + for features in [ + DetectedFeatures::Basic, + DetectedFeatures::Ldmatrix, + DetectedFeatures::Movmatrix, + DetectedFeatures::Sm75, + DetectedFeatures::Sm80, + DetectedFeatures::Cluster, + DetectedFeatures::Wgmma, + ] { + // An explicit target that cannot host the module is rejected + // outright; that is the other half of the contract, asserted + // separately below. Only successful selections are bound. + if let Ok((target, source)) = + resolve_ptx_target(explicit, "CUDA_OXIDE_TARGET", hint, features) + { + assert!( + target.capability() >= floor, + "PTX: {features:?} with explicit={explicit:?} hint={hint:?} \ + selected {} (from {source}) below floor {floor}", + target.sm() + ); + } + if let Ok(target) = crate::export::resolve_nvvm_target_with_generated( + explicit, + hint, + Some(features), + &generated, + ) { + assert!( + target.capability() >= floor, + "NVVM: {features:?} with explicit={explicit:?} hint={hint:?} \ + selected {} below floor {floor}", + target.sm() + ); + } + } + } + } +} + +/// The two cases that motivated the floor, named so a regression says which. +#[test] +fn the_floor_is_honoured_without_overriding_a_runnable_device() { + let generated = crate::generated::GeneratedModuleRequirements::default(); + + // Nothing pinned: the ladder advertises the sm_80 default, so a module + // whose features only need sm_75 must not be built for sm_75. + let (ptx, _) = + resolve_ptx_target(None, "CUDA_OXIDE_TARGET", None, DetectedFeatures::Ldmatrix).unwrap(); + assert_eq!(ptx.sm(), "sm_80"); + let nvvm = crate::export::resolve_nvvm_target_with_generated( + None, + None, + Some(DetectedFeatures::Ldmatrix), + &generated, + ) + .unwrap(); + assert_eq!(nvvm.sm(), "sm_80"); + + // A detected Blackwell with a WGMMA module still selects sm_90a, because + // the hint cannot raise the floor: it is advisory, and this is exactly the + // case the backend is documented to build elsewhere for. + let blackwell = "sm_120a".parse::().unwrap(); + let (wgmma, _) = resolve_ptx_target( + None, + "CUDA_OXIDE_TARGET", + Some(&blackwell), + DetectedFeatures::Wgmma, + ) + .unwrap(); + assert_eq!(wgmma.sm(), "sm_90a"); + assert_eq!( + cuda_target_spec::resolve_sm_floor(None, Some(blackwell.as_ref())).unwrap(), + 80 + ); + + // A detected device *below* the default pulls the floor down with it, so + // running on Turing still produces sm_75 rather than PTX it cannot load. + let sm_75 = "sm_75".parse::().unwrap(); + let (turing, source) = resolve_ptx_target( + None, + "CUDA_OXIDE_TARGET", + Some(&sm_75), + DetectedFeatures::Basic, + ) + .unwrap(); + assert_eq!((turing.sm().as_str(), source), ("sm_75", "detected GPU")); + assert_eq!( + cuda_target_spec::resolve_sm_floor(None, Some(sm_75.as_ref())).unwrap(), + 75 + ); +} + +/// An architecture family that cannot host the module is refused where it is +/// stated, rather than quietly resolved to something else. +#[test] +fn an_explicit_target_that_cannot_host_the_module_is_refused() { + let error = resolve_ptx_target( + Some("sm_120a"), + "CUDA_OXIDE_TARGET", + None, + DetectedFeatures::Wgmma, + ) + .unwrap_err() + .to_string(); + assert!(error.contains("Wgmma"), "{error}"); + + // A blank target, which the two stages read differently. + // + // `resolve_sm_floor` treats a blank `CUDA_OXIDE_TARGET` as unset and falls + // back to the default floor, while the backend reads the variable with + // `env::var().ok()` and hands the empty string to the target parser, which + // refuses it. The strict side is the one that decides whether anything is + // built, so the ladder can never be the thing that overstates: the build + // fails before a module exists. + assert_eq!( + cuda_target_spec::resolve_sm_floor(Some(" "), None).unwrap(), + 80 + ); + assert!( + resolve_ptx_target( + Some(" "), + "CUDA_OXIDE_TARGET", + None, + DetectedFeatures::Basic + ) + .is_err() + ); +} diff --git a/cuda-oxide/crates/cuda-target-spec/src/lib.rs b/cuda-oxide/crates/cuda-target-spec/src/lib.rs index 62b2f65d99..0a5375f37b 100644 --- a/cuda-oxide/crates/cuda-target-spec/src/lib.rs +++ b/cuda-oxide/crates/cuda-target-spec/src/lib.rs @@ -556,9 +556,170 @@ pub fn spelling_at_least(floor: u16) -> Option { PtxSpelling::round_up(floor).map(PtxSpelling::get) } +/// Compute-capability floors device code can test with the +/// `cuda_oxide_sm_at_least` cfg, ascending. +/// +/// `cfg` compares strings, not numbers, so a single "the floor is 86" cfg +/// could not answer "is this at least sm_80". `cuda-device`'s build script +/// instead sets every rung at or below the resolved capability, and device +/// code tests the one rung its instruction needs. +pub const SM_FLOOR_LADDER: &[u32] = &[70, 75, 80, 86, 90, 100, 120]; + +/// Capability floor assumed when nothing names a target. +/// +/// Matches the backend's own "Basic CUDA / sm_80 / Ampere+ (max compat)" +/// default, so a cross-compile with no environment set agrees with the PTX it +/// will actually produce. +pub const DEFAULT_SM_FLOOR: u32 = 80; + +/// Resolve the compute-capability floor device code may assume. +/// +/// Shared with the backend's target selection rather than restated, so the +/// `cuda_oxide_sm_at_least` ladder `cuda-device`'s build script fixes before +/// rustc runs cannot drift from the target the PTX is actually built for. +/// The property that has to hold is one-directional: the selected target is +/// never *below* this floor. +/// +/// An explicit target sets it exactly, because that target is what gets built. +/// +/// A detected device can only lower it, never raise it. `CUDA_OXIDE_DEVICE_ARCH` +/// is advisory by contract -- the backend "builds for the detected GPU only +/// when that GPU can actually run the kernel", and otherwise for the arch the +/// kernel requires -- so it says nothing about how *high* selection will go: a +/// detected `sm_120` with a WGMMA module lands on `sm_90a`. What it does say +/// is how *low* selection may go, because a device that can run the kernel is +/// selected as-is. Running on Turing must still produce `sm_75`, so a detected +/// device below the default pulls the floor down with it rather than promising +/// device code rungs the PTX will not have. +/// +/// With neither, the floor is [`DEFAULT_SM_FLOOR`]: every architecture at or +/// above it runs what a lower one does, so selection can always honour it, and +/// it matches both the featureless default selection and the Ampere+ minimum +/// the book documents. +/// +/// Values arrive as arguments rather than being read from the environment so +/// the rule is testable without mutating process state, which is `unsafe` in +/// edition 2024 and racy across test threads. +/// +/// An architecture-family suffix is ignored: `sm_90a` floors at `90`. A named +/// value that does not parse is an error rather than a silent fallback, +/// because guessing high emits instructions the target cannot run and guessing +/// low silently drops the faster form. A blank value is treated as unset. +pub fn resolve_sm_floor( + target: Option<&str>, + device_arch: Option<&CudaArch>, +) -> Result { + if let Some(target) = target.map(str::trim).filter(|target| !target.is_empty()) { + return Ok(target.parse::()?.capability()); + } + Ok(device_arch.map_or(DEFAULT_SM_FLOOR, |device| { + DEFAULT_SM_FLOOR.min(device.capability()) + })) +} + +/// The ladder rungs at or below `capability`, ascending. +pub fn sm_floors_at_most(capability: u32) -> impl Iterator { + SM_FLOOR_LADDER + .iter() + .copied() + .filter(move |floor| *floor <= capability) +} + #[cfg(test)] mod tests { use super::*; + + /// A detected device, as the backend and the build script both carry it. + fn device(raw: &str) -> CudaArch { + raw.parse::().unwrap().into() + } + + /// An explicit target sets the floor exactly; a detected device can only + /// lower it, because the backend may build for that device as-is but is + /// documented to build elsewhere when the kernel needs it. + #[test] + fn a_detected_device_lowers_the_floor_and_never_raises_it() { + assert_eq!(resolve_sm_floor(Some("sm_86"), None).unwrap(), 86); + assert_eq!(resolve_sm_floor(None, None).unwrap(), DEFAULT_SM_FLOOR); + + // Below the default: running on Turing really does produce sm_75, so + // device code must not be told it has Ampere rungs. + assert_eq!(resolve_sm_floor(None, Some(&device("sm_75"))).unwrap(), 75); + + // Above the default: selection may still land on sm_90a for a WGMMA + // module, so the hint promises nothing higher. + assert_eq!( + resolve_sm_floor(None, Some(&device("sm_120a"))).unwrap(), + DEFAULT_SM_FLOOR + ); + + // An explicit target wins over the hint in both directions. + assert_eq!( + resolve_sm_floor(Some("sm_75"), Some(&device("sm_120"))).unwrap(), + 75 + ); + assert_eq!( + resolve_sm_floor(Some("sm_120"), Some(&device("sm_75"))).unwrap(), + 120 + ); + } + + /// An env var set to the empty string is how a shell spells "unset", and + /// must not be read as a target that failed to parse. + #[test] + fn blank_env_values_are_not_targets() { + assert_eq!(resolve_sm_floor(Some(""), None).unwrap(), DEFAULT_SM_FLOOR); + assert_eq!( + resolve_sm_floor(Some(" "), Some(&device("sm_75"))).unwrap(), + 75 + ); + assert_eq!(resolve_sm_floor(Some(" sm_86 "), None).unwrap(), 86); + } + + /// Family suffixes carry no capability of their own. + #[test] + fn architecture_family_suffixes_do_not_change_the_floor() { + assert_eq!(resolve_sm_floor(Some("sm_90a"), None).unwrap(), 90); + assert_eq!(resolve_sm_floor(Some("sm_100f"), None).unwrap(), 100); + } + + /// Guessing high emits instructions the target cannot run and guessing low + /// silently drops the faster form, so a named value that does not parse + /// fails instead of falling back. + #[test] + fn a_named_target_that_does_not_parse_is_an_error() { + assert!(resolve_sm_floor(Some("ampere"), None).is_err()); + assert!(resolve_sm_floor(Some("sm_9"), None).is_err()); + } + + #[test] + fn the_floor_ladder_is_ascending_and_carries_the_default() { + assert!(SM_FLOOR_LADDER.windows(2).all(|pair| pair[0] < pair[1])); + assert!(SM_FLOOR_LADDER.contains(&DEFAULT_SM_FLOOR)); + } + + /// The cumulative rungs are what `cfg` needs: every floor at or below the + /// capability, so device code can ask for the one it needs. + #[test] + fn floors_at_most_is_cumulative_and_excludes_higher_rungs() { + assert_eq!( + sm_floors_at_most(86).collect::>(), + vec![70, 75, 80, 86] + ); + assert_eq!( + sm_floors_at_most(120).collect::>(), + SM_FLOOR_LADDER.to_vec() + ); + assert_eq!(sm_floors_at_most(75).collect::>(), vec![70, 75]); + // Between rungs: sm_89 is Ada, which is Ampere-or-newer for our + // purposes but is not itself a rung. + assert_eq!( + sm_floors_at_most(89).collect::>(), + vec![70, 75, 80, 86] + ); + assert!(sm_floors_at_most(50).next().is_none()); + } + #[test] fn device_arch_requires_sm_spelling_and_reuses_cuda_grammar() { for entry in RECORDED_PTX_FLOORS { 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..1c037b019f 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2f99ba5cb4 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7ff69ffe2e 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..29fe6e089d 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6747dd6c5c 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..15f35f5197 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a2a49b552d 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4c4c4c7bd5 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2f3bffbb7b 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3f73a4c5aa 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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 ab1c6b4fec..68817beb61 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 @@ -195,6 +195,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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 3b94cbfb24..efe5bf39d2 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 @@ -195,6 +195,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a55ef17f89 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..e28aa6fc8b 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/atomics/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/atomics/Cargo.lock @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b03042ac63 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/barrier/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/barrier/Cargo.lock @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f5b8b08b52 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..88337dc62b 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b327a54001 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..9706deab29 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4db0dee9b7 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..82195e4daf 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..5521aef908 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..74a8aca8fa 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1221c22166 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/clc/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/clc/Cargo.lock @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1ae3946b07 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/cluster/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/cluster/Cargo.lock @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2c5406ce95 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 @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a243c74625 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..9ff59e70b0 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a6c3424c8b 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1491f549d4 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 @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2957b1a0fb 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7a7a1efe68 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7fe1ee92df 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ed9fa48387 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7a874e4c1e 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..35139018a9 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..82d1a43eef 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..5865614589 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_u64/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_u64/Cargo.lock index 935aa613e3..716b20eaa4 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_u64/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/coop_groups_u64/Cargo.lock @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..9847319872 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..55b3886540 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b09ef38b52 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a4bb9ebae2 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..9e16701e8b 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..da584ef548 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 @@ -171,6 +171,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ed75c2bf63 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 @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..84a4ff48a1 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 @@ -174,6 +174,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6f749e9635 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 @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..8b5f0656f2 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 @@ -173,6 +173,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7ca25500c3 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..44236d3e5b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..50f44cce13 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..e3bec59d3c 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f7cce8bb04 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c65a158656 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c6acadbcf9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4d03e6dd7c 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/debug/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/debug/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..926a0137e8 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4c0d82b6c2 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..56b5fe6a62 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..18a542e41b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ceb811decf 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3798850eb3 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..90dd6bca48 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d2edf71367 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/dotprod/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/dotprod/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..af7dea7437 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a02ec311ef 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..552e1b9bad 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7015b20273 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c435cb2bde 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f611ffe9d2 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2ef7776beb 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4d15fa1520 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..67cd2b9f27 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4452da4c23 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..78df78238b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ba0b36932e 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/error/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/error/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4eb33dbb42 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..da36590a8a 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..30a5d19fbe 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c638cd5a9d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3c015d65c9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..952d75056f 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..bb02509679 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..efe8d52bdf 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..551bec2cb1 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..33cb33cbcc 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..11249cd4aa 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..8ce99d11dc 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..06935c53f4 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..94066c4a07 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] @@ -171,6 +172,7 @@ version = "0.2.1" dependencies = [ "cuda-artifact-finalizer", "cuda-core", + "cuda-device", "cuda-macros", "half", "libc", 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..918493743b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] @@ -171,6 +172,7 @@ version = "0.2.1" dependencies = [ "cuda-artifact-finalizer", "cuda-core", + "cuda-device", "cuda-macros", "half", "libc", 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..d3aece5b21 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..78768b95a3 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7c9635b8ed 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2353b6c89c 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6b2d77fbf4 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a1fe7827fe 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..153d1b747a 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2de9080c66 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..494aa89941 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b02627ad72 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..40041e86a0 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2882b3761e 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3fcf1bfd04 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c57202a9f9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a614b8d41d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4635756394 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f5f595e278 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/gemm/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..fdde048e42 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..80d559f317 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..376e2993c3 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..5a01003256 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..bef0c8092a 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..5ff3ff2109 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1f38a4a4d5 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/generic/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/generic/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d4ec0655f9 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/hashmap/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..cc41b1be4b 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 @@ -194,6 +194,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3161b61d72 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 @@ -194,6 +194,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..554f6008c5 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d302e295ee 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..cfbcac7f36 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 @@ -184,6 +184,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..0b7f8eafb1 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..87776671f9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..225ee308b8 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 @@ -175,6 +175,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..62b01613bf 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a0c305571c 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..96d49c87de 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] @@ -171,6 +172,7 @@ version = "0.2.1" dependencies = [ "cuda-artifact-finalizer", "cuda-core", + "cuda-device", "cuda-macros", "half", "libc", 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..3f6adac1fd 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2b867e71e9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..8847d0b906 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..8582b89ade 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6ea1923a1a 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 @@ -184,6 +184,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..bd1b51686e 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2d42059b18 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6f141a2ab3 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..888a1c77e0 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..da449995b1 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..311408c3b9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..59f0630cb5 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..29a55b18eb 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..314c42a125 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4d56e5dd31 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7abc46b63e 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7c46dc1101 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_special/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_special/Cargo.lock index 71036a0499..893f3f2ee5 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/math_special/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/math_special/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..185be7575c 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b6b8feb646 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 @@ -183,6 +183,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..372fde43cb 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a56847b624 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..809a4e79c0 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..379ea8036d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ac68d3341b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..90c45ff531 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/nounroll/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/nounroll/Cargo.lock index ae86965e4f..cf3a7f0c68 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/nounroll/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/nounroll/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..65055e5ade 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..9d880ebed9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..58d2e13c4d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a9b10e3445 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c5469428b7 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..9a885661d1 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1c5b6e72a9 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..5f0be6c0cb 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..94bcdf97e5 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6e0bda829d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..19a3b3683d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6b62c2f8ff 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d766778ad2 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f053b36e82 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c53cd9fa5d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/printf/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/printf/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c82c369a71 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b5d9e8de17 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a08d9e3796 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..6e90116bda 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3d67761786 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ecb7d6be00 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/reborrow/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/reborrow/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..0b7a04baf1 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..baf5d2ce4f 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..74966c9701 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ff2c954b9b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ef811c5618 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d7500c65e7 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..fd7641b10a 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f8438ac9bb 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d2e54efa6d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c0627f2d71 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..048a40ac50 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..82a6d18c05 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..852a52de4c 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1b5282e2ed 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..81f39ccb60 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..559bbe5c0d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2f03083890 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d015357585 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..58fdabea61 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a9a7be574a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/sharedmem/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/sharedmem/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f32432b024 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..33105fbd49 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..cb65f89584 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c6ac39ade8 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..68ad0fb1d4 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..e2d5d86d3a 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..cbcb51b958 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1b392f2167 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..25f2a4ddcf 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..aa7cc04eee 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b38f75418f 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..0cc58983b8 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..cc870067a8 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..e798da7dde 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1ecd158288 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..21e93254d0 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..85807f7f8d 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d45d3751a8 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ce4ec1e466 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3207bdbe8a 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/tcgen05/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ad72fa0e51 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..776e16e4fd 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..e681835c96 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b60e96ebaf 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..154a81a7ca 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..24c3127807 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ec527a7d45 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a718e698fd 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..bfec58cea2 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..c7834958c2 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..bcb4d56f7e 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..e03faa623b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..5140192555 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..0afbb669fb 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..2a47b10693 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..49434636a0 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..a1e2282c26 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..bb81e18c53 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..f030ae8470 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/vecadd/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/vecadd/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..4ecd4ca57d 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/vectorization/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/vectorization/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1357f5366e 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..1604434012 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..eeba836e27 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ca44e609c9 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma/Cargo.lock +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/wgmma/Cargo.lock @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d16ca4f61b 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 @@ -163,6 +163,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..45e5879073 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] diff --git a/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md b/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md index 4df7a75d2a..48ccdf93b6 100644 --- a/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md +++ b/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md @@ -161,10 +161,17 @@ Three constraints: example does, on `ctx.compute_capability()`, or restrict the build to Ampere and newer. -`warp_reduce` does not select this form for you today; making it do so -automatically needs a way for device code to know its target architecture, -which is the open question in -[#811](https://github.com/NVlabs/cuda-oxide/issues/811). +`warp_reduce` selects this form for you, for integer element types on a full +32-lane tile, whenever the build's compute-capability floor is `sm_80` or +newer. That floor comes from the `cuda_oxide_sm_at_least` cfg, which +`cuda-device`'s build script derives from the same environment the backend +reads to choose a target: `CUDA_OXIDE_TARGET`, else `CUDA_OXIDE_DEVICE_ARCH`, +else `sm_80`. A cfg is resolved before rustc runs, so a build below the floor +drops the branch entirely and never emits an instruction it cannot assemble. + +Calling `redux_sync_add` and friends directly is still the right move when you +want the single instruction regardless of the surrounding generic code, and it +is the only option for a sub-warp tile. ### Floats on Blackwell: `redux.sync` for `f32` 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..361e2d9a50 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 @@ -183,6 +183,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7e9e906fc0 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 @@ -181,6 +181,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..0005bbc90c 100644 --- a/cuda-oxide/cute-rs-preview/examples/elementwise_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/elementwise_cute/Cargo.lock @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..43d578161c 100644 --- a/cuda-oxide/cute-rs-preview/examples/ffn_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/ffn_cute/Cargo.lock @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..8df63e9eb8 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..3c3198c3a8 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7cf39fd79c 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 @@ -172,6 +172,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..dfe124c501 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d11ece7f2f 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..ca56f1c40d 100644 --- a/cuda-oxide/cute-rs-preview/examples/rmsnorm_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/rmsnorm_cute/Cargo.lock @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..fb668acd7e 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..d95a884552 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..b64a273af2 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 @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..617f8b43b0 100644 --- a/cuda-oxide/cute-rs-preview/examples/swiglu_cute/Cargo.lock +++ b/cuda-oxide/cute-rs-preview/examples/swiglu_cute/Cargo.lock @@ -170,6 +170,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..7a7bf382a0 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 @@ -176,6 +176,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] 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..36e08f678f 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 @@ -176,6 +176,7 @@ name = "cuda-device" version = "0.2.1" dependencies = [ "cuda-macros", + "cuda-target-spec", ] [[package]] From 444b8641b4d1cb62c796a9bf998295041d9ed5b2 Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Wed, 23 Sep 2026 14:03:57 +0700 Subject: [PATCH 04/10] example(warp_reduce_redux): show both forms of warp_reduce and their controls `warp_reduce` now takes `redux.sync` for the nine integer pairs at the Ampere floor and the shuffle butterfly below it, but no example demonstrated either: the only caller of the generic API is `coop_groups_demo`, which also uses thread-block clusters and so cannot be built below sm_90 at all. There was nowhere to read the PTX difference, and nothing that would notice if the fast path started answering differently from the tree it replaces. This example uses one warp and nothing else, so it builds at both floors: cargo oxide build warp_reduce_redux --arch sm_80 redux.sync, no shfl cargo oxide build warp_reduce_redux --arch sm_75 shfl butterfly Four kernels, three of them controls. The `u32` kernel takes every supported op, with inputs that pin the whole warp: a distinct bit per lane, so `or` and `xor` are `0xFFFFFFFF` and `and` over the complements is 0 -- a reduction that dropped lanes could not produce those. The `i32` kernel straddles zero, because signedness is what a single-instruction form gets wrong silently: `redux.sync.min.s32` and `.u32` disagree on exactly those inputs. The two controls are the cases that must *not* move. `f32` has no `redux` before sm_100, so a hook that claimed one would name an instruction that does not exist. A `WarpTile<16>` must reduce within its own tile: the fast path is gated on `N == 32`, and if that gate broke, both tiles would answer 496 instead of 120, which the expected values catch. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../examples/warp_reduce_redux/Cargo.lock | 755 ++++++++++++++++++ .../examples/warp_reduce_redux/Cargo.toml | 26 + .../examples/warp_reduce_redux/src/main.rs | 267 +++++++ 3 files changed, 1048 insertions(+) create mode 100644 cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.lock create mode 100644 cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.toml create mode 100644 cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.lock b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.lock new file mode 100644 index 0000000000..0e2dba1210 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.lock @@ -0,0 +1,755 @@ +# 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", + "cuda-target-spec", +] + +[[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", + "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 = "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d9a941c0c43d2dceaf25f5c9ca4c9f9cceb28dfa5e4e3cfd14e476f003e7c9" +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 = "warp_reduce_redux" +version = "0.1.0" +dependencies = [ + "cuda-core", + "cuda-device", + "cuda-host", +] + +[[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/warp_reduce_redux/Cargo.toml b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.toml new file mode 100644 index 0000000000..9cabf31879 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "warp_reduce_redux" +version = "0.1.0" +edition = "2024" +license = "Apache-2.0" + +# Mark as standalone crate (not part of parent workspace) +[workspace] + +# This example shows `warp_reduce` taking the single-instruction +# `redux.sync` form at the Ampere floor and the shuffle butterfly below it. +# The form is chosen by the `cuda_oxide_sm_at_least` cfg, so the same source +# builds both ways: +# cargo oxide build warp_reduce_redux --arch sm_80 # redux.sync +# cargo oxide build warp_reduce_redux --arch sm_75 # shfl butterfly +# cargo oxide run warp_reduce_redux + +[dependencies] +# Device-side cooperative groups (warp_reduce, tiled_partition) +cuda-device = { path = "../../../cuda-device" } + +# Host-side utilities (CudaKernel trait, etc.) +cuda-host = { path = "../../../cuda-host" } + +# Host-side CUDA runtime +cuda-core = { path = "../../../../../cuda-core" } diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs new file mode 100644 index 0000000000..a9e9965cbe --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs @@ -0,0 +1,267 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +//! `warp_reduce` on the Ampere single-instruction form, and its controls. +//! +//! `warp_reduce` reduces a full warp with a `shfl`-based butterfly: five +//! rounds of shuffle-and-combine, ten instructions. Ampere does the integer +//! cases in one (`redux.sync`), which #811 measured at 4.74x for the +//! primitive. The form is not chosen at run time -- there is no branch in the +//! emitted code -- it is chosen by the `cuda_oxide_sm_at_least` cfg that +//! `cuda-device`'s build script derives from the target, so the same source +//! builds both ways: +//! +//! ```text +//! cargo oxide build warp_reduce_redux --arch sm_80 redux.sync, no shfl +//! cargo oxide build warp_reduce_redux --arch sm_75 shfl butterfly +//! ``` +//! +//! Three things have to stay true, and each has a kernel below: +//! +//! * the nine integer pairs must take the fast form and still be correct; +//! * `f32` must not -- there is no `redux` for floats before sm_100, so a +//! hook that claimed one would name an instruction that does not exist; +//! * a sub-warp tile must not -- `redux.sync` reduces over the lanes in +//! `membermask`, and a `WarpTile<16>`'s contract is not that shape yet. +//! +//! Run with: +//! cargo oxide run warp_reduce_redux + +use cuda_device::cooperative_groups::{ + ThreadGroup, + ops::{BitAnd, BitOr, BitXor, Max, Min, Sum}, + this_thread_block, warp_reduce, +}; +use cuda_device::{DisjointSlice, kernel, thread}; +use cuda_host::cuda_module; + +// ============================================================================= +// KERNELS +// ============================================================================= +#[cuda_module] +mod kernels { + use super::*; + + /// Every `u32` op `warp_reduce` supports, over one full warp. + /// + /// Lane `l` contributes `l` for sum/min/max, and a single distinct bit + /// `1 << l` for the bitwise ops, so each answer pins the whole warp: + /// an `or` or `xor` of all 32 single-bit values is `0xFFFFFFFF`, and an + /// `and` of their complements is `0` -- every bit is cleared by exactly + /// one lane. A reduction that silently dropped lanes could not produce + /// those. + /// + /// Lane 0 writes `[sum, min, max, and, or, xor]`. + #[kernel] + pub fn reduce_u32_all_ops(mut out: DisjointSlice) { + let warp = this_thread_block().tiled_partition::<32>(); + let lane = warp.thread_rank(); + + let v_one = 1u32 << lane; + let v_inv = !v_one; + + let r_sum = warp_reduce::(&warp, lane); + let r_min = warp_reduce::(&warp, lane); + let r_max = warp_reduce::(&warp, lane); + let r_and = warp_reduce::(&warp, v_inv); + let r_or = warp_reduce::(&warp, v_one); + let r_xor = warp_reduce::(&warp, v_one); + + if lane == 0 { + // SAFETY: the host allocates six elements for this kernel. + unsafe { + *out.get_unchecked_mut(0) = r_sum; + *out.get_unchecked_mut(1) = r_min; + *out.get_unchecked_mut(2) = r_max; + *out.get_unchecked_mut(3) = r_and; + *out.get_unchecked_mut(4) = r_or; + *out.get_unchecked_mut(5) = r_xor; + } + } + } + + /// The signed ops, with values that straddle zero (`-16..=15`). + /// + /// Signedness is the part a single-instruction form can get wrong + /// silently: `redux.sync.min.s32` and `.u32` disagree on exactly these + /// inputs, and only the signed answer is `-16`. + /// + /// Lane 0 writes `[sum, min, max]`. + #[kernel] + pub fn reduce_i32_signed_ops(mut out: DisjointSlice) { + let warp = this_thread_block().tiled_partition::<32>(); + let lane = warp.thread_rank(); + let v = lane as i32 - 16; + + let r_sum = warp_reduce::(&warp, v); + let r_min = warp_reduce::(&warp, v); + let r_max = warp_reduce::(&warp, v); + + if lane == 0 { + // SAFETY: the host allocates three elements for this kernel. + unsafe { + *out.get_unchecked_mut(0) = r_sum; + *out.get_unchecked_mut(1) = r_min; + *out.get_unchecked_mut(2) = r_max; + } + } + } + + /// Control: `f32` keeps the butterfly at every floor. + /// + /// There is no `redux` for floats before sm_100, so this must reduce the + /// same way at sm_75 and sm_80 and stay correct. + /// + /// Lane 0 writes `[sum, min, max]`. + #[kernel] + pub fn reduce_f32_control(mut out: DisjointSlice) { + let warp = this_thread_block().tiled_partition::<32>(); + let lane = warp.thread_rank(); + let v = lane as f32; + + let r_sum = warp_reduce::(&warp, v); + let r_min = warp_reduce::(&warp, v); + let r_max = warp_reduce::(&warp, v); + + if lane == 0 { + // SAFETY: the host allocates three elements for this kernel. + unsafe { + *out.get_unchecked_mut(0) = r_sum; + *out.get_unchecked_mut(1) = r_min; + *out.get_unchecked_mut(2) = r_max; + } + } + } + + /// Control: a `WarpTile<16>` keeps the butterfly, and each half reduces + /// only its own lanes. + /// + /// Lane `l` contributes its rank within the tile, so both tiles answer + /// `0 + 1 + ... + 15 = 120`. A fast path that reduced the whole warp + /// instead would answer `496` and be caught here. + /// + /// Tile leader `t` writes `out[t]`. + #[kernel] + pub fn reduce_subwarp_control(mut out: DisjointSlice) { + let tile = this_thread_block().tiled_partition::<16>(); + let rank = tile.thread_rank(); + let tile_index = thread::index_1d().get() / 16; + + let r_sum = warp_reduce::(&tile, rank); + + if rank == 0 { + // SAFETY: the host allocates one element per tile (two). + unsafe { + *out.get_unchecked_mut(tile_index as usize) = r_sum; + } + } + } +} + +// ============================================================================= +// HOST CODE +// ============================================================================= + +fn main() { + use cuda_core::simt::LaunchConfig; + use cuda_core::{CudaContext, DeviceBuffer}; + + println!("=== warp_reduce: single-instruction form and its controls ===\n"); + + let ctx = CudaContext::new(0).expect("Failed to create CUDA context"); + let stream = ctx.default_stream(); + + let (major, minor) = ctx.compute_capability().expect("compute capability"); + println!("GPU Compute Capability: sm_{}{}", major, minor); + + let module = kernels::load(&ctx).expect("Failed to load embedded CUDA module"); + // One warp is the whole contract; a second would only repeat it. + let cfg = LaunchConfig { + block_dim: (32, 1, 1), + grid_dim: (1, 1, 1), + shared_mem_bytes: 0, + }; + + let mut failed = false; + + // ===== Test 1: every u32 op ===== + println!("\n--- Test 1: warp_reduce over u32, all six ops ---"); + let mut u32_dev = DeviceBuffer::::zeroed(&stream, 6).unwrap(); + // SAFETY: launch shape/resources match the kernel; the buffer covers its writes. + unsafe { module.reduce_u32_all_ops((stream).as_ref(), cfg, &mut u32_dev) } + .expect("Kernel launch failed"); + let got = u32_dev.to_host_vec(&stream).unwrap(); + let want: [u32; 6] = [496, 0, 31, 0, u32::MAX, u32::MAX]; + println!("[sum, min, max, and, or, xor] = {:?}", got); + println!("expected = {:?}", want); + if got == want { + println!("✓ every u32 reduction correct"); + } else { + println!("✗ u32 reduction mismatch!"); + failed = true; + } + + // ===== Test 2: signed ops across zero ===== + println!("\n--- Test 2: warp_reduce over i32, values -16..=15 ---"); + let mut i32_dev = DeviceBuffer::::zeroed(&stream, 3).unwrap(); + // SAFETY: launch shape/resources match the kernel; the buffer covers its writes. + unsafe { module.reduce_i32_signed_ops((stream).as_ref(), cfg, &mut i32_dev) } + .expect("Kernel launch failed"); + let got = i32_dev.to_host_vec(&stream).unwrap(); + let want: [i32; 3] = [-16, -16, 15]; + println!("[sum, min, max] = {:?}", got); + println!( + "expected = {:?} (unsigned min/max would read 0 / 4294967295)", + want + ); + if got == want { + println!("✓ signed reductions correct"); + } else { + println!("✗ signed reduction mismatch!"); + failed = true; + } + + // ===== Test 3: f32 control ===== + println!("\n--- Test 3: control, f32 keeps the butterfly ---"); + let mut f32_dev = DeviceBuffer::::zeroed(&stream, 3).unwrap(); + // SAFETY: launch shape/resources match the kernel; the buffer covers its writes. + unsafe { module.reduce_f32_control((stream).as_ref(), cfg, &mut f32_dev) } + .expect("Kernel launch failed"); + let got = f32_dev.to_host_vec(&stream).unwrap(); + let want: [f32; 3] = [496.0, 0.0, 31.0]; + println!("[sum, min, max] = {:?}", got); + println!("expected = {:?}", want); + if got == want { + println!("✓ f32 reductions correct"); + } else { + println!("✗ f32 reduction mismatch!"); + failed = true; + } + + // ===== Test 4: sub-warp control ===== + println!("\n--- Test 4: control, WarpTile<16> reduces only its own lanes ---"); + let mut tile_dev = DeviceBuffer::::zeroed(&stream, 2).unwrap(); + // SAFETY: launch shape/resources match the kernel; the buffer covers its writes. + unsafe { module.reduce_subwarp_control((stream).as_ref(), cfg, &mut tile_dev) } + .expect("Kernel launch failed"); + let got = tile_dev.to_host_vec(&stream).unwrap(); + let want: [u32; 2] = [120, 120]; + println!("per-tile sums = {:?}", got); + println!( + "expected = {:?} (a whole-warp reduction would read 496)", + want + ); + if got == want { + println!("✓ sub-warp tiles reduce independently"); + } else { + println!("✗ sub-warp reduction mismatch!"); + failed = true; + } + + if failed { + std::process::exit(1); + } + println!("\nSUCCESS: warp_reduce is correct in both forms"); +} From ae36eb301bcb98ab5bac9bff88b70d12faed7a3c Mon Sep 17 00:00:00 2001 From: nihalpasham Date: Thu, 24 Sep 2026 13:13:45 +0000 Subject: [PATCH 05/10] docs: clarify the shared SM floor contract Signed-off-by: nihalpasham --- cuda-oxide/crates/cuda-device/build.rs | 21 ++---- .../cuda-device/src/cooperative_groups.rs | 72 ++++--------------- .../crates/cuda-oxide-codegen/src/export.rs | 7 +- .../cuda-oxide-codegen/src/target/select.rs | 17 +---- cuda-oxide/crates/cuda-target-spec/src/lib.rs | 38 ++-------- 5 files changed, 27 insertions(+), 128 deletions(-) diff --git a/cuda-oxide/crates/cuda-device/build.rs b/cuda-oxide/crates/cuda-device/build.rs index 34141176d1..8b4579bb99 100644 --- a/cuda-oxide/crates/cuda-device/build.rs +++ b/cuda-oxide/crates/cuda-device/build.rs @@ -3,24 +3,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -//! Expose the compute-capability floor to device code as `cfg`s. +//! Expose the target's minimum compute capability as device cfgs. //! -//! Device code has no way to ask what target it is being compiled for, so an -//! API with a faster form on newer hardware -- `redux.sync` in place of a -//! shuffle tree, for one -- either always pays for the portable form or asks -//! every caller to gate the choice by hand. A `cfg` is decided before rustc -//! runs, so rustc drops the branch that does not apply and the requirement -//! scan never sees an instruction the target cannot run. -//! -//! Because a `cfg` is fixed before compilation it can only carry a *lower* -//! bound: the floor is the lowest capability the resulting PTX will be built -//! for, never the exact device. `CUDA_OXIDE_TARGET` sets it exactly, since -//! that is what gets built. `CUDA_OXIDE_DEVICE_ARCH` can only lower it: the -//! backend builds for the detected device when that device can run the kernel -//! and otherwise for the arch the kernel requires, so it bounds how low -//! selection may go, not how high. The rule lives in `cuda-target-spec` and is -//! shared with the backend's own target selection rather than restated here, -//! so the two cannot disagree about what the floor is. +//! An explicit target sets the floor; an advisory device hint can only lower +//! the default. The shared resolver keeps these cfgs consistent with backend +//! selection. Unsupported intrinsic branches disappear before MIR lowering. fn main() { // The two variables the backend already reads to pick a target. diff --git a/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs b/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs index b441c7bed3..21d0c5cda6 100644 --- a/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs +++ b/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs @@ -910,55 +910,24 @@ pub mod ops { /// Binary combiner. Must be associative and commutative. fn combine(a: T, b: T) -> T; - /// Whether this `(Op, T)` pair reduces a full warp in one instruction - /// on the target being compiled for. - /// - /// `false` by default, which is what keeps the choice sound: an - /// operation with no single-instruction form, and every operation at - /// all when the floor is below `sm_80`, falls through to the - /// butterfly. Rust has no specialization, so this pair of items is how - /// a reduction generic over `T` and `Op` reaches a form that exists - /// for only some pairs. - /// - /// A `const` rather than an `Option` return, and not for style: an - /// `Option` crossing this boundary is an enum with a signed - /// payload, which device lowering rejects with `enum payload storage - /// type mismatch: si32 cannot be adapted to i32`. A `const` leaves no - /// enum to lower and folds the branch before codegen. + /// Whether this operation has a full-warp instruction at the target floor. + /// Other operation/type pairs use the shuffle implementation. const HAS_FULL_WARP_FORM: bool = false; - /// The whole full-warp reduction as one instruction. - /// - /// Only reached when [`Self::HAS_FULL_WARP_FORM`] is true, so the - /// default is unreachable. It returns the input rather than panicking - /// because a device panic would pull formatting machinery into every - /// kernel that instantiates it. - /// - /// `mask` is the tile's participation mask. Only - /// [`super::warp_reduce`] calls this, and only at `N == 32`, where - /// that mask is `u32::MAX`. + /// Reduce the participating warp. Called only when `HAS_FULL_WARP_FORM` + /// is true and the tile contains all 32 lanes. #[inline(always)] fn reduce_full_warp(_mask: u32, value: T) -> T { value } } - /// Give one integer `(Op, T)` pair its `redux.sync` form. - /// - /// The `cfg` is what makes this safe to write unconditionally: below the - /// Ampere floor the body is not compiled at all, so `redux.sync` never - /// reaches the requirement scan and cannot raise a module's target. + // Exclude unsupported intrinsics before MIR and feature detection run. macro_rules! redux_full_warp { ($ty:ty, |$mask:ident, $value:ident| $call:expr) => { const HAS_FULL_WARP_FORM: bool = cfg!(cuda_oxide_sm_at_least = "80"); - // Two whole definitions rather than one body with a `cfg` inside: - // the body has to be a single expression that hands back the - // intrinsic's result, which is the shape `WarpShuffle::shfl_xor_via` - // already uses for the shuffle stubs. Wrapping the call in a block - // bound to a local instead makes device lowering reject the - // function with `ReturnOp operand type does not match the - // function's result type`. + // Keep the intrinsic call as the return expression for device lowering. #[cfg(cuda_oxide_sm_at_least = "80")] #[inline(always)] fn reduce_full_warp($mask: u32, $value: $ty) -> $ty { @@ -1327,25 +1296,13 @@ impl WarpShuffle for i64 { /// bit-identical results. That is the primitive in isolation — a kernel that /// reduces once after a memory-bound pass will see far less. /// -/// **This function now selects that form for you**, for integer `T` on a full -/// warp (`N == 32`), whenever the compiled-for floor is `sm_80` or newer. -/// `cuda-device`'s build script derives that floor from the same environment -/// the backend reads to pick a target — `CUDA_OXIDE_TARGET`, else -/// `CUDA_OXIDE_DEVICE_ARCH`, else `sm_80` — and exposes it as the -/// `cuda_oxide_sm_at_least` cfg. Because a cfg is decided before rustc runs, -/// the branch that does not apply is dropped before MIR exists, so a target -/// below the floor never sees a `redux.sync` it cannot assemble. -/// -/// Three things keep the butterfly, all of them for a reason rather than an -/// omission: floats (there is no `f32` `redux` before `sm_100`), sub-warp -/// tiles (`redux.sync` reduces over whatever lanes are in `membermask`, but -/// the sub-warp wrapper's out-of-tile lane substitution needs its own check -/// first), and any build whose floor is below `sm_80`. +/// Full-warp integer reductions use `redux.sync` when the target floor is +/// `sm_80` or newer. Floats, smaller tiles and lower floors use shuffles. /// -/// One consequence worth knowing: with no explicit target the floor is -/// `sm_80`, so an integer `warp_reduce` emits `redux.sync` and the module -/// requires Ampere. Build with `--arch sm_75` (or `CUDA_OXIDE_TARGET=sm_75`) -/// to keep the portable form. +/// `CUDA_OXIDE_TARGET` sets the floor. An advisory `CUDA_OXIDE_DEVICE_ARCH` +/// can lower the default `sm_80` floor, but cannot raise it: incompatible +/// kernels may target another architecture. The build script and backend +/// share this rule. Use `--arch sm_75` to select the shuffle implementation. /// /// `N` is the tile size (1, 2, 4, 8, 16, or 32) — already validated by /// [`ThreadBlock::tiled_partition`] at construction time. @@ -1373,10 +1330,7 @@ where T: WarpShuffle, Op: ops::ReduceOp, { - // A full warp with a one-instruction form takes it. `N` is a const - // generic and `reduce_full_warp` is `None` at compile time for every pair - // without one, so this collapses to the butterfly with nothing left - // behind for the sub-warp and float paths. + // The const conditions remove this branch for floats and smaller tiles. if N == 32 && Op::HAS_FULL_WARP_FORM { return Op::reduce_full_warp(tile.mask(), value); } diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs index 7a4311db1c..40eef02b00 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/export.rs @@ -84,12 +84,7 @@ impl llvm_export::export::AsDeviceExtern for DeviceExternDecl { } } -/// The floor device code was compiled against, for the paths where selection -/// is free to choose. Those are reached only without an explicit target, so -/// only the detected-device hint can move it -- downwards, per -/// [`resolve_sm_floor`]. Taken from that one function rather than written out, -/// so `cuda-device`'s `cuda_oxide_sm_at_least` ladder and the target selected -/// here have a single definition between them. +/// Resolve the shared device cfg floor when no target was explicitly selected. fn sm_floor_for_selection(device_arch_hint: Option<&CudaArch>) -> Result { resolve_sm_floor(None, device_arch_hint).map_err(|error| PipelineError::TargetSelection { target: String::new(), diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs index 5772bc963c..766ca4437c 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/select.rs @@ -167,21 +167,8 @@ pub fn resolve_ptx_target( ) } -/// Raise a feature-selected target to the floor device code was compiled -/// against, or say why the two cannot both be satisfied. -/// -/// `cuda-device`'s build script fixes its `cuda_oxide_sm_at_least` ladder -/// before rustc runs, from the same [`resolve_sm_floor`] the callers below -/// use, so the two cannot drift. Selection then runs with something the build -/// script could not have: the module's own features. A module whose features -/// need less than the floor -- `ldmatrix` alone asks only for `sm_75` -- would -/// otherwise be built below the capability device code was told to assume. -/// -/// Raising is the repair whenever the floor can still run the module, which -/// is every case reachable today: the floor is only ever the default when -/// this is called, and every feature below it is forward compatible. The -/// error arm is not decoration -- it is what keeps a future floor from -/// silently selecting an architecture family that cannot host the module. +/// Raise an automatically selected target to the device cfg floor. +/// Reject the combination if that floor cannot run the module's features. pub(crate) fn honour_sm_floor( selected: CudaArch, floor: u32, diff --git a/cuda-oxide/crates/cuda-target-spec/src/lib.rs b/cuda-oxide/crates/cuda-target-spec/src/lib.rs index 0a5375f37b..e7ed477a7e 100644 --- a/cuda-oxide/crates/cuda-target-spec/src/lib.rs +++ b/cuda-oxide/crates/cuda-target-spec/src/lib.rs @@ -572,39 +572,15 @@ pub const SM_FLOOR_LADDER: &[u32] = &[70, 75, 80, 86, 90, 100, 120]; /// will actually produce. pub const DEFAULT_SM_FLOOR: u32 = 80; -/// Resolve the compute-capability floor device code may assume. +/// Resolve the minimum compute capability assumed by device code. /// -/// Shared with the backend's target selection rather than restated, so the -/// `cuda_oxide_sm_at_least` ladder `cuda-device`'s build script fixes before -/// rustc runs cannot drift from the target the PTX is actually built for. -/// The property that has to hold is one-directional: the selected target is -/// never *below* this floor. +/// An explicit target sets the floor. A device hint can only lower the default +/// `sm_80` floor because backend selection may override an incompatible hint. +/// Both device cfg generation and backend selection use this rule. /// -/// An explicit target sets it exactly, because that target is what gets built. -/// -/// A detected device can only lower it, never raise it. `CUDA_OXIDE_DEVICE_ARCH` -/// is advisory by contract -- the backend "builds for the detected GPU only -/// when that GPU can actually run the kernel", and otherwise for the arch the -/// kernel requires -- so it says nothing about how *high* selection will go: a -/// detected `sm_120` with a WGMMA module lands on `sm_90a`. What it does say -/// is how *low* selection may go, because a device that can run the kernel is -/// selected as-is. Running on Turing must still produce `sm_75`, so a detected -/// device below the default pulls the floor down with it rather than promising -/// device code rungs the PTX will not have. -/// -/// With neither, the floor is [`DEFAULT_SM_FLOOR`]: every architecture at or -/// above it runs what a lower one does, so selection can always honour it, and -/// it matches both the featureless default selection and the Ampere+ minimum -/// the book documents. -/// -/// Values arrive as arguments rather than being read from the environment so -/// the rule is testable without mutating process state, which is `unsafe` in -/// edition 2024 and racy across test threads. -/// -/// An architecture-family suffix is ignored: `sm_90a` floors at `90`. A named -/// value that does not parse is an error rather than a silent fallback, -/// because guessing high emits instructions the target cannot run and guessing -/// low silently drops the faster form. A blank value is treated as unset. +/// Blank inputs are unset. Malformed explicit targets are errors; malformed +/// hints are ignored. Architecture suffixes do not affect this numeric floor, +/// which does not imply support for architecture-specific instruction families. pub fn resolve_sm_floor( target: Option<&str>, device_arch: Option<&CudaArch>, From 94a84ce60c59e50a5aaf07b818214130dce49103 Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Sun, 11 Oct 2026 12:41:19 +0700 Subject: [PATCH 06/10] test(codegen): pin that both readers of the device hint agree Since #1256 the backend validates CUDA_OXIDE_DEVICE_ARCH once, at its input boundary, and hands selection a DeviceArch: a hint that does not parse is an error before either backend chooses a target. The three readings of a malformed hint this stack used to pin -- the floor resolver and the PTX selector ignoring it, the NVVM selector rejecting it -- no longer exist, so that test was dropped rather than carried forward. What the floor depends on now is narrower. cuda-device's build script reads the same variable with `parse::().ok()`, so its floor matches selection exactly when the boundary accepts the values that parse and rejects the rest. The new test asks both about the same inputs -- valid, blank, padded, bare, too short, virtual and family spellings -- and fails if they disagree. Making the boundary trim its input fails it on `" sm_86"`, which the build script would leave out while the backend selected it. The resolver's doc no longer says malformed hints are ignored, since the hint now reaches it parsed. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../src/target/tests/selection.rs | 34 +++++++++++++++++++ cuda-oxide/crates/cuda-target-spec/src/lib.rs | 6 ++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs index e11bcfd9a7..c6ef2a59c9 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs @@ -665,3 +665,37 @@ fn an_explicit_target_that_cannot_host_the_module_is_refused() { .is_err() ); } + +/// `cuda-device`'s build script reads `CUDA_OXIDE_DEVICE_ARCH` as +/// `value.parse::().ok()`. Its floor matches selection only while +/// the backend's input boundary accepts exactly those values and rejects the +/// rest before any target is chosen. +#[test] +fn the_build_script_reads_the_device_hint_as_the_backend_does() { + for raw in [ + "sm_75", + "sm_86", + "sm_120a", + "", + " ", + " sm_86", + "sm_86 ", + "86", + "sm_9", + "compute_86", + "sm_100f", + ] { + let build_script = raw.parse::().ok(); + let backend = crate::options::DeviceArchHint::from_env_value(Ok(raw.to_string())) + .expect("a set variable is a hint") + .as_device_arch() + .ok() + .cloned(); + assert_eq!(build_script, backend, "CUDA_OXIDE_DEVICE_ARCH={raw:?}"); + } + assert!( + crate::options::DeviceArchHint::from_env_value(Err(std::env::VarError::NotPresent)) + .is_none(), + "an unset variable is no hint on either side" + ); +} diff --git a/cuda-oxide/crates/cuda-target-spec/src/lib.rs b/cuda-oxide/crates/cuda-target-spec/src/lib.rs index e7ed477a7e..09a7908db8 100644 --- a/cuda-oxide/crates/cuda-target-spec/src/lib.rs +++ b/cuda-oxide/crates/cuda-target-spec/src/lib.rs @@ -578,9 +578,9 @@ pub const DEFAULT_SM_FLOOR: u32 = 80; /// `sm_80` floor because backend selection may override an incompatible hint. /// Both device cfg generation and backend selection use this rule. /// -/// Blank inputs are unset. Malformed explicit targets are errors; malformed -/// hints are ignored. Architecture suffixes do not affect this numeric floor, -/// which does not imply support for architecture-specific instruction families. +/// A blank target is unset and a malformed one is an error; the hint arrives +/// parsed. Architecture suffixes do not affect this numeric floor, which does +/// not imply support for architecture-specific instruction families. pub fn resolve_sm_floor( target: Option<&str>, device_arch: Option<&CudaArch>, From 5428da1bc3ae6c227e7df765319d3c7fc45625e7 Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:32:23 +0700 Subject: [PATCH 07/10] fix(nvvm-transforms): lower integer redux.sync to inline PTX for legacy NVVM LLVM 7 has no `llvm.nvvm.redux.sync.*`, so below sm_100, where the legacy dialect is used, libNVVM leaves the eight integer calls as `.extern .func` declarations that ptxas cannot parse. On this branch every integer `warp_reduce` and `block_reduce` at a floor of sm_80 or newer reaches them: `cargo oxide build warp_reduce_redux --materialize-cubin --arch sm_86` failed with `ptxas ... Parsing error near '.nvvm': syntax error`. Direct `redux_sync_*` callers already had the gap on main. `legalize_for_legacy_nvvm` now rewrites each call to its PTX instruction -- `redux.sync.{add,min,max}.s32`, `.{min,max}.u32`, `.{and,or,xor}.b32` -- as `=r,r,r` inline asm of the convergent kind, the way it already handles atomics LLVM 7 cannot express. The call's operands are already in PTX order (value, then member mask). Calls are validated before any rewrite, and the final subset check rejects one left behind. A unit test checks the exported LLVM 7 IR for all eight, including operand order and the `convergent` attribute, and a malformed signature is rejected. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../crates/nvvm-transforms/src/legalize.rs | 121 +++++++++++++++++- 1 file changed, 120 insertions(+), 1 deletion(-) diff --git a/cuda-oxide/crates/nvvm-transforms/src/legalize.rs b/cuda-oxide/crates/nvvm-transforms/src/legalize.rs index a3fb9f3e79..54e0d777bb 100644 --- a/cuda-oxide/crates/nvvm-transforms/src/legalize.rs +++ b/cuda-oxide/crates/nvvm-transforms/src/legalize.rs @@ -55,7 +55,8 @@ const NNEG_ATTR: &str = "llvm_nneg_flag"; /// and compare-exchange operations with stronger failure ordering are rewritten /// to inline PTX instead of weakening scope or ordering. Other atomic and fence /// operations return an error instead of being emitted with unverified -/// semantics. +/// semantics. Integer `redux.sync`, which LLVM 7 has no intrinsic for, becomes +/// convergent inline PTX. pub(crate) fn legalize_for_legacy_nvvm( ctx: &mut Context, module: Ptr, @@ -137,6 +138,9 @@ pub(crate) fn legalize_for_legacy_nvvm( } else if vote_mode(&name).is_some() { rewrite_vote(ctx, op, &name)?; obsolete_declarations.push(name); + } else if integer_redux_ptx(&name).is_some() { + rewrite_integer_redux(ctx, op, &name)?; + obsolete_declarations.push(name); } else if let Some(legacy_name) = legacy_memory_intrinsic_name(&name) { rewrite_renamed_call(ctx, op, &legacy_name)?; obsolete_declarations.push(name); @@ -1203,6 +1207,8 @@ fn validate_rewrite_candidate(ctx: &Context, op: Ptr) -> Result<()> { validate_shuffle_call(ctx, op, &name)?; } else if vote_mode(&name).is_some() { validate_vote_call(ctx, op, &name)?; + } else if integer_redux_ptx(&name).is_some() { + validate_integer_redux_call(ctx, op, &name)?; } Ok(()) } @@ -2011,6 +2017,57 @@ fn rewrite_vote(ctx: &mut Context, op: Ptr, name: &str) -> Result<()> replace_one_result(ctx, op, result) } +/// The PTX instruction for an integer `llvm.nvvm.redux.sync.*` call. +fn integer_redux_ptx(name: &str) -> Option<&'static str> { + match name { + "llvm_nvvm_redux_sync_add" => Some("redux.sync.add.s32"), + "llvm_nvvm_redux_sync_min" => Some("redux.sync.min.s32"), + "llvm_nvvm_redux_sync_max" => Some("redux.sync.max.s32"), + "llvm_nvvm_redux_sync_umin" => Some("redux.sync.min.u32"), + "llvm_nvvm_redux_sync_umax" => Some("redux.sync.max.u32"), + "llvm_nvvm_redux_sync_and" => Some("redux.sync.and.b32"), + "llvm_nvvm_redux_sync_or" => Some("redux.sync.or.b32"), + "llvm_nvvm_redux_sync_xor" => Some("redux.sync.xor.b32"), + _ => None, + } +} + +fn validate_integer_redux_call(ctx: &Context, op: Ptr, name: &str) -> Result<()> { + let operands: Vec<_> = op.deref(ctx).operands().collect(); + let i32_ty: TypeHandle = IntegerType::get(ctx, 32, Signedness::Signless).into(); + if operands.len() != 2 + || op.deref(ctx).get_num_results() != 1 + || operands + .iter() + .any(|operand| operand.get_type(ctx) != i32_ty) + || op.deref(ctx).get_result(0).get_type(ctx) != i32_ty + { + return pliron::input_err!( + op.deref(ctx).loc(), + "{name} must take (i32 value, i32 member mask) and return i32" + ); + } + Ok(()) +} + +/// Replace an integer `redux.sync` call with the same PTX instruction. The +/// call's operands are already in PTX order: value, then member mask. +fn rewrite_integer_redux(ctx: &mut Context, op: Ptr, name: &str) -> Result<()> { + let opcode = integer_redux_ptx(name).expect("validated redux name"); + let operands: Vec<_> = op.deref(ctx).operands().collect(); + let i32_ty: TypeHandle = IntegerType::get(ctx, 32, Signedness::Signless).into(); + let asm = llvm::InlineAsmOp::build( + ctx, + i32_ty, + operands, + &format!("{opcode} $0, $1, $2;"), + "=r,r,r", + AsmKind::Convergent, + ); + let result = insert_before(ctx, op, asm.get_operation()); + replace_one_result(ctx, op, result) +} + fn legacy_memory_intrinsic_name(name: &str) -> Option { for stem in ["memcpy", "memmove"] { if let Some(rest) = name.strip_prefix(&format!("llvm_{stem}_p")) { @@ -2148,6 +2205,7 @@ fn verify_legacy_subset(ctx: &Context, module: Ptr, capability: u32) || legacy_bit_rewrite(&name).is_some() || shuffle_mode(&name).is_some() || vote_mode(&name).is_some() + || integer_redux_ptx(&name).is_some() || legacy_memory_intrinsic_name(&name).is_some() { return pliron::input_err!( @@ -2830,6 +2888,67 @@ mod tests { module.get_operation().deref(&ctx).verify(&ctx).unwrap(); } + /// LLVM 7 has no `llvm.nvvm.redux.sync.*`, so legacy libNVVM would leave + /// these calls as undefined external functions that ptxas rejects. Each + /// becomes its PTX instruction, convergent, with the operands in the + /// intrinsic's order: value, then member mask. + #[test] + fn integer_redux_calls_become_convergent_inline_ptx() { + for (name, opcode) in [ + ("llvm_nvvm_redux_sync_add", "redux.sync.add.s32"), + ("llvm_nvvm_redux_sync_min", "redux.sync.min.s32"), + ("llvm_nvvm_redux_sync_max", "redux.sync.max.s32"), + ("llvm_nvvm_redux_sync_umin", "redux.sync.min.u32"), + ("llvm_nvvm_redux_sync_umax", "redux.sync.max.u32"), + ("llvm_nvvm_redux_sync_and", "redux.sync.and.b32"), + ("llvm_nvvm_redux_sync_or", "redux.sync.or.b32"), + ("llvm_nvvm_redux_sync_xor", "redux.sync.xor.b32"), + ] { + let mut ctx = Context::new(); + let module = ModuleOp::new(&mut ctx, name.try_into().unwrap()); + let i32_ty: TypeHandle = IntegerType::get(&ctx, 32, Signedness::Signless).into(); + direct_intrinsic_call(&mut ctx, &module, name, i32_ty, vec![i32_ty, i32_ty]); + + legalize_for_legacy_nvvm(&mut ctx, module.get_operation(), 80).unwrap(); + + module.get_operation().deref(&ctx).verify(&ctx).unwrap(); + let ir = export_module_to_string_with_config( + &ctx, + &module, + &NvvmExportConfig::new(NvvmIrDialect::LegacyLlvm7), + ) + .expect("legalized redux exports as LLVM 7 NVVM IR"); + let asm = format!( + r#"call i32 asm sideeffect "{opcode} $0, $1, $2;", "=r,r,r"(i32 %v0, i32 %v1) #0"# + ); + assert_eq!(ir.matches(&asm).count(), 1, "missing `{asm}`:\n{ir}"); + assert!(ir.contains("attributes #0 = { convergent }"), "{ir}"); + assert!(!ir.contains("llvm.nvvm.redux"), "{ir}"); + } + } + + /// The float forms need sm_100, which uses the modern dialect, so only + /// the eight integer calls are rewritten; a malformed one is an error. + #[test] + fn integer_redux_call_with_a_wrong_signature_is_rejected() { + let mut ctx = Context::new(); + let module = ModuleOp::new(&mut ctx, "redux_i64".try_into().unwrap()); + let i64_ty: TypeHandle = IntegerType::get(&ctx, 64, Signedness::Signless).into(); + let i32_ty: TypeHandle = IntegerType::get(&ctx, 32, Signedness::Signless).into(); + direct_intrinsic_call( + &mut ctx, + &module, + "llvm_nvvm_redux_sync_add", + i64_ty, + vec![i64_ty, i32_ty], + ); + + let error = legalize_for_legacy_nvvm(&mut ctx, module.get_operation(), 80).unwrap_err(); + let text = error.disp(&ctx).to_string(); + assert!(text.contains("llvm_nvvm_redux_sync_add"), "{text}"); + assert!(text.contains("return i32"), "{text}"); + } + #[test] fn f16_function_signature_is_rejected_without_needing_an_fneg() { let mut ctx = Context::new(); From b82f08ce24b02ac1e7f861bd220a4d52d0eccb1c Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:32:23 +0700 Subject: [PATCH 08/10] test(codegen): cover the floor's reject arm in honour_sm_floor A feature-selected target below the device-code floor is raised only when the floor can host the module. Nothing exercised the other outcome: a WGMMA module (sm_90a only) against a floor of 100 must be reported, not resolved to another architecture family. Controls: a floor the selection already meets leaves it alone, and one that can host the module raises it. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../src/target/tests/selection.rs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs index c6ef2a59c9..b65b21837b 100644 --- a/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs +++ b/cuda-oxide/crates/cuda-oxide-codegen/src/target/tests/selection.rs @@ -666,6 +666,29 @@ fn an_explicit_target_that_cannot_host_the_module_is_refused() { ); } +/// The floor's reject arm. A feature-selected target below the floor is +/// raised only when the floor can host the module: WGMMA exists only on +/// sm_90a, so a floor of 100 cannot, and that is reported instead of resolved +/// to another architecture family. +#[test] +fn a_floor_that_cannot_host_the_module_is_reported() { + let generated = crate::generated::GeneratedModuleRequirements::default(); + let sm_90a = "sm_90a".parse::().unwrap(); + + let error = + honour_sm_floor(sm_90a.clone(), 100, DetectedFeatures::Wgmma, &generated).unwrap_err(); + assert!(error.contains("compute capability 100"), "{error}"); + assert!(error.contains("run only on sm_90a"), "{error}"); + + // Controls: a floor the selection already meets leaves it alone, and one + // that can host the module raises it. + let kept = honour_sm_floor(sm_90a, 90, DetectedFeatures::Wgmma, &generated).unwrap(); + assert_eq!(kept.sm(), "sm_90a"); + let sm_75 = "sm_75".parse::().unwrap(); + let raised = honour_sm_floor(sm_75, 80, DetectedFeatures::Ldmatrix, &generated).unwrap(); + assert_eq!(raised.sm(), "sm_80"); +} + /// `cuda-device`'s build script reads `CUDA_OXIDE_DEVICE_ARCH` as /// `value.parse::().ok()`. Its floor matches selection only while /// the backend's input boundary accepts exactly those values and rejects the From 655a2ed67d7f3115926dba62a3dbbbd4906ac0c2 Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:32:23 +0700 Subject: [PATCH 09/10] test(examples): pin warp_reduce_redux's PTX shape and unsigned min/max The run only proves the answers, which the shuffle butterfly also produces. `verify-code-shape.sh` reads the PTX's own target: at sm_80 or newer the two integer kernels must hold exactly their `redux.sync` count and no `shfl.sync`, the f32 and sub-warp controls no `redux`, and below sm_80 no `redux` at all. Smoketest runs it after every build of the example. The u32 min/max inputs were 0..32, which read the same signed or unsigned, so a `min.s32` emitted for `min.u32` would have passed. Min and max now also run over `lane << 27`, which sets bit 31 on half the lanes: unsigned answers 0 and 0xF800_0000, signed would give 0x8000_0000 and 0x7800_0000. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../examples/warp_reduce_redux/src/main.rs | 29 +++++-- .../warp_reduce_redux/verify-code-shape.sh | 80 +++++++++++++++++++ 2 files changed, 103 insertions(+), 6 deletions(-) create mode 100755 cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/verify-code-shape.sh diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs index a9e9965cbe..526345c353 100644 --- a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/src/main.rs @@ -53,7 +53,12 @@ mod kernels { /// one lane. A reduction that silently dropped lanes could not produce /// those. /// - /// Lane 0 writes `[sum, min, max, and, or, xor]`. + /// Min and max run again over `l << 27`, which sets bit 31 on lanes 16..32. + /// Unsigned, the answers are `0` and `0xF800_0000`; a signed reduction + /// would read those lanes as negative and answer `0x8000_0000` and + /// `0x7800_0000`. + /// + /// Lane 0 writes `[sum, min, max, and, or, xor, min_high, max_high]`. #[kernel] pub fn reduce_u32_all_ops(mut out: DisjointSlice) { let warp = this_thread_block().tiled_partition::<32>(); @@ -61,6 +66,7 @@ mod kernels { let v_one = 1u32 << lane; let v_inv = !v_one; + let v_high = lane << 27; let r_sum = warp_reduce::(&warp, lane); let r_min = warp_reduce::(&warp, lane); @@ -68,9 +74,11 @@ mod kernels { let r_and = warp_reduce::(&warp, v_inv); let r_or = warp_reduce::(&warp, v_one); let r_xor = warp_reduce::(&warp, v_one); + let r_min_high = warp_reduce::(&warp, v_high); + let r_max_high = warp_reduce::(&warp, v_high); if lane == 0 { - // SAFETY: the host allocates six elements for this kernel. + // SAFETY: the host allocates eight elements for this kernel. unsafe { *out.get_unchecked_mut(0) = r_sum; *out.get_unchecked_mut(1) = r_min; @@ -78,6 +86,8 @@ mod kernels { *out.get_unchecked_mut(3) = r_and; *out.get_unchecked_mut(4) = r_or; *out.get_unchecked_mut(5) = r_xor; + *out.get_unchecked_mut(6) = r_min_high; + *out.get_unchecked_mut(7) = r_max_high; } } } @@ -188,14 +198,21 @@ fn main() { // ===== Test 1: every u32 op ===== println!("\n--- Test 1: warp_reduce over u32, all six ops ---"); - let mut u32_dev = DeviceBuffer::::zeroed(&stream, 6).unwrap(); + let mut u32_dev = DeviceBuffer::::zeroed(&stream, 8).unwrap(); // SAFETY: launch shape/resources match the kernel; the buffer covers its writes. unsafe { module.reduce_u32_all_ops((stream).as_ref(), cfg, &mut u32_dev) } .expect("Kernel launch failed"); let got = u32_dev.to_host_vec(&stream).unwrap(); - let want: [u32; 6] = [496, 0, 31, 0, u32::MAX, u32::MAX]; - println!("[sum, min, max, and, or, xor] = {:?}", got); - println!("expected = {:?}", want); + let want: [u32; 8] = [496, 0, 31, 0, u32::MAX, u32::MAX, 0, 0xF800_0000]; + println!( + "[sum, min, max, and, or, xor, min_high, max_high] = {:?}", + got + ); + println!( + "expected = {:?}", + want + ); + println!("(a signed min/max would read 2147483648 / 2013265920 for the last two)"); if got == want { println!("✓ every u32 reduction correct"); } else { diff --git a/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/verify-code-shape.sh b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/verify-code-shape.sh new file mode 100755 index 0000000000..41993a0cb5 --- /dev/null +++ b/cuda-oxide/crates/rustc-codegen-cuda/examples/warp_reduce_redux/verify-code-shape.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The runtime PASS gate only proves the reductions are correct, which the +# shuffle butterfly also achieves. Which form was emitted lives in the PTX: +# at a floor of sm_80 or newer each integer reduction must be one `redux.sync` +# and the butterfly must be gone; the f32 and sub-warp controls must never use +# `redux`; and below sm_80 no `redux` may appear at all. + +set -euo pipefail + +root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ptx="${root}/warp_reduce_redux.ptx" + +test -s "${ptx}" + +target="$(grep -m1 -oE '^\.target sm_[0-9]+' "${ptx}" | grep -oE '[0-9]+$')" || true +if [[ -z "${target}" ]]; then + echo "error: no .target sm_NN line in ${ptx}" >&2 + exit 1 +fi + +# Print the body of one PTX entry. Waits for the header's `{` so a forward +# declaration (which ends in `;`) is skipped. +entry_body() { + local symbol="$1" + awk -v marker="${symbol}(" ' + !emit && !candidate && index($0, marker) && index($0, ".entry") { + candidate = 1 + } + candidate && $0 ~ /^[[:space:]]*;[[:space:]]*$/ { + candidate = 0 + next + } + candidate && $0 ~ /^[[:space:]]*\{[[:space:]]*$/ { + emit = 1 + candidate = 0 + } + emit { print } + emit && index($0, "End function") != 0 { exit } + ' "${ptx}" +} + +# count : instructions in the kernel body whose opcode +# matches, anchored at instruction position so comments never count. +count() { + local symbol="$1" opcode="$2" body + body="$(entry_body "${symbol}")" + if [[ -z "${body}" ]]; then + echo "error: no .entry body found for ${symbol} in ${ptx}" >&2 + exit 1 + fi + grep -cE "^[[:space:]]*(@%p[0-9]+[[:space:]]+)?${opcode}" <<<"${body}" || true +} + +# require +require() { + local symbol="$1" opcode="$2" want="$3" got + got="$(count "${symbol}" "${opcode}")" + if [[ "${got}" -ne "${want}" ]]; then + echo "error: sm_${target}: ${symbol} has ${got}x ${opcode}, expected ${want}x in ${ptx}" >&2 + exit 1 + fi +} + +if [[ "${target}" -ge 80 ]]; then + # Six u32 ops plus the unsigned min/max over values above 2^31. + require reduce_u32_all_ops 'redux\.sync\.' 8 + require reduce_i32_signed_ops 'redux\.sync\.' 3 + require reduce_u32_all_ops 'shfl\.sync\.' 0 + require reduce_i32_signed_ops 'shfl\.sync\.' 0 +else + require reduce_u32_all_ops 'redux\.' 0 + require reduce_i32_signed_ops 'redux\.' 0 +fi +require reduce_f32_control 'redux\.' 0 +require reduce_subwarp_control 'redux\.' 0 + +echo "warp_reduce_redux code shape OK at sm_${target}" From 009946b831dfb665bd9128a888deb15f95394ced Mon Sep 17 00:00:00 2001 From: Vyncint Ng <115854244+vyncint@users.noreply.github.com> Date: Thu, 22 Oct 2026 10:32:23 +0700 Subject: [PATCH 10/10] docs: state the device-code floor where targets are chosen The warp chapter read as if `CUDA_OXIDE_DEVICE_ARCH` sets the floor; it can only lower the sm_80 default. The conditional-compilation section now says the `cuda_oxide_sm_at_least` ladder is private to `cuda-device`: a kernel crate sees it as false, with an `unexpected_cfgs` warning. Both target-precedence pages gain the floor raise of a feature-based default, and `reduce_full_warp`'s doc says it must be overridden whenever `HAS_FULL_WARP_FORM` is true. Signed-off-by: Vyncint Ng <115854244+vyncint@users.noreply.github.com> --- .../crates/cuda-device/src/cooperative_groups.rs | 4 +++- .../advanced/warp-level-programming.md | 11 +++++++---- .../cuda-oxide-book/compiler/lowering-pipeline.md | 5 ++++- .../cuda-oxide-book/compiler/rustc-codegen-cuda.md | 5 ++++- .../gpu-programming/kernels-and-device-functions.md | 5 ++++- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs b/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs index 21d0c5cda6..53cb0c0bd4 100644 --- a/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs +++ b/cuda-oxide/crates/cuda-device/src/cooperative_groups.rs @@ -915,7 +915,9 @@ pub mod ops { const HAS_FULL_WARP_FORM: bool = false; /// Reduce the participating warp. Called only when `HAS_FULL_WARP_FORM` - /// is true and the tile contains all 32 lanes. + /// is true and the tile contains all 32 lanes. An implementation that + /// sets `HAS_FULL_WARP_FORM` must override it: this default returns + /// `value` unreduced. #[inline(always)] fn reduce_full_warp(_mask: u32, value: T) -> T { value diff --git a/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md b/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md index 48ccdf93b6..254b82d7f1 100644 --- a/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md +++ b/cuda-oxide/cuda-oxide-book/advanced/warp-level-programming.md @@ -164,10 +164,13 @@ Three constraints: `warp_reduce` selects this form for you, for integer element types on a full 32-lane tile, whenever the build's compute-capability floor is `sm_80` or newer. That floor comes from the `cuda_oxide_sm_at_least` cfg, which -`cuda-device`'s build script derives from the same environment the backend -reads to choose a target: `CUDA_OXIDE_TARGET`, else `CUDA_OXIDE_DEVICE_ARCH`, -else `sm_80`. A cfg is resolved before rustc runs, so a build below the floor -drops the branch entirely and never emits an instruction it cannot assemble. +`cuda-device`'s build script derives with the same rule the backend uses to +choose a target. An explicit target (`--arch` or `CUDA_OXIDE_TARGET`) sets the +floor. Without one it is `sm_80`, or the detected GPU +(`CUDA_OXIDE_DEVICE_ARCH`) if that is older: a newer GPU never raises it, +because the backend may still build for an older architecture the kernel +needs. A cfg is resolved before rustc runs, so a build below the floor drops +the branch entirely and never emits an instruction it cannot assemble. Calling `redux_sync_add` and friends directly is still the right move when you want the single instruction regardless of the surrounding generic code, and it diff --git a/cuda-oxide/cuda-oxide-book/compiler/lowering-pipeline.md b/cuda-oxide/cuda-oxide-book/compiler/lowering-pipeline.md index 668013f72a..962f041f8c 100644 --- a/cuda-oxide/cuda-oxide-book/compiler/lowering-pipeline.md +++ b/cuda-oxide/cuda-oxide-book/compiler/lowering-pipeline.md @@ -612,7 +612,10 @@ to the backend so the generated module is guaranteed to load on the local GPU. The full precedence is `--arch` > `CUDA_OXIDE_TARGET` > host CC (for `run` only) > backend feature-based default. `cargo oxide build` and `cargo oxide pipeline` deliberately skip the host-CC step so they remain -usable for cross-compilation. +usable for cross-compilation. Without an explicit target, a feature-based +choice below the device-code floor -- `sm_80`, or the detected GPU if that is +older -- is raised to it, so the module never targets less than +`cuda-device`'s `cuda_oxide_sm_at_least` cfg assumed. If the lowered module calls CUDA libdevice, cuda-oxide switches from `llc` to the NVVM path automatically. It resolves the target with the same precedence diff --git a/cuda-oxide/cuda-oxide-book/compiler/rustc-codegen-cuda.md b/cuda-oxide/cuda-oxide-book/compiler/rustc-codegen-cuda.md index 683605591e..d3ad8e65ea 100644 --- a/cuda-oxide/cuda-oxide-book/compiler/rustc-codegen-cuda.md +++ b/cuda-oxide/cuda-oxide-book/compiler/rustc-codegen-cuda.md @@ -411,7 +411,10 @@ without fighting the compiler driver's flag plumbing. `CUDA_OXIDE_TARGET` sits in the middle of a precedence chain that `cargo oxide` honours: explicit `--arch` wins, then `CUDA_OXIDE_TARGET`, then `cargo oxide run`'s host-CC auto-detect (only for `run`, not `build` -or `pipeline`), and finally the backend's feature-based default. +or `pipeline`), and finally the backend's feature-based default. That default +is raised to the device-code floor -- `sm_80`, or the detected GPU if that is +older -- so the target never falls below what `cuda-device`'s +`cuda_oxide_sm_at_least` cfg assumed. ```{note} `CUDA_OXIDE_VERBOSE=1 cargo oxide build` is your best friend when debugging diff --git a/cuda-oxide/cuda-oxide-book/gpu-programming/kernels-and-device-functions.md b/cuda-oxide/cuda-oxide-book/gpu-programming/kernels-and-device-functions.md index 466a0e9617..4c2535012c 100644 --- a/cuda-oxide/cuda-oxide-book/gpu-programming/kernels-and-device-functions.md +++ b/cuda-oxide/cuda-oxide-book/gpu-programming/kernels-and-device-functions.md @@ -264,7 +264,10 @@ target-derived `cfg`, so a kernel has no way to ask which architecture it is being compiled for. Arch requirements live in doc comments and are enforced by the caller, which is why an example that needs `redux.sync` checks `ctx.compute_capability()` on the host and skips rather than specializing the -kernel. +kernel. `cuda-device` does derive a `cuda_oxide_sm_at_least` cfg for its own +`warp_reduce`, but a build script's `cfg` reaches only its own crate: in a +kernel crate the name is undeclared, so `#[cfg(cuda_oxide_sm_at_least = "80")]` +is always false and warns as `unexpected_cfgs`. `--device-cfg NAME` is how you supply one yourself. It is repeatable, and each occurrence becomes a `--cfg NAME` in the build's rustflags: