From 4aaf009a786d0012e9377e7d4a30528e4ec14306 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 1 Dec 2025 22:23:41 +0000 Subject: [PATCH 1/2] Start description of core ops. --- compiler/src/graphalg/evaluate/Evaluator.cpp | 1 + spec/core/operations.md | 131 ++++++++++++++++++- 2 files changed, 128 insertions(+), 4 deletions(-) diff --git a/compiler/src/graphalg/evaluate/Evaluator.cpp b/compiler/src/graphalg/evaluate/Evaluator.cpp index 8545c4b..20c09f3 100644 --- a/compiler/src/graphalg/evaluate/Evaluator.cpp +++ b/compiler/src/graphalg/evaluate/Evaluator.cpp @@ -84,6 +84,7 @@ mlir::LogicalResult Evaluator::evaluate(DiagOp op) { MatrixAttrReader input(_values[op.getInput()]); MatrixAttrBuilder result(op.getType()); + // TODO: Need to handle row vector case. for (auto row : llvm::seq(input.nRows())) { result.set(row, row, input.at(row, 0)); } diff --git a/spec/core/operations.md b/spec/core/operations.md index 3fae316..71f66ca 100644 --- a/spec/core/operations.md +++ b/spec/core/operations.md @@ -6,13 +6,136 @@ nav_order: 1 --- # Operations in GraphAlg Core +This page defines the operational semantics of the operations in GraphAlg Core. +Operations are referred to by their MLIR Op name. +GraphAlg Core is a compiler-internal IR that has no defined syntax apart from the standard MLIR syntax. {:.warning-title} > Under Construction > > This part of the documentation is not yet finished. -TODO: -- Core does not have a syntax or grammar, only definitions of operations -- Describe all operations that exist in the language -- Give operational semantics +## Matrix Operations + +### `TransposeOp` +Matrix Transpose. + +```math +O_{ij} = I_{ji} +``` + +### `DiagOp` +Diagonalizes the input vector into matrix. + +If the input is a column vector: +```math +O_{ii} = I_{0,i} +``` + +If the input is row vector: +```math +O_{ii} = I_{i,0} +``` + +### `MatMulOp` +Matrix multiplication using the addition operator and multiplication operator as defined by the matrix semiring. + +```math +O_{ik} = \bigoplus_j L_{ij} \otimes R_{jk} +``` + +### `ReduceOp` +Reduce input matrix along one or two dimensions. +If the output type is scalar: + +```math +O_{0,0} = \bigoplus_{ij} I_{ij} +``` + +If the output type is a column vector: + +```math +O_{i,0} = \bigoplus_{j} I_{ij} +``` + +If the output type is row vector: + +```math +O_{0,j} = \bigoplus_{i} I_{ij} +``` + +### `BroadcastOp` +Broadcast the input to a higher dimension by duplicating elements. + +TODO: Define the semantics in a concise way (use 1-vector?) + +### `ConstantMatrixOp` +Fill a matrix with a constant scalar value. + +```math +O_{ij} = c +``` + +### `ForConstOp` +TODO: Define precise semantics. + +### `ApplyOp` +TODO: Describe op semantics. + +TODO: Note implicit broadcasting + +### `PickAnyOp` +TODO: Describe op semantics. + +## Scalar Operations +### `ConstantOp` +Scalar constant. + +```math +O = c +``` + +NOTE: Implementation also needs to handle `mlir::arith::ConstantOp` due to folding of `arith` ops. + +### `AddOp` +Applies the semiring addition operator. + +```math +O = l \oplus r +``` + +### `MulOp` +Applies the semiring multiplication operator. + +```math +O = l \otimes r +``` + +### `CastScalarOp` +TODO: Describe op semantics. + +### `EqOp` +Tests whether two scalars have the same value. + +```math +O = (l = r) +``` + +### `mlir::arith::DivFOp` +Floating point division. Dividing by zero is well-defined, producing a zero-value output. + +```math +O = \begin{cases} + 0 & \text{ if } r = 0 \\ + l / r & \text{ otherwise } +\end{cases} +``` + +### `mlir::arith::SubIOp`/`mlir::arith::SubFOp` +Integer or floating-point subtraction. + +```math +O = l - r +``` + + From 8bdab33bad1cfa13319e6060080e4885745b0a33 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 3 Dec 2025 12:26:03 +0000 Subject: [PATCH 2/2] Allow diag for row vectors. --- compiler/src/graphalg/evaluate/Evaluator.cpp | 13 ++++++++++--- compiler/test/exec/diag-rowvec.mlir | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 compiler/test/exec/diag-rowvec.mlir diff --git a/compiler/src/graphalg/evaluate/Evaluator.cpp b/compiler/src/graphalg/evaluate/Evaluator.cpp index 20c09f3..78ad466 100644 --- a/compiler/src/graphalg/evaluate/Evaluator.cpp +++ b/compiler/src/graphalg/evaluate/Evaluator.cpp @@ -84,9 +84,16 @@ mlir::LogicalResult Evaluator::evaluate(DiagOp op) { MatrixAttrReader input(_values[op.getInput()]); MatrixAttrBuilder result(op.getType()); - // TODO: Need to handle row vector case. - for (auto row : llvm::seq(input.nRows())) { - result.set(row, row, input.at(row, 0)); + auto inputType = llvm::cast(op.getInput().getType()); + if (inputType.isColumnVector()) { + for (auto row : llvm::seq(input.nRows())) { + result.set(row, row, input.at(row, 0)); + } + } else { + assert(inputType.isRowVector()); + for (auto col : llvm::seq(input.nCols())) { + result.set(col, col, input.at(0, col)); + } } _values[op.getResult()] = result.build(); diff --git a/compiler/test/exec/diag-rowvec.mlir b/compiler/test/exec/diag-rowvec.mlir new file mode 100644 index 0000000..66ed6f1 --- /dev/null +++ b/compiler/test/exec/diag-rowvec.mlir @@ -0,0 +1,16 @@ +// RUN: split-file %s %t +// RUN: graphalg-exec %t/input.mlir Diag %t/input.m | diff - %t/output.m + +//--- input.m +0 0 42 +0 1 43 + +//--- input.mlir +func.func @Diag(%arg0: !graphalg.mat<1 x 2 x i64>) -> !graphalg.mat<2 x 2 x i64> { + %0 = graphalg.diag %arg0 : !graphalg.mat<1 x 2 x i64> + return %0 : !graphalg.mat<2 x 2 x i64> +} + +//--- output.m +0 0 42 : i64 +1 1 43 : i64