Skip to content

Commit

Permalink
[RTG] Separate operation for sequence randomization and randomized se…
Browse files Browse the repository at this point in the history
…quence type
  • Loading branch information
maerhart committed Jan 30, 2025
1 parent 1058927 commit 03cdb45
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 78 deletions.
6 changes: 6 additions & 0 deletions include/circt-c/Dialect/RTG.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ MLIR_CAPI_EXPORTED unsigned rtgSequenceTypeGetNumElements(MlirType type);
MLIR_CAPI_EXPORTED MlirType rtgSequenceTypeGetElement(MlirType type,
unsigned i);

/// If the type is an RTG randomized sequence.
MLIR_CAPI_EXPORTED bool rtgTypeIsARandomizedSequence(MlirType type);

/// Creates an RTG randomized sequence type in the context.
MLIR_CAPI_EXPORTED MlirType rtgRandomizedSequenceTypeGet(MlirContext ctxt);

/// If the type is an RTG label.
MLIR_CAPI_EXPORTED bool rtgTypeIsALabel(MlirType type);

Expand Down
35 changes: 30 additions & 5 deletions include/circt/Dialect/RTG/IR/RTGOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,42 @@ def SequenceClosureOp : RTGOp<"sequence_closure", [
}];
}

def InvokeSequenceOp : RTGOp<"invoke_sequence", []> {
let summary = "invoke a sequence of instructions";
def RandomizeSequenceOp : RTGOp<"randomize_sequence", []> {
let summary = "randomize the content of a sequence";
let description = [{
This operation takes a sequence closure as operand and acts as a placeholder
for that sequence instantiated with the arguments in the closure in place.
This operation takes a fully substituted sequence and randomizes its
content. This means, no operations the returned sequence does not contain
any randomization constructs anymore (such as random selection from sets and
bags, or other 'randomize_sequence' operations).

It is useful to have this operation separate from 'embed_sequence' such that
the exact same sequence (i.e., with the same random choices taken) can be
embedded at multiple places.
It is also useful to have this separate from sequence substitution because
this operation is sensitive to the context, but the substitution values for
a sequence family might already be available in a parent sequence that is
placed on a different context. Thus, not having it separated would mean that
the substitution values must all be passed down as arguments to the child
sequence instead of a a single fully substituted sequence value.
}];

let arguments = (ins FullySubstitutedSequenceType:$sequence);
let results = (outs RandomizedSequenceType:$randomizedSequence);

let assemblyFormat = "$sequence attr-dict";
}

def EmbedSequenceOp : RTGOp<"embed_sequence", []> {
let summary = "embed a sequence of instructions into another sequence";
let description = [{
This operation takes a fully randomized sequence and embeds it into another
sequence or test at the position of this operation.
In particular, this is not any kind of function call, it doesn't set up a
stack frame, etc. It behaves as if the sequence of instructions it refers to
were directly inlined relacing this operation.
}];

let arguments = (ins FullySubstitutedSequenceType:$sequence);
let arguments = (ins RandomizedSequenceType:$sequence);

let assemblyFormat = "$sequence attr-dict";
}
Expand Down
11 changes: 11 additions & 0 deletions include/circt/Dialect/RTG/IR/RTGTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ def SequenceType : RTGTypeDef<"Sequence"> {
let assemblyFormat = "(`<` $elementTypes^ `>`)?";
}

def RandomizedSequenceType : RTGTypeDef<"RandomizedSequence"> {
let summary = "handle to a fully randomized sequence";
let description = [{
Sequences can contain operations to randomize their content in various ways.
A sequence of this type is guaranteed to not have any such operations
anymore (transitively).
}];

let mnemonic = "randomized_sequence";
}

def FullySubstitutedSequenceType : DialectType<RTGDialect,
CPred<"llvm::isa<rtg::SequenceType>($_self) && "
"llvm::cast<rtg::SequenceType>($_self).getElementTypes().empty()">,
Expand Down
5 changes: 3 additions & 2 deletions include/circt/Dialect/RTG/IR/RTGVisitors.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class RTGOpVisitor {
// RTG tests
TestOp, TargetOp, YieldOp,
// Sequences
SequenceOp, SequenceClosureOp, InvokeSequenceOp,
SequenceOp, SequenceClosureOp, RandomizeSequenceOp, EmbedSequenceOp,
// Sets
SetCreateOp, SetSelectRandomOp, SetDifferenceOp, SetUnionOp,
SetSizeOp>([&](auto expr) -> ResultType {
Expand Down Expand Up @@ -88,7 +88,8 @@ class RTGOpVisitor {

HANDLE(SequenceOp, Unhandled);
HANDLE(SequenceClosureOp, Unhandled);
HANDLE(InvokeSequenceOp, Unhandled);
HANDLE(RandomizeSequenceOp, Unhandled);
HANDLE(EmbedSequenceOp, Unhandled);
HANDLE(SetCreateOp, Unhandled);
HANDLE(SetSelectRandomOp, Unhandled);
HANDLE(SetDifferenceOp, Unhandled);
Expand Down
14 changes: 9 additions & 5 deletions integration_test/Bindings/Python/dialects/rtg.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,18 @@
setTy = rtg.SetType.get(indexTy)
bagTy = rtg.BagType.get(indexTy)
ireg = rtgtest.IntegerRegisterType.get()
randomizedSequenceTy = rtg.RandomizedSequenceType.get()
seq = rtg.SequenceOp(
'seq',
TypeAttr.get(
rtg.SequenceType.get([sequenceTy, labelTy, setTy, bagTy, ireg])))
Block.create_at_start(seq.bodyRegion,
[sequenceTy, labelTy, setTy, bagTy, ireg])

# CHECK: rtg.sequence @seq(%{{.*}}: !rtg.sequence, %{{.*}}: !rtg.label, %{{.*}}: !rtg.set<index>, %{{.*}}: !rtg.bag<index>, %{{.*}}: !rtgtest.ireg)
rtg.SequenceType.get(
[sequenceTy, labelTy, setTy, bagTy, ireg,
randomizedSequenceTy])))
Block.create_at_start(
seq.bodyRegion,
[sequenceTy, labelTy, setTy, bagTy, ireg, randomizedSequenceTy])

# CHECK: rtg.sequence @seq(%{{.*}}: !rtg.sequence, %{{.*}}: !rtg.label, %{{.*}}: !rtg.set<index>, %{{.*}}: !rtg.bag<index>, %{{.*}}: !rtgtest.ireg, %{{.*}}: !rtg.randomized_sequence)
print(m)

with Context() as ctx, Location.unknown():
Expand Down
8 changes: 8 additions & 0 deletions lib/Bindings/Python/RTGModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@ void circt::python::populateDialectRTGSubmodule(py::module &m) {
return rtgSequenceTypeGetElement(self, i);
});

mlir_type_subclass(m, "RandomizedSequenceType", rtgTypeIsARandomizedSequence)
.def_classmethod(
"get",
[](py::object cls, MlirContext ctxt) {
return cls(rtgRandomizedSequenceTypeGet(ctxt));
},
py::arg("self"), py::arg("ctxt") = nullptr);

mlir_type_subclass(m, "LabelType", rtgTypeIsALabel)
.def_classmethod(
"get",
Expand Down
11 changes: 11 additions & 0 deletions lib/CAPI/Dialect/RTG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,17 @@ MlirType rtgSequenceTypeGetElement(MlirType type, unsigned i) {
return wrap(cast<SequenceType>(unwrap(type)).getElementTypes()[i]);
}

// RandomizedSequenceType
//===----------------------------------------------------------------------===//

bool rtgTypeIsARandomizedSequence(MlirType type) {
return isa<RandomizedSequenceType>(unwrap(type));
}

MlirType rtgRandomizedSequenceTypeGet(MlirContext ctxt) {
return wrap(RandomizedSequenceType::get(unwrap(ctxt)));
}

// LabelType
//===----------------------------------------------------------------------===//

Expand Down
Loading

0 comments on commit 03cdb45

Please sign in to comment.