Skip to main content

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}