Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7190a64
Initial garel dialect definition.
wildarch Jan 19, 2026
bde1692
Verifiers.
wildarch Jan 19, 2026
087ef65
verify ProjectOp.
wildarch Jan 19, 2026
d0393a9
Add SelectOp and JoinOp.
wildarch Jan 20, 2026
96cd4e3
All relational ops.
wildarch Jan 21, 2026
01bc2f2
Start conversion pass.
wildarch Jan 21, 2026
5f8e0a3
Use local ids instead of column attributes.
wildarch Jan 21, 2026
b95b73a
Fix transpose test.
wildarch Jan 21, 2026
f536606
Start with ApplyOp.
wildarch Jan 21, 2026
a7535f5
AddOp, finish apply.mlir test.
wildarch Jan 21, 2026
fc3287a
Fix apply.mlir test to add joins.
wildarch Jan 21, 2026
4353044
Port over add.mlir.
wildarch Jan 21, 2026
664cb47
Notes for LLM.
wildarch Jan 21, 2026
39790e1
WIP: broadcast.
wildarch Jan 22, 2026
d6be611
Broadcast tests.
wildarch Jan 22, 2026
c7f4219
WIP: casting.
wildarch Jan 22, 2026
b0528f8
Casting.
wildarch Jan 23, 2026
16373ee
ConstantMatrixOp.
wildarch Jan 23, 2026
60616f8
constants.
wildarch Jan 23, 2026
e98f561
DeferredReduceOp.
wildarch Jan 23, 2026
5a1c87e
DiagOp.
wildarch Jan 23, 2026
d7993ce
EqOp.
wildarch Jan 23, 2026
02a74e9
Started with ForConstOp.
wildarch Jan 24, 2026
2c917da
Finish ForConstOp.
wildarch Jan 24, 2026
1a0d2d6
MatMulJoinOp.
wildarch Jan 24, 2026
faefc67
MulOp.
wildarch Jan 24, 2026
3057504
PickAnyOp.
wildarch Jan 24, 2026
c1eecc3
SubOp.
wildarch Jan 24, 2026
1559e17
TrilOp.
wildarch Jan 24, 2026
3422d5c
UnionOp.
wildarch Jan 24, 2026
e40417c
Finished porting graphalg-to-rel.
wildarch Jan 24, 2026
22b37e9
Cleanup.
wildarch Jan 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ endif ()

# Directories with MLIR dialects
add_subdirectory(include/graphalg)
add_subdirectory(include/garel)

add_subdirectory(src)
add_subdirectory(test)
Expand Down
15 changes: 15 additions & 0 deletions compiler/include/garel/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
include_directories(SYSTEM ${MLIR_INCLUDE_DIRS})
include_directories(SYSTEM ${PROJECT_BINARY_DIR}/include)

set(LLVM_TARGET_DEFINITIONS GARelAttr.td)
mlir_tablegen(GARelEnumAttr.h.inc -gen-enum-decls)
mlir_tablegen(GARelEnumAttr.cpp.inc -gen-enum-defs)
mlir_tablegen(GARelAttr.h.inc --gen-attrdef-decls)
mlir_tablegen(GARelAttr.cpp.inc -gen-attrdef-defs)

set(LLVM_TARGET_DEFINITIONS GARelOps.td)
add_mlir_dialect(GARelOps garel)

set(LLVM_TARGET_DEFINITIONS GARelPasses.td)
mlir_tablegen(GARelPasses.h.inc --gen-pass-decls)
add_public_tablegen_target(MLIRGARelPassesIncGen)
16 changes: 16 additions & 0 deletions compiler/include/garel/GARelAttr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include <mlir/IR/Attributes.h>
#include <mlir/IR/BuiltinAttributes.h>

#include "garel/GARelEnumAttr.h.inc"

namespace garel {

/** Reference to a column inside of \c RelationType or \c TupleType. */
using ColumnIdx = std::int32_t;

} // namespace garel

#define GET_ATTRDEF_CLASSES
#include "garel/GARelAttr.h.inc"
72 changes: 72 additions & 0 deletions compiler/include/garel/GARelAttr.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef GAREL_ATTR
#define GAREL_ATTR

include "mlir/IR/BuiltinAttributeInterfaces.td"

include "GARelDialect.td"

class GARel_Attr<string name, string attrMnemonic, list<Trait> traits = []>
: AttrDef<GARel_Dialect, name, traits> {
let mnemonic = attrMnemonic;
}

