mlx_c_rust/compile/
swiglu.rs1use std::os::raw::c_int;
2
3use crate::MlxBindingsContext;
4use crate::{MlxArray, MlxStream, raw};
5use crate::{
6 MlxCError,
7 compile::graph::{MlxCompiledGraph, array_from_vector, graph_output_array, set_graph_output},
8};
9
10const APPLY_COMPILED_SWIGLU_OPERATION: &str = "apply a compiled MLX SwiGLU graph";
11const COMPILE_SWIGLU_OPERATION: &str = "compile a shapeless MLX SwiGLU graph";
12
13#[derive(Debug)]
15pub struct MlxCompiledSwiGlu {
16 compiled_graph: MlxCompiledGraph,
17}
18
19impl MlxCompiledSwiGlu {
20 pub fn new() -> Result<Self, MlxCError> {
22 Ok(Self {
23 compiled_graph: MlxCompiledGraph::new(
24 build_swiglu_graph,
25 COMPILE_SWIGLU_OPERATION,
26 true,
27 )?,
28 })
29 }
30}
31
32impl MlxBindingsContext {
33 pub fn apply_compiled_swiglu(
35 &self,
36 compiled_swiglu: &MlxCompiledSwiGlu,
37 gate: &MlxArray,
38 input: &MlxArray,
39 ) -> Result<MlxArray, MlxCError> {
40 compiled_swiglu
41 .compiled_graph
42 .apply(&[gate, input], APPLY_COMPILED_SWIGLU_OPERATION)
43 }
44}
45
46unsafe extern "C" fn build_swiglu_graph(
47 output_vector: *mut raw::mlx_vector_array,
48 input_vector: raw::mlx_vector_array,
49) -> c_int {
50 if output_vector.is_null() {
51 return 1;
52 }
53 if unsafe { raw::mlx_vector_array_size(input_vector) } != 2 {
54 return 1;
55 }
56 let gate = match array_from_vector(input_vector, 0) {
57 Ok(gate) => gate,
58 Err(status) => return status,
59 };
60 let input = match array_from_vector(input_vector, 1) {
61 Ok(input) => input,
62 Err(status) => return status,
63 };
64 let gpu_stream = match MlxStream::default_gpu() {
65 Ok(gpu_stream) => gpu_stream,
66 Err(_) => return 1,
67 };
68 let sigmoid_gate = match graph_output_array(|output| {
69 unsafe { raw::mlx_sigmoid(output, gate.raw(), gpu_stream.raw()) }
71 }) {
72 Ok(sigmoid_gate) => sigmoid_gate,
73 Err(status) => return status,
74 };
75 let activated_gate = match graph_output_array(|output| {
76 unsafe { raw::mlx_multiply(output, gate.raw(), sigmoid_gate.raw(), gpu_stream.raw()) }
78 }) {
79 Ok(activated_gate) => activated_gate,
80 Err(status) => return status,
81 };
82 let swiglu_output = match graph_output_array(|output| {
83 unsafe { raw::mlx_multiply(output, activated_gate.raw(), input.raw(), gpu_stream.raw()) }
85 }) {
86 Ok(swiglu_output) => swiglu_output,
87 Err(status) => return status,
88 };
89 unsafe { set_graph_output(output_vector, &swiglu_output) }
91}