1use core::ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign};
2
3use crate::{AdditionalOps, AssignOps, BaseOps};
4
5#[cfg(feature = "opencl")]
6use custos::{
7 opencl::api::{enqueue_write_buffer, wait_for_event},
8 OpenCL,
9};
10use custos::{
11 Alloc, Buffer, CloneBuf, Device, IsShapeIndep, MainMemory, Read, ShallowCopy, Shape, ToDim, CPU,
12};
13
14#[cfg(feature = "cuda")]
15use custos::{cuda::api::cu_write, CUDA};
16
17mod impl_with_shape;
18
19#[cfg_attr(feature = "cpu", doc = "```")]
23#[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
24pub struct Matrix<'a, T = f32, D: Device = CPU, S: Shape = ()> {
36 pub data: Buffer<'a, T, D, S>,
37 pub dims: (usize, usize),
38}
39
40impl<'a, T, D: Device, S: Shape> Matrix<'a, T, D, S> {
41 #[cfg_attr(feature = "cpu", doc = "```")]
44 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
45 #[inline]
55 pub fn new(device: &'a D, dims: (usize, usize)) -> Matrix<'a, T, D, S>
56 where
57 D: Alloc<'a, T, S>,
58 {
59 Matrix {
60 data: Buffer::new(device, dims.0 * dims.1),
61 dims,
62 }
63 }
64
65 #[inline]
66 pub fn device(&self) -> &'a D {
67 self.data.device()
68 }
69
70 #[cfg_attr(feature = "cpu", doc = "```")]
81 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
82 #[inline]
91 pub fn as_buf(&self) -> &Buffer<'a, T, D, S> {
92 &self.data
93 }
94
95 #[inline]
96 pub fn to_buf(self) -> Buffer<'a, T, D, S> {
97 self.data
98 }
99
100 #[inline]
102 pub fn as_buf_mut(&mut self) -> &mut Buffer<'a, T, D, S> {
103 &mut self.data
104 }
105
106 #[inline]
107 pub fn dims(&self) -> (usize, usize) {
108 self.dims
109 }
110
111 #[inline]
112 pub fn reshape(&mut self, dims: (usize, usize)) {
113 self.dims = dims;
114 }
115
116 #[cfg_attr(feature = "cpu", doc = "```")]
120 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
121 #[inline]
129 pub fn rows(&self) -> usize {
130 self.dims.0
131 }
132
133 #[cfg_attr(feature = "cpu", doc = "```")]
137 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
138 #[inline]
146 pub fn cols(&self) -> usize {
147 self.dims.1
148 }
149
150 #[cfg_attr(feature = "cpu", doc = "```")]
154 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
155 #[inline]
163 pub fn size(&self) -> usize {
164 self.dims.0 * self.dims.1
165 }
166
167 #[inline]
168 pub fn as_slice(&self) -> &[T]
169 where
170 D: MainMemory,
171 {
172 self.data.as_slice()
173 }
174
175 #[inline]
176 pub fn as_mut_slice(&mut self) -> &mut [T]
177 where
178 D: MainMemory,
179 {
180 self.as_buf_mut().as_mut_slice()
181 }
182
183 #[cfg_attr(feature = "cpu", doc = "```")]
207 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
208 pub fn read(&'a self) -> D::Read<'a>
217 where
218 T: Default + Copy,
219 D: Read<T, D, S>,
220 {
221 self.device().read(self.as_buf())
222 }
223
224 #[cfg_attr(feature = "cpu", doc = "```")]
228 #[cfg_attr(not(feature = "cpu"), doc = "```ignore")]
229 #[cfg(not(feature = "no-std"))]
238 pub fn read_to_vec(&self) -> Vec<T>
239 where
240 T: Default + Copy,
241 D: Read<T, D, S>,
242 {
243 self.device().read_to_vec(self.as_buf())
244 }
245
246 pub fn shallow(&self) -> Matrix<'a, T, D, S>
248 where
249 D::Ptr<T, S>: ShallowCopy,
250 {
251 unsafe {
252 Self {
253 data: self.data.shallow(),
254 dims: self.dims,
255 }
256 }
257 }
258
259 pub fn shallow_or_clone(&self) -> Matrix<'a, T, D, S>
261 where
262 T: Clone,
263 D::Ptr<T, S>: ShallowCopy,
264 D: CloneBuf<'a, T, S>,
265 {
266 unsafe {
267 Self {
268 data: self.data.shallow_or_clone(),
269 dims: self.dims,
270 }
271 }
272 }
273}
274
275impl<T, D: Device> Default for Matrix<'_, T, D>
276where
277 D::Ptr<T, ()>: Default,
278{
279 fn default() -> Self {
280 Self {
281 data: Default::default(),
282 dims: Default::default(),
283 }
284 }
285}
286
287impl<'a, T, D: Device, S: Shape> Matrix<'a, T, D, S> {
288 #[inline]
290 pub fn to_dims<O: Shape>(self) -> Matrix<'a, T, D, O>
291 where
292 D: ToDim<T, S, O>,
293 {
294 let data = self.data.to_dims();
295
296 Matrix {
297 data,
298 dims: self.dims,
299 }
300 }
301}
302
303impl<T, D: IsShapeIndep, S: Shape> Matrix<'_, T, D, S> {
304 #[inline]
305 pub fn as_dims<'b, O: Shape>(&self) -> &Matrix<'b, T, D, O> {
306 unsafe { &*(self as *const Self).cast() }
307 }
308
309 #[inline]
310 pub fn as_dims_mut<'b, O: Shape>(&mut self) -> &mut Matrix<'b, T, D, O> {
311 unsafe { &mut *(self as *mut Self).cast() }
312 }
313}
314
315impl<'a, T, D: Device, S: Shape> core::ops::Deref for Matrix<'a, T, D, S> {
316 type Target = Buffer<'a, T, D, S>;
317
318 #[inline]
319 fn deref(&self) -> &Self::Target {
320 self.as_buf()
321 }
322}
323
324impl<'a, T, D: Device, S: Shape> core::ops::DerefMut for Matrix<'a, T, D, S> {
325 #[inline]
326 fn deref_mut(&mut self) -> &mut Self::Target {
327 self.as_buf_mut()
328 }
329}
330
331impl<'a, T, S, D> Clone for Matrix<'a, T, D, S>
332where
333 T: Clone,
334 S: Shape,
335 D: CloneBuf<'a, T, S>,
336{
337 fn clone(&self) -> Self {
338 Self {
339 data: self.data.clone(),
340 dims: self.dims.clone(),
341 }
342 }
343}
344
345impl<'a, T, D: Device, S: Shape> From<(Buffer<'a, T, D, S>, (usize, usize))>
348 for Matrix<'a, T, D, S>
349{
350 #[inline]
351 fn from((data, dims): (Buffer<'a, T, D, S>, (usize, usize))) -> Self {
352 Matrix { data, dims }
353 }
354}
355
356impl<'a, T, D: Device, S: Shape> From<(Buffer<'a, T, D, S>, usize, usize)> for Matrix<'a, T, D, S> {
358 #[inline]
359 fn from((data, rows, cols): (Buffer<'a, T, D, S>, usize, usize)) -> Self {
360 Matrix {
361 data,
362 dims: (rows, cols),
363 }
364 }
365}
366
367#[cfg(feature = "cpu")]
369impl<'a, T> From<(*mut T, (usize, usize))> for Matrix<'a, T> {
370 #[inline]
371 fn from((ptr, dims): (*mut T, (usize, usize))) -> Self {
372 unsafe {
373 Matrix {
374 data: Buffer::from_raw_host(ptr, dims.0 * dims.1),
375 dims,
376 }
377 }
378 }
379}
380
381#[cfg(feature = "cpu")]
383impl<'a, T> From<(&'a CPU, *mut T, (usize, usize))> for Matrix<'a, T> {
384 #[inline]
385 fn from((cpu, ptr, dims): (&'a CPU, *mut T, (usize, usize))) -> Self {
386 unsafe {
387 Matrix {
388 data: Buffer::from_raw_host_device(cpu, ptr, dims.0 * dims.1),
389 dims,
390 }
391 }
392 }
393}
394
395#[cfg(feature = "opencl")]
451impl<'a, 'b, T> From<(&'a OpenCL, Matrix<'b, T>)> for Matrix<'a, T, OpenCL> {
452 fn from((device, matrix): (&'a OpenCL, Matrix<'b, T>)) -> Self {
453 let out = device.retrieve(matrix.size(), ());
455
456 let event =
457 unsafe { enqueue_write_buffer(&device.queue(), out.ptr.ptr, &matrix, true).unwrap() };
458 wait_for_event(event).unwrap();
459 Matrix::from((out, matrix.dims()))
460 }
461}
462
463#[cfg(feature = "static-api")]
464impl<'a, T: Clone> From<(usize, usize, &[T])> for Matrix<'a, T> {
465 #[inline]
466 fn from((rows, cols, slice): (usize, usize, &[T])) -> Self {
467 Matrix::from((Buffer::from(slice), rows, cols))
468 }
469}
470
471#[cfg(feature = "static-api")]
472impl<'a, T: Clone, const N: usize> From<(usize, usize, [T; N])> for Matrix<'a, T> {
473 #[inline]
474 fn from((rows, cols, slice): (usize, usize, [T; N])) -> Self {
475 Matrix::from((Buffer::from(slice), rows, cols))
476 }
477}
478
479#[cfg(feature = "cuda")]
480impl<'a, 'b, T> From<(&'a CUDA, Matrix<'b, T>)> for Matrix<'a, T, CUDA> {
481 fn from(device_matrix: (&'a CUDA, Matrix<'b, T>)) -> Self {
482 let dst = device_matrix.0.retrieve(device_matrix.1.size(), ());
483 cu_write(dst.ptr.ptr, &device_matrix.1).unwrap();
484 Matrix::from((dst, device_matrix.1.dims()))
485 }
486}
487
488impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep, const N: usize>
489 From<(&'a D, (usize, usize), [T; N])> for Matrix<'a, T, D>
490{
491 fn from((device, dims, slice): (&'a D, (usize, usize), [T; N])) -> Self {
492 let data = Buffer::from((device, slice));
493 Matrix { data, dims }
494 }
495}
496
497impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep, const N: usize>
499 From<(&'a D, usize, usize, [T; N])> for Matrix<'a, T, D>
500{
501 fn from(dims_slice: (&'a D, usize, usize, [T; N])) -> Self {
502 let data = Buffer::from((dims_slice.0, dims_slice.3));
503 Matrix {
504 data,
505 dims: (dims_slice.1, dims_slice.2),
506 }
507 }
508}
509
510impl<'a, T: Copy, D: Alloc<'a, T>> From<(&'a D, usize, usize)> for Matrix<'a, T, D> {
511 fn from((device, rows, cols): (&'a D, usize, usize)) -> Self {
512 let data = Buffer::new(device, rows * cols);
513 Matrix {
514 data,
515 dims: (rows, cols),
516 }
517 }
518}
519
520impl<'a, T: Copy, D: Alloc<'a, T>> From<(&'a D, (usize, usize))> for Matrix<'a, T, D> {
521 fn from((device, dims): (&'a D, (usize, usize))) -> Self {
522 let data = Buffer::new(device, dims.0 * dims.1);
523 Matrix { data, dims }
524 }
525}
526
527#[cfg(not(feature = "no-std"))]
529impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep> From<(&'a D, (usize, usize), Vec<T>)>
530 for Matrix<'a, T, D>
531{
532 fn from(dims_slice: (&'a D, (usize, usize), Vec<T>)) -> Self {
533 let data = Buffer::from((dims_slice.0, dims_slice.2));
534 Matrix {
535 data,
536 dims: dims_slice.1,
537 }
538 }
539}
540
541#[cfg(not(feature = "no-std"))]
543impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep> From<(&'a D, usize, usize, Vec<T>)>
545 for Matrix<'a, T, D>
546{
547 fn from(dims_slice: (&'a D, usize, usize, Vec<T>)) -> Self {
548 let data = Buffer::from((dims_slice.0, dims_slice.3));
549 Matrix {
550 data,
551 dims: (dims_slice.1, dims_slice.2),
552 }
553 }
554}
555
556impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep> From<(&'a D, (usize, usize), &[T])>
558 for Matrix<'a, T, D>
559{
560 fn from(dims_slice: (&'a D, (usize, usize), &[T])) -> Self {
561 let data = Buffer::from((dims_slice.0, dims_slice.2));
562 Matrix {
563 data,
564 dims: dims_slice.1,
565 }
566 }
567}
568
569impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep> From<(&'a D, usize, usize, &[T])>
572 for Matrix<'a, T, D>
573{
574 fn from(dims_slice: (&'a D, usize, usize, &[T])) -> Self {
575 let data = Buffer::from((dims_slice.0, dims_slice.3));
576 Matrix {
577 data,
578 dims: (dims_slice.1, dims_slice.2),
579 }
580 }
581}
582
583#[cfg(not(feature = "no-std"))]
584impl<'a, T: Copy, D: Alloc<'a, T> + IsShapeIndep> From<(&'a D, (usize, usize), &Vec<T>)>
585 for Matrix<'a, T, D>
586{
587 fn from(dims_slice: (&'a D, (usize, usize), &Vec<T>)) -> Self {
588 let data = Buffer::from((dims_slice.0, dims_slice.2));
589 Matrix {
590 data,
591 dims: dims_slice.1,
592 }
593 }
594}
595
596impl<'a, T, D, S: Shape> Add<Self> for &Matrix<'a, T, D, S>
599where
600 D: BaseOps<T, S>,
601{
602 type Output = Matrix<'a, T, D, S>;
603
604 fn add(self, rhs: Self) -> Self::Output {
605 self.device().add(self, rhs)
606 }
607}
608
609impl<'a, T, D, S: Shape> Add<Self> for Matrix<'a, T, D, S>
610where
611 D: BaseOps<T, S>,
612{
613 type Output = Matrix<'a, T, D, S>;
614
615 fn add(self, rhs: Self) -> Self::Output {
616 self.device().add(&self, &rhs)
617 }
618}
619
620impl<'a, T, D, S: Shape> Add<&Self> for Matrix<'a, T, D, S>
621where
622 D: BaseOps<T, S>,
623{
624 type Output = Matrix<'a, T, D, S>;
625
626 fn add(self, rhs: &Self) -> Self::Output {
627 self.device().add(&self, rhs)
628 }
629}
630
631impl<'a, T, D, S: Shape> Add<Matrix<'a, T, D, S>> for &Matrix<'a, T, D, S>
632where
633 D: BaseOps<T, S>,
634{
635 type Output = Matrix<'a, T, D, S>;
636
637 fn add(self, rhs: Matrix<T, D, S>) -> Self::Output {
638 self.device().add(self, &rhs)
639 }
640}
641
642impl<'a, T, D, S: Shape> Add<T> for &Matrix<'a, T, D, S>
643where
644 D: AdditionalOps<T, S>,
645{
646 type Output = Matrix<'a, T, D, S>;
647
648 fn add(self, rhs: T) -> Self::Output {
649 self.adds(rhs)
650 }
651}
652
653impl<'a, T, D> Add<T> for Matrix<'a, T, D>
654where
655 D: AdditionalOps<T>,
656{
657 type Output = Matrix<'a, T, D>;
658
659 fn add(self, rhs: T) -> Self::Output {
660 self.adds(rhs)
661 }
662}
663
664impl<'a, T, D, S> Sub<Self> for &Matrix<'a, T, D, S>
667where
668 D: BaseOps<T, S>,
669 S: Shape,
670{
671 type Output = Matrix<'a, T, D, S>;
672
673 fn sub(self, rhs: Self) -> Self::Output {
674 self.device().sub(self, rhs)
675 }
676}
677
678impl<'a, T, D, S> Sub<Self> for Matrix<'a, T, D, S>
679where
680 D: BaseOps<T, S>,
681 S: Shape,
682{
683 type Output = Matrix<'a, T, D, S>;
684
685 fn sub(self, rhs: Self) -> Self::Output {
686 self.device().sub(&self, &rhs)
687 }
688}
689
690impl<'a, T, D, S> Sub<&Self> for Matrix<'a, T, D, S>
691where
692 D: BaseOps<T, S>,
693 S: Shape,
694{
695 type Output = Matrix<'a, T, D, S>;
696
697 fn sub(self, rhs: &Self) -> Self::Output {
698 self.device().sub(&self, rhs)
699 }
700}
701
702impl<'a, T, D, S> Sub<Matrix<'a, T, D, S>> for &Matrix<'a, T, D, S>
703where
704 D: BaseOps<T, S>,
705 S: Shape,
706{
707 type Output = Matrix<'a, T, D, S>;
708
709 fn sub(self, rhs: Matrix<T, D, S>) -> Self::Output {
710 self.device().sub(self, &rhs)
711 }
712}
713
714impl<'a, T, D, S> Sub<T> for &Matrix<'a, T, D, S>
715where
716 S: Shape,
717 D: AdditionalOps<T, S>,
718{
719 type Output = Matrix<'a, T, D, S>;
720
721 fn sub(self, rhs: T) -> Self::Output {
722 self.subs(rhs);
723 todo!()
724 }
726}
727
728impl<'a, T> Sub<T> for Matrix<'a, T> {
729 type Output = Matrix<'a, T>;
730
731 fn sub(self, _rhs: T) -> Self::Output {
732 todo!()
733 }
735}
736
737impl<'a, T, D, S: Shape> Mul<Self> for &Matrix<'a, T, D, S>
740where
741 D: BaseOps<T, S>,
742{
743 type Output = Matrix<'a, T, D, S>;
744
745 fn mul(self, rhs: Self) -> Self::Output {
746 self.device().mul(self, rhs)
747 }
748}
749
750impl<'a, T, D, S: Shape> Mul<Self> for Matrix<'a, T, D, S>
751where
752 D: BaseOps<T, S>,
753{
754 type Output = Matrix<'a, T, D, S>;
755
756 fn mul(self, rhs: Self) -> Self::Output {
757 self.device().mul(&self, &rhs)
758 }
759}
760
761impl<'a, T, D, S: Shape> Mul<&Self> for Matrix<'a, T, D, S>
762where
763 D: BaseOps<T, S>,
764{
765 type Output = Matrix<'a, T, D, S>;
766
767 fn mul(self, rhs: &Self) -> Self::Output {
768 self.device().mul(&self, rhs)
769 }
770}
771
772impl<'a, T, S: Shape, D: AdditionalOps<T, S>> Mul<T> for Matrix<'a, T, D, S> {
773 type Output = Matrix<'a, T, D, S>;
774
775 fn mul(self, rhs: T) -> Self::Output {
776 self.muls(rhs)
777 }
778}
779
780impl<'a, T: Copy, S: Shape, D: AdditionalOps<T, S>> Mul<&T> for Matrix<'a, T, D, S> {
781 type Output = Matrix<'a, T, D, S>;
782
783 fn mul(self, rhs: &T) -> Self::Output {
784 self.muls(*rhs)
785 }
786}
787
788impl<'a, T, S: Shape, D: AdditionalOps<T, S>> Mul<T> for &Matrix<'a, T, D, S> {
789 type Output = Matrix<'a, T, D, S>;
790
791 fn mul(self, rhs: T) -> Self::Output {
792 self.muls(rhs)
793 }
794}
795
796impl<'a, T, S: Shape, D: BaseOps<T, S>> Div<Self> for &Matrix<'a, T, D, S> {
799 type Output = Matrix<'a, T, D, S>;
800
801 fn div(self, rhs: Self) -> Self::Output {
802 self.device().div(self, rhs)
803 }
804}
805
806impl<'a, T, S: Shape, D: AdditionalOps<T, S>> Div<T> for Matrix<'a, T, D, S> {
807 type Output = Matrix<'a, T, D, S>;
808
809 fn div(self, rhs: T) -> Self::Output {
810 self.divs(rhs)
811 }
812}
813
814impl<'a, T, S: Shape, D: AdditionalOps<T, S>> Div<T> for &Matrix<'a, T, D, S> {
815 type Output = Matrix<'a, T, D, S>;
816
817 fn div(self, rhs: T) -> Self::Output {
818 self.divs(rhs)
819 }
820}
821
822impl<T, D, S: Shape> AddAssign<&Self> for Matrix<'_, T, D, S>
823where
824 D: AssignOps<T, S, D>,
825{
826 fn add_assign(&mut self, rhs: &Self) {
827 rhs.device().add_assign(self, rhs)
828 }
829}
830
831impl<T, D, S: Shape> AddAssign<Self> for Matrix<'_, T, D, S>
832where
833 D: AssignOps<T, S, D>,
834{
835 fn add_assign(&mut self, rhs: Self) {
836 rhs.device().add_assign(self, &rhs)
837 }
838}
839
840impl<T, D, S: Shape> MulAssign<&Self> for Matrix<'_, T, D, S>
841where
842 D: AssignOps<T, S, D>,
843{
844 fn mul_assign(&mut self, rhs: &Self) {
845 rhs.device().mul_assign(self, rhs)
846 }
847}
848
849impl<T, D, S: Shape> MulAssign<Self> for Matrix<'_, T, D, S>
850where
851 D: AssignOps<T, S, D>,
852{
853 fn mul_assign(&mut self, rhs: Self) {
854 rhs.device().mul_assign(self, &rhs)
855 }
856}
857
858impl<T, D, S: Shape> SubAssign<&Matrix<'_, T, D, S>> for &mut Matrix<'_, T, D, S>
859where
860 D: AssignOps<T, S, D>,
861{
862 fn sub_assign(&mut self, rhs: &Matrix<T, D, S>) {
863 rhs.device().sub_assign(self, rhs)
864 }
865}
866
867impl<T, D, S: Shape> SubAssign<Matrix<'_, T, D, S>> for &mut Matrix<'_, T, D, S>
868where
869 D: AssignOps<T, S, D>,
870{
871 fn sub_assign(&mut self, rhs: Matrix<T, D, S>) {
872 rhs.device().sub_assign(self, &rhs)
873 }
874}
875
876impl<T, D, S: Shape> SubAssign<&Self> for Matrix<'_, T, D, S>
877where
878 D: AssignOps<T, S, D>,
879{
880 fn sub_assign(&mut self, rhs: &Self) {
881 rhs.device().sub_assign(self, rhs)
882 }
883}
884
885impl<T, D, S: Shape> SubAssign<Self> for Matrix<'_, T, D, S>
886where
887 D: AssignOps<T, S, D>,
888{
889 fn sub_assign(&mut self, rhs: Self) {
890 rhs.device().sub_assign(self, &rhs)
891 }
892}
893
894#[cfg(not(feature = "no-std"))]
895impl<'a, T: Default + Copy + core::fmt::Debug, D: Read<T, D>> core::fmt::Debug for Matrix<'a, T, D>
896where
897 D: Read<T, D> + 'a,
898 {
900 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
901 let data = self.read_to_vec();
902
903 writeln!(f, "dims={:?}", self.dims)?;
904 write!(f, "[")?;
905
906 let max = self.dims.0 * self.dims.1;
907 for (count, value) in data.iter().enumerate() {
908 write!(f, "{:?}, ", value)?;
909
910 if (count + 1) % self.dims.1 == 0 && count + 1 != max {
911 writeln!(f)?;
912 }
913 }
914 write!(f, ":datatype={}]", core::any::type_name::<T>())
915 }
916}
917
918#[cfg(feature = "stack")]
919impl<'a, T, const N: usize> From<(&custos::Stack, usize, usize, [T; N])>
920 for Matrix<'a, T, custos::Stack, custos::Dim1<N>>
921{
922 fn from((_, rows, cols, array): (&custos::Stack, usize, usize, [T; N])) -> Self {
923 let data = Buffer::from((&custos::Stack, array));
924 Matrix {
925 data,
926 dims: (rows, cols),
927 }
928 }
929}
930
931#[cfg(feature = "stack")]
932impl<'a, T: Copy + Default, const A: usize, const B: usize, const N: usize>
933 From<(&custos::Stack, usize, usize, [T; N])>
934 for Matrix<'a, T, custos::Stack, custos::Dim2<A, B>>
935{
936 fn from((_, rows, cols, array): (&custos::Stack, usize, usize, [T; N])) -> Self {
937 let data = Buffer::from((&custos::Stack, array));
938 Matrix {
939 data,
940 dims: (rows, cols),
941 }
942 }
943}
944
945#[cfg(test)]
950mod tests {
951 use crate::Matrix;
952
953 #[cfg(feature = "stack")]
954 #[cfg(not(feature = "no-std"))]
955 #[test]
956 fn test_run() {
957 let device = custos::CPU::new();
958
959 let a = Matrix::from((&device, 1, 1000, [1; 1000]));
960 let b = Matrix::from((&device, 1, 1000, [7; 1000]));
961
962 loop {
963 let out = &a + &b;
964 assert_eq!(out.as_slice(), &[8; 1000]);
965 }
966 }
967
968 #[cfg(feature = "cpu")]
969 #[test]
970 fn test_to_dims() {
971 use custos::{Dim1, ToDim, CPU};
972
973 let device = CPU::new();
974 let a = Matrix::from((&device, 1, 1000, [1; 1000]));
975 ToDim::<i32, (), Dim1<1000>>::to_dim(&device, a.data.ptr);
976 }
978}