1use crate::array::Array;
2use crate::error::Result;
3use crate::utils::axes_or_default_to_all;
4use crate::utils::guard::Guarded;
5use crate::{Axes, Stream};
6use mlx_internal_macros::generate_macro;
7
8#[derive(Debug, Clone, Default, PartialEq, Eq)]
10pub struct CountNonzeroOptions {
11 pub axes: Axes,
13
14 pub keep_dims: bool,
16}
17
18static EMPTY_AXES_DUMMY: [i32; 1] = [0];
19
20impl Array {
21 pub fn count_nonzero(&self, options: CountNonzeroOptions) -> Result<Array> {
39 let stream = Stream::thread_local_or_default();
40 match options.axes {
41 Axes::All => Array::try_from_op(|res| unsafe {
42 mlx_sys::mlx_count_nonzero(
43 res,
44 self.as_ptr(),
45 options.keep_dims,
46 stream.as_ref().as_ptr(),
47 )
48 }),
49 Axes::Axis(axis) => Array::try_from_op(|res| unsafe {
50 mlx_sys::mlx_count_nonzero_axis(
51 res,
52 self.as_ptr(),
53 axis,
54 options.keep_dims,
55 stream.as_ref().as_ptr(),
56 )
57 }),
58 Axes::Axes(axes) => {
59 let axes_ptr = if axes.is_empty() {
60 EMPTY_AXES_DUMMY.as_ptr()
61 } else {
62 axes.as_ptr()
63 };
64 Array::try_from_op(|res| unsafe {
65 mlx_sys::mlx_count_nonzero_axes(
66 res,
67 self.as_ptr(),
68 axes_ptr,
69 axes.len(),
70 options.keep_dims,
71 stream.as_ref().as_ptr(),
72 )
73 })
74 }
75 }
76 }
77
78 pub fn all_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
96 let stream = Stream::thread_local_or_default();
97 Array::try_from_op(|res| unsafe {
98 mlx_sys::mlx_all_axes(
99 res,
100 self.as_ptr(),
101 axes.as_ptr(),
102 axes.len(),
103 keep_dims.into().unwrap_or(false),
104 stream.as_ref().as_ptr(),
105 )
106 })
107 }
108
109 #[deprecated(
111 since = "0.26.0",
112 note = "use `with_stream` or `with_device` around `all_axes`"
113 )]
114 pub fn all_axes_device(
115 &self,
116 axes: &[i32],
117 keep_dims: impl Into<Option<bool>>,
118 stream: impl AsRef<Stream>,
119 ) -> Result<Array> {
120 crate::with_stream(stream.as_ref(), || self.all_axes(axes, keep_dims))
121 }
122
123 pub fn all_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
125 let stream = Stream::thread_local_or_default();
126 Array::try_from_op(|res| unsafe {
127 mlx_sys::mlx_all_axis(
128 res,
129 self.as_ptr(),
130 axis,
131 keep_dims.into().unwrap_or(false),
132 stream.as_ref().as_ptr(),
133 )
134 })
135 }
136
137 #[deprecated(
139 since = "0.26.0",
140 note = "use `with_stream` or `with_device` around `all_axis`"
141 )]
142 pub fn all_axis_device(
143 &self,
144 axis: i32,
145 keep_dims: impl Into<Option<bool>>,
146 stream: impl AsRef<Stream>,
147 ) -> Result<Array> {
148 crate::with_stream(stream.as_ref(), || self.all_axis(axis, keep_dims))
149 }
150
151 pub fn all(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
153 let stream = Stream::thread_local_or_default();
154 Array::try_from_op(|res| unsafe {
155 mlx_sys::mlx_all(
156 res,
157 self.as_ptr(),
158 keep_dims.into().unwrap_or(false),
159 stream.as_ref().as_ptr(),
160 )
161 })
162 }
163
164 #[deprecated(
166 since = "0.26.0",
167 note = "use `with_stream` or `with_device` around `all`"
168 )]
169 pub fn all_device(
170 &self,
171 keep_dims: impl Into<Option<bool>>,
172 stream: impl AsRef<Stream>,
173 ) -> Result<Array> {
174 crate::with_stream(stream.as_ref(), || self.all(keep_dims))
175 }
176
177 pub fn prod_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
194 let stream = Stream::thread_local_or_default();
195 Array::try_from_op(|res| unsafe {
196 mlx_sys::mlx_prod_axes(
197 res,
198 self.as_ptr(),
199 axes.as_ptr(),
200 axes.len(),
201 keep_dims.into().unwrap_or(false),
202 stream.as_ref().as_ptr(),
203 )
204 })
205 }
206
207 #[deprecated(
209 since = "0.26.0",
210 note = "use `with_stream` or `with_device` around `prod_axes`"
211 )]
212 pub fn prod_axes_device(
213 &self,
214 axes: &[i32],
215 keep_dims: impl Into<Option<bool>>,
216 stream: impl AsRef<Stream>,
217 ) -> Result<Array> {
218 crate::with_stream(stream.as_ref(), || self.prod_axes(axes, keep_dims))
219 }
220
221 pub fn prod_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
223 let stream = Stream::thread_local_or_default();
224 Array::try_from_op(|res| unsafe {
225 mlx_sys::mlx_prod_axis(
226 res,
227 self.as_ptr(),
228 axis,
229 keep_dims.into().unwrap_or(false),
230 stream.as_ref().as_ptr(),
231 )
232 })
233 }
234
235 #[deprecated(
237 since = "0.26.0",
238 note = "use `with_stream` or `with_device` around `prod_axis`"
239 )]
240 pub fn prod_axis_device(
241 &self,
242 axis: i32,
243 keep_dims: impl Into<Option<bool>>,
244 stream: impl AsRef<Stream>,
245 ) -> Result<Array> {
246 crate::with_stream(stream.as_ref(), || self.prod_axis(axis, keep_dims))
247 }
248
249 pub fn prod(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
251 let stream = Stream::thread_local_or_default();
252 Array::try_from_op(|res| unsafe {
253 mlx_sys::mlx_prod(
254 res,
255 self.as_ptr(),
256 keep_dims.into().unwrap_or(false),
257 stream.as_ref().as_ptr(),
258 )
259 })
260 }
261
262 #[deprecated(
264 since = "0.26.0",
265 note = "use `with_stream` or `with_device` around `prod`"
266 )]
267 pub fn prod_device(
268 &self,
269 keep_dims: impl Into<Option<bool>>,
270 stream: impl AsRef<Stream>,
271 ) -> Result<Array> {
272 crate::with_stream(stream.as_ref(), || self.prod(keep_dims))
273 }
274
275 pub fn max_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
292 let stream = Stream::thread_local_or_default();
293 Array::try_from_op(|res| unsafe {
294 mlx_sys::mlx_max_axes(
295 res,
296 self.as_ptr(),
297 axes.as_ptr(),
298 axes.len(),
299 keep_dims.into().unwrap_or(false),
300 stream.as_ref().as_ptr(),
301 )
302 })
303 }
304
305 #[deprecated(
307 since = "0.26.0",
308 note = "use `with_stream` or `with_device` around `max_axes`"
309 )]
310 pub fn max_axes_device(
311 &self,
312 axes: &[i32],
313 keep_dims: impl Into<Option<bool>>,
314 stream: impl AsRef<Stream>,
315 ) -> Result<Array> {
316 crate::with_stream(stream.as_ref(), || self.max_axes(axes, keep_dims))
317 }
318
319 pub fn max_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
321 let stream = Stream::thread_local_or_default();
322 Array::try_from_op(|res| unsafe {
323 mlx_sys::mlx_max_axis(
324 res,
325 self.as_ptr(),
326 axis,
327 keep_dims.into().unwrap_or(false),
328 stream.as_ref().as_ptr(),
329 )
330 })
331 }
332
333 #[deprecated(
335 since = "0.26.0",
336 note = "use `with_stream` or `with_device` around `max_axis`"
337 )]
338 pub fn max_axis_device(
339 &self,
340 axis: i32,
341 keep_dims: impl Into<Option<bool>>,
342 stream: impl AsRef<Stream>,
343 ) -> Result<Array> {
344 crate::with_stream(stream.as_ref(), || self.max_axis(axis, keep_dims))
345 }
346
347 pub fn max(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
349 let stream = Stream::thread_local_or_default();
350 Array::try_from_op(|res| unsafe {
351 mlx_sys::mlx_max(
352 res,
353 self.as_ptr(),
354 keep_dims.into().unwrap_or(false),
355 stream.as_ref().as_ptr(),
356 )
357 })
358 }
359
360 #[deprecated(
362 since = "0.26.0",
363 note = "use `with_stream` or `with_device` around `max`"
364 )]
365 pub fn max_device(
366 &self,
367 keep_dims: impl Into<Option<bool>>,
368 stream: impl AsRef<Stream>,
369 ) -> Result<Array> {
370 crate::with_stream(stream.as_ref(), || self.max(keep_dims))
371 }
372
373 pub fn sum_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
390 let stream = Stream::thread_local_or_default();
391 Array::try_from_op(|res| unsafe {
392 mlx_sys::mlx_sum_axes(
393 res,
394 self.as_ptr(),
395 axes.as_ptr(),
396 axes.len(),
397 keep_dims.into().unwrap_or(false),
398 stream.as_ref().as_ptr(),
399 )
400 })
401 }
402
403 #[deprecated(
405 since = "0.26.0",
406 note = "use `with_stream` or `with_device` around `sum_axes`"
407 )]
408 pub fn sum_axes_device(
409 &self,
410 axes: &[i32],
411 keep_dims: impl Into<Option<bool>>,
412 stream: impl AsRef<Stream>,
413 ) -> Result<Array> {
414 crate::with_stream(stream.as_ref(), || self.sum_axes(axes, keep_dims))
415 }
416
417 pub fn sum_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
419 let stream = Stream::thread_local_or_default();
420 Array::try_from_op(|res| unsafe {
421 mlx_sys::mlx_sum_axis(
422 res,
423 self.as_ptr(),
424 axis,
425 keep_dims.into().unwrap_or(false),
426 stream.as_ref().as_ptr(),
427 )
428 })
429 }
430
431 #[deprecated(
433 since = "0.26.0",
434 note = "use `with_stream` or `with_device` around `sum_axis`"
435 )]
436 pub fn sum_axis_device(
437 &self,
438 axis: i32,
439 keep_dims: impl Into<Option<bool>>,
440 stream: impl AsRef<Stream>,
441 ) -> Result<Array> {
442 crate::with_stream(stream.as_ref(), || self.sum_axis(axis, keep_dims))
443 }
444
445 pub fn sum(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
447 let stream = Stream::thread_local_or_default();
448 Array::try_from_op(|res| unsafe {
449 mlx_sys::mlx_sum(
450 res,
451 self.as_ptr(),
452 keep_dims.into().unwrap_or(false),
453 stream.as_ref().as_ptr(),
454 )
455 })
456 }
457
458 #[deprecated(
460 since = "0.26.0",
461 note = "use `with_stream` or `with_device` around `sum`"
462 )]
463 pub fn sum_device(
464 &self,
465 keep_dims: impl Into<Option<bool>>,
466 stream: impl AsRef<Stream>,
467 ) -> Result<Array> {
468 crate::with_stream(stream.as_ref(), || self.sum(keep_dims))
469 }
470
471 pub fn mean_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
488 let stream = Stream::thread_local_or_default();
489 let axes = axes_or_default_to_all(axes, self.ndim() as i32);
490 Array::try_from_op(|res| unsafe {
491 mlx_sys::mlx_mean_axes(
492 res,
493 self.as_ptr(),
494 axes.as_ptr(),
495 axes.len(),
496 keep_dims.into().unwrap_or(false),
497 stream.as_ref().as_ptr(),
498 )
499 })
500 }
501
502 #[deprecated(
504 since = "0.26.0",
505 note = "use `with_stream` or `with_device` around `mean_axes`"
506 )]
507 pub fn mean_axes_device(
508 &self,
509 axes: &[i32],
510 keep_dims: impl Into<Option<bool>>,
511 stream: impl AsRef<Stream>,
512 ) -> Result<Array> {
513 crate::with_stream(stream.as_ref(), || self.mean_axes(axes, keep_dims))
514 }
515
516 pub fn mean_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
518 let stream = Stream::thread_local_or_default();
519 Array::try_from_op(|res| unsafe {
520 mlx_sys::mlx_mean_axis(
521 res,
522 self.as_ptr(),
523 axis,
524 keep_dims.into().unwrap_or(false),
525 stream.as_ref().as_ptr(),
526 )
527 })
528 }
529
530 #[deprecated(
532 since = "0.26.0",
533 note = "use `with_stream` or `with_device` around `mean_axis`"
534 )]
535 pub fn mean_axis_device(
536 &self,
537 axis: i32,
538 keep_dims: impl Into<Option<bool>>,
539 stream: impl AsRef<Stream>,
540 ) -> Result<Array> {
541 crate::with_stream(stream.as_ref(), || self.mean_axis(axis, keep_dims))
542 }
543
544 pub fn mean(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
546 let stream = Stream::thread_local_or_default();
547 Array::try_from_op(|res| unsafe {
548 mlx_sys::mlx_mean(
549 res,
550 self.as_ptr(),
551 keep_dims.into().unwrap_or(false),
552 stream.as_ref().as_ptr(),
553 )
554 })
555 }
556
557 #[deprecated(
559 since = "0.26.0",
560 note = "use `with_stream` or `with_device` around `mean`"
561 )]
562 pub fn mean_device(
563 &self,
564 keep_dims: impl Into<Option<bool>>,
565 stream: impl AsRef<Stream>,
566 ) -> Result<Array> {
567 crate::with_stream(stream.as_ref(), || self.mean(keep_dims))
568 }
569
570 pub fn min_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
587 let stream = Stream::thread_local_or_default();
588 Array::try_from_op(|res| unsafe {
589 mlx_sys::mlx_min_axes(
590 res,
591 self.as_ptr(),
592 axes.as_ptr(),
593 axes.len(),
594 keep_dims.into().unwrap_or(false),
595 stream.as_ref().as_ptr(),
596 )
597 })
598 }
599
600 #[deprecated(
602 since = "0.26.0",
603 note = "use `with_stream` or `with_device` around `min_axes`"
604 )]
605 pub fn min_axes_device(
606 &self,
607 axes: &[i32],
608 keep_dims: impl Into<Option<bool>>,
609 stream: impl AsRef<Stream>,
610 ) -> Result<Array> {
611 crate::with_stream(stream.as_ref(), || self.min_axes(axes, keep_dims))
612 }
613
614 pub fn min_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
616 let stream = Stream::thread_local_or_default();
617 Array::try_from_op(|res| unsafe {
618 mlx_sys::mlx_min_axis(
619 res,
620 self.as_ptr(),
621 axis,
622 keep_dims.into().unwrap_or(false),
623 stream.as_ref().as_ptr(),
624 )
625 })
626 }
627
628 #[deprecated(
630 since = "0.26.0",
631 note = "use `with_stream` or `with_device` around `min_axis`"
632 )]
633 pub fn min_axis_device(
634 &self,
635 axis: i32,
636 keep_dims: impl Into<Option<bool>>,
637 stream: impl AsRef<Stream>,
638 ) -> Result<Array> {
639 crate::with_stream(stream.as_ref(), || self.min_axis(axis, keep_dims))
640 }
641
642 pub fn min(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
644 let stream = Stream::thread_local_or_default();
645 Array::try_from_op(|res| unsafe {
646 mlx_sys::mlx_min(
647 res,
648 self.as_ptr(),
649 keep_dims.into().unwrap_or(false),
650 stream.as_ref().as_ptr(),
651 )
652 })
653 }
654
655 #[deprecated(
657 since = "0.26.0",
658 note = "use `with_stream` or `with_device` around `min`"
659 )]
660 pub fn min_device(
661 &self,
662 keep_dims: impl Into<Option<bool>>,
663 stream: impl AsRef<Stream>,
664 ) -> Result<Array> {
665 crate::with_stream(stream.as_ref(), || self.min(keep_dims))
666 }
667
668 pub fn var_axes(
676 &self,
677 axes: &[i32],
678 keep_dims: impl Into<Option<bool>>,
679 ddof: impl Into<Option<i32>>,
680 ) -> Result<Array> {
681 let stream = Stream::thread_local_or_default();
682 Array::try_from_op(|res| unsafe {
683 mlx_sys::mlx_var_axes(
684 res,
685 self.as_ptr(),
686 axes.as_ptr(),
687 axes.len(),
688 keep_dims.into().unwrap_or(false),
689 ddof.into().unwrap_or(0),
690 stream.as_ref().as_ptr(),
691 )
692 })
693 }
694
695 #[deprecated(
697 since = "0.26.0",
698 note = "use `with_stream` or `with_device` around `var_axes`"
699 )]
700 pub fn var_axes_device(
701 &self,
702 axes: &[i32],
703 keep_dims: impl Into<Option<bool>>,
704 ddof: impl Into<Option<i32>>,
705 stream: impl AsRef<Stream>,
706 ) -> Result<Array> {
707 crate::with_stream(stream.as_ref(), || self.var_axes(axes, keep_dims, ddof))
708 }
709
710 pub fn var_axis(
712 &self,
713 axis: i32,
714 keep_dims: impl Into<Option<bool>>,
715 ddof: impl Into<Option<i32>>,
716 ) -> Result<Array> {
717 let stream = Stream::thread_local_or_default();
718 Array::try_from_op(|res| unsafe {
719 mlx_sys::mlx_var_axis(
720 res,
721 self.as_ptr(),
722 axis,
723 keep_dims.into().unwrap_or(false),
724 ddof.into().unwrap_or(0),
725 stream.as_ref().as_ptr(),
726 )
727 })
728 }
729
730 #[deprecated(
732 since = "0.26.0",
733 note = "use `with_stream` or `with_device` around `var_axis`"
734 )]
735 pub fn var_axis_device(
736 &self,
737 axis: i32,
738 keep_dims: impl Into<Option<bool>>,
739 ddof: impl Into<Option<i32>>,
740 stream: impl AsRef<Stream>,
741 ) -> Result<Array> {
742 crate::with_stream(stream.as_ref(), || self.var_axis(axis, keep_dims, ddof))
743 }
744
745 pub fn var(
747 &self,
748 keep_dims: impl Into<Option<bool>>,
749 ddof: impl Into<Option<i32>>,
750 ) -> Result<Array> {
751 let stream = Stream::thread_local_or_default();
752 Array::try_from_op(|res| unsafe {
753 mlx_sys::mlx_var(
754 res,
755 self.as_ptr(),
756 keep_dims.into().unwrap_or(false),
757 ddof.into().unwrap_or(0),
758 stream.as_ref().as_ptr(),
759 )
760 })
761 }
762
763 #[deprecated(
765 since = "0.26.0",
766 note = "use `with_stream` or `with_device` around `var`"
767 )]
768 pub fn var_device(
769 &self,
770 keep_dims: impl Into<Option<bool>>,
771 ddof: impl Into<Option<i32>>,
772 stream: impl AsRef<Stream>,
773 ) -> Result<Array> {
774 crate::with_stream(stream.as_ref(), || self.var(keep_dims, ddof))
775 }
776
777 pub fn median_axes(&self, axes: &[i32], keep_dims: impl Into<Option<bool>>) -> Result<Array> {
784 let stream = Stream::thread_local_or_default();
785 Array::try_from_op(|res| unsafe {
786 mlx_sys::mlx_median_axes(
787 res,
788 self.as_ptr(),
789 axes.as_ptr(),
790 axes.len(),
791 keep_dims.into().unwrap_or(false),
792 stream.as_ref().as_ptr(),
793 )
794 })
795 }
796
797 #[deprecated(
799 since = "0.26.0",
800 note = "use `with_stream` or `with_device` around `median_axes`"
801 )]
802 pub fn median_axes_device(
803 &self,
804 axes: &[i32],
805 keep_dims: impl Into<Option<bool>>,
806 stream: impl AsRef<Stream>,
807 ) -> Result<Array> {
808 crate::with_stream(stream.as_ref(), || self.median_axes(axes, keep_dims))
809 }
810
811 pub fn median_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
813 let stream = Stream::thread_local_or_default();
814 Array::try_from_op(|res| unsafe {
815 mlx_sys::mlx_median_axis(
816 res,
817 self.as_ptr(),
818 axis,
819 keep_dims.into().unwrap_or(false),
820 stream.as_ref().as_ptr(),
821 )
822 })
823 }
824
825 #[deprecated(
827 since = "0.26.0",
828 note = "use `with_stream` or `with_device` around `median_axis`"
829 )]
830 pub fn median_axis_device(
831 &self,
832 axis: i32,
833 keep_dims: impl Into<Option<bool>>,
834 stream: impl AsRef<Stream>,
835 ) -> Result<Array> {
836 crate::with_stream(stream.as_ref(), || self.median_axis(axis, keep_dims))
837 }
838
839 pub fn median(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
841 let stream = Stream::thread_local_or_default();
842 Array::try_from_op(|res| unsafe {
843 mlx_sys::mlx_median(
844 res,
845 self.as_ptr(),
846 keep_dims.into().unwrap_or(false),
847 stream.as_ref().as_ptr(),
848 )
849 })
850 }
851
852 #[deprecated(
854 since = "0.26.0",
855 note = "use `with_stream` or `with_device` around `median`"
856 )]
857 pub fn median_device(
858 &self,
859 keep_dims: impl Into<Option<bool>>,
860 stream: impl AsRef<Stream>,
861 ) -> Result<Array> {
862 crate::with_stream(stream.as_ref(), || self.median(keep_dims))
863 }
864
865 pub fn logsumexp_axes(
874 &self,
875 axes: &[i32],
876 keep_dims: impl Into<Option<bool>>,
877 ) -> Result<Array> {
878 let stream = Stream::thread_local_or_default();
879 Array::try_from_op(|res| unsafe {
880 mlx_sys::mlx_logsumexp_axes(
881 res,
882 self.as_ptr(),
883 axes.as_ptr(),
884 axes.len(),
885 keep_dims.into().unwrap_or(false),
886 stream.as_ref().as_ptr(),
887 )
888 })
889 }
890
891 #[deprecated(
893 since = "0.26.0",
894 note = "use `with_stream` or `with_device` around `logsumexp_axes`"
895 )]
896 pub fn logsumexp_axes_device(
897 &self,
898 axes: &[i32],
899 keep_dims: impl Into<Option<bool>>,
900 stream: impl AsRef<Stream>,
901 ) -> Result<Array> {
902 crate::with_stream(stream.as_ref(), || self.logsumexp_axes(axes, keep_dims))
903 }
904
905 pub fn logsumexp_axis(&self, axis: i32, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
907 let stream = Stream::thread_local_or_default();
908 Array::try_from_op(|res| unsafe {
909 mlx_sys::mlx_logsumexp_axis(
910 res,
911 self.as_ptr(),
912 axis,
913 keep_dims.into().unwrap_or(false),
914 stream.as_ref().as_ptr(),
915 )
916 })
917 }
918
919 #[deprecated(
921 since = "0.26.0",
922 note = "use `with_stream` or `with_device` around `logsumexp_axis`"
923 )]
924 pub fn logsumexp_axis_device(
925 &self,
926 axis: i32,
927 keep_dims: impl Into<Option<bool>>,
928 stream: impl AsRef<Stream>,
929 ) -> Result<Array> {
930 crate::with_stream(stream.as_ref(), || self.logsumexp_axis(axis, keep_dims))
931 }
932
933 pub fn logsumexp(&self, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
935 let stream = Stream::thread_local_or_default();
936 Array::try_from_op(|res| unsafe {
937 mlx_sys::mlx_logsumexp(
938 res,
939 self.as_ptr(),
940 keep_dims.into().unwrap_or(false),
941 stream.as_ref().as_ptr(),
942 )
943 })
944 }
945
946 #[deprecated(
948 since = "0.26.0",
949 note = "use `with_stream` or `with_device` around `logsumexp`"
950 )]
951 pub fn logsumexp_device(
952 &self,
953 keep_dims: impl Into<Option<bool>>,
954 stream: impl AsRef<Stream>,
955 ) -> Result<Array> {
956 crate::with_stream(stream.as_ref(), || self.logsumexp(keep_dims))
957 }
958}
959
960pub fn all_axes(
962 array: impl AsRef<Array>,
963 axes: &[i32],
964 keep_dims: impl Into<Option<bool>>,
965) -> Result<Array> {
966 array.as_ref().all_axes(axes, keep_dims)
967}
968
969#[generate_macro(customize(forwarding_shim = true))]
971#[deprecated(
972 since = "0.26.0",
973 note = "use `with_stream` or `with_device` around `all_axes`"
974)]
975pub fn all_axes_device(
976 array: impl AsRef<Array>,
977 axes: &[i32],
978 #[optional] keep_dims: impl Into<Option<bool>>,
979 #[optional] stream: impl AsRef<Stream>,
980) -> Result<Array> {
981 crate::with_stream(stream.as_ref(), || all_axes(array, axes, keep_dims))
982}
983
984pub fn all_axis(
986 array: impl AsRef<Array>,
987 axis: i32,
988 keep_dims: impl Into<Option<bool>>,
989) -> Result<Array> {
990 array.as_ref().all_axis(axis, keep_dims)
991}
992
993#[generate_macro(customize(forwarding_shim = true))]
995#[deprecated(
996 since = "0.26.0",
997 note = "use `with_stream` or `with_device` around `all_axis`"
998)]
999pub fn all_axis_device(
1000 array: impl AsRef<Array>,
1001 axis: i32,
1002 #[optional] keep_dims: impl Into<Option<bool>>,
1003 #[optional] stream: impl AsRef<Stream>,
1004) -> Result<Array> {
1005 crate::with_stream(stream.as_ref(), || all_axis(array, axis, keep_dims))
1006}
1007
1008pub fn all(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1010 array.as_ref().all(keep_dims)
1011}
1012
1013#[generate_macro(customize(forwarding_shim = true))]
1015#[deprecated(
1016 since = "0.26.0",
1017 note = "use `with_stream` or `with_device` around `all`"
1018)]
1019pub fn all_device(
1020 array: impl AsRef<Array>,
1021 #[optional] keep_dims: impl Into<Option<bool>>,
1022 #[optional] stream: impl AsRef<Stream>,
1023) -> Result<Array> {
1024 crate::with_stream(stream.as_ref(), || all(array, keep_dims))
1025}
1026
1027pub fn prod_axes(
1029 array: impl AsRef<Array>,
1030 axes: &[i32],
1031 keep_dims: impl Into<Option<bool>>,
1032) -> Result<Array> {
1033 array.as_ref().prod_axes(axes, keep_dims)
1034}
1035
1036#[generate_macro(customize(forwarding_shim = true))]
1038#[deprecated(
1039 since = "0.26.0",
1040 note = "use `with_stream` or `with_device` around `prod_axes`"
1041)]
1042pub fn prod_axes_device(
1043 array: impl AsRef<Array>,
1044 axes: &[i32],
1045 #[optional] keep_dims: impl Into<Option<bool>>,
1046 #[optional] stream: impl AsRef<Stream>,
1047) -> Result<Array> {
1048 crate::with_stream(stream.as_ref(), || prod_axes(array, axes, keep_dims))
1049}
1050
1051pub fn prod_axis(
1053 array: impl AsRef<Array>,
1054 axis: i32,
1055 keep_dims: impl Into<Option<bool>>,
1056) -> Result<Array> {
1057 array.as_ref().prod_axis(axis, keep_dims)
1058}
1059
1060#[generate_macro(customize(forwarding_shim = true))]
1062#[deprecated(
1063 since = "0.26.0",
1064 note = "use `with_stream` or `with_device` around `prod_axis`"
1065)]
1066pub fn prod_axis_device(
1067 array: impl AsRef<Array>,
1068 axis: i32,
1069 #[optional] keep_dims: impl Into<Option<bool>>,
1070 #[optional] stream: impl AsRef<Stream>,
1071) -> Result<Array> {
1072 crate::with_stream(stream.as_ref(), || prod_axis(array, axis, keep_dims))
1073}
1074
1075pub fn prod(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1077 array.as_ref().prod(keep_dims)
1078}
1079
1080#[generate_macro(customize(forwarding_shim = true))]
1082#[deprecated(
1083 since = "0.26.0",
1084 note = "use `with_stream` or `with_device` around `prod`"
1085)]
1086pub fn prod_device(
1087 array: impl AsRef<Array>,
1088 #[optional] keep_dims: impl Into<Option<bool>>,
1089 #[optional] stream: impl AsRef<Stream>,
1090) -> Result<Array> {
1091 crate::with_stream(stream.as_ref(), || prod(array, keep_dims))
1092}
1093
1094pub fn max_axes(
1096 array: impl AsRef<Array>,
1097 axes: &[i32],
1098 keep_dims: impl Into<Option<bool>>,
1099) -> Result<Array> {
1100 array.as_ref().max_axes(axes, keep_dims)
1101}
1102
1103#[generate_macro(customize(forwarding_shim = true))]
1105#[deprecated(
1106 since = "0.26.0",
1107 note = "use `with_stream` or `with_device` around `max_axes`"
1108)]
1109pub fn max_axes_device(
1110 array: impl AsRef<Array>,
1111 axes: &[i32],
1112 #[optional] keep_dims: impl Into<Option<bool>>,
1113 #[optional] stream: impl AsRef<Stream>,
1114) -> Result<Array> {
1115 crate::with_stream(stream.as_ref(), || max_axes(array, axes, keep_dims))
1116}
1117
1118pub fn max_axis(
1120 array: impl AsRef<Array>,
1121 axis: i32,
1122 keep_dims: impl Into<Option<bool>>,
1123) -> Result<Array> {
1124 array.as_ref().max_axis(axis, keep_dims)
1125}
1126
1127#[generate_macro(customize(forwarding_shim = true))]
1129#[deprecated(
1130 since = "0.26.0",
1131 note = "use `with_stream` or `with_device` around `max_axis`"
1132)]
1133pub fn max_axis_device(
1134 array: impl AsRef<Array>,
1135 axis: i32,
1136 #[optional] keep_dims: impl Into<Option<bool>>,
1137 #[optional] stream: impl AsRef<Stream>,
1138) -> Result<Array> {
1139 crate::with_stream(stream.as_ref(), || max_axis(array, axis, keep_dims))
1140}
1141
1142pub fn max(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1144 array.as_ref().max(keep_dims)
1145}
1146
1147#[generate_macro(customize(forwarding_shim = true))]
1149#[deprecated(
1150 since = "0.26.0",
1151 note = "use `with_stream` or `with_device` around `max`"
1152)]
1153pub fn max_device(
1154 array: impl AsRef<Array>,
1155 #[optional] keep_dims: impl Into<Option<bool>>,
1156 #[optional] stream: impl AsRef<Stream>,
1157) -> Result<Array> {
1158 crate::with_stream(stream.as_ref(), || max(array, keep_dims))
1159}
1160
1161pub fn std_axes(
1171 a: impl AsRef<Array>,
1172 axes: &[i32],
1173 keep_dims: impl Into<Option<bool>>,
1174 ddof: impl Into<Option<i32>>,
1175) -> Result<Array> {
1176 let stream = Stream::thread_local_or_default();
1177 let a = a.as_ref();
1178 let keep_dims = keep_dims.into().unwrap_or(false);
1179 let ddof = ddof.into().unwrap_or(0);
1180 Array::try_from_op(|res| unsafe {
1181 mlx_sys::mlx_std_axes(
1182 res,
1183 a.as_ptr(),
1184 axes.as_ptr(),
1185 axes.len(),
1186 keep_dims,
1187 ddof,
1188 stream.as_ref().as_ptr(),
1189 )
1190 })
1191}
1192
1193#[generate_macro(customize(forwarding_shim = true))]
1195#[deprecated(
1196 since = "0.26.0",
1197 note = "use `with_stream` or `with_device` around `std_axes`"
1198)]
1199pub fn std_axes_device(
1200 a: impl AsRef<Array>,
1201 axes: &[i32],
1202 #[optional] keep_dims: impl Into<Option<bool>>,
1203 #[optional] ddof: impl Into<Option<i32>>,
1204 #[optional] stream: impl AsRef<Stream>,
1205) -> Result<Array> {
1206 crate::with_stream(stream.as_ref(), || std_axes(a, axes, keep_dims, ddof))
1207}
1208
1209pub fn std_axis(
1211 a: impl AsRef<Array>,
1212 axis: i32,
1213 keep_dims: impl Into<Option<bool>>,
1214 ddof: impl Into<Option<i32>>,
1215) -> Result<Array> {
1216 let stream = Stream::thread_local_or_default();
1217 let a = a.as_ref();
1218 let keep_dims = keep_dims.into().unwrap_or(false);
1219 let ddof = ddof.into().unwrap_or(0);
1220 Array::try_from_op(|res| unsafe {
1221 mlx_sys::mlx_std_axis(
1222 res,
1223 a.as_ptr(),
1224 axis,
1225 keep_dims,
1226 ddof,
1227 stream.as_ref().as_ptr(),
1228 )
1229 })
1230}
1231
1232#[generate_macro(customize(forwarding_shim = true))]
1234#[deprecated(
1235 since = "0.26.0",
1236 note = "use `with_stream` or `with_device` around `std_axis`"
1237)]
1238pub fn std_axis_device(
1239 a: impl AsRef<Array>,
1240 axis: i32,
1241 #[optional] keep_dims: impl Into<Option<bool>>,
1242 #[optional] ddof: impl Into<Option<i32>>,
1243 #[optional] stream: impl AsRef<Stream>,
1244) -> Result<Array> {
1245 crate::with_stream(stream.as_ref(), || std_axis(a, axis, keep_dims, ddof))
1246}
1247
1248pub fn std(
1250 a: impl AsRef<Array>,
1251 keep_dims: impl Into<Option<bool>>,
1252 ddof: impl Into<Option<i32>>,
1253) -> Result<Array> {
1254 let stream = Stream::thread_local_or_default();
1255 let a = a.as_ref();
1256 let keep_dims = keep_dims.into().unwrap_or(false);
1257 let ddof = ddof.into().unwrap_or(0);
1258 Array::try_from_op(|res| unsafe {
1259 mlx_sys::mlx_std(res, a.as_ptr(), keep_dims, ddof, stream.as_ref().as_ptr())
1260 })
1261}
1262
1263#[generate_macro(customize(forwarding_shim = true))]
1265#[deprecated(
1266 since = "0.26.0",
1267 note = "use `with_stream` or `with_device` around `std`"
1268)]
1269pub fn std_device(
1270 a: impl AsRef<Array>,
1271 #[optional] keep_dims: impl Into<Option<bool>>,
1272 #[optional] ddof: impl Into<Option<i32>>,
1273 #[optional] stream: impl AsRef<Stream>,
1274) -> Result<Array> {
1275 crate::with_stream(stream.as_ref(), || std(a, keep_dims, ddof))
1276}
1277
1278pub fn sum_axes(
1280 array: impl AsRef<Array>,
1281 axes: &[i32],
1282 keep_dims: impl Into<Option<bool>>,
1283) -> Result<Array> {
1284 array.as_ref().sum_axes(axes, keep_dims)
1285}
1286
1287#[generate_macro(customize(forwarding_shim = true))]
1289#[deprecated(
1290 since = "0.26.0",
1291 note = "use `with_stream` or `with_device` around `sum_axes`"
1292)]
1293pub fn sum_axes_device(
1294 array: impl AsRef<Array>,
1295 axes: &[i32],
1296 #[optional] keep_dims: impl Into<Option<bool>>,
1297 #[optional] stream: impl AsRef<Stream>,
1298) -> Result<Array> {
1299 crate::with_stream(stream.as_ref(), || sum_axes(array, axes, keep_dims))
1300}
1301
1302pub fn sum_axis(
1304 array: impl AsRef<Array>,
1305 axis: i32,
1306 keep_dims: impl Into<Option<bool>>,
1307) -> Result<Array> {
1308 array.as_ref().sum_axis(axis, keep_dims)
1309}
1310
1311#[generate_macro(customize(forwarding_shim = true))]
1313#[deprecated(
1314 since = "0.26.0",
1315 note = "use `with_stream` or `with_device` around `sum_axis`"
1316)]
1317pub fn sum_axis_device(
1318 array: impl AsRef<Array>,
1319 axis: i32,
1320 #[optional] keep_dims: impl Into<Option<bool>>,
1321 #[optional] stream: impl AsRef<Stream>,
1322) -> Result<Array> {
1323 crate::with_stream(stream.as_ref(), || sum_axis(array, axis, keep_dims))
1324}
1325
1326pub fn sum(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1328 array.as_ref().sum(keep_dims)
1329}
1330
1331#[generate_macro(customize(forwarding_shim = true))]
1333#[deprecated(
1334 since = "0.26.0",
1335 note = "use `with_stream` or `with_device` around `sum`"
1336)]
1337pub fn sum_device(
1338 array: impl AsRef<Array>,
1339 #[optional] keep_dims: impl Into<Option<bool>>,
1340 #[optional] stream: impl AsRef<Stream>,
1341) -> Result<Array> {
1342 crate::with_stream(stream.as_ref(), || sum(array, keep_dims))
1343}
1344
1345pub fn mean_axes(
1347 array: impl AsRef<Array>,
1348 axes: &[i32],
1349 keep_dims: impl Into<Option<bool>>,
1350) -> Result<Array> {
1351 array.as_ref().mean_axes(axes, keep_dims)
1352}
1353
1354#[generate_macro(customize(forwarding_shim = true))]
1356#[deprecated(
1357 since = "0.26.0",
1358 note = "use `with_stream` or `with_device` around `mean_axes`"
1359)]
1360pub fn mean_axes_device(
1361 array: impl AsRef<Array>,
1362 axes: &[i32],
1363 #[optional] keep_dims: impl Into<Option<bool>>,
1364 #[optional] stream: impl AsRef<Stream>,
1365) -> Result<Array> {
1366 crate::with_stream(stream.as_ref(), || mean_axes(array, axes, keep_dims))
1367}
1368
1369pub fn mean_axis(
1371 array: impl AsRef<Array>,
1372 axis: i32,
1373 keep_dims: impl Into<Option<bool>>,
1374) -> Result<Array> {
1375 array.as_ref().mean_axis(axis, keep_dims)
1376}
1377
1378#[generate_macro(customize(forwarding_shim = true))]
1380#[deprecated(
1381 since = "0.26.0",
1382 note = "use `with_stream` or `with_device` around `mean_axis`"
1383)]
1384pub fn mean_axis_device(
1385 array: impl AsRef<Array>,
1386 axis: i32,
1387 #[optional] keep_dims: impl Into<Option<bool>>,
1388 #[optional] stream: impl AsRef<Stream>,
1389) -> Result<Array> {
1390 crate::with_stream(stream.as_ref(), || mean_axis(array, axis, keep_dims))
1391}
1392
1393pub fn mean(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1395 array.as_ref().mean(keep_dims)
1396}
1397
1398#[generate_macro(customize(forwarding_shim = true))]
1400#[deprecated(
1401 since = "0.26.0",
1402 note = "use `with_stream` or `with_device` around `mean`"
1403)]
1404pub fn mean_device(
1405 array: impl AsRef<Array>,
1406 #[optional] keep_dims: impl Into<Option<bool>>,
1407 #[optional] stream: impl AsRef<Stream>,
1408) -> Result<Array> {
1409 crate::with_stream(stream.as_ref(), || mean(array, keep_dims))
1410}
1411
1412pub fn min_axes(
1414 array: impl AsRef<Array>,
1415 axes: &[i32],
1416 keep_dims: impl Into<Option<bool>>,
1417) -> Result<Array> {
1418 array.as_ref().min_axes(axes, keep_dims)
1419}
1420
1421#[generate_macro(customize(forwarding_shim = true))]
1423#[deprecated(
1424 since = "0.26.0",
1425 note = "use `with_stream` or `with_device` around `min_axes`"
1426)]
1427pub fn min_axes_device(
1428 array: impl AsRef<Array>,
1429 axes: &[i32],
1430 #[optional] keep_dims: impl Into<Option<bool>>,
1431 #[optional] stream: impl AsRef<Stream>,
1432) -> Result<Array> {
1433 crate::with_stream(stream.as_ref(), || min_axes(array, axes, keep_dims))
1434}
1435
1436pub fn min_axis(
1438 array: impl AsRef<Array>,
1439 axis: i32,
1440 keep_dims: impl Into<Option<bool>>,
1441) -> Result<Array> {
1442 array.as_ref().min_axis(axis, keep_dims)
1443}
1444
1445#[generate_macro(customize(forwarding_shim = true))]
1447#[deprecated(
1448 since = "0.26.0",
1449 note = "use `with_stream` or `with_device` around `min_axis`"
1450)]
1451pub fn min_axis_device(
1452 array: impl AsRef<Array>,
1453 axis: i32,
1454 #[optional] keep_dims: impl Into<Option<bool>>,
1455 #[optional] stream: impl AsRef<Stream>,
1456) -> Result<Array> {
1457 crate::with_stream(stream.as_ref(), || min_axis(array, axis, keep_dims))
1458}
1459
1460pub fn min(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1462 array.as_ref().min(keep_dims)
1463}
1464
1465#[generate_macro(customize(forwarding_shim = true))]
1467#[deprecated(
1468 since = "0.26.0",
1469 note = "use `with_stream` or `with_device` around `min`"
1470)]
1471pub fn min_device(
1472 array: impl AsRef<Array>,
1473 #[optional] keep_dims: impl Into<Option<bool>>,
1474 #[optional] stream: impl AsRef<Stream>,
1475) -> Result<Array> {
1476 crate::with_stream(stream.as_ref(), || min(array, keep_dims))
1477}
1478
1479pub fn var_axes(
1481 array: impl AsRef<Array>,
1482 axes: &[i32],
1483 keep_dims: impl Into<Option<bool>>,
1484 ddof: impl Into<Option<i32>>,
1485) -> Result<Array> {
1486 array.as_ref().var_axes(axes, keep_dims, ddof)
1487}
1488
1489#[generate_macro(customize(forwarding_shim = true))]
1491#[deprecated(
1492 since = "0.26.0",
1493 note = "use `with_stream` or `with_device` around `var_axes`"
1494)]
1495pub fn var_axes_device(
1496 array: impl AsRef<Array>,
1497 axes: &[i32],
1498 #[optional] keep_dims: impl Into<Option<bool>>,
1499 #[optional] ddof: impl Into<Option<i32>>,
1500 #[optional] stream: impl AsRef<Stream>,
1501) -> Result<Array> {
1502 crate::with_stream(stream.as_ref(), || var_axes(array, axes, keep_dims, ddof))
1503}
1504
1505pub fn var_axis(
1507 array: impl AsRef<Array>,
1508 axis: i32,
1509 keep_dims: impl Into<Option<bool>>,
1510 ddof: impl Into<Option<i32>>,
1511) -> Result<Array> {
1512 array.as_ref().var_axis(axis, keep_dims, ddof)
1513}
1514
1515#[generate_macro(customize(forwarding_shim = true))]
1517#[deprecated(
1518 since = "0.26.0",
1519 note = "use `with_stream` or `with_device` around `var_axis`"
1520)]
1521pub fn var_axis_device(
1522 array: impl AsRef<Array>,
1523 axis: i32,
1524 #[optional] keep_dims: impl Into<Option<bool>>,
1525 #[optional] ddof: impl Into<Option<i32>>,
1526 #[optional] stream: impl AsRef<Stream>,
1527) -> Result<Array> {
1528 crate::with_stream(stream.as_ref(), || var_axis(array, axis, keep_dims, ddof))
1529}
1530
1531pub fn var(
1533 array: impl AsRef<Array>,
1534 keep_dims: impl Into<Option<bool>>,
1535 ddof: impl Into<Option<i32>>,
1536) -> Result<Array> {
1537 array.as_ref().var(keep_dims, ddof)
1538}
1539
1540#[generate_macro(customize(forwarding_shim = true))]
1542#[deprecated(
1543 since = "0.26.0",
1544 note = "use `with_stream` or `with_device` around `var`"
1545)]
1546pub fn var_device(
1547 array: impl AsRef<Array>,
1548 #[optional] keep_dims: impl Into<Option<bool>>,
1549 #[optional] ddof: impl Into<Option<i32>>,
1550 #[optional] stream: impl AsRef<Stream>,
1551) -> Result<Array> {
1552 crate::with_stream(stream.as_ref(), || var(array, keep_dims, ddof))
1553}
1554
1555pub fn median_axes(
1557 array: impl AsRef<Array>,
1558 axes: &[i32],
1559 keep_dims: impl Into<Option<bool>>,
1560) -> Result<Array> {
1561 array.as_ref().median_axes(axes, keep_dims)
1562}
1563
1564#[generate_macro(customize(forwarding_shim = true))]
1566#[deprecated(
1567 since = "0.26.0",
1568 note = "use `with_stream` or `with_device` around `median_axes`"
1569)]
1570pub fn median_axes_device(
1571 array: impl AsRef<Array>,
1572 axes: &[i32],
1573 #[optional] keep_dims: impl Into<Option<bool>>,
1574 #[optional] stream: impl AsRef<Stream>,
1575) -> Result<Array> {
1576 crate::with_stream(stream.as_ref(), || median_axes(array, axes, keep_dims))
1577}
1578
1579pub fn median_axis(
1581 array: impl AsRef<Array>,
1582 axis: i32,
1583 keep_dims: impl Into<Option<bool>>,
1584) -> Result<Array> {
1585 array.as_ref().median_axis(axis, keep_dims)
1586}
1587
1588#[generate_macro(customize(forwarding_shim = true))]
1590#[deprecated(
1591 since = "0.26.0",
1592 note = "use `with_stream` or `with_device` around `median_axis`"
1593)]
1594pub fn median_axis_device(
1595 array: impl AsRef<Array>,
1596 axis: i32,
1597 #[optional] keep_dims: impl Into<Option<bool>>,
1598 #[optional] stream: impl AsRef<Stream>,
1599) -> Result<Array> {
1600 crate::with_stream(stream.as_ref(), || median_axis(array, axis, keep_dims))
1601}
1602
1603pub fn median(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1605 array.as_ref().median(keep_dims)
1606}
1607
1608#[generate_macro(customize(forwarding_shim = true))]
1610#[deprecated(
1611 since = "0.26.0",
1612 note = "use `with_stream` or `with_device` around `median`"
1613)]
1614pub fn median_device(
1615 array: impl AsRef<Array>,
1616 #[optional] keep_dims: impl Into<Option<bool>>,
1617 #[optional] stream: impl AsRef<Stream>,
1618) -> Result<Array> {
1619 crate::with_stream(stream.as_ref(), || median(array, keep_dims))
1620}
1621
1622pub fn logsumexp_axes(
1624 array: impl AsRef<Array>,
1625 axes: &[i32],
1626 keep_dims: impl Into<Option<bool>>,
1627) -> Result<Array> {
1628 array.as_ref().logsumexp_axes(axes, keep_dims)
1629}
1630
1631#[generate_macro(customize(forwarding_shim = true))]
1633#[deprecated(
1634 since = "0.26.0",
1635 note = "use `with_stream` or `with_device` around `logsumexp_axes`"
1636)]
1637pub fn logsumexp_axes_device(
1638 array: impl AsRef<Array>,
1639 axes: &[i32],
1640 #[optional] keep_dims: impl Into<Option<bool>>,
1641 #[optional] stream: impl AsRef<Stream>,
1642) -> Result<Array> {
1643 crate::with_stream(stream.as_ref(), || logsumexp_axes(array, axes, keep_dims))
1644}
1645
1646pub fn logsumexp_axis(
1648 array: impl AsRef<Array>,
1649 axis: i32,
1650 keep_dims: impl Into<Option<bool>>,
1651) -> Result<Array> {
1652 array.as_ref().logsumexp_axis(axis, keep_dims)
1653}
1654
1655#[generate_macro(customize(forwarding_shim = true))]
1657#[deprecated(
1658 since = "0.26.0",
1659 note = "use `with_stream` or `with_device` around `logsumexp_axis`"
1660)]
1661pub fn logsumexp_axis_device(
1662 array: impl AsRef<Array>,
1663 axis: i32,
1664 #[optional] keep_dims: impl Into<Option<bool>>,
1665 #[optional] stream: impl AsRef<Stream>,
1666) -> Result<Array> {
1667 crate::with_stream(stream.as_ref(), || logsumexp_axis(array, axis, keep_dims))
1668}
1669
1670pub fn logsumexp(array: impl AsRef<Array>, keep_dims: impl Into<Option<bool>>) -> Result<Array> {
1672 array.as_ref().logsumexp(keep_dims)
1673}
1674
1675#[generate_macro(customize(forwarding_shim = true))]
1677#[deprecated(
1678 since = "0.26.0",
1679 note = "use `with_stream` or `with_device` around `logsumexp`"
1680)]
1681pub fn logsumexp_device(
1682 array: impl AsRef<Array>,
1683 #[optional] keep_dims: impl Into<Option<bool>>,
1684 #[optional] stream: impl AsRef<Stream>,
1685) -> Result<Array> {
1686 crate::with_stream(stream.as_ref(), || logsumexp(array, keep_dims))
1687}
1688
1689#[cfg(test)]
1690mod tests {
1691 use super::*;
1692 use pretty_assertions::assert_eq;
1693
1694 #[test]
1695 fn test_all() {
1696 let array = Array::from_slice(&[true, false, true, false], &[2, 2]);
1697
1698 assert_eq!(array.all(None).unwrap().item_exact::<bool>(), false);
1699 assert_eq!(array.all(true).unwrap().shape(), &[1, 1]);
1700 assert_eq!(
1701 array.all_axes(&[0, 1], None).unwrap().item_exact::<bool>(),
1702 false
1703 );
1704
1705 let result = array.all_axis(0, None).unwrap();
1706 assert_eq!(result.as_slice::<bool>(), &[true, false]);
1707
1708 let result = array.all_axis(1, None).unwrap();
1709 assert_eq!(result.as_slice::<bool>(), &[false, false]);
1710 }
1711
1712 #[test]
1713 fn test_all_empty_axes() {
1714 let array = Array::from_slice(&[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], &[3, 4]);
1715 let all = array.all_axes(&[], None).unwrap();
1716
1717 let results: &[bool] = all.as_slice();
1718 assert_eq!(
1719 results,
1720 &[false, true, true, true, true, true, true, true, true, true, true, true]
1721 );
1722 }
1723
1724 #[test]
1725 fn test_prod() {
1726 let x = Array::from_slice(&[1, 2, 3, 3], &[2, 2]);
1727 assert_eq!(x.prod(None).unwrap().item_exact::<i32>(), 18);
1728
1729 let y = x.prod(true).unwrap();
1730 assert_eq!(y.item_exact::<i32>(), 18);
1731 assert_eq!(y.shape(), &[1, 1]);
1732
1733 let result = x.prod_axis(0, None).unwrap();
1734 assert_eq!(result.as_slice::<i32>(), &[3, 6]);
1735
1736 let result = x.prod_axis(1, None).unwrap();
1737 assert_eq!(result.as_slice::<i32>(), &[2, 9])
1738 }
1739
1740 #[test]
1741 fn test_prod_empty_axes() {
1742 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1743 let result = array.prod_axes(&[], None).unwrap();
1744
1745 let results: &[i32] = result.as_slice();
1746 assert_eq!(results, &[5, 8, 4, 9]);
1747 }
1748
1749 #[test]
1750 fn test_max() {
1751 let x = Array::from_slice(&[1, 2, 3, 4], &[2, 2]);
1752 assert_eq!(x.max(None).unwrap().item_exact::<i32>(), 4);
1753 let y = x.max(true).unwrap();
1754 assert_eq!(y.item_exact::<i32>(), 4);
1755 assert_eq!(y.shape(), &[1, 1]);
1756
1757 let result = x.max_axis(0, None).unwrap();
1758 assert_eq!(result.as_slice::<i32>(), &[3, 4]);
1759
1760 let result = x.max_axis(1, None).unwrap();
1761 assert_eq!(result.as_slice::<i32>(), &[2, 4]);
1762 }
1763
1764 #[test]
1765 fn test_max_empty_axes() {
1766 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1767 let result = array.max_axes(&[], None).unwrap();
1768
1769 let results: &[i32] = result.as_slice();
1770 assert_eq!(results, &[5, 8, 4, 9]);
1771 }
1772
1773 #[test]
1774 fn test_sum() {
1775 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1776 let result = array.sum_axis(0, None).unwrap();
1777
1778 let results: &[i32] = result.as_slice();
1779 assert_eq!(results, &[9, 17]);
1780 }
1781
1782 #[test]
1783 fn test_sum_empty_axes() {
1784 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1785 let result = array.sum_axes(&[], None).unwrap();
1786
1787 let results: &[i32] = result.as_slice();
1788 assert_eq!(results, &[5, 8, 4, 9]);
1789 }
1790
1791 #[test]
1792 fn test_mean() {
1793 let x = Array::from_slice(&[1, 2, 3, 4], &[2, 2]);
1794 assert_eq!(x.mean(None).unwrap().item_exact::<f32>(), 2.5);
1795 let y = x.mean(true).unwrap();
1796 assert_eq!(y.item_exact::<f32>(), 2.5);
1797 assert_eq!(y.shape(), &[1, 1]);
1798
1799 let result = x.mean_axis(0, None).unwrap();
1800 assert_eq!(result.as_slice::<f32>(), &[2.0, 3.0]);
1801
1802 let result = x.mean_axis(1, None).unwrap();
1803 assert_eq!(result.as_slice::<f32>(), &[1.5, 3.5]);
1804 }
1805
1806 #[test]
1807 fn test_mean_empty_axes() {
1808 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1809 let result = array.mean_axes(&[], None).unwrap();
1810
1811 let results: &[f32] = result.as_slice();
1812 assert_eq!(results, &[5.0, 8.0, 4.0, 9.0]);
1813 }
1814
1815 #[test]
1816 fn test_mean_out_of_bounds() {
1817 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1818 let result = array.mean_axis(2, None);
1819 assert!(result.is_err());
1820 }
1821
1822 #[test]
1823 fn test_min() {
1824 let x = Array::from_slice(&[1, 2, 3, 4], &[2, 2]);
1825 assert_eq!(x.min(None).unwrap().item_exact::<i32>(), 1);
1826 let y = x.min(true).unwrap();
1827 assert_eq!(y.item_exact::<i32>(), 1);
1828 assert_eq!(y.shape(), &[1, 1]);
1829
1830 let result = x.min_axis(0, None).unwrap();
1831 assert_eq!(result.as_slice::<i32>(), &[1, 2]);
1832
1833 let result = x.min_axis(1, None).unwrap();
1834 assert_eq!(result.as_slice::<i32>(), &[1, 3]);
1835 }
1836
1837 #[test]
1838 fn test_min_empty_axes() {
1839 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1840 let result = array.min_axes(&[], None).unwrap();
1841
1842 let results: &[i32] = result.as_slice();
1843 assert_eq!(results, &[5, 8, 4, 9]);
1844 }
1845
1846 #[test]
1847 fn test_var() {
1848 let x = Array::from_slice(&[1, 2, 3, 4], &[2, 2]);
1849 assert_eq!(x.var(None, None).unwrap().item_exact::<f32>(), 1.25);
1850 let y = x.var(true, None).unwrap();
1851 assert_eq!(y.item_exact::<f32>(), 1.25);
1852 assert_eq!(y.shape(), &[1, 1]);
1853
1854 let result = x.var_axis(0, None, None).unwrap();
1855 assert_eq!(result.as_slice::<f32>(), &[1.0, 1.0]);
1856
1857 let result = x.var_axis(1, None, None).unwrap();
1858 assert_eq!(result.as_slice::<f32>(), &[0.25, 0.25]);
1859
1860 let x = Array::from_slice(&[1.0, 2.0], &[2]);
1861 let out = x.var(None, Some(3)).unwrap();
1862 assert_eq!(out.item_exact::<f32>(), f32::INFINITY);
1863 }
1864
1865 #[test]
1866 fn test_var_empty_axes() {
1867 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1868 let result = array.var_axes(&[], None, 0).unwrap();
1869
1870 let results: &[f32] = result.as_slice();
1871 assert_eq!(results, &[0.0, 0.0, 0.0, 0.0]);
1872 }
1873
1874 #[test]
1875 fn test_log_sum_exp() {
1876 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1877 let result = array.logsumexp_axis(0, None).unwrap();
1878
1879 let results: &[f32] = result.as_slice();
1880 assert_eq!(results, &[5.3132615, 9.313262]);
1881 }
1882
1883 #[test]
1884 fn test_log_sum_exp_empty_axes() {
1885 let array = Array::from_slice(&[5, 8, 4, 9], &[2, 2]);
1886 let result = array.logsumexp_axes(&[], None).unwrap();
1887
1888 let results: &[f32] = result.as_slice();
1889 assert_eq!(results, &[5.0, 8.0, 4.0, 9.0]);
1890 }
1891
1892 #[test]
1894 fn test_median() {
1895 let x = Array::from_slice(&[0, 1, 2, 3, 4], &[5]);
1897 let out = x.median(None).unwrap();
1898 assert_eq!(out.shape(), &[] as &[i32]);
1899 assert_eq!(out.item_exact::<f32>(), 2.0);
1900
1901 let out = x.median(true).unwrap();
1903 assert_eq!(out.shape(), &[1]);
1904
1905 let x = Array::from_slice(&[0, 1, 2, 3, 4, 5], &[6]);
1907 let out = x.median(None).unwrap();
1908 assert!((out.item_exact::<f32>() - 2.5).abs() < 1e-5);
1909
1910 use crate::random;
1912 random::seed(0).unwrap();
1913 let x = random::normal::<f32>(&[5, 5, 5, 5], None, None, None).unwrap();
1914
1915 let out = x.median_axes(&[0, 2], true).unwrap();
1916 assert_eq!(out.shape(), &[1, 5, 1, 5]);
1917
1918 let out = x.median_axes(&[1, 3], true).unwrap();
1919 assert_eq!(out.shape(), &[5, 1, 5, 1]);
1920
1921 let x = Array::from_slice(&[1, 5, 2, 4, 3, 6], &[2, 3]);
1923 let out = x.median_axis(0, None).unwrap();
1924 assert_eq!(out.shape(), &[3]);
1925
1926 let out = x.median_axis(1, None).unwrap();
1927 assert_eq!(out.shape(), &[2]);
1928 }
1929}