Rust-GPU / Rust-CUDA

Ecosystem of libraries and tools for writing and executing fast GPU code fully in Rust.
Apache License 2.0
2.97k stars 112 forks source link

Is it possible to copy data to device constant memory? #88

Open patrickcsullivan opened 1 year ago

patrickcsullivan commented 1 year ago

When using C CUDA it's possible to allocate constant memory on the GPU by using cudaMemcpyToSymbol rather than cudaMemcpy. Is there a similar mechanism in the cust library for copying an array with a constant size from the host to the device constant memory?

RDambrosio016 commented 1 year ago

I believe module::Symbol's impl of CopyDestination should work for this, i don't think the driver API actually has memcpyToSymbol, at least from what i can see, we just use HtoD memcpys which will probably work the same.

patrickcsullivan commented 1 year ago

Thanks for the response!

Using module::Symbol makes sense to me. However, do you know how I can declare a variable in my GPU module so that it is compiled as a global symbol which I can then access by calling the Module::get_global function?

Here’s an example of what I’m trying to do:

// GPU Code

use cuda_std::prelude::*;

// I assume this is the wrong way to declare a global symbol.
// If this were C CUDA, then I'd annotate MY_NUM with __const__
pub static MY_NUM: i64 = 0;

#[kernel]
#[allow(improper_ctypes_definitions, clippy::missing_safety_doc)]
pub unsafe fn simple_kernel(out: *mut i64, n: usize) {
    let mut tid = (thread::thread_idx_x() + thread::block_idx_x() * thread::block_dim_x()) as usize;
    while tid < n {
        *out.add(tid) = MY_NUM;
        tid += (thread::block_dim_x() * thread::grid_dim_x()) as usize;
    }
}
// CPU Code

let _ctx = cust::quick_init()?;
let module = Module::from_ptx(PTX, &[])?;
let kernel = module.get_function("simple_kernel")?;

let symbol_name = CString::new("MY_NUM")?;
let mut symbol = module.get_global::<i64>(symbol_name.as_c_str())?;

let my_num: i64 = 1234;
symbol.copy_from(&my_num)?;

When I run this I get the following error:

Error: NotFound

I assume that MY_NUM is not getting compiled as a global symbol, so module.get_global can’t find it.

If I were writing C CUDA then I assume I’d need to annotate MY_NUM with __const__. Do you know what I need to do in my Rust GPU code to ensure that MY_NUM gets compiled as a global symbol?

Stock84-dev commented 7 months ago
#[no_mangle]
static DATA: [f32; 1024] = [0.; 1024];