Skip to content

Commit 68a9509

Browse files
committed
constant memory overspill handling
- if constant memory overspill, automatically move that static to global and throw a warning intead of failing - statics are packed in first-come-first-serve order, user can manually overrides this
1 parent e5a4085 commit 68a9509

4 files changed

Lines changed: 47 additions & 32 deletions

File tree

crates/cuda_builder/src/lib.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ pub struct CudaBuilder {
201201
/// Exceeding the limit may cause `IllegalAddress` runtime
202202
/// errors (CUDA error code: `700`).
203203
///
204+
/// Statics are placed on a first-come-first-served basis in the order the
205+
/// codegen encounters them. When the cumulative size would exceed the 64KB
206+
/// limit, the overflowing static is automatically spilled to global memory
207+
/// with a compile-time warning. Subsequent smaller statics may still fit
208+
/// and will continue to be placed in constant memory. This means the
209+
/// codegen does not optimize for the "best" packing — it simply fills
210+
/// constant memory in encounter order.
211+
///
204212
/// The default is `false`, which places all statics in global memory. This avoids
205213
/// such errors but may reduce performance and use more general memory. When set to
206214
/// `false`, you can still annotate `static` variables with
@@ -210,6 +218,8 @@ pub struct CudaBuilder {
210218
/// Use [`place_static`](Self::place_static) and
211219
/// [`crate_memory_space`](Self::crate_memory_space) to override placement for
212220
/// individual statics or entire crates (including third-party crates).
221+
/// These overrides let you prioritize performance-critical statics for
222+
/// constant memory regardless of encounter order.
213223
pub use_constant_memory_space: bool,
214224
/// Per-static memory placement overrides. Keys are Rust path strings
215225
/// (e.g., `"my_crate::module::MY_STATIC"`). These take priority over per-crate
@@ -370,6 +380,14 @@ impl CudaBuilder {
370380
/// Exceeding the limit may cause `IllegalAddress` runtime
371381
/// errors (CUDA error code: `700`).
372382
///
383+
/// Statics are placed on a first-come-first-served basis in the order the
384+
/// codegen encounters them. When the cumulative size would exceed the 64KB
385+
/// limit, the overflowing static is automatically spilled to global memory
386+
/// with a compile-time warning. Subsequent smaller statics may still fit
387+
/// and will continue to be placed in constant memory. This means the
388+
/// codegen does not optimize for the "best" packing — it simply fills
389+
/// constant memory in encounter order.
390+
///
373391
/// If `false`, all statics are placed in global memory. This avoids such errors but
374392
/// may reduce performance and use more general memory. You can still annotate
375393
/// `static` variables with `#[cuda_std::address_space(constant)]` to place them in
@@ -378,6 +396,8 @@ impl CudaBuilder {
378396
/// Use [`place_static`](Self::place_static) and
379397
/// [`crate_memory_space`](Self::crate_memory_space) to override placement for
380398
/// individual statics or entire crates.
399+
/// These overrides let you prioritize performance-critical statics for
400+
/// constant memory regardless of encounter order.
381401
pub fn use_constant_memory_space(mut self, use_constant_memory_space: bool) -> Self {
382402
self.use_constant_memory_space = use_constant_memory_space;
383403
self

crates/rustc_codegen_nvvm/src/context.rs

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -366,37 +366,27 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
366366
}
367367

368368
// Check if adding this static would exceed the cumulative limit
369+
// Auto-spill to global memory with a warning instead of failing
369370
if new_usage > CONSTANT_MEMORY_SIZE_LIMIT_BYTES {
370371
let def_id = instance.def_id();
371372
let span = self.tcx.def_span(def_id);
372-
let mut diag = self.tcx.sess.dcx().struct_span_err(
373-
span,
374-
format!(
375-
"cannot place static `{instance}` ({size_bytes} bytes) in constant memory: \
376-
cumulative constant memory usage would be {new_usage} bytes, exceeding the {} byte limit",
377-
CONSTANT_MEMORY_SIZE_LIMIT_BYTES
378-
),
379-
);
380-
diag.span_label(
373+
let remaining = CONSTANT_MEMORY_SIZE_LIMIT_BYTES.saturating_sub(current_usage);
374+
let mut diag = self.tcx.sess.dcx().struct_span_warn(
381375
span,
382376
format!(
383-
"this static would cause total usage to exceed {} bytes",
377+
"constant memory overflow: static `{instance}` ({size_bytes} bytes) does not fit in remaining \
378+
constant memory ({remaining} bytes free of {} bytes total)",
384379
CONSTANT_MEMORY_SIZE_LIMIT_BYTES
385380
),
386381
);
382+
diag.span_label(span, "automatically placed in global memory");
387383
diag.note(format!(
388-
"current constant memory usage: {current_usage} bytes"
384+
"current constant memory usage: {current_usage} / {} bytes",
385+
CONSTANT_MEMORY_SIZE_LIMIT_BYTES
389386
));
390-
diag.note(format!("static size: {size_bytes} bytes"));
391-
diag.note(format!("would result in: {new_usage} bytes total"));
392-
393-
diag.help("move this or other statics to global memory using `#[cuda_std::address_space(global)]` or `.place_static(\"path\", MemorySpace::Global)` in build.rs");
394-
diag.help("reduce the total size of static data");
395-
diag.help("disable automatic constant memory placement by setting `.use_constant_memory_space(false)` on `CudaBuilder` in build.rs");
396-
387+
diag.help("use `.place_static(\"path\", MemorySpace::Constant)` in build.rs to prioritize specific statics for constant memory");
397388
diag.emit();
398-
self.tcx.sess.dcx().abort_if_errors();
399-
unreachable!()
389+
return AddressSpace(1);
400390
}
401391

402392
// If successfully placed in constant memory: update cumulative usage

tests/compiletests/ui/lang/consts/constant_memory_overflow.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// Test that automatic constant memory placement fails when exceeding the 64KB limit
2-
// This test creates multiple large static arrays that together exceed the limit
1+
// Test that automatic constant memory placement spills to global with a warning
2+
// when exceeding the 64KB limit
33

44
// compile-flags: -Cllvm-args=--use-constant-memory-space
55

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
error: cannot place static `BIG_ARRAY_2` (35840 bytes) in constant memory: cumulative constant memory usage would be 71680 bytes, exceeding the 65536 byte limit
1+
warning: constant memory overflow: static `BIG_ARRAY_2` (35840 bytes) does not fit in remaining constant memory (29696 bytes free of 65536 bytes total)
22
--> $DIR/constant_memory_overflow.rs:15:1
33
|
44
LL | static BIG_ARRAY_2: [u32; ARRAY_SIZE] = [222u32; ARRAY_SIZE];
5-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this static would cause total usage to exceed 65536 bytes
6-
|
7-
= note: current constant memory usage: 35840 bytes
8-
= note: static size: 35840 bytes
9-
= note: would result in: 71680 bytes total
10-
= help: move this or other statics to global memory using `#[cuda_std::address_space(global)]`
11-
= help: reduce the total size of static data
12-
= help: disable automatic constant memory placement by setting `.use_constant_memory_space(false)` on `CudaBuilder` in build.rs
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ automatically placed in global memory
6+
|
7+
= note: current constant memory usage: 35840 / 65536 bytes
8+
= help: use `.place_static("path", MemorySpace::Constant)` in build.rs to prioritize specific statics for constant memory
9+
10+
warning: constant memory overflow: static `BIG_ARRAY_3` (35840 bytes) does not fit in remaining constant memory (29696 bytes free of 65536 bytes total)
11+
--> $DIR/constant_memory_overflow.rs:16:1
12+
|
13+
LL | static BIG_ARRAY_3: [u32; ARRAY_SIZE] = [333u32; ARRAY_SIZE];
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ automatically placed in global memory
15+
|
16+
= note: current constant memory usage: 35840 / 65536 bytes
17+
= help: use `.place_static("path", MemorySpace::Constant)` in build.rs to prioritize specific statics for constant memory
1318

14-
error: aborting due to 1 previous error
19+
warning: 2 warnings emitted
1520

0 commit comments

Comments
 (0)