-
-
Notifications
You must be signed in to change notification settings - Fork 108
Expand file tree
/
Copy pathcpu_kernels.rs
More file actions
85 lines (75 loc) · 2.17 KB
/
Copy pathcpu_kernels.rs
File metadata and controls
85 lines (75 loc) · 2.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use crate::{
shapes::{Shape, Unit},
tensor::{
cpu::{Cpu, LendingIterator},
Tensor, ZerosTensor,
},
};
use super::{
CmpKernel, EqKernelOp, GeKernelOp, GtKernelOp, LeKernelOp, LtKernelOp, NeKernelOp,
ScalarCmpKernel,
};
trait CmpOpCpuKernel<E: Unit> {
fn func(lhs: E, rhs: E) -> bool;
}
impl<Op: CmpOpCpuKernel<E>, E: Unit> CmpKernel<Op, E> for Cpu {
fn forward<S: Shape, T>(
&self,
lhs: &Tensor<S, E, Self, T>,
rhs: &Tensor<S, E, Self, T>,
) -> Result<Tensor<S, bool, Self>, Self::Err> {
let mut out: Tensor<S, bool, Self> = self.try_zeros_like(&lhs.shape)?;
let mut lhs_iter = lhs.iter();
let mut rhs_iter = rhs.iter();
let mut out_iter = out.iter_mut();
while let Some((o, (l, r))) = out_iter.next().zip(lhs_iter.next().zip(rhs_iter.next())) {
*o = Op::func(*l, *r);
}
Ok(out)
}
}
impl<Op: CmpOpCpuKernel<E>, E: Unit> ScalarCmpKernel<Op, E> for Cpu {
fn forward<S: Shape, T>(
&self,
lhs: &Tensor<S, E, Self, T>,
scalar: E,
) -> Result<Tensor<S, bool, Self>, Self::Err> {
let mut out: Tensor<S, bool, Self> = self.try_zeros_like(&lhs.shape)?;
let mut lhs_iter = lhs.iter();
let mut out_iter = out.iter_mut();
while let Some((o, l)) = out_iter.next().zip(lhs_iter.next()) {
*o = Op::func(*l, scalar);
}
Ok(out)
}
}
impl<E: Unit + PartialOrd> CmpOpCpuKernel<E> for EqKernelOp {
fn func(lhs: E, rhs: E) -> bool {
lhs == rhs
}
}
impl<E: Unit + PartialOrd> CmpOpCpuKernel<E> for NeKernelOp {
fn func(lhs: E, rhs: E) -> bool {
lhs != rhs
}
}
impl<E: Unit + PartialOrd> CmpOpCpuKernel<E> for GtKernelOp {
fn func(lhs: E, rhs: E) -> bool {
lhs > rhs
}
}
impl<E: Unit + PartialOrd> CmpOpCpuKernel<E> for GeKernelOp {
fn func(lhs: E, rhs: E) -> bool {
lhs >= rhs
}
}
impl<E: Unit + PartialOrd> CmpOpCpuKernel<E> for LtKernelOp {
fn func(lhs: E, rhs: E) -> bool {
lhs < rhs
}
}
impl<E: Unit + PartialOrd> CmpOpCpuKernel<E> for LeKernelOp {
fn func(lhs: E, rhs: E) -> bool {
lhs <= rhs
}
}