1use crate::{assign_to_lhs_scalar, Matrix};
2use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
3use custos::{impl_stack, CDatatype, Device, MainMemory, Shape, CPU};
4
5#[cfg(feature = "stack")]
6use custos::Stack;
7
8#[cfg(feature = "opencl")]
9use crate::cl_assign_scalar;
10#[cfg(feature = "opencl")]
11use custos::OpenCL;
12
13#[cfg(feature = "cuda")]
14use crate::cu_assign_scalar;
15#[cfg(feature = "cuda")]
16use custos::CUDA;
17
18impl<'a, T, S, D> AddAssign<T> for Matrix<'a, T, D, S>
19where
20 S: Shape,
21 D: ScalarAssign<T, S>,
22{
23 #[inline]
24 fn add_assign(&mut self, rhs: T) {
25 self.device().adds_assign(self, rhs)
26 }
27}
28
29impl<T, S, D> MulAssign<T> for Matrix<'_, T, D, S>
30where
31 S: Shape,
32 D: ScalarAssign<T, S>,
33{
34 #[inline]
35 fn mul_assign(&mut self, rhs: T) {
36 self.device().muls_assign(self, rhs);
37 }
38}
39
40impl<T, S, D> DivAssign<T> for Matrix<'_, T, D, S>
41where
42 S: Shape,
43 D: ScalarAssign<T, S>,
44{
45 #[inline]
46 fn div_assign(&mut self, rhs: T) {
47 self.device().divs_assign(self, rhs);
48 }
49}
50
51pub trait ScalarAssign<T, S: Shape = (), D: Device = Self>: Device {
52 fn adds_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T);
53 fn muls_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T);
54 fn divs_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T);
55 fn subs_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T);
56}
57
58#[impl_stack]
59impl<T, D: MainMemory, S: Shape> ScalarAssign<T, S, D> for CPU
60where
61 T: Copy + AddAssign + MulAssign + DivAssign + SubAssign,
62{
63 #[inline]
64 fn adds_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T) {
65 assign_to_lhs_scalar(lhs, rhs, |x, y| *x += y);
66 }
67
68 #[inline]
69 fn muls_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T) {
70 assign_to_lhs_scalar(lhs, rhs, |x, y| *x *= y);
71 }
72
73 #[inline]
74 fn divs_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T) {
75 assign_to_lhs_scalar(lhs, rhs, |x, y| *x /= y);
76 }
77
78 #[inline]
79 fn subs_assign(&self, lhs: &mut Matrix<T, D, S>, rhs: T) {
80 assign_to_lhs_scalar(lhs, rhs, |x, y| *x -= y);
81 }
82}
83
84#[cfg(feature = "opencl")]
85impl<T: CDatatype> ScalarAssign<T> for OpenCL {
86 #[inline]
87 fn adds_assign(&self, lhs: &mut Matrix<T, Self>, rhs: T) {
88 cl_assign_scalar(self, lhs, rhs, "+").unwrap();
89 }
90
91 #[inline]
92 fn muls_assign(&self, lhs: &mut Matrix<T, Self>, rhs: T) {
93 cl_assign_scalar(self, lhs, rhs, "*").unwrap();
94 }
95
96 fn divs_assign(&self, lhs: &mut Matrix<T, Self>, rhs: T) {
97 cl_assign_scalar(self, lhs, rhs, "/").unwrap();
98 }
99
100 fn subs_assign(&self, lhs: &mut Matrix<T, Self>, rhs: T) {
101 cl_assign_scalar(self, lhs, rhs, "-").unwrap();
102 }
103}
104
105#[cfg(feature = "cuda")]
106impl<T: CDatatype> ScalarAssign<T> for CUDA {
107 #[inline]
108 fn adds_assign(&self, lhs: &mut Matrix<T, CUDA>, rhs: T) {
109 cu_assign_scalar(self, lhs, rhs, "+").unwrap();
110 }
111
112 #[inline]
113 fn muls_assign(&self, lhs: &mut Matrix<T, CUDA>, rhs: T) {
114 cu_assign_scalar(self, lhs, rhs, "*").unwrap();
115 }
116
117 #[inline]
118 fn divs_assign(&self, lhs: &mut Matrix<T, CUDA>, rhs: T) {
119 cu_assign_scalar(self, lhs, rhs, "/").unwrap();
120 }
121
122 #[inline]
123 fn subs_assign(&self, lhs: &mut Matrix<T, CUDA>, rhs: T) {
124 cu_assign_scalar(self, lhs, rhs, "-").unwrap();
125 }
126}