Skip to content
Draft
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
4 changes: 2 additions & 2 deletions docs/sphinx/using/extending/backend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@ Create a ``YAML`` configuration file for your target:
gen-target-backend: true
# Add preprocessor defines to compilation
preprocessor-defines: ["-D CUDAQ_QUANTUM_DEVICE"]
# Define the lowering pipeline
# Define the JIT lowering pipeline
# This will cover applying hardware-specific constraints since each provider may have different native gate sets, requiring custom mappings and decompositions. You may need assistance from the CUDA-Q team to set this up correctly.
platform-lowering-config: "classical-optimization-pipeline,globalize-array-values,func.func(state-prep),unitary-synthesis,canonicalize,apply-op-specialization,aggressive-inlining,classical-optimization-pipeline,lower-to-cfg,func.func(canonicalize,multicontrol-decomposition),decomposition{enable-patterns=U3ToRotations},symbol-dce,<provider_name>-gate-set-mapping"
jit-mid-level-pipeline: "lower-to-cfg,func.func(canonicalize,multicontrol-decomposition),decomposition{enable-patterns=U3ToRotations},symbol-dce,<provider_name>-gate-set-mapping"
# Tell the rest-qpu that we are generating QIR base profile.
# As of the time of this writing, qasm2, qir-base and qir-adaptive are supported.
codegen-emission: qir-base
Expand Down
29 changes: 29 additions & 0 deletions include/cudaq/Optimizer/CodeGen/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,35 @@ void registerToExecutionManagerCCPipeline();

void registerWireSetToProfileQIRPipeline();
void populateCCTypeConversions(mlir::LLVMTypeConverter *converter);
void addLowerToCCPipeline(mlir::OpPassManager &pm);

//===----------------------------------------------------------------------===//
// Final code generation: converting to a transport layer
//===----------------------------------------------------------------------===//

/// Pipeline builder to convert Quake to QIR at JIT compilation.
///
/// \p pm Pass manager to append passes to.
/// \p convertTo QIR triple to specify the QIR profile to convert to.
///
/// The QIR triple is a name indicating the selected profile (`qir`, `qir-full`,
/// `qir-base`, or `qir-adaptive`) followed by an optional `:` and QIR version
/// followed by an optional `:` and a list of `suboptions`.
void addJITPipelineConvertToQIR(mlir::PassManager &pm,
mlir::StringRef convertTo);

/// Pipeline builder to convert Quake to QIR at AOT compilation.
///
/// The driver always uses full QIR, but it can support other profiles if
/// necessary. Letting \p convertTo default means full QIR.
void addAOTPipelineConvertToQIR(mlir::PassManager &pm,
mlir::StringRef convertTo = {});

/// Pipeline builder to convert Quake to Open QASM 2.0
void addPipelineTranslateToOpenQASM(mlir::PassManager &pm);

/// Pipeline builder to convert Quake to IQM `Json`.
void addPipelineTranslateToIQMJson(mlir::PassManager &pm);

// declarative passes
#define GEN_PASS_DECL
Expand Down
47 changes: 0 additions & 47 deletions include/cudaq/Optimizer/CodeGen/Pipelines.h

This file was deleted.

3 changes: 3 additions & 0 deletions include/cudaq/Optimizer/InitAllPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ inline void registerCudaqPassesAndPipelines() {
opt::registerWireSetToProfileQIRPipeline();
opt::registerMappingPipeline();
opt::registerToCFGPipeline();

// JIT compiler pipelines
opt::registerJITPipelines();
}

