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

loading the pulse calibrations #137

merged 22 commits into from
Sep 15, 2023

Conversation

reza-j
Copy link
Contributor

@reza-j reza-j commented Jul 26, 2023

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

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

include/Conversion/QUIRToPulse/LoadPulseCals.h Outdated Show resolved Hide resolved
include/Conversion/QUIRToPulse/LoadPulseCals.h Outdated Show resolved Hide resolved
include/Conversion/QUIRToPulse/LoadPulseCals.h Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
reza-j and others added 3 commits August 1, 2023 16:04
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
@github-actions
Copy link
Contributor

github-actions bot commented Aug 2, 2023

clang-tidy review says "All clean, LGTM! 👍"

@github-actions
Copy link
Contributor

github-actions bot commented Aug 9, 2023

clang-tidy review says "All clean, LGTM! 👍"

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
Copy link
Collaborator

@kitbarton kitbarton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is coming along really nicely.

There are a couple github checks that I've never seen before, but are good to fix.

I have a couple other general comments, which I flagged in a couple places but I think it would be good to change throughout this patch:

  1. Error handling in the case that the pulse cals cannot be loaded (bad path, no file, etc).
  2. Use of if (condition) assert(false && "message");. I think it is better to sink the condition into the assert. It improves readability (in my opinion) and makes things a bit easier to reason about in the case when asserts are disabled.

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Show resolved Hide resolved
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
@reza-j reza-j requested a review from kitbarton August 17, 2023 21:49
@reza-j
Copy link
Contributor Author

reza-j commented Sep 11, 2023

@kitbarton gentle reminder that this PR is ready for a second review

Copy link
Contributor

