Skip to content

Commit

Permalink
Merge branch 'main' into relkabetz/issue-2223-qe
Browse files Browse the repository at this point in the history
  • Loading branch information
RoyElkabetz committed Mar 18, 2024
2 parents 56b2534 + 00ee5a5 commit b060cfc
Show file tree
Hide file tree
Showing 124 changed files with 4,105 additions and 282 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})
include(TableGen)
include(AddLLVM)
include(AddMLIR)
include(AddMLIRPython)
include(HandleLLVMOptions)
include(LLVMExports)

Expand Down
2 changes: 1 addition & 1 deletion conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ requirements:
- zlib/1.2.13
- zstd/1.5.5
- nlohmann_json/3.9.1
- pybind11/2.10.1
- pybind11/2.11.1
- clang-tools-extra/17.0.5-0@
- llvm/17.0.5-0@
- qasm/0.3.0@qss/stable
9 changes: 8 additions & 1 deletion conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,14 @@ def package(self):
def test(self, cmake):
cmake = self._configure_cmake()
cmake.test(target="check-tests")
self.run(f"cd {self.source_folder} && pytest test/python_lib")
# Separate pytest calls to avoid
# cross contaminating the test environments
# due to fixtures/tests of the same name being cached
self.run(
f"cd {self.source_folder} && "
"pytest test/python_lib && "
"pytest targets/systems/mock/test/python_lib"
)

def package_info(self):
self.cpp_info.libs = tools.collect_libs(self)
32 changes: 15 additions & 17 deletions include/Conversion/QUIRToPulse/QUIRToPulse.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ struct QUIRToPulsePass
mlir::Operation *mainFuncFirstOp;

// convert quir circuit to pulse sequence
void convertCircuitToSequence(mlir::quir::CallCircuitOp callCircuitOp,
mlir::func::FuncOp &mainFunc,
ModuleOp moduleOp);
mlir::pulse::CallSequenceOp
convertCircuitToSequence(mlir::quir::CallCircuitOp &callCircuitOp,
mlir::func::FuncOp &mainFunc, ModuleOp &moduleOp);
// helper datastructure for converting quir circuit to pulse sequence; these
// will be reset every time convertCircuitToSequence is called and will be
// used by several functions that are called within that function
Expand All @@ -75,51 +75,51 @@ struct QUIRToPulsePass

