MCPcopy Create free account
hub / github.com/Rust-GPU/rust-cuda / main

Function main

examples/cuda/cpu/add/src/main.rs:10–78  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

8static PTX: &str = include_str!("../../../resources/add.ptx");
9
10fn main() -> Result<(), Box<dyn Error>> {
11 // generate our random vectors.
12 let mut wyrand = WyRand::new();
13 let mut lhs = vec![2.0f32; NUMBERS_LEN];
14 wyrand.fill(&mut lhs);
15 let mut rhs = vec![0.0f32; NUMBERS_LEN];
16 wyrand.fill(&mut rhs);
17
18 // initialize CUDA, this will pick the first available device and will
19 // make a CUDA context from it.
20 // We don't need the context for anything but it must be kept alive.
21 let _ctx = cust::quick_init()?;
22
23 // Make the CUDA module, modules just house the GPU code for the kernels we created.
24 // they can be made from PTX code, cubins, or fatbins.
25 let module = Module::from_ptx(PTX, &[])?;
26
27 // make a CUDA stream to issue calls to. You can think of this as an OS thread but for dispatching
28 // GPU calls.
29 let stream = Stream::new(StreamFlags::NON_BLOCKING, None)?;
30
31 // allocate the GPU memory needed to house our numbers and copy them over.
32 let lhs_gpu = lhs.as_slice().as_dbuf()?;
33 let rhs_gpu = rhs.as_slice().as_dbuf()?;
34
35 // allocate our output buffer. You could also use DeviceBuffer::uninitialized() to avoid the
36 // cost of the copy, but you need to be careful not to read from the buffer.
37 let mut out = vec![0.0f32; NUMBERS_LEN];
38 let out_buf = out.as_slice().as_dbuf()?;
39
40 // retrieve the add kernel from the module so we can calculate the right launch config.
41 let func = module.get_function("add")?;
42
43 // use the CUDA occupancy API to find an optimal launch configuration for the grid and block size.
44 // This will try to maximize how much of the GPU is used by finding the best launch configuration for the
45 // current CUDA device/architecture.
46 let (_, block_size) = func.suggested_launch_configuration(0, 0.into())?;
47
48 let grid_size = (NUMBERS_LEN as u32 + block_size - 1) / block_size;
49
50 println!(
51 "using {} blocks and {} threads per block",
52 grid_size, block_size
53 );
54
55 // Actually launch the GPU kernel. This will queue up the launch on the stream, it will
56 // not block the thread until the kernel is finished.
57 unsafe {
58 launch!(
59 // slices are passed as two parameters, the pointer and the length.
60 func<<<grid_size, block_size, 0, stream>>>(
61 lhs_gpu.as_device_ptr(),
62 lhs_gpu.len(),
63 rhs_gpu.as_device_ptr(),
64 rhs_gpu.len(),
65 out_buf.as_device_ptr(),
66 )
67 )?;

Callers

nothing calls this directly

Calls 8

newFunction · 0.85
quick_initFunction · 0.85
as_dbufMethod · 0.80
get_functionMethod · 0.80
as_sliceMethod · 0.45
synchronizeMethod · 0.45
copy_toMethod · 0.45

Tested by

no test coverage detected