Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce OpenQASM 3 (OQ3) dialect #34

Merged
merged 29 commits into from
Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
adafe65
QUIR_{AssignArrayElement,DeclareVariable}Op -> OQ3_{...}
vrpascuzzi Jan 23, 2023
df3e6b8
QUIR_{UseArrayElementOp,UseVariableOp} -> OQ3_{...}
vrpascuzzi Jan 23, 2023
f8df914
Cbit -> CBit
vrpascuzzi Jan 25, 2023
ea5e1aa
Migrate `CBit` ops from `QUIR` to `OQ3` dialect (Part 1)
vrpascuzzi Jan 25, 2023
8203f0e
Remove QUIR CBit remnants
vrpascuzzi Jan 26, 2023
f57d00f
QUIR_Angle.*Op -> OQ3_Angle.*Op
vrpascuzzi Jan 26, 2023
2d91bee
QUIR duration ops -> OQ3 duration ops; some small refactoring
vrpascuzzi Jan 26, 2023
0079ddf
Remove QUIR pattern remnants
vrpascuzzi Jan 26, 2023
d2186cc
QUIR_CastOp -> OQ3_CastOp
vrpascuzzi Jan 27, 2023
1184ec9
{QUIR -> OQ3}_DeclareStretchOp
vrpascuzzi Jan 27, 2023
1f47a54
{QUIR -> OQ3}_{Duration, Stretch}
vrpascuzzi Jan 27, 2023
5b48309
Remove QUIR CastOp remnants
vrpascuzzi Jan 27, 2023
cea40ea
QUIR_CallKernel -> OQ3_KernelCall
vrpascuzzi Jan 27, 2023
10a1343
Add inlining support for OQ3 dialect
vrpascuzzi Jan 30, 2023
bc53cf4
Add missing `CBit` and variable patterns
vrpascuzzi Jan 31, 2023
998c590
Use single population function for all conversions (cast+`CBit`)
vrpascuzzi Jan 31, 2023
9a81c6e
Fix comments, copyrights; remove unused files
vrpascuzzi Jan 31, 2023
0066495
Merge branch 'main' into vrp-iss651-qasm3-mlir-dialect
vrpascuzzi Feb 18, 2023
fb5b14c
Merge branch 'main' into vrp-iss651-qasm3-mlir-dialect
vrpascuzzi Feb 23, 2023
169ae89
Fix for failing `bell-0.qasm` test when using `mock_target`
vrpascuzzi Mar 10, 2023
3b8f596
Drop `KernelOps`
vrpascuzzi Mar 10, 2023
0b4eb63
Revert `variable_decl` -> `declare_variable`
vrpascuzzi Mar 10, 2023
33afedd
Add tests for `OQ3` ops
vrpascuzzi Mar 10, 2023
84c223b
Revert `DurationOp` from `OQ3` -> `QUIR`; remove duration arith
vrpascuzzi Mar 11, 2023
2b47aea
Merge remote-tracking branch 'origin/main' into vrp-iss651-qasm3-mlir…
vrpascuzzi Mar 16, 2023
a4a4548
Merge remote-tracking branch 'origin/main' into vrp-iss651-qasm3-mlir…
vrpascuzzi Mar 17, 2023
fbf1139
* `VariableUse` -> `VariableLoad`
vrpascuzzi Mar 17, 2023
67cc3db
clang-format
vrpascuzzi Mar 17, 2023
50523d4
fix typo
vrpascuzzi Mar 17, 2023
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
24 changes: 12 additions & 12 deletions docs/variable-lowering.rst
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ identifies a location in memory and each reference or assignment to that
variables reads or writes that location.

- Variables are declared by the QUIR operation
``quir.declare_variable`` and identified as `MLIR
``oq3.declare_variable`` and identified as `MLIR
symbols <https://mlir.llvm.org/docs/SymbolsAndSymbolTables/>`__.
- Each reference to a variable is modeled as an operation
``quir.use_variable`` that returns the variables value at that point.
- The operation ``quir.assign_variable`` updates the variable’s value
``oq3.use_variable`` that returns the variables value at that point.
- The operation ``oq3.assign_variable`` updates the variable’s value
(visible from that operation forward until a subsequent
``quir.assign_variable`` that operates on the same variable).
- Both ``quir.use_variable`` and ``quir.assign_variable`` refer the
MLIR symbol defined by the operations ``quir.declare_variable`` (the
``oq3.assign_variable`` that operates on the same variable).
- Both ``oq3.use_variable`` and ``oq3.assign_variable`` refer the
MLIR symbol defined by the operations ``oq3.declare_variable`` (the
symbol’s name is a string).

As an example, the OpenQASM 3 statement ``a = a ^ b`` (with ``a`` and
Expand All @@ -66,10 +66,10 @@ for clarity):

::

