oneapi_rs/buffer.rs
1//
2// Copyright (C) 2026 Intel Corporation
3//
4// Under the MIT License or the Apache License v2.0.
5// See LICENSE-MIT and LICENSE-APACHE for license information.
6// SPDX-License-Identifier: MIT OR Apache-2.0
7//
8
9use std::{alloc::{Layout, handle_alloc_error}, ops::{Deref, DerefMut}, ptr::NonNull, slice};
10
11use crate::usm::UsmAlloc;
12
13/// The Buffer struct defines a shared array of one, two or three dimensions that can be used
14/// by the SYCL kernel. Buffers are templated on the type of their data, and the number of
15/// dimensions that the data is stored and accessed through.
16///
17/// A Buffer does not map to only one underlying backend object, and all SYCL backend memory objects
18/// may be temporary for use on a specific device.
19///
20/// Buffers can be constructed by methods provided by the [`Queue`](`crate::queue::Queue`) class.
21///
22/// The Buffer struct template takes a template parameter [`UsmAlloc`](`crate::usm::UsmAlloc`) for
23/// specifying an allocator which is used by the SYCL runtime when allocating temporary memory on
24/// the host.
25pub struct Buffer<T, A: UsmAlloc> {
26 data: NonNull<T>,
27 len: usize,
28 layout: Layout,
29 allocator: A,
30}
31
32impl<T, A: UsmAlloc> Buffer<T, A> {
33 /// Creates a new buffer given an allocator.
34 /// Safety: returns uninitialized memory.
35 pub(crate) unsafe fn new(allocator: A, len: usize) -> Self {
36 let layout = Layout::array::<T>(len).unwrap();
37 let ptr = match allocator.allocate(layout.clone()) {
38 Ok(ptr) => ptr,
39 _ => handle_alloc_error(layout)
40 };
41
42 Self {
43 data: ptr.cast(),
44 len,
45 layout,
46 allocator,
47 }
48 }
49}
50
51impl<T, A: UsmAlloc> Deref for Buffer<T, A> {
52 type Target = [T];
53 fn deref(&self) -> &Self::Target {
54 unsafe {
55 slice::from_raw_parts(self.data.as_ptr(), self.len)
56 }
57 }
58}
59
60impl<T, A: UsmAlloc> DerefMut for Buffer<T, A> {
61 fn deref_mut(&mut self) -> &mut Self::Target {
62 unsafe {
63 slice::from_raw_parts_mut(self.data.as_ptr(), self.len)
64 }
65 }
66}
67
68impl<T, A: UsmAlloc> Drop for Buffer<T, A> {
69 fn drop(&mut self) {
70 unsafe { self.allocator.deallocate(self.data.cast(), self.layout); }
71 }
72}