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

loading the pulse calibrations #137

Merged
merged 22 commits into from
Sep 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
127 changes: 127 additions & 0 deletions include/Conversion/QUIRToPulse/LoadPulseCals.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//===- LoadPulseCals.h ------------------------------------------*- C++ -*-===//
//
// (C) Copyright IBM 2023.
//
// 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 to load the pulse calibrations.
///
//===----------------------------------------------------------------------===//

#ifndef LOAD_PULSE_CALS_H
#define LOAD_PULSE_CALS_H

#include "Dialect/Pulse/IR/PulseOps.h"

#include "mlir/IR/MLIRContext.h"
#include "mlir/Pass/Pass.h"

#include <unordered_set>
#include <vector>

namespace mlir::pulse {

struct LoadPulseCalsPass
: public PassWrapper<LoadPulseCalsPass, OperationPass<ModuleOp>> {
std::string DEFAULT_PULSE_CALS = "";
std::string ADDITIONAL_PULSE_CALS = "";

// this pass uses up to three sources to obtain the pulse calibration
// sequences. (1) default pulse calibration file if specified.
// (2) additional pulse calibration file if specified; this will
// override default pulse calibrations. (3) pulse calibration
// sequences specified in the MLIR input program by compiler user;
// this will override both default and additional pulse calibrations.
LoadPulseCalsPass() = default;
LoadPulseCalsPass(const LoadPulseCalsPass &pass) : PassWrapper(pass) {}
LoadPulseCalsPass(std::string inDefaultPulseCals) {
DEFAULT_PULSE_CALS = std::move(inDefaultPulseCals);
reza-j marked this conversation as resolved.
Show resolved Hide resolved
}
LoadPulseCalsPass(std::string inDefaultPulseCals,
std::string inAdditionalPulseCals) {
DEFAULT_PULSE_CALS = std::move(inDefaultPulseCals);
reza-j marked this conversation as resolved.
Show resolved Hide resolved
ADDITIONAL_PULSE_CALS = std::move(inAdditionalPulseCals);
reza-j marked this conversation as resolved.
Show resolved Hide resolved
}

void runOnOperation() override;

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

// optionally, one can override the path to default pulse calibrations with
// this option; e.g., to write a LIT test one can invoke this pass with
// --load-pulse-cals=default-pulse-cals=<path-to-pulse-cals-file>
Option<std::string> defaultPulseCals{
*this, "default-pulse-cals",
llvm::cl::desc("default pulse calibrations MLIR file"),
llvm::cl::value_desc("filename"), llvm::cl::init("")};

void loadPulseCals(mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::CallGateOp callGateOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::BuiltinCXOp CXOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::Builtin_UOp UOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::MeasureOp measureOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::BarrierOp barrierOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::DelayOp delayOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);
void loadPulseCals(mlir::quir::ResetQubitOp resetOp,
mlir::quir::CallCircuitOp callCircuitOp, FuncOp funcOp);

void addPulseCalToModule(FuncOp funcOp, mlir::pulse::SequenceOp sequenceOp);

// parse the pulse cals and return the parsed module
llvm::Error parsePulseCalsModuleOp(std::string &pulseCalsPath,
mlir::OwningOpRef<ModuleOp> &owningOpRef);
mlir::OwningOpRef<ModuleOp> defaultPulseCalsModule;
mlir::OwningOpRef<ModuleOp> additionalPulseCalsModule;
std::map<std::string, SequenceOp> pulseCalsNameToSequenceMap;

mlir::pulse::SequenceOp
mergePulseSequenceOps(std::vector<mlir::pulse::SequenceOp> &sequenceOps,
const std::string &mergedSequenceOpName);
// remove the redundant delay args after merging multiple delayOp pulse cals
void removeRedundantDelayArgs(mlir::pulse::SequenceOp sequenceOp,
mlir::OpBuilder &builder);

// set of pulse cals already added to IR
std::unordered_set<std::string> pulseCalsAddedToIR;

// returns true if all the sequence ops in the input vector has the same
// duration
bool doAllSequenceOpsHaveSameDuration(
std::vector<mlir::pulse::SequenceOp> &sequenceOps);
// returns true if all the sequence ops in the input vector has attrName
// attribute and if yes, merges the attributes
bool mergeAttributes(std::vector<mlir::pulse::SequenceOp> &sequenceOps,
const std::string &attrName,
std::vector<mlir::Attribute> &attrVector);

std::string getMangledName(std::string &gateName,
std::vector<uint32_t> &qubits);
std::string getMangledName(std::string &gateName, uint32_t qubit);
std::vector<uint32_t>
getQubitOperands(std::vector<Value> &qubitOperands,
mlir::quir::CallCircuitOp callCircuitOp);

// TODO: move this function to Utils; it's used here and MergeCircuitsPass
static mlir::quir::CircuitOp
getCircuitOp(mlir::quir::CallCircuitOp callCircuitOp);
};
} // namespace mlir::pulse

#endif // LOAD_PULSE_CALS_H
1 change: 1 addition & 0 deletions include/Dialect/Pulse/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#ifndef PULSE_PULSEPASSES_H
#define PULSE_PULSEPASSES_H

#include "Conversion/QUIRToPulse/LoadPulseCals.h"
#include "Conversion/QUIRToPulse/QUIRToPulse.h"
#include "Dialect/Pulse/Transforms/ClassicalOnlyDetection.h"
#include "Dialect/Pulse/Transforms/MergeDelays.h"
Expand Down
2 changes: 2 additions & 0 deletions lib/Conversion/QUIRToPulse/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

add_mlir_conversion_library(QUIRToPulse

LoadPulseCals.cpp

detail/TypeConversion.cpp

ADDITIONAL_HEADER_DIRS
Expand Down
Loading