1use burn_backend::ops::AttentionModuleOptions;
2use burn_backend::tensor::IndexingUpdateOp;
3use core::hash::Hash;
4use serde::{Deserialize, Serialize};
5
6use alloc::borrow::ToOwned;
7use alloc::boxed::Box;
8use alloc::{string::String, vec::Vec};
9
10use burn_backend::{
11 DType, Distribution, Slice,
12 ops::{
13 ConvOptions, ConvTransposeOptions, DeformConvOptions, GridSampleOptions,
14 GridSamplePaddingMode, InterpolateMode, InterpolateOptions, PadMode,
15 },
16 quantization::QuantScheme,
17};
18
19use crate::{ScalarIr, TensorId, TensorIr, TensorStatus};
20
21pub trait IrVisitorMut {
23 fn visit_tensor_mut(&mut self, _tensor: &mut TensorIr) {}
25 fn visit_scalar_mut(&mut self, _scalar: &mut ScalarIr) {}
27 fn visit_range_mut(&mut self, _range: &mut Slice) {}
29}
30
31#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
33pub struct CustomOpIr {
34 pub id: String,
36 pub inputs: Vec<TensorIr>,
38 pub outputs: Vec<TensorIr>,
40 pub scalars: Vec<ScalarIr>,
47}
48
49impl CustomOpIr {
50 pub fn new(id: &'static str, inputs: &[TensorIr], outputs: &[TensorIr]) -> Self {
52 Self {
53 id: id.to_owned(),
54 inputs: inputs.to_vec(),
55 outputs: outputs.to_vec(),
56 scalars: Vec::new(),
57 }
58 }
59
60 pub fn with_scalars(
62 id: &'static str,
63 inputs: &[TensorIr],
64 outputs: &[TensorIr],
65 scalars: Vec<ScalarIr>,
66 ) -> Self {
67 Self {
68 id: id.to_owned(),
69 inputs: inputs.to_vec(),
70 outputs: outputs.to_vec(),
71 scalars,
72 }
73 }
74
75 pub fn as_fixed<const N_IN: usize, const N_OUT: usize>(
77 &self,
78 ) -> (&[TensorIr; N_IN], &[TensorIr; N_OUT]) {
79 (
80 self.inputs.as_slice().try_into().expect(
81 "Wrong number of inputs expected (expected {D}, is {}), check your implementation",
82 ),
83 self.outputs.as_slice().try_into().expect(
84 "Wrong number of outputs expected (expected {D}, is {}), check your implementation",
85 ),
86 )
87 }
88
89 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
90 Box::new(self.inputs.iter())
91 }
92
93 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
94 Box::new(self.outputs.iter())
95 }
96
97 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
98 for t in self.inputs.iter_mut() {
99 v.visit_tensor_mut(t);
100 }
101 for t in self.outputs.iter_mut() {
102 v.visit_tensor_mut(t);
103 }
104 for s in self.scalars.iter_mut() {
105 v.visit_scalar_mut(s);
106 }
107 }
108}
109
110#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
112#[allow(clippy::large_enum_variant)]
113pub enum OperationIr {
114 BaseFloat(BaseOperationIr),
116 BaseInt(BaseOperationIr),
118 BaseBool(BaseOperationIr),
120 NumericFloat(DType, NumericOperationIr),
122 NumericInt(DType, NumericOperationIr),
124 Bool(BoolOperationIr),
126 Int(IntOperationIr),
128 Float(DType, FloatOperationIr),
130 Module(ModuleOperationIr),
132 Init(InitOperationIr),
134 Custom(CustomOpIr),
136 Drop(TensorIr),
138 Distributed(DistributedOperationIr),
140 Activation(ActivationOperationIr),
142}
143
144#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
146pub enum FloatOperationIr {
147 Exp(UnaryOpIr),
149 Log(UnaryOpIr),
151 Log1p(UnaryOpIr),
153 Erf(UnaryOpIr),
155 PowfScalar(ScalarOpIr),
157 Sqrt(UnaryOpIr),
159 Cos(UnaryOpIr),
161 Cosh(UnaryOpIr),
163 Sin(UnaryOpIr),
165 Sinh(UnaryOpIr),
167 Tan(UnaryOpIr),
169 Tanh(UnaryOpIr),
171 ArcCos(UnaryOpIr),
173 ArcCosh(UnaryOpIr),
175 ArcSin(UnaryOpIr),
177 ArcSinh(UnaryOpIr),
179 ArcTan(UnaryOpIr),
181 ArcTanh(UnaryOpIr),
183 ArcTan2(BinaryOpIr),
185 Round(UnaryOpIr),
187 Floor(UnaryOpIr),
189 Ceil(UnaryOpIr),
191 Trunc(UnaryOpIr),
193 IntoInt(CastOpIr),
195 Matmul(MatmulOpIr),
197 Cross(CrossOpIr),
199 Random(RandomOpIr),
201 Recip(UnaryOpIr),
203 IsNan(UnaryOpIr),
205 IsInf(UnaryOpIr),
207 Quantize(QuantizeOpIr),
209 Dequantize(DequantizeOpIr),
211 GridSample2d(GridSample2dOpIr),
213 Powf(BinaryOpIr),
215 Hypot(BinaryOpIr),
217}
218
219#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
221pub enum ModuleOperationIr {
222 BatchNorm(BatchNormOpIr),
225 Embedding(EmbeddingOpIr),
227 EmbeddingBackward(EmbeddingBackwardOpIr),
229 Linear(LinearOpIr),
231 LinearXBackward(LinearXBackwardOpIr),
233 LinearWeightBackward(LinearWeightBackwardOpIr),
235 LinearBiasBackward(LinearBiasBackwardOpIr),
237 Conv1d(Conv1dOpIr),
239 Conv1dXBackward(Conv1dXBackwardOpIr),
241 Conv1dWeightBackward(Conv1dWeightBackwardOpIr),
243 Conv1dBiasBackward(Conv1dBiasBackwardOpIr),
245 Conv2d(Conv2dOpIr),
247 Conv2dXBackward(Conv2dXBackwardOpIr),
249 Conv2dWeightBackward(Conv2dWeightBackwardOpIr),
251 Conv2dBiasBackward(Conv2dBiasBackwardOpIr),
253 Conv3d(Conv3dOpIr),
255 Conv3dXBackward(Conv3dXBackwardOpIr),
257 Conv3dWeightBackward(Conv3dWeightBackwardOpIr),
259 Conv3dBiasBackward(Conv3dBiasBackwardOpIr),
261 DeformableConv2d(Box<DeformConv2dOpIr>),
263 DeformableConv2dBackward(Box<DeformConv2dBackwardOpIr>),
265 ConvTranspose1d(ConvTranspose1dOpIr),
267 ConvTranspose2d(ConvTranspose2dOpIr),
269 ConvTranspose3d(ConvTranspose3dOpIr),
271 AvgPool1d(AvgPool1dOpIr),
273 AvgPool2d(AvgPool2dOpIr),
275 AvgPool1dBackward(AvgPool1dBackwardOpIr),
278 AvgPool2dBackward(AvgPool2dBackwardOpIr),
281 AdaptiveAvgPool1d(AdaptiveAvgPool1dOpIr),
284 AdaptiveAvgPool2d(AdaptiveAvgPool2dOpIr),
287 AdaptiveAvgPool1dBackward(AdaptiveAvgPool1dBackwardOpIr),
290 AdaptiveAvgPool2dBackward(AdaptiveAvgPool2dBackwardOpIr),
293 AdaptiveAvgPool3d(AdaptiveAvgPool3dOpIr),
296 AdaptiveAvgPool3dBackward(AdaptiveAvgPool3dBackwardOpIr),
299 MaxPool1d(MaxPool1dOpIr),
302 MaxPool1dWithIndices(MaxPool1dWithIndicesOpIr),
305 MaxPool1dWithIndicesBackward(MaxPool1dWithIndicesBackwardOpIr),
308 MaxPool2d(MaxPool2dOpIr),
311 MaxPool2dWithIndices(MaxPool2dWithIndicesOpIr),
314 MaxPool2dWithIndicesBackward(MaxPool2dWithIndicesBackwardOpIr),
317 Interpolate(InterpolateOpIr),
319 InterpolateBackward(InterpolateBackwardOpIr),
321 Attention(AttentionOpIr),
323 CtcLoss(CtcLossOpIr),
325 CtcLossBackward(CtcLossBackwardOpIr),
328 LayerNorm(LayerNormOpIr),
330 Unfold4d(Unfold4dOpIr),
332 ConvTranspose1dWeightBackward(ConvTranspose1dWeightBackwardOpIr),
335 ConvTranspose1dBiasBackward(ConvTranspose1dBiasBackwardOpIr),
338 ConvTranspose2dWeightBackward(ConvTranspose2dWeightBackwardOpIr),
341 ConvTranspose2dBiasBackward(ConvTranspose2dBiasBackwardOpIr),
344 ConvTranspose3dWeightBackward(ConvTranspose3dWeightBackwardOpIr),
347 ConvTranspose3dBiasBackward(ConvTranspose3dBiasBackwardOpIr),
350}
351
352#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
354pub enum BaseOperationIr {
355 Reshape(ShapeOpIr),
361
362 SwapDims(SwapDimsOpIr),
368
369 Permute(PermuteOpIr),
375
376 Flip(FlipOpIr),
381
382 Expand(ShapeOpIr),
388
389 Unfold(UnfoldOpIr),
392
393 Slice(SliceOpIr),
399 SliceAssign(SliceAssignOpIr),
405 Select(SelectOpIr),
411 SelectAssign(SelectAssignOpIr),
417 MaskWhere(MaskWhereOpIr),
423 MaskFill(MaskFillOpIr),
429 Gather(GatherOpIr),
435 Scatter(ScatterOpIr),
441 ScatterNd(ScatterNdOpIr),
443 GatherNd(GatherNdOpIr),
445 Equal(BinaryOpIr),
451 EqualElem(ScalarOpIr),
457 RepeatDim(RepeatDimOpIr),
463 Cat(CatOpIr),
469 Cast(CastOpIr),
471 Empty(CreationOpIr),
477 Ones(CreationOpIr),
483 Zeros(CreationOpIr),
489 NotEqual(BinaryOpIr),
495 NotEqualElem(ScalarOpIr),
501 All(ReduceOpIr),
506 Any(ReduceOpIr),
508 AllDim(ReduceDimOpIr),
510 AnyDim(ReduceDimOpIr),
512}
513
514#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
516pub enum NumericOperationIr {
517 Add(BinaryOpIr),
522 AddScalar(ScalarOpIr),
527 Sub(BinaryOpIr),
532 SubScalar(ScalarOpIr),
537 Div(BinaryOpIr),
542 DivScalar(ScalarOpIr),
547 Rem(BinaryOpIr),
552 RemScalar(ScalarOpIr),
557 Mul(BinaryOpIr),
562 MulScalar(ScalarOpIr),
567 Abs(UnaryOpIr),
572 Full(FullOpIr),
577 MeanDim(ReduceDimOpIr),
582 Mean(ReduceOpIr),
587 Sum(ReduceOpIr),
592 SumDim(ReduceDimOpIr),
597 SumDims(ReduceDimsOpIr),
599 Prod(ReduceOpIr),
604 ProdDim(ReduceDimOpIr),
609 Greater(BinaryOpIr),
614 GreaterElem(ScalarOpIr),
619 GreaterEqual(BinaryOpIr),
624 GreaterEqualElem(ScalarOpIr),
629 Lower(BinaryOpIr),
634 LowerElem(ScalarOpIr),
639 LowerEqual(BinaryOpIr),
644 LowerEqualElem(ScalarOpIr),
649 ArgMax(ReduceDimOpIr),
654 ArgTopK(ReduceDimOpIr),
659 TopK(ReduceDimOpIr),
664 TopKWithIndices(TopKWithIndicesOpIr),
669 ArgMin(ReduceDimOpIr),
674 Max(ReduceOpIr),
679 MaxDimWithIndices(ReduceDimWithIndicesOpIr),
684 MinDimWithIndices(ReduceDimWithIndicesOpIr),
689 Min(ReduceOpIr),
694 MaxDim(ReduceDimOpIr),
699 MinDim(ReduceDimOpIr),
704 MaxAbs(ReduceOpIr),
709 MaxAbsDim(ReduceDimOpIr),
714 Clamp(ClampOpIr),
719 IntRandom(RandomOpIr),
723 Powi(BinaryOpIr),
728 PowiScalar(ScalarOpIr),
733 CumSum(DimOpIr),
738 CumProd(DimOpIr),
743 CumMin(DimOpIr),
748 CumMax(DimOpIr),
753 Neg(UnaryOpIr),
758 Sign(UnaryOpIr),
763 ClampMin(ScalarOpIr),
768 ClampMax(ScalarOpIr),
773 Sort(SortOpIr),
775 SortWithIndices(SortWithIndicesOpIr),
777 ArgSort(SortOpIr),
781 Pad(PadOpIr),
786}
787
788#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
790pub enum IntOperationIr {
791 IntoFloat(CastOpIr),
793 BitwiseAnd(BinaryOpIr),
797 BitwiseAndScalar(ScalarOpIr),
801 BitwiseOr(BinaryOpIr),
805 BitwiseOrScalar(ScalarOpIr),
809 BitwiseXor(BinaryOpIr),
813 BitwiseXorScalar(ScalarOpIr),
817 BitwiseNot(UnaryOpIr),
821 BitwiseLeftShift(BinaryOpIr),
825 BitwiseLeftShiftScalar(ScalarOpIr),
829 BitwiseRightShift(BinaryOpIr),
833 BitwiseRightShiftScalar(ScalarOpIr),
837 Matmul(MatmulOpIr),
839}
840
841#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
843pub enum BoolOperationIr {
844 IntoFloat(CastOpIr),
846 IntoInt(CastOpIr),
848 Not(UnaryOpIr),
850 And(BinaryOpIr),
852 Or(BinaryOpIr),
854 Xor(BinaryOpIr),
856}
857
858#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
860#[allow(clippy::large_enum_variant)]
861pub enum DistributedOperationIr {
862 AllReduce(AllReduceOpIr),
865 SyncCollective,
872}
873
874#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
876pub struct SwapDimsOpIr {
877 pub input: TensorIr,
879 pub out: TensorIr,
881 pub dim1: usize,
883 pub dim2: usize,
885}
886
887#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
889pub struct PermuteOpIr {
890 pub input: TensorIr,
892 pub out: TensorIr,
894 pub axes: Vec<usize>,
896}
897
898#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
900pub struct ShapeOpIr {
901 pub input: TensorIr,
903 pub out: TensorIr,
905}
906
907#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
909pub struct UnfoldOpIr {
910 pub input: TensorIr,
912 pub out: TensorIr,
914
915 pub dim: usize,
917 pub size: usize,
919 pub step: usize,
921}
922
923#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
925pub struct FlipOpIr {
926 pub input: TensorIr,
928 pub out: TensorIr,
930 pub axes: Vec<usize>,
932}
933
934#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
936pub struct PadOpIr {
937 pub input: TensorIr,
939 pub out: TensorIr,
941 pub padding: Vec<(usize, usize)>,
943 pub mode: PadModeIr,
945}
946
947#[derive(Clone, Copy, Debug, Hash, PartialEq, Serialize, Deserialize)]
949pub enum PadModeIr {
950 Constant(ScalarIr),
952 Reflect,
954 Edge,
956}
957
958impl From<PadMode> for PadModeIr {
959 fn from(value: PadMode) -> Self {
960 match value {
961 PadMode::Constant(value) => Self::Constant(ScalarIr::Float(value as f64)),
962 PadMode::Reflect => Self::Reflect,
963 PadMode::Edge => Self::Edge,
964 }
965 }
966}
967
968impl From<PadModeIr> for PadMode {
969 fn from(value: PadModeIr) -> Self {
970 match value {
971 PadModeIr::Constant(value) => Self::Constant(value.elem()),
972 PadModeIr::Reflect => Self::Reflect,
973 PadModeIr::Edge => Self::Edge,
974 }
975 }
976}
977
978#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
979#[allow(missing_docs)]
980pub struct RandomOpIr {
981 pub out: TensorIr,
982 pub distribution: Distribution,
983}
984
985#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
988pub struct CreationOpIr {
989 pub out: TensorIr,
991}
992
993#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
995pub struct FullOpIr {
996 pub out: TensorIr,
998 pub value: ScalarIr,
1000}
1001
1002#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1003pub struct InitOperationIr {
1007 pub out: TensorIr,
1009}
1010
1011#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1012#[allow(missing_docs)]
1013pub struct BinaryOpIr {
1014 pub lhs: TensorIr,
1015 pub rhs: TensorIr,
1016 pub out: TensorIr,
1017}
1018
1019#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1020#[allow(missing_docs)]
1021pub struct MatmulOpIr {
1022 pub lhs: TensorIr,
1023 pub rhs: TensorIr,
1024 pub out: TensorIr,
1025}
1026
1027#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1028#[allow(missing_docs)]
1029pub struct CrossOpIr {
1030 pub lhs: TensorIr,
1031 pub rhs: TensorIr,
1032 pub out: TensorIr,
1033 pub dim: usize,
1034}
1035
1036#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1037#[allow(missing_docs)]
1038pub struct UnaryOpIr {
1039 pub input: TensorIr,
1040 pub out: TensorIr,
1041}
1042
1043#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1044#[allow(missing_docs)]
1045pub struct ScalarOpIr {
1046 pub lhs: TensorIr,
1047 pub rhs: ScalarIr,
1050 pub out: TensorIr,
1051}
1052
1053#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Hash)]
1054#[allow(missing_docs)]
1055pub struct ReduceOpIr {
1056 pub input: TensorIr,
1057 pub out: TensorIr,
1058}
1059
1060#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Hash)]
1061#[allow(missing_docs)]
1062pub struct ReduceDimOpIr {
1063 pub input: TensorIr,
1064 pub out: TensorIr,
1065 pub axis: usize,
1066 pub accumulator_len: usize,
1067}
1068
1069#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Hash)]
1071#[allow(missing_docs)]
1072pub struct ReduceDimsOpIr {
1073 pub input: TensorIr,
1074 pub out: TensorIr,
1075 pub axes: Vec<usize>,
1076}
1077
1078#[allow(missing_docs)]
1079impl ReduceDimsOpIr {
1080 pub fn create<F>(input: TensorIr, axes: Vec<usize>, mut new_id: F) -> Self
1081 where
1082 F: FnMut() -> crate::TensorId,
1083 {
1084 let mut shape = input.shape.clone();
1085 for axis in &axes {
1086 shape[*axis] = 1;
1087 }
1088 let dtype = input.dtype;
1089
1090 Self {
1091 out: TensorIr::uninit(new_id(), shape, dtype),
1092 input,
1093 axes,
1094 }
1095 }
1096}
1097
1098#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1099#[allow(missing_docs)]
1100pub struct CastOpIr {
1101 pub input: TensorIr,
1102 pub out: TensorIr,
1103}
1104
1105#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Hash)]
1108#[allow(missing_docs)]
1109pub struct DimOpIr {
1110 pub input: TensorIr,
1111 pub out: TensorIr,
1112 pub axis: usize,
1113}
1114
1115#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1116#[allow(missing_docs)]
1117pub struct GatherOpIr {
1118 pub tensor: TensorIr,
1119 pub dim: usize,
1120 pub indices: TensorIr,
1121 pub out: TensorIr,
1122}
1123
1124#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1125#[allow(missing_docs)]
1126pub struct ScatterOpIr {
1127 pub tensor: TensorIr,
1128 pub dim: usize,
1129 pub indices: TensorIr,
1130 pub value: TensorIr,
1131 pub update: IndexingUpdateOp,
1132 pub out: TensorIr,
1133}
1134
1135#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1136#[allow(missing_docs)]
1137pub struct ScatterNdOpIr {
1138 pub data: TensorIr,
1139 pub indices: TensorIr,
1140 pub values: TensorIr,
1141 pub reduction: IndexingUpdateOp,
1142 pub out: TensorIr,
1143}
1144
1145#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1146#[allow(missing_docs)]
1147pub struct GatherNdOpIr {
1148 pub data: TensorIr,
1149 pub indices: TensorIr,
1150 pub out: TensorIr,
1151}
1152
1153#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1154#[allow(missing_docs)]
1155pub struct SelectOpIr {
1156 pub tensor: TensorIr,
1157 pub dim: usize,
1158 pub indices: TensorIr,
1159 pub out: TensorIr,
1160}
1161
1162#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1163#[allow(missing_docs)]
1164pub struct SelectAssignOpIr {
1165 pub tensor: TensorIr,
1166 pub dim: usize,
1167 pub indices: TensorIr,
1168 pub value: TensorIr,
1169 pub update: IndexingUpdateOp,
1170 pub out: TensorIr,
1171}
1172
1173#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1174#[allow(missing_docs)]
1175pub struct SliceOpIr {
1176 pub tensor: TensorIr,
1177 pub ranges: Vec<Slice>,
1178 pub out: TensorIr,
1179}
1180
1181#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1182#[allow(missing_docs)]
1183pub struct SliceAssignOpIr {
1184 pub tensor: TensorIr,
1185 pub ranges: Vec<burn_backend::Slice>,
1186 pub value: TensorIr,
1187 pub out: TensorIr,
1188}
1189
1190#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1191#[allow(missing_docs)]
1192pub struct MaskWhereOpIr {
1193 pub tensor: TensorIr,
1194 pub mask: TensorIr,
1195 pub value: TensorIr,
1196 pub out: TensorIr,
1197}
1198
1199#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1200#[allow(missing_docs)]
1201pub struct MaskFillOpIr {
1202 pub tensor: TensorIr,
1203 pub mask: TensorIr,
1204 pub value: ScalarIr,
1205 pub out: TensorIr,
1206}
1207
1208#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1209#[allow(missing_docs)]
1210pub struct ClampOpIr {
1211 pub tensor: TensorIr,
1212 pub min: ScalarIr,
1213 pub max: ScalarIr,
1214 pub out: TensorIr,
1215}
1216
1217#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1218#[allow(missing_docs)]
1219pub struct RepeatDimOpIr {
1220 pub tensor: TensorIr,
1221 pub dim: usize,
1222 pub times: usize,
1223 pub out: TensorIr,
1224}
1225
1226#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1227#[allow(missing_docs)]
1228pub struct CatOpIr {
1229 pub tensors: Vec<TensorIr>,
1230 pub dim: usize,
1231 pub out: TensorIr,
1232}
1233
1234#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1235#[allow(missing_docs)]
1236pub struct AllReduceOpIr {
1237 pub tensor: TensorIr,
1238 pub out: TensorIr,
1239 pub op: burn_backend::distributed::ReduceOperation,
1241 pub device_ids: Vec<DeviceIdIr>,
1243}
1244
1245#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, Serialize, Deserialize)]
1250pub struct DeviceIdIr {
1251 pub type_id: u16,
1253 pub index_id: u16,
1255}
1256
1257impl From<burn_backend::DeviceId> for DeviceIdIr {
1258 fn from(value: burn_backend::DeviceId) -> Self {
1259 Self {
1260 type_id: value.type_id,
1261 index_id: value.index_id,
1262 }
1263 }
1264}
1265
1266impl From<DeviceIdIr> for burn_backend::DeviceId {
1267 fn from(value: DeviceIdIr) -> Self {
1268 burn_backend::DeviceId::new(value.type_id, value.index_id)
1269 }
1270}
1271
1272#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1273#[allow(missing_docs)]
1274pub struct ReduceDimWithIndicesOpIr {
1275 pub tensor: TensorIr,
1276 pub dim: usize,
1277 pub out: TensorIr,
1278 pub out_indices: TensorIr,
1279}
1280
1281#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1282#[allow(missing_docs)]
1283pub struct TopKWithIndicesOpIr {
1286 pub tensor: TensorIr,
1287 pub dim: usize,
1288 pub k: usize,
1289 pub out: TensorIr,
1290 pub out_indices: TensorIr,
1291}
1292
1293#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1294#[allow(missing_docs)]
1295pub struct EmbeddingOpIr {
1296 pub weights: TensorIr,
1297 pub indices: TensorIr,
1298 pub out: TensorIr,
1299}
1300
1301#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1302#[allow(missing_docs)]
1303pub struct EmbeddingBackwardOpIr {
1304 pub weights: TensorIr,
1305 pub out_grad: TensorIr,
1306 pub indices: TensorIr,
1307 pub out: TensorIr,
1308}
1309
1310#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1314#[allow(missing_docs)]
1315pub struct BatchNormOpIr {
1316 pub x: TensorIr,
1317 pub gamma: TensorIr,
1318 pub beta: TensorIr,
1319 pub mean: TensorIr,
1320 pub variance: TensorIr,
1321 pub epsilon: ScalarIr,
1322 pub out: TensorIr,
1323}
1324
1325#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1326#[allow(missing_docs)]
1327pub struct LinearOpIr {
1328 pub x: TensorIr,
1329 pub weight: TensorIr,
1330 pub bias: Option<TensorIr>,
1331 pub out: TensorIr,
1332}
1333
1334#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1335#[allow(missing_docs)]
1336pub struct LinearXBackwardOpIr {
1337 pub weight: TensorIr,
1338 pub output_grad: TensorIr,
1339 pub out: TensorIr,
1340}
1341
1342#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1343#[allow(missing_docs)]
1344pub struct LinearWeightBackwardOpIr {
1345 pub x: TensorIr,
1346 pub output_grad: TensorIr,
1347 pub out: TensorIr,
1348}
1349
1350#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1351#[allow(missing_docs)]
1352pub struct LinearBiasBackwardOpIr {
1353 pub output_grad: TensorIr,
1354 pub out: TensorIr,
1355}
1356
1357#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1358#[allow(missing_docs)]
1359pub struct Conv1dOpIr {
1360 pub x: TensorIr,
1361 pub weight: TensorIr,
1362 pub bias: Option<TensorIr>,
1363 pub options: Conv1dOptionsIr,
1364 pub out: TensorIr,
1365}
1366
1367#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1368#[allow(missing_docs)]
1369pub struct Conv1dXBackwardOpIr {
1370 pub x: TensorIr,
1371 pub weight: TensorIr,
1372 pub output_grad: TensorIr,
1373 pub options: Conv1dOptionsIr,
1374 pub out: TensorIr,
1375}
1376
1377#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1378#[allow(missing_docs)]
1379pub struct Conv1dWeightBackwardOpIr {
1380 pub x: TensorIr,
1381 pub weight: TensorIr,
1382 pub output_grad: TensorIr,
1383 pub options: Conv1dOptionsIr,
1384 pub out: TensorIr,
1385}
1386
1387#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1388#[allow(missing_docs)]
1389pub struct Conv1dBiasBackwardOpIr {
1390 pub x: TensorIr,
1391 pub bias: TensorIr,
1392 pub output_grad: TensorIr,
1393 pub out: TensorIr,
1394}
1395
1396#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1397#[allow(missing_docs)]
1398pub struct Conv2dOpIr {
1399 pub x: TensorIr,
1400 pub weight: TensorIr,
1401 pub bias: Option<TensorIr>,
1402 pub options: Conv2dOptionsIr,
1403 pub out: TensorIr,
1404}
1405
1406#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1407#[allow(missing_docs)]
1408pub struct Conv2dXBackwardOpIr {
1409 pub x: TensorIr,
1410 pub weight: TensorIr,
1411 pub output_grad: TensorIr,
1412 pub options: Conv2dOptionsIr,
1413 pub out: TensorIr,
1414}
1415
1416#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1417#[allow(missing_docs)]
1418pub struct Conv2dWeightBackwardOpIr {
1419 pub x: TensorIr,
1420 pub weight: TensorIr,
1421 pub output_grad: TensorIr,
1422 pub options: Conv2dOptionsIr,
1423 pub out: TensorIr,
1424}
1425
1426#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1427#[allow(missing_docs)]
1428pub struct Conv2dBiasBackwardOpIr {
1429 pub x: TensorIr,
1430 pub bias: TensorIr,
1431 pub output_grad: TensorIr,
1432 pub out: TensorIr,
1433}
1434
1435#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1436#[allow(missing_docs)]
1437pub struct DeformConv2dOpIr {
1438 pub x: TensorIr,
1439 pub offset: TensorIr,
1440 pub weight: TensorIr,
1441 pub mask: Option<TensorIr>,
1442 pub bias: Option<TensorIr>,
1443 pub options: DeformableConv2dOptionsIr,
1444 pub out: TensorIr,
1445}
1446
1447#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1448#[allow(missing_docs)]
1449pub struct DeformConv2dBackwardOpIr {
1450 pub x: TensorIr,
1451 pub offset: TensorIr,
1452 pub weight: TensorIr,
1453 pub mask: Option<TensorIr>,
1454 pub bias: Option<TensorIr>,
1455 pub out_grad: TensorIr,
1456 pub options: DeformableConv2dOptionsIr,
1457 pub input_grad: TensorIr,
1458 pub offset_grad: TensorIr,
1459 pub weight_grad: TensorIr,
1460 pub mask_grad: Option<TensorIr>,
1461 pub bias_grad: Option<TensorIr>,
1462}
1463
1464#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1465#[allow(missing_docs)]
1466pub struct Conv3dOpIr {
1467 pub x: TensorIr,
1468 pub weight: TensorIr,
1469 pub bias: Option<TensorIr>,
1470 pub options: Conv3dOptionsIr,
1471 pub out: TensorIr,
1472}
1473
1474#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1475#[allow(missing_docs)]
1476pub struct Conv3dXBackwardOpIr {
1477 pub x: TensorIr,
1478 pub weight: TensorIr,
1479 pub output_grad: TensorIr,
1480 pub options: Conv3dOptionsIr,
1481 pub out: TensorIr,
1482}
1483
1484#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1485#[allow(missing_docs)]
1486pub struct Conv3dWeightBackwardOpIr {
1487 pub x: TensorIr,
1488 pub weight: TensorIr,
1489 pub output_grad: TensorIr,
1490 pub options: Conv3dOptionsIr,
1491 pub out: TensorIr,
1492}
1493
1494#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1495#[allow(missing_docs)]
1496pub struct Conv3dBiasBackwardOpIr {
1497 pub x: TensorIr,
1498 pub bias: TensorIr,
1499 pub output_grad: TensorIr,
1500 pub out: TensorIr,
1501}
1502
1503#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1504#[allow(missing_docs)]
1505pub struct ConvTranspose1dOpIr {
1506 pub x: TensorIr,
1507 pub weight: TensorIr,
1508 pub bias: Option<TensorIr>,
1509 pub options: ConvTranspose1dOptionsIr,
1510 pub out: TensorIr,
1511}
1512
1513#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1514#[allow(missing_docs)]
1515pub struct ConvTranspose2dOpIr {
1516 pub x: TensorIr,
1517 pub weight: TensorIr,
1518 pub bias: Option<TensorIr>,
1519 pub options: ConvTranspose2dOptionsIr,
1520 pub out: TensorIr,
1521}
1522
1523#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1524#[allow(missing_docs)]
1525pub struct ConvTranspose3dOpIr {
1526 pub x: TensorIr,
1527 pub weight: TensorIr,
1528 pub bias: Option<TensorIr>,
1529 pub options: ConvTranspose3dOptionsIr,
1530 pub out: TensorIr,
1531}
1532
1533#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1534#[allow(missing_docs)]
1535pub struct Conv1dOptionsIr {
1536 pub stride: [usize; 1],
1537 pub padding: [(usize, usize); 1],
1538 pub dilation: [usize; 1],
1539 pub groups: usize,
1540}
1541
1542#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1543#[allow(missing_docs)]
1544pub struct Conv2dOptionsIr {
1545 pub stride: [usize; 2],
1546 pub padding: [(usize, usize); 2],
1547 pub dilation: [usize; 2],
1548 pub groups: usize,
1549}
1550
1551#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1552#[allow(missing_docs)]
1553pub struct DeformableConv2dOptionsIr {
1554 pub stride: [usize; 2],
1555 pub padding: [usize; 2],
1556 pub dilation: [usize; 2],
1557 pub weight_groups: usize,
1558 pub offset_groups: usize,
1559}
1560
1561#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1562#[allow(missing_docs)]
1563pub struct Conv3dOptionsIr {
1564 pub stride: [usize; 3],
1565 pub padding: [usize; 3],
1566 pub dilation: [usize; 3],
1567 pub groups: usize,
1568}
1569
1570#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1571#[allow(missing_docs)]
1572pub struct ConvTranspose1dOptionsIr {
1573 pub stride: [usize; 1],
1574 pub padding: [usize; 1],
1575 pub padding_out: [usize; 1],
1576 pub dilation: [usize; 1],
1577 pub groups: usize,
1578}
1579
1580#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1581#[allow(missing_docs)]
1582pub struct ConvTranspose2dOptionsIr {
1583 pub stride: [usize; 2],
1584 pub padding: [usize; 2],
1585 pub padding_out: [usize; 2],
1586 pub dilation: [usize; 2],
1587 pub groups: usize,
1588}
1589
1590#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1591#[allow(missing_docs)]
1592pub struct ConvTranspose3dOptionsIr {
1593 pub stride: [usize; 3],
1594 pub padding: [usize; 3],
1595 pub padding_out: [usize; 3],
1596 pub dilation: [usize; 3],
1597 pub groups: usize,
1598}
1599
1600#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
1602pub struct QuantizationParametersIr {
1603 pub scales: TensorIr,
1605 pub global: Option<TensorIr>,
1608}
1609
1610#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1611#[allow(missing_docs)]
1612pub struct QuantizeOpIr {
1613 pub tensor: TensorIr,
1614 pub qparams: QuantizationParametersIr,
1615 pub scheme: QuantScheme,
1616 pub out: TensorIr,
1617}
1618
1619#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1620#[allow(missing_docs)]
1621pub struct DequantizeOpIr {
1622 pub input: TensorIr,
1623 pub out: TensorIr,
1624}
1625
1626impl From<ConvOptions<1>> for Conv1dOptionsIr {
1627 fn from(value: ConvOptions<1>) -> Self {
1628 Self {
1629 stride: value.stride,
1630 padding: value.padding,
1631 dilation: value.dilation,
1632 groups: value.groups,
1633 }
1634 }
1635}
1636
1637impl From<ConvOptions<2>> for Conv2dOptionsIr {
1638 fn from(value: ConvOptions<2>) -> Self {
1639 Self {
1640 stride: value.stride,
1641 padding: value.padding,
1642 dilation: value.dilation,
1643 groups: value.groups,
1644 }
1645 }
1646}
1647
1648impl From<ConvOptions<3>> for Conv3dOptionsIr {
1649 fn from(value: ConvOptions<3>) -> Self {
1650 Self {
1651 stride: value.stride,
1652 padding: value.symmetric_padding(),
1653 dilation: value.dilation,
1654 groups: value.groups,
1655 }
1656 }
1657}
1658
1659impl From<DeformConvOptions<2>> for DeformableConv2dOptionsIr {
1660 fn from(value: DeformConvOptions<2>) -> Self {
1661 Self {
1662 stride: value.stride,
1663 padding: value.padding,
1664 dilation: value.dilation,
1665 weight_groups: value.weight_groups,
1666 offset_groups: value.offset_groups,
1667 }
1668 }
1669}
1670
1671impl From<ConvTransposeOptions<1>> for ConvTranspose1dOptionsIr {
1672 fn from(value: ConvTransposeOptions<1>) -> Self {
1673 Self {
1674 stride: value.stride,
1675 padding: value.padding,
1676 padding_out: value.padding_out,
1677 dilation: value.dilation,
1678 groups: value.groups,
1679 }
1680 }
1681}
1682
1683impl From<ConvTransposeOptions<2>> for ConvTranspose2dOptionsIr {
1684 fn from(value: ConvTransposeOptions<2>) -> Self {
1685 Self {
1686 stride: value.stride,
1687 padding: value.padding,
1688 padding_out: value.padding_out,
1689 dilation: value.dilation,
1690 groups: value.groups,
1691 }
1692 }
1693}
1694
1695impl From<ConvTransposeOptions<3>> for ConvTranspose3dOptionsIr {
1696 fn from(value: ConvTransposeOptions<3>) -> Self {
1697 Self {
1698 stride: value.stride,
1699 padding: value.padding,
1700 padding_out: value.padding_out,
1701 dilation: value.dilation,
1702 groups: value.groups,
1703 }
1704 }
1705}
1706
1707impl From<Conv1dOptionsIr> for ConvOptions<1> {
1708 fn from(val: Conv1dOptionsIr) -> Self {
1709 ConvOptions {
1710 stride: val.stride,
1711 padding: val.padding,
1712 dilation: val.dilation,
1713 groups: val.groups,
1714 }
1715 }
1716}
1717
1718impl From<Conv2dOptionsIr> for ConvOptions<2> {
1719 fn from(val: Conv2dOptionsIr) -> Self {
1720 ConvOptions {
1721 stride: val.stride,
1722 padding: val.padding,
1723 dilation: val.dilation,
1724 groups: val.groups,
1725 }
1726 }
1727}
1728
1729impl From<Conv3dOptionsIr> for ConvOptions<3> {
1730 fn from(val: Conv3dOptionsIr) -> Self {
1731 ConvOptions {
1732 stride: val.stride,
1733 padding: val.padding.map(|padding| (padding, padding)),
1734 dilation: val.dilation,
1735 groups: val.groups,
1736 }
1737 }
1738}
1739
1740impl From<DeformableConv2dOptionsIr> for DeformConvOptions<2> {
1741 fn from(value: DeformableConv2dOptionsIr) -> Self {
1742 DeformConvOptions {
1743 stride: value.stride,
1744 padding: value.padding,
1745 dilation: value.dilation,
1746 weight_groups: value.weight_groups,
1747 offset_groups: value.offset_groups,
1748 }
1749 }
1750}
1751
1752impl From<ConvTranspose1dOptionsIr> for ConvTransposeOptions<1> {
1753 fn from(val: ConvTranspose1dOptionsIr) -> Self {
1754 ConvTransposeOptions {
1755 stride: val.stride,
1756 padding: val.padding,
1757 padding_out: val.padding_out,
1758 dilation: val.dilation,
1759 groups: val.groups,
1760 }
1761 }
1762}
1763
1764impl From<ConvTranspose2dOptionsIr> for ConvTransposeOptions<2> {
1765 fn from(val: ConvTranspose2dOptionsIr) -> Self {
1766 ConvTransposeOptions {
1767 stride: val.stride,
1768 padding: val.padding,
1769 padding_out: val.padding_out,
1770 dilation: val.dilation,
1771 groups: val.groups,
1772 }
1773 }
1774}
1775
1776impl From<ConvTranspose3dOptionsIr> for ConvTransposeOptions<3> {
1777 fn from(val: ConvTranspose3dOptionsIr) -> Self {
1778 ConvTransposeOptions {
1779 stride: val.stride,
1780 padding: val.padding,
1781 padding_out: val.padding_out,
1782 dilation: val.dilation,
1783 groups: val.groups,
1784 }
1785 }
1786}
1787
1788#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1789#[allow(missing_docs)]
1790pub struct AvgPool1dOpIr {
1791 pub x: TensorIr,
1792 pub kernel_size: usize,
1793 pub stride: usize,
1794 pub padding: usize,
1795 pub count_include_pad: bool,
1796 pub ceil_mode: bool,
1797 pub out: TensorIr,
1798}
1799
1800#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1801#[allow(missing_docs)]
1802pub struct AvgPool2dOpIr {
1803 pub x: TensorIr,
1804 pub kernel_size: [usize; 2],
1805 pub stride: [usize; 2],
1806 pub padding: [usize; 2],
1807 pub count_include_pad: bool,
1808 pub ceil_mode: bool,
1809 pub out: TensorIr,
1810}
1811
1812#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1813#[allow(missing_docs)]
1814pub struct AvgPool1dBackwardOpIr {
1815 pub x: TensorIr,
1816 pub grad: TensorIr,
1817 pub kernel_size: usize,
1818 pub stride: usize,
1819 pub padding: usize,
1820 pub count_include_pad: bool,
1821 pub ceil_mode: bool,
1822 pub out: TensorIr,
1823}
1824
1825#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1826#[allow(missing_docs)]
1827pub struct AvgPool2dBackwardOpIr {
1828 pub x: TensorIr,
1829 pub grad: TensorIr,
1830 pub kernel_size: [usize; 2],
1831 pub stride: [usize; 2],
1832 pub padding: [usize; 2],
1833 pub count_include_pad: bool,
1834 pub ceil_mode: bool,
1835 pub out: TensorIr,
1836}
1837
1838#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1839#[allow(missing_docs)]
1840pub struct AdaptiveAvgPool1dOpIr {
1841 pub x: TensorIr,
1842 pub output_size: usize,
1843 pub out: TensorIr,
1844}
1845
1846#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1847#[allow(missing_docs)]
1848pub struct AdaptiveAvgPool2dOpIr {
1849 pub x: TensorIr,
1850 pub output_size: [usize; 2],
1851 pub out: TensorIr,
1852}
1853
1854#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1855#[allow(missing_docs)]
1856pub struct AdaptiveAvgPool1dBackwardOpIr {
1857 pub x: TensorIr,
1858 pub grad: TensorIr,
1859 pub out: TensorIr,
1860}
1861
1862#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1863#[allow(missing_docs)]
1864pub struct AdaptiveAvgPool2dBackwardOpIr {
1865 pub x: TensorIr,
1866 pub grad: TensorIr,
1867 pub out: TensorIr,
1868}
1869
1870#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1871#[allow(missing_docs)]
1872pub struct AdaptiveAvgPool3dOpIr {
1873 pub x: TensorIr,
1874 pub output_size: [usize; 3],
1875 pub out: TensorIr,
1876}
1877
1878#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1879#[allow(missing_docs)]
1880pub struct AdaptiveAvgPool3dBackwardOpIr {
1881 pub x: TensorIr,
1882 pub grad: TensorIr,
1883 pub out: TensorIr,
1884}
1885
1886#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1887#[allow(missing_docs)]
1888pub struct MaxPool1dOpIr {
1889 pub x: TensorIr,
1890 pub kernel_size: usize,
1891 pub stride: usize,
1892 pub padding: usize,
1893 pub dilation: usize,
1894 pub ceil_mode: bool,
1895 pub out: TensorIr,
1896}
1897
1898#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1899#[allow(missing_docs)]
1900pub struct MaxPool1dWithIndicesOpIr {
1901 pub x: TensorIr,
1902 pub kernel_size: usize,
1903 pub stride: usize,
1904 pub padding: usize,
1905 pub dilation: usize,
1906 pub ceil_mode: bool,
1907 pub out: TensorIr,
1908 pub out_indices: TensorIr,
1909}
1910
1911#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1912#[allow(missing_docs)]
1913pub struct MaxPool1dWithIndicesBackwardOpIr {
1914 pub x: TensorIr,
1915 pub grad: TensorIr,
1916 pub indices: TensorIr,
1917 pub kernel_size: usize,
1918 pub stride: usize,
1919 pub padding: usize,
1920 pub dilation: usize,
1921 pub ceil_mode: bool,
1922 pub out: TensorIr,
1923}
1924
1925#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1926#[allow(missing_docs)]
1927pub struct MaxPool2dOpIr {
1928 pub x: TensorIr,
1929 pub kernel_size: [usize; 2],
1930 pub stride: [usize; 2],
1931 pub padding: [usize; 2],
1932 pub dilation: [usize; 2],
1933 pub ceil_mode: bool,
1934 pub out: TensorIr,
1935}
1936
1937#[allow(missing_docs)]
1938#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1939pub struct MaxPool2dWithIndicesOpIr {
1940 pub x: TensorIr,
1941 pub kernel_size: [usize; 2],
1942 pub stride: [usize; 2],
1943 pub padding: [usize; 2],
1944 pub dilation: [usize; 2],
1945 pub ceil_mode: bool,
1946 pub out: TensorIr,
1947 pub out_indices: TensorIr,
1948}
1949
1950#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1951#[allow(missing_docs)]
1952pub struct MaxPool2dWithIndicesBackwardOpIr {
1953 pub x: TensorIr,
1954 pub grad: TensorIr,
1955 pub indices: TensorIr,
1956 pub kernel_size: [usize; 2],
1957 pub stride: [usize; 2],
1958 pub padding: [usize; 2],
1959 pub dilation: [usize; 2],
1960 pub ceil_mode: bool,
1961 pub out: TensorIr,
1962}
1963
1964#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1965#[allow(missing_docs)]
1966pub enum InterpolateModeIr {
1967 Nearest,
1968 NearestExact,
1969 Bilinear,
1970 Bicubic,
1971 Lanczos3,
1972}
1973
1974#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1975#[allow(missing_docs)]
1976pub struct InterpolateOptionsIr {
1977 pub mode: InterpolateModeIr,
1978 pub align_corners: bool,
1979}
1980
1981#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1982#[allow(missing_docs)]
1983pub struct InterpolateOpIr {
1984 pub x: TensorIr,
1985 pub output_size: [usize; 2],
1986 pub options: InterpolateOptionsIr,
1987 pub out: TensorIr,
1988}
1989
1990#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
1991#[allow(missing_docs)]
1992pub struct AttentionOptionsIr {
1993 pub scale: Option<ScalarIr>,
1994 pub softcap: Option<ScalarIr>,
1995 pub is_causal: bool,
1996}
1997
1998impl From<AttentionOptionsIr> for AttentionModuleOptions {
1999 fn from(ir: AttentionOptionsIr) -> Self {
2000 AttentionModuleOptions {
2001 scale: ir.scale.map(|s| s.elem()),
2002 softcap: ir.softcap.map(|s| s.elem()),
2003 is_causal: ir.is_causal,
2004 }
2005 }
2006}
2007
2008impl From<AttentionModuleOptions> for AttentionOptionsIr {
2009 fn from(ir: AttentionModuleOptions) -> Self {
2010 AttentionOptionsIr {
2011 scale: ir.scale.map(ScalarIr::Float),
2012 softcap: ir.softcap.map(ScalarIr::Float),
2013 is_causal: ir.is_causal,
2014 }
2015 }
2016}
2017
2018#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2019#[allow(missing_docs)]
2020pub struct AttentionOpIr {
2021 pub query: TensorIr,
2022 pub key: TensorIr,
2023 pub value: TensorIr,
2024 pub mask: Option<TensorIr>,
2025 pub attn_bias: Option<TensorIr>,
2026 pub options: AttentionOptionsIr,
2027 pub out: TensorIr,
2028}
2029
2030#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2031#[allow(missing_docs)]
2032pub struct CtcLossOpIr {
2033 pub log_probs: TensorIr,
2034 pub targets: TensorIr,
2035 pub input_lengths: TensorIr,
2036 pub target_lengths: TensorIr,
2037 pub blank: usize,
2038 pub out: TensorIr,
2039}
2040
2041#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2042#[allow(missing_docs)]
2043pub struct CtcLossBackwardOpIr {
2044 pub log_probs: TensorIr,
2045 pub targets: TensorIr,
2046 pub input_lengths: TensorIr,
2047 pub target_lengths: TensorIr,
2048 pub grad_loss: TensorIr,
2049 pub blank: usize,
2050 pub out: TensorIr,
2051}
2052
2053impl From<InterpolateModeIr> for InterpolateMode {
2054 fn from(val: InterpolateModeIr) -> Self {
2055 match val {
2056 InterpolateModeIr::Nearest => Self::Nearest,
2057 InterpolateModeIr::NearestExact => Self::NearestExact,
2058 InterpolateModeIr::Bilinear => Self::Bilinear,
2059 InterpolateModeIr::Bicubic => Self::Bicubic,
2060 InterpolateModeIr::Lanczos3 => Self::Lanczos3,
2061 }
2062 }
2063}
2064
2065impl From<InterpolateOptionsIr> for InterpolateOptions {
2066 fn from(val: InterpolateOptionsIr) -> Self {
2067 Self::new(val.mode.into()).with_align_corners(val.align_corners)
2068 }
2069}
2070
2071impl From<InterpolateMode> for InterpolateModeIr {
2072 fn from(val: InterpolateMode) -> Self {
2073 match val {
2074 InterpolateMode::Nearest => Self::Nearest,
2075 InterpolateMode::NearestExact => Self::NearestExact,
2076 InterpolateMode::Bilinear => Self::Bilinear,
2077 InterpolateMode::Bicubic => Self::Bicubic,
2078 InterpolateMode::Lanczos3 => Self::Lanczos3,
2079 }
2080 }
2081}
2082
2083impl From<InterpolateOptions> for InterpolateOptionsIr {
2084 fn from(val: InterpolateOptions) -> Self {
2085 Self {
2086 mode: val.mode.into(),
2087 align_corners: val.align_corners,
2088 }
2089 }
2090}
2091
2092#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2093#[allow(missing_docs)]
2094pub struct InterpolateBackwardOpIr {
2095 pub x: TensorIr,
2096 pub grad: TensorIr,
2097 pub output_size: [usize; 2],
2098 pub options: InterpolateOptionsIr,
2099 pub out: TensorIr,
2100}
2101
2102#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2103#[allow(missing_docs)]
2104pub enum GridSamplePaddingModeIr {
2105 Zeros,
2106 Border,
2107 Reflection,
2108}
2109
2110#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2111#[allow(missing_docs)]
2112pub struct GridSampleOptionsIr {
2113 pub mode: InterpolateModeIr,
2114 pub padding_mode: GridSamplePaddingModeIr,
2115 pub align_corners: bool,
2116}
2117
2118#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
2119#[allow(missing_docs)]
2120pub struct GridSample2dOpIr {
2121 pub tensor: TensorIr,
2122 pub grid: TensorIr,
2123 pub options: GridSampleOptionsIr,
2124 pub out: TensorIr,
2125}
2126
2127impl From<GridSamplePaddingModeIr> for GridSamplePaddingMode {
2128 fn from(val: GridSamplePaddingModeIr) -> Self {
2129 match val {
2130 GridSamplePaddingModeIr::Zeros => Self::Zeros,
2131 GridSamplePaddingModeIr::Border => Self::Border,
2132 GridSamplePaddingModeIr::Reflection => Self::Reflection,
2133 }
2134 }
2135}
2136
2137impl From<GridSamplePaddingMode> for GridSamplePaddingModeIr {
2138 fn from(val: GridSamplePaddingMode) -> Self {
2139 match val {
2140 GridSamplePaddingMode::Zeros => Self::Zeros,
2141 GridSamplePaddingMode::Border => Self::Border,
2142 GridSamplePaddingMode::Reflection => Self::Reflection,
2143 }
2144 }
2145}
2146
2147impl From<GridSampleOptionsIr> for GridSampleOptions {
2148 fn from(val: GridSampleOptionsIr) -> Self {
2149 Self {
2150 mode: val.mode.into(),
2151 padding_mode: val.padding_mode.into(),
2152 align_corners: val.align_corners,
2153 }
2154 }
2155}
2156
2157impl From<GridSampleOptions> for GridSampleOptionsIr {
2158 fn from(val: GridSampleOptions) -> Self {
2159 Self {
2160 mode: val.mode.into(),
2161 padding_mode: val.padding_mode.into(),
2162 align_corners: val.align_corners,
2163 }
2164 }
2165}
2166
2167impl OperationIr {
2168 pub fn inputs(&self) -> impl Iterator<Item = &TensorIr> {
2170 match self {
2171 OperationIr::BaseFloat(repr) => repr.inputs(),
2172 OperationIr::BaseInt(repr) => repr.inputs(),
2173 OperationIr::BaseBool(repr) => repr.inputs(),
2174 OperationIr::NumericFloat(_dtype, repr) => repr.inputs(),
2175 OperationIr::NumericInt(_dtype, repr) => repr.inputs(),
2176 OperationIr::Bool(repr) => repr.inputs(),
2177 OperationIr::Int(repr) => repr.inputs(),
2178 OperationIr::Float(_dtype, repr) => repr.inputs(),
2179 OperationIr::Module(repr) => repr.inputs(),
2180 OperationIr::Init(repr) => repr.inputs(),
2181 OperationIr::Custom(repr) => repr.inputs(),
2182 OperationIr::Drop(repr) => Box::new([repr].into_iter()),
2183 OperationIr::Distributed(repr) => repr.inputs(),
2184 OperationIr::Activation(repr) => repr.inputs(),
2185 }
2186 }
2187
2188 pub fn outputs(&self) -> impl Iterator<Item = &TensorIr> {
2190 match self {
2191 OperationIr::BaseFloat(repr) => repr.outputs(),
2192 OperationIr::BaseInt(repr) => repr.outputs(),
2193 OperationIr::BaseBool(repr) => repr.outputs(),
2194 OperationIr::NumericFloat(_dtype, repr) => repr.outputs(),
2195 OperationIr::NumericInt(_dtype, repr) => repr.outputs(),
2196 OperationIr::Bool(repr) => repr.outputs(),
2197 OperationIr::Int(repr) => repr.outputs(),
2198 OperationIr::Float(_dtype, repr) => repr.outputs(),
2199 OperationIr::Module(repr) => repr.outputs(),
2200 OperationIr::Init(repr) => repr.outputs(),
2201 OperationIr::Custom(repr) => repr.outputs(),
2202 OperationIr::Drop(_repr) => Box::new([].into_iter()),
2203 OperationIr::Distributed(repr) => repr.outputs(),
2204 OperationIr::Activation(repr) => repr.outputs(),
2205 }
2206 }
2207
2208 pub fn nodes(&self) -> Vec<&TensorIr> {
2210 self.inputs().chain(self.outputs()).collect()
2211 }
2212
2213 pub fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
2218 match self {
2219 OperationIr::BaseFloat(repr) => repr.mark_read_only(nodes),
2220 OperationIr::BaseInt(repr) => repr.mark_read_only(nodes),
2221 OperationIr::BaseBool(repr) => repr.mark_read_only(nodes),
2222 OperationIr::NumericFloat(_dtype, repr) => repr.mark_read_only(nodes),
2223 OperationIr::NumericInt(_dtype, repr) => repr.mark_read_only(nodes),
2224 OperationIr::Bool(repr) => repr.mark_read_only(nodes),
2225 OperationIr::Int(repr) => repr.mark_read_only(nodes),
2226 OperationIr::Float(_dtype, repr) => repr.mark_read_only(nodes),
2227 OperationIr::Module(repr) => repr.mark_read_only(nodes),
2228 OperationIr::Init(_) => Vec::new(),
2229 OperationIr::Drop(repr) => {
2230 let mut output = Vec::new();
2231 repr.mark_read_only(nodes, &mut output);
2232 output
2233 }
2234 OperationIr::Custom(repr) => {
2235 let mut output = Vec::new();
2236
2237 for input in repr.inputs.iter_mut() {
2238 input.mark_read_only(nodes, &mut output);
2239 }
2240
2241 output
2242 }
2243 OperationIr::Distributed(repr) => repr.mark_read_only(nodes),
2244 OperationIr::Activation(repr) => repr.mark_read_only(nodes),
2245 }
2246 }
2247
2248 pub fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
2255 match self {
2256 OperationIr::BaseFloat(repr) => repr.visit_mut(v),
2257 OperationIr::BaseInt(repr) => repr.visit_mut(v),
2258 OperationIr::BaseBool(repr) => repr.visit_mut(v),
2259 OperationIr::NumericFloat(_dtype, repr) => repr.visit_mut(v),
2260 OperationIr::NumericInt(_dtype, repr) => repr.visit_mut(v),
2261 OperationIr::Bool(repr) => repr.visit_mut(v),
2262 OperationIr::Int(repr) => repr.visit_mut(v),
2263 OperationIr::Float(_dtype, repr) => repr.visit_mut(v),
2264 OperationIr::Module(repr) => repr.visit_mut(v),
2265 OperationIr::Init(repr) => repr.visit_mut(v),
2266 OperationIr::Custom(repr) => repr.visit_mut(v),
2267 OperationIr::Drop(repr) => v.visit_tensor_mut(repr),
2268 OperationIr::Distributed(repr) => repr.visit_mut(v),
2269 OperationIr::Activation(repr) => repr.visit_mut(v),
2270 }
2271 }
2272}
2273
2274impl BaseOperationIr {
2275 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
2276 match self {
2277 BaseOperationIr::Reshape(repr) => Box::new([&repr.input].into_iter()),
2278 BaseOperationIr::SwapDims(repr) => Box::new([&repr.input].into_iter()),
2279 BaseOperationIr::Permute(repr) => Box::new([&repr.input].into_iter()),
2280 BaseOperationIr::Expand(repr) => Box::new([&repr.input].into_iter()),
2281 BaseOperationIr::Flip(repr) => Box::new([&repr.input].into_iter()),
2282 BaseOperationIr::Slice(repr) => Box::new([&repr.tensor].into_iter()),
2283 BaseOperationIr::SliceAssign(repr) => Box::new([&repr.tensor, &repr.value].into_iter()),
2284 BaseOperationIr::Gather(repr) => Box::new([&repr.tensor, &repr.indices].into_iter()),
2285 BaseOperationIr::Scatter(repr) => {
2286 Box::new([&repr.tensor, &repr.indices, &repr.value].into_iter())
2287 }
2288 BaseOperationIr::ScatterNd(repr) => {
2289 Box::new([&repr.data, &repr.indices, &repr.values].into_iter())
2290 }
2291 BaseOperationIr::GatherNd(repr) => Box::new([&repr.data, &repr.indices].into_iter()),
2292 BaseOperationIr::Select(repr) => Box::new([&repr.tensor, &repr.indices].into_iter()),
2293 BaseOperationIr::SelectAssign(repr) => {
2294 Box::new([&repr.tensor, &repr.indices, &repr.value].into_iter())
2295 }
2296 BaseOperationIr::MaskWhere(repr) => {
2297 Box::new([&repr.tensor, &repr.mask, &repr.value].into_iter())
2298 }
2299 BaseOperationIr::MaskFill(repr) => Box::new([&repr.tensor, &repr.mask].into_iter()),
2300 BaseOperationIr::Equal(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2301 BaseOperationIr::EqualElem(repr) => Box::new([&repr.lhs].into_iter()),
2302 BaseOperationIr::RepeatDim(repr) => Box::new([&repr.tensor].into_iter()),
2303 BaseOperationIr::Cat(repr) => Box::new(repr.tensors.iter()),
2304 BaseOperationIr::Cast(repr) => Box::new([&repr.input].into_iter()),
2305 BaseOperationIr::Unfold(repr) => Box::new([&repr.input].into_iter()),
2306 BaseOperationIr::Empty(_repr) => Box::new([].into_iter()),
2307 BaseOperationIr::Ones(_repr) => Box::new([].into_iter()),
2308 BaseOperationIr::Zeros(_repr) => Box::new([].into_iter()),
2309 BaseOperationIr::NotEqual(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2310 BaseOperationIr::NotEqualElem(repr) => Box::new([&repr.lhs].into_iter()),
2311 BaseOperationIr::All(repr) => Box::new([&repr.input].into_iter()),
2312 BaseOperationIr::Any(repr) => Box::new([&repr.input].into_iter()),
2313 BaseOperationIr::AllDim(repr) => Box::new([&repr.input].into_iter()),
2314 BaseOperationIr::AnyDim(repr) => Box::new([&repr.input].into_iter()),
2315 }
2316 }
2317
2318 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
2319 match self {
2320 BaseOperationIr::Reshape(repr) => Box::new([&repr.out].into_iter()),
2321 BaseOperationIr::SwapDims(repr) => Box::new([&repr.out].into_iter()),
2322 BaseOperationIr::Permute(repr) => Box::new([&repr.out].into_iter()),
2323 BaseOperationIr::Expand(repr) => Box::new([&repr.out].into_iter()),
2324 BaseOperationIr::Flip(repr) => Box::new([&repr.out].into_iter()),
2325 BaseOperationIr::Slice(repr) => Box::new([&repr.out].into_iter()),
2326 BaseOperationIr::SliceAssign(repr) => Box::new([&repr.out].into_iter()),
2327 BaseOperationIr::Gather(repr) => Box::new([&repr.out].into_iter()),
2328 BaseOperationIr::Scatter(repr) => Box::new([&repr.out].into_iter()),
2329 BaseOperationIr::ScatterNd(repr) => Box::new([&repr.out].into_iter()),
2330 BaseOperationIr::GatherNd(repr) => Box::new([&repr.out].into_iter()),
2331 BaseOperationIr::Select(repr) => Box::new([&repr.out].into_iter()),
2332 BaseOperationIr::SelectAssign(repr) => Box::new([&repr.out].into_iter()),
2333 BaseOperationIr::MaskWhere(repr) => Box::new([&repr.out].into_iter()),
2334 BaseOperationIr::MaskFill(repr) => Box::new([&repr.out].into_iter()),
2335 BaseOperationIr::Equal(repr) => Box::new([&repr.out].into_iter()),
2336 BaseOperationIr::EqualElem(repr) => Box::new([&repr.out].into_iter()),
2337 BaseOperationIr::RepeatDim(repr) => Box::new([&repr.out].into_iter()),
2338 BaseOperationIr::Cat(repr) => Box::new([&repr.out].into_iter()),
2339 BaseOperationIr::Cast(repr) => Box::new([&repr.out].into_iter()),
2340 BaseOperationIr::Unfold(repr) => Box::new([&repr.out].into_iter()),
2341 BaseOperationIr::Empty(repr) => Box::new([&repr.out].into_iter()),
2342 BaseOperationIr::Ones(repr) => Box::new([&repr.out].into_iter()),
2343 BaseOperationIr::Zeros(repr) => Box::new([&repr.out].into_iter()),
2344 BaseOperationIr::NotEqual(repr) => Box::new([&repr.out].into_iter()),
2345 BaseOperationIr::NotEqualElem(repr) => Box::new([&repr.out].into_iter()),
2346 BaseOperationIr::All(repr) => Box::new([&repr.out].into_iter()),
2347 BaseOperationIr::Any(repr) => Box::new([&repr.out].into_iter()),
2348 BaseOperationIr::AllDim(repr) => Box::new([&repr.out].into_iter()),
2349 BaseOperationIr::AnyDim(repr) => Box::new([&repr.out].into_iter()),
2350 }
2351 }
2352
2353 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
2354 let mut output = Vec::new();
2355
2356 match self {
2357 BaseOperationIr::Reshape(repr) => {
2358 repr.input.mark_read_only(nodes, &mut output);
2359 }
2360 BaseOperationIr::SwapDims(repr) => {
2361 repr.input.mark_read_only(nodes, &mut output);
2362 }
2363 BaseOperationIr::Permute(repr) => {
2364 repr.input.mark_read_only(nodes, &mut output);
2365 }
2366
2367 BaseOperationIr::Expand(repr) => {
2368 repr.input.mark_read_only(nodes, &mut output);
2369 }
2370
2371 BaseOperationIr::Flip(repr) => {
2372 repr.input.mark_read_only(nodes, &mut output);
2373 }
2374 BaseOperationIr::Slice(repr) => {
2375 repr.tensor.mark_read_only(nodes, &mut output);
2376 }
2377 BaseOperationIr::SliceAssign(repr) => {
2378 repr.tensor.mark_read_only(nodes, &mut output);
2379 repr.value.mark_read_only(nodes, &mut output);
2380 }
2381 BaseOperationIr::Gather(repr) => {
2382 repr.tensor.mark_read_only(nodes, &mut output);
2383 repr.indices.mark_read_only(nodes, &mut output);
2384 }
2385 BaseOperationIr::Scatter(repr) => {
2386 repr.tensor.mark_read_only(nodes, &mut output);
2387 repr.indices.mark_read_only(nodes, &mut output);
2388 repr.value.mark_read_only(nodes, &mut output);
2389 }
2390 BaseOperationIr::ScatterNd(repr) => {
2391 repr.data.mark_read_only(nodes, &mut output);
2392 repr.indices.mark_read_only(nodes, &mut output);
2393 repr.values.mark_read_only(nodes, &mut output);
2394 }
2395 BaseOperationIr::GatherNd(repr) => {
2396 repr.data.mark_read_only(nodes, &mut output);
2397 repr.indices.mark_read_only(nodes, &mut output);
2398 }
2399 BaseOperationIr::Select(repr) => {
2400 repr.tensor.mark_read_only(nodes, &mut output);
2401 repr.indices.mark_read_only(nodes, &mut output);
2402 }
2403 BaseOperationIr::SelectAssign(repr) => {
2404 repr.tensor.mark_read_only(nodes, &mut output);
2405 repr.indices.mark_read_only(nodes, &mut output);
2406 repr.value.mark_read_only(nodes, &mut output);
2407 }
2408 BaseOperationIr::MaskWhere(repr) => {
2409 repr.tensor.mark_read_only(nodes, &mut output);
2410 repr.mask.mark_read_only(nodes, &mut output);
2411 repr.value.mark_read_only(nodes, &mut output);
2412 }
2413 BaseOperationIr::MaskFill(repr) => {
2414 repr.tensor.mark_read_only(nodes, &mut output);
2415 repr.mask.mark_read_only(nodes, &mut output);
2416 }
2417 BaseOperationIr::Equal(repr) => {
2418 repr.lhs.mark_read_only(nodes, &mut output);
2419 repr.rhs.mark_read_only(nodes, &mut output);
2420 }
2421 BaseOperationIr::EqualElem(repr) => {
2422 repr.lhs.mark_read_only(nodes, &mut output);
2423 }
2424 BaseOperationIr::RepeatDim(repr) => {
2425 repr.tensor.mark_read_only(nodes, &mut output);
2426 }
2427 BaseOperationIr::Cat(repr) => {
2428 for t in repr.tensors.iter_mut() {
2429 t.mark_read_only(nodes, &mut output);
2430 }
2431 }
2432 BaseOperationIr::Cast(repr) => {
2433 repr.input.mark_read_only(nodes, &mut output);
2434 }
2435 BaseOperationIr::Unfold(repr) => {
2436 repr.input.mark_read_only(nodes, &mut output);
2437 }
2438 BaseOperationIr::Empty(_) => {}
2439 BaseOperationIr::Zeros(_) => {}
2440 BaseOperationIr::Ones(_) => {}
2441 BaseOperationIr::NotEqual(repr) => {
2442 repr.lhs.mark_read_only(nodes, &mut output);
2443 repr.rhs.mark_read_only(nodes, &mut output);
2444 }
2445 BaseOperationIr::NotEqualElem(repr) => {
2446 repr.lhs.mark_read_only(nodes, &mut output);
2447 }
2448 BaseOperationIr::All(repr) => {
2449 repr.input.mark_read_only(nodes, &mut output);
2450 }
2451 BaseOperationIr::Any(repr) => {
2452 repr.input.mark_read_only(nodes, &mut output);
2453 }
2454 BaseOperationIr::AllDim(repr) => {
2455 repr.input.mark_read_only(nodes, &mut output);
2456 }
2457 BaseOperationIr::AnyDim(repr) => {
2458 repr.input.mark_read_only(nodes, &mut output);
2459 }
2460 };
2461
2462 output
2463 }
2464
2465 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
2466 match self {
2467 BaseOperationIr::Reshape(repr) => {
2468 v.visit_tensor_mut(&mut repr.input);
2469 v.visit_tensor_mut(&mut repr.out);
2470 }
2471 BaseOperationIr::SwapDims(repr) => {
2472 v.visit_tensor_mut(&mut repr.input);
2473 v.visit_tensor_mut(&mut repr.out);
2474 }
2475 BaseOperationIr::Permute(repr) => {
2476 v.visit_tensor_mut(&mut repr.input);
2477 v.visit_tensor_mut(&mut repr.out);
2478 }
2479 BaseOperationIr::Expand(repr) => {
2480 v.visit_tensor_mut(&mut repr.input);
2481 v.visit_tensor_mut(&mut repr.out);
2482 }
2483 BaseOperationIr::Flip(repr) => {
2484 v.visit_tensor_mut(&mut repr.input);
2485 v.visit_tensor_mut(&mut repr.out);
2486 }
2487 BaseOperationIr::Slice(repr) => {
2488 v.visit_tensor_mut(&mut repr.tensor);
2489 v.visit_tensor_mut(&mut repr.out);
2490 repr.ranges.iter_mut().for_each(|r| v.visit_range_mut(r));
2491 }
2492 BaseOperationIr::SliceAssign(repr) => {
2493 v.visit_tensor_mut(&mut repr.tensor);
2494 v.visit_tensor_mut(&mut repr.value);
2495 v.visit_tensor_mut(&mut repr.out);
2496 repr.ranges.iter_mut().for_each(|r| v.visit_range_mut(r));
2497 }
2498 BaseOperationIr::Gather(repr) => {
2499 v.visit_tensor_mut(&mut repr.tensor);
2500 v.visit_tensor_mut(&mut repr.indices);
2501 v.visit_tensor_mut(&mut repr.out);
2502 }
2503 BaseOperationIr::Scatter(repr) => {
2504 v.visit_tensor_mut(&mut repr.tensor);
2505 v.visit_tensor_mut(&mut repr.indices);
2506 v.visit_tensor_mut(&mut repr.value);
2507 v.visit_tensor_mut(&mut repr.out);
2508 }
2509 BaseOperationIr::ScatterNd(repr) => {
2510 v.visit_tensor_mut(&mut repr.data);
2511 v.visit_tensor_mut(&mut repr.indices);
2512 v.visit_tensor_mut(&mut repr.values);
2513 v.visit_tensor_mut(&mut repr.out);
2514 }
2515 BaseOperationIr::GatherNd(repr) => {
2516 v.visit_tensor_mut(&mut repr.data);
2517 v.visit_tensor_mut(&mut repr.indices);
2518 v.visit_tensor_mut(&mut repr.out);
2519 }
2520 BaseOperationIr::Select(repr) => {
2521 v.visit_tensor_mut(&mut repr.tensor);
2522 v.visit_tensor_mut(&mut repr.indices);
2523 v.visit_tensor_mut(&mut repr.out);
2524 }
2525 BaseOperationIr::SelectAssign(repr) => {
2526 v.visit_tensor_mut(&mut repr.tensor);
2527 v.visit_tensor_mut(&mut repr.indices);
2528 v.visit_tensor_mut(&mut repr.value);
2529 v.visit_tensor_mut(&mut repr.out);
2530 }
2531 BaseOperationIr::MaskWhere(repr) => {
2532 v.visit_tensor_mut(&mut repr.tensor);
2533 v.visit_tensor_mut(&mut repr.mask);
2534 v.visit_tensor_mut(&mut repr.value);
2535 v.visit_tensor_mut(&mut repr.out);
2536 }
2537 BaseOperationIr::MaskFill(repr) => {
2538 v.visit_tensor_mut(&mut repr.tensor);
2539 v.visit_tensor_mut(&mut repr.mask);
2540 v.visit_tensor_mut(&mut repr.out);
2541 v.visit_scalar_mut(&mut repr.value);
2542 }
2543 BaseOperationIr::Equal(repr) => {
2544 v.visit_tensor_mut(&mut repr.lhs);
2545 v.visit_tensor_mut(&mut repr.rhs);
2546 v.visit_tensor_mut(&mut repr.out);
2547 }
2548 BaseOperationIr::EqualElem(repr) => {
2549 v.visit_tensor_mut(&mut repr.lhs);
2550 v.visit_tensor_mut(&mut repr.out);
2551 v.visit_scalar_mut(&mut repr.rhs);
2552 }
2553 BaseOperationIr::RepeatDim(repr) => {
2554 v.visit_tensor_mut(&mut repr.tensor);
2555 v.visit_tensor_mut(&mut repr.out);
2556 }
2557 BaseOperationIr::Cat(repr) => {
2558 for t in repr.tensors.iter_mut() {
2559 v.visit_tensor_mut(t);
2560 }
2561 v.visit_tensor_mut(&mut repr.out);
2562 }
2563 BaseOperationIr::Cast(repr) => {
2564 v.visit_tensor_mut(&mut repr.input);
2565 v.visit_tensor_mut(&mut repr.out);
2566 }
2567 BaseOperationIr::Unfold(repr) => {
2568 v.visit_tensor_mut(&mut repr.input);
2569 v.visit_tensor_mut(&mut repr.out);
2570 }
2571 BaseOperationIr::Empty(repr) => {
2572 v.visit_tensor_mut(&mut repr.out);
2573 }
2574 BaseOperationIr::Ones(repr) => {
2575 v.visit_tensor_mut(&mut repr.out);
2576 }
2577 BaseOperationIr::Zeros(repr) => {
2578 v.visit_tensor_mut(&mut repr.out);
2579 }
2580 BaseOperationIr::NotEqual(repr) => {
2581 v.visit_tensor_mut(&mut repr.lhs);
2582 v.visit_tensor_mut(&mut repr.rhs);
2583 v.visit_tensor_mut(&mut repr.out);
2584 }
2585 BaseOperationIr::NotEqualElem(repr) => {
2586 v.visit_tensor_mut(&mut repr.lhs);
2587 v.visit_tensor_mut(&mut repr.out);
2588 v.visit_scalar_mut(&mut repr.rhs);
2589 }
2590 BaseOperationIr::All(repr) => {
2591 v.visit_tensor_mut(&mut repr.input);
2592 v.visit_tensor_mut(&mut repr.out);
2593 }
2594 BaseOperationIr::Any(repr) => {
2595 v.visit_tensor_mut(&mut repr.input);
2596 v.visit_tensor_mut(&mut repr.out);
2597 }
2598 BaseOperationIr::AllDim(repr) => {
2599 v.visit_tensor_mut(&mut repr.input);
2600 v.visit_tensor_mut(&mut repr.out);
2601 }
2602 BaseOperationIr::AnyDim(repr) => {
2603 v.visit_tensor_mut(&mut repr.input);
2604 v.visit_tensor_mut(&mut repr.out);
2605 }
2606 }
2607 }
2608}
2609
2610impl NumericOperationIr {
2611 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
2612 match self {
2613 NumericOperationIr::Add(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2614 NumericOperationIr::AddScalar(repr) => Box::new([&repr.lhs].into_iter()),
2615 NumericOperationIr::Sub(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2616 NumericOperationIr::SubScalar(repr) => Box::new([&repr.lhs].into_iter()),
2617 NumericOperationIr::Mul(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2618 NumericOperationIr::MulScalar(repr) => Box::new([&repr.lhs].into_iter()),
2619 NumericOperationIr::Div(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2620 NumericOperationIr::DivScalar(repr) => Box::new([&repr.lhs].into_iter()),
2621 NumericOperationIr::Rem(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2622 NumericOperationIr::RemScalar(repr) => Box::new([&repr.lhs].into_iter()),
2623 NumericOperationIr::GreaterElem(repr) => Box::new([&repr.lhs].into_iter()),
2624 NumericOperationIr::GreaterEqualElem(repr) => Box::new([&repr.lhs].into_iter()),
2625 NumericOperationIr::LowerElem(repr) => Box::new([&repr.lhs].into_iter()),
2626 NumericOperationIr::LowerEqualElem(repr) => Box::new([&repr.lhs].into_iter()),
2627 NumericOperationIr::Greater(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2628 NumericOperationIr::GreaterEqual(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2629 NumericOperationIr::Lower(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2630 NumericOperationIr::LowerEqual(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2631 NumericOperationIr::ArgMax(repr) => Box::new([&repr.input].into_iter()),
2632 NumericOperationIr::ArgTopK(repr) => Box::new([&repr.input].into_iter()),
2633 NumericOperationIr::TopK(repr) => Box::new([&repr.input].into_iter()),
2634 NumericOperationIr::ArgMin(repr) => Box::new([&repr.input].into_iter()),
2635 NumericOperationIr::Clamp(repr) => Box::new([&repr.tensor].into_iter()),
2636 NumericOperationIr::Abs(repr) => Box::new([&repr.input].into_iter()),
2637 NumericOperationIr::Full(_repr) => Box::new([].into_iter()),
2638 NumericOperationIr::MeanDim(repr) => Box::new([&repr.input].into_iter()),
2639 NumericOperationIr::Mean(repr) => Box::new([&repr.input].into_iter()),
2640 NumericOperationIr::Sum(repr) => Box::new([&repr.input].into_iter()),
2641 NumericOperationIr::SumDim(repr) => Box::new([&repr.input].into_iter()),
2642 NumericOperationIr::SumDims(repr) => Box::new([&repr.input].into_iter()),
2643 NumericOperationIr::Prod(repr) => Box::new([&repr.input].into_iter()),
2644 NumericOperationIr::ProdDim(repr) => Box::new([&repr.input].into_iter()),
2645 NumericOperationIr::Max(repr) => Box::new([&repr.input].into_iter()),
2646 NumericOperationIr::MaxDimWithIndices(repr) => Box::new([&repr.tensor].into_iter()),
2647 NumericOperationIr::TopKWithIndices(repr) => Box::new([&repr.tensor].into_iter()),
2648 NumericOperationIr::MinDimWithIndices(repr) => Box::new([&repr.tensor].into_iter()),
2649 NumericOperationIr::Min(repr) => Box::new([&repr.input].into_iter()),
2650 NumericOperationIr::MaxDim(repr) => Box::new([&repr.input].into_iter()),
2651 NumericOperationIr::MinDim(repr) => Box::new([&repr.input].into_iter()),
2652 NumericOperationIr::MaxAbs(repr) => Box::new([&repr.input].into_iter()),
2653 NumericOperationIr::MaxAbsDim(repr) => Box::new([&repr.input].into_iter()),
2654 NumericOperationIr::IntRandom(_repr) => Box::new([].into_iter()),
2655 NumericOperationIr::Powi(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
2656 NumericOperationIr::PowiScalar(repr) => Box::new([&repr.lhs].into_iter()),
2657 NumericOperationIr::CumMin(repr) => Box::new([&repr.input].into_iter()),
2658 NumericOperationIr::CumMax(repr) => Box::new([&repr.input].into_iter()),
2659 NumericOperationIr::CumProd(repr) => Box::new([&repr.input].into_iter()),
2660 NumericOperationIr::CumSum(repr) => Box::new([&repr.input].into_iter()),
2661 NumericOperationIr::Neg(repr) => Box::new([&repr.input].into_iter()),
2662 NumericOperationIr::Sign(repr) => Box::new([&repr.input].into_iter()),
2663 NumericOperationIr::ClampMin(repr) => Box::new([&repr.lhs].into_iter()),
2664 NumericOperationIr::ClampMax(repr) => Box::new([&repr.lhs].into_iter()),
2665 NumericOperationIr::Sort(repr) => Box::new([&repr.input].into_iter()),
2666 NumericOperationIr::SortWithIndices(repr) => Box::new([&repr.input].into_iter()),
2667 NumericOperationIr::ArgSort(repr) => Box::new([&repr.input].into_iter()),
2668 NumericOperationIr::Pad(repr) => Box::new([&repr.input].into_iter()),
2669 }
2670 }
2671
2672 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
2673 match self {
2674 NumericOperationIr::Add(repr) => Box::new([&repr.out].into_iter()),
2675 NumericOperationIr::AddScalar(repr) => Box::new([&repr.out].into_iter()),
2676 NumericOperationIr::Sub(repr) => Box::new([&repr.out].into_iter()),
2677 NumericOperationIr::SubScalar(repr) => Box::new([&repr.out].into_iter()),
2678 NumericOperationIr::Mul(repr) => Box::new([&repr.out].into_iter()),
2679 NumericOperationIr::MulScalar(repr) => Box::new([&repr.out].into_iter()),
2680 NumericOperationIr::Div(repr) => Box::new([&repr.out].into_iter()),
2681 NumericOperationIr::DivScalar(repr) => Box::new([&repr.out].into_iter()),
2682 NumericOperationIr::Rem(repr) => Box::new([&repr.out].into_iter()),
2683 NumericOperationIr::RemScalar(repr) => Box::new([&repr.out].into_iter()),
2684 NumericOperationIr::GreaterElem(repr) => Box::new([&repr.out].into_iter()),
2685 NumericOperationIr::GreaterEqualElem(repr) => Box::new([&repr.out].into_iter()),
2686 NumericOperationIr::LowerElem(repr) => Box::new([&repr.out].into_iter()),
2687 NumericOperationIr::LowerEqualElem(repr) => Box::new([&repr.out].into_iter()),
2688 NumericOperationIr::Greater(repr) => Box::new([&repr.out].into_iter()),
2689 NumericOperationIr::GreaterEqual(repr) => Box::new([&repr.out].into_iter()),
2690 NumericOperationIr::Lower(repr) => Box::new([&repr.out].into_iter()),
2691 NumericOperationIr::LowerEqual(repr) => Box::new([&repr.out].into_iter()),
2692 NumericOperationIr::ArgMax(repr) => Box::new([&repr.out].into_iter()),
2693 NumericOperationIr::ArgTopK(repr) => Box::new([&repr.out].into_iter()),
2694 NumericOperationIr::TopK(repr) => Box::new([&repr.out].into_iter()),
2695 NumericOperationIr::ArgMin(repr) => Box::new([&repr.out].into_iter()),
2696 NumericOperationIr::Clamp(repr) => Box::new([&repr.out].into_iter()),
2697 NumericOperationIr::Abs(repr) => Box::new([&repr.out].into_iter()),
2698 NumericOperationIr::Full(repr) => Box::new([&repr.out].into_iter()),
2699 NumericOperationIr::MeanDim(repr) => Box::new([&repr.out].into_iter()),
2700 NumericOperationIr::Mean(repr) => Box::new([&repr.out].into_iter()),
2701 NumericOperationIr::Sum(repr) => Box::new([&repr.out].into_iter()),
2702 NumericOperationIr::SumDim(repr) => Box::new([&repr.out].into_iter()),
2703 NumericOperationIr::SumDims(repr) => Box::new([&repr.out].into_iter()),
2704 NumericOperationIr::Prod(repr) => Box::new([&repr.out].into_iter()),
2705 NumericOperationIr::ProdDim(repr) => Box::new([&repr.out].into_iter()),
2706 NumericOperationIr::Max(repr) => Box::new([&repr.out].into_iter()),
2707 NumericOperationIr::MaxDimWithIndices(repr) => {
2708 Box::new([&repr.out, &repr.out_indices].into_iter())
2709 }
2710 NumericOperationIr::TopKWithIndices(repr) => {
2711 Box::new([&repr.out, &repr.out_indices].into_iter())
2712 }
2713 NumericOperationIr::MinDimWithIndices(repr) => {
2714 Box::new([&repr.out, &repr.out_indices].into_iter())
2715 }
2716 NumericOperationIr::Min(repr) => Box::new([&repr.out].into_iter()),
2717 NumericOperationIr::MaxDim(repr) => Box::new([&repr.out].into_iter()),
2718 NumericOperationIr::MinDim(repr) => Box::new([&repr.out].into_iter()),
2719 NumericOperationIr::MaxAbs(repr) => Box::new([&repr.out].into_iter()),
2720 NumericOperationIr::MaxAbsDim(repr) => Box::new([&repr.out].into_iter()),
2721 NumericOperationIr::IntRandom(repr) => Box::new([&repr.out].into_iter()),
2722 NumericOperationIr::Powi(repr) => Box::new([&repr.out].into_iter()),
2723 NumericOperationIr::PowiScalar(repr) => Box::new([&repr.out].into_iter()),
2724 NumericOperationIr::CumMin(repr) => Box::new([&repr.out].into_iter()),
2725 NumericOperationIr::CumMax(repr) => Box::new([&repr.out].into_iter()),
2726 NumericOperationIr::CumProd(repr) => Box::new([&repr.out].into_iter()),
2727 NumericOperationIr::CumSum(repr) => Box::new([&repr.out].into_iter()),
2728 NumericOperationIr::Neg(repr) => Box::new([&repr.out].into_iter()),
2729 NumericOperationIr::Sign(repr) => Box::new([&repr.out].into_iter()),
2730 NumericOperationIr::ClampMin(repr) => Box::new([&repr.out].into_iter()),
2731 NumericOperationIr::ClampMax(repr) => Box::new([&repr.out].into_iter()),
2732 NumericOperationIr::Sort(repr) => Box::new([&repr.out].into_iter()),
2733 NumericOperationIr::SortWithIndices(repr) => {
2734 Box::new([&repr.out, &repr.out_indices].into_iter())
2735 }
2736 NumericOperationIr::ArgSort(repr) => Box::new([&repr.out].into_iter()),
2737 NumericOperationIr::Pad(repr) => Box::new([&repr.out].into_iter()),
2738 }
2739 }
2740 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
2741 let mut output = Vec::new();
2742
2743 match self {
2744 NumericOperationIr::Add(repr) => {
2745 repr.lhs.mark_read_only(nodes, &mut output);
2746 repr.rhs.mark_read_only(nodes, &mut output);
2747 }
2748 NumericOperationIr::AddScalar(repr) => {
2749 repr.lhs.mark_read_only(nodes, &mut output);
2750 }
2751 NumericOperationIr::Sub(repr) => {
2752 repr.lhs.mark_read_only(nodes, &mut output);
2753 repr.rhs.mark_read_only(nodes, &mut output);
2754 }
2755 NumericOperationIr::SubScalar(repr) => {
2756 repr.lhs.mark_read_only(nodes, &mut output);
2757 }
2758 NumericOperationIr::Mul(repr) => {
2759 repr.lhs.mark_read_only(nodes, &mut output);
2760 repr.rhs.mark_read_only(nodes, &mut output);
2761 }
2762 NumericOperationIr::MulScalar(repr) => {
2763 repr.lhs.mark_read_only(nodes, &mut output);
2764 }
2765 NumericOperationIr::Div(repr) => {
2766 repr.lhs.mark_read_only(nodes, &mut output);
2767 repr.rhs.mark_read_only(nodes, &mut output);
2768 }
2769 NumericOperationIr::DivScalar(repr) => {
2770 repr.lhs.mark_read_only(nodes, &mut output);
2771 }
2772 NumericOperationIr::Rem(repr) => {
2773 repr.lhs.mark_read_only(nodes, &mut output);
2774 repr.rhs.mark_read_only(nodes, &mut output);
2775 }
2776 NumericOperationIr::RemScalar(repr) => {
2777 repr.lhs.mark_read_only(nodes, &mut output);
2778 }
2779 NumericOperationIr::GreaterElem(repr) => {
2780 repr.lhs.mark_read_only(nodes, &mut output);
2781 }
2782 NumericOperationIr::GreaterEqualElem(repr) => {
2783 repr.lhs.mark_read_only(nodes, &mut output);
2784 }
2785 NumericOperationIr::LowerElem(repr) => {
2786 repr.lhs.mark_read_only(nodes, &mut output);
2787 }
2788 NumericOperationIr::LowerEqualElem(repr) => {
2789 repr.lhs.mark_read_only(nodes, &mut output);
2790 }
2791 NumericOperationIr::Greater(repr) => {
2792 repr.lhs.mark_read_only(nodes, &mut output);
2793 repr.rhs.mark_read_only(nodes, &mut output);
2794 }
2795 NumericOperationIr::GreaterEqual(repr) => {
2796 repr.lhs.mark_read_only(nodes, &mut output);
2797 repr.rhs.mark_read_only(nodes, &mut output);
2798 }
2799 NumericOperationIr::Lower(repr) => {
2800 repr.lhs.mark_read_only(nodes, &mut output);
2801 repr.rhs.mark_read_only(nodes, &mut output);
2802 }
2803 NumericOperationIr::LowerEqual(repr) => {
2804 repr.lhs.mark_read_only(nodes, &mut output);
2805 repr.rhs.mark_read_only(nodes, &mut output);
2806 }
2807 NumericOperationIr::ArgMax(repr) => {
2808 repr.input.mark_read_only(nodes, &mut output);
2809 }
2810 NumericOperationIr::ArgTopK(repr) => {
2811 repr.input.mark_read_only(nodes, &mut output);
2812 }
2813 NumericOperationIr::TopK(repr) => {
2814 repr.input.mark_read_only(nodes, &mut output);
2815 }
2816 NumericOperationIr::ArgMin(repr) => {
2817 repr.input.mark_read_only(nodes, &mut output);
2818 }
2819 NumericOperationIr::Clamp(repr) => {
2820 repr.tensor.mark_read_only(nodes, &mut output);
2821 }
2822 NumericOperationIr::Abs(repr) => {
2823 repr.input.mark_read_only(nodes, &mut output);
2824 }
2825 NumericOperationIr::Full(_) => {}
2826 NumericOperationIr::MeanDim(repr) => {
2827 repr.input.mark_read_only(nodes, &mut output);
2828 }
2829 NumericOperationIr::Mean(repr) => {
2830 repr.input.mark_read_only(nodes, &mut output);
2831 }
2832 NumericOperationIr::Sum(repr) => {
2833 repr.input.mark_read_only(nodes, &mut output);
2834 }
2835 NumericOperationIr::SumDim(repr) => {
2836 repr.input.mark_read_only(nodes, &mut output);
2837 }
2838 NumericOperationIr::SumDims(repr) => {
2839 repr.input.mark_read_only(nodes, &mut output);
2840 }
2841 NumericOperationIr::Prod(repr) => {
2842 repr.input.mark_read_only(nodes, &mut output);
2843 }
2844 NumericOperationIr::ProdDim(repr) => {
2845 repr.input.mark_read_only(nodes, &mut output);
2846 }
2847 NumericOperationIr::Max(repr) => {
2848 repr.input.mark_read_only(nodes, &mut output);
2849 }
2850 NumericOperationIr::MaxDimWithIndices(repr) => {
2851 repr.tensor.mark_read_only(nodes, &mut output);
2852 }
2853 NumericOperationIr::TopKWithIndices(repr) => {
2854 repr.tensor.mark_read_only(nodes, &mut output);
2855 }
2856 NumericOperationIr::MinDimWithIndices(repr) => {
2857 repr.tensor.mark_read_only(nodes, &mut output);
2858 }
2859 NumericOperationIr::Min(repr) => {
2860 repr.input.mark_read_only(nodes, &mut output);
2861 }
2862 NumericOperationIr::MaxDim(repr) => {
2863 repr.input.mark_read_only(nodes, &mut output);
2864 }
2865 NumericOperationIr::MinDim(repr) => {
2866 repr.input.mark_read_only(nodes, &mut output);
2867 }
2868 NumericOperationIr::MaxAbs(repr) => {
2869 repr.input.mark_read_only(nodes, &mut output);
2870 }
2871 NumericOperationIr::MaxAbsDim(repr) => {
2872 repr.input.mark_read_only(nodes, &mut output);
2873 }
2874 NumericOperationIr::IntRandom(_) => {}
2875 NumericOperationIr::Powi(repr) => {
2876 repr.lhs.mark_read_only(nodes, &mut output);
2877 repr.rhs.mark_read_only(nodes, &mut output);
2878 }
2879 NumericOperationIr::PowiScalar(repr) => {
2880 repr.lhs.mark_read_only(nodes, &mut output);
2881 }
2882 NumericOperationIr::CumSum(repr) => {
2883 repr.input.mark_read_only(nodes, &mut output);
2884 }
2885 NumericOperationIr::CumProd(repr) => {
2886 repr.input.mark_read_only(nodes, &mut output);
2887 }
2888 NumericOperationIr::CumMin(repr) => {
2889 repr.input.mark_read_only(nodes, &mut output);
2890 }
2891 NumericOperationIr::CumMax(repr) => {
2892 repr.input.mark_read_only(nodes, &mut output);
2893 }
2894 NumericOperationIr::Neg(repr) => {
2895 repr.input.mark_read_only(nodes, &mut output);
2896 }
2897 NumericOperationIr::Sign(repr) => {
2898 repr.input.mark_read_only(nodes, &mut output);
2899 }
2900 NumericOperationIr::ClampMin(repr) => {
2901 repr.lhs.mark_read_only(nodes, &mut output);
2902 }
2903 NumericOperationIr::ClampMax(repr) => {
2904 repr.lhs.mark_read_only(nodes, &mut output);
2905 }
2906 NumericOperationIr::Sort(repr) => {
2907 repr.input.mark_read_only(nodes, &mut output);
2908 }
2909 NumericOperationIr::SortWithIndices(repr) => {
2910 repr.input.mark_read_only(nodes, &mut output);
2911 }
2912 NumericOperationIr::ArgSort(repr) => {
2913 repr.input.mark_read_only(nodes, &mut output);
2914 }
2915 NumericOperationIr::Pad(repr) => {
2916 repr.input.mark_read_only(nodes, &mut output);
2917 }
2918 };
2919
2920 output
2921 }
2922
2923 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
2924 match self {
2925 NumericOperationIr::Add(repr) => {
2926 v.visit_tensor_mut(&mut repr.lhs);
2927 v.visit_tensor_mut(&mut repr.rhs);
2928 v.visit_tensor_mut(&mut repr.out);
2929 }
2930 NumericOperationIr::AddScalar(repr) => {
2931 v.visit_tensor_mut(&mut repr.lhs);
2932 v.visit_tensor_mut(&mut repr.out);
2933 v.visit_scalar_mut(&mut repr.rhs);
2934 }
2935 NumericOperationIr::Sub(repr) => {
2936 v.visit_tensor_mut(&mut repr.lhs);
2937 v.visit_tensor_mut(&mut repr.rhs);
2938 v.visit_tensor_mut(&mut repr.out);
2939 }
2940 NumericOperationIr::SubScalar(repr) => {
2941 v.visit_tensor_mut(&mut repr.lhs);
2942 v.visit_tensor_mut(&mut repr.out);
2943 v.visit_scalar_mut(&mut repr.rhs);
2944 }
2945 NumericOperationIr::Mul(repr) => {
2946 v.visit_tensor_mut(&mut repr.lhs);
2947 v.visit_tensor_mut(&mut repr.rhs);
2948 v.visit_tensor_mut(&mut repr.out);
2949 }
2950 NumericOperationIr::MulScalar(repr) => {
2951 v.visit_tensor_mut(&mut repr.lhs);
2952 v.visit_tensor_mut(&mut repr.out);
2953 v.visit_scalar_mut(&mut repr.rhs);
2954 }
2955 NumericOperationIr::Div(repr) => {
2956 v.visit_tensor_mut(&mut repr.lhs);
2957 v.visit_tensor_mut(&mut repr.rhs);
2958 v.visit_tensor_mut(&mut repr.out);
2959 }
2960 NumericOperationIr::DivScalar(repr) => {
2961 v.visit_tensor_mut(&mut repr.lhs);
2962 v.visit_tensor_mut(&mut repr.out);
2963 v.visit_scalar_mut(&mut repr.rhs);
2964 }
2965 NumericOperationIr::Rem(repr) => {
2966 v.visit_tensor_mut(&mut repr.lhs);
2967 v.visit_tensor_mut(&mut repr.rhs);
2968 v.visit_tensor_mut(&mut repr.out);
2969 }
2970 NumericOperationIr::RemScalar(repr) => {
2971 v.visit_tensor_mut(&mut repr.lhs);
2972 v.visit_tensor_mut(&mut repr.out);
2973 v.visit_scalar_mut(&mut repr.rhs);
2974 }
2975 NumericOperationIr::GreaterElem(repr) => {
2976 v.visit_tensor_mut(&mut repr.lhs);
2977 v.visit_tensor_mut(&mut repr.out);
2978 v.visit_scalar_mut(&mut repr.rhs);
2979 }
2980 NumericOperationIr::GreaterEqualElem(repr) => {
2981 v.visit_tensor_mut(&mut repr.lhs);
2982 v.visit_tensor_mut(&mut repr.out);
2983 v.visit_scalar_mut(&mut repr.rhs);
2984 }
2985 NumericOperationIr::LowerElem(repr) => {
2986 v.visit_tensor_mut(&mut repr.lhs);
2987 v.visit_tensor_mut(&mut repr.out);
2988 v.visit_scalar_mut(&mut repr.rhs);
2989 }
2990 NumericOperationIr::LowerEqualElem(repr) => {
2991 v.visit_tensor_mut(&mut repr.lhs);
2992 v.visit_tensor_mut(&mut repr.out);
2993 v.visit_scalar_mut(&mut repr.rhs);
2994 }
2995 NumericOperationIr::Greater(repr) => {
2996 v.visit_tensor_mut(&mut repr.lhs);
2997 v.visit_tensor_mut(&mut repr.rhs);
2998 v.visit_tensor_mut(&mut repr.out);
2999 }
3000 NumericOperationIr::GreaterEqual(repr) => {
3001 v.visit_tensor_mut(&mut repr.lhs);
3002 v.visit_tensor_mut(&mut repr.rhs);
3003 v.visit_tensor_mut(&mut repr.out);
3004 }
3005 NumericOperationIr::Lower(repr) => {
3006 v.visit_tensor_mut(&mut repr.lhs);
3007 v.visit_tensor_mut(&mut repr.rhs);
3008 v.visit_tensor_mut(&mut repr.out);
3009 }
3010 NumericOperationIr::LowerEqual(repr) => {
3011 v.visit_tensor_mut(&mut repr.lhs);
3012 v.visit_tensor_mut(&mut repr.rhs);
3013 v.visit_tensor_mut(&mut repr.out);
3014 }
3015 NumericOperationIr::ArgMax(repr) => {
3016 v.visit_tensor_mut(&mut repr.input);
3017 v.visit_tensor_mut(&mut repr.out);
3018 }
3019 NumericOperationIr::ArgTopK(repr) => {
3020 v.visit_tensor_mut(&mut repr.input);
3021 v.visit_tensor_mut(&mut repr.out);
3022 }
3023 NumericOperationIr::TopK(repr) => {
3024 v.visit_tensor_mut(&mut repr.input);
3025 v.visit_tensor_mut(&mut repr.out);
3026 }
3027 NumericOperationIr::ArgMin(repr) => {
3028 v.visit_tensor_mut(&mut repr.input);
3029 v.visit_tensor_mut(&mut repr.out);
3030 }
3031 NumericOperationIr::Clamp(repr) => {
3032 v.visit_tensor_mut(&mut repr.tensor);
3033 v.visit_tensor_mut(&mut repr.out);
3034 v.visit_scalar_mut(&mut repr.min);
3035 v.visit_scalar_mut(&mut repr.max);
3036 }
3037 NumericOperationIr::Abs(repr) => {
3038 v.visit_tensor_mut(&mut repr.input);
3039 v.visit_tensor_mut(&mut repr.out);
3040 }
3041 NumericOperationIr::Full(repr) => {
3042 v.visit_tensor_mut(&mut repr.out);
3043 v.visit_scalar_mut(&mut repr.value);
3044 }
3045 NumericOperationIr::MeanDim(repr) => {
3046 v.visit_tensor_mut(&mut repr.input);
3047 v.visit_tensor_mut(&mut repr.out);
3048 }
3049 NumericOperationIr::Mean(repr) => {
3050 v.visit_tensor_mut(&mut repr.input);
3051 v.visit_tensor_mut(&mut repr.out);
3052 }
3053 NumericOperationIr::Sum(repr) => {
3054 v.visit_tensor_mut(&mut repr.input);
3055 v.visit_tensor_mut(&mut repr.out);
3056 }
3057 NumericOperationIr::SumDim(repr) => {
3058 v.visit_tensor_mut(&mut repr.input);
3059 v.visit_tensor_mut(&mut repr.out);
3060 }
3061 NumericOperationIr::SumDims(repr) => {
3062 v.visit_tensor_mut(&mut repr.input);
3063 v.visit_tensor_mut(&mut repr.out);
3064 }
3065 NumericOperationIr::Prod(repr) => {
3066 v.visit_tensor_mut(&mut repr.input);
3067 v.visit_tensor_mut(&mut repr.out);
3068 }
3069 NumericOperationIr::ProdDim(repr) => {
3070 v.visit_tensor_mut(&mut repr.input);
3071 v.visit_tensor_mut(&mut repr.out);
3072 }
3073 NumericOperationIr::Max(repr) => {
3074 v.visit_tensor_mut(&mut repr.input);
3075 v.visit_tensor_mut(&mut repr.out);
3076 }
3077 NumericOperationIr::MaxDimWithIndices(repr) => {
3078 v.visit_tensor_mut(&mut repr.tensor);
3079 v.visit_tensor_mut(&mut repr.out);
3080 v.visit_tensor_mut(&mut repr.out_indices);
3081 }
3082 NumericOperationIr::TopKWithIndices(repr) => {
3083 v.visit_tensor_mut(&mut repr.tensor);
3084 v.visit_tensor_mut(&mut repr.out);
3085 v.visit_tensor_mut(&mut repr.out_indices);
3086 }
3087 NumericOperationIr::MinDimWithIndices(repr) => {
3088 v.visit_tensor_mut(&mut repr.tensor);
3089 v.visit_tensor_mut(&mut repr.out);
3090 v.visit_tensor_mut(&mut repr.out_indices);
3091 }
3092 NumericOperationIr::Min(repr) => {
3093 v.visit_tensor_mut(&mut repr.input);
3094 v.visit_tensor_mut(&mut repr.out);
3095 }
3096 NumericOperationIr::MaxDim(repr) => {
3097 v.visit_tensor_mut(&mut repr.input);
3098 v.visit_tensor_mut(&mut repr.out);
3099 }
3100 NumericOperationIr::MinDim(repr) => {
3101 v.visit_tensor_mut(&mut repr.input);
3102 v.visit_tensor_mut(&mut repr.out);
3103 }
3104 NumericOperationIr::MaxAbs(repr) => {
3105 v.visit_tensor_mut(&mut repr.input);
3106 v.visit_tensor_mut(&mut repr.out);
3107 }
3108 NumericOperationIr::MaxAbsDim(repr) => {
3109 v.visit_tensor_mut(&mut repr.input);
3110 v.visit_tensor_mut(&mut repr.out);
3111 }
3112 NumericOperationIr::IntRandom(repr) => {
3113 v.visit_tensor_mut(&mut repr.out);
3114 }
3115 NumericOperationIr::Powi(repr) => {
3116 v.visit_tensor_mut(&mut repr.lhs);
3117 v.visit_tensor_mut(&mut repr.rhs);
3118 v.visit_tensor_mut(&mut repr.out);
3119 }
3120 NumericOperationIr::PowiScalar(repr) => {
3121 v.visit_tensor_mut(&mut repr.lhs);
3122 v.visit_tensor_mut(&mut repr.out);
3123 v.visit_scalar_mut(&mut repr.rhs);
3124 }
3125 NumericOperationIr::CumMin(repr) => {
3126 v.visit_tensor_mut(&mut repr.input);
3127 v.visit_tensor_mut(&mut repr.out);
3128 }
3129 NumericOperationIr::CumMax(repr) => {
3130 v.visit_tensor_mut(&mut repr.input);
3131 v.visit_tensor_mut(&mut repr.out);
3132 }
3133 NumericOperationIr::CumProd(repr) => {
3134 v.visit_tensor_mut(&mut repr.input);
3135 v.visit_tensor_mut(&mut repr.out);
3136 }
3137 NumericOperationIr::CumSum(repr) => {
3138 v.visit_tensor_mut(&mut repr.input);
3139 v.visit_tensor_mut(&mut repr.out);
3140 }
3141 NumericOperationIr::Neg(repr) => {
3142 v.visit_tensor_mut(&mut repr.input);
3143 v.visit_tensor_mut(&mut repr.out);
3144 }
3145 NumericOperationIr::Sign(repr) => {
3146 v.visit_tensor_mut(&mut repr.input);
3147 v.visit_tensor_mut(&mut repr.out);
3148 }
3149 NumericOperationIr::ClampMin(repr) => {
3150 v.visit_tensor_mut(&mut repr.lhs);
3151 v.visit_tensor_mut(&mut repr.out);
3152 v.visit_scalar_mut(&mut repr.rhs);
3153 }
3154 NumericOperationIr::ClampMax(repr) => {
3155 v.visit_tensor_mut(&mut repr.lhs);
3156 v.visit_tensor_mut(&mut repr.out);
3157 v.visit_scalar_mut(&mut repr.rhs);
3158 }
3159 NumericOperationIr::Sort(repr) => {
3160 v.visit_tensor_mut(&mut repr.input);
3161 v.visit_tensor_mut(&mut repr.out);
3162 }
3163 NumericOperationIr::SortWithIndices(repr) => {
3164 v.visit_tensor_mut(&mut repr.input);
3165 v.visit_tensor_mut(&mut repr.out);
3166 v.visit_tensor_mut(&mut repr.out_indices);
3167 }
3168 NumericOperationIr::ArgSort(repr) => {
3169 v.visit_tensor_mut(&mut repr.input);
3170 v.visit_tensor_mut(&mut repr.out);
3171 }
3172 NumericOperationIr::Pad(repr) => {
3173 v.visit_tensor_mut(&mut repr.input);
3174 v.visit_tensor_mut(&mut repr.out);
3175 if let PadModeIr::Constant(value) = &mut repr.mode {
3176 v.visit_scalar_mut(value);
3177 }
3178 }
3179 }
3180 }
3181}
3182
3183impl FloatOperationIr {
3184 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3185 match self {
3186 FloatOperationIr::Matmul(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3187 FloatOperationIr::Cross(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3188 FloatOperationIr::Random(_repr) => Box::new([].into_iter()),
3189 FloatOperationIr::Exp(repr) => Box::new([&repr.input].into_iter()),
3190 FloatOperationIr::Log(repr) => Box::new([&repr.input].into_iter()),
3191 FloatOperationIr::Log1p(repr) => Box::new([&repr.input].into_iter()),
3192 FloatOperationIr::Erf(repr) => Box::new([&repr.input].into_iter()),
3193 FloatOperationIr::Recip(repr) => Box::new([&repr.input].into_iter()),
3194 FloatOperationIr::PowfScalar(repr) => Box::new([&repr.lhs].into_iter()),
3195 FloatOperationIr::Sqrt(repr) => Box::new([&repr.input].into_iter()),
3196 FloatOperationIr::Cos(repr) => Box::new([&repr.input].into_iter()),
3197 FloatOperationIr::Sin(repr) => Box::new([&repr.input].into_iter()),
3198 FloatOperationIr::Tanh(repr) => Box::new([&repr.input].into_iter()),
3199 FloatOperationIr::Round(repr) => Box::new([&repr.input].into_iter()),
3200 FloatOperationIr::Floor(repr) => Box::new([&repr.input].into_iter()),
3201 FloatOperationIr::Ceil(repr) => Box::new([&repr.input].into_iter()),
3202 FloatOperationIr::Trunc(repr) => Box::new([&repr.input].into_iter()),
3203 FloatOperationIr::IntoInt(repr) => Box::new([&repr.input].into_iter()),
3204 FloatOperationIr::Quantize(repr) => Box::new(
3205 [&repr.tensor, &repr.qparams.scales]
3206 .into_iter()
3207 .chain(repr.qparams.global.iter()),
3208 ),
3209 FloatOperationIr::Dequantize(repr) => Box::new([&repr.input].into_iter()),
3210 FloatOperationIr::IsNan(repr) => Box::new([&repr.input].into_iter()),
3211 FloatOperationIr::IsInf(repr) => Box::new([&repr.input].into_iter()),
3212 FloatOperationIr::GridSample2d(repr) => {
3213 Box::new([&repr.tensor, &repr.grid].into_iter())
3214 }
3215 FloatOperationIr::Tan(repr) => Box::new([&repr.input].into_iter()),
3216 FloatOperationIr::Cosh(repr) => Box::new([&repr.input].into_iter()),
3217 FloatOperationIr::Sinh(repr) => Box::new([&repr.input].into_iter()),
3218 FloatOperationIr::ArcCos(repr) => Box::new([&repr.input].into_iter()),
3219 FloatOperationIr::ArcCosh(repr) => Box::new([&repr.input].into_iter()),
3220 FloatOperationIr::ArcSin(repr) => Box::new([&repr.input].into_iter()),
3221 FloatOperationIr::ArcSinh(repr) => Box::new([&repr.input].into_iter()),
3222 FloatOperationIr::ArcTan(repr) => Box::new([&repr.input].into_iter()),
3223 FloatOperationIr::ArcTanh(repr) => Box::new([&repr.input].into_iter()),
3224 FloatOperationIr::ArcTan2(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3225 FloatOperationIr::Powf(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3226 FloatOperationIr::Hypot(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3227 }
3228 }
3229 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3230 match self {
3231 FloatOperationIr::Matmul(repr) => Box::new([&repr.out].into_iter()),
3232 FloatOperationIr::Cross(repr) => Box::new([&repr.out].into_iter()),
3233 FloatOperationIr::Random(repr) => Box::new([&repr.out].into_iter()),
3234 FloatOperationIr::Exp(repr) => Box::new([&repr.out].into_iter()),
3235 FloatOperationIr::Log(repr) => Box::new([&repr.out].into_iter()),
3236 FloatOperationIr::Log1p(repr) => Box::new([&repr.out].into_iter()),
3237 FloatOperationIr::Erf(repr) => Box::new([&repr.out].into_iter()),
3238 FloatOperationIr::Recip(repr) => Box::new([&repr.out].into_iter()),
3239 FloatOperationIr::PowfScalar(repr) => Box::new([&repr.out].into_iter()),
3240 FloatOperationIr::Sqrt(repr) => Box::new([&repr.out].into_iter()),
3241 FloatOperationIr::Cos(repr) => Box::new([&repr.out].into_iter()),
3242 FloatOperationIr::Sin(repr) => Box::new([&repr.out].into_iter()),
3243 FloatOperationIr::Tanh(repr) => Box::new([&repr.out].into_iter()),
3244 FloatOperationIr::Round(repr) => Box::new([&repr.out].into_iter()),
3245 FloatOperationIr::Floor(repr) => Box::new([&repr.out].into_iter()),
3246 FloatOperationIr::Ceil(repr) => Box::new([&repr.out].into_iter()),
3247 FloatOperationIr::Trunc(repr) => Box::new([&repr.out].into_iter()),
3248 FloatOperationIr::IntoInt(repr) => Box::new([&repr.out].into_iter()),
3249 FloatOperationIr::Quantize(repr) => Box::new([&repr.out].into_iter()),
3250 FloatOperationIr::Dequantize(repr) => Box::new([&repr.out].into_iter()),
3251 FloatOperationIr::IsNan(repr) => Box::new([&repr.out].into_iter()),
3252 FloatOperationIr::IsInf(repr) => Box::new([&repr.out].into_iter()),
3253 FloatOperationIr::GridSample2d(repr) => Box::new([&repr.out].into_iter()),
3254 FloatOperationIr::Tan(repr) => Box::new([&repr.out].into_iter()),
3255 FloatOperationIr::Cosh(repr) => Box::new([&repr.out].into_iter()),
3256 FloatOperationIr::Sinh(repr) => Box::new([&repr.out].into_iter()),
3257 FloatOperationIr::ArcCos(repr) => Box::new([&repr.out].into_iter()),
3258 FloatOperationIr::ArcCosh(repr) => Box::new([&repr.out].into_iter()),
3259 FloatOperationIr::ArcSin(repr) => Box::new([&repr.out].into_iter()),
3260 FloatOperationIr::ArcSinh(repr) => Box::new([&repr.out].into_iter()),
3261 FloatOperationIr::ArcTan(repr) => Box::new([&repr.out].into_iter()),
3262 FloatOperationIr::ArcTanh(repr) => Box::new([&repr.out].into_iter()),
3263 FloatOperationIr::ArcTan2(repr) => Box::new([&repr.out].into_iter()),
3264 FloatOperationIr::Powf(repr) => Box::new([&repr.out].into_iter()),
3265 FloatOperationIr::Hypot(repr) => Box::new([&repr.out].into_iter()),
3266 }
3267 }
3268
3269 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
3270 let mut output = Vec::new();
3271
3272 match self {
3273 FloatOperationIr::Matmul(repr) => {
3274 repr.lhs.mark_read_only(nodes, &mut output);
3275 repr.rhs.mark_read_only(nodes, &mut output);
3276 }
3277 FloatOperationIr::Cross(repr) => {
3278 repr.lhs.mark_read_only(nodes, &mut output);
3279 repr.rhs.mark_read_only(nodes, &mut output);
3280 }
3281 FloatOperationIr::Random(_) => {}
3282 FloatOperationIr::Exp(repr) => {
3283 repr.input.mark_read_only(nodes, &mut output);
3284 }
3285 FloatOperationIr::Log(repr) => {
3286 repr.input.mark_read_only(nodes, &mut output);
3287 }
3288 FloatOperationIr::Log1p(repr) => {
3289 repr.input.mark_read_only(nodes, &mut output);
3290 }
3291 FloatOperationIr::Erf(repr) => {
3292 repr.input.mark_read_only(nodes, &mut output);
3293 }
3294 FloatOperationIr::Recip(repr) => {
3295 repr.input.mark_read_only(nodes, &mut output);
3296 }
3297 FloatOperationIr::PowfScalar(repr) => {
3298 repr.lhs.mark_read_only(nodes, &mut output);
3299 }
3300 FloatOperationIr::Sqrt(repr) => {
3301 repr.input.mark_read_only(nodes, &mut output);
3302 }
3303 FloatOperationIr::Cos(repr) => {
3304 repr.input.mark_read_only(nodes, &mut output);
3305 }
3306 FloatOperationIr::Sin(repr) => {
3307 repr.input.mark_read_only(nodes, &mut output);
3308 }
3309 FloatOperationIr::Tanh(repr) => {
3310 repr.input.mark_read_only(nodes, &mut output);
3311 }
3312 FloatOperationIr::Round(repr) => {
3313 repr.input.mark_read_only(nodes, &mut output);
3314 }
3315 FloatOperationIr::Floor(repr) => {
3316 repr.input.mark_read_only(nodes, &mut output);
3317 }
3318 FloatOperationIr::Ceil(repr) => {
3319 repr.input.mark_read_only(nodes, &mut output);
3320 }
3321 FloatOperationIr::Trunc(repr) => {
3322 repr.input.mark_read_only(nodes, &mut output);
3323 }
3324 FloatOperationIr::Quantize(repr) => {
3325 repr.tensor.mark_read_only(nodes, &mut output);
3326 repr.qparams.scales.mark_read_only(nodes, &mut output);
3327 if let Some(global) = &mut repr.qparams.global {
3328 global.mark_read_only(nodes, &mut output);
3329 }
3330 }
3331 FloatOperationIr::Dequantize(repr) => {
3332 repr.input.mark_read_only(nodes, &mut output);
3333 }
3334 FloatOperationIr::IntoInt(repr) => {
3335 repr.input.mark_read_only(nodes, &mut output);
3336 }
3337 FloatOperationIr::IsNan(repr) => {
3338 repr.input.mark_read_only(nodes, &mut output);
3339 }
3340 FloatOperationIr::IsInf(repr) => {
3341 repr.input.mark_read_only(nodes, &mut output);
3342 }
3343 FloatOperationIr::GridSample2d(repr) => {
3344 repr.tensor.mark_read_only(nodes, &mut output);
3345 repr.grid.mark_read_only(nodes, &mut output);
3346 }
3347 FloatOperationIr::Tan(repr) => repr.input.mark_read_only(nodes, &mut output),
3348 FloatOperationIr::Cosh(repr) => repr.input.mark_read_only(nodes, &mut output),
3349 FloatOperationIr::Sinh(repr) => repr.input.mark_read_only(nodes, &mut output),
3350 FloatOperationIr::ArcCos(repr) => repr.input.mark_read_only(nodes, &mut output),
3351 FloatOperationIr::ArcCosh(repr) => repr.input.mark_read_only(nodes, &mut output),
3352 FloatOperationIr::ArcSin(repr) => repr.input.mark_read_only(nodes, &mut output),
3353 FloatOperationIr::ArcSinh(repr) => repr.input.mark_read_only(nodes, &mut output),
3354 FloatOperationIr::ArcTan(repr) => repr.input.mark_read_only(nodes, &mut output),
3355 FloatOperationIr::ArcTanh(repr) => repr.input.mark_read_only(nodes, &mut output),
3356 FloatOperationIr::ArcTan2(repr) => {
3357 repr.lhs.mark_read_only(nodes, &mut output);
3358 repr.rhs.mark_read_only(nodes, &mut output);
3359 }
3360 FloatOperationIr::Powf(repr) => {
3361 repr.lhs.mark_read_only(nodes, &mut output);
3362 repr.rhs.mark_read_only(nodes, &mut output);
3363 }
3364 FloatOperationIr::Hypot(repr) => {
3365 repr.lhs.mark_read_only(nodes, &mut output);
3366 repr.rhs.mark_read_only(nodes, &mut output);
3367 }
3368 };
3369
3370 output
3371 }
3372
3373 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
3374 match self {
3375 FloatOperationIr::Matmul(repr) => {
3376 v.visit_tensor_mut(&mut repr.lhs);
3377 v.visit_tensor_mut(&mut repr.rhs);
3378 v.visit_tensor_mut(&mut repr.out);
3379 }
3380 FloatOperationIr::Cross(repr) => {
3381 v.visit_tensor_mut(&mut repr.lhs);
3382 v.visit_tensor_mut(&mut repr.rhs);
3383 v.visit_tensor_mut(&mut repr.out);
3384 }
3385 FloatOperationIr::Random(repr) => {
3386 v.visit_tensor_mut(&mut repr.out);
3387 }
3388 FloatOperationIr::Exp(repr) => {
3389 v.visit_tensor_mut(&mut repr.input);
3390 v.visit_tensor_mut(&mut repr.out);
3391 }
3392 FloatOperationIr::Log(repr) => {
3393 v.visit_tensor_mut(&mut repr.input);
3394 v.visit_tensor_mut(&mut repr.out);
3395 }
3396 FloatOperationIr::Log1p(repr) => {
3397 v.visit_tensor_mut(&mut repr.input);
3398 v.visit_tensor_mut(&mut repr.out);
3399 }
3400 FloatOperationIr::Erf(repr) => {
3401 v.visit_tensor_mut(&mut repr.input);
3402 v.visit_tensor_mut(&mut repr.out);
3403 }
3404 FloatOperationIr::Recip(repr) => {
3405 v.visit_tensor_mut(&mut repr.input);
3406 v.visit_tensor_mut(&mut repr.out);
3407 }
3408 FloatOperationIr::PowfScalar(repr) => {
3409 v.visit_tensor_mut(&mut repr.lhs);
3410 v.visit_tensor_mut(&mut repr.out);
3411 v.visit_scalar_mut(&mut repr.rhs);
3412 }
3413 FloatOperationIr::Sqrt(repr) => {
3414 v.visit_tensor_mut(&mut repr.input);
3415 v.visit_tensor_mut(&mut repr.out);
3416 }
3417 FloatOperationIr::Cos(repr) => {
3418 v.visit_tensor_mut(&mut repr.input);
3419 v.visit_tensor_mut(&mut repr.out);
3420 }
3421 FloatOperationIr::Sin(repr) => {
3422 v.visit_tensor_mut(&mut repr.input);
3423 v.visit_tensor_mut(&mut repr.out);
3424 }
3425 FloatOperationIr::Tanh(repr) => {
3426 v.visit_tensor_mut(&mut repr.input);
3427 v.visit_tensor_mut(&mut repr.out);
3428 }
3429 FloatOperationIr::Round(repr) => {
3430 v.visit_tensor_mut(&mut repr.input);
3431 v.visit_tensor_mut(&mut repr.out);
3432 }
3433 FloatOperationIr::Floor(repr) => {
3434 v.visit_tensor_mut(&mut repr.input);
3435 v.visit_tensor_mut(&mut repr.out);
3436 }
3437 FloatOperationIr::Ceil(repr) => {
3438 v.visit_tensor_mut(&mut repr.input);
3439 v.visit_tensor_mut(&mut repr.out);
3440 }
3441 FloatOperationIr::Trunc(repr) => {
3442 v.visit_tensor_mut(&mut repr.input);
3443 v.visit_tensor_mut(&mut repr.out);
3444 }
3445 FloatOperationIr::IntoInt(repr) => {
3446 v.visit_tensor_mut(&mut repr.input);
3447 v.visit_tensor_mut(&mut repr.out);
3448 }
3449 FloatOperationIr::Quantize(repr) => {
3450 v.visit_tensor_mut(&mut repr.tensor);
3451 v.visit_tensor_mut(&mut repr.qparams.scales);
3452 if let Some(global) = &mut repr.qparams.global {
3453 v.visit_tensor_mut(global);
3454 }
3455 v.visit_tensor_mut(&mut repr.out);
3456 }
3457 FloatOperationIr::Dequantize(repr) => {
3458 v.visit_tensor_mut(&mut repr.input);
3459 v.visit_tensor_mut(&mut repr.out);
3460 }
3461 FloatOperationIr::IsNan(repr) => {
3462 v.visit_tensor_mut(&mut repr.input);
3463 v.visit_tensor_mut(&mut repr.out);
3464 }
3465 FloatOperationIr::IsInf(repr) => {
3466 v.visit_tensor_mut(&mut repr.input);
3467 v.visit_tensor_mut(&mut repr.out);
3468 }
3469 FloatOperationIr::GridSample2d(repr) => {
3470 v.visit_tensor_mut(&mut repr.tensor);
3471 v.visit_tensor_mut(&mut repr.grid);
3472 v.visit_tensor_mut(&mut repr.out);
3473 }
3474 FloatOperationIr::Tan(repr) => {
3475 v.visit_tensor_mut(&mut repr.input);
3476 v.visit_tensor_mut(&mut repr.out);
3477 }
3478 FloatOperationIr::Cosh(repr) => {
3479 v.visit_tensor_mut(&mut repr.input);
3480 v.visit_tensor_mut(&mut repr.out);
3481 }
3482 FloatOperationIr::Sinh(repr) => {
3483 v.visit_tensor_mut(&mut repr.input);
3484 v.visit_tensor_mut(&mut repr.out);
3485 }
3486 FloatOperationIr::ArcCos(repr) => {
3487 v.visit_tensor_mut(&mut repr.input);
3488 v.visit_tensor_mut(&mut repr.out);
3489 }
3490 FloatOperationIr::ArcCosh(repr) => {
3491 v.visit_tensor_mut(&mut repr.input);
3492 v.visit_tensor_mut(&mut repr.out);
3493 }
3494 FloatOperationIr::ArcSin(repr) => {
3495 v.visit_tensor_mut(&mut repr.input);
3496 v.visit_tensor_mut(&mut repr.out);
3497 }
3498 FloatOperationIr::ArcSinh(repr) => {
3499 v.visit_tensor_mut(&mut repr.input);
3500 v.visit_tensor_mut(&mut repr.out);
3501 }
3502 FloatOperationIr::ArcTan(repr) => {
3503 v.visit_tensor_mut(&mut repr.input);
3504 v.visit_tensor_mut(&mut repr.out);
3505 }
3506 FloatOperationIr::ArcTanh(repr) => {
3507 v.visit_tensor_mut(&mut repr.input);
3508 v.visit_tensor_mut(&mut repr.out);
3509 }
3510 FloatOperationIr::ArcTan2(repr) => {
3511 v.visit_tensor_mut(&mut repr.lhs);
3512 v.visit_tensor_mut(&mut repr.rhs);
3513 v.visit_tensor_mut(&mut repr.out);
3514 }
3515 FloatOperationIr::Powf(repr) => {
3516 v.visit_tensor_mut(&mut repr.lhs);
3517 v.visit_tensor_mut(&mut repr.rhs);
3518 v.visit_tensor_mut(&mut repr.out);
3519 }
3520 FloatOperationIr::Hypot(repr) => {
3521 v.visit_tensor_mut(&mut repr.lhs);
3522 v.visit_tensor_mut(&mut repr.rhs);
3523 v.visit_tensor_mut(&mut repr.out);
3524 }
3525 }
3526 }
3527}
3528
3529impl IntOperationIr {
3530 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3531 match self {
3532 IntOperationIr::Matmul(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3533 IntOperationIr::IntoFloat(repr) => Box::new([&repr.input].into_iter()),
3534 IntOperationIr::BitwiseAnd(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3535 IntOperationIr::BitwiseAndScalar(repr) => Box::new([&repr.lhs].into_iter()),
3536 IntOperationIr::BitwiseOr(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3537 IntOperationIr::BitwiseOrScalar(repr) => Box::new([&repr.lhs].into_iter()),
3538 IntOperationIr::BitwiseXor(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3539 IntOperationIr::BitwiseXorScalar(repr) => Box::new([&repr.lhs].into_iter()),
3540 IntOperationIr::BitwiseNot(repr) => Box::new([&repr.input].into_iter()),
3541 IntOperationIr::BitwiseLeftShift(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3542 IntOperationIr::BitwiseLeftShiftScalar(repr) => Box::new([&repr.lhs].into_iter()),
3543 IntOperationIr::BitwiseRightShift(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3544 IntOperationIr::BitwiseRightShiftScalar(repr) => Box::new([&repr.lhs].into_iter()),
3545 }
3546 }
3547
3548 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3549 match self {
3550 IntOperationIr::Matmul(repr) => Box::new([&repr.out].into_iter()),
3551 IntOperationIr::IntoFloat(repr) => Box::new([&repr.out].into_iter()),
3552 IntOperationIr::BitwiseAnd(repr) => Box::new([&repr.out].into_iter()),
3553 IntOperationIr::BitwiseAndScalar(repr) => Box::new([&repr.out].into_iter()),
3554 IntOperationIr::BitwiseOr(repr) => Box::new([&repr.out].into_iter()),
3555 IntOperationIr::BitwiseOrScalar(repr) => Box::new([&repr.out].into_iter()),
3556 IntOperationIr::BitwiseXor(repr) => Box::new([&repr.out].into_iter()),
3557 IntOperationIr::BitwiseXorScalar(repr) => Box::new([&repr.out].into_iter()),
3558 IntOperationIr::BitwiseNot(repr) => Box::new([&repr.out].into_iter()),
3559 IntOperationIr::BitwiseLeftShift(repr) => Box::new([&repr.out].into_iter()),
3560 IntOperationIr::BitwiseLeftShiftScalar(repr) => Box::new([&repr.out].into_iter()),
3561 IntOperationIr::BitwiseRightShift(repr) => Box::new([&repr.out].into_iter()),
3562 IntOperationIr::BitwiseRightShiftScalar(repr) => Box::new([&repr.out].into_iter()),
3563 }
3564 }
3565
3566 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
3567 let mut output = Vec::new();
3568
3569 match self {
3570 IntOperationIr::Matmul(repr) => {
3571 repr.lhs.mark_read_only(nodes, &mut output);
3572 repr.rhs.mark_read_only(nodes, &mut output);
3573 }
3574 IntOperationIr::IntoFloat(repr) => {
3575 repr.input.mark_read_only(nodes, &mut output);
3576 }
3577 IntOperationIr::BitwiseAnd(repr) => {
3578 repr.lhs.mark_read_only(nodes, &mut output);
3579 repr.rhs.mark_read_only(nodes, &mut output);
3580 }
3581 IntOperationIr::BitwiseAndScalar(repr) => {
3582 repr.lhs.mark_read_only(nodes, &mut output);
3583 }
3584 IntOperationIr::BitwiseOr(repr) => {
3585 repr.lhs.mark_read_only(nodes, &mut output);
3586 repr.rhs.mark_read_only(nodes, &mut output);
3587 }
3588 IntOperationIr::BitwiseOrScalar(repr) => {
3589 repr.lhs.mark_read_only(nodes, &mut output);
3590 }
3591 IntOperationIr::BitwiseXor(repr) => {
3592 repr.lhs.mark_read_only(nodes, &mut output);
3593 repr.rhs.mark_read_only(nodes, &mut output);
3594 }
3595 IntOperationIr::BitwiseXorScalar(repr) => {
3596 repr.lhs.mark_read_only(nodes, &mut output);
3597 }
3598 IntOperationIr::BitwiseNot(repr) => {
3599 repr.input.mark_read_only(nodes, &mut output);
3600 }
3601 IntOperationIr::BitwiseLeftShift(repr) => {
3602 repr.lhs.mark_read_only(nodes, &mut output);
3603 repr.rhs.mark_read_only(nodes, &mut output);
3604 }
3605 IntOperationIr::BitwiseLeftShiftScalar(repr) => {
3606 repr.lhs.mark_read_only(nodes, &mut output);
3607 }
3608 IntOperationIr::BitwiseRightShift(repr) => {
3609 repr.lhs.mark_read_only(nodes, &mut output);
3610 repr.rhs.mark_read_only(nodes, &mut output);
3611 }
3612 IntOperationIr::BitwiseRightShiftScalar(repr) => {
3613 repr.lhs.mark_read_only(nodes, &mut output);
3614 }
3615 };
3616
3617 output
3618 }
3619
3620 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
3621 match self {
3622 IntOperationIr::Matmul(repr) => {
3623 v.visit_tensor_mut(&mut repr.lhs);
3624 v.visit_tensor_mut(&mut repr.rhs);
3625 v.visit_tensor_mut(&mut repr.out);
3626 }
3627 IntOperationIr::IntoFloat(repr) => {
3628 v.visit_tensor_mut(&mut repr.input);
3629 v.visit_tensor_mut(&mut repr.out);
3630 }
3631 IntOperationIr::BitwiseAnd(repr) => {
3632 v.visit_tensor_mut(&mut repr.lhs);
3633 v.visit_tensor_mut(&mut repr.rhs);
3634 v.visit_tensor_mut(&mut repr.out);
3635 }
3636 IntOperationIr::BitwiseAndScalar(repr) => {
3637 v.visit_tensor_mut(&mut repr.lhs);
3638 v.visit_tensor_mut(&mut repr.out);
3639 v.visit_scalar_mut(&mut repr.rhs);
3640 }
3641 IntOperationIr::BitwiseOr(repr) => {
3642 v.visit_tensor_mut(&mut repr.lhs);
3643 v.visit_tensor_mut(&mut repr.rhs);
3644 v.visit_tensor_mut(&mut repr.out);
3645 }
3646 IntOperationIr::BitwiseOrScalar(repr) => {
3647 v.visit_tensor_mut(&mut repr.lhs);
3648 v.visit_tensor_mut(&mut repr.out);
3649 v.visit_scalar_mut(&mut repr.rhs);
3650 }
3651 IntOperationIr::BitwiseXor(repr) => {
3652 v.visit_tensor_mut(&mut repr.lhs);
3653 v.visit_tensor_mut(&mut repr.rhs);
3654 v.visit_tensor_mut(&mut repr.out);
3655 }
3656 IntOperationIr::BitwiseXorScalar(repr) => {
3657 v.visit_tensor_mut(&mut repr.lhs);
3658 v.visit_tensor_mut(&mut repr.out);
3659 v.visit_scalar_mut(&mut repr.rhs);
3660 }
3661 IntOperationIr::BitwiseNot(repr) => {
3662 v.visit_tensor_mut(&mut repr.input);
3663 v.visit_tensor_mut(&mut repr.out);
3664 }
3665 IntOperationIr::BitwiseLeftShift(repr) => {
3666 v.visit_tensor_mut(&mut repr.lhs);
3667 v.visit_tensor_mut(&mut repr.rhs);
3668 v.visit_tensor_mut(&mut repr.out);
3669 }
3670 IntOperationIr::BitwiseLeftShiftScalar(repr) => {
3671 v.visit_tensor_mut(&mut repr.lhs);
3672 v.visit_tensor_mut(&mut repr.out);
3673 v.visit_scalar_mut(&mut repr.rhs);
3674 }
3675 IntOperationIr::BitwiseRightShift(repr) => {
3676 v.visit_tensor_mut(&mut repr.lhs);
3677 v.visit_tensor_mut(&mut repr.rhs);
3678 v.visit_tensor_mut(&mut repr.out);
3679 }
3680 IntOperationIr::BitwiseRightShiftScalar(repr) => {
3681 v.visit_tensor_mut(&mut repr.lhs);
3682 v.visit_tensor_mut(&mut repr.out);
3683 v.visit_scalar_mut(&mut repr.rhs);
3684 }
3685 }
3686 }
3687}
3688
3689impl BoolOperationIr {
3690 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3691 match self {
3692 BoolOperationIr::IntoFloat(repr) => Box::new([&repr.input].into_iter()),
3693 BoolOperationIr::IntoInt(repr) => Box::new([&repr.input].into_iter()),
3694 BoolOperationIr::Not(repr) => Box::new([&repr.input].into_iter()),
3695 BoolOperationIr::And(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3696 BoolOperationIr::Or(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3697 BoolOperationIr::Xor(repr) => Box::new([&repr.lhs, &repr.rhs].into_iter()),
3698 }
3699 }
3700 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3701 match self {
3702 BoolOperationIr::IntoFloat(repr) => Box::new([&repr.out].into_iter()),
3703 BoolOperationIr::IntoInt(repr) => Box::new([&repr.out].into_iter()),
3704 BoolOperationIr::Not(repr) => Box::new([&repr.out].into_iter()),
3705 BoolOperationIr::And(repr) => Box::new([&repr.out].into_iter()),
3706 BoolOperationIr::Or(repr) => Box::new([&repr.out].into_iter()),
3707 BoolOperationIr::Xor(repr) => Box::new([&repr.out].into_iter()),
3708 }
3709 }
3710 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
3711 let mut output = Vec::new();
3712
3713 match self {
3714 BoolOperationIr::IntoFloat(repr) => {
3715 repr.input.mark_read_only(nodes, &mut output);
3716 }
3717 BoolOperationIr::IntoInt(repr) => {
3718 repr.input.mark_read_only(nodes, &mut output);
3719 }
3720 BoolOperationIr::Not(repr) => {
3721 repr.input.mark_read_only(nodes, &mut output);
3722 }
3723 BoolOperationIr::And(repr) => {
3724 repr.lhs.mark_read_only(nodes, &mut output);
3725 repr.rhs.mark_read_only(nodes, &mut output);
3726 }
3727 BoolOperationIr::Or(repr) => {
3728 repr.lhs.mark_read_only(nodes, &mut output);
3729 repr.rhs.mark_read_only(nodes, &mut output);
3730 }
3731 BoolOperationIr::Xor(repr) => {
3732 repr.lhs.mark_read_only(nodes, &mut output);
3733 repr.rhs.mark_read_only(nodes, &mut output);
3734 }
3735 };
3736
3737 output
3738 }
3739
3740 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
3741 match self {
3742 BoolOperationIr::IntoFloat(repr) => {
3743 v.visit_tensor_mut(&mut repr.input);
3744 v.visit_tensor_mut(&mut repr.out);
3745 }
3746 BoolOperationIr::IntoInt(repr) => {
3747 v.visit_tensor_mut(&mut repr.input);
3748 v.visit_tensor_mut(&mut repr.out);
3749 }
3750 BoolOperationIr::Not(repr) => {
3751 v.visit_tensor_mut(&mut repr.input);
3752 v.visit_tensor_mut(&mut repr.out);
3753 }
3754 BoolOperationIr::And(repr) => {
3755 v.visit_tensor_mut(&mut repr.lhs);
3756 v.visit_tensor_mut(&mut repr.rhs);
3757 v.visit_tensor_mut(&mut repr.out);
3758 }
3759 BoolOperationIr::Or(repr) => {
3760 v.visit_tensor_mut(&mut repr.lhs);
3761 v.visit_tensor_mut(&mut repr.rhs);
3762 v.visit_tensor_mut(&mut repr.out);
3763 }
3764 BoolOperationIr::Xor(repr) => {
3765 v.visit_tensor_mut(&mut repr.lhs);
3766 v.visit_tensor_mut(&mut repr.rhs);
3767 v.visit_tensor_mut(&mut repr.out);
3768 }
3769 }
3770 }
3771}
3772
3773impl ModuleOperationIr {
3774 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3775 match self {
3776 ModuleOperationIr::BatchNorm(repr) => {
3777 Box::new([&repr.x, &repr.gamma, &repr.beta, &repr.mean, &repr.variance].into_iter())
3778 }
3779 ModuleOperationIr::Embedding(repr) => {
3780 Box::new([&repr.weights, &repr.indices].into_iter())
3781 }
3782 ModuleOperationIr::EmbeddingBackward(repr) => {
3783 Box::new([&repr.weights, &repr.out_grad, &repr.indices].into_iter())
3784 }
3785 ModuleOperationIr::Linear(repr) => {
3786 if let Some(bias) = &repr.bias {
3787 Box::new([&repr.x, &repr.weight, bias].into_iter())
3788 } else {
3789 Box::new([&repr.x, &repr.weight].into_iter())
3790 }
3791 }
3792 ModuleOperationIr::LinearXBackward(repr) => {
3793 Box::new([&repr.weight, &repr.output_grad].into_iter())
3794 }
3795 ModuleOperationIr::LinearWeightBackward(repr) => {
3796 Box::new([&repr.x, &repr.output_grad].into_iter())
3797 }
3798 ModuleOperationIr::LinearBiasBackward(repr) => {
3799 Box::new([&repr.output_grad].into_iter())
3800 }
3801 ModuleOperationIr::Conv1d(repr) => {
3802 if let Some(bias) = &repr.bias {
3803 Box::new([&repr.x, &repr.weight, bias].into_iter())
3804 } else {
3805 Box::new([&repr.x, &repr.weight].into_iter())
3806 }
3807 }
3808 ModuleOperationIr::Conv1dXBackward(repr) => {
3809 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3810 }
3811 ModuleOperationIr::Conv1dWeightBackward(repr) => {
3812 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3813 }
3814 ModuleOperationIr::Conv1dBiasBackward(repr) => {
3815 Box::new([&repr.x, &repr.bias, &repr.output_grad].into_iter())
3816 }
3817 ModuleOperationIr::Conv2d(repr) => {
3818 if let Some(bias) = &repr.bias {
3819 Box::new([&repr.x, &repr.weight, bias].into_iter())
3820 } else {
3821 Box::new([&repr.x, &repr.weight].into_iter())
3822 }
3823 }
3824 ModuleOperationIr::Conv2dXBackward(repr) => {
3825 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3826 }
3827 ModuleOperationIr::Conv2dWeightBackward(repr) => {
3828 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3829 }
3830 ModuleOperationIr::Conv2dBiasBackward(repr) => {
3831 Box::new([&repr.x, &repr.bias, &repr.output_grad].into_iter())
3832 }
3833 ModuleOperationIr::Conv3d(repr) => {
3834 if let Some(bias) = &repr.bias {
3835 Box::new([&repr.x, &repr.weight, bias].into_iter())
3836 } else {
3837 Box::new([&repr.x, &repr.weight].into_iter())
3838 }
3839 }
3840 ModuleOperationIr::Conv3dXBackward(repr) => {
3841 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3842 }
3843 ModuleOperationIr::Conv3dWeightBackward(repr) => {
3844 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3845 }
3846 ModuleOperationIr::Conv3dBiasBackward(repr) => {
3847 Box::new([&repr.x, &repr.bias, &repr.output_grad].into_iter())
3848 }
3849 ModuleOperationIr::DeformableConv2d(repr) => match (&repr.mask, &repr.bias) {
3850 (Some(mask), Some(bias)) => {
3851 Box::new([&repr.x, &repr.offset, &repr.weight, mask, bias].into_iter())
3852 }
3853 (Some(mask), None) => {
3854 Box::new([&repr.x, &repr.offset, &repr.weight, mask].into_iter())
3855 }
3856 (None, Some(bias)) => {
3857 Box::new([&repr.x, &repr.offset, &repr.weight, bias].into_iter())
3858 }
3859 (None, None) => Box::new([&repr.x, &repr.offset, &repr.weight].into_iter()),
3860 },
3861 ModuleOperationIr::DeformableConv2dBackward(repr) => match (&repr.mask, &repr.bias) {
3862 (Some(mask), Some(bias)) => Box::new(
3863 [
3864 &repr.x,
3865 &repr.offset,
3866 &repr.weight,
3867 &repr.out_grad,
3868 mask,
3869 bias,
3870 ]
3871 .into_iter(),
3872 ),
3873 (Some(mask), None) => Box::new(
3874 [&repr.x, &repr.offset, &repr.weight, &repr.out_grad, mask].into_iter(),
3875 ),
3876 (None, Some(bias)) => Box::new(
3877 [&repr.x, &repr.offset, &repr.weight, &repr.out_grad, bias].into_iter(),
3878 ),
3879 (None, None) => {
3880 Box::new([&repr.x, &repr.offset, &repr.weight, &repr.out_grad].into_iter())
3881 }
3882 },
3883 ModuleOperationIr::ConvTranspose1d(repr) => {
3884 if let Some(bias) = &repr.bias {
3885 Box::new([&repr.x, &repr.weight, bias].into_iter())
3886 } else {
3887 Box::new([&repr.x, &repr.weight].into_iter())
3888 }
3889 }
3890 ModuleOperationIr::ConvTranspose2d(repr) => {
3891 if let Some(bias) = &repr.bias {
3892 Box::new([&repr.x, &repr.weight, bias].into_iter())
3893 } else {
3894 Box::new([&repr.x, &repr.weight].into_iter())
3895 }
3896 }
3897 ModuleOperationIr::ConvTranspose3d(repr) => {
3898 if let Some(bias) = &repr.bias {
3899 Box::new([&repr.x, &repr.weight, bias].into_iter())
3900 } else {
3901 Box::new([&repr.x, &repr.weight].into_iter())
3902 }
3903 }
3904 ModuleOperationIr::AvgPool1d(repr) => Box::new([&repr.x].into_iter()),
3905 ModuleOperationIr::AvgPool2d(repr) => Box::new([&repr.x].into_iter()),
3906 ModuleOperationIr::AvgPool1dBackward(repr) => {
3907 Box::new([&repr.x, &repr.grad].into_iter())
3908 }
3909 ModuleOperationIr::AvgPool2dBackward(repr) => {
3910 Box::new([&repr.x, &repr.grad].into_iter())
3911 }
3912 ModuleOperationIr::AdaptiveAvgPool1d(repr) => Box::new([&repr.x].into_iter()),
3913 ModuleOperationIr::AdaptiveAvgPool2d(repr) => Box::new([&repr.x].into_iter()),
3914 ModuleOperationIr::AdaptiveAvgPool1dBackward(repr) => {
3915 Box::new([&repr.x, &repr.grad].into_iter())
3916 }
3917 ModuleOperationIr::AdaptiveAvgPool2dBackward(repr) => {
3918 Box::new([&repr.x, &repr.grad].into_iter())
3919 }
3920 ModuleOperationIr::AdaptiveAvgPool3d(repr) => Box::new([&repr.x].into_iter()),
3921 ModuleOperationIr::AdaptiveAvgPool3dBackward(repr) => {
3922 Box::new([&repr.x, &repr.grad].into_iter())
3923 }
3924 ModuleOperationIr::MaxPool1d(repr) => Box::new([&repr.x].into_iter()),
3925 ModuleOperationIr::MaxPool1dWithIndices(repr) => Box::new([&repr.x].into_iter()),
3926 ModuleOperationIr::MaxPool1dWithIndicesBackward(repr) => {
3927 Box::new([&repr.x, &repr.indices, &repr.grad].into_iter())
3928 }
3929 ModuleOperationIr::MaxPool2d(repr) => Box::new([&repr.x].into_iter()),
3930 ModuleOperationIr::MaxPool2dWithIndices(repr) => Box::new([&repr.x].into_iter()),
3931 ModuleOperationIr::MaxPool2dWithIndicesBackward(repr) => {
3932 Box::new([&repr.x, &repr.indices, &repr.grad].into_iter())
3933 }
3934 ModuleOperationIr::Interpolate(repr) => Box::new([&repr.x].into_iter()),
3935 ModuleOperationIr::InterpolateBackward(repr) => {
3936 Box::new([&repr.x, &repr.grad].into_iter())
3937 }
3938 ModuleOperationIr::Attention(repr) => {
3939 if let Some(mask) = &repr.mask {
3940 if let Some(attn_bias) = &repr.attn_bias {
3941 Box::new([&repr.query, &repr.key, &repr.value, mask, attn_bias].into_iter())
3942 } else {
3943 Box::new([&repr.query, &repr.key, &repr.value, mask].into_iter())
3944 }
3945 } else if let Some(attn_bias) = &repr.attn_bias {
3946 Box::new([&repr.query, &repr.key, &repr.value, attn_bias].into_iter())
3947 } else {
3948 Box::new([&repr.query, &repr.key, &repr.value].into_iter())
3949 }
3950 }
3951 ModuleOperationIr::CtcLoss(repr) => Box::new(
3952 [
3953 &repr.log_probs,
3954 &repr.targets,
3955 &repr.input_lengths,
3956 &repr.target_lengths,
3957 ]
3958 .into_iter(),
3959 ),
3960 ModuleOperationIr::CtcLossBackward(repr) => Box::new(
3961 [
3962 &repr.log_probs,
3963 &repr.targets,
3964 &repr.input_lengths,
3965 &repr.target_lengths,
3966 &repr.grad_loss,
3967 ]
3968 .into_iter(),
3969 ),
3970 ModuleOperationIr::LayerNorm(repr) => match &repr.beta {
3971 Some(beta) => Box::new([&repr.input, &repr.gamma, beta].into_iter()),
3972 None => Box::new([&repr.input, &repr.gamma].into_iter()),
3973 },
3974 ModuleOperationIr::Unfold4d(repr) => Box::new([&repr.x].into_iter()),
3975 ModuleOperationIr::ConvTranspose1dWeightBackward(repr) => {
3976 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3977 }
3978 ModuleOperationIr::ConvTranspose1dBiasBackward(repr) => {
3979 Box::new([&repr.x, &repr.bias, &repr.output_grad].into_iter())
3980 }
3981 ModuleOperationIr::ConvTranspose2dWeightBackward(repr) => {
3982 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3983 }
3984 ModuleOperationIr::ConvTranspose2dBiasBackward(repr) => {
3985 Box::new([&repr.x, &repr.bias, &repr.output_grad].into_iter())
3986 }
3987 ModuleOperationIr::ConvTranspose3dWeightBackward(repr) => {
3988 Box::new([&repr.x, &repr.weight, &repr.output_grad].into_iter())
3989 }
3990 ModuleOperationIr::ConvTranspose3dBiasBackward(repr) => {
3991 Box::new([&repr.x, &repr.bias, &repr.output_grad].into_iter())
3992 }
3993 }
3994 }
3995 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
3996 match self {
3997 ModuleOperationIr::BatchNorm(repr) => Box::new([&repr.out].into_iter()),
3998 ModuleOperationIr::Embedding(repr) => Box::new([&repr.out].into_iter()),
3999 ModuleOperationIr::EmbeddingBackward(repr) => Box::new([&repr.out].into_iter()),
4000 ModuleOperationIr::Linear(repr) => Box::new([&repr.out].into_iter()),
4001 ModuleOperationIr::LinearXBackward(repr) => Box::new([&repr.out].into_iter()),
4002 ModuleOperationIr::LinearWeightBackward(repr) => Box::new([&repr.out].into_iter()),
4003 ModuleOperationIr::LinearBiasBackward(repr) => Box::new([&repr.out].into_iter()),
4004 ModuleOperationIr::Conv1d(repr) => Box::new([&repr.out].into_iter()),
4005 ModuleOperationIr::Conv1dXBackward(repr) => Box::new([&repr.out].into_iter()),
4006 ModuleOperationIr::Conv1dWeightBackward(repr) => Box::new([&repr.out].into_iter()),
4007 ModuleOperationIr::Conv1dBiasBackward(repr) => Box::new([&repr.out].into_iter()),
4008 ModuleOperationIr::Conv2d(repr) => Box::new([&repr.out].into_iter()),
4009 ModuleOperationIr::Conv2dXBackward(repr) => Box::new([&repr.out].into_iter()),
4010 ModuleOperationIr::Conv2dWeightBackward(repr) => Box::new([&repr.out].into_iter()),
4011 ModuleOperationIr::Conv2dBiasBackward(repr) => Box::new([&repr.out].into_iter()),
4012 ModuleOperationIr::Conv3d(repr) => Box::new([&repr.out].into_iter()),
4013 ModuleOperationIr::Conv3dXBackward(repr) => Box::new([&repr.out].into_iter()),
4014 ModuleOperationIr::Conv3dWeightBackward(repr) => Box::new([&repr.out].into_iter()),
4015 ModuleOperationIr::Conv3dBiasBackward(repr) => Box::new([&repr.out].into_iter()),
4016 ModuleOperationIr::DeformableConv2d(repr) => Box::new([&repr.out].into_iter()),
4017 ModuleOperationIr::DeformableConv2dBackward(repr) => {
4018 match (&repr.mask_grad, &repr.bias_grad) {
4019 (Some(mask_grad), Some(bias_grad)) => Box::new(
4020 [
4021 &repr.input_grad,
4022 &repr.offset_grad,
4023 &repr.weight_grad,
4024 mask_grad,
4025 bias_grad,
4026 ]
4027 .into_iter(),
4028 ),
4029 (Some(mask_grad), None) => Box::new(
4030 [
4031 &repr.input_grad,
4032 &repr.offset_grad,
4033 &repr.weight_grad,
4034 mask_grad,
4035 ]
4036 .into_iter(),
4037 ),
4038 (None, Some(bias_grad)) => Box::new(
4039 [
4040 &repr.input_grad,
4041 &repr.offset_grad,
4042 &repr.weight_grad,
4043 bias_grad,
4044 ]
4045 .into_iter(),
4046 ),
4047 (None, None) => Box::new(
4048 [&repr.input_grad, &repr.offset_grad, &repr.weight_grad].into_iter(),
4049 ),
4050 }
4051 }
4052 ModuleOperationIr::ConvTranspose1d(repr) => Box::new([&repr.out].into_iter()),
4053 ModuleOperationIr::ConvTranspose2d(repr) => Box::new([&repr.out].into_iter()),
4054 ModuleOperationIr::ConvTranspose3d(repr) => Box::new([&repr.out].into_iter()),
4055 ModuleOperationIr::AvgPool1d(repr) => Box::new([&repr.out].into_iter()),
4056 ModuleOperationIr::AvgPool2d(repr) => Box::new([&repr.out].into_iter()),
4057 ModuleOperationIr::AvgPool1dBackward(repr) => Box::new([&repr.out].into_iter()),
4058 ModuleOperationIr::AvgPool2dBackward(repr) => Box::new([&repr.out].into_iter()),
4059 ModuleOperationIr::AdaptiveAvgPool1d(repr) => Box::new([&repr.out].into_iter()),
4060 ModuleOperationIr::AdaptiveAvgPool2d(repr) => Box::new([&repr.out].into_iter()),
4061 ModuleOperationIr::AdaptiveAvgPool1dBackward(repr) => Box::new([&repr.out].into_iter()),
4062 ModuleOperationIr::AdaptiveAvgPool2dBackward(repr) => Box::new([&repr.out].into_iter()),
4063 ModuleOperationIr::AdaptiveAvgPool3d(repr) => Box::new([&repr.out].into_iter()),
4064 ModuleOperationIr::AdaptiveAvgPool3dBackward(repr) => Box::new([&repr.out].into_iter()),
4065 ModuleOperationIr::MaxPool1d(repr) => Box::new([&repr.out].into_iter()),
4066 ModuleOperationIr::MaxPool1dWithIndices(repr) => {
4067 Box::new([&repr.out, &repr.out_indices].into_iter())
4068 }
4069 ModuleOperationIr::MaxPool1dWithIndicesBackward(repr) => {
4070 Box::new([&repr.out].into_iter())
4071 }
4072 ModuleOperationIr::MaxPool2d(repr) => Box::new([&repr.out].into_iter()),
4073 ModuleOperationIr::MaxPool2dWithIndices(repr) => {
4074 Box::new([&repr.out, &repr.out_indices].into_iter())
4075 }
4076 ModuleOperationIr::MaxPool2dWithIndicesBackward(repr) => {
4077 Box::new([&repr.out].into_iter())
4078 }
4079 ModuleOperationIr::Interpolate(repr) => Box::new([&repr.out].into_iter()),
4080 ModuleOperationIr::InterpolateBackward(repr) => Box::new([&repr.out].into_iter()),
4081 ModuleOperationIr::Attention(repr) => Box::new([&repr.out].into_iter()),
4082 ModuleOperationIr::CtcLoss(repr) => Box::new([&repr.out].into_iter()),
4083 ModuleOperationIr::CtcLossBackward(repr) => Box::new([&repr.out].into_iter()),
4084 ModuleOperationIr::LayerNorm(repr) => Box::new([&repr.out].into_iter()),
4085 ModuleOperationIr::Unfold4d(repr) => Box::new([&repr.out].into_iter()),
4086 ModuleOperationIr::ConvTranspose1dWeightBackward(repr) => {
4087 Box::new([&repr.out].into_iter())
4088 }
4089 ModuleOperationIr::ConvTranspose1dBiasBackward(repr) => {
4090 Box::new([&repr.out].into_iter())
4091 }
4092 ModuleOperationIr::ConvTranspose2dWeightBackward(repr) => {
4093 Box::new([&repr.out].into_iter())
4094 }
4095 ModuleOperationIr::ConvTranspose2dBiasBackward(repr) => {
4096 Box::new([&repr.out].into_iter())
4097 }
4098 ModuleOperationIr::ConvTranspose3dWeightBackward(repr) => {
4099 Box::new([&repr.out].into_iter())
4100 }
4101 ModuleOperationIr::ConvTranspose3dBiasBackward(repr) => {
4102 Box::new([&repr.out].into_iter())
4103 }
4104 }
4105 }
4106
4107 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
4108 let mut output = Vec::new();
4109
4110 match self {
4111 ModuleOperationIr::BatchNorm(repr) => {
4112 repr.x.mark_read_only(nodes, &mut output);
4113 repr.gamma.mark_read_only(nodes, &mut output);
4114 repr.beta.mark_read_only(nodes, &mut output);
4115 repr.mean.mark_read_only(nodes, &mut output);
4116 repr.variance.mark_read_only(nodes, &mut output);
4117 }
4118 ModuleOperationIr::Embedding(repr) => {
4119 repr.weights.mark_read_only(nodes, &mut output);
4120 repr.indices.mark_read_only(nodes, &mut output);
4121 }
4122 ModuleOperationIr::EmbeddingBackward(repr) => {
4123 repr.weights.mark_read_only(nodes, &mut output);
4124 repr.out_grad.mark_read_only(nodes, &mut output);
4125 repr.indices.mark_read_only(nodes, &mut output);
4126 }
4127 ModuleOperationIr::Linear(repr) => {
4128 repr.x.mark_read_only(nodes, &mut output);
4129 repr.weight.mark_read_only(nodes, &mut output);
4130
4131 if let Some(bias) = &mut repr.bias {
4132 bias.mark_read_only(nodes, &mut output);
4133 }
4134 }
4135 ModuleOperationIr::LinearXBackward(repr) => {
4136 repr.weight.mark_read_only(nodes, &mut output);
4137 repr.output_grad.mark_read_only(nodes, &mut output);
4138 }
4139 ModuleOperationIr::LinearWeightBackward(repr) => {
4140 repr.x.mark_read_only(nodes, &mut output);
4141 repr.output_grad.mark_read_only(nodes, &mut output);
4142 }
4143 ModuleOperationIr::LinearBiasBackward(repr) => {
4144 repr.output_grad.mark_read_only(nodes, &mut output);
4145 }
4146 ModuleOperationIr::Conv1d(repr) => {
4147 repr.x.mark_read_only(nodes, &mut output);
4148 repr.weight.mark_read_only(nodes, &mut output);
4149
4150 if let Some(bias) = &mut repr.bias {
4151 bias.mark_read_only(nodes, &mut output);
4152 }
4153 }
4154 ModuleOperationIr::Conv1dXBackward(repr) => {
4155 repr.x.mark_read_only(nodes, &mut output);
4156 repr.weight.mark_read_only(nodes, &mut output);
4157 repr.output_grad.mark_read_only(nodes, &mut output);
4158 }
4159 ModuleOperationIr::Conv1dWeightBackward(repr) => {
4160 repr.x.mark_read_only(nodes, &mut output);
4161 repr.weight.mark_read_only(nodes, &mut output);
4162 repr.output_grad.mark_read_only(nodes, &mut output);
4163 }
4164 ModuleOperationIr::Conv1dBiasBackward(repr) => {
4165 repr.x.mark_read_only(nodes, &mut output);
4166 repr.bias.mark_read_only(nodes, &mut output);
4167 repr.output_grad.mark_read_only(nodes, &mut output);
4168 }
4169 ModuleOperationIr::Conv2d(repr) => {
4170 repr.x.mark_read_only(nodes, &mut output);
4171 repr.weight.mark_read_only(nodes, &mut output);
4172
4173 if let Some(bias) = &mut repr.bias {
4174 bias.mark_read_only(nodes, &mut output);
4175 }
4176 }
4177 ModuleOperationIr::Conv2dXBackward(repr) => {
4178 repr.x.mark_read_only(nodes, &mut output);
4179 repr.weight.mark_read_only(nodes, &mut output);
4180 repr.output_grad.mark_read_only(nodes, &mut output);
4181 }
4182 ModuleOperationIr::Conv2dWeightBackward(repr) => {
4183 repr.x.mark_read_only(nodes, &mut output);
4184 repr.weight.mark_read_only(nodes, &mut output);
4185 repr.output_grad.mark_read_only(nodes, &mut output);
4186 }
4187 ModuleOperationIr::Conv2dBiasBackward(repr) => {
4188 repr.x.mark_read_only(nodes, &mut output);
4189 repr.bias.mark_read_only(nodes, &mut output);
4190 repr.output_grad.mark_read_only(nodes, &mut output);
4191 }
4192 ModuleOperationIr::Conv3d(repr) => {
4193 repr.x.mark_read_only(nodes, &mut output);
4194 repr.weight.mark_read_only(nodes, &mut output);
4195
4196 if let Some(bias) = &mut repr.bias {
4197 bias.mark_read_only(nodes, &mut output);
4198 }
4199 }
4200 ModuleOperationIr::Conv3dXBackward(repr) => {
4201 repr.x.mark_read_only(nodes, &mut output);
4202 repr.weight.mark_read_only(nodes, &mut output);
4203 repr.output_grad.mark_read_only(nodes, &mut output);
4204 }
4205 ModuleOperationIr::Conv3dWeightBackward(repr) => {
4206 repr.x.mark_read_only(nodes, &mut output);
4207 repr.weight.mark_read_only(nodes, &mut output);
4208 repr.output_grad.mark_read_only(nodes, &mut output);
4209 }
4210 ModuleOperationIr::Conv3dBiasBackward(repr) => {
4211 repr.x.mark_read_only(nodes, &mut output);
4212 repr.bias.mark_read_only(nodes, &mut output);
4213 repr.output_grad.mark_read_only(nodes, &mut output);
4214 }
4215 ModuleOperationIr::DeformableConv2d(repr) => {
4216 repr.x.mark_read_only(nodes, &mut output);
4217 repr.weight.mark_read_only(nodes, &mut output);
4218 repr.offset.mark_read_only(nodes, &mut output);
4219
4220 match (&mut repr.mask, &mut repr.bias) {
4221 (Some(mask), Some(bias)) => {
4222 mask.mark_read_only(nodes, &mut output);
4223 bias.mark_read_only(nodes, &mut output);
4224 }
4225 (Some(mask), None) => {
4226 mask.mark_read_only(nodes, &mut output);
4227 }
4228 (None, Some(bias)) => {
4229 bias.mark_read_only(nodes, &mut output);
4230 }
4231 (None, None) => {}
4232 };
4233 }
4234 ModuleOperationIr::DeformableConv2dBackward(repr) => {
4235 repr.x.mark_read_only(nodes, &mut output);
4236 repr.weight.mark_read_only(nodes, &mut output);
4237 repr.offset.mark_read_only(nodes, &mut output);
4238 repr.out_grad.mark_read_only(nodes, &mut output);
4239
4240 if let Some(mask) = repr.mask.as_mut() {
4241 mask.mark_read_only(nodes, &mut output);
4242 }
4243 if let Some(bias) = repr.bias.as_mut() {
4244 bias.mark_read_only(nodes, &mut output);
4245 }
4246 }
4247 ModuleOperationIr::ConvTranspose1d(repr) => {
4248 repr.x.mark_read_only(nodes, &mut output);
4249 repr.weight.mark_read_only(nodes, &mut output);
4250
4251 if let Some(bias) = &mut repr.bias {
4252 bias.mark_read_only(nodes, &mut output);
4253 }
4254 }
4255 ModuleOperationIr::ConvTranspose2d(repr) => {
4256 repr.x.mark_read_only(nodes, &mut output);
4257 repr.weight.mark_read_only(nodes, &mut output);
4258
4259 if let Some(bias) = &mut repr.bias {
4260 bias.mark_read_only(nodes, &mut output);
4261 }
4262 }
4263 ModuleOperationIr::ConvTranspose3d(repr) => {
4264 repr.x.mark_read_only(nodes, &mut output);
4265 repr.weight.mark_read_only(nodes, &mut output);
4266
4267 if let Some(bias) = &mut repr.bias {
4268 bias.mark_read_only(nodes, &mut output);
4269 }
4270 }
4271 ModuleOperationIr::AvgPool1d(repr) => {
4272 repr.x.mark_read_only(nodes, &mut output);
4273 }
4274 ModuleOperationIr::AvgPool2d(repr) => {
4275 repr.x.mark_read_only(nodes, &mut output);
4276 }
4277 ModuleOperationIr::AvgPool1dBackward(repr) => {
4278 repr.x.mark_read_only(nodes, &mut output);
4279 repr.grad.mark_read_only(nodes, &mut output);
4280 }
4281 ModuleOperationIr::AvgPool2dBackward(repr) => {
4282 repr.x.mark_read_only(nodes, &mut output);
4283 repr.grad.mark_read_only(nodes, &mut output);
4284 }
4285 ModuleOperationIr::AdaptiveAvgPool1d(repr) => {
4286 repr.x.mark_read_only(nodes, &mut output);
4287 }
4288 ModuleOperationIr::AdaptiveAvgPool2d(repr) => {
4289 repr.x.mark_read_only(nodes, &mut output);
4290 }
4291 ModuleOperationIr::AdaptiveAvgPool1dBackward(repr) => {
4292 repr.x.mark_read_only(nodes, &mut output);
4293 repr.grad.mark_read_only(nodes, &mut output);
4294 }
4295 ModuleOperationIr::AdaptiveAvgPool2dBackward(repr) => {
4296 repr.x.mark_read_only(nodes, &mut output);
4297 repr.grad.mark_read_only(nodes, &mut output);
4298 }
4299 ModuleOperationIr::AdaptiveAvgPool3d(repr) => {
4300 repr.x.mark_read_only(nodes, &mut output);
4301 }
4302 ModuleOperationIr::AdaptiveAvgPool3dBackward(repr) => {
4303 repr.x.mark_read_only(nodes, &mut output);
4304 repr.grad.mark_read_only(nodes, &mut output);
4305 }
4306 ModuleOperationIr::MaxPool1d(repr) => {
4307 repr.x.mark_read_only(nodes, &mut output);
4308 }
4309 ModuleOperationIr::MaxPool1dWithIndices(repr) => {
4310 repr.x.mark_read_only(nodes, &mut output);
4311 }
4312 ModuleOperationIr::MaxPool1dWithIndicesBackward(repr) => {
4313 repr.x.mark_read_only(nodes, &mut output);
4314 repr.grad.mark_read_only(nodes, &mut output);
4315 }
4316 ModuleOperationIr::MaxPool2d(repr) => {
4317 repr.x.mark_read_only(nodes, &mut output);
4318 }
4319 ModuleOperationIr::MaxPool2dWithIndices(repr) => {
4320 repr.x.mark_read_only(nodes, &mut output);
4321 }
4322 ModuleOperationIr::MaxPool2dWithIndicesBackward(repr) => {
4323 repr.x.mark_read_only(nodes, &mut output);
4324 repr.grad.mark_read_only(nodes, &mut output);
4325 }
4326 ModuleOperationIr::Interpolate(repr) => {
4327 repr.x.mark_read_only(nodes, &mut output);
4328 }
4329 ModuleOperationIr::InterpolateBackward(repr) => {
4330 repr.x.mark_read_only(nodes, &mut output);
4331 repr.grad.mark_read_only(nodes, &mut output);
4332 }
4333 ModuleOperationIr::Attention(repr) => {
4334 repr.query.mark_read_only(nodes, &mut output);
4335 repr.key.mark_read_only(nodes, &mut output);
4336 repr.value.mark_read_only(nodes, &mut output);
4337 if let Some(mask) = &mut repr.mask {
4338 mask.mark_read_only(nodes, &mut output);
4339 }
4340 if let Some(attn_bias) = &mut repr.attn_bias {
4341 attn_bias.mark_read_only(nodes, &mut output);
4342 }
4343 }
4344 ModuleOperationIr::CtcLoss(repr) => {
4345 repr.log_probs.mark_read_only(nodes, &mut output);
4346 repr.targets.mark_read_only(nodes, &mut output);
4347 repr.input_lengths.mark_read_only(nodes, &mut output);
4348 repr.target_lengths.mark_read_only(nodes, &mut output);
4349 }
4350 ModuleOperationIr::CtcLossBackward(repr) => {
4351 repr.log_probs.mark_read_only(nodes, &mut output);
4352 repr.targets.mark_read_only(nodes, &mut output);
4353 repr.input_lengths.mark_read_only(nodes, &mut output);
4354 repr.target_lengths.mark_read_only(nodes, &mut output);
4355 repr.grad_loss.mark_read_only(nodes, &mut output);
4356 }
4357 ModuleOperationIr::LayerNorm(repr) => {
4358 repr.input.mark_read_only(nodes, &mut output);
4359 repr.gamma.mark_read_only(nodes, &mut output);
4360 if let Some(beta) = &mut repr.beta {
4361 beta.mark_read_only(nodes, &mut output);
4362 }
4363 }
4364 ModuleOperationIr::Unfold4d(repr) => {
4365 repr.x.mark_read_only(nodes, &mut output);
4366 }
4367 ModuleOperationIr::ConvTranspose1dWeightBackward(repr) => {
4368 repr.x.mark_read_only(nodes, &mut output);
4369 repr.weight.mark_read_only(nodes, &mut output);
4370 repr.output_grad.mark_read_only(nodes, &mut output);
4371 }
4372 ModuleOperationIr::ConvTranspose1dBiasBackward(repr) => {
4373 repr.x.mark_read_only(nodes, &mut output);
4374 repr.bias.mark_read_only(nodes, &mut output);
4375 repr.output_grad.mark_read_only(nodes, &mut output);
4376 }
4377 ModuleOperationIr::ConvTranspose2dWeightBackward(repr) => {
4378 repr.x.mark_read_only(nodes, &mut output);
4379 repr.weight.mark_read_only(nodes, &mut output);
4380 repr.output_grad.mark_read_only(nodes, &mut output);
4381 }
4382 ModuleOperationIr::ConvTranspose2dBiasBackward(repr) => {
4383 repr.x.mark_read_only(nodes, &mut output);
4384 repr.bias.mark_read_only(nodes, &mut output);
4385 repr.output_grad.mark_read_only(nodes, &mut output);
4386 }
4387 ModuleOperationIr::ConvTranspose3dWeightBackward(repr) => {
4388 repr.x.mark_read_only(nodes, &mut output);
4389 repr.weight.mark_read_only(nodes, &mut output);
4390 repr.output_grad.mark_read_only(nodes, &mut output);
4391 }
4392 ModuleOperationIr::ConvTranspose3dBiasBackward(repr) => {
4393 repr.x.mark_read_only(nodes, &mut output);
4394 repr.bias.mark_read_only(nodes, &mut output);
4395 repr.output_grad.mark_read_only(nodes, &mut output);
4396 }
4397 };
4398
4399 output
4400 }
4401
4402 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
4403 match self {
4404 ModuleOperationIr::BatchNorm(repr) => {
4405 v.visit_tensor_mut(&mut repr.x);
4406 v.visit_tensor_mut(&mut repr.gamma);
4407 v.visit_tensor_mut(&mut repr.beta);
4408 v.visit_tensor_mut(&mut repr.mean);
4409 v.visit_tensor_mut(&mut repr.variance);
4410 v.visit_scalar_mut(&mut repr.epsilon);
4411 v.visit_tensor_mut(&mut repr.out);
4412 }
4413 ModuleOperationIr::Embedding(repr) => {
4414 v.visit_tensor_mut(&mut repr.weights);
4415 v.visit_tensor_mut(&mut repr.indices);
4416 v.visit_tensor_mut(&mut repr.out);
4417 }
4418 ModuleOperationIr::EmbeddingBackward(repr) => {
4419 v.visit_tensor_mut(&mut repr.weights);
4420 v.visit_tensor_mut(&mut repr.out_grad);
4421 v.visit_tensor_mut(&mut repr.indices);
4422 v.visit_tensor_mut(&mut repr.out);
4423 }
4424 ModuleOperationIr::Linear(repr) => {
4425 v.visit_tensor_mut(&mut repr.x);
4426 v.visit_tensor_mut(&mut repr.weight);
4427 if let Some(bias) = &mut repr.bias {
4428 v.visit_tensor_mut(bias);
4429 }
4430 v.visit_tensor_mut(&mut repr.out);
4431 }
4432 ModuleOperationIr::LinearXBackward(repr) => {
4433 v.visit_tensor_mut(&mut repr.weight);
4434 v.visit_tensor_mut(&mut repr.output_grad);
4435 v.visit_tensor_mut(&mut repr.out);
4436 }
4437 ModuleOperationIr::LinearWeightBackward(repr) => {
4438 v.visit_tensor_mut(&mut repr.x);
4439 v.visit_tensor_mut(&mut repr.output_grad);
4440 v.visit_tensor_mut(&mut repr.out);
4441 }
4442 ModuleOperationIr::LinearBiasBackward(repr) => {
4443 v.visit_tensor_mut(&mut repr.output_grad);
4444 v.visit_tensor_mut(&mut repr.out);
4445 }
4446 ModuleOperationIr::Conv1d(repr) => {
4447 v.visit_tensor_mut(&mut repr.x);
4448 v.visit_tensor_mut(&mut repr.weight);
4449 if let Some(bias) = &mut repr.bias {
4450 v.visit_tensor_mut(bias);
4451 }
4452 v.visit_tensor_mut(&mut repr.out);
4453 }
4454 ModuleOperationIr::Conv1dXBackward(repr) => {
4455 v.visit_tensor_mut(&mut repr.x);
4456 v.visit_tensor_mut(&mut repr.weight);
4457 v.visit_tensor_mut(&mut repr.output_grad);
4458 v.visit_tensor_mut(&mut repr.out);
4459 }
4460 ModuleOperationIr::Conv1dWeightBackward(repr) => {
4461 v.visit_tensor_mut(&mut repr.x);
4462 v.visit_tensor_mut(&mut repr.weight);
4463 v.visit_tensor_mut(&mut repr.output_grad);
4464 v.visit_tensor_mut(&mut repr.out);
4465 }
4466 ModuleOperationIr::Conv1dBiasBackward(repr) => {
4467 v.visit_tensor_mut(&mut repr.x);
4468 v.visit_tensor_mut(&mut repr.bias);
4469 v.visit_tensor_mut(&mut repr.output_grad);
4470 v.visit_tensor_mut(&mut repr.out);
4471 }
4472 ModuleOperationIr::Conv2d(repr) => {
4473 v.visit_tensor_mut(&mut repr.x);
4474 v.visit_tensor_mut(&mut repr.weight);
4475 if let Some(bias) = &mut repr.bias {
4476 v.visit_tensor_mut(bias);
4477 }
4478 v.visit_tensor_mut(&mut repr.out);
4479 }
4480 ModuleOperationIr::Conv2dXBackward(repr) => {
4481 v.visit_tensor_mut(&mut repr.x);
4482 v.visit_tensor_mut(&mut repr.weight);
4483 v.visit_tensor_mut(&mut repr.output_grad);
4484 v.visit_tensor_mut(&mut repr.out);
4485 }
4486 ModuleOperationIr::Conv2dWeightBackward(repr) => {
4487 v.visit_tensor_mut(&mut repr.x);
4488 v.visit_tensor_mut(&mut repr.weight);
4489 v.visit_tensor_mut(&mut repr.output_grad);
4490 v.visit_tensor_mut(&mut repr.out);
4491 }
4492 ModuleOperationIr::Conv2dBiasBackward(repr) => {
4493 v.visit_tensor_mut(&mut repr.x);
4494 v.visit_tensor_mut(&mut repr.bias);
4495 v.visit_tensor_mut(&mut repr.output_grad);
4496 v.visit_tensor_mut(&mut repr.out);
4497 }
4498 ModuleOperationIr::Conv3d(repr) => {
4499 v.visit_tensor_mut(&mut repr.x);
4500 v.visit_tensor_mut(&mut repr.weight);
4501 if let Some(bias) = &mut repr.bias {
4502 v.visit_tensor_mut(bias);
4503 }
4504 v.visit_tensor_mut(&mut repr.out);
4505 }
4506 ModuleOperationIr::Conv3dXBackward(repr) => {
4507 v.visit_tensor_mut(&mut repr.x);
4508 v.visit_tensor_mut(&mut repr.weight);
4509 v.visit_tensor_mut(&mut repr.output_grad);
4510 v.visit_tensor_mut(&mut repr.out);
4511 }
4512 ModuleOperationIr::Conv3dWeightBackward(repr) => {
4513 v.visit_tensor_mut(&mut repr.x);
4514 v.visit_tensor_mut(&mut repr.weight);
4515 v.visit_tensor_mut(&mut repr.output_grad);
4516 v.visit_tensor_mut(&mut repr.out);
4517 }
4518 ModuleOperationIr::Conv3dBiasBackward(repr) => {
4519 v.visit_tensor_mut(&mut repr.x);
4520 v.visit_tensor_mut(&mut repr.bias);
4521 v.visit_tensor_mut(&mut repr.output_grad);
4522 v.visit_tensor_mut(&mut repr.out);
4523 }
4524 ModuleOperationIr::DeformableConv2d(repr) => {
4525 v.visit_tensor_mut(&mut repr.x);
4526 v.visit_tensor_mut(&mut repr.offset);
4527 v.visit_tensor_mut(&mut repr.weight);
4528 if let Some(mask) = &mut repr.mask {
4529 v.visit_tensor_mut(mask);
4530 }
4531 if let Some(bias) = &mut repr.bias {
4532 v.visit_tensor_mut(bias);
4533 }
4534 v.visit_tensor_mut(&mut repr.out);
4535 }
4536 ModuleOperationIr::DeformableConv2dBackward(repr) => {
4537 v.visit_tensor_mut(&mut repr.x);
4538 v.visit_tensor_mut(&mut repr.offset);
4539 v.visit_tensor_mut(&mut repr.weight);
4540 v.visit_tensor_mut(&mut repr.out_grad);
4541 if let Some(mask) = &mut repr.mask {
4542 v.visit_tensor_mut(mask);
4543 }
4544 if let Some(bias) = &mut repr.bias {
4545 v.visit_tensor_mut(bias);
4546 }
4547 v.visit_tensor_mut(&mut repr.input_grad);
4548 v.visit_tensor_mut(&mut repr.offset_grad);
4549 v.visit_tensor_mut(&mut repr.weight_grad);
4550 if let Some(mask_grad) = &mut repr.mask_grad {
4551 v.visit_tensor_mut(mask_grad);
4552 }
4553 if let Some(bias_grad) = &mut repr.bias_grad {
4554 v.visit_tensor_mut(bias_grad);
4555 }
4556 }
4557 ModuleOperationIr::ConvTranspose1d(repr) => {
4558 v.visit_tensor_mut(&mut repr.x);
4559 v.visit_tensor_mut(&mut repr.weight);
4560 if let Some(bias) = &mut repr.bias {
4561 v.visit_tensor_mut(bias);
4562 }
4563 v.visit_tensor_mut(&mut repr.out);
4564 }
4565 ModuleOperationIr::ConvTranspose2d(repr) => {
4566 v.visit_tensor_mut(&mut repr.x);
4567 v.visit_tensor_mut(&mut repr.weight);
4568 if let Some(bias) = &mut repr.bias {
4569 v.visit_tensor_mut(bias);
4570 }
4571 v.visit_tensor_mut(&mut repr.out);
4572 }
4573 ModuleOperationIr::ConvTranspose3d(repr) => {
4574 v.visit_tensor_mut(&mut repr.x);
4575 v.visit_tensor_mut(&mut repr.weight);
4576 if let Some(bias) = &mut repr.bias {
4577 v.visit_tensor_mut(bias);
4578 }
4579 v.visit_tensor_mut(&mut repr.out);
4580 }
4581 ModuleOperationIr::AvgPool1d(repr) => {
4582 v.visit_tensor_mut(&mut repr.x);
4583 v.visit_tensor_mut(&mut repr.out);
4584 }
4585 ModuleOperationIr::AvgPool2d(repr) => {
4586 v.visit_tensor_mut(&mut repr.x);
4587 v.visit_tensor_mut(&mut repr.out);
4588 }
4589 ModuleOperationIr::AvgPool1dBackward(repr) => {
4590 v.visit_tensor_mut(&mut repr.x);
4591 v.visit_tensor_mut(&mut repr.grad);
4592 v.visit_tensor_mut(&mut repr.out);
4593 }
4594 ModuleOperationIr::AvgPool2dBackward(repr) => {
4595 v.visit_tensor_mut(&mut repr.x);
4596 v.visit_tensor_mut(&mut repr.grad);
4597 v.visit_tensor_mut(&mut repr.out);
4598 }
4599 ModuleOperationIr::AdaptiveAvgPool1d(repr) => {
4600 v.visit_tensor_mut(&mut repr.x);
4601 v.visit_tensor_mut(&mut repr.out);
4602 }
4603 ModuleOperationIr::AdaptiveAvgPool2d(repr) => {
4604 v.visit_tensor_mut(&mut repr.x);
4605 v.visit_tensor_mut(&mut repr.out);
4606 }
4607 ModuleOperationIr::AdaptiveAvgPool1dBackward(repr) => {
4608 v.visit_tensor_mut(&mut repr.x);
4609 v.visit_tensor_mut(&mut repr.grad);
4610 v.visit_tensor_mut(&mut repr.out);
4611 }
4612 ModuleOperationIr::AdaptiveAvgPool2dBackward(repr) => {
4613 v.visit_tensor_mut(&mut repr.x);
4614 v.visit_tensor_mut(&mut repr.grad);
4615 v.visit_tensor_mut(&mut repr.out);
4616 }
4617 ModuleOperationIr::AdaptiveAvgPool3d(repr) => {
4618 v.visit_tensor_mut(&mut repr.x);
4619 v.visit_tensor_mut(&mut repr.out);
4620 }
4621 ModuleOperationIr::AdaptiveAvgPool3dBackward(repr) => {
4622 v.visit_tensor_mut(&mut repr.x);
4623 v.visit_tensor_mut(&mut repr.grad);
4624 v.visit_tensor_mut(&mut repr.out);
4625 }
4626 ModuleOperationIr::MaxPool1d(repr) => {
4627 v.visit_tensor_mut(&mut repr.x);
4628 v.visit_tensor_mut(&mut repr.out);
4629 }
4630 ModuleOperationIr::MaxPool1dWithIndices(repr) => {
4631 v.visit_tensor_mut(&mut repr.x);
4632 v.visit_tensor_mut(&mut repr.out);
4633 v.visit_tensor_mut(&mut repr.out_indices);
4634 }
4635 ModuleOperationIr::MaxPool1dWithIndicesBackward(repr) => {
4636 v.visit_tensor_mut(&mut repr.x);
4637 v.visit_tensor_mut(&mut repr.indices);
4638 v.visit_tensor_mut(&mut repr.grad);
4639 v.visit_tensor_mut(&mut repr.out);
4640 }
4641 ModuleOperationIr::MaxPool2d(repr) => {
4642 v.visit_tensor_mut(&mut repr.x);
4643 v.visit_tensor_mut(&mut repr.out);
4644 }
4645 ModuleOperationIr::MaxPool2dWithIndices(repr) => {
4646 v.visit_tensor_mut(&mut repr.x);
4647 v.visit_tensor_mut(&mut repr.out);
4648 v.visit_tensor_mut(&mut repr.out_indices);
4649 }
4650 ModuleOperationIr::MaxPool2dWithIndicesBackward(repr) => {
4651 v.visit_tensor_mut(&mut repr.x);
4652 v.visit_tensor_mut(&mut repr.indices);
4653 v.visit_tensor_mut(&mut repr.grad);
4654 v.visit_tensor_mut(&mut repr.out);
4655 }
4656 ModuleOperationIr::Interpolate(repr) => {
4657 v.visit_tensor_mut(&mut repr.x);
4658 v.visit_tensor_mut(&mut repr.out);
4659 }
4660 ModuleOperationIr::InterpolateBackward(repr) => {
4661 v.visit_tensor_mut(&mut repr.x);
4662 v.visit_tensor_mut(&mut repr.grad);
4663 v.visit_tensor_mut(&mut repr.out);
4664 }
4665 ModuleOperationIr::Attention(repr) => {
4666 v.visit_tensor_mut(&mut repr.query);
4667 v.visit_tensor_mut(&mut repr.key);
4668 v.visit_tensor_mut(&mut repr.value);
4669 if let Some(mask) = &mut repr.mask {
4670 v.visit_tensor_mut(mask);
4671 }
4672 if let Some(attn_bias) = &mut repr.attn_bias {
4673 v.visit_tensor_mut(attn_bias);
4674 }
4675 v.visit_tensor_mut(&mut repr.out);
4676 if let Some(scale) = &mut repr.options.scale {
4677 v.visit_scalar_mut(scale);
4678 }
4679 if let Some(softcap) = &mut repr.options.softcap {
4680 v.visit_scalar_mut(softcap);
4681 }
4682 }
4683 ModuleOperationIr::CtcLoss(repr) => {
4684 v.visit_tensor_mut(&mut repr.log_probs);
4685 v.visit_tensor_mut(&mut repr.targets);
4686 v.visit_tensor_mut(&mut repr.input_lengths);
4687 v.visit_tensor_mut(&mut repr.target_lengths);
4688 v.visit_tensor_mut(&mut repr.out);
4689 }
4690 ModuleOperationIr::CtcLossBackward(repr) => {
4691 v.visit_tensor_mut(&mut repr.log_probs);
4692 v.visit_tensor_mut(&mut repr.targets);
4693 v.visit_tensor_mut(&mut repr.input_lengths);
4694 v.visit_tensor_mut(&mut repr.target_lengths);
4695 v.visit_tensor_mut(&mut repr.grad_loss);
4696 v.visit_tensor_mut(&mut repr.out);
4697 }
4698 ModuleOperationIr::LayerNorm(repr) => {
4699 v.visit_tensor_mut(&mut repr.input);
4700 v.visit_tensor_mut(&mut repr.gamma);
4701 if let Some(beta) = &mut repr.beta {
4702 v.visit_tensor_mut(beta);
4703 }
4704 v.visit_tensor_mut(&mut repr.out);
4705 v.visit_scalar_mut(&mut repr.epsilon);
4706 }
4707 ModuleOperationIr::Unfold4d(repr) => {
4708 v.visit_tensor_mut(&mut repr.x);
4709 v.visit_tensor_mut(&mut repr.out);
4710 }
4711 ModuleOperationIr::ConvTranspose1dWeightBackward(repr) => {
4712 v.visit_tensor_mut(&mut repr.x);
4713 v.visit_tensor_mut(&mut repr.weight);
4714 v.visit_tensor_mut(&mut repr.output_grad);
4715 v.visit_tensor_mut(&mut repr.out);
4716 }
4717 ModuleOperationIr::ConvTranspose1dBiasBackward(repr) => {
4718 v.visit_tensor_mut(&mut repr.x);
4719 v.visit_tensor_mut(&mut repr.bias);
4720 v.visit_tensor_mut(&mut repr.output_grad);
4721 v.visit_tensor_mut(&mut repr.out);
4722 }
4723 ModuleOperationIr::ConvTranspose2dWeightBackward(repr) => {
4724 v.visit_tensor_mut(&mut repr.x);
4725 v.visit_tensor_mut(&mut repr.weight);
4726 v.visit_tensor_mut(&mut repr.output_grad);
4727 v.visit_tensor_mut(&mut repr.out);
4728 }
4729 ModuleOperationIr::ConvTranspose2dBiasBackward(repr) => {
4730 v.visit_tensor_mut(&mut repr.x);
4731 v.visit_tensor_mut(&mut repr.bias);
4732 v.visit_tensor_mut(&mut repr.output_grad);
4733 v.visit_tensor_mut(&mut repr.out);
4734 }
4735 ModuleOperationIr::ConvTranspose3dWeightBackward(repr) => {
4736 v.visit_tensor_mut(&mut repr.x);
4737 v.visit_tensor_mut(&mut repr.weight);
4738 v.visit_tensor_mut(&mut repr.output_grad);
4739 v.visit_tensor_mut(&mut repr.out);
4740 }
4741 ModuleOperationIr::ConvTranspose3dBiasBackward(repr) => {
4742 v.visit_tensor_mut(&mut repr.x);
4743 v.visit_tensor_mut(&mut repr.bias);
4744 v.visit_tensor_mut(&mut repr.output_grad);
4745 v.visit_tensor_mut(&mut repr.out);
4746 }
4747 }
4748 }
4749}
4750
4751impl DistributedOperationIr {
4752 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
4753 match self {
4754 DistributedOperationIr::AllReduce(repr) => Box::new([&repr.tensor].into_iter()),
4755 DistributedOperationIr::SyncCollective => Box::new([].into_iter()),
4756 }
4757 }
4758
4759 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
4760 match self {
4761 DistributedOperationIr::AllReduce(repr) => Box::new([&repr.out].into_iter()),
4762 DistributedOperationIr::SyncCollective => Box::new([].into_iter()),
4763 }
4764 }
4765
4766 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
4767 let mut output = Vec::new();
4768
4769 match self {
4770 DistributedOperationIr::AllReduce(repr) => {
4771 repr.tensor.mark_read_only(nodes, &mut output);
4772 }
4773 DistributedOperationIr::SyncCollective => {}
4774 }
4775
4776 output
4777 }
4778
4779 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
4780 match self {
4781 DistributedOperationIr::AllReduce(repr) => {
4782 v.visit_tensor_mut(&mut repr.tensor);
4783 v.visit_tensor_mut(&mut repr.out);
4784 }
4785 DistributedOperationIr::SyncCollective => {}
4786 }
4787 }
4788}
4789
4790impl InitOperationIr {
4791 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
4792 Box::new([].into_iter())
4793 }
4794 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
4795 Box::new([&self.out].into_iter())
4796 }
4797
4798 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
4799 v.visit_tensor_mut(&mut self.out);
4800 }
4801}
4802
4803impl TensorIr {
4804 fn mark_read_only(&mut self, nodes: &[TensorId], output: &mut Vec<TensorIr>) {
4805 if self.status == TensorStatus::ReadWrite && nodes.contains(&self.id) {
4806 output.push(self.clone());
4807 self.status = TensorStatus::ReadOnly;
4808 }
4809 }
4810}
4811
4812impl core::hash::Hash for RandomOpIr {
4813 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
4814 self.out.hash(state);
4815
4816 match self.distribution {
4817 Distribution::Default => 1u8.hash(state),
4818 Distribution::Bernoulli(_) => 2u8.hash(state),
4819 Distribution::Uniform(_, _) => 3u8.hash(state),
4820 Distribution::Normal(_, _) => 4u8.hash(state),
4821 }
4822 }
4823}
4824
4825pub trait OperationOutput<O> {
4827 fn output(self) -> O;
4829
4830 fn outputs<const N: usize>(self) -> [O; N];
4832}
4833
4834impl<O: core::fmt::Debug> OperationOutput<O> for Vec<O> {
4835 fn output(self) -> O {
4836 let [tensor] = self.outputs();
4837 tensor
4838 }
4839
4840 fn outputs<const N: usize>(self) -> [O; N] {
4841 self.try_into().unwrap()
4842 }
4843}
4844
4845#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4847pub struct SortOpIr {
4848 pub input: TensorIr,
4850 pub dim: usize,
4852 pub descending: bool,
4854 pub out: TensorIr,
4856}
4857
4858#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4860pub struct SortWithIndicesOpIr {
4861 pub input: TensorIr,
4863 pub dim: usize,
4865 pub descending: bool,
4867 pub out: TensorIr,
4869 pub out_indices: TensorIr,
4871}
4872
4873#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4875pub struct LayerNormOpIr {
4876 pub input: TensorIr,
4878 pub gamma: TensorIr,
4880 pub beta: Option<TensorIr>,
4882 pub epsilon: ScalarIr,
4884 pub out: TensorIr,
4886}
4887
4888#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4890pub struct Unfold4dOpIr {
4891 pub x: TensorIr,
4893 pub kernel_size: [usize; 2],
4895 pub options: Unfold4dOptionsIr,
4897 pub out: TensorIr,
4899}
4900
4901#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4903pub struct Unfold4dOptionsIr {
4904 pub stride: [usize; 2],
4906 pub padding: [usize; 2],
4908 pub dilation: [usize; 2],
4910}
4911
4912#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4914pub struct ConvTranspose1dWeightBackwardOpIr {
4915 pub x: TensorIr,
4917 pub weight: TensorIr,
4919 pub output_grad: TensorIr,
4921 pub options: ConvTranspose1dOptionsIr,
4923 pub out: TensorIr,
4925}
4926
4927#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4929pub struct ConvTranspose1dBiasBackwardOpIr {
4930 pub x: TensorIr,
4932 pub bias: TensorIr,
4934 pub output_grad: TensorIr,
4936 pub out: TensorIr,
4938}
4939
4940#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4942pub struct ConvTranspose2dWeightBackwardOpIr {
4943 pub x: TensorIr,
4945 pub weight: TensorIr,
4947 pub output_grad: TensorIr,
4949 pub options: ConvTranspose2dOptionsIr,
4951 pub out: TensorIr,
4953}
4954
4955#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4957pub struct ConvTranspose2dBiasBackwardOpIr {
4958 pub x: TensorIr,
4960 pub bias: TensorIr,
4962 pub output_grad: TensorIr,
4964 pub out: TensorIr,
4966}
4967
4968#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4970pub struct ConvTranspose3dWeightBackwardOpIr {
4971 pub x: TensorIr,
4973 pub weight: TensorIr,
4975 pub output_grad: TensorIr,
4977 pub options: ConvTranspose3dOptionsIr,
4979 pub out: TensorIr,
4981}
4982
4983#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4985pub struct ConvTranspose3dBiasBackwardOpIr {
4986 pub x: TensorIr,
4988 pub bias: TensorIr,
4990 pub output_grad: TensorIr,
4992 pub out: TensorIr,
4994}
4995
4996#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
4999pub struct HardSigmoidOpIr {
5000 pub tensor: TensorIr,
5002 pub alpha: ScalarIr,
5004 pub beta: ScalarIr,
5006 pub out: TensorIr,
5008}
5009
5010#[derive(Clone, Debug, Hash, PartialEq, Serialize, Deserialize)]
5016pub enum ActivationOperationIr {
5017 Relu(UnaryOpIr),
5019 ReluBackward(BinaryOpIr),
5022 LeakyRelu(ScalarOpIr),
5025 PRelu(BinaryOpIr),
5028 Gelu(UnaryOpIr),
5030 GeluBackward(BinaryOpIr),
5033 Sigmoid(UnaryOpIr),
5035 SigmoidBackward(BinaryOpIr),
5038 HardSigmoid(HardSigmoidOpIr),
5040 LogSigmoid(UnaryOpIr),
5042 LogSigmoidBackward(BinaryOpIr),
5045 Softmax(DimOpIr),
5047 LogSoftmax(DimOpIr),
5049 Softmin(DimOpIr),
5051}
5052
5053macro_rules! activation_ir_tensor_access {
5058 ($( $variant:ident => [ $($field:ident),+ ] ),+ $(,)?) => {
5059 impl ActivationOperationIr {
5060 fn inputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
5061 match self {
5062 $( Self::$variant(repr) => Box::new([$(&repr.$field),+].into_iter()), )+
5063 }
5064 }
5065
5066 fn outputs(&self) -> Box<dyn Iterator<Item = &TensorIr> + '_> {
5067 match self {
5068 $( Self::$variant(repr) => Box::new([&repr.out].into_iter()), )+
5069 }
5070 }
5071
5072 fn mark_read_only(&mut self, nodes: &[TensorId]) -> Vec<TensorIr> {
5073 let mut output = Vec::new();
5074 match self {
5075 $( Self::$variant(repr) => {
5076 $( repr.$field.mark_read_only(nodes, &mut output); )+
5077 } )+
5078 }
5079 output
5080 }
5081 }
5082 };
5083}
5084
5085impl ActivationOperationIr {
5086 fn visit_mut(&mut self, v: &mut impl IrVisitorMut) {
5087 match self {
5088 ActivationOperationIr::Relu(repr) => {
5089 v.visit_tensor_mut(&mut repr.input);
5090 v.visit_tensor_mut(&mut repr.out);
5091 }
5092 ActivationOperationIr::ReluBackward(repr) => {
5093 v.visit_tensor_mut(&mut repr.lhs);
5094 v.visit_tensor_mut(&mut repr.rhs);
5095 v.visit_tensor_mut(&mut repr.out);
5096 }
5097 ActivationOperationIr::LeakyRelu(repr) => {
5098 v.visit_tensor_mut(&mut repr.lhs);
5099 v.visit_tensor_mut(&mut repr.out);
5100 v.visit_scalar_mut(&mut repr.rhs);
5101 }
5102 ActivationOperationIr::PRelu(repr) => {
5103 v.visit_tensor_mut(&mut repr.lhs);
5104 v.visit_tensor_mut(&mut repr.rhs);
5105 v.visit_tensor_mut(&mut repr.out);
5106 }
5107 ActivationOperationIr::Gelu(repr) => {
5108 v.visit_tensor_mut(&mut repr.input);
5109 v.visit_tensor_mut(&mut repr.out);
5110 }
5111 ActivationOperationIr::GeluBackward(repr) => {
5112 v.visit_tensor_mut(&mut repr.lhs);
5113 v.visit_tensor_mut(&mut repr.rhs);
5114 v.visit_tensor_mut(&mut repr.out);
5115 }
5116 ActivationOperationIr::Sigmoid(repr) => {
5117 v.visit_tensor_mut(&mut repr.input);
5118 v.visit_tensor_mut(&mut repr.out);
5119 }
5120 ActivationOperationIr::SigmoidBackward(repr) => {
5121 v.visit_tensor_mut(&mut repr.lhs);
5122 v.visit_tensor_mut(&mut repr.rhs);
5123 v.visit_tensor_mut(&mut repr.out);
5124 }
5125 ActivationOperationIr::HardSigmoid(repr) => {
5126 v.visit_tensor_mut(&mut repr.tensor);
5127 v.visit_tensor_mut(&mut repr.out);
5128 v.visit_scalar_mut(&mut repr.alpha);
5129 v.visit_scalar_mut(&mut repr.beta);
5130 }
5131 ActivationOperationIr::LogSigmoid(repr) => {
5132 v.visit_tensor_mut(&mut repr.input);
5133 v.visit_tensor_mut(&mut repr.out);
5134 }
5135 ActivationOperationIr::LogSigmoidBackward(repr) => {
5136 v.visit_tensor_mut(&mut repr.lhs);
5137 v.visit_tensor_mut(&mut repr.rhs);
5138 v.visit_tensor_mut(&mut repr.out);
5139 }
5140 ActivationOperationIr::Softmax(repr) => {
5141 v.visit_tensor_mut(&mut repr.input);
5142 v.visit_tensor_mut(&mut repr.out);
5143 }
5144 ActivationOperationIr::LogSoftmax(repr) => {
5145 v.visit_tensor_mut(&mut repr.input);
5146 v.visit_tensor_mut(&mut repr.out);
5147 }
5148 ActivationOperationIr::Softmin(repr) => {
5149 v.visit_tensor_mut(&mut repr.input);
5150 v.visit_tensor_mut(&mut repr.out);
5151 }
5152 }
5153 }
5154}
5155
5156activation_ir_tensor_access! {
5157 Relu => [input],
5158 ReluBackward => [lhs, rhs],
5159 LeakyRelu => [lhs],
5160 PRelu => [lhs, rhs],
5161 Gelu => [input],
5162 GeluBackward => [lhs, rhs],
5163 Sigmoid => [input],
5164 SigmoidBackward => [lhs, rhs],
5165 HardSigmoid => [tensor],
5166 LogSigmoid => [input],
5167 LogSigmoidBackward => [lhs, rhs],
5168 Softmax => [input],
5169 LogSoftmax => [input],
5170 Softmin => [input],
5171}
5172
5173#[cfg(test)]
5174mod tests {
5175 use super::*;
5176 use burn_backend::{DType, Shape};
5177
5178 #[test]
5179 #[should_panic(expected = "expected symmetric convolution padding")]
5180 fn conv3d_options_ir_rejects_asymmetric_padding() {
5181 let options =
5182 ConvOptions::new_with_padding([1, 1, 1], [(0, 1), (2, 2), (3, 3)], [1, 1, 1], 1);
5183
5184 let _: Conv3dOptionsIr = options.into();
5185 }
5186
5187 fn tensor(id: u64) -> TensorIr {
5188 TensorIr::uninit(TensorId::new(id), Shape::from([2, 2]), DType::F32)
5189 }
5190
5191 #[derive(Default)]
5193 struct CollectVisitor {
5194 scalars: Vec<ScalarIr>,
5195 rewrite_scalar: Option<ScalarIr>,
5196 }
5197
5198 impl IrVisitorMut for CollectVisitor {
5199 fn visit_tensor_mut(&mut self, tensor: &mut TensorIr) {
5200 tensor.id = TensorId::new(tensor.id.value() + 100);
5201 }
5202
5203 fn visit_scalar_mut(&mut self, scalar: &mut ScalarIr) {
5204 self.scalars.push(*scalar);
5205 if let Some(value) = self.rewrite_scalar {
5206 *scalar = value;
5207 }
5208 }
5209 }
5210
5211 #[test]
5212 fn visit_mut_visits_all_tensors_and_scalars() {
5213 let mut mul = OperationIr::NumericFloat(
5215 DType::F32,
5216 NumericOperationIr::MulScalar(ScalarOpIr {
5217 lhs: tensor(1),
5218 rhs: ScalarIr::Float(2.0),
5219 out: tensor(2),
5220 }),
5221 );
5222
5223 let mut visitor = CollectVisitor {
5225 rewrite_scalar: Some(ScalarIr::Float(9.0)),
5226 ..Default::default()
5227 };
5228 mul.visit_mut(&mut visitor);
5229
5230 let ids: Vec<u64> = mul
5231 .inputs()
5232 .chain(mul.outputs())
5233 .map(|t| t.id.value())
5234 .collect();
5235 assert_eq!(ids, vec![101, 102]);
5236 assert_eq!(visitor.scalars, vec![ScalarIr::Float(2.0)]);
5238
5239 let mut after = CollectVisitor::default();
5241 mul.visit_mut(&mut after);
5242 assert_eq!(after.scalars, vec![ScalarIr::Float(9.0)]);
5243
5244 let mut reshape = OperationIr::BaseFloat(BaseOperationIr::Reshape(ShapeOpIr {
5246 input: tensor(10),
5247 out: tensor(11),
5248 }));
5249
5250 let mut visitor = CollectVisitor::default();
5251 reshape.visit_mut(&mut visitor);
5252 let ids: Vec<u64> = reshape
5253 .inputs()
5254 .chain(reshape.outputs())
5255 .map(|t| t.id.value())
5256 .collect();
5257 assert_eq!(ids, vec![110, 111]);
5258 assert_eq!(visitor.scalars.len(), 0);
5259 }
5260
5261 #[test]
5262 fn pad_ir_tracks_shape_tensors_and_constant_value() {
5263 let input = TensorIr::uninit(TensorId::new(1), Shape::from([2, 3]), DType::F32);
5264 let desc = PadOpIr::create(
5265 input,
5266 vec![(1, 2), (3, 4)],
5267 PadModeIr::Constant(ScalarIr::Float(5.0)),
5268 || TensorId::new(2),
5269 );
5270 assert_eq!(desc.out.shape, Shape::from([5, 10]));
5271
5272 let mut op = OperationIr::NumericFloat(DType::F32, NumericOperationIr::Pad(desc));
5273 let mut visitor = CollectVisitor {
5274 rewrite_scalar: Some(ScalarIr::Float(7.0)),
5275 ..Default::default()
5276 };
5277 op.visit_mut(&mut visitor);
5278
5279 let ids = op
5280 .inputs()
5281 .chain(op.outputs())
5282 .map(|tensor| tensor.id.value())
5283 .collect::<Vec<_>>();
5284 assert_eq!(ids, vec![101, 102]);
5285 assert_eq!(visitor.scalars, vec![ScalarIr::Float(5.0)]);
5286
5287 let OperationIr::NumericFloat(_, NumericOperationIr::Pad(desc)) = op else {
5288 panic!("expected pad operation");
5289 };
5290 assert_eq!(desc.mode, PadModeIr::Constant(ScalarIr::Float(7.0)));
5291 }
5292}