// process the args of the circuit op, and add corresponding args to the
// converted pulse sequence op
void processCircuitArgs(mlir::quir::CallCircuitOp callCircuitOp,
mlir::quir::CircuitOp circuitOp,
SequenceOp convertedPulseSequenceOp,
void processCircuitArgs(mlir::quir::CallCircuitOp &callCircuitOp,
mlir::quir::CircuitOp &circuitOp,
SequenceOp &convertedPulseSequenceOp,
mlir::func::FuncOp &mainFunc,
mlir::OpBuilder &builder);

// process the args of the pulse cal sequence op corresponding to quirOp
void processPulseCalArgs(mlir::Operation *quirOp,
SequenceOp pulseCalSequenceOp,
SequenceOp &pulseCalSequenceOp,
SmallVector<Value> &pulseCalSeqArgs,
SequenceOp convertedPulseSequenceOp,
SequenceOp &convertedPulseSequenceOp,
mlir::func::FuncOp &mainFunc,
mlir::OpBuilder &builder);
void getQUIROpClassicalOperands(mlir::Operation *quirOp,
std::queue<Value> &angleOperands,
std::queue<Value> &durationOperands);
void processMixFrameOpArg(std::string const &mixFrameName,
std::string const &portName,
SequenceOp convertedPulseSequenceOp,
SequenceOp &convertedPulseSequenceOp,
SmallVector<Value> &quirOpPulseCalSeqArgs,
Value argumentValue, mlir::func::FuncOp &mainFunc,
mlir::OpBuilder &builder);
void processPortOpArg(std::string const &portName,
SequenceOp convertedPulseSequenceOp,
SequenceOp &convertedPulseSequenceOp,
SmallVector<Value> &quirOpPulseCalSeqArgs,
Value argumentValue, mlir::func::FuncOp &mainFunc,
mlir::OpBuilder &builder);
void processWfrOpArg(std::string const &wfrName,
SequenceOp convertedPulseSequenceOp,
SequenceOp &convertedPulseSequenceOp,
SmallVector<Value> &quirOpPulseCalSeqArgs,
Value argumentValue, mlir::func::FuncOp &mainFunc,
mlir::OpBuilder &builder);
void processAngleArg(Value nextAngleOperand,
SequenceOp convertedPulseSequenceOp,
SequenceOp &convertedPulseSequenceOp,
SmallVector<Value> &quirOpPulseCalSeqArgs,
mlir::OpBuilder &builder);
void processDurationArg(Value frontDurOperand,
SequenceOp convertedPulseSequenceOp,
SequenceOp &convertedPulseSequenceOp,
SmallVector<Value> &quirOpPulseCalSeqArgs,
mlir::OpBuilder &builder);

// convert angle to F64
mlir::Value convertAngleToF64(Operation *angleOp, mlir::OpBuilder &builder);
// convert duration to I64
mlir::Value convertDurationToI64(mlir::quir::CallCircuitOp callCircuitOp,
mlir::Value convertDurationToI64(mlir::quir::CallCircuitOp &callCircuitOp,
Operation *durOp, uint &cnt,
mlir::OpBuilder &builder,
mlir::func::FuncOp &mainFunc);
Expand Down Expand Up @@ -149,18 +149,16 @@ struct QUIRToPulsePass
mlir::OpBuilder &builder);

void addCircuitToEraseList(mlir::Operation *op);
void addCallCircuitToEraseList(mlir::Operation *op);
void addCircuitOperandToEraseList(mlir::Operation *op);
std::vector<mlir::Operation *> quirCircuitEraseList;
std::vector<mlir::Operation *> quirCallCircuitEraseList;
std::vector<mlir::Operation *> quirCircuitOperandEraseList;

// parse the waveform containers and add them to pulseNameToWaveformMap
void parsePulseWaveformContainerOps(std::string &waveformContainerPath);
std::map<std::string, Waveform_CreateOp> pulseNameToWaveformMap;

llvm::StringMap<Operation *> symbolMap;
mlir::quir::CircuitOp getCircuitOp(mlir::quir::CallCircuitOp callCircuitOp);
mlir::quir::CircuitOp getCircuitOp(mlir::quir::CallCircuitOp &callCircuitOp);
mlir::pulse::SequenceOp getSequenceOp(std::string const &symbolName);
};
} // namespace mlir::pulse
Expand Down
1 change: 1 addition & 0 deletions include/Dialect/OQ3/IR/OQ3Base.td
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def OQ3_Dialect : Dialect {
let cppNamespace = "::mlir::oq3";
let dependentDialects = [
"mlir::arith::ArithDialect",
"mlir::math::MathDialect",
"mlir::LLVM::LLVMDialect"
];
}
Expand Down
1 change: 1 addition & 0 deletions include/Dialect/OQ3/IR/OQ3Dialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/LLVMIR/LLVMDialect.h"
#include "mlir/Dialect/Math/IR/Math.h"
#include "mlir/Dialect/SCF/IR/SCF.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Dialect.h"
Expand Down
6 changes: 3 additions & 3 deletions include/Dialect/Pulse/IR/PulseDialect.td
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//===- PulseDialect.td - Pulse dialect ---------------------*- tablegen -*-===//
//
// (C) Copyright IBM 2023.
// (C) Copyright IBM 2023, 2024.
//
// This code is part of Qiskit.
//
Expand Down Expand Up @@ -57,7 +57,7 @@ class Pulse_Attr<string name, string attrMnemonic, list<Trait> traits = []>
let mnemonic = attrMnemonic;
}

include "PulseTypes.td"
include "PulseOps.td"
include "Dialect/Pulse/IR/PulseTypes.td"
include "Dialect/Pulse/IR/PulseOps.td"

#endif // PULSE_DIALECT
4 changes: 2 additions & 2 deletions include/Dialect/Pulse/IR/PulseOps.td
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//===- PulseOps.td - Pulse dialect ops ---------------------*- tablegen -*-===//
//
// (C) Copyright IBM 2023.
// (C) Copyright IBM 2023, 2024.
//
// This code is part of Qiskit.
//
Expand All @@ -17,7 +17,7 @@
#ifndef PULSE_OPS
#define PULSE_OPS

