Skip to content

Commit 12b9fdf

Browse files
reza-jgithub-actions[bot]mbhealy
authored
loading the pulse calibrations (#137)
This PR adds a pass that loads the pulse calibrations, mark the quir operations with their pulse calibration name, and add the pulse calibrations to the module --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: mbhealy <[email protected]>
1 parent a48899d commit 12b9fdf

File tree

5 files changed

+754
-0
lines changed

5 files changed

+754
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
//===- LoadPulseCals.h ------------------------------------------*- 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+
/// This file declares the pass to load the pulse calibrations.
18+
///
19+
//===----------------------------------------------------------------------===//
20+
21+
#ifndef LOAD_PULSE_CALS_H
22+
#define LOAD_PULSE_CALS_H
23+
24+
#include "Dialect/Pulse/IR/PulseOps.h"
25+
26+
#include "mlir/IR/MLIRContext.h"
27+
#include "mlir/Pass/Pass.h"
28+
29+
#include <unordered_set>
30+
#include <vector>
31+
32+
namespace mlir::pulse {
33+
34+
struct LoadPulseCalsPass
35+
: public PassWrapper<LoadPulseCalsPass, OperationPass<ModuleOp>> {
36+
std::string DEFAULT_PULSE_CALS = "";
37+
std::string ADDITIONAL_PULSE_CALS = "";
38+
39+
// this pass uses up to three sources to obtain the pulse calibration
40+
// sequences. (1) default pulse calibration file if specified.
41+
// (2) additional pulse calibration file if specified; this will
42+
// override default pulse calibrations. (3) pulse calibration
43+
// sequences specified in the MLIR input program by compiler user;
44+
// this will override both default and additional pulse calibrations.
45+
LoadPulseCalsPass() = default;
46+
LoadPulseCalsPass(const LoadPulseCalsPass &pass) : PassWrapper(pass) {}
47+
LoadPulseCalsPass(std::string inDefaultPulseCals) {
48+
DEFAULT_PULSE_CALS = std::move(inDefaultPulseCals);
49+
}
50+
LoadPulseCalsPass(std::string inDefaultPulseCals,
51+
std::string inAdditionalPulseCals) {
52+
DEFAULT_PULSE_CALS = std::move(inDefaultPulseCals);
53+
ADDITIONAL_PULSE_CALS = std::move(inAdditionalPulseCals);
54+
}
55+
56+
void runOnOperation() override;
57+
58+
llvm::StringRef getArgument() const override;
59+
llvm::StringRef getDescription() const override;
60+
61+
// optionally, one can override the path to default pulse calibrations with
62+
// this option; e.g., to write a LIT test one can invoke this pass with
63+
// --load-pulse-cals=default-pulse-cals=<path-to-pulse-cals-file>
64+
Option<std::string> defaultPulseCals{
65+
*this, "default-pulse-cals",
66+
llvm::cl::desc("default pulse calibrations MLIR file"),
67+
llvm::cl::value_desc("filename"), llvm::cl::init("")};
68+
69+
void loadPulseCals(mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
70+
void loadPulseCals(mlir::quir::CallGateOp callGateOp,
71+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
72+
void loadPulseCals(mlir::quir::BuiltinCXOp CXOp,
73+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
74+
void loadPulseCals(mlir::quir::Builtin_UOp UOp,
75+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
76+
void loadPulseCals(mlir::quir::MeasureOp measureOp,
77+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
78+
void loadPulseCals(mlir::quir::BarrierOp barrierOp,
79+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
80+
void loadPulseCals(mlir::quir::DelayOp delayOp,
81+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
82+
void loadPulseCals(mlir::quir::ResetQubitOp resetOp,
83+
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
84+
85+
void addPulseCalToModule(FuncOp funcOp, mlir::pulse::SequenceOp sequenceOp);
86+
87+
// parse the pulse cals and return the parsed module
88+
llvm::Error parsePulseCalsModuleOp(std::string &pulseCalsPath,
89+
mlir::OwningOpRef<ModuleOp> &owningOpRef);
90+
mlir::OwningOpRef<ModuleOp> defaultPulseCalsModule;
91+
mlir::OwningOpRef<ModuleOp> additionalPulseCalsModule;
92+
std::map<std::string, SequenceOp> pulseCalsNameToSequenceMap;
93+
94+
mlir::pulse::SequenceOp
95+
mergePulseSequenceOps(std::vector<mlir::pulse::SequenceOp> &sequenceOps,
96+
const std::string &mergedSequenceOpName);
97+
// remove the redundant delay args after merging multiple delayOp pulse cals
98+
void removeRedundantDelayArgs(mlir::pulse::SequenceOp sequenceOp,
99+
mlir::OpBuilder &builder);
100+
101+
// set of pulse cals already added to IR
102+
std::unordered_set<std::string> pulseCalsAddedToIR;
103+
104+
// returns true if all the sequence ops in the input vector has the same
105+
// duration
106+
bool doAllSequenceOpsHaveSameDuration(
107+
std::vector<mlir::pulse::SequenceOp> &sequenceOps);
108+
// returns true if all the sequence ops in the input vector has attrName
109+
// attribute and if yes, merges the attributes
110+
bool mergeAttributes(std::vector<mlir::pulse::SequenceOp> &sequenceOps,
111+
const std::string &attrName,
112+
std::vector<mlir::Attribute> &attrVector);
113+
114+
std::string getMangledName(std::string &gateName,
115+
std::vector<uint32_t> &qubits);
116+
std::string getMangledName(std::string &gateName, uint32_t qubit);
117+
std::vector<uint32_t>
118+
getQubitOperands(std::vector<Value> &qubitOperands,
119+
mlir::quir::CallCircuitOp callCircuitOp);
120+
121+
// TODO: move this function to Utils; it's used here and MergeCircuitsPass
122+
static mlir::quir::CircuitOp
123+
getCircuitOp(mlir::quir::CallCircuitOp callCircuitOp);
124+
};
125+
} // namespace mlir::pulse
126+
127+
#endif // LOAD_PULSE_CALS_H

include/Dialect/Pulse/Transforms/Passes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#ifndef PULSE_PULSEPASSES_H
2222
#define PULSE_PULSEPASSES_H
2323

24+
#include "Conversion/QUIRToPulse/LoadPulseCals.h"
2425
#include "Conversion/QUIRToPulse/QUIRToPulse.h"
2526
#include "Dialect/Pulse/Transforms/ClassicalOnlyDetection.h"
2627
#include "Dialect/Pulse/Transforms/MergeDelays.h"

lib/Conversion/QUIRToPulse/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
add_mlir_conversion_library(QUIRToPulse
1414

15+
LoadPulseCals.cpp
16+
1517
detail/TypeConversion.cpp
1618

1719
ADDITIONAL_HEADER_DIRS

0 commit comments

Comments
 (0)