Struct gpgpu::GpuBuffer [−][src]
pub struct GpuBuffer<'fw, T> { /* fields omitted */ }
Expand description
Vector of contiguous homogeneous elements on GPU memory.
Its elements must implement bytemuck::Pod
.
Equivalent to OpenCL’s Buffer objects.
More information about its shader representation is
under the DescriptorSet::bind_buffer
documentation.
Implementations
Pulls some elements from the GpuBuffer
into buf
, returning how many elements were read.
Blocking version of GpuBuffer::read()
.
Blocking version of GpuBuffer::read_vec()
.
Examples found in repository
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
fn main() {
let shader = Arc::new(
gpgpu::Shader::from_wgsl_file(&FW, "examples/parallel-compute/shader.wgsl").unwrap(),
);
let threading = 4; // Threading level
let size = 32000; // Must be multiple of 32
let cpu_data = (0..size).into_iter().collect::<Vec<u32>>();
let shader_input_buffer = Arc::new(gpgpu::GpuBuffer::from_slice(&FW, &cpu_data)); // Data shared across threads shader invocations
let mut handles = Vec::with_capacity(threading);
for _ in 0..threading {
let local_shader = shader.clone();
let local_shader_input_buffer = shader_input_buffer.clone();
// Threads spawn
let handle = std::thread::spawn(move || {
// Current thread GPU objects
let local_cpu_data = (0..size).into_iter().collect::<Vec<u32>>();
let local_input_buffer = gpgpu::GpuBuffer::from_slice(&FW, &local_cpu_data);
let local_output_buffer = gpgpu::GpuBuffer::<u32>::with_capacity(&FW, size as u64);
let desc = gpgpu::DescriptorSet::default()
.bind_buffer(&local_shader_input_buffer, gpgpu::GpuBufferUsage::ReadOnly)
.bind_buffer(&local_input_buffer, gpgpu::GpuBufferUsage::ReadOnly)
.bind_buffer(&local_output_buffer, gpgpu::GpuBufferUsage::ReadWrite);
let program = gpgpu::Program::new(&local_shader, "main").add_descriptor_set(desc);
gpgpu::Kernel::new(&FW, program).enqueue(size / 32, 1, 1);
local_output_buffer.read_vec_blocking().unwrap()
});
handles.push(handle);
}
// Join threads
for handle in handles {
let output = handle.join().unwrap();
for (idx, a) in cpu_data.iter().enumerate() {
let cpu_mult = a.pow(2);
let gpu_mult = output[idx];
assert_eq!(cpu_mult, gpu_mult);
}
}
}
More examples
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
fn main() {
let fw = gpgpu::Framework::default(); // Framework initialization.
let shader = gpgpu::Shader::from_wgsl_file(&fw, "examples/simple-compute/shader.wgsl").unwrap(); // Shader loading.
let size = 10000; // Size of the vectors
let data_a = (0..size).into_iter().collect::<Vec<u32>>(); // Vector A data. 0, 1, 2, ..., 9999 (size - 1).
let data_b = (0..size).into_iter().rev().collect::<Vec<u32>>(); // Vector B data. 9999 (size - 1), 9998, ..., 0.
// Allocation of new vectors on the GPU
let gpu_vec_a = gpgpu::GpuBuffer::from_slice(&fw, &data_a); // Input vector A.
let gpu_vec_b = gpgpu::GpuBuffer::from_slice(&fw, &data_b); // Input vector B.
let gpu_vec_c = gpgpu::GpuBuffer::with_capacity(&fw, size as u64); // Output vector C. Empty.
// We have to tell the GPU how the data is sent. Take a look at the shader (mult.wgsl).
// The boolean indicates wether the vector is read-only or not.
let bindings = gpgpu::DescriptorSet::default() // Group 0
.bind_buffer(&gpu_vec_a, gpgpu::GpuBufferUsage::ReadOnly) // Binding 0
.bind_buffer(&gpu_vec_b, gpgpu::GpuBufferUsage::ReadOnly) // Binding 1
.bind_buffer(&gpu_vec_c, gpgpu::GpuBufferUsage::ReadWrite); // Binding 2. read_write in shader. No write-only yet.
// Match a shader entry point with its descriptor (the bindings).
// A program represents a function on a GPU with an already set of inputs and outputs following a layout (the variable `bindings` above).
let program = gpgpu::Program::new(&shader, "main").add_descriptor_set(bindings);
// Creation of a kernel. This represents the `program` function and its `enqueuing` parameters,
let kernel = gpgpu::Kernel::new(&fw, program);
// Execution of the kernel. It needs 3 dimmensions, x y and z.
// Since we are using single-dim vectors, only x is required.
kernel.enqueue(size as u32, 1, 1);
// After the kernel execution, we can read the results from the GPU.
let gpu_result = gpu_vec_c.read_vec_blocking().unwrap();
// We test that the results are correct.
for (idx, (a, b)) in data_a.into_iter().zip(data_b).enumerate() {
let cpu_mult = a * b;
let gpu_mult = gpu_result[idx];
assert_eq!(cpu_mult, gpu_mult);
}
}
Writes a buffer into this GpuBuffer
, returning how many elements were written. The operation is instantly offloaded.
This function will attempt to write the entire contents of buf
unless its capacity
exceeds the one of the source buffer, in which case GpuBuffer::capacity()
elements are written.
Trait Implementations
Returns the wgpu::Buffer
that handles the GPU data of the buffer.
Constructs a new zeroed buffer with the specified capacity. Read more
Constructs a new buffer from a slice. Read more
Constructs a new buffer from a wgpu::Buffer
and its byte size
. Read more
Decomposes a buffer into a wgpu::Buffer
and its byte size
.
Returns a wgpu::BindingResource
of all the elements in the buffer.