def JoinPredicate : GARel_Attr<"JoinPredicate", "join_pred"> {
let summary = "A binary equality join predicate";

let parameters = (ins
"std::int32_t":$lhsRelIdx,
"ColumnIdx":$lhsColIdx,
"std::int32_t":$rhsRelIdx,
"ColumnIdx":$rhsColIdx);

let assemblyFormat = [{
`<` $lhsRelIdx `[` $lhsColIdx `]` `=` $rhsRelIdx `[` $rhsColIdx `]` `>`
}];
}

def JoinPredicates : ArrayOfAttr<
GARel_Dialect,
"JoinPredicates",
"join_preds",
"JoinPredicateAttr">;

def AggregateFunc : I64EnumAttr<
"AggregateFunc", "",
[
I64EnumAttrCase<"SUM", 0>,
I64EnumAttrCase<"MIN", 1>,
I64EnumAttrCase<"MAX", 2>,
I64EnumAttrCase<"LOR", 3>, /* Logical OR (over i1) */
I64EnumAttrCase<"ARGMIN", 4>,
]
> {
let cppNamespace = "::garel";
}

// NOTE: assumes an aggregator produces exactly one output column.
def Aggregator : GARel_Attr<"Aggregator", "aggregator"> {
let summary = "Aggregate function with bound input columns";

let parameters = (ins
"AggregateFunc":$func,
ArrayRefParameter<"ColumnIdx">:$inputs);

let assemblyFormat = [{
`<` $func $inputs `>`
}];

let genVerifyDecl = 1;

let extraClassDeclaration = [{
/** Type for values in the output column. */
mlir::Type getResultType(::mlir::Type relType);
}];
}

def Aggregators : ArrayOfAttr<
GARel_Dialect,
"Aggregators",
"aggregators",
"AggregatorAttr">;

#endif // GAREL_ATTR
6 changes: 6 additions & 0 deletions compiler/include/garel/GARelDialect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <mlir/IR/Dialect.h>
#include <mlir/Interfaces/SideEffectInterfaces.h>

#include "garel/GARelOpsDialect.h.inc"
27 changes: 27 additions & 0 deletions compiler/include/garel/GARelDialect.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef GAREL_DIALECT
#define GAREL_DIALECT

include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/OpBase.td"

def GARel_Dialect : Dialect {
let name = "garel";
let cppNamespace = "::garel";

let extraClassDeclaration = [{
private:
void registerAttributes();
void registerTypes();
}];

let usePropertiesForAttributes = 1;
let useDefaultAttributePrinterParser = 1;
let useDefaultTypePrinterParser = 1;
}

// NOTE: GARel ops are always 'Pure'
class GARel_Op<string mnemonic, list<Trait> traits = []> :
Op<GARel_Dialect, mnemonic, !listconcat(traits, [Pure])>;

#endif // GAREL_DIALECT
15 changes: 15 additions & 0 deletions compiler/include/garel/GARelOps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include <mlir/Bytecode/BytecodeOpInterface.h>
#include <mlir/IR/BuiltinAttributes.h>
#include <mlir/IR/OpDefinition.h>
#include <mlir/IR/OpImplementation.h>
#include <mlir/IR/OperationSupport.h>
#include <mlir/IR/Region.h>
#include <mlir/Interfaces/InferTypeOpInterface.h>
#include <mlir/Interfaces/SideEffectInterfaces.h>

#include "garel/GARelTypes.h"

#define GET_OP_CLASSES
#include "garel/GARelOps.h.inc"
224 changes: 224 additions & 0 deletions compiler/include/garel/GARelOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
#ifndef GAREL_OPS
#define GAREL_OPS

/**
* Relation-level ops in the GARel dialect.
*
* See ./GARelTupleOps.td for the tuple-level ops.
*/

include "mlir/Interfaces/InferTypeOpInterface.td"

include "GARelDialect.td"
include "GARelTypes.td"

// Per-tuple ops kept in a separate file.
include "GARelTupleOps.td"

def ProjectOp : GARel_Op<"project", [IsolatedFromAbove]> {
let summary = "Remaps, reorders, drops and computes columns";

let arguments = (ins Relation:$input);

let regions = (region SizedRegion<1>:$projections);

let results = (outs Relation:$result);

let assemblyFormat = [{
$input `:` type($input) `->` type($result) $projections attr-dict
}];

let hasRegionVerifier = 1;

let extraClassDeclaration = [{
mlir::Block& createProjectionsBlock();
ProjectReturnOp getTerminator();
}];
}

