Skip to content

Commit e0f7f19

Browse files
committed
[RTG] Add operation to get a random number within a range
1 parent c572294 commit e0f7f19

File tree

5 files changed

+72
-0
lines changed

5 files changed

+72
-0
lines changed

include/circt/Dialect/RTG/IR/RTGOps.td

+18
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,24 @@ def BagUniqueSizeOp : RTGOp<"bag_unique_size", [Pure]> {
367367
}];
368368
}
369369

370+
//===- Integer Operations -------------------------------------------------===//
371+
372+
def RandomNumberInRangeOp : RTGOp<"random_number_in_range", []> {
373+
let summary = "returns a number uniformly at random within the given range";
374+
let description = [{
375+
This operation computes a random number based on a uniform distribution
376+
within the given range. The lower bound is inclusive while the upper bound
377+
is exclusive. If the range is empty, compilation will fail.
378+
This is (obviously) more performant than inserting all legal numbers into a
379+
set and using 'set_select_random', but yields the same behavior.
380+
}];
381+
382+
let arguments = (ins Index:$lowerBound, Index:$upperBound);
383+
let results = (outs Index:$result);
384+
385+
let assemblyFormat = "` ` `[` $lowerBound `,` $upperBound `)` attr-dict";
386+
}
387+
370388
//===- ISA Register Handling Operations -----------------------------------===//
371389

372390
def FixedRegisterOp : RTGOp<"fixed_reg", [

include/circt/Dialect/RTG/IR/RTGVisitors.h

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class RTGOpVisitor {
4141
FixedRegisterOp, VirtualRegisterOp,
4242
// RTG tests
4343
TestOp, TargetOp, YieldOp,
44+
// Integers
45+
RandomNumberInRangeOp,
4446
// Sequences
4547
SequenceOp, GetSequenceOp, SubstituteSequenceOp,
4648
RandomizeSequenceOp, EmbedSequenceOp,
@@ -92,6 +94,7 @@ class RTGOpVisitor {
9294
HANDLE(SubstituteSequenceOp, Unhandled);
9395
HANDLE(RandomizeSequenceOp, Unhandled);
9496
HANDLE(EmbedSequenceOp, Unhandled);
97+
HANDLE(RandomNumberInRangeOp, Unhandled);
9598
HANDLE(SetCreateOp, Unhandled);
9699
HANDLE(SetSelectRandomOp, Unhandled);
97100
HANDLE(SetDifferenceOp, Unhandled);

lib/Dialect/RTG/Transforms/ElaborationPass.cpp

+19
Original file line numberDiff line numberDiff line change
@@ -1017,6 +1017,25 @@ class Elaborator : public RTGOpVisitor<Elaborator, FailureOr<DeletionKind>> {
10171017

10181018
FailureOr<DeletionKind> visitOp(LabelOp op) { return DeletionKind::Keep; }
10191019

1020+
FailureOr<DeletionKind> visitOp(RandomNumberInRangeOp op) {
1021+
size_t lower = get<size_t>(op.getLowerBound());
1022+
size_t upper = get<size_t>(op.getUpperBound()) - 1;
1023+
if (lower > upper)
1024+
return op->emitError("cannot select a number from an empty range");
1025+
1026+
if (auto intAttr =
1027+
op->getAttrOfType<IntegerAttr>("rtg.elaboration_custom_seed")) {
1028+
std::mt19937 customRng(intAttr.getInt());
1029+
state[op.getResult()] =
1030+
size_t(getUniformlyInRange(customRng, lower, upper));
1031+
} else {
1032+
state[op.getResult()] =
1033+
size_t(getUniformlyInRange(sharedState.rng, lower, upper));
1034+
}
1035+
1036+
return DeletionKind::Delete;
1037+
}
1038+
10201039
FailureOr<DeletionKind> visitOp(scf::IfOp op) {
10211040
bool cond = get<bool>(op.getCondition());
10221041
auto &toElaborate = cond ? op.getThenRegion() : op.getElseRegion();

test/Dialect/RTG/IR/basic.mlir

+6
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,9 @@ rtg.target @target : !rtg.dict<num_cpus: i32, num_modes: i32> {
106106
rtg.test @test : !rtg.dict<num_cpus: i32, num_modes: i32> {
107107
^bb0(%arg0: i32, %arg1: i32):
108108
}
109+
110+
// CHECK-LABEL: rtg.sequence @integerHandlingOps
111+
rtg.sequence @integerHandlingOps(%arg0: index, %arg1: index) {
112+
// CHECK: rtg.random_number_in_range [%arg0, %arg1)
113+
rtg.random_number_in_range [%arg0, %arg1)
114+
}

test/Dialect/RTG/Transform/elaboration.mlir

+26
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,21 @@ rtg.test @labels : !rtg.dict<> {
374374
rtg.label local %l4
375375
}
376376

377+
// CHECK-LABEL: rtg.test @randomIntegers
378+
rtg.test @randomIntegers : !rtg.dict<> {
379+
%lower = index.constant 5
380+
%upper = index.constant 10
381+
%0 = rtg.random_number_in_range [%lower, %upper) {rtg.elaboration_custom_seed=0}
382+
// CHECK-NEXT: [[V0:%.+]] = index.constant 5
383+
// CHECK-NEXT: func.call @dummy2([[V0]])
384+
func.call @dummy2(%0) : (index) -> ()
385+
386+
%1 = rtg.random_number_in_range [%lower, %upper) {rtg.elaboration_custom_seed=3}
387+
// CHECK-NEXT: [[V1:%.+]] = index.constant 8
388+
// CHECK-NEXT: func.call @dummy2([[V1]])
389+
func.call @dummy2(%1) : (index) -> ()
390+
}
391+
377392
// -----
378393

379394
rtg.test @nestedRegionsNotSupported : !rtg.dict<> {
@@ -398,3 +413,14 @@ rtg.test @untypedAttributes : !rtg.dict<> {
398413
// expected-note @below {{while materializing value for operand#0}}
399414
func.call @dummy(%0) : (index) -> ()
400415
}
416+
417+
// -----
418+
419+
func.func @dummy2(%arg0: index) -> () {return}
420+
421+
rtg.test @randomIntegers : !rtg.dict<> {
422+
%c5 = index.constant 5
423+
// expected-error @below {{cannot select a number from an empty range}}
424+
%0 = rtg.random_number_in_range [%c5, %c5)
425+
func.call @dummy2(%0) : (index) -> ()
426+
}

0 commit comments

Comments
 (0)