Files
ollama/x/imagegen/mlx/mlx.h
Daniel Hiltgen 534342e7e2 Update MLX and MLX-C with threading fixes (#15845)
* Update MLX and MLX-C

* Run MLX CGO work on a locked OS thread

MLX now relies on OS-thread-local execution state for streams, encoders, and caches. Add an mlxthread executor backed by runtime.LockOSThread and route runner initialization, model load, inference, status memory reads, and cleanup through the worker so Go goroutine migration cannot split MLX state across native threads.

Also stop caching default MLX streams before the runner owns the thread and add worker/threaded MLX regression tests.

* mlx: use common status writer

* mlx: bundle missing libjaccl on arm64

Inspired by #15793

* review comments
2026-05-03 10:03:14 -07:00

2518 lines
143 KiB
C

// AUTO-GENERATED by generate_wrappers.go - DO NOT EDIT
// This file provides wrapper declarations for MLX-C functions that use dlopen/dlsym
//
// Strategy: Include MLX-C headers for type definitions, then provide wrapper
// functions that shadow the originals, allowing Go code to call them directly (e.g., C.mlx_add).
// Function pointers are defined in mlx.c (single compilation unit).
#ifndef MLX_WRAPPERS_H
#define MLX_WRAPPERS_H
// Include MLX headers for type definitions and original declarations
#include "mlx/c/mlx.h"
#include "mlx_dynamic.h"
#include <stdio.h>
// Undefine any existing MLX function macros
#undef mlx_dtype_size
#undef mlx_array_tostring
#undef mlx_array_new
#undef mlx_array_free
#undef mlx_array_new_bool
#undef mlx_array_new_int
#undef mlx_array_new_float32
#undef mlx_array_new_float
#undef mlx_array_new_float64
#undef mlx_array_new_double
#undef mlx_array_new_complex
#undef mlx_array_new_data
#undef mlx_array_new_data_managed
#undef mlx_array_new_data_managed_payload
#undef mlx_array_set
#undef mlx_array_set_bool
#undef mlx_array_set_int
#undef mlx_array_set_float32
#undef mlx_array_set_float
#undef mlx_array_set_float64
#undef mlx_array_set_double
#undef mlx_array_set_complex
#undef mlx_array_set_data
#undef mlx_array_itemsize
#undef mlx_array_size
#undef mlx_array_nbytes
#undef mlx_array_ndim
#undef mlx_array_shape
#undef mlx_array_strides
#undef mlx_array_dim
#undef mlx_array_dtype
#undef mlx_array_eval
#undef mlx_array_item_bool
#undef mlx_array_item_uint8
#undef mlx_array_item_uint16
#undef mlx_array_item_uint32
#undef mlx_array_item_uint64
#undef mlx_array_item_int8
#undef mlx_array_item_int16
#undef mlx_array_item_int32
#undef mlx_array_item_int64
#undef mlx_array_item_float32
#undef mlx_array_item_float64
#undef mlx_array_item_complex64
#undef mlx_array_item_float16
#undef mlx_array_item_bfloat16
#undef mlx_array_data_bool
#undef mlx_array_data_uint8
#undef mlx_array_data_uint16
#undef mlx_array_data_uint32
#undef mlx_array_data_uint64
#undef mlx_array_data_int8
#undef mlx_array_data_int16
#undef mlx_array_data_int32
#undef mlx_array_data_int64
#undef mlx_array_data_float32
#undef mlx_array_data_float64
#undef mlx_array_data_complex64
#undef mlx_array_data_float16
#undef mlx_array_data_bfloat16
#undef _mlx_array_is_available
#undef _mlx_array_wait
#undef _mlx_array_is_contiguous
#undef _mlx_array_is_row_contiguous
#undef _mlx_array_is_col_contiguous
#undef mlx_closure_new
#undef mlx_closure_free
#undef mlx_closure_new_func
#undef mlx_closure_new_func_payload
#undef mlx_closure_set
#undef mlx_closure_apply
#undef mlx_closure_new_unary
#undef mlx_closure_kwargs_new
#undef mlx_closure_kwargs_free
#undef mlx_closure_kwargs_new_func
#undef mlx_closure_kwargs_new_func_payload
#undef mlx_closure_kwargs_set
#undef mlx_closure_kwargs_apply
#undef mlx_closure_value_and_grad_new
#undef mlx_closure_value_and_grad_free
#undef mlx_closure_value_and_grad_new_func
#undef mlx_closure_value_and_grad_new_func_payload
#undef mlx_closure_value_and_grad_set
#undef mlx_closure_value_and_grad_apply
#undef mlx_closure_custom_new
#undef mlx_closure_custom_free
#undef mlx_closure_custom_new_func
#undef mlx_closure_custom_new_func_payload
#undef mlx_closure_custom_set
#undef mlx_closure_custom_apply
#undef mlx_closure_custom_jvp_new
#undef mlx_closure_custom_jvp_free
#undef mlx_closure_custom_jvp_new_func
#undef mlx_closure_custom_jvp_new_func_payload
#undef mlx_closure_custom_jvp_set
#undef mlx_closure_custom_jvp_apply
#undef mlx_closure_custom_vmap_new
#undef mlx_closure_custom_vmap_free
#undef mlx_closure_custom_vmap_new_func
#undef mlx_closure_custom_vmap_new_func_payload
#undef mlx_closure_custom_vmap_set
#undef mlx_closure_custom_vmap_apply
#undef mlx_compile
#undef mlx_detail_compile
#undef mlx_detail_compile_clear_cache
#undef mlx_detail_compile_erase
#undef mlx_disable_compile
#undef mlx_enable_compile
#undef mlx_set_compile_mode
#undef mlx_cuda_is_available
#undef mlx_device_new
#undef mlx_device_new_type
#undef mlx_device_free
#undef mlx_device_set
#undef mlx_device_tostring
#undef mlx_device_equal
#undef mlx_device_get_index
#undef mlx_device_get_type
#undef mlx_get_default_device
#undef mlx_set_default_device
#undef mlx_device_is_available
#undef mlx_device_count
#undef mlx_device_info_new
#undef mlx_device_info_get
#undef mlx_device_info_free
#undef mlx_device_info_has_key
#undef mlx_device_info_is_string
#undef mlx_device_info_get_string
#undef mlx_device_info_get_size
#undef mlx_device_info_get_keys
#undef mlx_distributed_all_gather
#undef mlx_distributed_all_max
#undef mlx_distributed_all_min
#undef mlx_distributed_all_sum
#undef mlx_distributed_recv
#undef mlx_distributed_recv_like
#undef mlx_distributed_send
#undef mlx_distributed_sum_scatter
#undef mlx_distributed_group_new
#undef mlx_distributed_group_free
#undef mlx_distributed_init
#undef mlx_distributed_group_rank
#undef mlx_distributed_group_size
#undef mlx_distributed_group_split
#undef mlx_distributed_is_available
#undef mlx_set_error_handler
#undef _mlx_error
#undef mlx_export_function
#undef mlx_export_function_kwargs
#undef mlx_function_exporter_new
#undef mlx_function_exporter_free
#undef mlx_function_exporter_apply
#undef mlx_function_exporter_apply_kwargs
#undef mlx_imported_function_new
#undef mlx_imported_function_free
#undef mlx_imported_function_apply
#undef mlx_imported_function_apply_kwargs
#undef mlx_fast_cuda_kernel_config_new
#undef mlx_fast_cuda_kernel_config_free
#undef mlx_fast_cuda_kernel_config_add_output_arg
#undef mlx_fast_cuda_kernel_config_set_grid
#undef mlx_fast_cuda_kernel_config_set_thread_group
#undef mlx_fast_cuda_kernel_config_set_init_value
#undef mlx_fast_cuda_kernel_config_set_verbose
#undef mlx_fast_cuda_kernel_config_add_template_arg_dtype
#undef mlx_fast_cuda_kernel_config_add_template_arg_int
#undef mlx_fast_cuda_kernel_config_add_template_arg_bool
#undef mlx_fast_cuda_kernel_new
#undef mlx_fast_cuda_kernel_free
#undef mlx_fast_cuda_kernel_apply
#undef mlx_fast_layer_norm
#undef mlx_fast_metal_kernel_config_new
#undef mlx_fast_metal_kernel_config_free
#undef mlx_fast_metal_kernel_config_add_output_arg
#undef mlx_fast_metal_kernel_config_set_grid
#undef mlx_fast_metal_kernel_config_set_thread_group
#undef mlx_fast_metal_kernel_config_set_init_value
#undef mlx_fast_metal_kernel_config_set_verbose
#undef mlx_fast_metal_kernel_config_add_template_arg_dtype
#undef mlx_fast_metal_kernel_config_add_template_arg_int
#undef mlx_fast_metal_kernel_config_add_template_arg_bool
#undef mlx_fast_metal_kernel_new
#undef mlx_fast_metal_kernel_free
#undef mlx_fast_metal_kernel_apply
#undef mlx_fast_rms_norm
#undef mlx_fast_rope
#undef mlx_fast_rope_dynamic
#undef mlx_fast_scaled_dot_product_attention
#undef mlx_fft_fft
#undef mlx_fft_fft2
#undef mlx_fft_fftfreq
#undef mlx_fft_fftn
#undef mlx_fft_fftshift
#undef mlx_fft_ifft
#undef mlx_fft_ifft2
#undef mlx_fft_ifftn
#undef mlx_fft_ifftshift
#undef mlx_fft_irfft
#undef mlx_fft_irfft2
#undef mlx_fft_irfftn
#undef mlx_fft_rfft
#undef mlx_fft_rfft2
#undef mlx_fft_rfftfreq
#undef mlx_fft_rfftn
#undef mlx_node_namer_free
#undef mlx_node_namer_set_name
#undef mlx_node_namer_get_name
#undef mlx_export_to_dot
#undef mlx_print_graph
#undef mlx_load_reader
#undef mlx_load
#undef mlx_load_gguf
#undef mlx_load_safetensors_reader
#undef mlx_load_safetensors
#undef mlx_save_writer
#undef mlx_save
#undef mlx_save_gguf
#undef mlx_save_safetensors_writer
#undef mlx_save_safetensors
#undef mlx_io_reader_new
#undef mlx_io_reader_descriptor
#undef mlx_io_reader_tostring
#undef mlx_io_reader_free
#undef mlx_io_writer_new
#undef mlx_io_writer_descriptor
#undef mlx_io_writer_tostring
#undef mlx_io_writer_free
#undef mlx_io_gguf_new
#undef mlx_io_gguf_free
#undef mlx_io_gguf_get_keys
#undef mlx_io_gguf_get_array
#undef mlx_io_gguf_get_metadata_array
#undef mlx_io_gguf_get_metadata_string
#undef mlx_io_gguf_get_metadata_vector_string
#undef mlx_io_gguf_has_metadata_array
#undef mlx_io_gguf_has_metadata_string
#undef mlx_io_gguf_has_metadata_vector_string
#undef mlx_io_gguf_set_array
#undef mlx_io_gguf_set_metadata_array
#undef mlx_io_gguf_set_metadata_string
#undef mlx_io_gguf_set_metadata_vector_string
#undef mlx_linalg_cholesky
#undef mlx_linalg_cholesky_inv
#undef mlx_linalg_cross
#undef mlx_linalg_eig
#undef mlx_linalg_eigh
#undef mlx_linalg_eigvals
#undef mlx_linalg_eigvalsh
#undef mlx_linalg_inv
#undef mlx_linalg_lu
#undef mlx_linalg_lu_factor
#undef mlx_linalg_norm
#undef mlx_linalg_norm_matrix
#undef mlx_linalg_norm_l2
#undef mlx_linalg_pinv
#undef mlx_linalg_qr
#undef mlx_linalg_solve
#undef mlx_linalg_solve_triangular
#undef mlx_linalg_svd
#undef mlx_linalg_tri_inv
#undef mlx_map_string_to_array_new
#undef mlx_map_string_to_array_set
#undef mlx_map_string_to_array_free
#undef mlx_map_string_to_array_insert
#undef mlx_map_string_to_array_get
#undef mlx_map_string_to_array_iterator_new
#undef mlx_map_string_to_array_iterator_free
#undef mlx_map_string_to_array_iterator_next
#undef mlx_map_string_to_string_new
#undef mlx_map_string_to_string_set
#undef mlx_map_string_to_string_free
#undef mlx_map_string_to_string_insert
#undef mlx_map_string_to_string_get
#undef mlx_map_string_to_string_iterator_new
#undef mlx_map_string_to_string_iterator_free
#undef mlx_map_string_to_string_iterator_next
#undef mlx_clear_cache
#undef mlx_get_active_memory
#undef mlx_get_cache_memory
#undef mlx_get_memory_limit
#undef mlx_get_peak_memory
#undef mlx_reset_peak_memory
#undef mlx_set_cache_limit
#undef mlx_set_memory_limit
#undef mlx_set_wired_limit
#undef mlx_metal_is_available
#undef mlx_metal_start_capture
#undef mlx_metal_stop_capture
#undef mlx_abs
#undef mlx_add
#undef mlx_addmm
#undef mlx_all_axes
#undef mlx_all_axis
#undef mlx_all
#undef mlx_allclose
#undef mlx_any_axes
#undef mlx_any_axis
#undef mlx_any
#undef mlx_arange
#undef mlx_arccos
#undef mlx_arccosh
#undef mlx_arcsin
#undef mlx_arcsinh
#undef mlx_arctan
#undef mlx_arctan2
#undef mlx_arctanh
#undef mlx_argmax_axis
#undef mlx_argmax
#undef mlx_argmin_axis
#undef mlx_argmin
#undef mlx_argpartition_axis
#undef mlx_argpartition
#undef mlx_argsort_axis
#undef mlx_argsort
#undef mlx_array_equal
#undef mlx_as_strided
#undef mlx_astype
#undef mlx_atleast_1d
#undef mlx_atleast_2d
#undef mlx_atleast_3d
#undef mlx_bartlett
#undef mlx_bitwise_and
#undef mlx_bitwise_invert
#undef mlx_bitwise_or
#undef mlx_bitwise_xor
#undef mlx_blackman
#undef mlx_block_masked_mm
#undef mlx_broadcast_arrays
#undef mlx_broadcast_to
#undef mlx_ceil
#undef mlx_clip
#undef mlx_concatenate_axis
#undef mlx_concatenate
#undef mlx_conjugate
#undef mlx_contiguous
#undef mlx_conv1d
#undef mlx_conv2d
#undef mlx_conv3d
#undef mlx_conv_general
#undef mlx_conv_transpose1d
#undef mlx_conv_transpose2d
#undef mlx_conv_transpose3d
#undef mlx_copy
#undef mlx_cos
#undef mlx_cosh
#undef mlx_cummax
#undef mlx_cummin
#undef mlx_cumprod
#undef mlx_cumsum
#undef mlx_degrees
#undef mlx_depends
#undef mlx_dequantize
#undef mlx_diag
#undef mlx_diagonal
#undef mlx_divide
#undef mlx_divmod
#undef mlx_einsum
#undef mlx_equal
#undef mlx_erf
#undef mlx_erfinv
#undef mlx_exp
#undef mlx_expand_dims_axes
#undef mlx_expand_dims
#undef mlx_expm1
#undef mlx_eye
#undef mlx_flatten
#undef mlx_floor
#undef mlx_floor_divide
#undef mlx_from_fp8
#undef mlx_full
#undef mlx_full_like
#undef mlx_gather
#undef mlx_gather_single
#undef mlx_gather_mm
#undef mlx_gather_qmm
#undef mlx_greater
#undef mlx_greater_equal
#undef mlx_hadamard_transform
#undef mlx_hamming
#undef mlx_hanning
#undef mlx_identity
#undef mlx_imag
#undef mlx_inner
#undef mlx_isclose
#undef mlx_isfinite
#undef mlx_isinf
#undef mlx_isnan
#undef mlx_isneginf
#undef mlx_isposinf
#undef mlx_kron
#undef mlx_left_shift
#undef mlx_less
#undef mlx_less_equal
#undef mlx_linspace
#undef mlx_log
#undef mlx_log10
#undef mlx_log1p
#undef mlx_log2
#undef mlx_logaddexp
#undef mlx_logcumsumexp
#undef mlx_logical_and
#undef mlx_logical_not
#undef mlx_logical_or
#undef mlx_logsumexp_axes
#undef mlx_logsumexp_axis
#undef mlx_logsumexp
#undef mlx_masked_scatter
#undef mlx_matmul
#undef mlx_max_axes
#undef mlx_max_axis
#undef mlx_max
#undef mlx_maximum
#undef mlx_mean_axes
#undef mlx_mean_axis
#undef mlx_mean
#undef mlx_median
#undef mlx_meshgrid
#undef mlx_min_axes
#undef mlx_min_axis
#undef mlx_min
#undef mlx_minimum
#undef mlx_moveaxis
#undef mlx_multiply
#undef mlx_nan_to_num
#undef mlx_negative
#undef mlx_not_equal
#undef mlx_number_of_elements
#undef mlx_ones
#undef mlx_ones_like
#undef mlx_outer
#undef mlx_pad
#undef mlx_pad_symmetric
#undef mlx_partition_axis
#undef mlx_partition
#undef mlx_power
#undef mlx_prod_axes
#undef mlx_prod_axis
#undef mlx_prod
#undef mlx_put_along_axis
#undef mlx_qqmm
#undef mlx_quantize
#undef mlx_quantized_matmul
#undef mlx_radians
#undef mlx_real
#undef mlx_reciprocal
#undef mlx_remainder
#undef mlx_repeat_axis
#undef mlx_repeat
#undef mlx_reshape
#undef mlx_right_shift
#undef mlx_roll_axis
#undef mlx_roll_axes
#undef mlx_roll
#undef mlx_round
#undef mlx_rsqrt
#undef mlx_scatter
#undef mlx_scatter_single
#undef mlx_scatter_add
#undef mlx_scatter_add_single
#undef mlx_scatter_add_axis
#undef mlx_scatter_max
#undef mlx_scatter_max_single
#undef mlx_scatter_min
#undef mlx_scatter_min_single
#undef mlx_scatter_prod
#undef mlx_scatter_prod_single
#undef mlx_segmented_mm
#undef mlx_sigmoid
#undef mlx_sign
#undef mlx_sin
#undef mlx_sinh
#undef mlx_slice
#undef mlx_slice_dynamic
#undef mlx_slice_update
#undef mlx_slice_update_dynamic
#undef mlx_slice_update_add
#undef mlx_slice_update_max
#undef mlx_slice_update_min
#undef mlx_slice_update_prod
#undef mlx_softmax_axes
#undef mlx_softmax_axis
#undef mlx_softmax
#undef mlx_sort_axis
#undef mlx_sort
#undef mlx_split
#undef mlx_split_sections
#undef mlx_sqrt
#undef mlx_square
#undef mlx_squeeze_axes
#undef mlx_squeeze_axis
#undef mlx_squeeze
#undef mlx_stack_axis
#undef mlx_stack
#undef mlx_std_axes
#undef mlx_std_axis
#undef mlx_std
#undef mlx_stop_gradient
#undef mlx_subtract
#undef mlx_sum_axes
#undef mlx_sum_axis
#undef mlx_sum
#undef mlx_swapaxes
#undef mlx_take_axis
#undef mlx_take
#undef mlx_take_along_axis
#undef mlx_tan
#undef mlx_tanh
#undef mlx_tensordot
#undef mlx_tensordot_axis
#undef mlx_tile
#undef mlx_to_fp8
#undef mlx_topk_axis
#undef mlx_topk
#undef mlx_trace
#undef mlx_transpose_axes
#undef mlx_transpose
#undef mlx_tri
#undef mlx_tril
#undef mlx_triu
#undef mlx_unflatten
#undef mlx_var_axes
#undef mlx_var_axis
#undef mlx_var
#undef mlx_view
#undef mlx_where
#undef mlx_zeros
#undef mlx_zeros_like
#undef mlx_random_bernoulli
#undef mlx_random_bits
#undef mlx_random_categorical_shape
#undef mlx_random_categorical_num_samples
#undef mlx_random_categorical
#undef mlx_random_gumbel
#undef mlx_random_key
#undef mlx_random_laplace
#undef mlx_random_multivariate_normal
#undef mlx_random_normal_broadcast
#undef mlx_random_normal
#undef mlx_random_permutation
#undef mlx_random_permutation_arange
#undef mlx_random_randint
#undef mlx_random_seed
#undef mlx_random_split_num
#undef mlx_random_split
#undef mlx_random_truncated_normal
#undef mlx_random_uniform
#undef mlx_stream_new
#undef mlx_stream_new_device
#undef mlx_stream_set
#undef mlx_stream_free
#undef mlx_stream_tostring
#undef mlx_stream_equal
#undef mlx_stream_get_device
#undef mlx_stream_get_index
#undef mlx_synchronize
#undef mlx_get_default_stream
#undef mlx_set_default_stream
#undef mlx_default_cpu_stream_new
#undef mlx_default_gpu_stream_new
#undef mlx_string_new
#undef mlx_string_new_data
#undef mlx_string_set
#undef mlx_string_data
#undef mlx_string_free
#undef mlx_async_eval
#undef mlx_checkpoint
#undef mlx_custom_function
#undef mlx_custom_vjp
#undef mlx_eval
#undef mlx_jvp
#undef mlx_value_and_grad
#undef mlx_vjp
#undef mlx_detail_vmap_replace
#undef mlx_detail_vmap_trace
#undef mlx_vector_array_new
#undef mlx_vector_array_set
#undef mlx_vector_array_free
#undef mlx_vector_array_new_data
#undef mlx_vector_array_new_value
#undef mlx_vector_array_set_data
#undef mlx_vector_array_set_value
#undef mlx_vector_array_append_data
#undef mlx_vector_array_append_value
#undef mlx_vector_array_size
#undef mlx_vector_array_get
#undef mlx_vector_vector_array_new
#undef mlx_vector_vector_array_set
#undef mlx_vector_vector_array_free
#undef mlx_vector_vector_array_new_data
#undef mlx_vector_vector_array_new_value
#undef mlx_vector_vector_array_set_data
#undef mlx_vector_vector_array_set_value
#undef mlx_vector_vector_array_append_data
#undef mlx_vector_vector_array_append_value
#undef mlx_vector_vector_array_size
#undef mlx_vector_vector_array_get
#undef mlx_vector_int_new
#undef mlx_vector_int_set
#undef mlx_vector_int_free
#undef mlx_vector_int_new_data
#undef mlx_vector_int_new_value
#undef mlx_vector_int_set_data
#undef mlx_vector_int_set_value
#undef mlx_vector_int_append_data
#undef mlx_vector_int_append_value
#undef mlx_vector_int_size
#undef mlx_vector_int_get
#undef mlx_vector_string_new
#undef mlx_vector_string_set
#undef mlx_vector_string_free
#undef mlx_vector_string_new_data
#undef mlx_vector_string_new_value
#undef mlx_vector_string_set_data
#undef mlx_vector_string_set_value
#undef mlx_vector_string_append_data
#undef mlx_vector_string_append_value
#undef mlx_vector_string_size
#undef mlx_vector_string_get
#undef mlx_version
// Function pointer declarations (defined in mlx.c, loaded via dlsym)
extern size_t (*mlx_dtype_size_ptr)(mlx_dtype dtype);
extern int (*mlx_array_tostring_ptr)(mlx_string* str, const mlx_array arr);
extern mlx_array (*mlx_array_new_ptr)(void);
extern int (*mlx_array_free_ptr)(mlx_array arr);
extern mlx_array (*mlx_array_new_bool_ptr)(bool val);
extern mlx_array (*mlx_array_new_int_ptr)(int val);
extern mlx_array (*mlx_array_new_float32_ptr)(float val);
extern mlx_array (*mlx_array_new_float_ptr)(float val);
extern mlx_array (*mlx_array_new_float64_ptr)(double val);
extern mlx_array (*mlx_array_new_double_ptr)(double val);
extern mlx_array (*mlx_array_new_complex_ptr)(float real_val, float imag_val);
extern mlx_array (*mlx_array_new_data_ptr)(const void* data, const int* shape, int dim, mlx_dtype dtype);
extern mlx_array (*mlx_array_new_data_managed_ptr)(void* data, const int* shape, int dim, mlx_dtype dtype, void (*dtor)(void*));
extern mlx_array (*mlx_array_new_data_managed_payload_ptr)(void* data, const int* shape, int dim, mlx_dtype dtype, void* payload, void (*dtor)(void*));
extern int (*mlx_array_set_ptr)(mlx_array* arr, const mlx_array src);
extern int (*mlx_array_set_bool_ptr)(mlx_array* arr, bool val);
extern int (*mlx_array_set_int_ptr)(mlx_array* arr, int val);
extern int (*mlx_array_set_float32_ptr)(mlx_array* arr, float val);
extern int (*mlx_array_set_float_ptr)(mlx_array* arr, float val);
extern int (*mlx_array_set_float64_ptr)(mlx_array* arr, double val);
extern int (*mlx_array_set_double_ptr)(mlx_array* arr, double val);
extern int (*mlx_array_set_complex_ptr)(mlx_array* arr, float real_val, float imag_val);
extern int (*mlx_array_set_data_ptr)(mlx_array* arr, const void* data, const int* shape, int dim, mlx_dtype dtype);
extern size_t (*mlx_array_itemsize_ptr)(const mlx_array arr);
extern size_t (*mlx_array_size_ptr)(const mlx_array arr);
extern size_t (*mlx_array_nbytes_ptr)(const mlx_array arr);
extern size_t (*mlx_array_ndim_ptr)(const mlx_array arr);
extern const int* (*mlx_array_shape_ptr)(const mlx_array arr);
extern const size_t* (*mlx_array_strides_ptr)(const mlx_array arr);
extern int (*mlx_array_dim_ptr)(const mlx_array arr, int dim);
extern mlx_dtype (*mlx_array_dtype_ptr)(const mlx_array arr);
extern int (*mlx_array_eval_ptr)(mlx_array arr);
extern int (*mlx_array_item_bool_ptr)(bool* res, const mlx_array arr);
extern int (*mlx_array_item_uint8_ptr)(uint8_t* res, const mlx_array arr);
extern int (*mlx_array_item_uint16_ptr)(uint16_t* res, const mlx_array arr);
extern int (*mlx_array_item_uint32_ptr)(uint32_t* res, const mlx_array arr);
extern int (*mlx_array_item_uint64_ptr)(uint64_t* res, const mlx_array arr);
extern int (*mlx_array_item_int8_ptr)(int8_t* res, const mlx_array arr);
extern int (*mlx_array_item_int16_ptr)(int16_t* res, const mlx_array arr);
extern int (*mlx_array_item_int32_ptr)(int32_t* res, const mlx_array arr);
extern int (*mlx_array_item_int64_ptr)(int64_t* res, const mlx_array arr);
extern int (*mlx_array_item_float32_ptr)(float* res, const mlx_array arr);
extern int (*mlx_array_item_float64_ptr)(double* res, const mlx_array arr);
extern int (*mlx_array_item_complex64_ptr)(mlx_complex64_t* res, const mlx_array arr);
#if defined(__aarch64__) || defined(_M_ARM64)
extern int (*mlx_array_item_float16_ptr)(float16_t* res, const mlx_array arr);
#endif
#if defined(__aarch64__) || defined(_M_ARM64)
extern int (*mlx_array_item_bfloat16_ptr)(bfloat16_t* res, const mlx_array arr);
#endif
extern const bool* (*mlx_array_data_bool_ptr)(const mlx_array arr);
extern const uint8_t* (*mlx_array_data_uint8_ptr)(const mlx_array arr);
extern const uint16_t* (*mlx_array_data_uint16_ptr)(const mlx_array arr);
extern const uint32_t* (*mlx_array_data_uint32_ptr)(const mlx_array arr);
extern const uint64_t* (*mlx_array_data_uint64_ptr)(const mlx_array arr);
extern const int8_t* (*mlx_array_data_int8_ptr)(const mlx_array arr);
extern const int16_t* (*mlx_array_data_int16_ptr)(const mlx_array arr);
extern const int32_t* (*mlx_array_data_int32_ptr)(const mlx_array arr);
extern const int64_t* (*mlx_array_data_int64_ptr)(const mlx_array arr);
extern const float* (*mlx_array_data_float32_ptr)(const mlx_array arr);
extern const double* (*mlx_array_data_float64_ptr)(const mlx_array arr);
extern const mlx_complex64_t* (*mlx_array_data_complex64_ptr)(const mlx_array arr);
#if defined(__aarch64__) || defined(_M_ARM64)
extern const float16_t* (*mlx_array_data_float16_ptr)(const mlx_array arr);
#endif
#if defined(__aarch64__) || defined(_M_ARM64)
extern const bfloat16_t* (*mlx_array_data_bfloat16_ptr)(const mlx_array arr);
#endif
extern int (*_mlx_array_is_available_ptr)(bool* res, const mlx_array arr);
extern int (*_mlx_array_wait_ptr)(const mlx_array arr);
extern int (*_mlx_array_is_contiguous_ptr)(bool* res, const mlx_array arr);
extern int (*_mlx_array_is_row_contiguous_ptr)(bool* res, const mlx_array arr);
extern int (*_mlx_array_is_col_contiguous_ptr)(bool* res, const mlx_array arr);
extern mlx_closure (*mlx_closure_new_ptr)(void);
extern int (*mlx_closure_free_ptr)(mlx_closure cls);
extern mlx_closure (*mlx_closure_new_func_ptr)(int (*fun)(mlx_vector_array*, const mlx_vector_array));
extern mlx_closure (*mlx_closure_new_func_payload_ptr)(int (*fun)(mlx_vector_array*, const mlx_vector_array, void*), void* payload, void (*dtor)(void*));
extern int (*mlx_closure_set_ptr)(mlx_closure* cls, const mlx_closure src);
extern int (*mlx_closure_apply_ptr)(mlx_vector_array* res, mlx_closure cls, const mlx_vector_array input);
extern mlx_closure (*mlx_closure_new_unary_ptr)(int (*fun)(mlx_array*, const mlx_array));
extern mlx_closure_kwargs (*mlx_closure_kwargs_new_ptr)(void);
extern int (*mlx_closure_kwargs_free_ptr)(mlx_closure_kwargs cls);
extern mlx_closure_kwargs (*mlx_closure_kwargs_new_func_ptr)(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_map_string_to_array));
extern mlx_closure_kwargs (*mlx_closure_kwargs_new_func_payload_ptr)(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_map_string_to_array, void*), void* payload, void (*dtor)(void*));
extern int (*mlx_closure_kwargs_set_ptr)(mlx_closure_kwargs* cls, const mlx_closure_kwargs src);
extern int (*mlx_closure_kwargs_apply_ptr)(mlx_vector_array* res, mlx_closure_kwargs cls, const mlx_vector_array input_0, const mlx_map_string_to_array input_1);
extern mlx_closure_value_and_grad (*mlx_closure_value_and_grad_new_ptr)(void);
extern int (*mlx_closure_value_and_grad_free_ptr)(mlx_closure_value_and_grad cls);
extern mlx_closure_value_and_grad (*mlx_closure_value_and_grad_new_func_ptr)(int (*fun)(mlx_vector_array*, mlx_vector_array*, const mlx_vector_array));
extern mlx_closure_value_and_grad (*mlx_closure_value_and_grad_new_func_payload_ptr)(int (*fun)( mlx_vector_array*, mlx_vector_array*, const mlx_vector_array, void*), void* payload, void (*dtor)(void*));
extern int (*mlx_closure_value_and_grad_set_ptr)(mlx_closure_value_and_grad* cls, const mlx_closure_value_and_grad src);
extern int (*mlx_closure_value_and_grad_apply_ptr)(mlx_vector_array* res_0, mlx_vector_array* res_1, mlx_closure_value_and_grad cls, const mlx_vector_array input);
extern mlx_closure_custom (*mlx_closure_custom_new_ptr)(void);
extern int (*mlx_closure_custom_free_ptr)(mlx_closure_custom cls);
extern mlx_closure_custom (*mlx_closure_custom_new_func_ptr)(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const mlx_vector_array));
extern mlx_closure_custom (*mlx_closure_custom_new_func_payload_ptr)(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const mlx_vector_array, void*), void* payload, void (*dtor)(void*));
extern int (*mlx_closure_custom_set_ptr)(mlx_closure_custom* cls, const mlx_closure_custom src);
extern int (*mlx_closure_custom_apply_ptr)(mlx_vector_array* res, mlx_closure_custom cls, const mlx_vector_array input_0, const mlx_vector_array input_1, const mlx_vector_array input_2);
extern mlx_closure_custom_jvp (*mlx_closure_custom_jvp_new_ptr)(void);
extern int (*mlx_closure_custom_jvp_free_ptr)(mlx_closure_custom_jvp cls);
extern mlx_closure_custom_jvp (*mlx_closure_custom_jvp_new_func_ptr)(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const int*, size_t _num));
extern mlx_closure_custom_jvp (*mlx_closure_custom_jvp_new_func_payload_ptr)(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const int*, size_t _num, void*), void* payload, void (*dtor)(void*));
extern int (*mlx_closure_custom_jvp_set_ptr)(mlx_closure_custom_jvp* cls, const mlx_closure_custom_jvp src);
extern int (*mlx_closure_custom_jvp_apply_ptr)(mlx_vector_array* res, mlx_closure_custom_jvp cls, const mlx_vector_array input_0, const mlx_vector_array input_1, const int* input_2, size_t input_2_num);
extern mlx_closure_custom_vmap (*mlx_closure_custom_vmap_new_ptr)(void);
extern int (*mlx_closure_custom_vmap_free_ptr)(mlx_closure_custom_vmap cls);
extern mlx_closure_custom_vmap (*mlx_closure_custom_vmap_new_func_ptr)(int (*fun)( mlx_vector_array*, mlx_vector_int*, const mlx_vector_array, const int*, size_t _num));
extern mlx_closure_custom_vmap (*mlx_closure_custom_vmap_new_func_payload_ptr)(int (*fun)( mlx_vector_array*, mlx_vector_int*, const mlx_vector_array, const int*, size_t _num, void*), void* payload, void (*dtor)(void*));
extern int (*mlx_closure_custom_vmap_set_ptr)(mlx_closure_custom_vmap* cls, const mlx_closure_custom_vmap src);
extern int (*mlx_closure_custom_vmap_apply_ptr)(mlx_vector_array* res_0, mlx_vector_int* res_1, mlx_closure_custom_vmap cls, const mlx_vector_array input_0, const int* input_1, size_t input_1_num);
extern int (*mlx_compile_ptr)(mlx_closure* res, const mlx_closure fun, bool shapeless);
extern int (*mlx_detail_compile_ptr)(mlx_closure* res, const mlx_closure fun, uintptr_t fun_id, bool shapeless, const uint64_t* constants, size_t constants_num);
extern int (*mlx_detail_compile_clear_cache_ptr)(void);
extern int (*mlx_detail_compile_erase_ptr)(uintptr_t fun_id);
extern int (*mlx_disable_compile_ptr)(void);
extern int (*mlx_enable_compile_ptr)(void);
extern int (*mlx_set_compile_mode_ptr)(mlx_compile_mode mode);
extern int (*mlx_cuda_is_available_ptr)(bool* res);
extern mlx_device (*mlx_device_new_ptr)(void);
extern mlx_device (*mlx_device_new_type_ptr)(mlx_device_type type, int index);
extern int (*mlx_device_free_ptr)(mlx_device dev);
extern int (*mlx_device_set_ptr)(mlx_device* dev, const mlx_device src);
extern int (*mlx_device_tostring_ptr)(mlx_string* str, mlx_device dev);
extern bool (*mlx_device_equal_ptr)(mlx_device lhs, mlx_device rhs);
extern int (*mlx_device_get_index_ptr)(int* index, mlx_device dev);
extern int (*mlx_device_get_type_ptr)(mlx_device_type* type, mlx_device dev);
extern int (*mlx_get_default_device_ptr)(mlx_device* dev);
extern int (*mlx_set_default_device_ptr)(mlx_device dev);
extern int (*mlx_device_is_available_ptr)(bool* avail, mlx_device dev);
extern int (*mlx_device_count_ptr)(int* count, mlx_device_type type);
extern mlx_device_info (*mlx_device_info_new_ptr)(void);
extern int (*mlx_device_info_get_ptr)(mlx_device_info* info, mlx_device dev);
extern int (*mlx_device_info_free_ptr)(mlx_device_info info);
extern int (*mlx_device_info_has_key_ptr)(bool* exists, mlx_device_info info, const char* key);
extern int (*mlx_device_info_is_string_ptr)(bool* is_string, mlx_device_info info, const char* key);
extern int (*mlx_device_info_get_string_ptr)(const char** value, mlx_device_info info, const char* key);
extern int (*mlx_device_info_get_size_ptr)(size_t* value, mlx_device_info info, const char* key);
extern int (*mlx_device_info_get_keys_ptr)(mlx_vector_string* keys, mlx_device_info info);
extern int (*mlx_distributed_all_gather_ptr)(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream S);
extern int (*mlx_distributed_all_max_ptr)(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
extern int (*mlx_distributed_all_min_ptr)(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
extern int (*mlx_distributed_all_sum_ptr)(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
extern int (*mlx_distributed_recv_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, int src, const mlx_distributed_group group , const mlx_stream s);
extern int (*mlx_distributed_recv_like_ptr)(mlx_array* res, const mlx_array x, int src, const mlx_distributed_group group , const mlx_stream s);
extern int (*mlx_distributed_send_ptr)(mlx_array* res, const mlx_array x, int dst, const mlx_distributed_group group , const mlx_stream s);
extern int (*mlx_distributed_sum_scatter_ptr)(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
extern mlx_distributed_group (*mlx_distributed_group_new_ptr)(void);
extern int (*mlx_distributed_group_free_ptr)(mlx_distributed_group group);
extern int (*mlx_distributed_init_ptr)(mlx_distributed_group* res, bool strict, const char* bk);
extern int (*mlx_distributed_group_rank_ptr)(mlx_distributed_group group);
extern int (*mlx_distributed_group_size_ptr)(mlx_distributed_group group);
extern int (*mlx_distributed_group_split_ptr)(mlx_distributed_group* res, mlx_distributed_group group, int color, int key);
extern bool (*mlx_distributed_is_available_ptr)(const char* bk);
extern void (*mlx_set_error_handler_ptr)(mlx_error_handler_func handler, void* data, void (*dtor)(void*));
extern void (*_mlx_error_ptr)(const char* file, const int line, const char* fmt, ...);
extern int (*mlx_export_function_ptr)(const char* file, const mlx_closure fun, const mlx_vector_array args, bool shapeless);
extern int (*mlx_export_function_kwargs_ptr)(const char* file, const mlx_closure_kwargs fun, const mlx_vector_array args, const mlx_map_string_to_array kwargs, bool shapeless);
extern mlx_function_exporter (*mlx_function_exporter_new_ptr)(const char* file, const mlx_closure fun, bool shapeless);
extern int (*mlx_function_exporter_free_ptr)(mlx_function_exporter xfunc);
extern int (*mlx_function_exporter_apply_ptr)(const mlx_function_exporter xfunc, const mlx_vector_array args);
extern int (*mlx_function_exporter_apply_kwargs_ptr)(const mlx_function_exporter xfunc, const mlx_vector_array args, const mlx_map_string_to_array kwargs);
extern mlx_imported_function (*mlx_imported_function_new_ptr)(const char* file);
extern int (*mlx_imported_function_free_ptr)(mlx_imported_function xfunc);
extern int (*mlx_imported_function_apply_ptr)(mlx_vector_array* res, const mlx_imported_function xfunc, const mlx_vector_array args);
extern int (*mlx_imported_function_apply_kwargs_ptr)(mlx_vector_array* res, const mlx_imported_function xfunc, const mlx_vector_array args, const mlx_map_string_to_array kwargs);
extern mlx_fast_cuda_kernel_config (*mlx_fast_cuda_kernel_config_new_ptr)(void);
extern void (*mlx_fast_cuda_kernel_config_free_ptr)(mlx_fast_cuda_kernel_config cls);
extern int (*mlx_fast_cuda_kernel_config_add_output_arg_ptr)(mlx_fast_cuda_kernel_config cls, const int* shape, size_t size, mlx_dtype dtype);
extern int (*mlx_fast_cuda_kernel_config_set_grid_ptr)(mlx_fast_cuda_kernel_config cls, int grid1, int grid2, int grid3);
extern int (*mlx_fast_cuda_kernel_config_set_thread_group_ptr)(mlx_fast_cuda_kernel_config cls, int thread1, int thread2, int thread3);
extern int (*mlx_fast_cuda_kernel_config_set_init_value_ptr)(mlx_fast_cuda_kernel_config cls, float value);
extern int (*mlx_fast_cuda_kernel_config_set_verbose_ptr)(mlx_fast_cuda_kernel_config cls, bool verbose);
extern int (*mlx_fast_cuda_kernel_config_add_template_arg_dtype_ptr)(mlx_fast_cuda_kernel_config cls, const char* name, mlx_dtype dtype);
extern int (*mlx_fast_cuda_kernel_config_add_template_arg_int_ptr)(mlx_fast_cuda_kernel_config cls, const char* name, int value);
extern int (*mlx_fast_cuda_kernel_config_add_template_arg_bool_ptr)(mlx_fast_cuda_kernel_config cls, const char* name, bool value);
extern mlx_fast_cuda_kernel (*mlx_fast_cuda_kernel_new_ptr)(const char* name, const mlx_vector_string input_names, const mlx_vector_string output_names, const char* source, const char* header, bool ensure_row_contiguous, int shared_memory);
extern void (*mlx_fast_cuda_kernel_free_ptr)(mlx_fast_cuda_kernel cls);
extern int (*mlx_fast_cuda_kernel_apply_ptr)(mlx_vector_array* outputs, mlx_fast_cuda_kernel cls, const mlx_vector_array inputs, const mlx_fast_cuda_kernel_config config, const mlx_stream stream);
extern int (*mlx_fast_layer_norm_ptr)(mlx_array* res, const mlx_array x, const mlx_array weight , const mlx_array bias , float eps, const mlx_stream s);
extern mlx_fast_metal_kernel_config (*mlx_fast_metal_kernel_config_new_ptr)(void);
extern void (*mlx_fast_metal_kernel_config_free_ptr)(mlx_fast_metal_kernel_config cls);
extern int (*mlx_fast_metal_kernel_config_add_output_arg_ptr)(mlx_fast_metal_kernel_config cls, const int* shape, size_t size, mlx_dtype dtype);
extern int (*mlx_fast_metal_kernel_config_set_grid_ptr)(mlx_fast_metal_kernel_config cls, int grid1, int grid2, int grid3);
extern int (*mlx_fast_metal_kernel_config_set_thread_group_ptr)(mlx_fast_metal_kernel_config cls, int thread1, int thread2, int thread3);
extern int (*mlx_fast_metal_kernel_config_set_init_value_ptr)(mlx_fast_metal_kernel_config cls, float value);
extern int (*mlx_fast_metal_kernel_config_set_verbose_ptr)(mlx_fast_metal_kernel_config cls, bool verbose);
extern int (*mlx_fast_metal_kernel_config_add_template_arg_dtype_ptr)(mlx_fast_metal_kernel_config cls, const char* name, mlx_dtype dtype);
extern int (*mlx_fast_metal_kernel_config_add_template_arg_int_ptr)(mlx_fast_metal_kernel_config cls, const char* name, int value);
extern int (*mlx_fast_metal_kernel_config_add_template_arg_bool_ptr)(mlx_fast_metal_kernel_config cls, const char* name, bool value);
extern mlx_fast_metal_kernel (*mlx_fast_metal_kernel_new_ptr)(const char* name, const mlx_vector_string input_names, const mlx_vector_string output_names, const char* source, const char* header, bool ensure_row_contiguous, bool atomic_outputs);
extern void (*mlx_fast_metal_kernel_free_ptr)(mlx_fast_metal_kernel cls);
extern int (*mlx_fast_metal_kernel_apply_ptr)(mlx_vector_array* outputs, mlx_fast_metal_kernel cls, const mlx_vector_array inputs, const mlx_fast_metal_kernel_config config, const mlx_stream stream);
extern int (*mlx_fast_rms_norm_ptr)(mlx_array* res, const mlx_array x, const mlx_array weight , float eps, const mlx_stream s);
extern int (*mlx_fast_rope_ptr)(mlx_array* res, const mlx_array x, int dims, bool traditional, mlx_optional_float base, float scale, int offset, const mlx_array freqs , const mlx_stream s);
extern int (*mlx_fast_rope_dynamic_ptr)(mlx_array* res, const mlx_array x, int dims, bool traditional, mlx_optional_float base, float scale, const mlx_array offset, const mlx_array freqs , const mlx_stream s);
extern int (*mlx_fast_scaled_dot_product_attention_ptr)(mlx_array* res, const mlx_array queries, const mlx_array keys, const mlx_array values, float scale, const char* mask_mode, const mlx_array mask_arr , const mlx_array sinks , const mlx_stream s);
extern int (*mlx_fft_fft_ptr)(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_fft2_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_fftfreq_ptr)(mlx_array* res, int n, double d, const mlx_stream s);
extern int (*mlx_fft_fftn_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_fftshift_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_fft_ifft_ptr)(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_ifft2_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_ifftn_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_ifftshift_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_fft_irfft_ptr)(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_irfft2_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_irfftn_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_rfft_ptr)(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_rfft2_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_fft_rfftfreq_ptr)(mlx_array* res, int n, double d, const mlx_stream s);
extern int (*mlx_fft_rfftn_ptr)(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
extern int (*mlx_node_namer_free_ptr)(mlx_node_namer namer);
extern int (*mlx_node_namer_set_name_ptr)(mlx_node_namer namer, const mlx_array arr, const char* name);
extern int (*mlx_node_namer_get_name_ptr)(const char** name, mlx_node_namer namer, const mlx_array arr);
extern int (*mlx_export_to_dot_ptr)(FILE* os, const mlx_node_namer namer, const mlx_vector_array outputs);
extern int (*mlx_print_graph_ptr)(FILE* os, const mlx_node_namer namer, const mlx_vector_array outputs);
extern int (*mlx_load_reader_ptr)(mlx_array* res, mlx_io_reader in_stream, const mlx_stream s);
extern int (*mlx_load_ptr)(mlx_array* res, const char* file, const mlx_stream s);
extern int (*mlx_load_gguf_ptr)(mlx_io_gguf* gguf, const char* file, const mlx_stream s);
extern int (*mlx_load_safetensors_reader_ptr)(mlx_map_string_to_array* res_0, mlx_map_string_to_string* res_1, mlx_io_reader in_stream, const mlx_stream s);
extern int (*mlx_load_safetensors_ptr)(mlx_map_string_to_array* res_0, mlx_map_string_to_string* res_1, const char* file, const mlx_stream s);
extern int (*mlx_save_writer_ptr)(mlx_io_writer out_stream, const mlx_array a);
extern int (*mlx_save_ptr)(const char* file, const mlx_array a);
extern int (*mlx_save_gguf_ptr)(const char* file, mlx_io_gguf gguf);
extern int (*mlx_save_safetensors_writer_ptr)(mlx_io_writer in_stream, const mlx_map_string_to_array param, const mlx_map_string_to_string metadata);
extern int (*mlx_save_safetensors_ptr)(const char* file, const mlx_map_string_to_array param, const mlx_map_string_to_string metadata);
extern mlx_io_reader (*mlx_io_reader_new_ptr)(void* desc, mlx_io_vtable vtable);
extern int (*mlx_io_reader_descriptor_ptr)(void** desc_, mlx_io_reader io);
extern int (*mlx_io_reader_tostring_ptr)(mlx_string* str_, mlx_io_reader io);
extern int (*mlx_io_reader_free_ptr)(mlx_io_reader io);
extern mlx_io_writer (*mlx_io_writer_new_ptr)(void* desc, mlx_io_vtable vtable);
extern int (*mlx_io_writer_descriptor_ptr)(void** desc_, mlx_io_writer io);
extern int (*mlx_io_writer_tostring_ptr)(mlx_string* str_, mlx_io_writer io);
extern int (*mlx_io_writer_free_ptr)(mlx_io_writer io);
extern mlx_io_gguf (*mlx_io_gguf_new_ptr)(void);
extern int (*mlx_io_gguf_free_ptr)(mlx_io_gguf io);
extern int (*mlx_io_gguf_get_keys_ptr)(mlx_vector_string* keys, mlx_io_gguf io);
extern int (*mlx_io_gguf_get_array_ptr)(mlx_array* arr, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_get_metadata_array_ptr)(mlx_array* arr, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_get_metadata_string_ptr)(mlx_string* str, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_get_metadata_vector_string_ptr)(mlx_vector_string* vstr, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_has_metadata_array_ptr)(bool* flag, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_has_metadata_string_ptr)(bool* flag, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_has_metadata_vector_string_ptr)(bool* flag, mlx_io_gguf io, const char* key);
extern int (*mlx_io_gguf_set_array_ptr)(mlx_io_gguf io, const char* key, const mlx_array arr);
extern int (*mlx_io_gguf_set_metadata_array_ptr)(mlx_io_gguf io, const char* key, const mlx_array marr);
extern int (*mlx_io_gguf_set_metadata_string_ptr)(mlx_io_gguf io, const char* key, const char* mstr);
extern int (*mlx_io_gguf_set_metadata_vector_string_ptr)(mlx_io_gguf io, const char* key, const mlx_vector_string mvstr);
extern int (*mlx_linalg_cholesky_ptr)(mlx_array* res, const mlx_array a, bool upper, const mlx_stream s);
extern int (*mlx_linalg_cholesky_inv_ptr)(mlx_array* res, const mlx_array a, bool upper, const mlx_stream s);
extern int (*mlx_linalg_cross_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, int axis, const mlx_stream s);
extern int (*mlx_linalg_eig_ptr)(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_eigh_ptr)(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const char* UPLO, const mlx_stream s);
extern int (*mlx_linalg_eigvals_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_eigvalsh_ptr)(mlx_array* res, const mlx_array a, const char* UPLO, const mlx_stream s);
extern int (*mlx_linalg_inv_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_lu_ptr)(mlx_vector_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_lu_factor_ptr)(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_norm_ptr)(mlx_array* res, const mlx_array a, double ord, const int* axis , size_t axis_num, bool keepdims, const mlx_stream s);
extern int (*mlx_linalg_norm_matrix_ptr)(mlx_array* res, const mlx_array a, const char* ord, const int* axis , size_t axis_num, bool keepdims, const mlx_stream s);
extern int (*mlx_linalg_norm_l2_ptr)(mlx_array* res, const mlx_array a, const int* axis , size_t axis_num, bool keepdims, const mlx_stream s);
extern int (*mlx_linalg_pinv_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_qr_ptr)(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const mlx_stream s);
extern int (*mlx_linalg_solve_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_linalg_solve_triangular_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, bool upper, const mlx_stream s);
extern int (*mlx_linalg_svd_ptr)(mlx_vector_array* res, const mlx_array a, bool compute_uv, const mlx_stream s);
extern int (*mlx_linalg_tri_inv_ptr)(mlx_array* res, const mlx_array a, bool upper, const mlx_stream s);
extern mlx_map_string_to_array (*mlx_map_string_to_array_new_ptr)(void);
extern int (*mlx_map_string_to_array_set_ptr)(mlx_map_string_to_array* map, const mlx_map_string_to_array src);
extern int (*mlx_map_string_to_array_free_ptr)(mlx_map_string_to_array map);
extern int (*mlx_map_string_to_array_insert_ptr)(mlx_map_string_to_array map, const char* key, const mlx_array value);
extern int (*mlx_map_string_to_array_get_ptr)(mlx_array* value, const mlx_map_string_to_array map, const char* key);
extern mlx_map_string_to_array_iterator (*mlx_map_string_to_array_iterator_new_ptr)(mlx_map_string_to_array map);
extern int (*mlx_map_string_to_array_iterator_free_ptr)(mlx_map_string_to_array_iterator it);
extern int (*mlx_map_string_to_array_iterator_next_ptr)(const char** key, mlx_array* value, mlx_map_string_to_array_iterator it);
extern mlx_map_string_to_string (*mlx_map_string_to_string_new_ptr)(void);
extern int (*mlx_map_string_to_string_set_ptr)(mlx_map_string_to_string* map, const mlx_map_string_to_string src);
extern int (*mlx_map_string_to_string_free_ptr)(mlx_map_string_to_string map);
extern int (*mlx_map_string_to_string_insert_ptr)(mlx_map_string_to_string map, const char* key, const char* value);
extern int (*mlx_map_string_to_string_get_ptr)(const char** value, const mlx_map_string_to_string map, const char* key);
extern mlx_map_string_to_string_iterator (*mlx_map_string_to_string_iterator_new_ptr)(mlx_map_string_to_string map);
extern int (*mlx_map_string_to_string_iterator_free_ptr)(mlx_map_string_to_string_iterator it);
extern int (*mlx_map_string_to_string_iterator_next_ptr)(const char** key, const char** value, mlx_map_string_to_string_iterator it);
extern int (*mlx_clear_cache_ptr)(void);
extern int (*mlx_get_active_memory_ptr)(size_t* res);
extern int (*mlx_get_cache_memory_ptr)(size_t* res);
extern int (*mlx_get_memory_limit_ptr)(size_t* res);
extern int (*mlx_get_peak_memory_ptr)(size_t* res);
extern int (*mlx_reset_peak_memory_ptr)(void);
extern int (*mlx_set_cache_limit_ptr)(size_t* res, size_t limit);
extern int (*mlx_set_memory_limit_ptr)(size_t* res, size_t limit);
extern int (*mlx_set_wired_limit_ptr)(size_t* res, size_t limit);
extern int (*mlx_metal_is_available_ptr)(bool* res);
extern int (*mlx_metal_start_capture_ptr)(const char* path);
extern int (*mlx_metal_stop_capture_ptr)(void);
extern int (*mlx_abs_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_add_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_addmm_ptr)(mlx_array* res, const mlx_array c, const mlx_array a, const mlx_array b, float alpha, float beta, const mlx_stream s);
extern int (*mlx_all_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_all_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_all_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_allclose_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, double rtol, double atol, bool equal_nan, const mlx_stream s);
extern int (*mlx_any_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_any_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_any_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_arange_ptr)(mlx_array* res, double start, double stop, double step, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_arccos_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_arccosh_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_arcsin_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_arcsinh_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_arctan_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_arctan2_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_arctanh_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_argmax_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_argmax_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_argmin_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_argmin_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_argpartition_axis_ptr)(mlx_array* res, const mlx_array a, int kth, int axis, const mlx_stream s);
extern int (*mlx_argpartition_ptr)(mlx_array* res, const mlx_array a, int kth, const mlx_stream s);
extern int (*mlx_argsort_axis_ptr)(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
extern int (*mlx_argsort_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_array_equal_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, bool equal_nan, const mlx_stream s);
extern int (*mlx_as_strided_ptr)(mlx_array* res, const mlx_array a, const int* shape, size_t shape_num, const int64_t* strides, size_t strides_num, size_t offset, const mlx_stream s);
extern int (*mlx_astype_ptr)(mlx_array* res, const mlx_array a, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_atleast_1d_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_atleast_2d_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_atleast_3d_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_bartlett_ptr)(mlx_array* res, int M, const mlx_stream s);
extern int (*mlx_bitwise_and_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_bitwise_invert_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_bitwise_or_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_bitwise_xor_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_blackman_ptr)(mlx_array* res, int M, const mlx_stream s);
extern int (*mlx_block_masked_mm_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, int block_size, const mlx_array mask_out , const mlx_array mask_lhs , const mlx_array mask_rhs , const mlx_stream s);
extern int (*mlx_broadcast_arrays_ptr)(mlx_vector_array* res, const mlx_vector_array inputs, const mlx_stream s);
extern int (*mlx_broadcast_to_ptr)(mlx_array* res, const mlx_array a, const int* shape, size_t shape_num, const mlx_stream s);
extern int (*mlx_ceil_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_clip_ptr)(mlx_array* res, const mlx_array a, const mlx_array a_min , const mlx_array a_max , const mlx_stream s);
extern int (*mlx_concatenate_axis_ptr)(mlx_array* res, const mlx_vector_array arrays, int axis, const mlx_stream s);
extern int (*mlx_concatenate_ptr)(mlx_array* res, const mlx_vector_array arrays, const mlx_stream s);
extern int (*mlx_conjugate_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_contiguous_ptr)(mlx_array* res, const mlx_array a, bool allow_col_major, const mlx_stream s);
extern int (*mlx_conv1d_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, int stride, int padding, int dilation, int groups, const mlx_stream s);
extern int (*mlx_conv2d_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int padding_0, int padding_1, int dilation_0, int dilation_1, int groups, const mlx_stream s);
extern int (*mlx_conv3d_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int stride_2, int padding_0, int padding_1, int padding_2, int dilation_0, int dilation_1, int dilation_2, int groups, const mlx_stream s);
extern int (*mlx_conv_general_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, const int* stride, size_t stride_num, const int* padding_lo, size_t padding_lo_num, const int* padding_hi, size_t padding_hi_num, const int* kernel_dilation, size_t kernel_dilation_num, const int* input_dilation, size_t input_dilation_num, int groups, bool flip, const mlx_stream s);
extern int (*mlx_conv_transpose1d_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, int stride, int padding, int dilation, int output_padding, int groups, const mlx_stream s);
extern int (*mlx_conv_transpose2d_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int padding_0, int padding_1, int dilation_0, int dilation_1, int output_padding_0, int output_padding_1, int groups, const mlx_stream s);
extern int (*mlx_conv_transpose3d_ptr)(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int stride_2, int padding_0, int padding_1, int padding_2, int dilation_0, int dilation_1, int dilation_2, int output_padding_0, int output_padding_1, int output_padding_2, int groups, const mlx_stream s);
extern int (*mlx_copy_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_cos_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_cosh_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_cummax_ptr)(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
extern int (*mlx_cummin_ptr)(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
extern int (*mlx_cumprod_ptr)(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
extern int (*mlx_cumsum_ptr)(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
extern int (*mlx_degrees_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_depends_ptr)(mlx_vector_array* res, const mlx_vector_array inputs, const mlx_vector_array dependencies);
extern int (*mlx_dequantize_ptr)(mlx_array* res, const mlx_array w, const mlx_array scales, const mlx_array biases , mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_array global_scale , mlx_optional_dtype dtype, const mlx_stream s);
extern int (*mlx_diag_ptr)(mlx_array* res, const mlx_array a, int k, const mlx_stream s);
extern int (*mlx_diagonal_ptr)(mlx_array* res, const mlx_array a, int offset, int axis1, int axis2, const mlx_stream s);
extern int (*mlx_divide_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_divmod_ptr)(mlx_vector_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_einsum_ptr)(mlx_array* res, const char* subscripts, const mlx_vector_array operands, const mlx_stream s);
extern int (*mlx_equal_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_erf_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_erfinv_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_exp_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_expand_dims_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_expand_dims_ptr)(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
extern int (*mlx_expm1_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_eye_ptr)(mlx_array* res, int n, int m, int k, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_flatten_ptr)(mlx_array* res, const mlx_array a, int start_axis, int end_axis, const mlx_stream s);
extern int (*mlx_floor_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_floor_divide_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_from_fp8_ptr)(mlx_array* res, const mlx_array x, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_full_ptr)(mlx_array* res, const int* shape, size_t shape_num, const mlx_array vals, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_full_like_ptr)(mlx_array* res, const mlx_array a, const mlx_array vals, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_gather_ptr)(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const int* axes, size_t axes_num, const int* slice_sizes, size_t slice_sizes_num, const mlx_stream s);
extern int (*mlx_gather_single_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, int axis, const int* slice_sizes, size_t slice_sizes_num, const mlx_stream s);
extern int (*mlx_gather_mm_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_array lhs_indices , const mlx_array rhs_indices , bool sorted_indices, const mlx_stream s);
extern int (*mlx_gather_qmm_ptr)(mlx_array* res, const mlx_array x, const mlx_array w, const mlx_array scales, const mlx_array biases , const mlx_array lhs_indices , const mlx_array rhs_indices , bool transpose, mlx_optional_int group_size, mlx_optional_int bits, const char* mode, bool sorted_indices, const mlx_stream s);
extern int (*mlx_greater_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_greater_equal_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_hadamard_transform_ptr)(mlx_array* res, const mlx_array a, mlx_optional_float scale, const mlx_stream s);
extern int (*mlx_hamming_ptr)(mlx_array* res, int M, const mlx_stream s);
extern int (*mlx_hanning_ptr)(mlx_array* res, int M, const mlx_stream s);
extern int (*mlx_identity_ptr)(mlx_array* res, int n, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_imag_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_inner_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_isclose_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, double rtol, double atol, bool equal_nan, const mlx_stream s);
extern int (*mlx_isfinite_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_isinf_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_isnan_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_isneginf_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_isposinf_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_kron_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_left_shift_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_less_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_less_equal_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_linspace_ptr)(mlx_array* res, double start, double stop, int num, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_log_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_log10_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_log1p_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_log2_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_logaddexp_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_logcumsumexp_ptr)(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
extern int (*mlx_logical_and_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_logical_not_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_logical_or_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_logsumexp_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_logsumexp_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_logsumexp_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_masked_scatter_ptr)(mlx_array* res, const mlx_array a, const mlx_array mask, const mlx_array src, const mlx_stream s);
extern int (*mlx_matmul_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_max_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_max_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_max_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_maximum_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_mean_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_mean_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_mean_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_median_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_meshgrid_ptr)(mlx_vector_array* res, const mlx_vector_array arrays, bool sparse, const char* indexing, const mlx_stream s);
extern int (*mlx_min_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_min_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_min_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_minimum_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_moveaxis_ptr)(mlx_array* res, const mlx_array a, int source, int destination, const mlx_stream s);
extern int (*mlx_multiply_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_nan_to_num_ptr)(mlx_array* res, const mlx_array a, float nan, mlx_optional_float posinf, mlx_optional_float neginf, const mlx_stream s);
extern int (*mlx_negative_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_not_equal_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_number_of_elements_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool inverted, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_ones_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_ones_like_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_outer_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_pad_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const int* low_pad_size, size_t low_pad_size_num, const int* high_pad_size, size_t high_pad_size_num, const mlx_array pad_value, const char* mode, const mlx_stream s);
extern int (*mlx_pad_symmetric_ptr)(mlx_array* res, const mlx_array a, int pad_width, const mlx_array pad_value, const char* mode, const mlx_stream s);
extern int (*mlx_partition_axis_ptr)(mlx_array* res, const mlx_array a, int kth, int axis, const mlx_stream s);
extern int (*mlx_partition_ptr)(mlx_array* res, const mlx_array a, int kth, const mlx_stream s);
extern int (*mlx_power_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_prod_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_prod_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_prod_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_put_along_axis_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array values, int axis, const mlx_stream s);
extern int (*mlx_qqmm_ptr)(mlx_array* res, const mlx_array x, const mlx_array w, const mlx_array w_scales , mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_array global_scale_x , const mlx_array global_scale_w , const mlx_stream s);
extern int (*mlx_quantize_ptr)(mlx_vector_array* res, const mlx_array w, mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_array global_scale , const mlx_stream s);
extern int (*mlx_quantized_matmul_ptr)(mlx_array* res, const mlx_array x, const mlx_array w, const mlx_array scales, const mlx_array biases , bool transpose, mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_stream s);
extern int (*mlx_radians_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_real_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_reciprocal_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_remainder_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_repeat_axis_ptr)(mlx_array* res, const mlx_array arr, int repeats, int axis, const mlx_stream s);
extern int (*mlx_repeat_ptr)(mlx_array* res, const mlx_array arr, int repeats, const mlx_stream s);
extern int (*mlx_reshape_ptr)(mlx_array* res, const mlx_array a, const int* shape, size_t shape_num, const mlx_stream s);
extern int (*mlx_right_shift_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_roll_axis_ptr)(mlx_array* res, const mlx_array a, const int* shift, size_t shift_num, int axis, const mlx_stream s);
extern int (*mlx_roll_axes_ptr)(mlx_array* res, const mlx_array a, const int* shift, size_t shift_num, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_roll_ptr)(mlx_array* res, const mlx_array a, const int* shift, size_t shift_num, const mlx_stream s);
extern int (*mlx_round_ptr)(mlx_array* res, const mlx_array a, int decimals, const mlx_stream s);
extern int (*mlx_rsqrt_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_scatter_ptr)(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_scatter_single_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
extern int (*mlx_scatter_add_ptr)(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_scatter_add_single_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
extern int (*mlx_scatter_add_axis_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array values, int axis, const mlx_stream s);
extern int (*mlx_scatter_max_ptr)(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_scatter_max_single_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
extern int (*mlx_scatter_min_ptr)(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_scatter_min_single_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
extern int (*mlx_scatter_prod_ptr)(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_scatter_prod_single_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
extern int (*mlx_segmented_mm_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_array segments, const mlx_stream s);
extern int (*mlx_sigmoid_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_sign_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_sin_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_sinh_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_slice_ptr)(mlx_array* res, const mlx_array a, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
extern int (*mlx_slice_dynamic_ptr)(mlx_array* res, const mlx_array a, const mlx_array start, const int* axes, size_t axes_num, const int* slice_size, size_t slice_size_num, const mlx_stream s);
extern int (*mlx_slice_update_ptr)(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
extern int (*mlx_slice_update_dynamic_ptr)(mlx_array* res, const mlx_array src, const mlx_array update, const mlx_array start, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_slice_update_add_ptr)(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
extern int (*mlx_slice_update_max_ptr)(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
extern int (*mlx_slice_update_min_ptr)(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
extern int (*mlx_slice_update_prod_ptr)(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
extern int (*mlx_softmax_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool precise, const mlx_stream s);
extern int (*mlx_softmax_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool precise, const mlx_stream s);
extern int (*mlx_softmax_ptr)(mlx_array* res, const mlx_array a, bool precise, const mlx_stream s);
extern int (*mlx_sort_axis_ptr)(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
extern int (*mlx_sort_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_split_ptr)(mlx_vector_array* res, const mlx_array a, int num_splits, int axis, const mlx_stream s);
extern int (*mlx_split_sections_ptr)(mlx_vector_array* res, const mlx_array a, const int* indices, size_t indices_num, int axis, const mlx_stream s);
extern int (*mlx_sqrt_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_square_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_squeeze_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_squeeze_axis_ptr)(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
extern int (*mlx_squeeze_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_stack_axis_ptr)(mlx_array* res, const mlx_vector_array arrays, int axis, const mlx_stream s);
extern int (*mlx_stack_ptr)(mlx_array* res, const mlx_vector_array arrays, const mlx_stream s);
extern int (*mlx_std_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, int ddof, const mlx_stream s);
extern int (*mlx_std_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, int ddof, const mlx_stream s);
extern int (*mlx_std_ptr)(mlx_array* res, const mlx_array a, bool keepdims, int ddof, const mlx_stream s);
extern int (*mlx_stop_gradient_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_subtract_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
extern int (*mlx_sum_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
extern int (*mlx_sum_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
extern int (*mlx_sum_ptr)(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
extern int (*mlx_swapaxes_ptr)(mlx_array* res, const mlx_array a, int axis1, int axis2, const mlx_stream s);
extern int (*mlx_take_axis_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, int axis, const mlx_stream s);
extern int (*mlx_take_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_stream s);
extern int (*mlx_take_along_axis_ptr)(mlx_array* res, const mlx_array a, const mlx_array indices, int axis, const mlx_stream s);
extern int (*mlx_tan_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_tanh_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_tensordot_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, const int* axes_a, size_t axes_a_num, const int* axes_b, size_t axes_b_num, const mlx_stream s);
extern int (*mlx_tensordot_axis_ptr)(mlx_array* res, const mlx_array a, const mlx_array b, int axis, const mlx_stream s);
extern int (*mlx_tile_ptr)(mlx_array* res, const mlx_array arr, const int* reps, size_t reps_num, const mlx_stream s);
extern int (*mlx_to_fp8_ptr)(mlx_array* res, const mlx_array x, const mlx_stream s);
extern int (*mlx_topk_axis_ptr)(mlx_array* res, const mlx_array a, int k, int axis, const mlx_stream s);
extern int (*mlx_topk_ptr)(mlx_array* res, const mlx_array a, int k, const mlx_stream s);
extern int (*mlx_trace_ptr)(mlx_array* res, const mlx_array a, int offset, int axis1, int axis2, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_transpose_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
extern int (*mlx_transpose_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_tri_ptr)(mlx_array* res, int n, int m, int k, mlx_dtype type, const mlx_stream s);
extern int (*mlx_tril_ptr)(mlx_array* res, const mlx_array x, int k, const mlx_stream s);
extern int (*mlx_triu_ptr)(mlx_array* res, const mlx_array x, int k, const mlx_stream s);
extern int (*mlx_unflatten_ptr)(mlx_array* res, const mlx_array a, int axis, const int* shape, size_t shape_num, const mlx_stream s);
extern int (*mlx_var_axes_ptr)(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, int ddof, const mlx_stream s);
extern int (*mlx_var_axis_ptr)(mlx_array* res, const mlx_array a, int axis, bool keepdims, int ddof, const mlx_stream s);
extern int (*mlx_var_ptr)(mlx_array* res, const mlx_array a, bool keepdims, int ddof, const mlx_stream s);
extern int (*mlx_view_ptr)(mlx_array* res, const mlx_array a, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_where_ptr)(mlx_array* res, const mlx_array condition, const mlx_array x, const mlx_array y, const mlx_stream s);
extern int (*mlx_zeros_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_stream s);
extern int (*mlx_zeros_like_ptr)(mlx_array* res, const mlx_array a, const mlx_stream s);
extern int (*mlx_random_bernoulli_ptr)(mlx_array* res, const mlx_array p, const int* shape, size_t shape_num, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_bits_ptr)(mlx_array* res, const int* shape, size_t shape_num, int width, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_categorical_shape_ptr)(mlx_array* res, const mlx_array logits, int axis, const int* shape, size_t shape_num, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_categorical_num_samples_ptr)(mlx_array* res, const mlx_array logits_, int axis, int num_samples, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_categorical_ptr)(mlx_array* res, const mlx_array logits, int axis, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_gumbel_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_key_ptr)(mlx_array* res, uint64_t seed);
extern int (*mlx_random_laplace_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, float loc, float scale, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_multivariate_normal_ptr)(mlx_array* res, const mlx_array mean, const mlx_array cov, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_normal_broadcast_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array loc , const mlx_array scale , const mlx_array key , const mlx_stream s);
extern int (*mlx_random_normal_ptr)(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, float loc, float scale, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_permutation_ptr)(mlx_array* res, const mlx_array x, int axis, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_permutation_arange_ptr)(mlx_array* res, int x, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_randint_ptr)(mlx_array* res, const mlx_array low, const mlx_array high, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_seed_ptr)(uint64_t seed);
extern int (*mlx_random_split_num_ptr)(mlx_array* res, const mlx_array key, int num, const mlx_stream s);
extern int (*mlx_random_split_ptr)(mlx_array* res_0, mlx_array* res_1, const mlx_array key, const mlx_stream s);
extern int (*mlx_random_truncated_normal_ptr)(mlx_array* res, const mlx_array lower, const mlx_array upper, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
extern int (*mlx_random_uniform_ptr)(mlx_array* res, const mlx_array low, const mlx_array high, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
extern mlx_stream (*mlx_stream_new_ptr)(void);
extern mlx_stream (*mlx_stream_new_device_ptr)(mlx_device dev);
extern int (*mlx_stream_set_ptr)(mlx_stream* stream, const mlx_stream src);
extern int (*mlx_stream_free_ptr)(mlx_stream stream);
extern int (*mlx_stream_tostring_ptr)(mlx_string* str, mlx_stream stream);
extern bool (*mlx_stream_equal_ptr)(mlx_stream lhs, mlx_stream rhs);
extern int (*mlx_stream_get_device_ptr)(mlx_device* dev, mlx_stream stream);
extern int (*mlx_stream_get_index_ptr)(int* index, mlx_stream stream);
extern int (*mlx_synchronize_ptr)(mlx_stream stream);
extern int (*mlx_get_default_stream_ptr)(mlx_stream* stream, mlx_device dev);
extern int (*mlx_set_default_stream_ptr)(mlx_stream stream);
extern mlx_stream (*mlx_default_cpu_stream_new_ptr)(void);
extern mlx_stream (*mlx_default_gpu_stream_new_ptr)(void);
extern mlx_string (*mlx_string_new_ptr)(void);
extern mlx_string (*mlx_string_new_data_ptr)(const char* str);
extern int (*mlx_string_set_ptr)(mlx_string* str, const mlx_string src);
extern const char* (*mlx_string_data_ptr)(mlx_string str);
extern int (*mlx_string_free_ptr)(mlx_string str);
extern int (*mlx_async_eval_ptr)(const mlx_vector_array outputs);
extern int (*mlx_checkpoint_ptr)(mlx_closure* res, const mlx_closure fun);
extern int (*mlx_custom_function_ptr)(mlx_closure* res, const mlx_closure fun, const mlx_closure_custom fun_vjp , const mlx_closure_custom_jvp fun_jvp , const mlx_closure_custom_vmap fun_vmap);
extern int (*mlx_custom_vjp_ptr)(mlx_closure* res, const mlx_closure fun, const mlx_closure_custom fun_vjp);
extern int (*mlx_eval_ptr)(const mlx_vector_array outputs);
extern int (*mlx_jvp_ptr)(mlx_vector_array* res_0, mlx_vector_array* res_1, const mlx_closure fun, const mlx_vector_array primals, const mlx_vector_array tangents);
extern int (*mlx_value_and_grad_ptr)(mlx_closure_value_and_grad* res, const mlx_closure fun, const int* argnums, size_t argnums_num);
extern int (*mlx_vjp_ptr)(mlx_vector_array* res_0, mlx_vector_array* res_1, const mlx_closure fun, const mlx_vector_array primals, const mlx_vector_array cotangents);
extern int (*mlx_detail_vmap_replace_ptr)(mlx_vector_array* res, const mlx_vector_array inputs, const mlx_vector_array s_inputs, const mlx_vector_array s_outputs, const int* in_axes, size_t in_axes_num, const int* out_axes, size_t out_axes_num);
extern int (*mlx_detail_vmap_trace_ptr)(mlx_vector_array* res_0, mlx_vector_array* res_1, const mlx_closure fun, const mlx_vector_array inputs, const int* in_axes, size_t in_axes_num);
extern mlx_vector_array (*mlx_vector_array_new_ptr)(void);
extern int (*mlx_vector_array_set_ptr)(mlx_vector_array* vec, const mlx_vector_array src);
extern int (*mlx_vector_array_free_ptr)(mlx_vector_array vec);
extern mlx_vector_array (*mlx_vector_array_new_data_ptr)(const mlx_array* data, size_t size);
extern mlx_vector_array (*mlx_vector_array_new_value_ptr)(const mlx_array val);
extern int (*mlx_vector_array_set_data_ptr)(mlx_vector_array* vec, const mlx_array* data, size_t size);
extern int (*mlx_vector_array_set_value_ptr)(mlx_vector_array* vec, const mlx_array val);
extern int (*mlx_vector_array_append_data_ptr)(mlx_vector_array vec, const mlx_array* data, size_t size);
extern int (*mlx_vector_array_append_value_ptr)(mlx_vector_array vec, const mlx_array val);
extern size_t (*mlx_vector_array_size_ptr)(mlx_vector_array vec);
extern int (*mlx_vector_array_get_ptr)(mlx_array* res, const mlx_vector_array vec, size_t idx);
extern mlx_vector_vector_array (*mlx_vector_vector_array_new_ptr)(void);
extern int (*mlx_vector_vector_array_set_ptr)(mlx_vector_vector_array* vec, const mlx_vector_vector_array src);
extern int (*mlx_vector_vector_array_free_ptr)(mlx_vector_vector_array vec);
extern mlx_vector_vector_array (*mlx_vector_vector_array_new_data_ptr)(const mlx_vector_array* data, size_t size);
extern mlx_vector_vector_array (*mlx_vector_vector_array_new_value_ptr)(const mlx_vector_array val);
extern int (*mlx_vector_vector_array_set_data_ptr)(mlx_vector_vector_array* vec, const mlx_vector_array* data, size_t size);
extern int (*mlx_vector_vector_array_set_value_ptr)(mlx_vector_vector_array* vec, const mlx_vector_array val);
extern int (*mlx_vector_vector_array_append_data_ptr)(mlx_vector_vector_array vec, const mlx_vector_array* data, size_t size);
extern int (*mlx_vector_vector_array_append_value_ptr)(mlx_vector_vector_array vec, const mlx_vector_array val);
extern size_t (*mlx_vector_vector_array_size_ptr)(mlx_vector_vector_array vec);
extern int (*mlx_vector_vector_array_get_ptr)(mlx_vector_array* res, const mlx_vector_vector_array vec, size_t idx);
extern mlx_vector_int (*mlx_vector_int_new_ptr)(void);
extern int (*mlx_vector_int_set_ptr)(mlx_vector_int* vec, const mlx_vector_int src);
extern int (*mlx_vector_int_free_ptr)(mlx_vector_int vec);
extern mlx_vector_int (*mlx_vector_int_new_data_ptr)(int* data, size_t size);
extern mlx_vector_int (*mlx_vector_int_new_value_ptr)(int val);
extern int (*mlx_vector_int_set_data_ptr)(mlx_vector_int* vec, int* data, size_t size);
extern int (*mlx_vector_int_set_value_ptr)(mlx_vector_int* vec, int val);
extern int (*mlx_vector_int_append_data_ptr)(mlx_vector_int vec, int* data, size_t size);
extern int (*mlx_vector_int_append_value_ptr)(mlx_vector_int vec, int val);
extern size_t (*mlx_vector_int_size_ptr)(mlx_vector_int vec);
extern int (*mlx_vector_int_get_ptr)(int* res, const mlx_vector_int vec, size_t idx);
extern mlx_vector_string (*mlx_vector_string_new_ptr)(void);
extern int (*mlx_vector_string_set_ptr)(mlx_vector_string* vec, const mlx_vector_string src);
extern int (*mlx_vector_string_free_ptr)(mlx_vector_string vec);
extern mlx_vector_string (*mlx_vector_string_new_data_ptr)(const char** data, size_t size);
extern mlx_vector_string (*mlx_vector_string_new_value_ptr)(const char* val);
extern int (*mlx_vector_string_set_data_ptr)(mlx_vector_string* vec, const char** data, size_t size);
extern int (*mlx_vector_string_set_value_ptr)(mlx_vector_string* vec, const char* val);
extern int (*mlx_vector_string_append_data_ptr)(mlx_vector_string vec, const char** data, size_t size);
extern int (*mlx_vector_string_append_value_ptr)(mlx_vector_string vec, const char* val);
extern size_t (*mlx_vector_string_size_ptr)(mlx_vector_string vec);
extern int (*mlx_vector_string_get_ptr)(char** res, const mlx_vector_string vec, size_t idx);
extern int (*mlx_version_ptr)(mlx_string* str_);
// Initialize all function pointers via dlsym (defined in mlx.c)
int mlx_load_functions(void* handle);
// Wrapper function declarations that call through function pointers
// Go code calls these directly as C.mlx_* (no #define redirection needed)
size_t mlx_dtype_size(mlx_dtype dtype);
int mlx_array_tostring(mlx_string* str, const mlx_array arr);
mlx_array mlx_array_new(void);
int mlx_array_free(mlx_array arr);
mlx_array mlx_array_new_bool(bool val);
mlx_array mlx_array_new_int(int val);
mlx_array mlx_array_new_float32(float val);
mlx_array mlx_array_new_float(float val);
mlx_array mlx_array_new_float64(double val);
mlx_array mlx_array_new_double(double val);
mlx_array mlx_array_new_complex(float real_val, float imag_val);
mlx_array mlx_array_new_data(const void* data, const int* shape, int dim, mlx_dtype dtype);
mlx_array mlx_array_new_data_managed(void* data, const int* shape, int dim, mlx_dtype dtype, void (*dtor)(void*));
mlx_array mlx_array_new_data_managed_payload(void* data, const int* shape, int dim, mlx_dtype dtype, void* payload, void (*dtor)(void*));
int mlx_array_set(mlx_array* arr, const mlx_array src);
int mlx_array_set_bool(mlx_array* arr, bool val);
int mlx_array_set_int(mlx_array* arr, int val);
int mlx_array_set_float32(mlx_array* arr, float val);
int mlx_array_set_float(mlx_array* arr, float val);
int mlx_array_set_float64(mlx_array* arr, double val);
int mlx_array_set_double(mlx_array* arr, double val);
int mlx_array_set_complex(mlx_array* arr, float real_val, float imag_val);
int mlx_array_set_data(mlx_array* arr, const void* data, const int* shape, int dim, mlx_dtype dtype);
size_t mlx_array_itemsize(const mlx_array arr);
size_t mlx_array_size(const mlx_array arr);
size_t mlx_array_nbytes(const mlx_array arr);
size_t mlx_array_ndim(const mlx_array arr);
const int* mlx_array_shape(const mlx_array arr);
const size_t* mlx_array_strides(const mlx_array arr);
int mlx_array_dim(const mlx_array arr, int dim);
mlx_dtype mlx_array_dtype(const mlx_array arr);
int mlx_array_eval(mlx_array arr);
int mlx_array_item_bool(bool* res, const mlx_array arr);
int mlx_array_item_uint8(uint8_t* res, const mlx_array arr);
int mlx_array_item_uint16(uint16_t* res, const mlx_array arr);
int mlx_array_item_uint32(uint32_t* res, const mlx_array arr);
int mlx_array_item_uint64(uint64_t* res, const mlx_array arr);
int mlx_array_item_int8(int8_t* res, const mlx_array arr);
int mlx_array_item_int16(int16_t* res, const mlx_array arr);
int mlx_array_item_int32(int32_t* res, const mlx_array arr);
int mlx_array_item_int64(int64_t* res, const mlx_array arr);
int mlx_array_item_float32(float* res, const mlx_array arr);
int mlx_array_item_float64(double* res, const mlx_array arr);
int mlx_array_item_complex64(mlx_complex64_t* res, const mlx_array arr);
#if defined(__aarch64__) || defined(_M_ARM64)
int mlx_array_item_float16(float16_t* res, const mlx_array arr);
#endif
#if defined(__aarch64__) || defined(_M_ARM64)
int mlx_array_item_bfloat16(bfloat16_t* res, const mlx_array arr);
#endif
const bool* mlx_array_data_bool(const mlx_array arr);
const uint8_t* mlx_array_data_uint8(const mlx_array arr);
const uint16_t* mlx_array_data_uint16(const mlx_array arr);
const uint32_t* mlx_array_data_uint32(const mlx_array arr);
const uint64_t* mlx_array_data_uint64(const mlx_array arr);
const int8_t* mlx_array_data_int8(const mlx_array arr);
const int16_t* mlx_array_data_int16(const mlx_array arr);
const int32_t* mlx_array_data_int32(const mlx_array arr);
const int64_t* mlx_array_data_int64(const mlx_array arr);
const float* mlx_array_data_float32(const mlx_array arr);
const double* mlx_array_data_float64(const mlx_array arr);
const mlx_complex64_t* mlx_array_data_complex64(const mlx_array arr);
#if defined(__aarch64__) || defined(_M_ARM64)
const float16_t* mlx_array_data_float16(const mlx_array arr);
#endif
#if defined(__aarch64__) || defined(_M_ARM64)
const bfloat16_t* mlx_array_data_bfloat16(const mlx_array arr);
#endif
int _mlx_array_is_available(bool* res, const mlx_array arr);
int _mlx_array_wait(const mlx_array arr);
int _mlx_array_is_contiguous(bool* res, const mlx_array arr);
int _mlx_array_is_row_contiguous(bool* res, const mlx_array arr);
int _mlx_array_is_col_contiguous(bool* res, const mlx_array arr);
mlx_closure mlx_closure_new(void);
int mlx_closure_free(mlx_closure cls);
mlx_closure mlx_closure_new_func(int (*fun)(mlx_vector_array*, const mlx_vector_array));
mlx_closure mlx_closure_new_func_payload(int (*fun)(mlx_vector_array*, const mlx_vector_array, void*), void* payload, void (*dtor)(void*));
int mlx_closure_set(mlx_closure* cls, const mlx_closure src);
int mlx_closure_apply(mlx_vector_array* res, mlx_closure cls, const mlx_vector_array input);
mlx_closure mlx_closure_new_unary(int (*fun)(mlx_array*, const mlx_array));
mlx_closure_kwargs mlx_closure_kwargs_new(void);
int mlx_closure_kwargs_free(mlx_closure_kwargs cls);
mlx_closure_kwargs mlx_closure_kwargs_new_func(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_map_string_to_array));
mlx_closure_kwargs mlx_closure_kwargs_new_func_payload(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_map_string_to_array, void*), void* payload, void (*dtor)(void*));
int mlx_closure_kwargs_set(mlx_closure_kwargs* cls, const mlx_closure_kwargs src);
int mlx_closure_kwargs_apply(mlx_vector_array* res, mlx_closure_kwargs cls, const mlx_vector_array input_0, const mlx_map_string_to_array input_1);
mlx_closure_value_and_grad mlx_closure_value_and_grad_new(void);
int mlx_closure_value_and_grad_free(mlx_closure_value_and_grad cls);
mlx_closure_value_and_grad mlx_closure_value_and_grad_new_func(int (*fun)(mlx_vector_array*, mlx_vector_array*, const mlx_vector_array));
mlx_closure_value_and_grad mlx_closure_value_and_grad_new_func_payload(int (*fun)( mlx_vector_array*, mlx_vector_array*, const mlx_vector_array, void*), void* payload, void (*dtor)(void*));
int mlx_closure_value_and_grad_set(mlx_closure_value_and_grad* cls, const mlx_closure_value_and_grad src);
int mlx_closure_value_and_grad_apply(mlx_vector_array* res_0, mlx_vector_array* res_1, mlx_closure_value_and_grad cls, const mlx_vector_array input);
mlx_closure_custom mlx_closure_custom_new(void);
int mlx_closure_custom_free(mlx_closure_custom cls);
mlx_closure_custom mlx_closure_custom_new_func(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const mlx_vector_array));
mlx_closure_custom mlx_closure_custom_new_func_payload(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const mlx_vector_array, void*), void* payload, void (*dtor)(void*));
int mlx_closure_custom_set(mlx_closure_custom* cls, const mlx_closure_custom src);
int mlx_closure_custom_apply(mlx_vector_array* res, mlx_closure_custom cls, const mlx_vector_array input_0, const mlx_vector_array input_1, const mlx_vector_array input_2);
mlx_closure_custom_jvp mlx_closure_custom_jvp_new(void);
int mlx_closure_custom_jvp_free(mlx_closure_custom_jvp cls);
mlx_closure_custom_jvp mlx_closure_custom_jvp_new_func(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const int*, size_t _num));
mlx_closure_custom_jvp mlx_closure_custom_jvp_new_func_payload(int (*fun)( mlx_vector_array*, const mlx_vector_array, const mlx_vector_array, const int*, size_t _num, void*), void* payload, void (*dtor)(void*));
int mlx_closure_custom_jvp_set(mlx_closure_custom_jvp* cls, const mlx_closure_custom_jvp src);
int mlx_closure_custom_jvp_apply(mlx_vector_array* res, mlx_closure_custom_jvp cls, const mlx_vector_array input_0, const mlx_vector_array input_1, const int* input_2, size_t input_2_num);
mlx_closure_custom_vmap mlx_closure_custom_vmap_new(void);
int mlx_closure_custom_vmap_free(mlx_closure_custom_vmap cls);
mlx_closure_custom_vmap mlx_closure_custom_vmap_new_func(int (*fun)( mlx_vector_array*, mlx_vector_int*, const mlx_vector_array, const int*, size_t _num));
mlx_closure_custom_vmap mlx_closure_custom_vmap_new_func_payload(int (*fun)( mlx_vector_array*, mlx_vector_int*, const mlx_vector_array, const int*, size_t _num, void*), void* payload, void (*dtor)(void*));
int mlx_closure_custom_vmap_set(mlx_closure_custom_vmap* cls, const mlx_closure_custom_vmap src);
int mlx_closure_custom_vmap_apply(mlx_vector_array* res_0, mlx_vector_int* res_1, mlx_closure_custom_vmap cls, const mlx_vector_array input_0, const int* input_1, size_t input_1_num);
int mlx_compile(mlx_closure* res, const mlx_closure fun, bool shapeless);
int mlx_detail_compile(mlx_closure* res, const mlx_closure fun, uintptr_t fun_id, bool shapeless, const uint64_t* constants, size_t constants_num);
int mlx_detail_compile_clear_cache(void);
int mlx_detail_compile_erase(uintptr_t fun_id);
int mlx_disable_compile(void);
int mlx_enable_compile(void);
int mlx_set_compile_mode(mlx_compile_mode mode);
int mlx_cuda_is_available(bool* res);
mlx_device mlx_device_new(void);
mlx_device mlx_device_new_type(mlx_device_type type, int index);
int mlx_device_free(mlx_device dev);
int mlx_device_set(mlx_device* dev, const mlx_device src);
int mlx_device_tostring(mlx_string* str, mlx_device dev);
bool mlx_device_equal(mlx_device lhs, mlx_device rhs);
int mlx_device_get_index(int* index, mlx_device dev);
int mlx_device_get_type(mlx_device_type* type, mlx_device dev);
int mlx_get_default_device(mlx_device* dev);
int mlx_set_default_device(mlx_device dev);
int mlx_device_is_available(bool* avail, mlx_device dev);
int mlx_device_count(int* count, mlx_device_type type);
mlx_device_info mlx_device_info_new(void);
int mlx_device_info_get(mlx_device_info* info, mlx_device dev);
int mlx_device_info_free(mlx_device_info info);
int mlx_device_info_has_key(bool* exists, mlx_device_info info, const char* key);
int mlx_device_info_is_string(bool* is_string, mlx_device_info info, const char* key);
int mlx_device_info_get_string(const char** value, mlx_device_info info, const char* key);
int mlx_device_info_get_size(size_t* value, mlx_device_info info, const char* key);
int mlx_device_info_get_keys(mlx_vector_string* keys, mlx_device_info info);
int mlx_distributed_all_gather(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream S);
int mlx_distributed_all_max(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
int mlx_distributed_all_min(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
int mlx_distributed_all_sum(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
int mlx_distributed_recv(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, int src, const mlx_distributed_group group , const mlx_stream s);
int mlx_distributed_recv_like(mlx_array* res, const mlx_array x, int src, const mlx_distributed_group group , const mlx_stream s);
int mlx_distributed_send(mlx_array* res, const mlx_array x, int dst, const mlx_distributed_group group , const mlx_stream s);
int mlx_distributed_sum_scatter(mlx_array* res, const mlx_array x, const mlx_distributed_group group , const mlx_stream s);
mlx_distributed_group mlx_distributed_group_new(void);
int mlx_distributed_group_free(mlx_distributed_group group);
int mlx_distributed_init(mlx_distributed_group* res, bool strict, const char* bk);
int mlx_distributed_group_rank(mlx_distributed_group group);
int mlx_distributed_group_size(mlx_distributed_group group);
int mlx_distributed_group_split(mlx_distributed_group* res, mlx_distributed_group group, int color, int key);
bool mlx_distributed_is_available(const char* bk);
void mlx_set_error_handler(mlx_error_handler_func handler, void* data, void (*dtor)(void*));
void _mlx_error(const char* file, const int line, const char* fmt, ...);
int mlx_export_function(const char* file, const mlx_closure fun, const mlx_vector_array args, bool shapeless);
int mlx_export_function_kwargs(const char* file, const mlx_closure_kwargs fun, const mlx_vector_array args, const mlx_map_string_to_array kwargs, bool shapeless);
mlx_function_exporter mlx_function_exporter_new(const char* file, const mlx_closure fun, bool shapeless);
int mlx_function_exporter_free(mlx_function_exporter xfunc);
int mlx_function_exporter_apply(const mlx_function_exporter xfunc, const mlx_vector_array args);
int mlx_function_exporter_apply_kwargs(const mlx_function_exporter xfunc, const mlx_vector_array args, const mlx_map_string_to_array kwargs);
mlx_imported_function mlx_imported_function_new(const char* file);
int mlx_imported_function_free(mlx_imported_function xfunc);
int mlx_imported_function_apply(mlx_vector_array* res, const mlx_imported_function xfunc, const mlx_vector_array args);
int mlx_imported_function_apply_kwargs(mlx_vector_array* res, const mlx_imported_function xfunc, const mlx_vector_array args, const mlx_map_string_to_array kwargs);
mlx_fast_cuda_kernel_config mlx_fast_cuda_kernel_config_new(void);
void mlx_fast_cuda_kernel_config_free(mlx_fast_cuda_kernel_config cls);
int mlx_fast_cuda_kernel_config_add_output_arg(mlx_fast_cuda_kernel_config cls, const int* shape, size_t size, mlx_dtype dtype);
int mlx_fast_cuda_kernel_config_set_grid(mlx_fast_cuda_kernel_config cls, int grid1, int grid2, int grid3);
int mlx_fast_cuda_kernel_config_set_thread_group(mlx_fast_cuda_kernel_config cls, int thread1, int thread2, int thread3);
int mlx_fast_cuda_kernel_config_set_init_value(mlx_fast_cuda_kernel_config cls, float value);
int mlx_fast_cuda_kernel_config_set_verbose(mlx_fast_cuda_kernel_config cls, bool verbose);
int mlx_fast_cuda_kernel_config_add_template_arg_dtype(mlx_fast_cuda_kernel_config cls, const char* name, mlx_dtype dtype);
int mlx_fast_cuda_kernel_config_add_template_arg_int(mlx_fast_cuda_kernel_config cls, const char* name, int value);
int mlx_fast_cuda_kernel_config_add_template_arg_bool(mlx_fast_cuda_kernel_config cls, const char* name, bool value);
mlx_fast_cuda_kernel mlx_fast_cuda_kernel_new(const char* name, const mlx_vector_string input_names, const mlx_vector_string output_names, const char* source, const char* header, bool ensure_row_contiguous, int shared_memory);
void mlx_fast_cuda_kernel_free(mlx_fast_cuda_kernel cls);
int mlx_fast_cuda_kernel_apply(mlx_vector_array* outputs, mlx_fast_cuda_kernel cls, const mlx_vector_array inputs, const mlx_fast_cuda_kernel_config config, const mlx_stream stream);
int mlx_fast_layer_norm(mlx_array* res, const mlx_array x, const mlx_array weight , const mlx_array bias , float eps, const mlx_stream s);
mlx_fast_metal_kernel_config mlx_fast_metal_kernel_config_new(void);
void mlx_fast_metal_kernel_config_free(mlx_fast_metal_kernel_config cls);
int mlx_fast_metal_kernel_config_add_output_arg(mlx_fast_metal_kernel_config cls, const int* shape, size_t size, mlx_dtype dtype);
int mlx_fast_metal_kernel_config_set_grid(mlx_fast_metal_kernel_config cls, int grid1, int grid2, int grid3);
int mlx_fast_metal_kernel_config_set_thread_group(mlx_fast_metal_kernel_config cls, int thread1, int thread2, int thread3);
int mlx_fast_metal_kernel_config_set_init_value(mlx_fast_metal_kernel_config cls, float value);
int mlx_fast_metal_kernel_config_set_verbose(mlx_fast_metal_kernel_config cls, bool verbose);
int mlx_fast_metal_kernel_config_add_template_arg_dtype(mlx_fast_metal_kernel_config cls, const char* name, mlx_dtype dtype);
int mlx_fast_metal_kernel_config_add_template_arg_int(mlx_fast_metal_kernel_config cls, const char* name, int value);
int mlx_fast_metal_kernel_config_add_template_arg_bool(mlx_fast_metal_kernel_config cls, const char* name, bool value);
mlx_fast_metal_kernel mlx_fast_metal_kernel_new(const char* name, const mlx_vector_string input_names, const mlx_vector_string output_names, const char* source, const char* header, bool ensure_row_contiguous, bool atomic_outputs);
void mlx_fast_metal_kernel_free(mlx_fast_metal_kernel cls);
int mlx_fast_metal_kernel_apply(mlx_vector_array* outputs, mlx_fast_metal_kernel cls, const mlx_vector_array inputs, const mlx_fast_metal_kernel_config config, const mlx_stream stream);
int mlx_fast_rms_norm(mlx_array* res, const mlx_array x, const mlx_array weight , float eps, const mlx_stream s);
int mlx_fast_rope(mlx_array* res, const mlx_array x, int dims, bool traditional, mlx_optional_float base, float scale, int offset, const mlx_array freqs , const mlx_stream s);
int mlx_fast_rope_dynamic(mlx_array* res, const mlx_array x, int dims, bool traditional, mlx_optional_float base, float scale, const mlx_array offset, const mlx_array freqs , const mlx_stream s);
int mlx_fast_scaled_dot_product_attention(mlx_array* res, const mlx_array queries, const mlx_array keys, const mlx_array values, float scale, const char* mask_mode, const mlx_array mask_arr , const mlx_array sinks , const mlx_stream s);
int mlx_fft_fft(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_fft2(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_fftfreq(mlx_array* res, int n, double d, const mlx_stream s);
int mlx_fft_fftn(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_fftshift(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_fft_ifft(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_ifft2(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_ifftn(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_ifftshift(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_fft_irfft(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_irfft2(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_irfftn(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_rfft(mlx_array* res, const mlx_array a, int n, int axis, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_rfft2(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_fft_rfftfreq(mlx_array* res, int n, double d, const mlx_stream s);
int mlx_fft_rfftn(mlx_array* res, const mlx_array a, const int* n, size_t n_num, const int* axes, size_t axes_num, mlx_fft_norm norm, const mlx_stream s);
int mlx_node_namer_free(mlx_node_namer namer);
int mlx_node_namer_set_name(mlx_node_namer namer, const mlx_array arr, const char* name);
int mlx_node_namer_get_name(const char** name, mlx_node_namer namer, const mlx_array arr);
int mlx_export_to_dot(FILE* os, const mlx_node_namer namer, const mlx_vector_array outputs);
int mlx_print_graph(FILE* os, const mlx_node_namer namer, const mlx_vector_array outputs);
int mlx_load_reader(mlx_array* res, mlx_io_reader in_stream, const mlx_stream s);
int mlx_load(mlx_array* res, const char* file, const mlx_stream s);
int mlx_load_gguf(mlx_io_gguf* gguf, const char* file, const mlx_stream s);
int mlx_load_safetensors_reader(mlx_map_string_to_array* res_0, mlx_map_string_to_string* res_1, mlx_io_reader in_stream, const mlx_stream s);
int mlx_load_safetensors(mlx_map_string_to_array* res_0, mlx_map_string_to_string* res_1, const char* file, const mlx_stream s);
int mlx_save_writer(mlx_io_writer out_stream, const mlx_array a);
int mlx_save(const char* file, const mlx_array a);
int mlx_save_gguf(const char* file, mlx_io_gguf gguf);
int mlx_save_safetensors_writer(mlx_io_writer in_stream, const mlx_map_string_to_array param, const mlx_map_string_to_string metadata);
int mlx_save_safetensors(const char* file, const mlx_map_string_to_array param, const mlx_map_string_to_string metadata);
mlx_io_reader mlx_io_reader_new(void* desc, mlx_io_vtable vtable);
int mlx_io_reader_descriptor(void** desc_, mlx_io_reader io);
int mlx_io_reader_tostring(mlx_string* str_, mlx_io_reader io);
int mlx_io_reader_free(mlx_io_reader io);
mlx_io_writer mlx_io_writer_new(void* desc, mlx_io_vtable vtable);
int mlx_io_writer_descriptor(void** desc_, mlx_io_writer io);
int mlx_io_writer_tostring(mlx_string* str_, mlx_io_writer io);
int mlx_io_writer_free(mlx_io_writer io);
mlx_io_gguf mlx_io_gguf_new(void);
int mlx_io_gguf_free(mlx_io_gguf io);
int mlx_io_gguf_get_keys(mlx_vector_string* keys, mlx_io_gguf io);
int mlx_io_gguf_get_array(mlx_array* arr, mlx_io_gguf io, const char* key);
int mlx_io_gguf_get_metadata_array(mlx_array* arr, mlx_io_gguf io, const char* key);
int mlx_io_gguf_get_metadata_string(mlx_string* str, mlx_io_gguf io, const char* key);
int mlx_io_gguf_get_metadata_vector_string(mlx_vector_string* vstr, mlx_io_gguf io, const char* key);
int mlx_io_gguf_has_metadata_array(bool* flag, mlx_io_gguf io, const char* key);
int mlx_io_gguf_has_metadata_string(bool* flag, mlx_io_gguf io, const char* key);
int mlx_io_gguf_has_metadata_vector_string(bool* flag, mlx_io_gguf io, const char* key);
int mlx_io_gguf_set_array(mlx_io_gguf io, const char* key, const mlx_array arr);
int mlx_io_gguf_set_metadata_array(mlx_io_gguf io, const char* key, const mlx_array marr);
int mlx_io_gguf_set_metadata_string(mlx_io_gguf io, const char* key, const char* mstr);
int mlx_io_gguf_set_metadata_vector_string(mlx_io_gguf io, const char* key, const mlx_vector_string mvstr);
int mlx_linalg_cholesky(mlx_array* res, const mlx_array a, bool upper, const mlx_stream s);
int mlx_linalg_cholesky_inv(mlx_array* res, const mlx_array a, bool upper, const mlx_stream s);
int mlx_linalg_cross(mlx_array* res, const mlx_array a, const mlx_array b, int axis, const mlx_stream s);
int mlx_linalg_eig(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const mlx_stream s);
int mlx_linalg_eigh(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const char* UPLO, const mlx_stream s);
int mlx_linalg_eigvals(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_linalg_eigvalsh(mlx_array* res, const mlx_array a, const char* UPLO, const mlx_stream s);
int mlx_linalg_inv(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_linalg_lu(mlx_vector_array* res, const mlx_array a, const mlx_stream s);
int mlx_linalg_lu_factor(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const mlx_stream s);
int mlx_linalg_norm(mlx_array* res, const mlx_array a, double ord, const int* axis , size_t axis_num, bool keepdims, const mlx_stream s);
int mlx_linalg_norm_matrix(mlx_array* res, const mlx_array a, const char* ord, const int* axis , size_t axis_num, bool keepdims, const mlx_stream s);
int mlx_linalg_norm_l2(mlx_array* res, const mlx_array a, const int* axis , size_t axis_num, bool keepdims, const mlx_stream s);
int mlx_linalg_pinv(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_linalg_qr(mlx_array* res_0, mlx_array* res_1, const mlx_array a, const mlx_stream s);
int mlx_linalg_solve(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_linalg_solve_triangular(mlx_array* res, const mlx_array a, const mlx_array b, bool upper, const mlx_stream s);
int mlx_linalg_svd(mlx_vector_array* res, const mlx_array a, bool compute_uv, const mlx_stream s);
int mlx_linalg_tri_inv(mlx_array* res, const mlx_array a, bool upper, const mlx_stream s);
mlx_map_string_to_array mlx_map_string_to_array_new(void);
int mlx_map_string_to_array_set(mlx_map_string_to_array* map, const mlx_map_string_to_array src);
int mlx_map_string_to_array_free(mlx_map_string_to_array map);
int mlx_map_string_to_array_insert(mlx_map_string_to_array map, const char* key, const mlx_array value);
int mlx_map_string_to_array_get(mlx_array* value, const mlx_map_string_to_array map, const char* key);
mlx_map_string_to_array_iterator mlx_map_string_to_array_iterator_new(mlx_map_string_to_array map);
int mlx_map_string_to_array_iterator_free(mlx_map_string_to_array_iterator it);
int mlx_map_string_to_array_iterator_next(const char** key, mlx_array* value, mlx_map_string_to_array_iterator it);
mlx_map_string_to_string mlx_map_string_to_string_new(void);
int mlx_map_string_to_string_set(mlx_map_string_to_string* map, const mlx_map_string_to_string src);
int mlx_map_string_to_string_free(mlx_map_string_to_string map);
int mlx_map_string_to_string_insert(mlx_map_string_to_string map, const char* key, const char* value);
int mlx_map_string_to_string_get(const char** value, const mlx_map_string_to_string map, const char* key);
mlx_map_string_to_string_iterator mlx_map_string_to_string_iterator_new(mlx_map_string_to_string map);
int mlx_map_string_to_string_iterator_free(mlx_map_string_to_string_iterator it);
int mlx_map_string_to_string_iterator_next(const char** key, const char** value, mlx_map_string_to_string_iterator it);
int mlx_clear_cache(void);
int mlx_get_active_memory(size_t* res);
int mlx_get_cache_memory(size_t* res);
int mlx_get_memory_limit(size_t* res);
int mlx_get_peak_memory(size_t* res);
int mlx_reset_peak_memory(void);
int mlx_set_cache_limit(size_t* res, size_t limit);
int mlx_set_memory_limit(size_t* res, size_t limit);
int mlx_set_wired_limit(size_t* res, size_t limit);
int mlx_metal_is_available(bool* res);
int mlx_metal_start_capture(const char* path);
int mlx_metal_stop_capture(void);
int mlx_abs(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_add(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_addmm(mlx_array* res, const mlx_array c, const mlx_array a, const mlx_array b, float alpha, float beta, const mlx_stream s);
int mlx_all_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_all_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_all(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_allclose(mlx_array* res, const mlx_array a, const mlx_array b, double rtol, double atol, bool equal_nan, const mlx_stream s);
int mlx_any_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_any_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_any(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_arange(mlx_array* res, double start, double stop, double step, mlx_dtype dtype, const mlx_stream s);
int mlx_arccos(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_arccosh(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_arcsin(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_arcsinh(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_arctan(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_arctan2(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_arctanh(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_argmax_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_argmax(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_argmin_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_argmin(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_argpartition_axis(mlx_array* res, const mlx_array a, int kth, int axis, const mlx_stream s);
int mlx_argpartition(mlx_array* res, const mlx_array a, int kth, const mlx_stream s);
int mlx_argsort_axis(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
int mlx_argsort(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_array_equal(mlx_array* res, const mlx_array a, const mlx_array b, bool equal_nan, const mlx_stream s);
int mlx_as_strided(mlx_array* res, const mlx_array a, const int* shape, size_t shape_num, const int64_t* strides, size_t strides_num, size_t offset, const mlx_stream s);
int mlx_astype(mlx_array* res, const mlx_array a, mlx_dtype dtype, const mlx_stream s);
int mlx_atleast_1d(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_atleast_2d(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_atleast_3d(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_bartlett(mlx_array* res, int M, const mlx_stream s);
int mlx_bitwise_and(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_bitwise_invert(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_bitwise_or(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_bitwise_xor(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_blackman(mlx_array* res, int M, const mlx_stream s);
int mlx_block_masked_mm(mlx_array* res, const mlx_array a, const mlx_array b, int block_size, const mlx_array mask_out , const mlx_array mask_lhs , const mlx_array mask_rhs , const mlx_stream s);
int mlx_broadcast_arrays(mlx_vector_array* res, const mlx_vector_array inputs, const mlx_stream s);
int mlx_broadcast_to(mlx_array* res, const mlx_array a, const int* shape, size_t shape_num, const mlx_stream s);
int mlx_ceil(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_clip(mlx_array* res, const mlx_array a, const mlx_array a_min , const mlx_array a_max , const mlx_stream s);
int mlx_concatenate_axis(mlx_array* res, const mlx_vector_array arrays, int axis, const mlx_stream s);
int mlx_concatenate(mlx_array* res, const mlx_vector_array arrays, const mlx_stream s);
int mlx_conjugate(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_contiguous(mlx_array* res, const mlx_array a, bool allow_col_major, const mlx_stream s);
int mlx_conv1d(mlx_array* res, const mlx_array input, const mlx_array weight, int stride, int padding, int dilation, int groups, const mlx_stream s);
int mlx_conv2d(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int padding_0, int padding_1, int dilation_0, int dilation_1, int groups, const mlx_stream s);
int mlx_conv3d(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int stride_2, int padding_0, int padding_1, int padding_2, int dilation_0, int dilation_1, int dilation_2, int groups, const mlx_stream s);
int mlx_conv_general(mlx_array* res, const mlx_array input, const mlx_array weight, const int* stride, size_t stride_num, const int* padding_lo, size_t padding_lo_num, const int* padding_hi, size_t padding_hi_num, const int* kernel_dilation, size_t kernel_dilation_num, const int* input_dilation, size_t input_dilation_num, int groups, bool flip, const mlx_stream s);
int mlx_conv_transpose1d(mlx_array* res, const mlx_array input, const mlx_array weight, int stride, int padding, int dilation, int output_padding, int groups, const mlx_stream s);
int mlx_conv_transpose2d(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int padding_0, int padding_1, int dilation_0, int dilation_1, int output_padding_0, int output_padding_1, int groups, const mlx_stream s);
int mlx_conv_transpose3d(mlx_array* res, const mlx_array input, const mlx_array weight, int stride_0, int stride_1, int stride_2, int padding_0, int padding_1, int padding_2, int dilation_0, int dilation_1, int dilation_2, int output_padding_0, int output_padding_1, int output_padding_2, int groups, const mlx_stream s);
int mlx_copy(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_cos(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_cosh(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_cummax(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
int mlx_cummin(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
int mlx_cumprod(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
int mlx_cumsum(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
int mlx_degrees(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_depends(mlx_vector_array* res, const mlx_vector_array inputs, const mlx_vector_array dependencies);
int mlx_dequantize(mlx_array* res, const mlx_array w, const mlx_array scales, const mlx_array biases , mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_array global_scale , mlx_optional_dtype dtype, const mlx_stream s);
int mlx_diag(mlx_array* res, const mlx_array a, int k, const mlx_stream s);
int mlx_diagonal(mlx_array* res, const mlx_array a, int offset, int axis1, int axis2, const mlx_stream s);
int mlx_divide(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_divmod(mlx_vector_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_einsum(mlx_array* res, const char* subscripts, const mlx_vector_array operands, const mlx_stream s);
int mlx_equal(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_erf(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_erfinv(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_exp(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_expand_dims_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_expand_dims(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
int mlx_expm1(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_eye(mlx_array* res, int n, int m, int k, mlx_dtype dtype, const mlx_stream s);
int mlx_flatten(mlx_array* res, const mlx_array a, int start_axis, int end_axis, const mlx_stream s);
int mlx_floor(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_floor_divide(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_from_fp8(mlx_array* res, const mlx_array x, mlx_dtype dtype, const mlx_stream s);
int mlx_full(mlx_array* res, const int* shape, size_t shape_num, const mlx_array vals, mlx_dtype dtype, const mlx_stream s);
int mlx_full_like(mlx_array* res, const mlx_array a, const mlx_array vals, mlx_dtype dtype, const mlx_stream s);
int mlx_gather(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const int* axes, size_t axes_num, const int* slice_sizes, size_t slice_sizes_num, const mlx_stream s);
int mlx_gather_single(mlx_array* res, const mlx_array a, const mlx_array indices, int axis, const int* slice_sizes, size_t slice_sizes_num, const mlx_stream s);
int mlx_gather_mm(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_array lhs_indices , const mlx_array rhs_indices , bool sorted_indices, const mlx_stream s);
int mlx_gather_qmm(mlx_array* res, const mlx_array x, const mlx_array w, const mlx_array scales, const mlx_array biases , const mlx_array lhs_indices , const mlx_array rhs_indices , bool transpose, mlx_optional_int group_size, mlx_optional_int bits, const char* mode, bool sorted_indices, const mlx_stream s);
int mlx_greater(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_greater_equal(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_hadamard_transform(mlx_array* res, const mlx_array a, mlx_optional_float scale, const mlx_stream s);
int mlx_hamming(mlx_array* res, int M, const mlx_stream s);
int mlx_hanning(mlx_array* res, int M, const mlx_stream s);
int mlx_identity(mlx_array* res, int n, mlx_dtype dtype, const mlx_stream s);
int mlx_imag(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_inner(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_isclose(mlx_array* res, const mlx_array a, const mlx_array b, double rtol, double atol, bool equal_nan, const mlx_stream s);
int mlx_isfinite(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_isinf(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_isnan(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_isneginf(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_isposinf(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_kron(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_left_shift(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_less(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_less_equal(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_linspace(mlx_array* res, double start, double stop, int num, mlx_dtype dtype, const mlx_stream s);
int mlx_log(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_log10(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_log1p(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_log2(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_logaddexp(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_logcumsumexp(mlx_array* res, const mlx_array a, int axis, bool reverse, bool inclusive, const mlx_stream s);
int mlx_logical_and(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_logical_not(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_logical_or(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_logsumexp_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_logsumexp_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_logsumexp(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_masked_scatter(mlx_array* res, const mlx_array a, const mlx_array mask, const mlx_array src, const mlx_stream s);
int mlx_matmul(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_max_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_max_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_max(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_maximum(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_mean_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_mean_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_mean(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_median(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_meshgrid(mlx_vector_array* res, const mlx_vector_array arrays, bool sparse, const char* indexing, const mlx_stream s);
int mlx_min_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_min_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_min(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_minimum(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_moveaxis(mlx_array* res, const mlx_array a, int source, int destination, const mlx_stream s);
int mlx_multiply(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_nan_to_num(mlx_array* res, const mlx_array a, float nan, mlx_optional_float posinf, mlx_optional_float neginf, const mlx_stream s);
int mlx_negative(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_not_equal(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_number_of_elements(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool inverted, mlx_dtype dtype, const mlx_stream s);
int mlx_ones(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_stream s);
int mlx_ones_like(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_outer(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_pad(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const int* low_pad_size, size_t low_pad_size_num, const int* high_pad_size, size_t high_pad_size_num, const mlx_array pad_value, const char* mode, const mlx_stream s);
int mlx_pad_symmetric(mlx_array* res, const mlx_array a, int pad_width, const mlx_array pad_value, const char* mode, const mlx_stream s);
int mlx_partition_axis(mlx_array* res, const mlx_array a, int kth, int axis, const mlx_stream s);
int mlx_partition(mlx_array* res, const mlx_array a, int kth, const mlx_stream s);
int mlx_power(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_prod_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_prod_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_prod(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_put_along_axis(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array values, int axis, const mlx_stream s);
int mlx_qqmm(mlx_array* res, const mlx_array x, const mlx_array w, const mlx_array w_scales , mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_array global_scale_x , const mlx_array global_scale_w , const mlx_stream s);
int mlx_quantize(mlx_vector_array* res, const mlx_array w, mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_array global_scale , const mlx_stream s);
int mlx_quantized_matmul(mlx_array* res, const mlx_array x, const mlx_array w, const mlx_array scales, const mlx_array biases , bool transpose, mlx_optional_int group_size, mlx_optional_int bits, const char* mode, const mlx_stream s);
int mlx_radians(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_real(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_reciprocal(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_remainder(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_repeat_axis(mlx_array* res, const mlx_array arr, int repeats, int axis, const mlx_stream s);
int mlx_repeat(mlx_array* res, const mlx_array arr, int repeats, const mlx_stream s);
int mlx_reshape(mlx_array* res, const mlx_array a, const int* shape, size_t shape_num, const mlx_stream s);
int mlx_right_shift(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_roll_axis(mlx_array* res, const mlx_array a, const int* shift, size_t shift_num, int axis, const mlx_stream s);
int mlx_roll_axes(mlx_array* res, const mlx_array a, const int* shift, size_t shift_num, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_roll(mlx_array* res, const mlx_array a, const int* shift, size_t shift_num, const mlx_stream s);
int mlx_round(mlx_array* res, const mlx_array a, int decimals, const mlx_stream s);
int mlx_rsqrt(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_scatter(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_scatter_single(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
int mlx_scatter_add(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_scatter_add_single(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
int mlx_scatter_add_axis(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array values, int axis, const mlx_stream s);
int mlx_scatter_max(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_scatter_max_single(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
int mlx_scatter_min(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_scatter_min_single(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
int mlx_scatter_prod(mlx_array* res, const mlx_array a, const mlx_vector_array indices, const mlx_array updates, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_scatter_prod_single(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_array updates, int axis, const mlx_stream s);
int mlx_segmented_mm(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_array segments, const mlx_stream s);
int mlx_sigmoid(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_sign(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_sin(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_sinh(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_slice(mlx_array* res, const mlx_array a, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
int mlx_slice_dynamic(mlx_array* res, const mlx_array a, const mlx_array start, const int* axes, size_t axes_num, const int* slice_size, size_t slice_size_num, const mlx_stream s);
int mlx_slice_update(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
int mlx_slice_update_dynamic(mlx_array* res, const mlx_array src, const mlx_array update, const mlx_array start, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_slice_update_add(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
int mlx_slice_update_max(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
int mlx_slice_update_min(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
int mlx_slice_update_prod(mlx_array* res, const mlx_array src, const mlx_array update, const int* start, size_t start_num, const int* stop, size_t stop_num, const int* strides, size_t strides_num, const mlx_stream s);
int mlx_softmax_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool precise, const mlx_stream s);
int mlx_softmax_axis(mlx_array* res, const mlx_array a, int axis, bool precise, const mlx_stream s);
int mlx_softmax(mlx_array* res, const mlx_array a, bool precise, const mlx_stream s);
int mlx_sort_axis(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
int mlx_sort(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_split(mlx_vector_array* res, const mlx_array a, int num_splits, int axis, const mlx_stream s);
int mlx_split_sections(mlx_vector_array* res, const mlx_array a, const int* indices, size_t indices_num, int axis, const mlx_stream s);
int mlx_sqrt(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_square(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_squeeze_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_squeeze_axis(mlx_array* res, const mlx_array a, int axis, const mlx_stream s);
int mlx_squeeze(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_stack_axis(mlx_array* res, const mlx_vector_array arrays, int axis, const mlx_stream s);
int mlx_stack(mlx_array* res, const mlx_vector_array arrays, const mlx_stream s);
int mlx_std_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, int ddof, const mlx_stream s);
int mlx_std_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, int ddof, const mlx_stream s);
int mlx_std(mlx_array* res, const mlx_array a, bool keepdims, int ddof, const mlx_stream s);
int mlx_stop_gradient(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_subtract(mlx_array* res, const mlx_array a, const mlx_array b, const mlx_stream s);
int mlx_sum_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, const mlx_stream s);
int mlx_sum_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, const mlx_stream s);
int mlx_sum(mlx_array* res, const mlx_array a, bool keepdims, const mlx_stream s);
int mlx_swapaxes(mlx_array* res, const mlx_array a, int axis1, int axis2, const mlx_stream s);
int mlx_take_axis(mlx_array* res, const mlx_array a, const mlx_array indices, int axis, const mlx_stream s);
int mlx_take(mlx_array* res, const mlx_array a, const mlx_array indices, const mlx_stream s);
int mlx_take_along_axis(mlx_array* res, const mlx_array a, const mlx_array indices, int axis, const mlx_stream s);
int mlx_tan(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_tanh(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_tensordot(mlx_array* res, const mlx_array a, const mlx_array b, const int* axes_a, size_t axes_a_num, const int* axes_b, size_t axes_b_num, const mlx_stream s);
int mlx_tensordot_axis(mlx_array* res, const mlx_array a, const mlx_array b, int axis, const mlx_stream s);
int mlx_tile(mlx_array* res, const mlx_array arr, const int* reps, size_t reps_num, const mlx_stream s);
int mlx_to_fp8(mlx_array* res, const mlx_array x, const mlx_stream s);
int mlx_topk_axis(mlx_array* res, const mlx_array a, int k, int axis, const mlx_stream s);
int mlx_topk(mlx_array* res, const mlx_array a, int k, const mlx_stream s);
int mlx_trace(mlx_array* res, const mlx_array a, int offset, int axis1, int axis2, mlx_dtype dtype, const mlx_stream s);
int mlx_transpose_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, const mlx_stream s);
int mlx_transpose(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_tri(mlx_array* res, int n, int m, int k, mlx_dtype type, const mlx_stream s);
int mlx_tril(mlx_array* res, const mlx_array x, int k, const mlx_stream s);
int mlx_triu(mlx_array* res, const mlx_array x, int k, const mlx_stream s);
int mlx_unflatten(mlx_array* res, const mlx_array a, int axis, const int* shape, size_t shape_num, const mlx_stream s);
int mlx_var_axes(mlx_array* res, const mlx_array a, const int* axes, size_t axes_num, bool keepdims, int ddof, const mlx_stream s);
int mlx_var_axis(mlx_array* res, const mlx_array a, int axis, bool keepdims, int ddof, const mlx_stream s);
int mlx_var(mlx_array* res, const mlx_array a, bool keepdims, int ddof, const mlx_stream s);
int mlx_view(mlx_array* res, const mlx_array a, mlx_dtype dtype, const mlx_stream s);
int mlx_where(mlx_array* res, const mlx_array condition, const mlx_array x, const mlx_array y, const mlx_stream s);
int mlx_zeros(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_stream s);
int mlx_zeros_like(mlx_array* res, const mlx_array a, const mlx_stream s);
int mlx_random_bernoulli(mlx_array* res, const mlx_array p, const int* shape, size_t shape_num, const mlx_array key , const mlx_stream s);
int mlx_random_bits(mlx_array* res, const int* shape, size_t shape_num, int width, const mlx_array key , const mlx_stream s);
int mlx_random_categorical_shape(mlx_array* res, const mlx_array logits, int axis, const int* shape, size_t shape_num, const mlx_array key , const mlx_stream s);
int mlx_random_categorical_num_samples(mlx_array* res, const mlx_array logits_, int axis, int num_samples, const mlx_array key , const mlx_stream s);
int mlx_random_categorical(mlx_array* res, const mlx_array logits, int axis, const mlx_array key , const mlx_stream s);
int mlx_random_gumbel(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
int mlx_random_key(mlx_array* res, uint64_t seed);
int mlx_random_laplace(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, float loc, float scale, const mlx_array key , const mlx_stream s);
int mlx_random_multivariate_normal(mlx_array* res, const mlx_array mean, const mlx_array cov, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
int mlx_random_normal_broadcast(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array loc , const mlx_array scale , const mlx_array key , const mlx_stream s);
int mlx_random_normal(mlx_array* res, const int* shape, size_t shape_num, mlx_dtype dtype, float loc, float scale, const mlx_array key , const mlx_stream s);
int mlx_random_permutation(mlx_array* res, const mlx_array x, int axis, const mlx_array key , const mlx_stream s);
int mlx_random_permutation_arange(mlx_array* res, int x, const mlx_array key , const mlx_stream s);
int mlx_random_randint(mlx_array* res, const mlx_array low, const mlx_array high, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
int mlx_random_seed(uint64_t seed);
int mlx_random_split_num(mlx_array* res, const mlx_array key, int num, const mlx_stream s);
int mlx_random_split(mlx_array* res_0, mlx_array* res_1, const mlx_array key, const mlx_stream s);
int mlx_random_truncated_normal(mlx_array* res, const mlx_array lower, const mlx_array upper, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
int mlx_random_uniform(mlx_array* res, const mlx_array low, const mlx_array high, const int* shape, size_t shape_num, mlx_dtype dtype, const mlx_array key , const mlx_stream s);
mlx_stream mlx_stream_new(void);
mlx_stream mlx_stream_new_device(mlx_device dev);
int mlx_stream_set(mlx_stream* stream, const mlx_stream src);
int mlx_stream_free(mlx_stream stream);
int mlx_stream_tostring(mlx_string* str, mlx_stream stream);
bool mlx_stream_equal(mlx_stream lhs, mlx_stream rhs);
int mlx_stream_get_device(mlx_device* dev, mlx_stream stream);
int mlx_stream_get_index(int* index, mlx_stream stream);
int mlx_synchronize(mlx_stream stream);
int mlx_get_default_stream(mlx_stream* stream, mlx_device dev);
int mlx_set_default_stream(mlx_stream stream);
mlx_stream mlx_default_cpu_stream_new(void);
mlx_stream mlx_default_gpu_stream_new(void);
mlx_string mlx_string_new(void);
mlx_string mlx_string_new_data(const char* str);
int mlx_string_set(mlx_string* str, const mlx_string src);
const char* mlx_string_data(mlx_string str);
int mlx_string_free(mlx_string str);
int mlx_async_eval(const mlx_vector_array outputs);
int mlx_checkpoint(mlx_closure* res, const mlx_closure fun);
int mlx_custom_function(mlx_closure* res, const mlx_closure fun, const mlx_closure_custom fun_vjp , const mlx_closure_custom_jvp fun_jvp , const mlx_closure_custom_vmap fun_vmap);
int mlx_custom_vjp(mlx_closure* res, const mlx_closure fun, const mlx_closure_custom fun_vjp);
int mlx_eval(const mlx_vector_array outputs);
int mlx_jvp(mlx_vector_array* res_0, mlx_vector_array* res_1, const mlx_closure fun, const mlx_vector_array primals, const mlx_vector_array tangents);
int mlx_value_and_grad(mlx_closure_value_and_grad* res, const mlx_closure fun, const int* argnums, size_t argnums_num);
int mlx_vjp(mlx_vector_array* res_0, mlx_vector_array* res_1, const mlx_closure fun, const mlx_vector_array primals, const mlx_vector_array cotangents);
int mlx_detail_vmap_replace(mlx_vector_array* res, const mlx_vector_array inputs, const mlx_vector_array s_inputs, const mlx_vector_array s_outputs, const int* in_axes, size_t in_axes_num, const int* out_axes, size_t out_axes_num);
int mlx_detail_vmap_trace(mlx_vector_array* res_0, mlx_vector_array* res_1, const mlx_closure fun, const mlx_vector_array inputs, const int* in_axes, size_t in_axes_num);
mlx_vector_array mlx_vector_array_new(void);
int mlx_vector_array_set(mlx_vector_array* vec, const mlx_vector_array src);
int mlx_vector_array_free(mlx_vector_array vec);
mlx_vector_array mlx_vector_array_new_data(const mlx_array* data, size_t size);
mlx_vector_array mlx_vector_array_new_value(const mlx_array val);
int mlx_vector_array_set_data(mlx_vector_array* vec, const mlx_array* data, size_t size);
int mlx_vector_array_set_value(mlx_vector_array* vec, const mlx_array val);
int mlx_vector_array_append_data(mlx_vector_array vec, const mlx_array* data, size_t size);
int mlx_vector_array_append_value(mlx_vector_array vec, const mlx_array val);
size_t mlx_vector_array_size(mlx_vector_array vec);
int mlx_vector_array_get(mlx_array* res, const mlx_vector_array vec, size_t idx);
mlx_vector_vector_array mlx_vector_vector_array_new(void);
int mlx_vector_vector_array_set(mlx_vector_vector_array* vec, const mlx_vector_vector_array src);
int mlx_vector_vector_array_free(mlx_vector_vector_array vec);
mlx_vector_vector_array mlx_vector_vector_array_new_data(const mlx_vector_array* data, size_t size);
mlx_vector_vector_array mlx_vector_vector_array_new_value(const mlx_vector_array val);
int mlx_vector_vector_array_set_data(mlx_vector_vector_array* vec, const mlx_vector_array* data, size_t size);
int mlx_vector_vector_array_set_value(mlx_vector_vector_array* vec, const mlx_vector_array val);
int mlx_vector_vector_array_append_data(mlx_vector_vector_array vec, const mlx_vector_array* data, size_t size);
int mlx_vector_vector_array_append_value(mlx_vector_vector_array vec, const mlx_vector_array val);
size_t mlx_vector_vector_array_size(mlx_vector_vector_array vec);
int mlx_vector_vector_array_get(mlx_vector_array* res, const mlx_vector_vector_array vec, size_t idx);
mlx_vector_int mlx_vector_int_new(void);
int mlx_vector_int_set(mlx_vector_int* vec, const mlx_vector_int src);
int mlx_vector_int_free(mlx_vector_int vec);
mlx_vector_int mlx_vector_int_new_data(int* data, size_t size);
mlx_vector_int mlx_vector_int_new_value(int val);
int mlx_vector_int_set_data(mlx_vector_int* vec, int* data, size_t size);
int mlx_vector_int_set_value(mlx_vector_int* vec, int val);
int mlx_vector_int_append_data(mlx_vector_int vec, int* data, size_t size);
int mlx_vector_int_append_value(mlx_vector_int vec, int val);
size_t mlx_vector_int_size(mlx_vector_int vec);
int mlx_vector_int_get(int* res, const mlx_vector_int vec, size_t idx);
mlx_vector_string mlx_vector_string_new(void);
int mlx_vector_string_set(mlx_vector_string* vec, const mlx_vector_string src);
int mlx_vector_string_free(mlx_vector_string vec);
mlx_vector_string mlx_vector_string_new_data(const char** data, size_t size);
mlx_vector_string mlx_vector_string_new_value(const char* val);
int mlx_vector_string_set_data(mlx_vector_string* vec, const char** data, size_t size);
int mlx_vector_string_set_value(mlx_vector_string* vec, const char* val);
int mlx_vector_string_append_data(mlx_vector_string vec, const char** data, size_t size);
int mlx_vector_string_append_value(mlx_vector_string vec, const char* val);
size_t mlx_vector_string_size(mlx_vector_string vec);
int mlx_vector_string_get(char** res, const mlx_vector_string vec, size_t idx);
int mlx_version(mlx_string* str_);
#endif // MLX_WRAPPERS_H