use crate::Error;
pub const MAX_TENSOR_RANK: usize = metal_rust_ffi::MAX_TENSOR_RANK;
#[derive(Clone)]
pub struct TensorBufferAttachment {
buffer: crate::metal::Buffer,
offset: usize,
layout: TensorLayout,
}
impl TensorBufferAttachment {
#[must_use]
pub const fn buffer(&self) -> &crate::metal::Buffer {
&self.buffer
}
#[must_use]
pub const fn offset(&self) -> usize {
self.offset
}
#[must_use]
pub const fn layout(&self) -> &TensorLayout {
&self.layout
}
}
pub struct CheckedTensorBufferAttachments {
inner: metal_rust_ffi::CheckedTensorBufferAttachments,
}
impl CheckedTensorBufferAttachments {
pub fn new() -> Result<Self, Error> {
metal_rust_ffi::CheckedTensorBufferAttachments::new()
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn set_buffer(
&mut self,
plane: crate::metal::TensorPlaneType,
buffer: &crate::metal::Buffer,
offset: usize,
layout: &TensorLayout,
) -> Result<(), Error> {
self.inner
.set_buffer(plane, &buffer.inner, offset, &layout.inner)
.map_err(Error::from_ffi)
}
pub fn buffer(
&self,
plane: crate::metal::TensorPlaneType,
) -> Result<Option<crate::metal::Buffer>, Error> {
self.inner
.buffer(plane)
.map(|value| value.map(crate::metal::Buffer::from_ffi))
.map_err(Error::from_ffi)
}
pub fn offset(&self, plane: crate::metal::TensorPlaneType) -> Result<Option<usize>, Error> {
self.inner.offset(plane).map_err(Error::from_ffi)
}
pub fn attachment(
&self,
plane: crate::metal::TensorPlaneType,
) -> Result<Option<TensorBufferAttachment>, Error> {
self.inner
.attachment(plane)
.map(|value| {
value.map(|attachment| TensorBufferAttachment {
buffer: crate::metal::Buffer::from_ffi(attachment.buffer().clone()),
offset: attachment.offset(),
layout: TensorLayout {
inner: attachment.layout().clone(),
},
})
})
.map_err(Error::from_ffi)
}
pub fn reset(&mut self) -> Result<(), Error> {
self.inner.reset().map_err(Error::from_ffi)
}
pub(crate) const fn as_ffi(&self) -> &metal_rust_ffi::CheckedTensorBufferAttachments {
&self.inner
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CheckedTensorExtents {
pub(crate) inner: metal_rust_ffi::CheckedTensorExtents,
}
impl CheckedTensorExtents {
pub fn new(values: &[usize]) -> Result<Self, Error> {
metal_rust_ffi::CheckedTensorExtents::new(values)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
#[must_use]
pub fn rank(&self) -> usize {
self.inner.rank()
}
#[must_use]
pub fn get(&self, dimension: usize) -> Option<usize> {
self.inner.get(dimension)
}
#[must_use]
pub fn as_slice(&self) -> &[usize] {
self.inner.as_slice()
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct TensorLayout {
inner: metal_rust_ffi::TensorLayout,
}
impl TensorLayout {
pub fn dense(
dimensions: &[usize],
data_type: crate::metal::TensorDataType,
) -> Result<Self, Error> {
metal_rust_ffi::TensorLayout::dense(dimensions, data_type)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn strided(
dimensions: &[usize],
strides: &[usize],
data_type: crate::metal::TensorDataType,
) -> Result<Self, Error> {
metal_rust_ffi::TensorLayout::strided(dimensions, strides, data_type)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
pub fn machine_learning(
dimensions: &[usize],
strides: &[usize],
data_type: crate::metal::TensorDataType,
) -> Result<Self, Error> {
metal_rust_ffi::TensorLayout::machine_learning(dimensions, strides, data_type)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
#[must_use]
pub fn dimensions(&self) -> &[usize] {
self.inner.dimensions().as_slice()
}
#[must_use]
pub fn strides(&self) -> &[usize] {
self.inner.strides().as_slice()
}
#[must_use]
pub const fn data_type(&self) -> crate::metal::TensorDataType {
self.inner.data_type()
}
#[must_use]
pub const fn byte_span(&self) -> usize {
self.inner.byte_span()
}
pub fn checked_buffer_range(
&self,
buffer_length: usize,
offset: usize,
usage: crate::metal::TensorUsage,
) -> Result<std::ops::Range<usize>, Error> {
self.inner
.checked_buffer_range(buffer_length, offset, usage)
.map_err(Error::from_ffi)
}
}
#[derive(Clone)]
pub struct CheckedTensorDescriptor {
inner: metal_rust_ffi::CheckedTensorDescriptor,
}
impl CheckedTensorDescriptor {
pub fn new(
layout: TensorLayout,
usage: crate::metal::TensorUsage,
resource_options: crate::metal::ResourceOptions,
) -> Result<Self, Error> {
metal_rust_ffi::CheckedTensorDescriptor::new(layout.inner, usage, resource_options)
.map(|inner| Self { inner })
.map_err(Error::from_ffi)
}
#[must_use]
pub fn dimensions(&self) -> &[usize] {
self.inner.layout().dimensions().as_slice()
}
#[must_use]
pub fn strides(&self) -> &[usize] {
self.inner.layout().strides().as_slice()
}
#[must_use]
pub const fn byte_span(&self) -> usize {
self.inner.layout().byte_span()
}
#[must_use]
pub const fn usage(&self) -> crate::metal::TensorUsage {
self.inner.usage()
}
#[must_use]
pub const fn resource_options(&self) -> crate::metal::ResourceOptions {
self.inner.resource_options()
}
pub fn checked_buffer_range(
&self,
buffer_length: usize,
offset: usize,
) -> Result<std::ops::Range<usize>, Error> {
self.inner
.checked_buffer_range(buffer_length, offset)
.map_err(Error::from_ffi)
}
pub(crate) const fn as_ffi(&self) -> &metal_rust_ffi::CheckedTensorDescriptor {
&self.inner
}
}
impl crate::generated_facade::metal::TensorAuxiliaryPlaneDescriptorMap {
pub fn set_descriptor(
&self,
plane: crate::metal::TensorPlaneType,
descriptor: &crate::metal::TensorAuxiliaryPlaneDescriptor,
) -> Result<(), Error> {
self.inner
.set_descriptor(plane, &descriptor.inner)
.map_err(Error::from_ffi)
}
pub fn descriptor(
&self,
plane: crate::metal::TensorPlaneType,
) -> Result<Option<crate::metal::TensorAuxiliaryPlaneDescriptor>, Error> {
self.inner
.descriptor(plane)
.map(|value| value.map(crate::metal::TensorAuxiliaryPlaneDescriptor::from_ffi))
.map_err(Error::from_ffi)
}
pub fn reset(&self) -> Result<(), Error> {
self.inner.reset().map_err(Error::from_ffi)
}
}
impl crate::generated_facade::metal::Tensor {
pub fn gpu_resource_id(&self) -> Result<crate::metal::ResourceID, Error> {
self.inner.gpu_resource_id().map_err(Error::from_ffi)
}
pub fn auxiliary_plane_objects(
&self,
) -> Result<Vec<crate::metal::TensorAuxiliaryPlane>, Error> {
self.inner
.auxiliary_plane_objects()
.map(|values| {
values
.into_iter()
.map(crate::metal::TensorAuxiliaryPlane::from_ffi)
.collect()
})
.map_err(Error::from_ffi)
}
pub fn read_slice(
&self,
origin: &[usize],
dimensions: &[usize],
memory_layout: &TensorLayout,
) -> Result<Vec<u8>, Error> {
self.inner
.read_slice(origin, dimensions, &memory_layout.inner)
.map_err(Error::from_ffi)
}
pub fn read_plane_slice(
&self,
origin: &[usize],
dimensions: &[usize],
memory_layout: &TensorLayout,
plane: crate::metal::TensorPlaneType,
) -> Result<Vec<u8>, Error> {
self.inner
.read_plane_slice(origin, dimensions, &memory_layout.inner, plane)
.map_err(Error::from_ffi)
}
pub fn write_slice(
&self,
origin: &[usize],
dimensions: &[usize],
memory_layout: &TensorLayout,
bytes: &[u8],
) -> Result<(), Error> {
self.inner
.write_slice(origin, dimensions, &memory_layout.inner, bytes)
.map_err(Error::from_ffi)
}
pub fn write_plane_slice(
&self,
origin: &[usize],
dimensions: &[usize],
memory_layout: &TensorLayout,
plane: crate::metal::TensorPlaneType,
bytes: &[u8],
) -> Result<(), Error> {
self.inner
.write_plane_slice(origin, dimensions, &memory_layout.inner, plane, bytes)
.map_err(Error::from_ffi)
}
}