qir-alliance / qat

QIR compiler tools and optimization passes for targeting QIR to different hardware backends

Home Page:https://qir-alliance.github.io/qat/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature proposal: Provide standalone QIR passes

LaurentAjdnik opened this issue · comments

This follows:

  • a demonstration of "QIR passes" in Python by @LaurentAjdnik on Apr. 14, 2022
  • a discussion during the "QIR²" community call on May 19, 2002

QAT includes/mimics/relies on LLVM passes but embeds them inside QAT-specific components.

LLVM passes can be provided as standalone libraries that can be applied with the opt tool.

Proposal: Initiate an ever-growing set of genuine and standalone LLVM passes dedicated to QIR analysis and transformation.

Notes:

  • We might need a specific Github repository
  • Some passes could be generic while others would be hardware-specific
  • Optimization passes could universally do what some QDKs provide only for their specific environment: Removing duplicate gates, Merging redundant gates...
  • Hardware-specific passes could include everything that's needed to compile towards specific backends
  • Hardware-specific passes could be provided by the corresponding vendors

Thanks for this proposal.

QAT already includes a number of custom written LLVM passes. Each of these passes are standalone and could, in theory at least, be used as standalone passes that could be loaded by opt or other LLVM infrastructure. The only requirement to do so would be write the corresponding dynamic library and reuse the existing passes.

To clarify what you are proposing:

  • Is this a proposal to restructure the library?
  • Or is it a proposal to replace the qat executable with opt?
  • Or something else?

Hi @troelsfr and thanks for your feedback!

First, I have to admit that, despite looking into it for a while, I am not too familiar yet with the whole architecture of QAT. 😁

I noticed QAT indeed uses LLVM passes but:

  • As you said, they lack the dynamic library approach (for both the legacy and the new LLVM pass managers) so that they can be used with opt
  • It seems their source code is sometimes closely linked to other classes being part of QAT

The core of the discussions was to provide some standalone LLVM/QIR passes, independently from QAT.

These standalone passes would provide many features, some of them potentially not being in the scope of QAT, falling into these categories: Analyses, Checks, Optimizations, Backend-conversions...

Hence, they could be used as part of an LLVM toolchain and selected according to the needs of the compiler.

This set could be enriched by users, OS project maintainers or hardware vendors. To the point where, when a need arises, one can pick from the available passes.

A bit in the way that LLVM already provides dozens of standard passes, these would become "QIR standard passes" that deal specifically with quantum stuff.

Note : QAT would clearly still be an important and useful tool. And it could also rely on some of these passes. Maybe a first step would be to extract the existing ones from QAT and provide them as a first subset of this "ever-growing set" I mentioned.

I hope I manage to express the need a bit more clearly. 😊

Maybe this is a duplicate with what QAT intends to achieve in the end, but I'm not sure about it. This is why, during the community calls, we agreed we should start a discussion about it here. 😉

Starting on a high level: The purpose of QAT is to 1) transform generic QIR into a profile specific QIR (i.e. specific to a given set of capabilities - machine or simulator specific), and 2) validate that a QIR satisfy the requirements of a specific profile. Note that rather than taking about hardware specificity we are using a similar concept which is "profile" that may cover either a QPU, a simulator or a hybrid CPU-QPU setup.

Both of the steps are achieved using LLVM passes and therefore the majority of the codebase consists of pure LLVM passes. The passes for transformation are set up in the component setup function. As you will see, all custom written passes are nearly free of dependencies (if you disregard the logger and the configuration component). This means that they could without much effort be made into an opt pass if this was desired (see below). You will also see that QAT makes use of pre-existing LLVM passes to complete tasks such as constant folding, loop unrolling, dead code elimination etc.

The passes follow the standard for the new pass manager meaning that you will either have analysis passes or transformation passes - I think this is well aligned with what you are writing. If you compile and run QAT, you will note that each component (a collection of LLVM passes) are configurable from the command-line, meaning that the end-user can pick and choose as the like, and create a profile transformation in accordance to their need. And yes, hopefully, QAT will eventually contain a large set of passes for users and hardware providers to pick and choose from.

I think of all of the above is in line with your suggestions and the only thing needed would be some one writing the dynamic libraries. To give a concrete example, in order to create a opt version of the grouping pass, the code needed would be something along the lines of:

PassPluginLibraryInfo getGroupingPlugin() {
  return {LLVM_PLUGIN_API_VERSION, PluginName, LLVM_VERSION_STRING,
          [](PassBuilder &pass_builder) {
            auto logger = std::make_shared<CommentLogger>();

            pass_builder.registerAnalysisRegistrationCallback(
                [logger](ModuleAnalysisManager &mam) {
                  mam.registerPass([&] { return GroupingAnalysisPass({}, logger); });
                });


            pass_builder.registerPipelineParsingCallback(
                [&](StringRef name, ModulePassManager &mpm,
                    ArrayRef<PassBuilder::PipelineElement>) {
                  if (name.equals("group-quantum-instructions")) {
                    auto pass = GroupingPass({});
                    pass.setLogger(logger);
                    mpm.addPass(std::move(pass));
                    return true;
                  }

                  return false;
                });
          }};
}

extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
llvmGetPassPluginInfo() {
  return getGroupingPlugin();
}

which would make it loadable in opt. These kinds of dynamic plugins are not currently on our roadmap for QAT, however, it is possible to add opt support if needed. From your message, it seems that the dynamic code above would be the only thing need to have opt support, unless I missed something.

Could your proposal be summarised as adding opt support for the passes? Or did you have something additional in mind to the above?

Thanks again @troelsfr for this very detailed reply!

It helps me A LOT in better understanding the goals and ambitions of QAT. This is probably what we missed the most during the community calls.

I agree my initial proposal has lots to do with what you write. Once again, reaching this conclusion (or not) was the whole point of starting this conversation. 😁

we are using a similar concept which is "profile"

This is where I wonder the most.

It seems to me that "profiles" are monolithic.

I'm not sure whether QAT allows something like "I want to use JUST the atomic pass that" (or a combination of these passes), for instance:

  • Removes duplicate gates (three X gates in a row is really just one X gate)
  • Or the opposite: Duplicates gates in order to do Probabilistic Error Cancellation (MITIQ-style)
  • Merges redundant gates (two Rx gates in a row really are just one Rx gate with the sum of angles, or even no gate if the angles cancel out)
  • Replaces SWAP gates with three CX in a row
  • Replaces X gates with HZH gates
  • ...

if you disregard the logger and the configuration component

Talking about the Configuration component, is this related to what you wrote in the docs : "The downsides to opt is that we cannot pass a configuration to the individual passes" ?

Isn't cl::opt a way to do it?

they could without much effort be made into an opt pass if this was desired (see below)

Totally agreed.

Except when they rely on some configuration?

in order to create a opt version of the grouping pass, the code needed would be something along the lines of:

Indeed. I've been using something quite similar to make passes available to opt (though I also declared them for the legacy Pass Manager).

Could your proposal be summarised as adding opt support for the passes?

Beyond that, I'd say.

On an architectural standpoint and even in terms of repo organization, the idea was to provide each pass as an independent "package" (not only for opt, but also to include them as libraries in other LLVM/QIR projects).

And then to have documentation that describes each one of them, just like here.

I hope this all makes sense...

A small update to this proposal: Passes are getting separated into separate folders which is the preliminary work to have them as stand-alone/opt compatible entities in PR #137 .

A small update to this proposal: Passes are getting separated into separate folders which is the preliminary work to have them as stand-alone/opt compatible entities in PR #137 .

@troelsfr: Great! Thanks!