From a096e55ff3fd929db08cb0135e1207de41d42104 Mon Sep 17 00:00:00 2001 From: Alex McCaskey Date: Tue, 3 Dec 2024 09:56:22 -0500 Subject: [PATCH] Add a get_operator_pool function to C++ to mirror the Python (#13) --- docs/sphinx/api/solvers/cpp_api.rst | 2 ++ docs/sphinx/components/solvers/introduction.rst | 5 ++--- docs/sphinx/examples/solvers/cpp/adapt_h2.cpp | 6 +++--- .../cudaq/solvers/operators/operator_pool.h | 17 +++++++++++++++++ .../operators/operator_pools/operator_pool.cpp | 7 +++++++ .../python/bindings/solvers/py_solvers.cpp | 10 +--------- libs/solvers/unittests/test_operator_pools.cpp | 11 +++++++++++ 7 files changed, 43 insertions(+), 15 deletions(-) diff --git a/docs/sphinx/api/solvers/cpp_api.rst b/docs/sphinx/api/solvers/cpp_api.rst index 623fecb..e363f39 100644 --- a/docs/sphinx/api/solvers/cpp_api.rst +++ b/docs/sphinx/api/solvers/cpp_api.rst @@ -8,6 +8,8 @@ CUDA-Q Solvers C++ API .. doxygenclass:: cudaq::solvers::uccsd .. doxygenclass:: cudaq::solvers::qaoa_pool +.. doxygenfunction:: cudaq::solvers::get_operator_pool + .. doxygenstruct:: cudaq::solvers::atom :members: diff --git a/docs/sphinx/components/solvers/introduction.rst b/docs/sphinx/components/solvers/introduction.rst index 0bbc36c..3bd0c86 100644 --- a/docs/sphinx/components/solvers/introduction.rst +++ b/docs/sphinx/components/solvers/introduction.rst @@ -420,9 +420,8 @@ Basic Usage auto h = molecule.hamiltonian; // Generate operator pool - auto pool = cudaq::solvers::operator_pool::get( - "spin_complement_gsd"); - auto operators = pool->generate({ + auto operators = cudaq::solvers::get_operator_pool( + "spin_complement_gsd", { {"num-orbitals", h.num_qubits() / 2} }); diff --git a/docs/sphinx/examples/solvers/cpp/adapt_h2.cpp b/docs/sphinx/examples/solvers/cpp/adapt_h2.cpp index 987e9ee..1ff4ddc 100644 --- a/docs/sphinx/examples/solvers/cpp/adapt_h2.cpp +++ b/docs/sphinx/examples/solvers/cpp/adapt_h2.cpp @@ -24,8 +24,8 @@ int main() { auto h = molecule.hamiltonian; // Create the operator pool - auto pool = cudaq::solvers::operator_pool::get("spin_complement_gsd"); - auto poolList = pool->generate({{"num-orbitals", h.num_qubits() / 2}}); + std::vector opPool = cudaq::solvers::get_operator_pool( + "spin_complement_gsd", {{"num-orbitals", h.num_qubits() / 2}}); // Run ADAPT auto [energy, thetas, ops] = cudaq::solvers::adapt_vqe( @@ -33,7 +33,7 @@ int main() { x(q[0]); x(q[1]); }, - h, poolList, {{"grad_norm_tolerance", 1e-3}}); + h, opPool, {{"grad_norm_tolerance", 1e-3}}); printf("Final = %.12lf\n", energy); } \ No newline at end of file diff --git a/libs/solvers/include/cudaq/solvers/operators/operator_pool.h b/libs/solvers/include/cudaq/solvers/operators/operator_pool.h index 4d067a5..bfaa6a6 100644 --- a/libs/solvers/include/cudaq/solvers/operators/operator_pool.h +++ b/libs/solvers/include/cudaq/solvers/operators/operator_pool.h @@ -42,4 +42,21 @@ class operator_pool : public extension_point { generate(const heterogeneous_map &config) const = 0; }; +/// @brief Retrieves a quantum operator pool based on the specified name and +/// configuration options. +/// +/// This function creates and returns a vector of quantum spin operators by +/// instantiating the appropriate operator_pool implementation specified by the +/// name parameter. The generated operators are configured according to the +/// provided options. +/// +/// @param name The identifier string for the desired operator pool +/// implementation +/// @param options Configuration parameters for operator pool generation stored +/// in a heterogeneous map +/// @return std::vector A vector containing the generated +/// quantum spin operators +std::vector get_operator_pool(const std::string &name, + const heterogeneous_map &options); + } // namespace cudaq::solvers \ No newline at end of file diff --git a/libs/solvers/lib/operators/operator_pools/operator_pool.cpp b/libs/solvers/lib/operators/operator_pools/operator_pool.cpp index f0b203d..86d432f 100644 --- a/libs/solvers/lib/operators/operator_pools/operator_pool.cpp +++ b/libs/solvers/lib/operators/operator_pools/operator_pool.cpp @@ -9,3 +9,10 @@ #include "cudaq/solvers/operators/operator_pool.h" INSTANTIATE_REGISTRY_NO_ARGS(cudaq::solvers::operator_pool) + +namespace cudaq::solvers { +std::vector +get_operator_pool(const std::string &name, const heterogeneous_map &options) { + return cudaq::solvers::operator_pool::get(name)->generate(options); +} +} // namespace cudaq::solvers \ No newline at end of file diff --git a/libs/solvers/python/bindings/solvers/py_solvers.cpp b/libs/solvers/python/bindings/solvers/py_solvers.cpp index f7d605e..784789c 100644 --- a/libs/solvers/python/bindings/solvers/py_solvers.cpp +++ b/libs/solvers/python/bindings/solvers/py_solvers.cpp @@ -501,15 +501,7 @@ RuntimeError mod.def( "get_operator_pool", [](const std::string &name, py::kwargs config) { - heterogeneous_map asCpp; - for (auto &[k, v] : config) { - std::string asStr = k.cast(); - if (py::isinstance(v)) - asCpp.insert(asStr, v.cast()); - if (py::isinstance(v)) - asCpp.insert(asStr, v.cast>()); - } - return operator_pool::get(name)->generate(asCpp); + return operator_pool::get(name)->generate(hetMapFromKwargs(config)); }, R"#(Get and generate an operator pool based on the specified name and configuration. diff --git a/libs/solvers/unittests/test_operator_pools.cpp b/libs/solvers/unittests/test_operator_pools.cpp index 3961816..8fb9fe6 100644 --- a/libs/solvers/unittests/test_operator_pools.cpp +++ b/libs/solvers/unittests/test_operator_pools.cpp @@ -26,6 +26,17 @@ TEST(UCCSDTest, GenerateWithDefaultConfig) { } } +TEST(UCCSDTest, GenerateFromAPIFunction) { + auto operators = cudaq::solvers::get_operator_pool( + "uccsd", {{"num-qubits", 4}, {"num-electrons", 2}}); + ASSERT_FALSE(operators.empty()); + EXPECT_EQ(operators.size(), 2 * 2 + 1 * 8); + + for (const auto &op : operators) { + EXPECT_EQ(op.num_qubits(), 4); + } +} + TEST(UCCSDTest, GenerateWithCustomCoefficients) { auto pool = cudaq::solvers::operator_pool::get("uccsd"); heterogeneous_map config;