1/**
2 * Copyright (c) Glow Contributors. See CONTRIBUTORS file.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16#include "NodeBuilder.h"
17
18#include <fstream>
19#include <iostream>
20
21int main(int argc, char **argv) {
22 if (argc != 6) {
23 std::cerr << "Usage: " << argv[0]
24 << " output.h output.cpp output.def import.h export.h\n";
25 return -1;
26 }
27
28 std::cout << "Writing node descriptors to:\n\t" << argv[1] << "\n\t"
29 << argv[2] << "\n\t" << argv[3] << "\n\t" << argv[4] << "\n\t"
30 << argv[5] << "\n";
31
32 std::ofstream hFile(argv[1]);
33 std::ofstream cFile(argv[2]);
34 std::ofstream dFile(argv[3]);
35 std::ofstream iFile(argv[4]);
36 std::ofstream eFile(argv[5]);
37
38 Builder BB(hFile, cFile, dFile, iFile, eFile);
39
40 //===--------------------------------------------------------------------===//
41 // Input/Output nodes
42 //===--------------------------------------------------------------------===//
43
44 BB.includeHeader("glow/Graph/Nodes.h");
45
46 BB.declareNode("Storage");
47 BB.declareNode("Constant");
48 BB.declareNode("Placeholder");
49
50 BB.newNode("Save")
51 .addInput("Input")
52 .addInput("Output")
53 .addExtraMethod("Placeholder *getPlaceholder() const;",
54 "Placeholder *SaveNode::getPlaceholder() const { return "
55 "llvm::cast<Placeholder>(Output_.getNode()); };")
56 .addOverwrittenInput("Output")
57 .setHasSideEffects(true)
58 .dataParallel()
59 .skipAutogenSerialization()
60 .setDocstring("Specifies a node whose Input will be copied to Output."
61 "This node prevents graph optimizations from eliminating "
62 "this node and all of its ancestor nodes. Generally "
63 "intended to save the final result of a network.");
64
65 //===--------------------------------------------------------------------===//
66 // Convolution / Pool / FC
67 //===--------------------------------------------------------------------===//
68
69 BB.newNode("Pad")
70 .addInput("Input")
71 .addMember(MemberType::Enum, "Mode")
72 .addMember(MemberType::VectorSigned, "Pads")
73 .addMember(MemberType::Float, "Value")
74 .addResultFromCtorArg()
75 .setDocstring(
76 "Performs padding of a given input tensor. The Padding information "
77 "must be specified for each dimension of the tensor in Pads (start "
78 "and end padding). In case the padding is negative, it means that "
79 "the tensor must be cropped. Mode defines how extra padding elements "
80 "are created. Supported modes are defined in the PaddingMode enum: "
81 "CONSTANT, REFLECT, EDGE. Value is only used with the CONSTANT "
82 "mode.");
83
84 BB.newNode("Convolution")
85 .addInput("Input")
86 .addInput("Filter")
87 .addInput("Bias")
88 .addMember(MemberType::VectorUnsigned, "Kernels")
89 .addMember(MemberType::VectorUnsigned, "Strides")
90 .addMember(MemberType::VectorUnsigned, "Pads", /* addSetter */ true)
91 .addMember(MemberType::Unsigned, "Group", /* addSetter */ true)
92 .addMember(MemberType::VectorUnsigned, "Dilation")
93 .addMember(MEMBER_TYPE_INFO(glow::ConvolutionLayout), "Layout")
94 .addFusedActivation()
95 .addResultFromCtorArg()
96 .addGradient()
97 .setDocstring(
98 "Performs 2D Convolution using a given Input, Filter, and "
99 "Bias tensors, as well as provided Kernels, Strides, Pads, "
100 "Group and Dilation. Supported Layouts are defined in the "
101 "ConvolutionLayout enum: NHWC and NCHW. Supported FusedActivations "
102 "are defined in the FusedActivation enum.");
103
104 BB.newNode("ChannelwiseQuantizedConvolution")
105 .addInput("Input")
106 .addInput("Filter")
107 .addInput("Bias")
108 .addInput("FilterScales")
109 .addInput("FilterOffsets")
110 .addInput("BiasScales")
111 .addInput("BiasOffsets")
112 .addMember(MemberType::VectorUnsigned, "Kernels", /* addSetter */ true)
113 .addMember(MemberType::VectorUnsigned, "Strides")
114 .addMember(MemberType::VectorUnsigned, "Pads", /* addSetter */ true)
115 .addMember(MemberType::Unsigned, "Group", /* addSetter */ true)
116 .addMember(MemberType::VectorUnsigned, "Dilation")
117 .addFusedActivation()
118 .addResultFromCtorArg()
119 .setDocstring(
120 "Performs 2D Convolution using a given Input, Filter, and "
121 "Bias tensors, as well as provided Kernels, Strides, Pads, "
122 "and Group. The filter channel wise quantization parameters "
123 "are provided by FilterScales and FilterOffsets while the "
124 "bias channel wise quantization parameters are provided by "
125 "BiasScales and BiasOffsets.");
126
127 BB.newNode("ConvTranspose")
128 .addInput("Input")
129 .addInput("Filter")
130 .addInput("Bias")
131 .addMember(MemberType::VectorUnsigned, "Kernels")
132 .addMember(MemberType::VectorUnsigned, "Strides")
133 .addMember(MemberType::VectorUnsigned, "Pads")
134 .addMember(MemberType::Unsigned, "Group")
135 .addMember(MemberType::VectorUnsigned, "Dilation")
136 .addResultFromCtorArg()
137 .setDocstring("Performs 2D Transposed Convolution using a given Input,"
138 "Filter, and Bias tensors, as well as provided Kernels,"
139 "Strides, Pads, and Group.");
140
141 BB.newNode("Convolution3D")
142 .addInput("Input")
143 .addInput("Filter")
144 .addInput("Bias")
145 .addMember(MemberType::VectorUnsigned, "Kernels")
146 .addMember(MemberType::VectorUnsigned, "Strides")
147 .addMember(MemberType::VectorUnsigned, "Pads")
148 .addMember(MemberType::Unsigned, "Group")
149 .addResultFromCtorArg()
150 .addGradient()
151 .setDocstring("Performs 3D Convolution using a given Input, Filter, and "
152 "Bias tensors, as well as provided Kernels, Strides, Pads, "
153 "and Group.");
154
155 BB.newNode("MaxPool")
156 .addInput("Input")
157 .addMember(MemberType::VectorUnsigned, "Kernels")
158 .addMember(MemberType::VectorUnsigned, "Strides")
159 .addMember(MemberType::VectorUnsigned, "Pads", /* addSetter */ true)
160 .addMember(MemberType::Enum, "Layout")
161 .addResultFromCtorArg("Result")
162 .addResultFromCtorArg("Argmax")
163 .addGradient()
164 .setDocstring(
165 "Performs a Max Pool with Argmax operation on the Input "
166 "given provided Kernels, Strides, and Pads. Argmax is a flattened "
167 "index corresponding to respective max element. Supported layouts "
168 "are defined in the ConvolutionLayout enum: NHWC and NCHW.");
169
170 BB.newNode("ArgMax")
171 .addInput("Input")
172 .addMember(MemberType::Unsigned, "Axis")
173 .addMember(MemberType::Boolean, "KeepDims")
174 .addResultFromCtorArg()
175 .setDocstring("Finds index of a maximum element along Axis. "
176 "If KeepDims is not true, the axis is removed from output");
177
178 BB.newNode("ArgMin")
179 .addInput("Input")
180 .addMember(MemberType::Unsigned, "Axis")
181 .addMember(MemberType::Boolean, "KeepDims")
182 .addResultFromCtorArg()
183 .setDocstring("Finds index of a minimum element along Axis. "
184 "If KeepDims is not true, the axis is removed from output");
185
186 BB.newNode("AvgPool")
187 .addInput("Input")
188 .addMember(MemberType::VectorUnsigned, "Kernels")
189 .addMember(MemberType::VectorUnsigned, "Strides")
190 .addMember(MemberType::VectorUnsigned, "Pads", /* addSetter */ true)
191 .addMember(MemberType::Enum, "Layout")
192 .addMember(MemberType::Boolean, "CountIncludePads")
193 .addResultFromCtorArg()
194 .addGradient()
195 .setDocstring(
196 "Performs an Average Pool operation on the Input given "
197 "provided Kernels, Strides, and Pads. Supported layouts are defined "
198 "in the ConvolutionLayout enum: NHWC, NCHW, NTHWC and NCTHW.");
199
200 BB.newNode("AdaptiveAvgPool")
201 .addInput("Input")
202 .addResultFromCtorArg()
203 .addGradient()
204 .setDocstring(
205 "Performs an Adaptive Average Pool operation on the Input given");
206
207 BB.newNode("Gemm")
208 .addInput("A")
209 .addInput("B")
210 .addInput("C")
211 .addMember(MemberType::Float, "Alpha")
212 .addMember(MemberType::Float, "Beta")
213 .addMember(MemberType::Boolean, "TransposeA")
214 .addMember(MemberType::Boolean, "TransposeB")
215 .addResultFromCtorArg()
216 .setDocstring(
217 "Computes Y = Alpha * A * B + Beta * C where Alpha, Beta are scalars "
218 "and A, B, C are matrices. If TransposeA or TransposeB is used then "
219 "A or B is additionally transposed.");
220
221 BB.newNode("FullyConnected")
222 .addInput("Input")
223 .addInput("Weights")
224 .addInput("Bias")
225 .addResultFromCtorArg()
226 .addGradient()
227 .setDocstring("Creates a FullyConnected node where the Input tensor and "
228 "Weights tensor are multiplied, and then the Bias tensor "
229 "is added to it, producing the Output.");
230
231 BB.newNode("RowwiseQuantizedFullyConnected")
232 .addInput("Input")
233 .addInput("Weights")
234 .addInput("Scales")
235 .addInput("Offsets")
236 .addInput("Bias")
237 .addResultFromCtorArg()
238 .setDocstring(
239 "Creates a RowwiseQuantizedFullyConnected node where the Input "
240 "matrix and the transpose of Weights matrix are multiplied, and "
241 "then the Bias vector is broadcast-added to the result. Input, "
242 "Bias and Result are regularly quantized, while Weights use row-wise"
243 "quantization.");
244
245 BB.newNode("DynamicQuantizedFullyConnected")
246 .addInput("Input")
247 .addInput("Weights")
248 .addInput("Bias")
249 .addMember(MemberType::Boolean, "IsSymmetric")
250 .addMember(MemberType::Boolean, "IsPerBatchElement")
251 .addResultFromCtorArg()
252 .setDocstring(
253 "Creates a DynamicQuantizedFullyConnectedNode which implement the "
254 "functionality of dynamic_quantization => quantized_fc => "
255 "dequantize, which support symmteric/asymmetric quantization. "
256 "Quantize parameters are automatically selected from range of input, "
257 "while weights are pre-quantized to int8 and bias are whether float "
258 "or int32");
259
260 BB.newNode("DynamicRowwiseQuantizedFullyConnected")
261 .addInput("Input")
262 .addInput("Weights")
263 .addInput("Bias")
264 .addInput("Scales")
265 .addInput("Offsets")
266 .addMember(MemberType::Boolean, "IsSymmetric")
267 .addMember(MemberType::Boolean, "IsPerBatchElement")
268 .addResultFromCtorArg()
269 .setDocstring(
270 "Creates a DynamicRowwiseQuantizedFullyConnectedNode which implement "
271 "the functionality of dynamic_quantization => quantized_fc => "
272 "dequantize, which support symmteric/asymmetric quantization. "
273 "Quantize parameters are automatically selected from range of input, "
274 "while weights are pre-rowwise-quantized to int8, whose rowwise "
275 "params stored in Scales and Offsets, and bias are whether float "
276 "or int32");
277 //===--------------------------------------------------------------------===//
278 // Normalization
279 //===--------------------------------------------------------------------===//
280
281 BB.newNode("BatchNormalization")
282 .addInput("Input")
283 .addInput("Scale")
284 .addInput("Bias")
285 .addInput("Mean")
286 .addInput("Var")
287 .addMember(MemberType::Unsigned, "ChannelIdx")
288 .addMember(MemberType::Float, "Epsilon")
289 .addMember(MemberType::Float, "Momentum")
290 .addResultFromCtorArg()
291 .addGradient()
292 .setDocstring("Performs batch normalization on the Input tensor with the "
293 "provided Scale, Bias, Mean, Var, ChannelIdx, Epsilon, and "
294 "Momentum. Similar to Caffe2 SpatialBN, and ONNX "
295 "BatchNormalization operator.");
296
297 BB.newNode("InstanceNormalization")
298 .addInput("Input")
299 .addInput("Scale")
300 .addInput("Bias")
301 .addMember(MemberType::Unsigned, "ChannelIdx")
302 .addMember(MemberType::Float, "Epsilon")
303 .addResult("Input.getType()")
304 .setDocstring("Performs instance normalization on the Input tensor with "
305 "the provided Scale, Bias, Epsilon. Similar to ONNX "
306 "InstanceNormalization operator.");
307
308 BB.newNode("MeanVarNormalization")
309 .addInput("Input")
310 .addInput("Mean")
311 .addInput("Var")
312 .addMember(MemberType::Unsigned, "ChannelIdx")
313 .addMember(MemberType::Float, "Momentum")
314 .addResult("Mean.getType()", "NewMean")
315 .addResult("Var.getType()", "NewVar")
316 .setDocstring("Calculates new normalized mean and variance based on the "
317 "input mean, variance, and input.");
318
319 BB.newNode("LocalResponseNormalization")
320 .addInput("Input")
321 .addMember(MemberType::Unsigned, "HalfWindowSize")
322 .addMember(MemberType::Float, "Alpha")
323 .addMember(MemberType::Float, "Beta")
324 .addMember(MemberType::Float, "K")
325 .addResult("Input.getType()")
326 .addGradient()
327 .setDocstring("Performs local response normalization on the Input tensor "
328 "with the provided Scale, Bias, Mean, Var, ChannelIdx, "
329 "Epsilon, and Momentum. Similar to Caffe2 and ONNX LRN.");
330
331 BB.newNode("LayerNormalization")
332 .addInput("Input")
333 .addInput("Scale")
334 .addInput("Bias")
335 .addMember(MemberType::Float, "Epsilon")
336 .addResultFromCtorArg()
337 .setDocstring("Performs layer normalization on the Input tensor with the "
338 "provided Scale, Bias, and Epsilon. Layer sizes are "
339 "determined by the dimensions of Scale and Bias. Similar "
340 "to PyTorch layer_norm.");
341
342 BB.newNode("BatchBoxCox")
343 .addInput("Input")
344 .addInput("Lambda1")
345 .addInput("Lambda2")
346 .addMember(MemberType::Float, "Epsilon")
347 .addResult("Input.getType()")
348 .setDocstring("Apply box-cox transform for each column for each column "
349 "in NxD input tensor");
350
351 BB.newNode("VectorNorm")
352 .addInput("Input")
353 .addMember(MemberType::Unsigned, "Axis")
354 .addMember(MemberType::Unsigned, "P")
355 .addResultFromCtorArg()
356 .setDocstring("Performs L2 norm of the Input operand based on Axis.");
357
358 //===--------------------------------------------------------------------===//
359 // Bucketing
360 //===--------------------------------------------------------------------===//
361
362 BB.newNode("Bucketize")
363 .addInput("Input")
364 .addMember(MemberType::VectorFloat, "Boundaries")
365 .addResultFromCtorArg()
366 .setDocstring("Performs bucketization on the input given Boundaries");
367
368 //===--------------------------------------------------------------------===//
369 // Loss operations
370 //===--------------------------------------------------------------------===//
371
372 BB.newNode("SoftMax")
373 .addInput("Input")
374 .addInput("Selected")
375 .addResultFromCtorArg()
376 .addGradient()
377 .setDocstring("Performs SoftMax normalization on the Input tensor.");
378
379 BB.newNode("LogSoftMax")
380 .addInput("Input")
381 .addInput("Selected")
382 .addResultFromCtorArg()
383 .addGradient()
384 .setDocstring("Performs LogSoftMax normalization on the Input tensor.");
385
386 BB.newNode("CrossEntropyLoss")
387 .addInput("P")
388 .addInput("Labels")
389 .addResultFromCtorArg("CE")
390 .addGradient()
391 .setDocstring("Computes the average cross entropy loss of the input.");
392
393 BB.newNode("Regression")
394 .addInput("Input")
395 .addInput("Expected")
396 .addResult("Input.getType()")
397 .addGradient()
398 .setDocstring(
399 "Takes an Input tensor and creates a regression output layer.");
400
401 BB.newNode("SigmoidCrossEntropyWithLogits")
402 .addInput("Logits")
403 .addInput("Targets")
404 .addResultFromCtorArg()
405 .setDocstring("Computes the sigmoid cross entropy between two inputs.");
406
407 //===--------------------------------------------------------------------===//
408 // Arithmetic
409 //===--------------------------------------------------------------------===//
410
411 BB.newNode("Add")
412 .addInput("LHS")
413 .addInput("RHS")
414 .addResultFromCtorArg()
415 .dataParallel()
416 .addGradient()
417 .setDocstring("Performs Add on the LHS and RHS operands.");
418
419 BB.newNode("Mul")
420 .addInput("LHS")
421 .addInput("RHS")
422 .addResultFromCtorArg()
423 .dataParallel()
424 .addGradient()
425 .setDocstring("Performs Mul on the LHS and RHS operands.");
426
427 BB.newNode("Sub")
428 .addInput("LHS")
429 .addInput("RHS")
430 .addResultFromCtorArg()
431 .dataParallel()
432 .addGradient()
433 .setDocstring("Performs Sub on the LHS and RHS operands.");
434
435 BB.newNode("Div")
436 .addInput("LHS")
437 .addInput("RHS")
438 .addResultFromCtorArg()
439 .dataParallel()
440 .addGradient()
441 .setDocstring("Performs Div on the LHS and RHS operands.");
442
443 BB.newNode("FloorDiv")
444 .addInput("LHS")
445 .addInput("RHS")
446 .addMember(MemberType::Boolean, "Truncate")
447 .addResultFromCtorArg()
448 .dataParallel()
449 .setDocstring(
450 "Performs Div on the LHS and RHS operands, then Floor. If Truncate "
451 "is set to true then truncate the quotient to zero instead.");
452
453 BB.newNode("Fmod")
454 .addInput("LHS")
455 .addInput("RHS")
456 .addResultFromCtorArg()
457 .dataParallel()
458 .setDocstring("Computes the element-wise remainder of division.");
459
460 BB.newNode("Max")
461 .addInput("LHS")
462 .addInput("RHS")
463 .addResultFromCtorArg()
464 .dataParallel()
465 .setDocstring("Performs Max on the LHS and RHS operands.");
466
467 BB.newNode("Min")
468 .addInput("LHS")
469 .addInput("RHS")
470 .addResultFromCtorArg()
471 .dataParallel()
472 .setDocstring("Performs Min on the LHS and RHS operands.");
473
474 BB.newNode("CmpEQ")
475 .addInput("LHS")
476 .addInput("RHS")
477 .addResultFromCtorArg()
478 .dataParallel()
479 .setDocstring("Performs an element-wise EQUAL comparison between the "
480 "LHS and RHS operands.");
481
482 BB.newNode("CmpNEQ")
483 .addInput("LHS")
484 .addInput("RHS")
485 .addResultFromCtorArg()
486 .dataParallel()
487 .setDocstring("Performs an element-wise NOT EQUAL comparison between "
488 "the LHS and RHS operands.");
489
490 BB.newNode("CmpLT")
491 .addInput("LHS")
492 .addInput("RHS")
493 .addResultFromCtorArg()
494 .dataParallel()
495 .setDocstring("Performs an element-wise LESS THAN comparison between "
496 "the LHS and RHS operands.");
497
498 BB.newNode("CmpLTE")
499 .addInput("LHS")
500 .addInput("RHS")
501 .addResultFromCtorArg()
502 .dataParallel()
503 .setDocstring("Performs an element-wise LESS THAN OR EQUAL comparison "
504 "between the LHS and RHS operands.");
505
506 BB.newNode("Pow")
507 .addInput("LHS")
508 .addInput("RHS")
509 .addResultFromCtorArg()
510 .dataParallel()
511 .setDocstring("Performs elementwise pow(LHS, RHS).");
512
513 BB.newNode("And")
514 .addInput("LHS")
515 .addInput("RHS")
516 .addResultFromCtorArg()
517 .dataParallel()
518 .setDocstring("Performs an element-wise logical AND between the LHS and "
519 "RHS operands.");
520
521 BB.newNode("BitwiseAnd")
522 .addInput("LHS")
523 .addInput("RHS")
524 .addResultFromCtorArg()
525 .dataParallel()
526 .setDocstring("Performs an element-wise bitwise AND between the LHS and "
527 "RHS operands.");
528
529 BB.newNode("Or")
530 .addInput("LHS")
531 .addInput("RHS")
532 .addResultFromCtorArg()
533 .dataParallel()
534 .setDocstring("Performs an element-wise logical OR between the LHS and "
535 "RHS operands.");
536
537 BB.newNode("BitwiseOr")
538 .addInput("LHS")
539 .addInput("RHS")
540 .addResultFromCtorArg()
541 .dataParallel()
542 .setDocstring("Performs an element-wise bitwise OR between the LHS and "
543 "RHS operands.");
544
545 BB.newNode("Xor")
546 .addInput("LHS")
547 .addInput("RHS")
548 .addResultFromCtorArg()
549 .dataParallel()
550 .setDocstring("Performs an element-wise logical XOR between the LHS and "
551 "RHS operands.");
552
553 BB.newNode("BitwiseXor")
554 .addInput("LHS")
555 .addInput("RHS")
556 .addResultFromCtorArg()
557 .dataParallel()
558 .setDocstring("Performs an element-wise bitwise XOR between the LHS and "
559 "RHS operands.");
560
561 BB.newNode("Not")
562 .addInput("Input")
563 .addResultFromCtorArg()
564 .dataParallel()
565 .setDocstring("Performs an element-wise logical NOT of the Input "
566 "operand.");
567
568 BB.newNode("BitwiseNot")
569 .addInput("Input")
570 .addResultFromCtorArg()
571 .dataParallel()
572 .setDocstring("Performs an element-wise bitwise NOT of the Input "
573 "operand.");
574
575 BB.newNode("Neg")
576 .addInput("Input")
577 .addResultFromCtorArg()
578 .dataParallel()
579 .setDocstring("Performs an element-wise negation (sign flip) of the "
580 "Input operand.");
581
582 BB.newNode("Abs")
583 .addInput("Input")
584 .addResultFromCtorArg()
585 .dataParallel()
586 .setDocstring("Performs an element-wise ABS(x) of the Input operand.");
587
588 BB.newNode("Floor")
589 .addInput("Input")
590 .addResultFromCtorArg()
591 .dataParallel()
592 .setDocstring("Performs an element-wise FLOOR(x) of the Input operand.");
593
594 BB.newNode("Sign")
595 .addInput("Input")
596 .addResultFromCtorArg()
597 .dataParallel()
598 .setDocstring("Performs an element-wise Sign(x) of the Input operand");
599
600 BB.newNode("Ceil")
601 .addInput("Input")
602 .addResultFromCtorArg()
603 .dataParallel()
604 .setDocstring("Performs an element-wise CEIL(x) of the Input operand.");
605
606 BB.newNode("Round")
607 .addInput("Input")
608 .addResultFromCtorArg()
609 .dataParallel()
610 .setDocstring("Performs an element-wise ROUND(x) of the Input operand.");
611
612 BB.newNode("Truncate")
613 .addInput("Input")
614 .addResultFromCtorArg()
615 .dataParallel()
616 .setDocstring(
617 "Performs an element-wise TRUNCATE(x) of the Input operand.");
618
619 BB.newNode("Sqrt")
620 .addInput("Input")
621 .addResultFromCtorArg()
622 .dataParallel()
623 .setDocstring("Performs an element-wise SQRT(x) of the Input operand.");
624
625 BB.newNode("Rsqrt")
626 .addInput("Input")
627 .addResultFromCtorArg()
628 .dataParallel()
629 .setDocstring("Performs an element-wise RSQRT(x) = 1 / SQRT(x) of the "
630 "Input operand.");
631
632 BB.newNode("Reciprocal")
633 .addInput("Input")
634 .addResultFromCtorArg()
635 .dataParallel()
636 .setDocstring("Performs an element-wise RECIPROCAL(x) = 1 / x of the "
637 "Input operand.");
638
639 BB.newNode("Sin")
640 .addInput("Input")
641 .addResultFromCtorArg()
642 .dataParallel()
643 .setDocstring("Performs an element-wise SIN(x) of the Input operand.");
644
645 BB.newNode("Cos")
646 .addInput("Input")
647 .addResultFromCtorArg()
648 .dataParallel()
649 .setDocstring("Performs an element-wise COS(x) of the Input operand.");
650
651 // clang-format off
652 BB.newNode("Log")
653 .addInput("Input")
654 .addResultFromCtorArg()
655 .dataParallel()
656 .setDocstring("Performs element-wise natural log to the Input.");
657
658 BB.newNode("Acos")
659 .addInput("Input")
660 .addResultFromCtorArg()
661 .dataParallel()
662 .setDocstring("Performs an element-wise Arccosine(x) of the Input operand.");
663
664 BB.newNode("Asin")
665 .addInput("Input")
666 .addResultFromCtorArg()
667 .dataParallel()
668 .setDocstring("Performs an element-wise Arcsine(x) of the Input operand.");
669
670 BB.newNode("Atan")
671 .addInput("Input")
672 .addResultFromCtorArg()
673 .dataParallel()
674 .setDocstring("Performs an element-wise Arctan(x) of the Input operand.");
675
676 BB.newNode("Erf")
677 .addInput("Input")
678 .addResultFromCtorArg()
679 .dataParallel()
680 .setDocstring("Performs an element-wise Erf(x) of the Input operand.");
681
682 BB.newNode("Exp")
683 .addInput("Input")
684 .addResultFromCtorArg()
685 .dataParallel()
686 .setDocstring("Performs element-wise exponential to the Input.");
687 // clang-format on
688
689 BB.newNode("Logit")
690 .addInput("Input")
691 .addMember(MemberType::Float, "Epsilon")
692 .addResultFromCtorArg()
693 .dataParallel()
694 .setDocstring("Computes elementwise: result = log(input / (1 - input)).");
695
696 BB.newNode("NonZero")
697 .addInput("Cond")
698 .addResultFromCtorArg()
699 .dataParallel()
700 .setDocstring("Selects indices of the true elements in Cond");
701
702 BB.newNode("Select")
703 .addInput("Cond")
704 .addInput("LHS")
705 .addInput("RHS")
706 .addResultFromCtorArg()
707 .dataParallel()
708 .setDocstring("Selects between values on the LHS or RHS, depending on "
709 "the value of Cond. Cond is generated by the compare "
710 "instruction, and is target- and type-specific.");
711
712 BB.newNode("BatchedAdd")
713 .addInput("Batch")
714 .addInput("Slice")
715 .addResultFromCtorArg()
716 .setDocstring(
717 "Adds the 'Slice' operand to each one of the slices in the batch.");
718
719 BB.newNode("BatchedMul")
720 .addInput("Batch")
721 .addInput("Slice")
722 .addResultFromCtorArg()
723 .setDocstring("Multiplies the 'Slice' operand to each one of the slices "
724 "in the batch.");
725
726 BB.newNode("MatMul")
727 .addInput("LHS")
728 .addInput("RHS")
729 .addResultFromCtorArg()
730 .setDocstring("Performs matrix multiplication between the LHS and RHS."
731 "Example: (A, Z) x (Z, B) => (A, B)");
732
733 BB.newNode("BatchMatMul")
734 .addInput("LHS")
735 .addInput("RHS")
736 .addResultFromCtorArg()
737 .setDocstring("Performs batch matrix multiplication between the LHS and "
738 "RHS. The operands are a stack of two dimensional "
739 "matrices. Example: (N, A, Z) x (N, Z, B) => (N, A, B)");
740
741 BB.newNode("BatchedReduceAdd")
742 .addInput("Batch")
743 .addMember(MemberType::Unsigned, "Axis")
744 .addResultFromCtorArg()
745 .setDocstring("Accumulates all of the layers in the batch and produce a "
746 "tensor that has the same dimensions as the input tensor "
747 "without the first dimension.");
748
749 BB.newNode("BatchedReduceSumSquare")
750 .addInput("Batch")
751 .addMember(MemberType::Unsigned, "Axis")
752 .addResultFromCtorArg()
753 .setDocstring(
754 "Accumulates squares of all of the layers in the batch and produce a "
755 "tensor that has the same dimensions as the input tensor "
756 "without the first dimension.");
757
758 BB.newNode("BatchedReduceMean")
759 .addInput("Batch")
760 .addMember(MemberType::VectorUnsigned, "Axes")
761 .addResultFromCtorArg()
762 .setDocstring("Performs Average Mean operation on the Input given "
763 "Axes.");
764
765 BB.newNode("BatchedReduceMin")
766 .addInput("Batch")
767 .addMember(MemberType::VectorUnsigned, "Axes")
768 .addResultFromCtorArg()
769 .setDocstring("Performs Reduce Min operation on the Input given "
770 "Axes.");
771
772 BB.newNode("BatchedReduceMax")
773 .addInput("Batch")
774 .addMember(MemberType::VectorUnsigned, "Axes")
775 .addResultFromCtorArg()
776 .setDocstring("Performs Reduce Max operation on the Input given "
777 "Axes.");
778
779 BB.newNode("BatchedReduceProd")
780 .addInput("Batch")
781 .addMember(MemberType::Unsigned, "Axis")
782 .addResultFromCtorArg()
783 .setDocstring("Accumulates the product all of the layers in the batch "
784 " and produce a tensor that has the same dimensions as "
785 " the input tensor without the first dimension.");
786
787 BB.newNode("ChannelShuffle")
788 .addInput("Input")
789 .addMember(MemberType::Unsigned, "Group")
790 .addMember(MemberType::Unsigned, "Kernel")
791 .addResultFromCtorArg()
792 .setDocstring("Performs Channel shuffle.");
793
794 BB.newNode("CumSum")
795 .addInput("Input")
796 .addMember(MemberType::Int64, "Dim")
797 .addMember(MemberType::Unsigned, "Exclusive")
798 .addMember(MemberType::Unsigned, "Reverse")
799 .addResultFromCtorArg()
800 .dataParallel()
801 .setDocstring("Performs a Cumulative Sum operation over a 1D vector with "
802 "flags for working in exclusive mode and in reverse. In "
803 "each case the output size is the same as in input size."
804 "e.g (default) [1, 2, 3, 4] -> [1, 3, 6, 10]. "
805 "(exclusive) [1, 2, 3, 4] -> [0, 1, 3, 6]. "
806 "(reverse) [1, 2, 3, 4] -> [10, 9, 7, 4]. ");
807
808 BB.newNode("LengthsSum")
809 .addInput("Data")
810 .addInput("Lengths")
811 .addResultFromCtorArg()
812 .setDocstring("Sums slices of the outermost dimension of Data in groups "
813 "defined by Lengths. The first Lengths[0] slices are "
814 "added together and stored in Result[0], the subsequent "
815 "Lengths[1] slices are added together and stored in "
816 "Result[1], etc.");
817
818 BB.newNode("SparseLengthsSum")
819 .addInput("Data")
820 .addInput("Indices")
821 .addInput("Lengths")
822 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
823 .addMember(MemberType::Float, "AvgLength")
824 .addResultFromCtorArg()
825 .addGradient()
826 .setDocstring("Gathers slices of the outer-most dimension of Data "
827 "indexed by Indices vector, and then accumulates them into "
828 "len(Lengths) entries: first Lengths[0] slices are "
829 "aggregated to Result[0], next Lengths[1] slices are "
830 "aggregated to Result[1], etc. I.e. sum(Lengths) must be "
831 "equal to len(Indices).");
832
833 BB.newNode("SparseLengthsWeightedSum")
834 .addInput("Data")
835 .addInput("Weights")
836 .addInput("Indices")
837 .addInput("Lengths")
838 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
839 .addMember(MemberType::Float, "AvgLength")
840 .addResultFromCtorArg()
841 .addGradient()
842 .setDocstring("Gathers slices of the outer-most dimension of Data "
843 "indexed by Indices vector, and then accumulates them into "
844 "len(Lengths) entries: first Lengths[0] slices are "
845 "aggregated to Result[0], next Lengths[1] slices are "
846 "aggregated to Result[1], etc. I.e. sum(Lengths) must be "
847 "equal to len(Indices). Before doing aggregation, each "
848 "individual slice is scaled by its weight: Result[0] = "
849 "Weights[0] * Slice(0) + Weights[1] * Slice(1) + ... "
850 "It implies that len(Weights) == len(Indices).");
851
852 BB.newNode("Embedding")
853 .addInput("Weights")
854 .addInput("Indices")
855 .addMember(MemberType::Int64, "PadIdx")
856 .addMember(MemberType::Boolean, "Scale")
857 .addMember(MemberType::Boolean, "Sparse")
858 .addResultFromCtorArg()
859 .setDocstring("Gathers slices of the outer-most dimension of Weights "
860 "indexed by Indices tensor.");
861
862 BB.newNode("EmbeddingBag")
863 .addInput("Data")
864 .addInput("Weights")
865 .addInput("Indices")
866 .addInput("Offsets")
867 .addMember(MemberType::Boolean, "HasEndOffset")
868 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
869 .addMember(MemberType::Float, "AvgLength")
870 .addResultFromCtorArg()
871 .setDocstring(
872 "Gathers slices of the outer-most dimension of Data "
873 "indexed by Indices vector, and then accumulates them into "
874 "len(Offsets) entries: first slice between Offsets[0] and Offsets[1] "
875 "(or total length if there's only one elem in Offsets) are "
876 "aggregated to Result[0], etc. I.e. largest offset must be "
877 "less than or equal to len(Indices). Before doing aggregation, each "
878 "individual slice is scaled by its weight: Result[0] = "
879 "Weights[0] * Slice(0) + Weights[1] * Slice(1) + ... "
880 "It implies that len(Weights) == len(Indices).");
881
882 BB.newNode("EmbeddingBagByteRowwiseOffsets")
883 .addInput("Data")
884 .addInput("Weights")
885 .addInput("Indices")
886 .addInput("Offsets")
887 .addMember(MemberType::Boolean, "UseFP16Accumulation",
888 /* addSetter */ true)
889 .addMember(MemberType::Boolean, "HasEndOffset")
890 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
891 .addMember(MemberType::Float, "AvgLength")
892 .addResultFromCtorArg()
893 .setDocstring("Same as FusedRowwiseQuantizedSparseLengthsWeightedSum but "
894 "using offsets instead of lengths.");
895
896 BB.newNode("RowwiseQuantizedSparseLengthsWeightedSum")
897 .addInput("Data")
898 .addInput("Scales")
899 .addInput("Offsets")
900 .addInput("Weights")
901 .addInput("Indices")
902 .addInput("Lengths")
903 .addMember(MemberType::Boolean, "UseFP16Accumulation",
904 /* addSetter */ true)
905 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
906 .addMember(MemberType::Float, "AvgLength")
907 .addResultFromCtorArg()
908 .setDocstring("Gathers slices of the outer-most dimension of Data "
909 "indexed by Indices vector, and then accumulates them into "
910 "len(Lengths) entries: first Lengths[0] slices are "
911 "aggregated to Result[0], next Lengths[1] slices are "
912 "aggregated to Result[1], etc. I.e. sum(Lengths) must be "
913 "equal to len(Indices). Before doing aggregation, each "
914 "individual slice is scaled by its weight: Result[0] = "
915 "Weights[0] * Slice(0) + Weights[1] * Slice(1) + ... "
916 "It implies that len(Weights) == len(Indices). The input "
917 "data is rowwise-quantized, where the Scales and Offsets "
918 "are 1D tensors of length equal to the first dim of Data.");
919
920 BB.newNode("FusedRowwiseQuantizedSparseLengthsWeightedSum")
921 .addInput("Data")
922 .addInput("Weights")
923 .addInput("Indices")
924 .addInput("Lengths")
925 .addMember(MemberType::Boolean, "UseFP16Accumulation",
926 /* addSetter */ true)
927 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
928 .addMember(MemberType::Float, "AvgLength")
929 .addResultFromCtorArg()
930 .setDocstring("Gathers slices of the outer-most dimension of Data "
931 "indexed by Indices vector, and then accumulates them into "
932 "len(Lengths) entries: first Lengths[0] slices are "
933 "aggregated to Result[0], next Lengths[1] slices are "
934 "aggregated to Result[1], etc. I.e. sum(Lengths) must be "
935 "equal to len(Indices). Before doing aggregation, each "
936 "individual slice is scaled by its weight: Result[0] = "
937 "Weights[0] * Slice(0) + Weights[1] * Slice(1) + ... "
938 "It implies that len(Weights) == len(Indices). The input "
939 "data is fused rowwise-quantized, where the Scales and "
940 "Offsets are appended to the end of each row. Thus, Data "
941 "must be a two-dimensional tensor.");
942
943 BB.newNode("FusedRowwiseQuantizedSparseLengthsSum")
944 .addInput("Data")
945 .addInput("Indices")
946 .addInput("Lengths")
947 .addMember(MemberType::Boolean, "UseFP16Accumulation",
948 /* addSetter */ true)
949 .addMember(MEMBER_TYPE_INFO(glow::LengthsMode), "LengthsMode")
950 .addMember(MemberType::Float, "AvgLength")
951 .addResultFromCtorArg()
952 .setDocstring("Gathers slices of the outer-most dimension of Data "
953 "indexed by Indices vector, and then accumulates them into "
954 "len(Lengths) entries: first Lengths[0] slices are "
955 "aggregated to Result[0], next Lengths[1] slices are "
956 "aggregated to Result[1], etc. I.e. sum(Lengths) must be "
957 "equal to len(Indices). The input "
958 "data is fused rowwise-quantized, where the Scales and "
959 "Offsets are appended to the end of each row. Thus, Data "
960 "must be a two-dimensional tensor.");
961
962 BB.newNode("LengthsToRanges")
963 .addInput("Lengths")
964 .addResultFromCtorArg()
965 .setDocstring("Given a vector of segment lengths, calculates offsets of "
966 "each segment and packs them next to the lengths. For the "
967 "input vector of length N the output is a Nx2 matrix with "
968 "(offset, lengths) packaged for each segment.");
969
970 BB.newNode("LengthsRangeFill")
971 .addInput("Lengths")
972 .addResultFromCtorArg()
973 .setDocstring(
974 "Converts an input Lengths 1D vector into a range sequence.");
975
976 BB.newNode("BatchSparseToDense")
977 .addInput("Lengths")
978 .addInput("Indices")
979 .addInput("Values")
980 .addMember(MemberType::Float, "DefaultValue")
981 .addMember(MemberType::Unsigned, "DenseLastDim")
982 .addResultFromCtorArg()
983 .setDocstring(
984 "Converts the sparse representation specified by "
985 "(Lengths, Indices, Values) into a dense one. In the dense "
986 "representation, elements of the lengths vector represent the number "
987 "of indices in the corresponding batch, where each batch "
988 "contains each value from Values at the "
989 "corresponding index specified in Indices, and is filled with "
990 "DefaultValue otherwise. Within each batch, Indices shouldn't "
991 "contain duplicate indices.");
992
993 BB.newNode("FillExamplesWithIndicator")
994 .addInput("Data")
995 .addInput("Indicator")
996 .addResultFromCtorArg()
997 .setDocstring("Inserts zeros into data along axis=0 for indices where "
998 "indicator is zero.");
999
1000 BB.newNode("SparseToDenseMask")
1001 .addInput("Indices")
1002 .addInput("Values")
1003 .addInput("DefaultValue")
1004 .addInput("Lengths")
1005 .addMember(MemberType::VectorDimT, "Mask")
1006 .addResultFromCtorArg()
1007 .setDocstring(
1008 "Converts the sparse representation specified by the pair "
1009 "(Indices, Values) into a dense one, where compacted tensor only "
1010 "contains IDs from given Mask. Indices cannot contain duplicate "
1011 "values. Lengths is used to distinguish elements from different "
1012 "examples of one batch. That is, first Lengths[0] index-value pairs "
1013 "belong to batch's example 0, next Lengths[1] pairs belong to "
1014 "example 1, and so on.");
1015
1016 // clang-format off
1017 BB.newNode("IsNaN")
1018 .addInput("Input")
1019 .addResultFromCtorArg()
1020 .dataParallel()
1021 .setDocstring("Determines whether each element of the Input is NaN and "
1022 "generates a mask that can be consumed by a Select node.");
1023 // clang-format on
1024
1025 BB.newNode("ReplaceNaN")
1026 .addInput("Input")
1027 .addMember(MemberType::Float, "Value")
1028 .addResultFromCtorArg()
1029 .setDocstring("Replaces NaNs found in Input with Value.");
1030
1031 BB.newNode("Modulo")
1032 .addInput("Input")
1033 .addMember(MemberType::Int64, "Divisor")
1034 .addMember(MemberType::Boolean, "SignFollowDivisor")
1035 .addResultFromCtorArg()
1036 .dataParallel()
1037 .setDocstring("Performs elementwise modulo operation on the input where "
1038 "each element in the output is the corresponding element "
1039 "in the input data modulo Divisor.");
1040
1041 BB.newNode("BatchedPairwiseDotProduct")
1042 .addMember(MemberType::VectorNodeValue, "Inputs")
1043 .addResultFromCtorArg()
1044 .setDocstring(
1045 "Performs batched pairwise dot products of the input vectors");
1046
1047 BB.newNode("BatchedPairwiseDotProductGrad")
1048 .addInput("OutputGrad")
1049 .hasExtraResults()
1050 .addMember(MemberType::VectorNodeValue, "OriginalInputs")
1051 .setDocstring(
1052 "Performs the gradient operation for BatchedPairwiseDotProduct");
1053
1054 BB.newNode("BatchedUnaryEmbeddingsBags")
1055 .addInput("Weights")
1056 .addInput("TableOffsets")
1057 .addInput("Offsets")
1058 .addInput("Indices")
1059 .addResultFromCtorArg()
1060 .setDocstring("Sum weight embeddings according to offsets and indices");
1061
1062 BB.newNode("IntNBitSplitEmbeddingBags")
1063 .addInput("DevWeights")
1064 .addInput("UvmWeights")
1065 .addInput("WeightsPlacements")
1066 .addInput("WeightsOffsets")
1067 .addInput("WeightsTys")
1068 .addInput("DimOffsets")
1069 .addInput("Indices")
1070 .addInput("Offsets")
1071 .addMember(MemberType::Int64, "TotalDims")
1072 .addMember(MEMBER_TYPE_INFO(glow::SplitEmbeddingPoolingMode),
1073 "PoolingMode")
1074 .addMember(MEMBER_TYPE_INFO(glow::SplitEmbeddingSparseType),
1075 "OutputDType")
1076 .addResultFromCtorArg()
1077 .setDocstring("Table based batched embeddingbags with quantization "
1078 "support. Experimental only and subject to change.");
1079
1080 BB.newNode("IntNBitSplitEmbeddingWeightedBags")
1081 .addInput("DevWeights")
1082 .addInput("UvmWeights")
1083 .addInput("WeightsPlacements")
1084 .addInput("WeightsOffsets")
1085 .addInput("WeightsTys")
1086 .addInput("DimOffsets")
1087 .addInput("Indices")
1088 .addInput("Offsets")
1089 .addInput("IndiceWeight")
1090 .addMember(MemberType::Int64, "TotalDims")
1091 .addMember(MEMBER_TYPE_INFO(glow::SplitEmbeddingPoolingMode),
1092 "PoolingMode")
1093 .addMember(MEMBER_TYPE_INFO(glow::SplitEmbeddingSparseType),
1094 "OutputDType")
1095 .addResultFromCtorArg()
1096 .setDocstring(
1097 "Table based batched embeddingbags with quantization support and "
1098 "indice weights. Experimental only and subject to change.");
1099
1100 //===--------------------------------------------------------------------===//
1101 // Fillers
1102 //===--------------------------------------------------------------------===//
1103
1104 BB.newNode("GaussianFill")
1105 .addInput("Input")
1106 .addMember(MemberType::Float, "Mean")
1107 .addMember(MemberType::Float, "Scale")
1108 .addMember(MemberType::Float, "Seed")
1109 .addResultFromCtorArg()
1110 .setDocstring("Fills an output tensor with samples drawn from a normal "
1111 "distribution specified by the mean and standard deviation "
1112 "arguments. The output tensor shape is determined by the "
1113 "input shape if provided, and shape otherwise");
1114
1115 //===--------------------------------------------------------------------===//
1116 // Non-linearities
1117 //===--------------------------------------------------------------------===//
1118
1119 BB.newNode("Relu")
1120 .addInput("Input")
1121 .addResultFromCtorArg()
1122 .dataParallel()
1123 .addGradient()
1124 .setDocstring(
1125 "Applies ReLU, max(0, x), to each element in the Input tensor.");
1126
1127 BB.newNode("HardSwish")
1128 .addInput("Input")
1129 .addResultFromCtorArg()
1130 .dataParallel()
1131 .setDocstring("Applies HardSwish to each element in the Input tensor.");
1132
1133 BB.newNode("Gelu")
1134 .addInput("Input")
1135 .addResultFromCtorArg()
1136 .dataParallel()
1137 .setDocstring("Applies GeLU, to each element in the Input tensor.");
1138
1139 BB.newNode("Clip")
1140 .addInput("Input")
1141 .addMember(MemberType::Float, "Min")
1142 .addMember(MemberType::Float, "Max")
1143 .addResultFromCtorArg()
1144 .dataParallel()
1145 .setDocstring("Clip range of inputs to lie in [Min, Max].");
1146
1147 BB.newNode("PRelu")
1148 .addInput("Input")
1149 .addInput("Slope")
1150 .addResultFromCtorArg()
1151 .dataParallel()
1152 .setDocstring("Applies PReLU, slope * min(0, x) + max(0, x), to each "
1153 "element in the Input tensor.");
1154
1155 BB.newNode("Sigmoid")
1156 .addInput("Input")
1157 .addResultFromCtorArg()
1158 .dataParallel()
1159 .addGradient()
1160 .setDocstring("Applies Sigmoid, 1 / (1 + exp(-x)), to each element in "
1161 "the Input tensor.");
1162
1163 BB.newNode("Swish")
1164 .addInput("Input")
1165 .addResultFromCtorArg()
1166 .dataParallel()
1167 .setDocstring("Applies Swish, X * Sigmoid(X), to each element in "
1168 "the Input tensor.");
1169
1170 BB.newNode("Tanh")
1171 .addInput("Input")
1172 .addResultFromCtorArg()
1173 .dataParallel()
1174 .addGradient()
1175 .setDocstring("Applies hyperbolic tangent to each element in the Input "
1176 "tensor.");
1177
1178 BB.newNode("LeakyRelu")
1179 .addInput("Input")
1180 .addMember(MemberType::Float, "Alpha")
1181 .addResultFromCtorArg()
1182 .dataParallel()
1183 .setDocstring(
1184 "Applies LeakyReLU = x for positive x and alpha * x for negative x "
1185 "to each element in the Input tensor.");
1186
1187 BB.newNode("SoftPlus")
1188 .addInput("Input")
1189 .addResultFromCtorArg()
1190 .dataParallel()
1191 .setDocstring("Performs SoftPlus, ln(exp(x) + 1), to each element in the "
1192 "Input tensor.");
1193
1194 //===--------------------------------------------------------------------===//
1195 // Shape transformations
1196 //===--------------------------------------------------------------------===//
1197
1198 BB.newNode("Reshape")
1199 .addInput("Input")
1200 .addMember(MemberType::VectorDimT, "Dims")
1201 .addMember(MemberType::String, "Layout")
1202 .addResultFromCtorArg()
1203 .setDocstring("Reshape the Input tensor to shape Dims.");
1204
1205 BB.newNode("Transpose")
1206 .addInput("Input")
1207 .addMember(MemberType::VectorUnsigned, "Shuffle")
1208 .addMember(MemberType::String, "Layout")
1209 .addResultFromCtorArg()
1210 .setDocstring("Transpose the Input tensor based on the vector Shuffle, "
1211 "which assigns a new axis for each dimension in Input.");
1212
1213 BB.newNode("Concat")
1214 .addMember(MemberType::VectorNodeValue, "Inputs")
1215 .addMember(MemberType::Unsigned, "Dim")
1216 .addResultFromCtorArg()
1217 .setDocstring("The concat operator adds two tensors together.\nThe "
1218 "parameter 'dim' specifies the dimension to use when "
1219 "joining the tensors.");
1220
1221 BB.newNode("Slice")
1222 .addInput("Input")
1223 .addMember(MemberType::VectorDimT, "Start")
1224 .addResultFromCtorArg()
1225 .setDocstring("Produces a slice of the Input tensor. The Start vector "
1226 "defines the starting indices for each dimension from "
1227 "which the slice should be taken. The end index for each "
1228 "dimension is determined from the input type's shape.");
1229
1230 BB.newNode("InsertTensor")
1231 .addInput("Big")
1232 .addInput("Small")
1233 .addMember(MemberType::VectorDimT, "Start")
1234 .addMember(MemberType::Unsigned, "Count")
1235 .addMember(MemberType::Unsigned, "Axis")
1236 .addResult("Big.getType()")
1237 .setDocstring("Insert tensor Small into tensor Big given indices Start. "
1238 "Small is inserted Count times along Axis. The resulting "
1239 "Tensor will have the same type as the input Big tensor.");
1240
1241 // TODO: Rename "BatchDims" member to "Axis". This was attempted in #5565 but
1242 // some internal FB tests failed. The member needs to be renamed because that
1243 // is the true meaning of the member and that is what the implementation does
1244 // according to both Caffe2, ONNX and TFLite operator definitions.
1245 // https://github.com/onnx/onnx/blob/master/docs/Operators.md#gather
1246 // https://www.tensorflow.org/mlir/tfl_ops#tflgather_tflgatherop
1247 BB.newNode("Gather")
1248 .addInput("Data")
1249 .addInput("Indices")
1250 .addMember(MemberType::Unsigned, "BatchDims")
1251 .addResultFromCtorArg()
1252 .setDocstring("Gathers entries of the outer-most dimension of Data "
1253 "indexed by Indices, and concatenates them. Output tensor "
1254 "will have dimensions: {I_0, I_1, ... I_n, D_1, D_2, ... "
1255 "D_m}, where D_i and I_j denote Data and Indices "
1256 "dimensions respectively. If axis is not zero, the "
1257 "gather operator will treat the first axis as the "
1258 "batch and will concat the result of the gather operation "
1259 "on each sample in the batch.");
1260
1261 BB.newNode("GatherND")
1262 .addInput("Data")
1263 .addInput("Indices")
1264 .addMember(MemberType::Unsigned, "BatchDims")
1265 .addResultFromCtorArg()
1266 .setDocstring(
1267 "Given Data tensor of rank r >= 1, Indices tensor of rank q >= 1 "
1268 "This operator gathers slices of Data into "
1269 "an output tensor of rank q + r - Indices_shape[-1] - 1 .");
1270
1271 BB.newNode("GatherElements")
1272 .addInput("Data")
1273 .addInput("Indices")
1274 .addMember(MemberType::Unsigned, "Dim")
1275 .addResultFromCtorArg()
1276 .setDocstring(
1277 "GatherElements takes inputs data and indices of the same rank r "
1278 ">= 1 and an attribute axis specified by dim. It is an indexing"
1279 "operation that produces its output by indexing into the "
1280 "input data tensor at index positions determined by elements of the "
1281 "indices tensor. Its output shape is the same as the shape of "
1282 "indices and consists of one value (gathered from the data) for each "
1283 "element in indices.");
1284
1285 BB.newNode("GatherRanges")
1286 .addInput("Data")
1287 .addInput("Ranges")
1288 .addResultFromCtorArg("Output")
1289 .addResultFromCtorArg("Lengths")
1290 .setDocstring("Gathers entries of Data into Output in groups specified "
1291 "by the elements of Ranges. Each element of Ranges "
1292 "contains a list of pairs of indices of the form (index, "
1293 "length) which specify which entries of data to gather. "
1294 "The ordering of elements in Ranges and of pairs within an "
1295 "element is preserved in Output. Lengths contains the "
1296 "lengths of the ranges gathered by each list of pairs in "
1297 "Ranges.");
1298
1299 BB.newNode("ScatterData")
1300 .addInput("Data")
1301 .addInput("Indices")
1302 .addInput("Slices")
1303 .addMember(MemberType::Boolean, "Cumulative")
1304 .addResult("Data.getType()")
1305 .setDocstring(
1306 "Copies each slice from Slices into Data at the "
1307 "corresponding index in Indices. For example, given input "
1308 "Data {{1,2},{3,4},{5,6}}, Slices {{-3,-4}}, and Indices "
1309 "{{1}}, the result is {{1,2},{-3,-4},{5,6}}. It also supports "
1310 "multi-dimensional indices. For example, given input Data "
1311 "{{1,2},{3,4},{5,6}}, Slices {-3,-4}, and Indices {{1,0},{1,1}} also "
1312 "produces {{1,2},{-3,-4},{5,6}}. If Cumulative is true, the node "
1313 "adds values from Slices to Data instead of copying. For example, "
1314 "given input Data {{1,2},{3,4},{5,6}}, Slices {{-3,-4}}, and Indices "
1315 "{1}, the result is {{1,2},{0,0},{5,6}}. If an index is specified "
1316 "several times, its updates will be added several times as well.");
1317
1318 BB.newNode("Tile")
1319 .addInput("Input")
1320 .addMember(MemberType::Unsigned, "Count")
1321 .addMember(MemberType::Unsigned, "Axis")
1322 .addResultFromCtorArg()
1323 .setDocstring("Tile an Input tensor Count times along Axis.");
1324
1325 BB.newNode("BatchOneHot")
1326 .addInput("Data")
1327 .addInput("Lengths")
1328 .addInput("Values")
1329 .addResultFromCtorArg()
1330 .setDocstring("Expands each row of the Data to a row of zeros and ones, "
1331 "according to One Hot Encoding. i-th element of Result's "
1332 "row is one iff Values[i] equals to the corresponding "
1333 "element of Data.");
1334
1335 BB.newNode("SpaceToDepth")
1336 .addInput("Input")
1337 .addMember(MemberType::Unsigned, "BlockSize")
1338 .addResultFromCtorArg()
1339 .setDocstring("Given Input tensor of [N,H,W,C], where N is the batch "
1340 "axis, C is the channel or depth, H is the height and W is "
1341 "the width. This produces Output tensor of [N, "
1342 "H/BlockSize, W/BlockSize, C * "
1343 "BlockSize * BlockSize].");
1344
1345 BB.newNode("ResizeNearest")
1346 .addInput("Input")
1347 .addMember(MemberType::VectorFloat, "Scale")
1348 .addResultFromCtorArg()
1349 .setDocstring(
1350 "Given Input tensor of 3D, 4D, 5D or 6D, generates an "
1351 "Output tensor with resized spatial dimensions using nearest "
1352 "neighbor interpolation. The Output tensor is of shape "
1353 "floor(input_dimension * scale)");
1354
1355 BB.newNode("ResizeBilinear")
1356 .addInput("Input")
1357 .addMember(MemberType::VectorFloat, "Scale")
1358 .addResultFromCtorArg()
1359 .setDocstring(
1360 "Given Input tensor of [N,H,W,C], where N is the batch, C is the "
1361 "channel or depth, H is the height and W is the width, Generates an "
1362 "Output tensor with resized spatial dimensions using bilinear "
1363 "neighbor interpolation. The Output tensor is of shape "
1364 "floor(input_dimension * scale)");
1365
1366 BB.newNode("Broadcast")
1367 .addInput("Input")
1368 .addMember(MemberType::Unsigned, "Axis")
1369 .addMember(MemberType::VectorDimT, "TargetDim")
1370 .addResultFromCtorArg()
1371 .setDocstring(
1372 "Broadcast the Input tensor to TargetDim using Axis to indicate the "
1373 "offset between Input dimension and TargetDim");
1374
1375 BB.newNode("SparseLabelSplit")
1376 .addInput("Lengths")
1377 .addInput("Indices")
1378 .addInput("Values")
1379 .addMember(MemberType::Unsigned, "NumLabels")
1380 .addResultFromCtorArg("LabelValues")
1381 .addResultFromCtorArg("ExampleIds")
1382 .addResultFromCtorArg("GradientOffsetMap")
1383 .setDocstring("TODO");
1384
1385 //===--------------------------------------------------------------------===//
1386 // Reorder transformations
1387 //===--------------------------------------------------------------------===//
1388
1389 BB.newNode("Flip")
1390 .addInput("Input")
1391 .addMember(MemberType::Unsigned, "Axis")
1392 .addResultFromCtorArg()
1393 .setDocstring(
1394 "Reverse the order of elements in a tensor along the given axis. The "
1395 "shape of the tensor is preserved, but the elements are reordered. "
1396 "The node is inspired from Python numpy.");
1397
1398 //===--------------------------------------------------------------------===//
1399 // Nodes used for network training
1400 //===--------------------------------------------------------------------===//
1401
1402 BB.newNode("Splat")
1403 .addMember(MemberType::Float, "Value")
1404 .addResultFromCtorArg()
1405 .setDocstring("Generate a tensor of a specific type filled with 'Value'."
1406 "Splat always keep floating point value internally but can"
1407 "quantize it based on the output type.");
1408
1409 // clang-format off
1410 BB.newNode("Touch")
1411 .addResultFromCtorArg()
1412 .setDocstring(
1413 "Generate a tensor of a specific type without initializing "
1414 "it. This is useful when filling a big tensor entirely with "
1415 "multiple small slices using InsertTensor nodes such that "
1416 "the big tensor is not required to be initialized (filled) "
1417 "with some value prior to insertion. This node is intended "
1418 "to remove the overhead associated with the initialization "
1419 "in situations where it is not required.");
1420 // clang-format on
1421
1422 BB.newNode("SGD")
1423 .addInput("Gradient")
1424 .addInput("Weight")
1425 .addMember(MemberType::Float, "L1Decay")
1426 .addMember(MemberType::Float, "L2Decay")
1427 .addMember(MemberType::Float, "LearningRate")
1428 .addMember(MemberType::Float, "Momentum")
1429 .addMember(MemberType::Unsigned, "BatchSize")
1430 .addResult("Weight.getType()", "UpdatedWeight")
1431 .setHasSideEffects(true)
1432 .setDocstring("Stochastic Gradient Descent node used during training. "
1433 "Produces the updated weight that needs to be used "
1434 "instead of Weight for the next iteration.");
1435
1436 //===--------------------------------------------------------------------===//
1437 // Nodes used for debugging/profiling/printing
1438 //===--------------------------------------------------------------------===//
1439
1440 BB.newNode("TraceEvent")
1441 .addInput("Data")
1442 .addMember(MemberType::String, "EventName")
1443 .addMember(MemberType::String, "EventType")
1444 .addMember(MemberType::Unsigned, "Index")
1445 .setHasSideEffects(true)
1446 .setDocstring("Inserts a TraceEvent for profiling.");
1447
1448 //===--------------------------------------------------------------------===//
1449 // Nodes used by quantization.
1450 //===--------------------------------------------------------------------===//
1451
1452 BB.newNode("QuantizationProfile")
1453 .addInput("Input")
1454 .addInput("Histogram")
1455 .addInput("ComputationInfo")
1456 .addMember(MemberType::String, "ProfiledNodeName")
1457 .addMember(MemberType::Unsigned, "ProfiledOutputNumber")
1458 .addExtraMethod(
1459 "Placeholder *getHistogramPlaceholder() const ;\n",
1460 "Placeholder *QuantizationProfileNode::getHistogramPlaceholder() "
1461 "const { return "
1462 "llvm::cast<Placeholder>(Histogram_.getNode()); };\n")
1463 .addExtraMethod(
1464 "Placeholder *getComputationInfoPlaceholder() const;\n",
1465 "Placeholder "
1466 "*QuantizationProfileNode::getComputationInfoPlaceholder() const "
1467 "{ "
1468 "return llvm::cast<Placeholder>(ComputationInfo_.getNode()); };\n")
1469 .addOverwrittenInput("ComputationInfo")
1470 .addOverwrittenInput("Histogram")
1471 .setHasSideEffects(true)
1472 .setDocstring(
1473 "Generate profile (distribution of values) of the Input "
1474 "tensor. This data is used for quantization of the tensor "
1475 "later on. ProfiledNodeName contains the name of the node "
1476 "which is profiled by the QuantizationProfile node. "
1477 "ProfiledNodeName is helpful as lowering might transform the "
1478 "original graph. "
1479 "ProfiledOutputNumber contains the position of the node's output "
1480 "which gets profiled.");
1481
1482 BB.newNode("IntLookupTable")
1483 .addInput("Input")
1484 .addInput("Mapping")
1485 .addResultFromCtorArg()
1486 .dataParallel()
1487 .setDocstring("Simple mapping between quantized numbers."
1488 "This can be used as quantized sigmoid or tanh functions.");
1489
1490 BB.newNode("Quantize")
1491 .addInput("Input")
1492 .addResultFromCtorArg()
1493 .dataParallel()
1494 .setDocstring("Quantize floating point tensor. This operation converts "
1495 "floating point numbers to integers based on the given "
1496 "Scale and Offset. Scale and Offset are deduced from the "
1497 "type of the output."
1498 "x_q = clip(round(x/Scale) + Offset, -128, 127)");
1499
1500 BB.newNode("Dequantize")
1501 .addInput("Input")
1502 .addResultFromCtorArg()
1503 .dataParallel()
1504 .setDocstring("Convert quantized input tensor into the float "
1505 "representation. x = Scale * (x_q - Offset).");
1506
1507 BB.newNode("RescaleQuantized")
1508 .addInput("Input")
1509 .addResultFromCtorArg()
1510 .dataParallel()
1511 .setDocstring("Rescale the input quantized tensor to a new Scale and "
1512 "Offset. The new Scale and Offset are specified by the "
1513 "output type passed to the constructor");
1514
1515 //===--------------------------------------------------------------------===//
1516 // Nodes used by RNN
1517 //===--------------------------------------------------------------------===//
1518
1519 BB.newNode("TopK")
1520 .addInput("Input")
1521 .addMember(MemberType::Unsigned, "K")
1522 .addResultFromCtorArg("Values")
1523 .addResultFromCtorArg("Indices")
1524 .setDocstring("Finds the top K maximal elements for each vector in the "
1525 "tensor. Vectors are defined as the last dimension in the "
1526 "tensor. The input shape {D_0, D_1, ... D_n} results in "
1527 "the outputs {D_0, D_1, ... D_n-1, K}, sorted in "
1528 "non-decreasing order.");
1529
1530 BB.newNode("LSTMUnit")
1531 .addInput("Input")
1532 .addInput("C")
1533 .addResult("C.getType()", "newC")
1534 .addResult("C.getType()", "newH")
1535 .setDocstring(
1536 "A LSTM unit node, take Input as I, F, G, O,"
1537 "takes F from forget gate, I from input gate,"
1538 "O from output gate, G from cell gate and C from cell state. "
1539 "Calulates newC = sigmoid(F) * C + sigmoid(I) * tanh(G), "
1540 "newH = tanh(newC) * sigmoid(O).");
1541
1542 //===--------------------------------------------------------------------===//
1543 // Conversions
1544 //===--------------------------------------------------------------------===//
1545
1546 BB.newNode("ConvertTo")
1547 .addInput("Input")
1548 .addResultFromCtorArg()
1549 .dataParallel()
1550 .setDocstring(
1551 "Convert the input from its current type to the destination "
1552 "type. The input and output types must have the same shapes. "
1553 "Moreover the input and output types must not be quantized types. "
1554 "Quantized types should use the appropriate Quantize, Dequantize, "
1555 "and Rescale nodes.");
1556
1557 //===--------------------------------------------------------------------===//
1558 // Custom kernels invocations
1559 //===--------------------------------------------------------------------===//
1560 BB.newNode("ExternalFunctionCall")
1561 .addMember(MemberType::VectorNodeValue, "Inputs")
1562 // For now use single output.
1563 .addResultFromCtorArg()
1564 .addMember(MemberType::String, "FunctionName")
1565 // Examples are function source code, binary, or as needed.
1566 // The use of the following two fields will vary depending
1567 // on which kind of external function is used.
1568 .addMember(MemberType::String, "FunctionImpl")
1569 // Function kind, e.g. CUDA, function pointer, binary, backend-specific
1570 // source code.
1571 .addMember(MemberType::String, "FunctionKind")
1572 .skipAutogenSerialization()
1573 .setHasSideEffects(true)
1574 .setDocstring("This is a node representing an external function call. "
1575 "One possible use of this capability is to pass a source "
1576 "code for a function/kernel. When processing this node, a "
1577 "backend can compile and execute the source code. This "
1578 "node can also be used to pass binary or pointers to "
1579 "executable code. The semantics and implementation of this "
1580 "node not standardized and is very backend-specific.");
1581
1582 //===--------------------------------------------------------------------===//
1583 // Pre Processing
1584 //===--------------------------------------------------------------------===//
1585
1586 BB.newNode("AudioSpectrogram")
1587 .addInput("Input")
1588 .addInput("Window")
1589 .addInput("TwiddleFactors")
1590 .addInput("BitReverseIndices")
1591 .addInput("ComplexToRealWeights")
1592 .addMember(MemberType::Unsigned, "WindowSize")
1593 .addMember(MemberType::Unsigned, "WindowStride")
1594 .addMember(MemberType::Boolean, "MagnitudeSquared")
1595 .addResultFromCtorArg("Spectrogram")
1596 .setDocstring("Computes the spectrogram of a mono audio signal using "
1597 "given window size and stride. The FFT length used to "
1598 "compute the spectrogram is the next power of 2 (for a "
1599 "window size of 640 the FFT length is 1024). The length "
1600 "of each spectrogram window is FFT_length / 2 + 1. "
1601 "This node is inspired from TensorFlow.");
1602
1603 BB.newNode("MFCC")
1604 .addInput("Spectrogram")
1605 .addInput("MelWeights")
1606 .addInput("MelRanges")
1607 .addInput("DctMat")
1608 .addMember(MemberType::Float, "SampleRate")
1609 .addMember(MemberType::Float, "LowerFrequency")
1610 .addMember(MemberType::Float, "UpperFrequency")
1611 .addMember(MemberType::Unsigned, "FilterBankCount")
1612 .addMember(MemberType::Unsigned, "NumCoefficients")
1613 .addResultFromCtorArg("Coefficients")
1614 .setDocstring("Computes the MFCC (Mel Frequency Cepstral Coefficient) "
1615 "for the given spectrogram. This node is mostly used as "
1616 "feature extractor for voice/speech audio data in "
1617 "voice command or keyword spotting applications. The input "
1618 "is assumed to be a power spectrogram and not a magnitude."
1619 "This node is inspired from TensorFlow.");
1620
1621 //===--------------------------------------------------------------------===//
1622 // Post Processing
1623 //===--------------------------------------------------------------------===//
1624
1625 BB.newNode("NonMaxSuppression")
1626 .addInput("Boxes")
1627 .addInput("Scores")
1628 .addMember(MemberType::Unsigned, "CenterPointBox")
1629 .addMember(MemberType::Unsigned, "MaxOutputBoxesPerClass")
1630 .addMember(MemberType::Float, "IouThreshold")
1631 .addMember(MemberType::Float, "ScoreThreshold")
1632 .addMember(MemberType::Boolean, "IsTFVersion4")
1633 .addResultFromCtorArg("Indices")
1634 .addResultFromCtorArg("NumberOfSelectedIndices")
1635 .setDocstring("This is a mix of ONNX and TF NMSv4. It supports multiple "
1636 "classes and does per class NMS. It also supports TF NMS "
1637 "V4 by outputting indices and scalar tensor with number of "
1638 "valid indices. It pads the rest with global MIN box.");
1639
1640 BB.newNode("TFLiteDetectionPostProcess")
1641 .addInput("Boxes")
1642 .addInput("Scores")
1643 .addInput("Anchors")
1644 .addMember(MemberType::Unsigned, "NumClasses")
1645 .addMember(MemberType::Unsigned, "MaxDetections")
1646 .addMember(MemberType::Unsigned, "MaxClassesPerDetection")
1647 .addMember(MemberType::Unsigned, "MaxDetectionsPerClass")
1648 .addMember(MemberType::Float, "IouThreshold")
1649 .addMember(MemberType::Float, "ScoreThreshold")
1650 .addMember(MemberType::Float, "XScale")
1651 .addMember(MemberType::Float, "YScale")
1652 .addMember(MemberType::Float, "HScale")
1653 .addMember(MemberType::Float, "WScale")
1654 .addMember(MemberType::Boolean, "RegularNMS")
1655 .addResultFromCtorArg("DetectionBoxes")
1656 .addResultFromCtorArg("DetectionClasses")
1657 .addResultFromCtorArg("DetectionScores")
1658 .addResultFromCtorArg("NumDetections")
1659 .setDocstring(
1660 "This node is a TensorFlowLite version of NonMaxSuppresion. The node "
1661 "has the following inputs: Boxes with size [N, B, 4], Scores with "
1662 "size [N, B, C] and Anchors with size [B, 4] where N is the batch "
1663 "size, B is the number of boxes and C is the number of classes. "
1664 "The node has the following attributes (parameters): "
1665 "NumClasses - Number of classes (without the background class). "
1666 "MaxDetections - The maximum number of detections. "
1667 "MaxClassesPerDetection - Maximum classes per detection (Fast NMS). "
1668 "MaxDetectionsPerClass - Maximum detections per class (Regular NMS). "
1669 "IouThreshold - Detection threshold for IoU metric. "
1670 "ScoreThreshold - Detection threshold for scores. "
1671 "XScale - X scale used for decoding the boxes. "
1672 "YScale - Y scale used for decoding the boxes. "
1673 "HScale - H scale used for decoding the boxes. "
1674 "WScale - W scale used for decoding the boxes. "
1675 "RegularNMS - Whether the NMS is 'Regular' or 'Fast'. "
1676 "The node will have the following outputs: "
1677 "DetectionBoxes - the chosen boxes (float). "
1678 "DetectionClasses - the classes of the chosen boxes (int32). "
1679 "DetectionScores - the scores of the chosen boxes (float). "
1680 "NumDetections - number of chose boxes (int32). "
1681 "The first three output tensors will be allocated using the maximum "
1682 "number of possible detections (worst case scenario) but the actual "
1683 "usage will be given by the 'NumDetections' output. ");
1684
1685 //===--------------------------------------------------------------------===//
1686 // Region of Interest nodes
1687 //===--------------------------------------------------------------------===//
1688
1689 BB.newNode("ROIAlign")
1690 .addInput("FeatureMap")
1691 .addInput("Boxes")
1692 .addInput("BatchIndices")
1693 .addMember(MemberType::Enum, "Mode")
1694 .addMember(MemberType::Unsigned, "OutputHeight")
1695 .addMember(MemberType::Unsigned, "OutputWidth")
1696 .addMember(MemberType::Unsigned, "SamplingRatio")
1697 .addMember(MemberType::Float, "SpatialScale")
1698 .addMember(MemberType::Boolean, "Aligned")
1699 .addMember(MemberType::Boolean, "Rotated")
1700 .addResultFromCtorArg()
1701 .setDocstring(
1702 "Performs region of interest align (ROI) operator. "
1703 "FeatureMap - a tensor of [N,H,W,C]. N is the batch, C is the "
1704 "channel, H is the height, W is the width. "
1705 "Boxes - a tensor of [K,4] or [K,5] with format "
1706 "[[optinal_batch_index] x0, y0, x1, y1]. K is the number of boxes. "
1707 "BatchIndices - a tensor of [K,]. If N > 1 and Box shape is [K,4], "
1708 "BatchIndices must be valid. "
1709 "Output is a tensor with shape [K, OutputHeight, OutputWidth, C]. "
1710 "Aligned - if true, coordinates are aligned to a center of a pixel.");
1711
1712 BB.newNode("BBoxTransform")
1713 .addInput("Rois")
1714 .addInput("Deltas")
1715 .addInput("ImInfo")
1716 .addMember(MemberType::VectorFloat, "Weights")
1717 .addMember(MemberType::Boolean, "ApplyScale")
1718 .addMember(MemberType::Boolean, "Rotated")
1719 .addMember(MemberType::Boolean, "AngleBoundOn")
1720 .addMember(MemberType::Int64, "AngleBoundLo")
1721 .addMember(MemberType::Int64, "AngleBoundHi")
1722 .addMember(MemberType::Float, "ClipAngleThresh")
1723 .addMember(MemberType::Boolean, "LegacyPlusOne")
1724 .addResultFromCtorArg("BoxOut")
1725 .addResultFromCtorArg("RoiBatchSplits")
1726 .setDocstring(
1727 "Transform proposal bounding boxes to target bounding box using "
1728 "bounding box regression deltas. "
1729 "Rois tensor's format is: "
1730 "<[optional_batch_index], x1, y1, x2, y2>, shape (M, 4) or (M, 5) "
1731 "where M is the number of Rois. "
1732 "For rotated boxes, this would have an additional angle (in degrees) "
1733 "in the format <[optional_batch_id], ctr_x, ctr_y, w, h, angle> "
1734 "Deltas are of shape (M, K*4) with format <dx, dy, dw, dh>, "
1735 "where K is the number of classes. "
1736 "For rotated Rois: shape (M, K*5), format <dx, dy, dw, dh, da>. "
1737 "ImInfo is of shape <batch_size, 3> with format <img_height, "
1738 "img_width, img_scale>."
1739 "If proposals from multiple images in a batch are present, they "
1740 "should be grouped sequentially and in incremental order.");
1741
1742 BB.newNode("CollectRpnProposals")
1743 .addMember(MemberType::VectorNodeValue, "RoisIn")
1744 .addMember(MemberType::VectorNodeValue, "RoisProbsIn")
1745 .addMember(MemberType::Int64, "RpnMaxLevel")
1746 .addMember(MemberType::Int64, "RpnMinLevel")
1747 .addMember(MemberType::Unsigned, "RpnPostNmsTopN")
1748 .addResultFromCtorArg()
1749 .setDocstring(
1750 "Given RpnMinLevel, RpnMaxLevel and RpnPostNmsTopN "
1751 "CollectRpnProposals merges RoisIn based on "
1752 "RoisProbsIn and returns top proposals limited to "
1753 "RpnPostNmsTopN total, size (n x B), where B is "
1754 "box dimensions and based on dimension of input rois. "
1755 "Format for upright boxes is (image_index, x1, y1, x2, y2)."
1756 "Format for rotated boxes (image_index, ctr_x, ctr_y, w, h, angle)"
1757 "RpnPostNmsTopN should be greater than zero");
1758
1759 //===--------------------------------------------------------------------===//
1760 // Lookup Table Operators
1761 //===--------------------------------------------------------------------===//
1762
1763 BB.newNode("LookupTable")
1764 // Input to the function.
1765 .addInput("Input")
1766 // Table containing the coefficients for interpolation.
1767 .addInput("Table")
1768 // Table containing the index mapping to find the right entry in the main
1769 // table.
1770 .addInput("TableIdx")
1771 .addMember(MEMBER_TYPE_INFO(glow::LUTOperator), "Operator")
1772 .addMember(MemberType::VectorFloat, "OperatorArgs")
1773 .addResultFromCtorArg()
1774 .dataParallel()
1775 .setDocstring(
1776 "LookupTable based data-parallel operation."
1777 "Given an interpolation table and and index table, "
1778 "return interpolated approximations for arbitrary functions.");
1779
1780 //===--------------------------------------------------------------------===//
1781 // Backend-Specific Nodes
1782 //===--------------------------------------------------------------------===//
1783
1784#include "glow/NodeGenIncludes.h"
1785
1786 return 0;
1787}
1788