Skip to main content

MatrixMultiplication

Struct MatrixMultiplication 

Source
pub struct MatrixMultiplication { /* private fields */ }

Implementations§

Source§

impl MatrixMultiplication

Source

pub const fn as_ptr(&self) -> *mut c_void

Source§

impl MatrixMultiplication

Source

pub fn new( device: &MetalDevice, descriptor: MatrixMultiplicationDescriptor, ) -> Option<Self>

Build a configurable GEMM kernel with optional transposition and scaling.

Source

pub fn new_simple( device: &MetalDevice, result_rows: usize, result_columns: usize, interior_columns: usize, ) -> Option<Self>

Convenience constructor for the common C = A * B case.

Examples found in repository?
examples/02_matrix_multiply.rs (line 67)
20fn main() {
21    let device = MetalDevice::system_default().expect("no Metal device available");
22    let queue = device
23        .new_command_queue()
24        .expect("failed to create command queue");
25
26    let left_desc = MatrixDescriptor::contiguous(2, 3, data_type::FLOAT32)
27        .expect("FLOAT32 matrix descriptor should be supported");
28    let right_desc = MatrixDescriptor::contiguous(3, 2, data_type::FLOAT32)
29        .expect("FLOAT32 matrix descriptor should be supported");
30    let result_desc = MatrixDescriptor::contiguous(2, 2, data_type::FLOAT32)
31        .expect("FLOAT32 matrix descriptor should be supported");
32
33    let left_buffer = device
34        .new_buffer(
35            left_desc.matrix_bytes,
36            resource_options::STORAGE_MODE_SHARED,
37        )
38        .expect("failed to allocate left buffer");
39    let right_buffer = device
40        .new_buffer(
41            right_desc.matrix_bytes,
42            resource_options::STORAGE_MODE_SHARED,
43        )
44        .expect("failed to allocate right buffer");
45    let result_buffer = device
46        .new_buffer(
47            result_desc.matrix_bytes,
48            resource_options::STORAGE_MODE_SHARED,
49        )
50        .expect("failed to allocate result buffer");
51
52    let left_values = [1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0];
53    let right_values = [7.0_f32, 8.0, 9.0, 10.0, 11.0, 12.0];
54    let zeros = [0.0_f32; 4];
55
56    let _ = left_buffer.write_bytes(as_bytes(&left_values));
57    let _ = right_buffer.write_bytes(as_bytes(&right_values));
58    let _ = result_buffer.write_bytes(as_bytes(&zeros));
59
60    let left =
61        Matrix::new_with_buffer(&left_buffer, left_desc).expect("failed to wrap left matrix");
62    let right =
63        Matrix::new_with_buffer(&right_buffer, right_desc).expect("failed to wrap right matrix");
64    let result =
65        Matrix::new_with_buffer(&result_buffer, result_desc).expect("failed to wrap result matrix");
66
67    let gemm = MatrixMultiplication::new_simple(&device, 2, 2, 3)
68        .expect("failed to create matrix multiplication kernel");
69    let command_buffer = queue
70        .new_command_buffer()
71        .expect("failed to allocate command buffer");
72    gemm.encode(&command_buffer, &left, &right, &result);
73    command_buffer.commit();
74    command_buffer.wait_until_completed();
75
76    let output = read_f32s(&result_buffer, 4);
77    let expected = [58.0_f32, 64.0, 139.0, 154.0];
78    for (actual, expected_value) in output.iter().zip(expected) {
79        assert!(
80            (actual - expected_value).abs() < 1.0e-4,
81            "unexpected matrix multiply result: {output:?}"
82        );
83    }
84
85    println!("matmul smoke passed: {output:?}");
86}
Source

pub fn encode( &self, command_buffer: &CommandBuffer, left: &Matrix, right: &Matrix, result: &Matrix, )

Encode the matrix multiplication onto a command buffer.

Examples found in repository?
examples/02_matrix_multiply.rs (line 72)
20fn main() {
21    let device = MetalDevice::system_default().expect("no Metal device available");
22    let queue = device
23        .new_command_queue()
24        .expect("failed to create command queue");
25
26    let left_desc = MatrixDescriptor::contiguous(2, 3, data_type::FLOAT32)
27        .expect("FLOAT32 matrix descriptor should be supported");
28    let right_desc = MatrixDescriptor::contiguous(3, 2, data_type::FLOAT32)
29        .expect("FLOAT32 matrix descriptor should be supported");
30    let result_desc = MatrixDescriptor::contiguous(2, 2, data_type::FLOAT32)
31        .expect("FLOAT32 matrix descriptor should be supported");
32
33    let left_buffer = device
34        .new_buffer(
35            left_desc.matrix_bytes,
36            resource_options::STORAGE_MODE_SHARED,
37        )
38        .expect("failed to allocate left buffer");
39    let right_buffer = device
40        .new_buffer(
41            right_desc.matrix_bytes,
42            resource_options::STORAGE_MODE_SHARED,
43        )
44        .expect("failed to allocate right buffer");
45    let result_buffer = device
46        .new_buffer(
47            result_desc.matrix_bytes,
48            resource_options::STORAGE_MODE_SHARED,
49        )
50        .expect("failed to allocate result buffer");
51
52    let left_values = [1.0_f32, 2.0, 3.0, 4.0, 5.0, 6.0];
53    let right_values = [7.0_f32, 8.0, 9.0, 10.0, 11.0, 12.0];
54    let zeros = [0.0_f32; 4];
55
56    let _ = left_buffer.write_bytes(as_bytes(&left_values));
57    let _ = right_buffer.write_bytes(as_bytes(&right_values));
58    let _ = result_buffer.write_bytes(as_bytes(&zeros));
59
60    let left =
61        Matrix::new_with_buffer(&left_buffer, left_desc).expect("failed to wrap left matrix");
62    let right =
63        Matrix::new_with_buffer(&right_buffer, right_desc).expect("failed to wrap right matrix");
64    let result =
65        Matrix::new_with_buffer(&result_buffer, result_desc).expect("failed to wrap result matrix");
66
67    let gemm = MatrixMultiplication::new_simple(&device, 2, 2, 3)
68        .expect("failed to create matrix multiplication kernel");
69    let command_buffer = queue
70        .new_command_buffer()
71        .expect("failed to allocate command buffer");
72    gemm.encode(&command_buffer, &left, &right, &result);
73    command_buffer.commit();
74    command_buffer.wait_until_completed();
75
76    let output = read_f32s(&result_buffer, 4);
77    let expected = [58.0_f32, 64.0, 139.0, 154.0];
78    for (actual, expected_value) in output.iter().zip(expected) {
79        assert!(
80            (actual - expected_value).abs() < 1.0e-4,
81            "unexpected matrix multiply result: {output:?}"
82        );
83    }
84
85    println!("matmul smoke passed: {output:?}");
86}

Trait Implementations§

Source§

impl Drop for MatrixMultiplication

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for MatrixMultiplication

Source§

impl Sync for MatrixMultiplication

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.