Class IROp
- Namespace
- AiDotNet.JitCompiler.IR
- Assembly
- AiDotNet.dll
Base class for all IR operations.
public abstract class IROp
- Inheritance
-
IROp
- Derived
- Inherited Members
Remarks
IROp represents a single operation in the intermediate representation graph. Each operation has inputs (tensor IDs), produces an output (tensor ID), and has metadata about types and shapes.
For Beginners: An IROp is like a single step in a recipe.
Each operation:
- Takes some inputs (the tensor IDs it needs)
- Performs a calculation (add, multiply, etc.)
- Produces an output (a new tensor ID)
- Knows what type and shape the output will be
For example, an "Add" operation might:
- Take inputs: tensor 0 and tensor 1
- Perform: element-wise addition
- Produce: tensor 2
- Know: output has the same shape as the inputs
The JIT compiler uses this information to generate optimized code.
Properties
InputIds
Gets or sets the identifiers of the input tensors to this operation.
public int[] InputIds { get; set; }
Property Value
- int[]
Remarks
Input IDs reference tensors that must be computed before this operation. They can be graph inputs, constants, or outputs from earlier operations.
For Beginners: These are the inputs this operation needs.
For a binary operation like addition:
- InputIds = [0, 1] means "add tensor 0 and tensor 1"
For a unary operation like ReLU:
- InputIds = [5] means "apply ReLU to tensor 5"
The order matters! For subtraction, [0, 1] means "0 - 1", not "1 - 0".
OpType
Gets the operation type name for debugging and visualization.
public virtual string OpType { get; }
Property Value
Remarks
By default, this returns the class name without the "Op" suffix. For example, "MatMulOp" becomes "MatMul".
For Beginners: This is a human-readable name for the operation.
Used for:
- Debugging (see what operations are in the graph)
- Visualization (draw a graph diagram)
- Logging (track what the compiler is doing)
Examples: "Add", "MatMul", "ReLU", "Conv2D"
OutputId
Gets or sets the primary output ID (first element of OutputIds).
public int OutputId { get; set; }
Property Value
Remarks
This is a convenience property for operations that produce a single output. For multi-output operations like gradient ops, use OutputIds directly.
For Beginners: Most operations produce just one result. This property makes it easy to work with the common case.
OutputIds
Gets or sets the identifiers for the outputs of this operation.
public int[] OutputIds { get; set; }
Property Value
- int[]
Remarks
The output IDs identify the tensors produced by this operation. They're used by subsequent operations to reference these results. Most operations produce a single output, but gradient operations may produce multiple outputs (one gradient per input).
For Beginners: These are like variable names for the results.
For example, if this operation computes "c = a + b":
- OutputIds might be [2] (representing "c")
- InputIds might be [0, 1] (representing "a" and "b")
For gradient operations like "grad(a * b)":
- OutputIds might be [3, 4] (representing "d_a" and "d_b")
- InputIds might be [0, 1, 2] (representing "a", "b", "d_c")
Later operations can use these tensor IDs as their inputs.
OutputShape
Gets or sets the shape of the output tensor.
public int[] OutputShape { get; set; }
Property Value
- int[]
Remarks
The output shape is represented as an int[] array matching the existing Tensor<T>.Shape format. Each element is the size of that dimension.
For Beginners: This tells us the size and dimensions of the result.
Examples:
- [] = scalar (single number)
- [10] = vector with 10 elements
- [3, 4] = 3×4 matrix
- [32, 3, 224, 224] = batch of 32 RGB images, each 224×224 pixels
The shape is determined by the operation:
- Adding [3, 4] + [3, 4] → [3, 4] (same shape)
- Matrix multiply [3, 4] × [4, 5] → [3, 5] (rows from left, cols from right)
- Sum [3, 4] along axis 1 → [3] (reduces one dimension)
OutputShapes
Gets the shapes of all output tensors, indexed by position in OutputIds.
public virtual int[][] OutputShapes { get; }
Property Value
- int[][]
Remarks
For multi-output operations (e.g., split, gradient ops), each output may have a different shape. This property returns an array where OutputShapes[i] corresponds to OutputIds[i].
If not explicitly set, defaults to using OutputShape for all outputs (backward compatibility for single-output operations).
For Beginners: When an operation produces multiple outputs, each output can have its own shape. For example, a "split" operation that splits a [6, 4] tensor into two parts might produce: - OutputIds = [1, 2] - OutputShapes = [[3, 4], [3, 4]] (each half)
OutputType
Gets or sets the data type of the output tensor.
public IRType OutputType { get; set; }
Property Value
Remarks
The output type determines what numeric type (float, double, int, etc.) the result tensor will use. This affects memory usage and precision.
For Beginners: This tells us what kind of numbers the result contains.
Common types:
- Float32: Single-precision floating point (most common for neural networks)
- Float64: Double-precision floating point (higher precision, more memory)
- Int32: 32-bit integers
The type affects:
- Memory usage (float32 uses half the memory of float64)
- Precision (how accurate calculations are)
- Performance (some operations are faster with certain types)
Methods
ToString()
Gets a string representation of this operation for debugging.
public override string ToString()
Returns
- string
A string describing this operation.
Remarks
The string format is: "tOutput = OpType(tInput1, tInput2, ...) : Type [Shape]"
For Beginners: This creates a readable description of the operation.
Example outputs:
- "t2 = Add(t0, t1) : Float32 [3, 4]"
- "t5 = MatMul(t3, t4) : Float32 [128, 256]"
- "t8 = ReLU(t7) : Float32 [32, 128]"
This is super helpful for debugging - you can see exactly what each operation does and what shape tensors flow through the graph.
Validate()
Validates that this operation is correctly formed.
public virtual bool Validate()
Returns
- bool
True if valid, false otherwise.
Remarks
Basic validation checks that the operation has required information. Derived classes can override to add operation-specific validation.
For Beginners: This checks that the operation makes sense.
Basic checks:
- Output ID is valid (non-negative)
- Has the right number of inputs
- Shapes are compatible
Specific operations add their own checks:
- MatMul: inner dimensions must match
- Conv2D: kernel size must be valid
- Reshape: total elements must be preserved
If validation fails, the operation can't be compiled.