@mbhealy mbhealy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few changes would improve things. I'm also concerned by the OwningRef release semantics.

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
Comment on lines 213 to 217
if (pulseCalsNameToSequenceMap.find(gateMangledName) !=
pulseCalsNameToSequenceMap.end()) {
// found a pulse calibration for the barrier gate
addPulseCalToModule(funcOp, pulseCalsNameToSequenceMap[gateMangledName]);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here, return early and drop the else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in
036e5b1

Comment on lines 249 to 253
if (pulseCalsNameToSequenceMap.find(gateMangledName) !=
pulseCalsNameToSequenceMap.end()) {
// found a pulse calibration for the barrier gate
addPulseCalToModule(funcOp, pulseCalsNameToSequenceMap[gateMangledName]);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in
036e5b1

Comment on lines 286 to 290
if (pulseCalsNameToSequenceMap.find(gateMangledName) !=
pulseCalsNameToSequenceMap.end()) {
// found a pulse calibration for the gate
addPulseCalToModule(funcOp, pulseCalsNameToSequenceMap[gateMangledName]);
} else {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in
036e5b1

Comment on lines 312 to 319
if (pulseCalsAddedToIR.find(sequenceOp.sym_name().str()) ==
pulseCalsAddedToIR.end()) {
OpBuilder builder(funcOp.body());
auto *clonedPulseCalOp = builder.clone(*sequenceOp);
auto clonedPulseCalSequenceOp = dyn_cast<SequenceOp>(clonedPulseCalOp);
clonedPulseCalSequenceOp->moveBefore(funcOp);
pulseCalsAddedToIR.insert(sequenceOp.sym_name().str());
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be useful to add an else here with a debug message?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added in
80ddf0f

Comment on lines 333 to 343
mlir::OwningOpRef<ModuleOp> pulseCalsModule(
mlir::parseSourceFile(sourceMgr, &getContext()));
if (!pulseCalsModule)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Failed to parse pulse calibrations file: " +
pulseCalsPath);
auto pulseCalsModuleRelease = pulseCalsModule.release();
pulseCalsModuleRelease->walk([&](mlir::pulse::SequenceOp sequenceOp) {
auto sequenceName = sequenceOp.sym_name().str();
pulseCalsNameToSequenceMap[sequenceName] = sequenceOp;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole section worries me. You parse in a module into an owning ref, then release it and store the name in a map. I'm worried this is only working currently because the memory is hanging around and not allocated for something else. Am I misunderstanding? It seems like there should be a copy of the contents of the parsed module into the existing top-level module for the translation unit.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole section worries me. You parse in a module into an owning ref, then release it and store the name in a map. I'm worried this is only working currently because the memory is hanging around and not allocated for something else. Am I misunderstanding? It seems like there should be a copy of the contents of the parsed module into the existing top-level module for the translation unit.

Doesn't this depend on whether the copy constructor for the sequenceOp performs a deep copy or shallow copy?
I couldn't find the definition of sequenceOp quickly, so I don't know for sure.
Since this is a map of string to sequenceOp (and not sequenceOp reference or pointer) I would assume each sequence op is being copied as part of adding it to the map.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so pulseCalsModule is of type mlir::OwningOpRef<ModuleOp>, and pulseCalsModule.release() returns the corresponding ModuleOp, and its result (i.e., pulseCalsModuleRelease) is of type ModuleOp which I then do further processing on. In other words, I used release function to obtain the ModuleOp. Please let me know what you think

Another example of this in the codebase is https://github.com/Qiskit/qss-compiler/blob/6528f4e7a7feeec7f72f784a4784151fb83b7a7c/lib/API/api.cpp#L611

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mbhealy @kitbarton was my answer related to your comment? or your concern is that maybe only a reference to sequenceOp is copied to the map, instead of the whole object?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From looking at the definition of owningOpRef it looks like the destructor only erases the memory if the op contains something, and release() should swap the memory from the owning ref to the moduleOp it's released to. Kit's point also about the copy for the map seems relevant. I'm still a bit worried because I'm not clear on exactly how Ops interact with the map constructs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactored and removed release() in 4dba7d8. Thanks for looking into this! @mbhealy


// clone the body of the original sequence ops
for (std::size_t seqNum = 1; seqNum < sequenceOps.size(); seqNum++) {
builder.setInsertionPointAfter(&mergedSequenceOp.back().back());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does insertion point setting have to be done inside the loop? Or can it be done once before the loop only?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in
80ddf0f

sequenceOp->setAttr("pulse.args", builder.getArrayAttr(argAttrVec));
}

bool LoadPulseCalsPass::areAllSequenceOpsHasSameDuration(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly more grammatical function name

Suggested change
bool LoadPulseCalsPass::areAllSequenceOpsHasSameDuration(
bool LoadPulseCalsPass::doAllSequenceOpsHaveSameDuration(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addressed in
80ddf0f

Copy link
Collaborator

@kitbarton kitbarton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good.
I have a few non-blocking comments/questions.

@mbhealy had a good question about dangling memory for the sequenceOps that should get resolved before this is merged though.


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

// parse the pulse cals and add them to pulseCalsNameToSequenceMap
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are standard comments, not doxygen comments.
Is that intentional or an oversight?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is just standard comment

else if (auto castOp = dyn_cast<mlir::quir::DelayOp>(op))
loadPulseCals(castOp, callCircuitOp, funcOp);
else if (auto castOp = dyn_cast<mlir::quir::ResetQubitOp>(op))
loadPulseCals(castOp, callCircuitOp, funcOp);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a final else here if nothing matches? Or is that acceptable behaviour?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if nothing matches we need to make sure it's not a quantum gate/measure, that needs calibration loading. Added in
80ddf0f

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added assert condition instead of assert false in 567e7fb

Comment on lines 333 to 343
mlir::OwningOpRef<ModuleOp> pulseCalsModule(
mlir::parseSourceFile(sourceMgr, &getContext()));
if (!pulseCalsModule)
return llvm::createStringError(llvm::inconvertibleErrorCode(),
"Failed to parse pulse calibrations file: " +
pulseCalsPath);
auto pulseCalsModuleRelease = pulseCalsModule.release();
pulseCalsModuleRelease->walk([&](mlir::pulse::SequenceOp sequenceOp) {
auto sequenceName = sequenceOp.sym_name().str();
pulseCalsNameToSequenceMap[sequenceName] = sequenceOp;
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole section worries me. You parse in a module into an owning ref, then release it and store the name in a map. I'm worried this is only working currently because the memory is hanging around and not allocated for something else. Am I misunderstanding? It seems like there should be a copy of the contents of the parsed module into the existing top-level module for the translation unit.

Doesn't this depend on whether the copy constructor for the sequenceOp performs a deep copy or shallow copy?
I couldn't find the definition of sequenceOp quickly, so I don't know for sure.
Since this is a map of string to sequenceOp (and not sequenceOp reference or pointer) I would assume each sequence op is being copied as part of adding it to the map.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang-tidy made some suggestions

lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
lib/Conversion/QUIRToPulse/LoadPulseCals.cpp Outdated Show resolved Hide resolved
reza-j and others added 2 commits September 15, 2023 11:56
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

@mbhealy mbhealy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@github-actions
Copy link
Contributor

clang-tidy review says "All clean, LGTM! 👍"

@reza-j reza-j merged commit 12b9fdf into main Sep 15, 2023
2 checks passed
@reza-j reza-j deleted the rj-load-pulse-cals branch September 15, 2023 20:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants