Skip to content

New launch kernel for python #2706

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

Merged
merged 141 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
141 commits
Select commit Hold shift + click to select a range
ac01dd1
DCO Remediation Commit for Ben Howe <bhowe@nvidia.com>
bmhowe23 Oct 11, 2024
21a87c1
State pointer synthesis for quantum hardware
annagrin Sep 17, 2024
3fc56de
Merge with main
annagrin Oct 17, 2024
7969a75
Merge with main
annagrin Oct 17, 2024
755d0d1
Fix test failure on anyon platform
annagrin Oct 17, 2024
dc5e77e
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Oct 17, 2024
382bc99
Make StateInitialization a funcOp pass
annagrin Oct 17, 2024
d3a05d4
Fix issues and tests for the rest of quantum architectures
annagrin Oct 18, 2024
ac151f2
Merge with main
annagrin Oct 18, 2024
51ef054
Fix failing quantinuum state prep tests
annagrin Oct 18, 2024
0cdf3e9
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Oct 18, 2024
5307aa4
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Oct 21, 2024
a7f5387
Address CR comments
annagrin Oct 21, 2024
eb8db13
Merge with main
annagrin Oct 21, 2024
9f0937f
Format
annagrin Oct 21, 2024
2f3a623
Fix failing test
annagrin Oct 22, 2024
b381350
Format
annagrin Oct 22, 2024
dc87ca4
Format
annagrin Oct 22, 2024
e4c7735
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Oct 22, 2024
53a34c9
Replaced getState intrinsic by cc.get_state op
annagrin Oct 22, 2024
30777f3
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Oct 22, 2024
fe6d409
Remove print
annagrin Oct 22, 2024
48704e3
Remove getCudaqState references
annagrin Oct 22, 2024
137f621
Minor updates
annagrin Oct 22, 2024
ad7c6bc
Fix failing quake test
annagrin Oct 23, 2024
83683f7
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Nov 4, 2024
78c0a44
Add a few state-related cc ops
annagrin Nov 5, 2024
6682c39
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Nov 5, 2024
102f819
Fix test_argument_conversion
annagrin Nov 5, 2024
6b2c015
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Nov 5, 2024
5ea1d97
Add printing in failing tests
annagrin Nov 5, 2024
074c60f
Add printing in failing tests
annagrin Nov 5, 2024
310f6ca
Fix failing tests
annagrin Nov 12, 2024
f0176ae
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Nov 12, 2024
d17fa6d
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Nov 12, 2024
3425182
Merge with state-ops
annagrin Nov 12, 2024
6fdccba
Add description for new algorithm for state syntesis
annagrin Nov 12, 2024
fc5e154
Merge with main
annagrin Jan 9, 2025
1dfa805
Fix tests
annagrin Jan 9, 2025
b67fc88
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Jan 9, 2025
9563371
Make intermediate IR legal by separating allocs
annagrin Jan 21, 2025
f32b066
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Jan 21, 2025
008e8c1
DCO Remediation Commit for Anna Gringauze <agringauze@nvidia.com>
annagrin Jan 21, 2025
84a4369
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Jan 22, 2025
1c0a4b3
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 11, 2025
f8e35eb
Address some PR comments
annagrin Feb 12, 2025
e79ad6a
Address more CR comments
annagrin Feb 12, 2025
88cd5d5
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 12, 2025
c0d9ae9
Cleanup
annagrin Feb 13, 2025
1ecd8cc
Address CR comments
annagrin Feb 13, 2025
0238a66
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 14, 2025
de387fc
Address more CR comments
annagrin Feb 14, 2025
a5150a5
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 14, 2025
7cf306a
Address more CR comments
annagrin Feb 18, 2025
16de803
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 18, 2025
1402471
Store new functions in subst module and update synthesis
annagrin Feb 20, 2025
816fdca
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 20, 2025
9a528dd
Make argument synthesis transitive
annagrin Feb 20, 2025
af2fd79
Update callers of synthesis
annagrin Feb 20, 2025
a25d468
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Feb 20, 2025
4d6f7ee
Use PointerOf in quake defs
annagrin Feb 20, 2025
e7d95d5
Addressed more CR comments
annagrin Feb 20, 2025
c4d600f
Recursive with caching
annagrin Feb 21, 2025
e58f577
StateAggregatorWithArgumentConverter
annagrin Feb 21, 2025
6c0dd7d
Make ArgumentConverter handle the state call tree
annagrin Feb 25, 2025
472ff60
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into ar…
annagrin Mar 3, 2025
5ef4c3d
Make argument converter handle kernels created from states
annagrin Mar 3, 2025
ab28edb
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 3, 2025
5e43057
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into ar…
annagrin Mar 3, 2025
36d9425
Merge branch 'argument-converter-all-functions' of https://github.com…
annagrin Mar 3, 2025
7c76533
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 4, 2025
2026cb3
Temp
annagrin Mar 6, 2025
9f70371
Temp
annagrin Mar 6, 2025
9a84fd1
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 6, 2025
7977a2e
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 6, 2025
43b5f85
Temp
annagrin Mar 6, 2025
b0e1c1b
Temp
annagrin Mar 7, 2025
a3cfd75
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 10, 2025
efdbbcc
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 10, 2025
6fefc27
Fix null alloc size and add tests
annagrin Mar 10, 2025
dcf565e
Fix const prop complex and numQubits bugs
annagrin Mar 11, 2025
53b7f5a
Add tests
annagrin Mar 12, 2025
ba5c77e
Format
annagrin Mar 12, 2025
e003e9c
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 12, 2025
3e5ee3b
Fix state copy in python
annagrin Mar 12, 2025
fb5ad4b
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 12, 2025
8590dfa
Remove temp files
annagrin Mar 12, 2025
79e8fdb
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 12, 2025
7e39116
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 12, 2025
55e25dd
Keep storing ops when generating numSubits func
annagrin Mar 12, 2025
745fc5d
Cleanup
annagrin Mar 12, 2025
4322ee4
Merge with main
annagrin Mar 12, 2025
b8c8c8a
Cleanup
annagrin Mar 12, 2025
98c19af
Merge with main
annagrin Mar 14, 2025
edf0224
Cleanup
annagrin Mar 14, 2025
6b5161a
Fix failing test
annagrin Mar 14, 2025
054f4b7
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 14, 2025
4df4390
Fix failing doc build
annagrin Mar 14, 2025
95bf223
Merge with quantum-state-synthesis
annagrin Mar 14, 2025
7a2e0c4
Allow old launch kernel for tests
annagrin Mar 15, 2025
dff43a0
Cleanup
annagrin Mar 15, 2025
91af463
Cleanup
annagrin Mar 15, 2025
a5d63c5
Address CR comments
annagrin Mar 18, 2025
eba1c1d
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into qu…
annagrin Mar 18, 2025
4a12db0
Address more CR comments and add a test
annagrin Mar 18, 2025
cc1faea
Address more CR comments
annagrin Mar 18, 2025
37b364d
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 18, 2025
2dfca46
Merge branch 'quantum-device-state' of https://github.com/annagrin/cu…
annagrin Mar 18, 2025
303bc04
Address more python tests
annagrin Mar 18, 2025
395acbe
Merge with main
annagrin Mar 20, 2025
175a70d
Fix links
annagrin Mar 20, 2025
e1449de
Fix links
annagrin Mar 20, 2025
c5c9a68
Fix links and tests
annagrin Mar 20, 2025
0ce5d31
Merge with main
annagrin Mar 20, 2025
9a5f042
Merge with origin/quantum-device-state
annagrin Mar 20, 2025
7621bc2
Merge with main
annagrin Mar 20, 2025
f554259
Fix test on ionq
annagrin Mar 20, 2025
f55e79a
Merge with main
annagrin Mar 24, 2025
56fa126
Undo unrelated changes
annagrin Mar 24, 2025
1aabbd4
Undo unrelated changes
annagrin Mar 24, 2025
1d27fea
Undo unrelated changes
annagrin Mar 24, 2025
6d67d5e
Undo unrelated changes
annagrin Mar 24, 2025
64217e5
Remove unneded unique pointer
annagrin Mar 24, 2025
76d11aa
Fix failing Ionq test
annagrin Mar 24, 2025
8687159
Fix failing Ionq and OQC tests
annagrin Mar 25, 2025
dcddd9f
Fix failing Ionq and OQC tests
annagrin Mar 25, 2025
6d26d12
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Mar 26, 2025
d9a1629
Remove trotter tests for quantum devices
annagrin Mar 26, 2025
fe40668
Merge branch 'main' into state-synthesis-python
annagrin Mar 31, 2025
f575d54
Merge branch 'main' into state-synthesis-python
annagrin Apr 1, 2025
5a506e8
Address CR comments
annagrin Apr 2, 2025
f99e3c4
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Apr 2, 2025
e3f45f5
Merge branch 'state-synthesis-python' of https://github.com/annagrin/…
annagrin Apr 2, 2025
e2784a2
Address CR comments
annagrin Apr 2, 2025
1171b34
Address CR comments
annagrin Apr 2, 2025
30469ff
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Apr 2, 2025
5a47157
Remote unrelated changes
annagrin Apr 3, 2025
2dd1ec6
fix failing tests
annagrin Apr 3, 2025
1cf54d6
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into st…
annagrin Apr 3, 2025
4bc229e
DCO Remediation Commit for Anna Gringauze <agringauze@nvidia.com>
annagrin Apr 3, 2025
8ace3be
Remove debugging code
annagrin Apr 3, 2025
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
43 changes: 37 additions & 6 deletions python/runtime/cudaq/algorithms/py_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ class PyRemoteSimulationState : public RemoteSimulationState {
std::size_t size, std::size_t returnOffset)
: argsData(argsDataToOwn), kernelMod(args.mod) {
this->kernelName = in_kernelName;
this->args = argsData->getArgs();
}