include "PulseTraits.td"
include "Dialect/Pulse/IR/PulseTraits.td"

include "Dialect/QUIR/IR/QUIRTypeConstraints.td"
include "Dialect/Pulse/IR/PulseInterfaces.td"
Expand Down
9 changes: 8 additions & 1 deletion include/Dialect/QUIR/IR/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# (C) Copyright IBM 2023.
# (C) Copyright IBM 2023, 2024.
#
# This code is part of Qiskit.
#
Expand All @@ -16,9 +16,16 @@ add_mlir_doc(QUIR QUIRDialect generated/Dialect/QUIR/ -gen-dialect-doc -dialect=
set(LLVM_TARGET_DEFINITIONS QUIR.td)
mlir_tablegen(QUIRAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=quir)
mlir_tablegen(QUIRAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=quir)
add_public_tablegen_target(QUIRAttributesIncGen)

set(LLVM_TARGET_DEFINITIONS QUIR.td)
mlir_tablegen(QUIREnums.h.inc -gen-enum-decls)
mlir_tablegen(QUIREnums.cpp.inc -gen-enum-defs)
add_public_tablegen_target(QUIREnumsIncGen)

# This dependency makes sure that the attributes and enums include files are
# generated before anything that requires the include files generated for the
# QUIR dialect
add_dependencies(MLIRQUIRIncGen QUIREnumsIncGen QUIRAttributesIncGen)

add_mlir_interface(QUIRInterfaces)
31 changes: 31 additions & 0 deletions include/Dialect/QUIR/Transforms/BreakReset.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,28 @@
#include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/Pass.h"

#include "Dialect/QUIR/IR/QUIROps.h"

#include <deque>

namespace mlir::quir {

/// This pass converts input ResetQubitOps to a parameterized number of
/// measure and the conditionally called x gates, as well as an optional delay.
struct BreakResetPass
: public mlir::PassWrapper<BreakResetPass,
mlir::OperationPass<mlir::ModuleOp>> {
bool insertQuantumGatesIntoCirc = false;

BreakResetPass() = default;
BreakResetPass(const BreakResetPass &pass) : PassWrapper(pass) {}
BreakResetPass(uint inNumIterations, uint inDelayCycles) {
numIterations = inNumIterations;
delayCycles = inDelayCycles;
}
BreakResetPass(bool inInsertCallGatesAndMeasuresIntoCircuit) {
insertQuantumGatesIntoCirc = inInsertCallGatesAndMeasuresIntoCircuit;
}

void runOnOperation() override;
Option<uint> numIterations{
Expand All @@ -49,10 +58,32 @@ struct BreakResetPass
llvm::cl::desc("Number of cycles of delay to add between reset "
"iterations, default is 1000"),
llvm::cl::value_desc("num"), llvm::cl::init(1000)};
Option<bool> insertCallGatesAndMeasuresIntoCircuit{
*this, "quantum-gates-in-circuit",
llvm::cl::desc(
"an option to insert call gates and measures into circuit"),
llvm::cl::value_desc("bool"), llvm::cl::init(false)};

llvm::StringRef getArgument() const override;
llvm::StringRef getDescription() const override;
llvm::StringRef getName() const override;

std::deque<Operation *> measureList;
std::deque<Operation *> callGateList;

private:
// keep track of all circuits
llvm::StringMap<Operation *> circuitsSymbolMap;
void insertMeasureInCircuit(mlir::func::FuncOp &mainFunc,
mlir::quir::MeasureOp measureOp);
void insertCallGateInCircuit(mlir::func::FuncOp &mainFunc,
mlir::quir::CallGateOp callGateOp);
template <class measureOrCallGate>
mlir::quir::CircuitOp startCircuit(mlir::func::FuncOp &mainFunc,
measureOrCallGate quantumGate);
void finishCircuit(mlir::quir::CircuitOp circOp, Operation *quantumGate);
uint circuitCounter = 0;
std::string getMangledName();
}; // struct BreakResetPass
} // namespace mlir::quir

Expand Down
73 changes: 73 additions & 0 deletions include/Dialect/QUIR/Transforms/ExtractCircuits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//===- ExtractCircuits.h - Extract circuits ops -----------------*- C++ -*-===//
//
// (C) Copyright IBM 2024.
//
// This code is part of Qiskit.
//
// This code is licensed under the Apache License, Version 2.0 with LLVM
// Exceptions. You may obtain a copy of this license in the LICENSE.txt
// file in the root directory of this source tree.
//
// 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 declares the pass for extracting quantum ops into quir.circuits
///
//===----------------------------------------------------------------------===//

#ifndef QUIR_EXTRACT_CIRCUITS_H
#define QUIR_EXTRACT_CIRCUITS_H

#include "Dialect/QUIR/IR/QUIROps.h"

#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Pass/Pass.h"

#include "llvm/ADT/SmallVector.h"

#include <unordered_map>

namespace mlir::quir {

struct ExtractCircuitsPass
: public PassWrapper<ExtractCircuitsPass, OperationPass<>> {
void runOnOperation() override;

llvm::StringRef getArgument() const override;
llvm::StringRef getDescription() const override;
llvm::StringRef getName() const override;

private:
void processRegion(mlir::Region &region, OpBuilder topLevelBuilder,
OpBuilder circuitBuilder);
void processBlock(mlir::Block &block, OpBuilder topLevelBuilder,
OpBuilder circuitBuilder);
OpBuilder startCircuit(mlir::Location location, OpBuilder topLevelBuilder);
void endCircuit(mlir::Operation *firstOp, mlir::Operation *lastOp,
OpBuilder topLevelBuilder, OpBuilder circuitBuilder,
llvm::SmallVector<Operation *> &eraseList);
void addToCircuit(mlir::Operation *currentOp, OpBuilder circuitBuilder,
llvm::SmallVector<Operation *> &eraseList);
uint64_t circuitCount = 0;
llvm::StringMap<Operation *> circuitOpsMap;

mlir::quir::CircuitOp currentCircuitOp = nullptr;
mlir::quir::CallCircuitOp newCallCircuitOp;

llvm::SmallVector<Type> inputTypes;
llvm::SmallVector<Value> inputValues;
llvm::SmallVector<Type> outputTypes;
llvm::SmallVector<Value> outputValues;
std::vector<int> phyiscalIds;
std::unordered_map<uint32_t, int> argToId;

std::unordered_map<Operation *, uint32_t> circuitOperands;
llvm::SmallVector<OpResult> originalResults;

}; // struct ExtractCircuitsPass
} // namespace mlir::quir
#endif // QUIR_EXTRACT_CIRCUITS_H
3 changes: 2 additions & 1 deletion include/Dialect/QUIR/Transforms/Passes.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//===- Passes.h - Quir Passes -----------------------------------*- C++ -*-===//
//
// (C) Copyright IBM 2023.
// (C) Copyright IBM 2023, 2024.
//
// This code is part of Qiskit.
//
Expand All @@ -21,6 +21,7 @@
#include "AngleConversion.h"
#include "BreakReset.h"
#include "ConvertDurationUnits.h"
#include "ExtractCircuits.h"
#include "FunctionArgumentSpecialization.h"
#include "LoadElimination.h"
#include "MergeCircuitMeasures.h"
Expand Down
2 changes: 2 additions & 0 deletions include/Dialect/QUIR/Utils/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ std::tuple<Value, MeasureOp> qubitFromMeasResult(MeasureOp measureOp,
Value result);
std::tuple<Value, MeasureOp> qubitFromMeasResult(CallCircuitOp callCircuitOp,
Value result);
std::tuple<Value, MeasureOp> qubitFromMeasResult(CircuitOp circuitOp,
Value result);

} // end namespace mlir::quir

Expand Down
2 changes: 2 additions & 0 deletions include/Frontend/OpenQASM3/BaseQASM3Visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ class BaseQASM3Visitor {

virtual void visit(const QASM::ASTOperatorNode *) = 0;

virtual void visit(const QASM::ASTOperandNode *) = 0;

virtual void visit(const QASM::ASTUnaryOpNode *) = 0;
};

Expand Down
2 changes: 2 additions & 0 deletions include/Frontend/OpenQASM3/PrintQASM3Visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ class PrintQASM3Visitor : public BaseQASM3Visitor {

void visit(const QASM::ASTOperatorNode *) override;

void visit(const QASM::ASTOperandNode *) override;

void visit(const QASM::ASTUnaryOpNode *) override;
};

Expand Down
Loading

0 comments on commit b060cfc

Please sign in to comment.