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

Add dep-analysis pass (a.k.a. features/qubit-mgmt) #2163

Merged
merged 116 commits into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
a447bd9
Add dependency analysis code
atgeller Jun 24, 2024
c465360
Formatting
atgeller Jun 24, 2024
0943b5a
Use lifetimes computed from dependency graph to map to physical qubits.
atgeller Jun 27, 2024
31a7d64
Use lifetimes to determine when it is safe to reuse qubits, and reord…
atgeller Jul 3, 2024
49edf9e
Insert into new block and whack old block after instead of erasing in…
atgeller Jul 3, 2024
7a31f75
Missed an erase
atgeller Jul 3, 2024
615ee75
Forgot to actually erase old block
atgeller Jul 3, 2024
7a752d9
Some cleanup and fixes
atgeller Jul 10, 2024
96fa396
Merge branch 'main' into dependency_analysis
atgeller Jul 10, 2024
3565142
Fix up scheduling to address bugs, includes two test cases for these …
atgeller Jul 11, 2024
fc5c485
Merge branch 'dependency_analysis' of github.com:atgeller/cuda-quantu…
atgeller Jul 11, 2024
0212dde
Add filecheck commands to tests
atgeller Jul 11, 2024
07050d7
Add assertions and validation functions, and tests for errors. Also i…
atgeller Jul 13, 2024
d959274
More assertions in place
atgeller Jul 15, 2024
2884c07
Add support for classical values
atgeller Jul 16, 2024
4b3136b
Merge branch 'main' into dependency_analysis
atgeller Jul 16, 2024
a9d4941
Fixes several bugs (mostly related to classical values) and adds test…
atgeller Jul 19, 2024
0f5f20a
Merge branch 'dependency_analysis' of github.com:atgeller/cuda-quantu…
atgeller Jul 19, 2024
68a056e
Some cleanup, remove unused functions
atgeller Jul 19, 2024
9a9f826
Remove unnecessary TODO
atgeller Jul 19, 2024
9d5d12d
Improve error messages, add missing test files
atgeller Jul 22, 2024
6526b5e
Improve errors a bit
atgeller Jul 24, 2024
24843c1
Fix performance issue with finding nodes at a given cycle
atgeller Jul 24, 2024
a61ac20
Ensure that classical operations after quantum values are generated
atgeller Jul 24, 2024
0d7160a
Preliminary addition of qubit management passes to JIT pipeline
atgeller Jul 24, 2024
622b8b2
Update pass descriptions
atgeller Jul 24, 2024
f4e93bc
Add qubit management pipeline
atgeller Jul 24, 2024
ffc4c4c
Merge remote-tracking branch 'upstream/main' into dependency_analysis
atgeller Jul 24, 2024
32ecc13
Add to yaml configs, add options to disable qubit management and to d…
atgeller Jul 24, 2024
02b45c9
Add targettests for qubit management
atgeller Jul 24, 2024
ffad80d
Fix bug counting number of virtual qubits
atgeller Jul 25, 2024
da4f915
Update how qubit-management is added to qir-base pipeline
atgeller Jul 29, 2024
6c0ff58
Forgot to remove debug code
atgeller Jul 30, 2024
3de2006
Run qubit management before mapping
atgeller Aug 2, 2024
6ca7756
Add cudaq::draw support for hardware targets
bmhowe23 Aug 2, 2024
c61600e
Impose ordering on assigning physical qubits
atgeller Aug 2, 2024
ff3ee15
Merge remote-tracking branch 'atgellar/dependency_analysis' into feat…
bmhowe23 Aug 3, 2024
c2ad4b8
Merge branch 'pr-add-draw-for-hw-target' into features/qubit-mgmt
bmhowe23 Aug 3, 2024
113d80d
Reformat the descriptions of the passes to conform to 80 columns.
schweitzpgi Aug 5, 2024
5384690
Update the pipeline constructions so they are more linear with the
schweitzpgi Aug 5, 2024
0296628
Move the verification of QIR profile out to its own file. Update the
schweitzpgi Aug 5, 2024
a5e061e
Reformat comments. Use modern spelling of `dyn_cast_or_null`.
schweitzpgi Aug 5, 2024
4d3635a
Start adding new passes.
schweitzpgi Aug 5, 2024
39c6cb5
Fix typo.
schweitzpgi Aug 5, 2024
bc909a1
Rename file to conform with suite.
schweitzpgi Aug 5, 2024
523c556
Write a new test.
schweitzpgi Aug 6, 2024
f4d939e
Merge pull request #2061 from schweitzpgi/ch-wireset.codegen
schweitzpgi Aug 7, 2024
454b7ef
Update WireSetsToProfileQIR pass: remove WireSets and fix LLVM loweri…
bmhowe23 Aug 9, 2024
a3e4a78
Merge branch 'main' into features/qubit-mgmt
bmhowe23 Aug 9, 2024
515d5b1
Merge pull request #2072 from bmhowe23/pr-merge-main-to-feature
schweitzpgi Aug 9, 2024
00a324e
Merge branch 'main' into pr-merge-main-into-qubit-mgmt
bmhowe23 Aug 13, 2024
e97f14b
Replace base profile DependencyAnalysis with WIP adaptive profile Dep…
atgeller Aug 15, 2024
6085ed2
Updates to control flow support in dependency analysis (#2114)
atgeller Aug 21, 2024
df46477
Merge branch 'main' into pr-merge-qubit-mgmt-to-main
bmhowe23 Aug 21, 2024
324fce1
Follow-up to #2114 - fix compilation issues and restore quantinuum.ym…
bmhowe23 Aug 21, 2024
43a6c6c
Update wireset_codegen.qke check data (#2125)
bmhowe23 Aug 21, 2024
5237673
Add destructors and fix up tests (#2124)
atgeller Aug 22, 2024
2953619
Merge branch 'main' into features/qubit-mgmt
schweitzpgi Aug 26, 2024
d2c30b6
Add `opt-test` target (#2122)
bmhowe23 Aug 26, 2024
d33ddb2
Final code changes and tests for Qubit Management (#2155)
atgeller Aug 27, 2024
aed5e86
Merge branch 'main' into features/qubit-mgmt
bmhowe23 Aug 27, 2024
a2c5088
Remove XFAIL from some tests after merge
bmhowe23 Aug 27, 2024
0483eff
Spelling
bmhowe23 Aug 27, 2024
82671ba
Remove DISABLE_QUBIT_MANAGEMENT env var
bmhowe23 Aug 27, 2024
82f31f0
Test commit: documentation for QID types
atgeller Aug 27, 2024
ad8960e
Add documentation, misc cleanup
atgeller Aug 27, 2024
c4e5b58
More code cleanup
atgeller Aug 28, 2024
ecc8e64
Add/adjust todos and tests for known bugs
atgeller Aug 28, 2024
93bcd8e
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Aug 28, 2024
fa7d0b3
Address feedback on types, make lifetimes not be pointers
atgeller Aug 28, 2024
37ce98c
Merge branch 'pr-qubit-mgmt' of github.com:bmhowe23/cuda-quantum into…
atgeller Aug 28, 2024
7f5d081
Rename print to dump, remove unnecessary friends
atgeller Aug 28, 2024
5d304b3
Small fixes
atgeller Aug 28, 2024
d5c2a9d
Update WireSetsToProfileQIR, IQM, NVQIR, and runtime
bmhowe23 Aug 28, 2024
a98465a
clang-format after merge
bmhowe23 Aug 28, 2024
a7b8e08
More documentation
atgeller Aug 28, 2024
a7fea7c
Merge branch 'pr-qubit-mgmt' of github.com:bmhowe23/cuda-quantum into…
atgeller Aug 28, 2024
3089c1a
Don't lift ifs, test case should now pass
atgeller Aug 28, 2024
b103ce6
A bit more cleanup
atgeller Aug 29, 2024
6265ce0
Add note about function arguments
atgeller Aug 29, 2024
7ee9296
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Aug 29, 2024
4026f02
Update include/cudaq/Optimizer/Transforms/Passes.td
schweitzpgi Aug 29, 2024
eebbb25
Update lib/Optimizer/Transforms/DependencyAnalysis.cpp
schweitzpgi Aug 29, 2024
3879872
Various documentation changes
atgeller Aug 29, 2024
f1b4ebd
Add failing test case
atgeller Aug 29, 2024
4478db9
Bad filecheck commands
atgeller Aug 29, 2024
198bb09
Fix a few bugs related to BlockArgument indices
atgeller Aug 29, 2024
c2cf4a9
Fix some minor bugs related to lifting
atgeller Aug 29, 2024
89f94c4
Add TODO for how to get pass statistics
atgeller Aug 29, 2024
95ed470
Fix naming conflict
atgeller Aug 29, 2024
7bfc801
Merge quake tests, rename them
atgeller Aug 30, 2024
8773e7c
Stray character
atgeller Aug 30, 2024
0f180e4
Add todo
atgeller Aug 30, 2024
6e9dc27
Add metadata clean up
atgeller Aug 30, 2024
a8a173a
Bad test file added by mistake
atgeller Aug 30, 2024
f233628
Check wasn't properly catching NullWireOps
atgeller Aug 30, 2024
edc6654
Rename test
atgeller Aug 30, 2024
2235ec5
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Aug 30, 2024
3078533
Update tests
atgeller Aug 30, 2024
5ef2e70
Merge branch 'pr-qubit-mgmt' of github.com:bmhowe23/cuda-quantum into…
atgeller Aug 30, 2024
42c37dc
Remove name from LifetimeAnalysis, use constant instead
atgeller Aug 30, 2024
419f8bd
Add comments about linearity assumptions
atgeller Aug 30, 2024
b9d16aa
Ensure DependencyEdge metadata is updated correctly
atgeller Aug 30, 2024
bd01e60
Added changes to wrong branch
atgeller Aug 30, 2024
c31d959
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 3, 2024
f3abaa9
Address PR comment
bmhowe23 Sep 3, 2024
7d4f9c0
Ensure qids are unique when splitting during lowering, update tests
atgeller Aug 30, 2024
580fcb4
Update QIDs within inner blocks too
atgeller Aug 31, 2024
4e760a8
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 9, 2024
4998830
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 10, 2024
5938ce4
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 11, 2024
d48d5cf
Disable test due to #1712
bmhowe23 Sep 11, 2024
c237067
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 11, 2024
4043d9f
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 12, 2024
8ff06f8
Revert "Disable test due to #1712"
bmhowe23 Sep 12, 2024
1dec538
Merge branch 'main' into pr-qubit-mgmt
bmhowe23 Sep 13, 2024
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
47 changes: 47 additions & 0 deletions include/cudaq/Optimizer/CallGraphFix.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/****************************************************************-*- C++ -*-****
* Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. *
* All rights reserved. *
* *
* This source code and the accompanying materials are made available under *
* the terms of the Apache License 2.0 which accompanies this distribution. *
******************************************************************************/

#pragma once

#include "mlir/Analysis/CallGraph.h"

namespace llvm {
// FIXME: `GraphTraits` specialization for `const mlir::CallGraphNode *` in
bmhowe23 marked this conversation as resolved.
Show resolved Hide resolved
// "mlir/Analysis/CallGraph.h" has a bug.
// In particular, `GraphTraits<const mlir::CallGraphNode *>` typedef'ed `NodeRef
// -> mlir::CallGraphNode *`, (without `const`), causing problems when using
// `mlir::CallGraphNode` with graph iterator (e.g., `llvm::df_iterator`). The
// entry node getter has the signature `NodeRef getEntryNode(NodeRef node)`,
// i.e., `mlir::CallGraphNode * getEntryNode(mlir::CallGraphNode * node)`; but a
// graph iterator for `const mlir::CallGraphNode *` will pass a `const
// mlir::CallGraphNode *` to that `getEntryNode` function => compile error.
// Here, we define a non-const overload, which hasn't been defined, to work
// around that issue.
//
// Note: this isn't an issue for the whole `mlir::CallGraph` graph, i.e.,
// `GraphTraits<const mlir::CallGraph *>`. `getEntryNode` is defined as
// `getExternalCallerNode`, which is a const method of `mlir::CallGraph`.

template <>
struct GraphTraits<mlir::CallGraphNode *> {
using NodeRef = mlir::CallGraphNode *;
static NodeRef getEntryNode(NodeRef node) { return node; }

static NodeRef unwrap(const mlir::CallGraphNode::Edge &edge) {
return edge.getTarget();
}
using ChildIteratorType =
mapped_iterator<mlir::CallGraphNode::iterator, decltype(&unwrap)>;
static ChildIteratorType child_begin(NodeRef node) {
return {node->begin(), &unwrap};
}
static ChildIteratorType child_end(NodeRef node) {
return {node->end(), &unwrap};
}
};
} // namespace llvm
10 changes: 7 additions & 3 deletions include/cudaq/Optimizer/CodeGen/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,19 @@ class LLVMStructType;
} // namespace mlir

namespace cudaq::opt {
void registerConvertToQIRPass();

/// Convert (generic) QIR to the profile-specific QIR for a specific target.
/// @param pm Pass Manager to add QIR passes to
/// @param convertTo Expected to be `qir-base` or `qir-adaptive` (comes from the
/// cudaq-translate command line `--convert-to` parameter)
void addQIRProfilePipeline(mlir::OpPassManager &pm, llvm::StringRef convertTo);
/// @param performPrep Whether or not to perform the initial prep pass (normally
/// true, but false for the WireSet QIR path)
void addQIRProfilePipeline(mlir::OpPassManager &pm, llvm::StringRef convertTo,
bool performPrep = true);

void addLowerToCCPipeline(mlir::OpPassManager &pm);
void addWiresetToProfileQIRPipeline(mlir::OpPassManager &pm,
llvm::StringRef profile);
bmhowe23 marked this conversation as resolved.
Show resolved Hide resolved

/// @brief Verify that all `CallOp` targets are QIR- or NVQIR-defined functions
/// or in the provided allowed list.
Expand All @@ -45,7 +49,6 @@ createVerifyNVQIRCallOpsPass(const std::vector<llvm::StringRef> &allowedFuncs);
// Use the addQIRProfilePipeline() for the following passes.
std::unique_ptr<mlir::Pass>
createQIRToQIRProfilePass(llvm::StringRef convertTo);
std::unique_ptr<mlir::Pass> verifyQIRProfilePass(llvm::StringRef convertTo);
std::unique_ptr<mlir::Pass> createQIRProfilePreparationPass();
std::unique_ptr<mlir::Pass>
createConvertToQIRFuncPass(llvm::StringRef convertTo);
Expand All @@ -59,6 +62,7 @@ void registerCodeGenDialect(mlir::DialectRegistry &registry);
mlir::LLVM::LLVMStructType lambdaAsPairOfPointers(mlir::MLIRContext *context);

void registerToExecutionManagerCCPipeline();
void registerWireSetToProfileQIRPipeline();
void populateCCTypeConversions(mlir::LLVMTypeConverter *converter);

// declarative passes
Expand Down
73 changes: 53 additions & 20 deletions include/cudaq/Optimizer/CodeGen/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ def QuakeToCC : Pass<"quake-to-cc", "mlir::ModuleOp"> {
execution manager.
}];

let dependentDialects = [
"cudaq::cc::CCDialect", "mlir::LLVM::LLVMDialect"
];
let dependentDialects = ["cudaq::cc::CCDialect", "mlir::LLVM::LLVMDialect"];
}

def QuakeToCCPrep : Pass<"quake-to-cc-prep", "mlir::ModuleOp"> {
Expand Down Expand Up @@ -89,21 +87,6 @@ def QIRToQIRProfilePrep : Pass<"qir-profile-prep", "mlir::ModuleOp"> {
let constructor = "cudaq::opt::createQIRProfilePreparationPass()";
}

def VerifyQIRProfile : Pass<"verify-qir-profile", "mlir::LLVM::LLVMFuncOp"> {
let summary = "Verify that the output conforms to the specific profile";
let description = [{
This pass scans over functions in the LLVM-IR dialect to make sure they
conform to the QIR specific profile.
}];

let options = [
Option<"convertTo", "convert-to", "std::string", "\"qir-base\"",
"Which QIR profile to convert to (default is 'qir-base')">
];

let constructor = "cudaq::opt::verifyQIRProfilePass(\"qir-base\")";
}

def QIRToQIRProfileFunc : Pass<"quake-to-qir-func",
"mlir::LLVM::LLVMFuncOp"> {
let summary = "Analyze kernels and add attributes and record calls.";
Expand All @@ -118,7 +101,7 @@ def QIRToQIRProfileFunc : Pass<"quake-to-qir-func",
}];

let options = [
Option<"convertTo", "convert-to", "std::string", "\"qir-base\"",
Option<"convertTo", "convert-to", "std::string", /*default=*/"\"qir-base\"",
"Which QIR profile to convert to (default is 'qir-base')">
];

Expand All @@ -127,8 +110,10 @@ def QIRToQIRProfileFunc : Pass<"quake-to-qir-func",

def QIRToQIRProfile : Pass<"convert-to-qir-profile"> {
let summary =
"After lowering a Quake kernel to QIR, lower further to the specific QIR Profile.";
"Lower full QIR further to the specific QIR Profile.";
let description = [{
This is run after lowering a Quake kernel to full QIR.

This is a subpass of the pipeline to convert to the specific QIR Profile.

This pass lowers various QIR DAGs to the specific QIR Profile. See
Expand Down Expand Up @@ -179,4 +164,52 @@ def VerifyNVQIRCallOps :
let constructor = "cudaq::opt::createVerifyNVQIRCallOpsPass({})";
}

def VerifyQIRProfile : Pass<"verify-qir-profile", "mlir::LLVM::LLVMFuncOp"> {
let summary = "Verify that the output conforms to the specific profile";
let description = [{
This pass scans over functions in the LLVM-IR dialect to make sure they
conform to the QIR specific profile.
}];

let options = [
Option<"convertTo", "convert-to", "std::string", "\"qir-base\"",
"Which QIR profile to convert to (default is 'qir-base')">
];
}

def WireSetToProfileQIR : Pass<"wireset-to-profile-qir", "mlir::func::FuncOp"> {
let summary = "Convert quake using wire sets to a profile of QIR";
let description = [{
This pass takes quake in "value semantics" form and after it has been
converted to use wire sets (qubit management, mapping, etc.) and converts
the code to CC dialect with QIR calls, etc.
}];

let dependentDialects = ["cudaq::cc::CCDialect", "mlir::LLVM::LLVMDialect"];
let options = [
Option<"convertTo", "convert-to", "std::string", /*default=*/"\"qir-base\"",
"Select the profile to convert wire sets to.">
];
}

def WireSetToProfileQIRPost :
Pass<"wireset-to-profile-qir-post", "mlir::ModuleOp"> {
let summary = "Post processing for lowering wire sets to a profile of QIR";
let description = [{
This pass should be run immediately after wireset-to-profile-qir.
}];

let dependentDialects = ["cudaq::cc::CCDialect", "mlir::func::FuncDialect"];
}

def WireSetToProfileQIRPrep :
Pass<"wireset-to-profile-qir-prep", "mlir::ModuleOp"> {
let summary = "Prepare for lowering wire sets to a profile of QIR";
let description = [{
This pass should be run immediately before wireset-to-profile-qir.
}];

let dependentDialects = ["cudaq::cc::CCDialect", "mlir::func::FuncDialect"];
}

#endif // CUDAQ_OPT_OPTIMIZER_CODEGEN_PASSES
27 changes: 27 additions & 0 deletions include/cudaq/Optimizer/CodeGen/QIRAttributeNames.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/****************************************************************-*- C++ -*-****
* Copyright (c) 2022 - 2024 NVIDIA Corporation & Affiliates. *
* All rights reserved. *
* *
* This source code and the accompanying materials are made available under *
* the terms of the Apache License 2.0 which accompanies this distribution. *
******************************************************************************/

#pragma once

/// This file provides some common QIR attribute names for use in code gen.

namespace cudaq::opt {

static constexpr const char QIRRegisterNameAttr[] = "registerName";
schweitzpgi marked this conversation as resolved.
Show resolved Hide resolved
static constexpr const char QIREntryPointAttrName[] = "entry_point";
static constexpr const char QIRProfilesAttrName[] = "qir_profiles";
static constexpr const char QIROutputLabelingSchemaAttrName[] =
"output_labeling_schema";
static constexpr const char QIROutputNamesAttrName[] = "output_names";
static constexpr const char QIRRequiredQubitsAttrName[] = "requiredQubits";
static constexpr const char QIRRequiredResultsAttrName[] = "requiredResults";
static constexpr const char QIRIrreversibleFlagName[] = "irreversible";

static constexpr const char StartingOffsetAttrName[] = "StartingOffset";

} // namespace cudaq::opt
11 changes: 11 additions & 0 deletions include/cudaq/Optimizer/CodeGen/QIRFunctionNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,21 @@ static constexpr const char QIRArrayConcatArray[] =
static constexpr const char QIRArrayCreateArray[] =
"__quantum__rt__array_create_1d";

/// Dynamic qubit management helper functions. These are currently only used by
/// the NVQIR simulator.
static constexpr const char QIRisDynamicQubitManagement[] =
"__quantum__rt__is_dynamic_qubit_management";
static constexpr const char QIRsetDynamicQubitManagement[] =
"__quantum__rt__set_dynamic_qubit_management";

/// QIR Base/Adaptive Profile record output function names
static constexpr const char QIRRecordOutput[] =
"__quantum__rt__result_record_output";

/// Custom NVQIR method to cleanup result maps in between consecutive programs.
static constexpr const char QIRClearResultMaps[] =
"__quantum__rt__clear_result_maps";

inline mlir::Type getQuantumTypeByName(mlir::StringRef type,
mlir::MLIRContext *context) {
return mlir::LLVM::LLVMStructType::getOpaque(type, context);
Expand Down
7 changes: 7 additions & 0 deletions include/cudaq/Optimizer/Dialect/Quake/QuakeOps.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ void genericOpPrinter(mlir::OpAsmPrinter &_odsPrinter, mlir::Operation *op,
// Utility functions to test the form of an operation.
//===----------------------------------------------------------------------===//

// Is \p op in the Quake dialect?
inline bool isQuakeOperation(mlir::Operation *op) {
if (auto *dialect = op->getDialect())
return dialect->getNamespace().equals("quake");
return false;
}

namespace quake {
/// Returns true if and only if any quantum operand has type `!quake.ref` or
/// `!quake.veq`.
Expand Down
46 changes: 45 additions & 1 deletion include/cudaq/Optimizer/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ def DelayMeasurements : Pass<"delay-measurements", "mlir::func::FuncOp"> {
"Move measurements as late as possible";

let description = [{
Move measurements as late as possible. This is useful for a Base Profile QIR program.
Move measurements as late as possible. This is useful for a Base Profile
QIR program.
}];

let constructor = "cudaq::opt::createDelayMeasurementsPass()";
Expand Down Expand Up @@ -214,6 +215,49 @@ def DecompositionPass: Pass<"decomposition", "mlir::ModuleOp"> {
];
}

def DependencyAnalysis : Pass<"dep-analysis", "mlir::ModuleOp"> {
let summary = "Maps qubits and reorders operations based on dependency graph.";
let description = [{
A dependency graph is a Directed Acyclic Graph (DAG) where each node
represents an operation, and each edge represents a "depends on" relation
between that operation and another operation. For example, in the following
snippet the `x` operation depends on the `h` operation because it is applied
to the same qubit (`q`), so the `h` operation must happen before the `x`
operation:
```c++
cudaq::qubit q;
x(q);
h(q);
```

Once a dependency graph is created, it is then scheduled, assigning each
operation a virtual cycle. Operations that don't depend on each other may
be scheduled at the same cycle. However, an operation that depends on a
second operation must be scheduled after the second operation. The
scheduling algorithm tries to pack operations as densely as possible,
minimizing the number of cycles between operations.

From this dependency graph, we can calculate the lifetime of a qubit: from
the cycle in which it is first used through the cycle in which it is last
used. If two virtual qubits have non-overlapping lifetimes, they can be
assigned to the same physical qubit, as every virtual qubit is assumed to be
fully reset before release. Failure to fully reset virtual qubits before
release is undefinied behavior, and will likely lead to incorrect output
when running DependencyAnalysis.
bmhowe23 marked this conversation as resolved.
Show resolved Hide resolved
}];

let dependentDialects = ["quake::QuakeDialect"];

let statistics = [
Statistic<"numVirtualQubits", "num-virtual-qubits",
"Number of virtual qubits used">,
Statistic<"numPhysicalQubits", "num-physical-qubits",
"Number of phyiscal qubits used">,
Statistic<"numCycles", "num-cycles",
"Length of kernel in cycles">,
];
}

def EraseNopCalls : Pass<"erase-nop-calls", "mlir::func::FuncOp"> {
let summary = "Erase calls to any builtin intrinsics that are NOPs.";
let description = [{
Expand Down
4 changes: 4 additions & 0 deletions include/cudaq/Support/TargetConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ enum TargetFeatureFlag : unsigned {
flagsFP64 = 0x0002,
flagsMgpu = 0x0004,
flagsMqpu = 0x0008,
flagsDepAnalysis = 0x0010,
flagsQPP = 0x0020,
schweitzpgi marked this conversation as resolved.
Show resolved Hide resolved
};

/// @brief Configuration argument type annotation
Expand Down Expand Up @@ -69,6 +71,8 @@ struct BackendEndConfigEntry {
std::optional<bool> LibraryMode;
/// IR lowering configuration (hardware REST QPU)
std::string PlatformLoweringConfig;
/// Exact cudaq-opt passes for pseudo-targets
std::string TargetPassPipeline;
/// Codegen emission configuration (hardware REST QPU)
std::string CodegenEmission;
/// Post code generation IR passes configuration (hardware REST QPU)
Expand Down
2 changes: 2 additions & 0 deletions lib/Optimizer/CodeGen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ add_cudaq_library(OptCodeGen
TranslateToIQMJson.cpp
TranslateToOpenQASM.cpp
VerifyNVQIRCalls.cpp
VerifyQIRProfile.cpp
WireSetsToProfileQIR.cpp

DEPENDS
CCDialect
Expand Down
2 changes: 1 addition & 1 deletion lib/Optimizer/CodeGen/ConvertToQIR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class ConvertToQIR : public cudaq::opt::impl::ConvertToQIRBase<ConvertToQIR> {
/// Measurement counter for unnamed measurements. Resets every module.
unsigned measureCounter = 0;

// This is an ad hox transformation to convert constant array values into a
// This is an ad hoc transformation to convert constant array values into a
// buffer of constants.
LogicalResult eraseConstantArrayOps() {
bool ok = true;
Expand Down
Loading
Loading