void execute() const override {
Expand All @@ -98,11 +99,6 @@ class PyRemoteSimulationState : public RemoteSimulationState {
}
}

std::optional<std::pair<std::string, std::vector<void *>>>
getKernelInfo() const override {
return std::make_pair(kernelName, argsData->getArgs());
}

std::complex<double> overlap(const cudaq::SimulationState &other) override {
const auto &otherState =
dynamic_cast<const PyRemoteSimulationState &>(other);
Expand All @@ -121,7 +117,7 @@ class PyRemoteSimulationState : public RemoteSimulationState {
return context.overlapResult.value();
}

~PyRemoteSimulationState() { delete argsData; }
virtual ~PyRemoteSimulationState() override { delete argsData; }
};

/// @brief Run `cudaq::get_state` for remote execution targets on the provided
Expand All @@ -140,6 +136,39 @@ state pyGetStateRemote(py::object kernel, py::args args) {
size, returnOffset));
}

/// @brief Python implementation of the `QPUState`.
// Note: Python kernel arguments are wrapped hence need to be unwrapped
// accordingly.
class PyQPUState : public QPUState {
// Holder of args data for clean-up.
cudaq::OpaqueArguments *argsData;

public:
PyQPUState(const std::string &in_kernelName,
cudaq::OpaqueArguments *argsDataToOwn)
: argsData(argsDataToOwn) {
this->kernelName = in_kernelName;
this->args = argsData->getArgs();
}

virtual ~PyQPUState() override { delete argsData; }
};