inline void registerAllPasses() {
Expand Down
7 changes: 7 additions & 0 deletions include/cudaq/Optimizer/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,16 @@ void registerAggressiveInliningPipeline();

void registerUnrollingPipeline();
void registerClassicalOptimizationPipeline();
void createClassicalOptimizationPipeline(mlir::OpPassManager &pm);
void registerMappingPipeline();
void registerToCFGPipeline();

void createPreDeviceCodeLoaderPipeline(mlir::OpPassManager &pm,
bool autoGenRunStack);
void registerAOTPipelines();
void createTargetFinalizePipeline(mlir::OpPassManager &pm);
void registerJITPipelines();

std::unique_ptr<mlir::Pass> createDelayMeasurementsPass();
std::unique_ptr<mlir::Pass> createExpandMeasurementsPass();
std::unique_ptr<mlir::Pass> createLambdaLiftingPass();
Expand Down
11 changes: 6 additions & 5 deletions include/cudaq/Support/TargetConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@
#include <string>
#include <vector>

namespace cudaq {
namespace config {
namespace cudaq::config {
/// Flag to enable feature(s) of the unified NVIDIA target.
// Use bitset so that we can combine different options, e.g., multi-gpu with
// fp32/64.
Expand Down Expand Up @@ -98,7 +97,9 @@ struct BackendEndConfigEntry {
/// Enable/disable the library mode if provide.
std::optional<bool> LibraryMode;
/// IR lowering configuration (hardware REST QPU)
std::string PlatformLoweringConfig;
std::string JITHighLevelPipeline;
std::string JITMidLevelPipeline;
std::string JITLowLevelPipeline;
/// Exact cudaq-opt passes for pseudo-targets
std::string TargetPassPipeline;
/// Codegen emission configuration (hardware REST QPU)
Expand Down Expand Up @@ -172,5 +173,5 @@ class TargetConfig {
/// to the provided compile time (C++)/runtime (Python) target arguments.
std::string processRuntimeArgs(const TargetConfig &config,
const std::vector<std::string> &targetArgv);
} // namespace config
} // namespace cudaq

} // namespace cudaq::config
1 change: 0 additions & 1 deletion lib/Optimizer/CodeGen/ConvertToExecMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "cudaq/Optimizer/Builder/Intrinsics.h"
#include "cudaq/Optimizer/CodeGen/CudaqFunctionNames.h"
#include "cudaq/Optimizer/CodeGen/Passes.h"
#include "cudaq/Optimizer/CodeGen/Pipelines.h"
#include "cudaq/Optimizer/CodeGen/QuakeToExecMgr.h"
#include "cudaq/Optimizer/Dialect/CC/CCTypes.h"
#include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h"
Expand Down
34 changes: 20 additions & 14 deletions lib/Optimizer/CodeGen/ConvertToQIRAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
#include "cudaq/Optimizer/Builder/Runtime.h"
#include "cudaq/Optimizer/CodeGen/CodeGenDialect.h"
#include "cudaq/Optimizer/CodeGen/Passes.h"
#include "cudaq/Optimizer/CodeGen/Pipelines.h"
#include "cudaq/Optimizer/CodeGen/QIRAttributeNames.h"
#include "cudaq/Optimizer/CodeGen/QIRFunctionNames.h"
#include "cudaq/Optimizer/CodeGen/QIROpaqueStructTypes.h"
Expand All @@ -20,6 +19,7 @@
#include "cudaq/Optimizer/Dialect/CC/CCOps.h"
#include "cudaq/Optimizer/Dialect/Quake/QuakeDialect.h"
#include "cudaq/Optimizer/Dialect/Quake/QuakeOps.h"
#include "cudaq/Optimizer/Transforms/Passes.h" // for GlobalizeArrayValues
#include "nlohmann/json.hpp"
#include "llvm/Support/Debug.h"
#include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h"
Expand All @@ -29,6 +29,7 @@
#include "mlir/Pass/PassOptions.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
#include "mlir/Transforms/Passes.h"

#define DEBUG_TYPE "convert-to-qir-api"

Expand Down Expand Up @@ -2040,42 +2041,47 @@ struct QuakeToQIRAPIPass
if (apiField[0] == "full") {
if (opaquePtr)
processOperation<FullQIR</*opaquePtr=*/true>>(typeConverter);
processOperation<FullQIR</*opaquePtr=*/false>>(typeConverter);
else
processOperation<FullQIR</*opaquePtr=*/false>>(typeConverter);
} else if (apiField[0] == "base-profile") {
if (apiField.size() > 1 && apiField[1] == "0.2") {
if (opaquePtr)
processOperation<
BaseProfileQIR</*opaquePtr=*/true, QirVersion::version_0_2>>(
typeConverter);
processOperation<
BaseProfileQIR</*opaquePtr=*/false, QirVersion::version_0_2>>(
typeConverter);
else
processOperation<
BaseProfileQIR</*opaquePtr=*/false, QirVersion::version_0_2>>(
typeConverter);
} else {
if (opaquePtr)
processOperation<
BaseProfileQIR</*opaquePtr=*/true, QirVersion::version_0_1>>(
typeConverter);
processOperation<
BaseProfileQIR</*opaquePtr=*/false, QirVersion::version_0_1>>(
typeConverter);
else
processOperation<
BaseProfileQIR</*opaquePtr=*/false, QirVersion::version_0_1>>(
typeConverter);
}
} else if (apiField[0] == "adaptive-profile") {
if (apiField.size() > 1 && apiField[1] == "0.2") {
if (opaquePtr)
processOperation<
AdaptiveProfileQIR</*opaquePtr=*/true, QirVersion::version_0_2>>(
typeConverter);
processOperation<
AdaptiveProfileQIR</*opaquePtr=*/false, QirVersion::version_0_2>>(
typeConverter);
else
processOperation<
AdaptiveProfileQIR</*opaquePtr=*/false, QirVersion::version_0_2>>(
typeConverter);
} else {
if (opaquePtr)
processOperation<
AdaptiveProfileQIR</*opaquePtr=*/true, QirVersion::version_0_1>>(
typeConverter);
processOperation<
AdaptiveProfileQIR</*opaquePtr=*/false, QirVersion::version_0_1>>(
typeConverter);
else
processOperation<
AdaptiveProfileQIR</*opaquePtr=*/false, QirVersion::version_0_1>>(
typeConverter);
}
} else {
getOperation()->emitOpError("The currently supported APIs are: 'full', "
Expand Down
Loading
Loading