def ProjectReturnOp : GARel_Op<"project.return", [
Terminator,
HasParent<"ProjectOp">]> {
let summary = "The output projections";

let arguments = (ins Variadic<ColumnType>:$projections);

let assemblyFormat = [{
$projections `:` type($projections) attr-dict
}];

// NOTE: verification performed by ProjectOp
}

def SelectOp : GARel_Op<"select", [
SameOperandsAndResultType,
IsolatedFromAbove]> {
let summary = "Removes tuples that fail (one of) the predicates";

let arguments = (ins Relation:$input);
let regions = (region SizedRegion<1>:$predicates);

let results = (outs Relation:$result);

let assemblyFormat = [{
$input `:` type($input) $predicates attr-dict
}];

let hasRegionVerifier = 1;

let extraClassDeclaration = [{
mlir::Block& createPredicatesBlock();
SelectReturnOp getTerminator();
}];
}

def SelectReturnOp : GARel_Op<"select.return", [
Terminator,
HasParent<"SelectOp">]> {
let summary = "Return the select predicates";

let arguments = (ins Variadic<I1>:$predicates);

let assemblyFormat = [{
$predicates attr-dict
}];
}

def JoinOp : GARel_Op<"join", [InferTypeOpAdaptor]> {
let summary = "Natural (equi)join of relations";

let arguments = (ins
// NOTE: All inputs must have distinct columns
Variadic<Relation>:$inputs,
// NOTE: Equality predicates only
JoinPredicates:$predicates);

let results = (outs Relation:$result);

let assemblyFormat = [{
$inputs `:` type($inputs)
$predicates
attr-dict
}];

let hasVerifier = 1;
let hasFolder = 1;
}

def UnionOp : GARel_Op<"union", [SameOperandsAndResultType]> {
let summary = "Union of relations";

let arguments = (ins Variadic<Relation>:$inputs);

let results = (outs Relation:$result);

let assemblyFormat = [{
$inputs `:` type($inputs)
attr-dict
}];

let hasFolder = 1;
}

def AggregateOp : GARel_Op<"aggregate", [InferTypeOpAdaptor]> {
let summary = "Groups tuples by key columns, aggregating values of other columns";

let arguments = (ins
Relation:$input,
DenseI32ArrayAttr:$groupBy,
Aggregators:$aggregators);

let results = (outs Relation:$result);

let assemblyFormat = [{
$input `:` type($input)
`group_by` `` `=` `` $groupBy
`aggregators` `` `=` `` $aggregators
attr-dict
}];
}

def ForOp : GARel_Op<"for", [InferTypeOpAdaptor]> {
let summary = "Bounded iteration";

let arguments = (ins
Variadic<Relation>:$init,
I64Attr:$iters,
I64Attr:$resultIdx);

let regions = (region
SizedRegion<1>:$body,
MaxSizedRegion<1>:$until);

let results = (outs Relation:$result);

let assemblyFormat = [{
$init `:` type($init)
`iters` `` `=` `` $iters
`result_idx` `` `=` `` $resultIdx
$body
(`until` $until^)?
attr-dict
}];

let hasVerifier = 1;
let hasRegionVerifier = 1;
}

def ForYieldOp : GARel_Op<"for.yield", [
Terminator,
HasParent<"ForOp">]> {
let summary = "Produces the iter args for the next iteration";

let arguments = (ins Variadic<Relation>:$inputs);

let assemblyFormat = [{
$inputs `:` type($inputs)
attr-dict
}];

// Note: verification performed by parent ForOp.
}

def RangeOp : GARel_Op<"range", [InferTypeOpAdaptor]> {
let summary = "generates a range of `index` values from `[0, size)`";

let arguments = (ins I64Attr:$size);

let results = (outs Relation:$result);

let assemblyFormat = [{
$size attr-dict
}];
}

def RemapOp : GARel_Op<"remap", [InferTypeOpAdaptor]> {
let summary = "reorders or drop columns";

let arguments = (ins Relation:$input, DenseI32ArrayAttr:$remap);

let results = (outs Relation:$result);

let assemblyFormat = [{
$input `:` type($input)
$remap
attr-dict
}];

let hasVerifier = 1;
let hasFolder = 1;
}

def ConstantOp : GARel_Op<"const", [InferTypeOpAdaptor]> {
let summary = "A relation with one constant-value tuple";

let arguments = (ins TypedAttrInterface:$value);

let results = (outs Relation:$result);

let assemblyFormat = [{
$value attr-dict
}];
}

#endif // GAREL_OPS
Loading