/// @brief Run `cudaq::get_state` for qpu targets on the provided
/// kernel and args
state pyGetStateQPU(py::object kernel, py::args args) {
if (py::hasattr(kernel, "compile"))
kernel.attr("compile")();

auto kernelName = kernel.attr("name").cast<std::string>();
args = simplifiedValidateInputArguments(args);
auto kernelMod = kernel.attr("module").cast<MlirModule>();
auto *argData = toOpaqueArgs(args, kernelMod, kernelName);
auto [argWrapper, size, returnOffset] =
pyCreateNativeKernel(kernelName, kernelMod, *argData);
return state(new PyQPUState(kernelName, argData));
}

state pyGetStateLibraryMode(py::object kernel, py::args args) {
return details::extractState([&]() mutable {
if (0 == args.size())
Expand Down Expand Up @@ -671,6 +700,8 @@ index pair.
return pyGetStateRemote(kernel, args);
if (holder.getTarget().name == "orca-photonics")
return pyGetStateLibraryMode(kernel, args);
if (holder.getTarget().is_remote() || holder.getTarget().is_emulated())
return pyGetStateQPU(kernel, args);
return pyGetState(kernel, args);
},
R"#(Return the :class:`State` of the system after execution of the provided `kernel`.
Expand Down
18 changes: 17 additions & 1 deletion python/runtime/cudaq/platform/py_alt_launch_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -337,15 +337,31 @@ pyAltLaunchKernelBase(const std::string &name, MlirModule module,
if (launch) {
auto &platform = cudaq::get_platform();
auto uReturnOffset = static_cast<std::uint64_t>(returnOffset);
if (platform.is_remote() || platform.is_emulated()) {
auto isRemoteSimulator =
platform.get_remote_capabilities().isRemoteSimulator;
auto isQuantumDevice =
!isRemoteSimulator && (platform.is_remote() || platform.is_emulated());

if (isRemoteSimulator) {
// Remote simulator - use altLaunchKernel to support returning values.
// TODO: after cudaq::run support this should be merged with the quantum
// device case.
auto *wrapper = new cudaq::ArgWrapper{mod, names, rawArgs};
auto dynamicResult = cudaq::altLaunchKernel(
name.c_str(), thunk, reinterpret_cast<void *>(wrapper), size,
uReturnOffset);
if (dynamicResult.data_buffer || dynamicResult.size)
throw std::runtime_error("not implemented: support dynamic results");
delete wrapper;
} else if (isQuantumDevice) {
// Quantum devices or their emulation - we can use streamlinedLaunchKernel
// as quantum platform do not support direct returns.
auto dynamicResult =
cudaq::streamlinedLaunchKernel(name.c_str(), runtimeArgs.getArgs());
if (dynamicResult.data_buffer || dynamicResult.size)
throw std::runtime_error("not implemented: support dynamic results");
} else {
// Local simulator - use altLaunchKernel with the thunk function.
auto dynamicResult = cudaq::altLaunchKernel(name.c_str(), thunk, rawArgs,
size, uReturnOffset);
if (dynamicResult.data_buffer || dynamicResult.size)
Expand Down
57 changes: 44 additions & 13 deletions python/runtime/utils/PyFermioniqRESTQPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
******************************************************************************/

#include "common/ArgumentWrapper.h"
#include "cudaq/Optimizer/InitAllDialects.h"
#include "cudaq/platform/fermioniq/FermioniqBaseQPU.h"

#include "mlir/Target/LLVMIR/Dialect/LLVMIR/LLVMToLLVMIRTranslation.h"
Expand All @@ -27,41 +28,69 @@ void registerLLVMDialectTranslation(MLIRContext *context);
namespace cudaq {

class PyFermioniqRESTQPU : public cudaq::FermioniqBaseQPU {
private:
/// Creates new context without mlir initialization.
MLIRContext *createContext() {
DialectRegistry registry;
cudaq::opt::registerCodeGenDialect(registry);
cudaq::registerAllDialects(registry);
auto context = new MLIRContext(registry);
context->loadAllAvailableDialects();
registerLLVMDialectTranslation(*context);
return context;
}

protected:
std::tuple<ModuleOp, MLIRContext *, void *>
extractQuakeCodeAndContext(const std::string &kernelName,
void *data) override {
auto [mod, ctx] = extractQuakeCodeAndContextImpl(kernelName);
void *updatedArgs = nullptr;
if (data) {
auto *wrapper = reinterpret_cast<cudaq::ArgWrapper *>(data);
updatedArgs = wrapper->rawArgs;
}
return {mod, ctx, updatedArgs};
}

std::tuple<ModuleOp, MLIRContext *>
extractQuakeCodeAndContextImpl(const std::string &kernelName) {

auto *wrapper = reinterpret_cast<cudaq::ArgWrapper *>(data);
auto m_module = wrapper->mod;
auto callableNames = wrapper->callableNames;
cudaq::info("extract quake code\n");

MLIRContext *context = createContext();

auto *context = m_module->getContext();
static bool initOnce = [&] {
registerToQIRTranslation();
registerToOpenQASMTranslation();
registerToIQMJsonTranslation();
registerLLVMDialectTranslation(*context);
return true;
}();
(void)initOnce;

// Get the quake representation of the kernel
auto quakeCode = cudaq::get_quake_by_name(kernelName);
auto m_module = parseSourceString<ModuleOp>(quakeCode, context);
if (!m_module)
throw std::runtime_error("module cannot be parsed");

// Here we have an opportunity to run any passes that are
// specific to python before the rest of the RemoteRESTQPU workflow
auto cloned = m_module.clone();
auto cloned = m_module->clone();
PassManager pm(cloned.getContext());
pm.addNestedPass<func::FuncOp>(cudaq::opt::createPySynthCallableBlockArgs(
SmallVector<StringRef>(callableNames.begin(), callableNames.end())));

pm.addPass(cudaq::opt::createLambdaLiftingPass());
cudaq::opt::addAggressiveEarlyInlining(pm);
pm.addPass(mlir::createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(cudaq::opt::createClassicalMemToReg());
pm.addNestedPass<func::FuncOp>(createCanonicalizerPass());
pm.addNestedPass<mlir::func::FuncOp>(
cudaq::opt::createUnwindLoweringPass());
pm.addPass(mlir::createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(createCanonicalizerPass());
pm.addPass(cudaq::opt::createApplyOpSpecializationPass());
pm.addPass(createInlinerPass());
pm.addPass(cudaq::opt::createExpandMeasurementsPass());
pm.addPass(createCanonicalizerPass());
pm.addPass(createCSEPass());
pm.addNestedPass<func::FuncOp>(createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(createCSEPass());
if (failed(pm.run(cloned)))
throw std::runtime_error(
"Failure to synthesize callable block arguments in PyRemoteRESTQPU ");
Expand All @@ -75,8 +104,10 @@ class PyFermioniqRESTQPU : public cudaq::FermioniqBaseQPU {
// The remote rest qpu workflow will need the module string in
// the internal registry.
__cudaq_deviceCodeHolderAdd(kernelName.c_str(), moduleStr.c_str());
return std::make_tuple(cloned, context, wrapper->rawArgs);
return std::make_tuple(cloned, context);
}

void cleanupContext(MLIRContext *context) override { delete context; }
};
} // namespace cudaq

Expand Down
58 changes: 43 additions & 15 deletions python/runtime/utils/PyRemoteRESTQPU.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "common/ArgumentWrapper.h"
#include "common/BaseRemoteRESTQPU.h"
#include "common/RuntimeMLIRCommonImpl.h"
#include "cudaq/Optimizer/InitAllDialects.h"

// [RFC]:
// The RemoteRESTQPU implementation that is now split across several files needs
Expand Down Expand Up @@ -57,40 +58,65 @@ TranslateFromMLIRRegistration::TranslateFromMLIRRegistration(
// implement some core functionality here in PyRemoteRESTQPU so we don't load
// twice
class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU {
private:
/// Creates new context without mlir initialization.
MLIRContext *createContext() {
DialectRegistry registry;
cudaq::opt::registerCodeGenDialect(registry);
cudaq::registerAllDialects(registry);
auto context = new MLIRContext(registry);
context->loadAllAvailableDialects();
registerLLVMDialectTranslation(*context);
return context;
}

protected:
std::tuple<ModuleOp, MLIRContext *, void *>
extractQuakeCodeAndContext(const std::string &kernelName,
void *data) override {
auto [mod, ctx] = extractQuakeCodeAndContextImpl(kernelName);
void *updatedArgs = nullptr;
if (data) {
auto *wrapper = reinterpret_cast<cudaq::ArgWrapper *>(data);
updatedArgs = wrapper->rawArgs;
}
return {mod, ctx, updatedArgs};
}

auto *wrapper = reinterpret_cast<cudaq::ArgWrapper *>(data);
auto m_module = wrapper->mod;
auto callableNames = wrapper->callableNames;
std::tuple<ModuleOp, MLIRContext *>
extractQuakeCodeAndContextImpl(const std::string &kernelName) {

MLIRContext *context = createContext();

auto *context = m_module->getContext();
static bool initOnce = [&] {
registerToQIRTranslation();
registerToOpenQASMTranslation();
registerToIQMJsonTranslation();
registerLLVMDialectTranslation(*context);
return true;
}();
(void)initOnce;

// Get the quake representation of the kernel
auto quakeCode = cudaq::get_quake_by_name(kernelName);
auto m_module = parseSourceString<ModuleOp>(quakeCode, context);
if (!m_module)
throw std::runtime_error("module cannot be parsed");

// Here we have an opportunity to run any passes that are
// specific to python before the rest of the RemoteRESTQPU workflow
auto cloned = m_module.clone();
auto cloned = m_module->clone();
PassManager pm(cloned.getContext());
pm.addNestedPass<func::FuncOp>(cudaq::opt::createPySynthCallableBlockArgs(
SmallVector<StringRef>(callableNames.begin(), callableNames.end())));

pm.addPass(cudaq::opt::createLambdaLiftingPass());
cudaq::opt::addAggressiveEarlyInlining(pm);
pm.addPass(mlir::createCanonicalizerPass());
pm.addNestedPass<mlir::func::FuncOp>(
cudaq::opt::createUnwindLoweringPass());
pm.addPass(mlir::createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(cudaq::opt::createClassicalMemToReg());
pm.addNestedPass<func::FuncOp>(createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(cudaq::opt::createUnwindLoweringPass());
pm.addNestedPass<func::FuncOp>(createCanonicalizerPass());
pm.addPass(cudaq::opt::createApplyOpSpecializationPass());
pm.addPass(createInlinerPass());
pm.addPass(createCanonicalizerPass());
pm.addPass(createCSEPass());
pm.addNestedPass<func::FuncOp>(createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(createCSEPass());
if (failed(pm.run(cloned)))
throw std::runtime_error(
"Failure to synthesize callable block arguments in PyRemoteRESTQPU ");
Expand All @@ -103,8 +129,10 @@ class PyRemoteRESTQPU : public cudaq::BaseRemoteRESTQPU {
// The remote rest qpu workflow will need the module string in
// the internal registry.
__cudaq_deviceCodeHolderAdd(kernelName.c_str(), moduleStr.c_str());
return std::make_tuple(cloned, context, wrapper->rawArgs);
return std::make_tuple(cloned, context);
}

void cleanupContext(MLIRContext *context) override { delete context; }
};
} // namespace cudaq

Expand Down
80 changes: 80 additions & 0 deletions python/tests/backends/test_IQM.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,86 @@ def test_IQM_state_preparation_builder():
assert assert_close(counts["11"], 0., 2)


def test_IQM_state_synthesis_from_simulator():

@cudaq.kernel
def kernel(state: cudaq.State):
qubits = cudaq.qvector(state)

state = cudaq.State.from_data(
np.array([1. / np.sqrt(2.), 1. / np.sqrt(2.), 0., 0.], dtype=complex))

counts = cudaq.sample(kernel, state)
print(counts)
assert "00" in counts
assert "10" in counts
assert assert_close(counts["01"], 0., 2)
assert assert_close(counts["11"], 0., 2)

synthesized = cudaq.synthesize(kernel, state)
counts = cudaq.sample(synthesized)
assert '00' in counts
assert '10' in counts
assert assert_close(counts["01"], 0., 2)
assert assert_close(counts["11"], 0., 2)


def test_IQM_state_synthesis_from_simulator_builder():

kernel, state = cudaq.make_kernel(cudaq.State)
qubits = kernel.qalloc(state)

state = cudaq.State.from_data(
np.array([1. / np.sqrt(2.), 1. / np.sqrt(2.), 0., 0.], dtype=complex))

counts = cudaq.sample(kernel, state)
assert "00" in counts
assert "10" in counts
assert assert_close(counts["01"], 0., 2)
assert assert_close(counts["11"], 0., 2)


def test_IQM_state_synthesis():

@cudaq.kernel
def init(n: int):
q = cudaq.qvector(n)
x(q[0])

@cudaq.kernel
def kernel(s: cudaq.State):
q = cudaq.qvector(s)
x(q[1])

s = cudaq.get_state(init, 2)
s = cudaq.get_state(kernel, s)
counts = cudaq.sample(kernel, s)
assert '10' in counts
assert assert_close(counts["00"], 0., 2)
assert assert_close(counts["01"], 0., 2)
assert assert_close(counts["11"], 0., 2)


def test_IQM_state_synthesis_builder():

init, n = cudaq.make_kernel(int)
qubits = init.qalloc(n)
init.x(qubits[0])

s = cudaq.get_state(init, 2)

kernel, state = cudaq.make_kernel(cudaq.State)
qubits = kernel.qalloc(state)
kernel.x(qubits[1])

s = cudaq.get_state(kernel, s)
counts = cudaq.sample(kernel, s)
assert '10' in counts
assert assert_close(counts["00"], 0., 2)
assert assert_close(counts["01"], 0., 2)
assert assert_close(counts["11"], 0., 2)


def test_exp_pauli():

@cudaq.kernel
Expand Down
Loading
Loading