From 8146ee0cfc9c46d020a73b63639840a3689c1eb7 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 19 Jan 2026 13:26:58 +0100 Subject: [PATCH] Add C API for atom and molecule types, provide C enums --- include/gauxc/atom.h | 42 ++++++++++++++++++ include/gauxc/enum.h | 81 ++++++++++++++++++++++++++++++++++ include/gauxc/enums.hpp | 46 +++++++++++-------- include/gauxc/grid_factory.hpp | 8 +--- include/gauxc/molecule.h | 67 ++++++++++++++++++++++++++++ src/CMakeLists.txt | 12 ++++- src/c_molecule.cxx | 64 +++++++++++++++++++++++++++ tests/moltypes_test.cxx | 16 +++++++ 8 files changed, 309 insertions(+), 27 deletions(-) create mode 100644 include/gauxc/atom.h create mode 100644 include/gauxc/enum.h create mode 100644 include/gauxc/molecule.h create mode 100644 src/c_molecule.cxx diff --git a/include/gauxc/atom.h b/include/gauxc/atom.h new file mode 100644 index 00000000..9183ee16 --- /dev/null +++ b/include/gauxc/atom.h @@ -0,0 +1,42 @@ +/** + * GauXC Copyright (c) 2020-2024, The Regents of the University of California, + * through Lawrence Berkeley National Laboratory (subject to receipt of + * any required approvals from the U.S. Dept. of Energy). + * + * (c) 2024-2025, Microsoft Corporation + * + * All rights reserved. + * + * See LICENSE.txt for details + */ +#pragma once + +#ifdef __cplusplus +#include +#include +#include +#else +#include +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC C API Atom representation. + */ +typedef struct GauXCAtom { + int64_t Z; ///< Atomic number. + double x; ///< X coordinate (Bohr). + double y; ///< Y coordinate (Bohr). + double z; ///< Z coordinate (Bohr). +} GauXCAtom; + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif diff --git a/include/gauxc/enum.h b/include/gauxc/enum.h new file mode 100644 index 00000000..b3e77e07 --- /dev/null +++ b/include/gauxc/enum.h @@ -0,0 +1,81 @@ +/** + * GauXC Copyright (c) 2020-2024, The Regents of the University of California, + * through Lawrence Berkeley National Laboratory (subject to receipt of + * any required approvals from the U.S. Dept. of Energy). + * + * (c) 2024-2025, Microsoft Corporation + * + * All rights reserved. + * + * See LICENSE.txt for details + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC specific enums for the specification of radial quadratures + * + * Generally mapped to equivalent enums in IntegratorXX + */ +enum GauXC_RadialQuad { + GauXC_RadialQuad_Becke, ///< Becke radial quadrature + GauXC_RadialQuad_MuraKnowles, ///< Mura-Knowles radial quadrature + GauXC_RadialQuad_MurrayHandyLaming, ///< Murray-Handy-Laming radial quadrature + GauXC_RadialQuad_TreutlerAhlrichs ///< Treutler-Ahlrichs radial quadrature +}; + +/** + * @brief Specifications of grid defaults for atomic integration + * + * See https://gaussian.com/integral for specification + */ +enum GauXC_AtomicGridSizeDefault { + GauXC_AtomicGridSizeDefault_FineGrid, ///< Fine grid (least accurate) + GauXC_AtomicGridSizeDefault_UltraFineGrid, ///< Ultrafine grid (appropriate accuracy) + GauXC_AtomicGridSizeDefault_SuperFineGrid, ///< Superfine grid (most accurate) + GauXC_AtomicGridSizeDefault_GM3, ///< Treutler-Ahlrichs GM3 + GauXC_AtomicGridSizeDefault_GM5 ///< Treutlet-Ahlrichs GM5 +}; + +/** + * @brief Specifications of atomic partitioning scheme for the + * molecular integration + */ +enum GauXC_XCWeightAlg { + GauXC_XCWeightAlg_NOTPARTITIONED, ///< Not partitioned + GauXC_XCWeightAlg_Becke, ///< The original Becke weighting scheme + GauXC_XCWeightAlg_SSF, ///< The Stratmann-Scuseria-Frisch weighting scheme + GauXC_XCWeightAlg_LKO ///< The Lauqua-Kuessman-Ochsenfeld weighting scheme +}; + +/** + * @brief Specification of the execution space for various operations + */ +enum GauXC_ExecutionSpace { + GauXC_ExecutionSpace_Host, ///< Execute task on the host + GauXC_ExecutionSpace_Device ///< Execute task on the device (e.g. GPU) +}; + +/// Supported Algorithms / Integrands +enum GauXC_SupportedAlg { + GauXC_SupportedAlg_XC, + GauXC_SupportedAlg_DEN, + GauXC_SupportedAlg_SNLINK +}; + +/// High-level specification of pruning schemes for atomic quadratures +enum GauXC_PruningScheme { + GauXC_PruningScheme_Unpruned, ///< Unpruned atomic quadrature + GauXC_PruningScheme_Robust, ///< The "Robust" scheme of Psi4 + GauXC_PruningScheme_Treutler ///< The Treutler-Ahlrichs scheme +}; + + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif \ No newline at end of file diff --git a/include/gauxc/enums.hpp b/include/gauxc/enums.hpp index 76d4500c..6ced51c8 100644 --- a/include/gauxc/enums.hpp +++ b/include/gauxc/enums.hpp @@ -11,6 +11,8 @@ */ #pragma once +#include + namespace GauXC { /** @@ -19,10 +21,10 @@ namespace GauXC { * Generally mapped to equivalent enums in IntegratorXX */ enum class RadialQuad { - Becke, ///< Becke radial quadrature - MuraKnowles, ///< Mura-Knowles radial quadrature - MurrayHandyLaming, ///< Murray-Handy-Laming radial quadrature - TreutlerAhlrichs ///< Treutler-Ahlrichs radial quadrature + Becke = C::GauXC_RadialQuad_Becke, ///< Becke radial quadrature + MuraKnowles = C::GauXC_RadialQuad_MuraKnowles, ///< Mura-Knowles radial quadrature + MurrayHandyLaming = C::GauXC_RadialQuad_MurrayHandyLaming, ///< Murray-Handy-Laming radial quadrature + TreutlerAhlrichs = C::GauXC_RadialQuad_TreutlerAhlrichs ///< Treutler-Ahlrichs radial quadrature }; /** @@ -31,11 +33,11 @@ enum class RadialQuad { * See https://gaussian.com/integral for specification */ enum class AtomicGridSizeDefault { - FineGrid, ///< Fine grid (least accurate) - UltraFineGrid, ///< Ultrafine grid (appropriate accuracy) - SuperFineGrid, ///< Superfine grid (most accurate) - GM3, ///< Treutler-Ahlrichs GM3 - GM5 ///< Treutlet-Ahlrichs GM5 + FineGrid = C::GauXC_AtomicGridSizeDefault_FineGrid, ///< Fine grid (least accurate) + UltraFineGrid = C::GauXC_AtomicGridSizeDefault_UltraFineGrid, ///< Ultrafine grid (appropriate accuracy) + SuperFineGrid = C::GauXC_AtomicGridSizeDefault_SuperFineGrid, ///< Superfine grid (most accurate) + GM3 = C::GauXC_AtomicGridSizeDefault_GM3, ///< Treutler-Ahlrichs GM3 + GM5 = C::GauXC_AtomicGridSizeDefault_GM5 ///< Treutlet-Ahlrichs GM5 }; /** @@ -43,25 +45,33 @@ enum class AtomicGridSizeDefault { * molecular integration */ enum class XCWeightAlg { - NOTPARTITIONED, ///< Not partitioned - Becke, ///< The original Becke weighting scheme - SSF, ///< The Stratmann-Scuseria-Frisch weighting scheme - LKO ///< The Lauqua-Kuessman-Ochsenfeld weighting scheme + NOTPARTITIONED = C::GauXC_XCWeightAlg_NOTPARTITIONED, ///< Not partitioned + Becke = C::GauXC_XCWeightAlg_Becke, ///< The original Becke weighting scheme + SSF = C::GauXC_XCWeightAlg_SSF, ///< The Stratmann-Scuseria-Frisch weighting scheme + LKO = C::GauXC_XCWeightAlg_LKO ///< The Lauqua-Kuessman-Ochsenfeld weighting scheme }; /** * @brief Specification of the execution space for various operations */ enum class ExecutionSpace { - Host, ///< Execute task on the host - Device ///< Execute task on the device (e.g. GPU) + Host = C::GauXC_ExecutionSpace_Host, ///< Execute task on the host + Device = C::GauXC_ExecutionSpace_Device ///< Execute task on the device (e.g. GPU) }; /// Supported Algorithms / Integrands enum class SupportedAlg { - XC, - DEN, - SNLINK + XC = C::GauXC_SupportedAlg_XC, + DEN = C::GauXC_SupportedAlg_DEN, + SNLINK = C::GauXC_SupportedAlg_SNLINK +}; + +/// High-level specification of pruning schemes for atomic quadratures +enum class PruningScheme { + Unpruned = C::GauXC_PruningScheme_Unpruned, ///< Unpruned atomic quadrature + Robust = C::GauXC_PruningScheme_Robust, ///< The "Robust" scheme of Psi4 + Treutler = C::GauXC_PruningScheme_Treutler ///< The Treutler-Ahlrichs scheme }; + } // namespace GauXC diff --git a/include/gauxc/grid_factory.hpp b/include/gauxc/grid_factory.hpp index ecf65526..b2ed0a8d 100644 --- a/include/gauxc/grid_factory.hpp +++ b/include/gauxc/grid_factory.hpp @@ -11,6 +11,7 @@ */ #pragma once #include +#include #include #include @@ -61,13 +62,6 @@ PrunedAtomicGridSpecification treutler_pruning_scheme( UnprunedAtomicGridSpecification ); -/// High-level specification of pruning schemes for atomic quadratures -enum class PruningScheme { - Unpruned, /// Unpruned atomic quadrature - Robust, /// The "Robust" scheme of Psi4 - Treutler /// The Treutler-Ahlrichs scheme -}; - /// Generate a pruning specification from a specificed pruning scheme and /// an unpruned grid specification PrunedAtomicGridSpecification create_pruned_spec( diff --git a/include/gauxc/molecule.h b/include/gauxc/molecule.h new file mode 100644 index 00000000..e3f4bc7c --- /dev/null +++ b/include/gauxc/molecule.h @@ -0,0 +1,67 @@ +/** + * GauXC Copyright (c) 2020-2024, The Regents of the University of California, + * through Lawrence Berkeley National Laboratory (subject to receipt of + * any required approvals from the U.S. Dept. of Energy). + * + * (c) 2024-2025, Microsoft Corporation + * + * All rights reserved. + * + * See LICENSE.txt for details + */ +#pragma once + +#ifdef __cplusplus +#include +#include +#include +#else +#include +#include +#include +#endif +#include + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC C API Molecule handle. + */ +typedef struct GauXCMolecule { + void* ptr; ///< Pointer to the Molecule instance. +} GauXCMolecule; + +/** + * @brief Create a new empty Molecule instance. + * @return Handle to the created Molecule. + */ +extern GauXCMolecule gauxc_molecule_new(); + +/** + * @brief Create a new Molecule instance from an array of Atoms. + * @param atoms Pointer to an array of GauXCAtom. + * @param natoms Number of atoms in the array. + * @return Handle to the created Molecule. + */ +extern GauXCMolecule gauxc_molecule_new_from_atoms( GauXCAtom* atoms, size_t natoms ); + +/** + * @brief Delete a Molecule instance. + * @param mol Handle to the Molecule to delete. + */ +extern void gauxc_molecule_delete( GauXCMolecule mol ); + +/** + * @brief Get the number of atoms in the Molecule. + * @param mol Handle to the Molecule. + * @return Number of atoms in the Molecule. + */ +extern size_t gauxc_molecule_natoms( GauXCMolecule mol ); + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2c18af5c..f01aa45d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -40,7 +40,8 @@ add_library( gauxc molgrid.cxx molgrid_impl.cxx molgrid_defaults.cxx - atomic_radii.cxx + atomic_radii.cxx + c_molecule.cxx ) target_include_directories( gauxc @@ -178,13 +179,20 @@ export(EXPORT gauxc-targets NAMESPACE gauxc:: FILE "${PROJECT_BINARY_DIR}/gauxc-targets.cmake") -# Install static headers +# Install static C++ headers install( DIRECTORY ${PROJECT_SOURCE_DIR}/include DESTINATION . FILES_MATCHING PATTERN "*.hpp" ) +# Install static C headers +install( + DIRECTORY ${PROJECT_SOURCE_DIR}/include + DESTINATION . + FILES_MATCHING PATTERN "*.h" +) + # Install generated headers install( FILES ${PROJECT_BINARY_DIR}/include/gauxc/gauxc_config.hpp diff --git a/src/c_molecule.cxx b/src/c_molecule.cxx new file mode 100644 index 00000000..de4e9e94 --- /dev/null +++ b/src/c_molecule.cxx @@ -0,0 +1,64 @@ +/** + * GauXC Copyright (c) 2020-2024, The Regents of the University of California, + * through Lawrence Berkeley National Laboratory (subject to receipt of + * any required approvals from the U.S. Dept. of Energy). + * + * (c) 2024-2025, Microsoft Corporation + * + * All rights reserved. + * + * See LICENSE.txt for details + */ +#include +#include +#include +#include + +namespace GauXC { +namespace detail { + +static inline Molecule* get_molecule_ptr(C::GauXCMolecule mol) noexcept { + return static_cast(mol.ptr); +} + +static inline Atom convert_atom(C::GauXCAtom atom) noexcept { + return Atom{AtomicNumber(atom.Z), + atom.x, atom.y, atom.z }; +} + +} + +extern "C" { +namespace C { + +GauXCMolecule gauxc_molecule_new() { + GauXCMolecule mol; + mol.ptr = new Molecule(); + return mol; +} + +GauXCMolecule gauxc_molecule_new_from_atoms(GauXCAtom* atoms, size_t natoms) { + GauXCMolecule mol; + Molecule* mol_ptr = new Molecule(); + mol_ptr->reserve( natoms ); + for( size_t i = 0; i < natoms; ++i ) { + mol_ptr->push_back( detail::convert_atom( atoms[i] ) ); + } + mol.ptr = mol_ptr; + return mol; +} + +void gauxc_molecule_delete(GauXCMolecule mol) { + if(mol.ptr != nullptr) + delete detail::get_molecule_ptr(mol); + mol.ptr = nullptr; +} + +size_t gauxc_molecule_natoms(GauXCMolecule mol) { + if(mol.ptr == nullptr) return 0; + return detail::get_molecule_ptr(mol)->natoms(); +} + +} +} +} // namespace GauXC \ No newline at end of file diff --git a/tests/moltypes_test.cxx b/tests/moltypes_test.cxx index d87685f7..6855ff37 100644 --- a/tests/moltypes_test.cxx +++ b/tests/moltypes_test.cxx @@ -11,6 +11,7 @@ */ #include "ut_common.hpp" #include "catch2/catch.hpp" +#include #include #include #include @@ -41,6 +42,14 @@ TEST_CASE("Atom", "[moltypes]") { CHECK( atom.y == y ); CHECK( atom.z == z ); + SECTION("C Interop") { + C::GauXCAtom c_atom = { Z, x, y, z }; + + CHECK( c_atom.Z == atom.Z.get() ); + CHECK( c_atom.x == atom.x ); + CHECK( c_atom.y == atom.y ); + CHECK( c_atom.z == atom.z ); + } } TEST_CASE("Molecule", "[moltypes]") { @@ -58,6 +67,13 @@ TEST_CASE("Molecule", "[moltypes]") { CHECK(mol.natoms() == 0); } + SECTION("Default C") { + C::GauXCMolecule mol = C::gauxc_molecule_new(); + CHECK(C::gauxc_molecule_natoms(mol) == 0); + + C::gauxc_molecule_delete(mol); + } + SECTION("From std::vector") { std::vector atoms;