Skip to content

Commit 3bd92bc

Browse files
authored
New duration representation (#161)
This PR introduces a typed MLIR encoding of durations and replaces the previous string-based representation. This will yield a large performance improvement as it avoids additional string parsing and will enable leveraging MLIR's type/conversion systems.
1 parent 4e67df7 commit 3bd92bc

33 files changed

+400
-234
lines changed

include/Dialect/QUIR/IR/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,8 @@ set(LLVM_TARGET_DEFINITIONS QUIR.td)
1717
mlir_tablegen(QUIRAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=quir)
1818
mlir_tablegen(QUIRAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=quir)
1919

20+
set(LLVM_TARGET_DEFINITIONS QUIR.td)
21+
mlir_tablegen(QUIREnums.h.inc -gen-enum-decls)
22+
mlir_tablegen(QUIREnums.cpp.inc -gen-enum-defs)
23+
2024
add_mlir_interface(QUIRInterfaces)

include/Dialect/QUIR/IR/QUIR.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,11 @@
1818
#define QUIR_TD
1919

2020
include "Dialect/QUIR/IR/QUIRDialect.td"
21+
include "Dialect/QUIR/IR/QUIREnums.td"
22+
include "Dialect/QUIR/IR/QUIRTypes.td"
23+
include "Dialect/QUIR/IR/QUIRTypeConstraints.td"
24+
include "Dialect/QUIR/IR/QUIRAttributes.td"
25+
include "Dialect/QUIR/IR/QUIRTraits.td"
26+
include "Dialect/QUIR/IR/QUIROps.td"
2127

2228
#endif // QUIR_TD

include/Dialect/QUIR/IR/QUIRAttributes.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,10 @@
2828

2929
#include "llvm/ADT/StringRef.h"
3030
#include "llvm/ADT/TypeSwitch.h"
31-
32-
#define GET_ATTRDEF_CLASSES
33-
#include "Dialect/QUIR/IR/QUIRAttributes.h.inc"
31+
#include "llvm/Support/Error.h"
3432

3533
namespace mlir::quir {
34+
3635
static inline llvm::StringRef getInputParameterAttrName() {
3736
return "quir.inputParameter";
3837
}
@@ -57,4 +56,7 @@ static inline llvm::StringRef getDurationAttrName() {
5756

5857
} // namespace mlir::quir
5958

59+
#define GET_ATTRDEF_CLASSES
60+
#include "Dialect/QUIR/IR/QUIRAttributes.h.inc"
61+
6062
#endif // QUIR_QUIRATTRIBUTES_H

include/Dialect/QUIR/IR/QUIRAttributes.td

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
#ifndef QUIR_ATTRIBUTES
1919
#define QUIR_ATTRIBUTES
2020

21+
include "Dialect/QUIR/IR/QUIRTypes.td"
22+
23+
include "mlir/IR/BuiltinAttributes.td"
2124
include "mlir/IR/OpBase.td"
2225

2326
def QUIR_AngleAttr : QUIR_Attr<"Angle", "angle"> {
@@ -46,15 +49,20 @@ def QUIR_AngleAttr : QUIR_Attr<"Angle", "angle"> {
4649
def QUIR_DurationAttr : QUIR_Attr<"Duration", "duration"> {
4750
let summary = "A duration of time";
4851
let description = [{
49-
Duration attributes represent OpenQASM 3.0 durations, which are lengths of
50-
time. They are represented by a string containing a float literal and unit
51-
specifiers. Valid units are s, ms, ns, us, and dt.
52+
Duration attributes represent a duration of time.
53+
These are represented by a floating point value and a duration
54+
units type.
5255
}];
5356

54-
let parameters = (ins AttributeSelfTypeParameter<"">:$type,
55-
StringRefParameter<"the duration">:$value);
57+
let parameters = (ins AttributeSelfTypeParameter<"", "DurationType">:$type,
58+
"APFloat":$duration);
59+
60+
let extraClassDeclaration = [{
61+
uint64_t getSchedulingCycles(const double dt);
62+
}];
63+
64+
let assemblyFormat = "`<` $duration `:` $type `>`";
5665

57-
let assemblyFormat = "`<` $value `:` $type `>`";
5866
}
5967

6068
def QUIR_InputParameterAttr : QUIR_Attr<"InputParameter", "inputParameter"> {

include/Dialect/QUIR/IR/QUIRDialect.td

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,4 @@ class QUIR_Attr<string name, string attrMnemonic, list<Trait> traits = []>
5757
let mnemonic = attrMnemonic;
5858
}
5959

60-
include "Dialect/QUIR/IR/QUIRTypes.td"
61-
include "Dialect/QUIR/IR/QUIRTypeConstraints.td"
62-
include "Dialect/QUIR/IR/QUIRAttributes.td"
63-
include "Dialect/QUIR/IR/QUIRTraits.td"
64-
include "Dialect/QUIR/IR/QUIROps.td"
65-
6660
#endif // QUIR_DIALECT

include/Dialect/QUIR/IR/QUIREnums.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//===- QUIREnums.h - QUIR dialect enums -------------------------*- C++ -*-===//
2+
//
3+
// (C) Copyright IBM 2023.
4+
//
5+
// This code is part of Qiskit.
6+
//
7+
// This code is licensed under the Apache License, Version 2.0 with LLVM
8+
// Exceptions. You may obtain a copy of this license in the LICENSE.txt
9+
// file in the root directory of this source tree.
10+
//
11+
// Any modifications or derivative works of this code must retain this
12+
// copyright notice, and modified files need to carry a notice indicating
13+
// that they have been altered from the originals.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
#ifndef QUIR_QUIRENUMS_H
18+
#define QUIR_QUIRENUMS_H
19+
20+
#include "mlir/IR/BuiltinTypes.h"
21+
#include "mlir/IR/Dialect.h"
22+
#include "mlir/IR/DialectImplementation.h"
23+
#include "mlir/IR/OpDefinition.h"
24+
25+
#define GET_ENUM_CLASSES
26+
#include "Dialect/QUIR/IR/QUIREnums.h.inc"
27+
28+
namespace mlir {} // namespace mlir
29+
30+
#endif // QUIR_QUIRENUMS_H

include/Dialect/QUIR/IR/QUIREnums.td

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//===- QUIREnums.td - QUIR dialect enums -------------------*- tablegen -*-===//
2+
//
3+
// (C) Copyright IBM 2023.
4+
//
5+
// This code is part of Qiskit.
6+
//
7+
// This code is licensed under the Apache License, Version 2.0 with LLVM
8+
// Exceptions. You may obtain a copy of this license in the LICENSE.txt
9+
// file in the root directory of this source tree.
10+
//
11+
// Any modifications or derivative works of this code must retain this
12+
// copyright notice, and modified files need to carry a notice indicating
13+
// that they have been altered from the originals.
14+
//
15+
//===----------------------------------------------------------------------===//
16+
17+
18+
#ifndef QUIR_ENUMS
19+
#define QUIR_ENUMS
20+
21+
include "Dialect/QUIR/IR/QUIRDialect.td"
22+
23+
include "mlir/IR/EnumAttr.td"
24+
25+
def TimeUnits : I32EnumAttr<
26+
"TimeUnits", "time units enum",
27+
[
28+
// dt is the "scheduling rate" of the target system
29+
// ie., the smallest step of time exposed.
30+
I32EnumAttrCase<"dt", 0>,
31+
I32EnumAttrCase<"s", 1>,
32+
I32EnumAttrCase<"ms", 2>,
33+
I32EnumAttrCase<"us", 3>,
34+
I32EnumAttrCase<"ns", 4>,
35+
I32EnumAttrCase<"ps", 5>,
36+
I32EnumAttrCase<"fs", 6>,
37+
38+
]> {
39+
let genSpecializedAttr = 0;
40+
let cppNamespace = "::mlir::quir";
41+
42+
}
43+
44+
def QUIR_TimeUnitsAttr : EnumAttr<
45+
QUIRDialect, TimeUnits, "time_units">;
46+
47+
#endif // QUIR_ENUMS

include/Dialect/QUIR/IR/QUIROps.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -485,8 +485,8 @@ def QUIR_DelayOp : QUIR_Op<"delay", [
485485

486486
Example:
487487
```mlir
488-
%dur1 = quir.declare_duration {value = "10ns"} : !quir.duration
489-
"quir.delay"(%dur1, %q1_1) : (!quir.duration, !quir.qubit)
488+
%dur1 = quir.constant #quir.duration<10.0 : !quir.duration<dt>>
489+
"quir.delay"(%dur1, %q1_1) : (!quir.duration<dt>, !quir.qubit)
490490
```
491491
}];
492492

include/Dialect/QUIR/IR/QUIRTypes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#ifndef QUIR_QUIRTYPES_H
1818
#define QUIR_QUIRTYPES_H
1919

20+
#include "Dialect/QUIR/IR/QUIREnums.h"
21+
2022
#include "mlir/IR/BuiltinTypes.h"
2123
#include "mlir/IR/Dialect.h"
2224
#include "mlir/IR/OpDefinition.h"

include/Dialect/QUIR/IR/QUIRTypes.td

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#ifndef QUIR_TYPES
1818
#define QUIR_TYPES
1919

20+
include "Dialect/QUIR/IR/QUIREnums.td"
21+
2022
include "mlir/IR/BuiltinTypeInterfaces.td"
2123
include "mlir/IR/OpBase.td"
2224

@@ -60,11 +62,28 @@ def QUIR_AngleType : QUIR_Type<"Angle", "angle"> {
6062
let genVerifyDecl = 1;
6163
}
6264

65+
66+
6367
def QUIR_DurationType : QUIR_Type<"Duration", "duration"> {
64-
let summary = "represents a duration of time as a string w/ specified units.";
68+
let summary = "represents a duration of time.";
6569
let description = [{
66-
A QUIR duration expresses timing.
70+
A QUIR duration type.
71+
72+
Example:
73+
```mlir
74+
// Defaults to units at the scheduling rate (dt)
75+
%duration_dt = quir.constant #quir.duration<10.0 : !quir.duration>
76+
%duration_s = quir.constant #quir.duration<3.14 : !quir.duration<s>>
77+
```
78+
6779
}];
80+
81+
// As best I an tell this is undocumented in LLVM 14.
82+
// Based on studying the implementation of EnumAttr
83+
// https://github.com/llvm/llvm-project/blob/f28c006a5895fc0e329fe15fead81e37457cb1d1/mlir/include/mlir/IR/EnumAttr.td#L86
84+
let parameters = (ins EnumParameter<TimeUnits>:$units);
85+
86+
let assemblyFormat = "`<` $units `>`";
6887
}
6988

7089
def QUIR_StretchType : QUIR_Type<"Stretch", "stretch"> {

0 commit comments

Comments
 (0)