%0 = quir.use_variable @a
%1 = quir.use_variable @b
%0 = oq3.use_variable @a
%1 = oq3.use_variable @b
%2 = quir.cbit_xor %s02, %s13
quir.assign_variable @a = %2
oq3.assign_variable @a = %2

Variable scoping is not supported yet (there is only the global scope). Adding
support is future work.
Expand Down Expand Up @@ -99,7 +99,7 @@ Best-Effort SSA Transformation
The
`VariableEliminationPass <https://github.com/Qiskit/qss-compiler/blob/main/lib/Dialect/QUIR/Transforms/VariableElimination.cpp>`__
reuses the scalar-replacement pass from MLIR’s affine dialect to
replace instances of `quir.use_variable` with the MLIR Value previously
replace instances of `oq3.use_variable` with the MLIR Value previously
assigned to the respective variable, in many cases. Noteably, that code
does not perform a complete SSA transformation and variable assignment
and use around control flow will be left as memory operations. The
Expand All @@ -108,8 +108,8 @@ and use around control flow will be left as memory operations. The
Lowering to Memory Operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The operations ``quir.declare_variable``, ``quir.use_variable``, and
``quir.assign_variable`` are converted to MLIR’s ``memref`` and
The operations ``oq3.declare_variable``, ``oq3.use_variable``, and
``oq3.assign_variable`` are converted to MLIR’s ``memref`` and
``affine`` dialects. Each variable declaration is turned into a global
variable (``memref.global``) and variable reads/writes are converted
into ``load`` and ``store`` operations from the ``affine`` dialect (only
Expand Down
43 changes: 43 additions & 0 deletions include/Conversion/OQ3ToStandard/OQ3ToStandard.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//===- OQ3ToStandard.h - OpenQASM 3 to Standard patterns --------*- C++ -*-===//
mhillenbrand marked this conversation as resolved.
Show resolved Hide resolved
//
// (C) Copyright IBM 2023.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.
//
//===----------------------------------------------------------------------===//
///
/// This file implements patterns to convert OpenQASM 3 to Standard dialect.
///
//===----------------------------------------------------------------------===//

#ifndef CONVERSION_OQ3TOSTANDARD_OQ3TOSTANDARD_H_
#define CONVERSION_OQ3TOSTANDARD_OQ3TOSTANDARD_H_

#include "Dialect/OQ3/IR/OQ3Types.h"

#include "mlir/IR/BuiltinTypes.h"
#include "mlir/Transforms/DialectConversion.h"

namespace mlir::oq3 {
template <typename OQ3Op>
class OQ3ToStandardConversion : public OpConversionPattern<OQ3Op> {
public:
OQ3ToStandardConversion(MLIRContext *context, TypeConverter &typeConverter,
PatternBenefit benefit = 1)
: OpConversionPattern<OQ3Op>(typeConverter, context, benefit),
typeConverter(typeConverter) {}

protected:
TypeConverter &typeConverter;
};

// Appends to a pattern list additional patterns for translating OpenQASM 3
// ops to Standard ops.
void populateOQ3ToStandardConversionPatterns(
TypeConverter &typeConverter, RewritePatternSet &patterns,
bool includeBitmapOperationPatterns = true);
}; // namespace mlir::oq3

#endif // CONVERSION_OQ3TOSTANDARD_OQ3TOSTANDARD_H_
32 changes: 0 additions & 32 deletions include/Conversion/QUIRToStandard/CBitOperations.h

This file was deleted.

32 changes: 0 additions & 32 deletions include/Conversion/QUIRToStandard/QUIRCast.h

This file was deleted.

1 change: 1 addition & 0 deletions include/Dialect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

add_subdirectory(OQ3)
add_subdirectory(QUIR)
add_subdirectory(Pulse)
add_subdirectory(QCS)
7 changes: 7 additions & 0 deletions include/Dialect/OQ3/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# (C) Copyright IBM 2023.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

add_subdirectory(IR)
14 changes: 14 additions & 0 deletions include/Dialect/OQ3/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# (C) Copyright IBM 2023.
#
# Any modifications or derivative works of this code must retain this
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

add_mlir_dialect(OQ3Ops oq3)
qssc_add_mlir_doc(OQ3Ops OQ3Ops generated/Dialect/OQ3/ -gen-dialect-doc)

set(LLVM_TARGET_DEFINITIONS OQ3Dialect.td)

set(LLVM_TARGET_DEFINITIONS OQ3Patterns.td)
mlir_tablegen(OQ3Patterns.inc -gen-rewriters)
add_public_tablegen_target(MLIROQ3PatternsIncGen)
103 changes: 103 additions & 0 deletions include/Dialect/OQ3/IR/OQ3AngleOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
//===- OQ3AngleOps.td - OpenQASM 3 angle ops --------*- tablegen --------*-===//
//
// (C) Copyright IBM 2023.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.
//
//===----------------------------------------------------------------------===//
///
/// This is the operation definition file for OpenQASM 3 operations on
/// angles.
///
//===----------------------------------------------------------------------===//

#ifndef OQ3_ANGLE_OPS
#define OQ3_ANGLE_OPS

include "Dialect/OQ3/IR/OQ3Base.td"

class OQ3_BinaryAngleOp<string mnemonic, list<Trait> traits = []> :
OQ3_BinaryOp<mnemonic, !listconcat(traits, [SameOperandsAndResultType])> {
let arguments = (ins AnyAngle:$lhs, AnyAngle:$rhs);
let results = (outs AnyAngle:$result);
let assemblyFormat = [{
attr-dict $lhs `,` $rhs `:` type($result)
}];
}

class OQ3_BinaryCmpOp<string mnemonic, list<Trait> traits = []> :
OQ3_BinaryOp<mnemonic, !listconcat(traits, [SameTypeOperands])> {
let results = (outs I1:$result);
let assemblyFormat = [{
attr-dict $lhs `,` $rhs `:` type($lhs) `->` type($result)
}];

let verifier = [{
std::vector predicates = { "eq", "ne", "slt", "sle", "sgt", "sge", "ult", "ule", "ugt", "uge" };

if (std::find(predicates.begin(), predicates.end(), this->predicate()) != predicates.end())
return success();
else
return emitOpError("requires predicate \"eq\", \"ne\", \"slt\", \"sle\", \"sgt\", \"sge\", \"ult\", \"ule\", \"ugt\", \"uge\"");
}];
}

// -----

def OQ3_AngleAddOp : OQ3_BinaryAngleOp<"angle_add"> {
let summary = "Add two angles";
let description = [{
The `oq3.angle_add` operation takes two angle operands and returns one angle
result, which is the sum of the two operands. All angle operations are performed
over the interval [0,2*pi).
}];
}

// -----

def OQ3_AngleSubOp : OQ3_BinaryAngleOp<"angle_sub"> {
let summary = "Subtract two angles";
let description = [{
The `oq3.angle_sub` operation takes two angle operands and returns one angle
result, which is the difference of the two operands. All angle operations are performed
over the interval [0,2*pi).
}];
}

// -----

def OQ3_AngleMulOp : OQ3_BinaryAngleOp<"angle_mul"> {
let summary = "Multiply two angles";
let description = [{
The `oq3.angle_mul` operation takes two angle operands and returns one angle
result, which is the multiplication of the two operands. All angle operations are performed
over the interval [0,2*pi).
}];
}

// -----

def OQ3_AngleDivOp : OQ3_BinaryAngleOp<"angle_div"> {
let summary = "Divide two angles";
let description = [{
The `oq3.angle_div` operation takes two angle operands and returns one angle
result, which is the division of the two operands. All angle operations are performed
over the interval [0,2*pi).
}];
}

// -----

def OQ3_AngleCmpOp : OQ3_BinaryCmpOp<"angle_cmp"> {
let summary = "Compare two angles";
let description = [{
The `oq3.angle_cmp` operation takes two angle operands and returns one boolean
result. All angle operations are performed over the interval [0,2*pi).
}];

let arguments = (ins StrAttr:$predicate, AnyAngle:$lhs, AnyAngle:$rhs);
}

#endif // OQ3_ANGLE_OPS
36 changes: 36 additions & 0 deletions include/Dialect/OQ3/IR/OQ3ArithmeticOps.td
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//===- OQ3ArithmeticOps.td - OpenQASM 3 arithmetic ops -----*- tablegen -*-===//
//
// (C) Copyright IBM 2023.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.
//
//===----------------------------------------------------------------------===//
///
/// This is the definition file for the OpenQASM 3 dialect arithmetic
/// operations.
///
//===----------------------------------------------------------------------===//

#ifndef OQ3_ARITHMETIC_OPS
#define OQ3_ARITHMETIC_OPS

include "mlir/Interfaces/InferTypeOpInterface.td"

class OQ3_ArithmeticUnaryOp<string mnemonic, list<Trait> traits = []> :
OQ3_UnaryOp<mnemonic,
!listconcat(traits, [SameOperandsAndResultType])>;

class OQ3_ArithmeticBinaryOp<string mnemonic, list<Trait> traits = []> :
OQ3_BinaryOp<mnemonic,
!listconcat(traits,
[NoSideEffect, SameOperandsAndResultType])> {
let arguments = (ins AnyClassical:$lhs, AnyClassical:$rhs);
let results = (outs AnyClassical:$result);
let assemblyFormat = [{
attr-dict $lhs `,` $rhs `:` `(` type($lhs) `,` type($rhs) `)` `->` type($result)
}];
}

#endif // OQ3_ARITHMETIC_OPS
Loading