From 8146ee0cfc9c46d020a73b63639840a3689c1eb7 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 19 Jan 2026 13:26:58 +0100 Subject: [PATCH 01/15] 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; From b5feeb27921d6863bcb4a293ffc85eed71748908 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Wed, 21 Jan 2026 14:56:18 +0100 Subject: [PATCH 02/15] Add basis set and shell definitions --- include/gauxc/basisset.h | 61 ++++++++++++++++++++++++++++++++++ include/gauxc/shell.h | 42 +++++++++++++++++++++++ src/CMakeLists.txt | 1 + src/c_basisset.cxx | 72 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 176 insertions(+) create mode 100644 include/gauxc/basisset.h create mode 100644 include/gauxc/shell.h create mode 100644 src/c_basisset.cxx diff --git a/include/gauxc/basisset.h b/include/gauxc/basisset.h new file mode 100644 index 00000000..3e8e9eae --- /dev/null +++ b/include/gauxc/basisset.h @@ -0,0 +1,61 @@ +/** + * 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 BasisSet handle. + */ +typedef struct GauXCBasisSet { + void* ptr; ///< Pointer to the BasisSet instance. +} GauXCBasisSet; + +/** + * @brief Create a new BasisSet instance. + * @return Handle to the created BasisSet. + */ +extern GauXCBasisSet gauxc_basisset_new(); + +/** + * @brief Create a new BasisSet instance from arrays of shells. + * @param shells Pointer to an array of GauXCShell. + * @param nshells Number of shells in the array. + * @param normalize Whether to normalize the basis functions. + * @return Handle to the created BasisSet. + */ +extern GauXCBasisSet gauxc_basisset_new_from_shells( GauXCShell* shells, size_t nshells, bool normalize ); + +/** + * @brief Delete a BasisSet instance. + * @param basis Handle to the BasisSet to delete. + */ +extern void gauxc_basisset_delete( GauXCBasisSet basis ); + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif \ No newline at end of file diff --git a/include/gauxc/shell.h b/include/gauxc/shell.h new file mode 100644 index 00000000..22e2cff7 --- /dev/null +++ b/include/gauxc/shell.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 +#else +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC C API shell representation. + */ +typedef struct GauXCShell { + int32_t l; ///< Angular momentum. + bool pure; ///< Spherical (true) or Cartesian (false) functions. + int32_t nprim; ///< Number of primitives. + double exponents[32]; ///< Pointer to array of primitive exponents. + double coefficients[32]; ///< Pointer to array of contraction coefficients. + double shell_tolerance; ///< Shell tolerance. +} GauXCShell; + +#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 f01aa45d..dafe0f2e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -42,6 +42,7 @@ add_library( gauxc molgrid_defaults.cxx atomic_radii.cxx c_molecule.cxx + c_basisset.cxx ) target_include_directories( gauxc diff --git a/src/c_basisset.cxx b/src/c_basisset.cxx new file mode 100644 index 00000000..f596d696 --- /dev/null +++ b/src/c_basisset.cxx @@ -0,0 +1,72 @@ +/** + * 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 BasisSet* get_basisset_ptr(C::GauXCBasisSet basis) noexcept { + return static_cast*>(basis.ptr); +} +static inline Shell convert_shell(C::GauXCShell shell, bool normalize) noexcept { + Shell::prim_array alpha{}; + Shell::prim_array coeff{}; + Shell::cart_array O{0.0, 0.0, 0.0}; + + for( int32_t i = 0; i < shell.nprim; ++i ) { + alpha[i] = shell.exponents[i]; + coeff[i] = shell.coefficients[i]; + } + + Shell sh{ PrimSize{shell.nprim}, + AngularMomentum{shell.l}, + SphericalType{shell.pure}, + alpha, coeff, O, normalize }; + + if (shell.shell_tolerance >= 0.0) { + sh.set_shell_tolerance( shell.shell_tolerance ); + } + + return sh; +} +} // namespace detail +namespace C { +extern "C" { + +GauXCBasisSet gauxc_basisset_new() { + GauXCBasisSet basis; + basis.ptr = new BasisSet(); + return basis; +} + +GauXCBasisSet gauxc_basisset_new_from_shells(GauXCShell* shells, size_t nshells, bool normalize) { + GauXCBasisSet basis; + BasisSet* basis_ptr = new BasisSet(); + basis_ptr->reserve( nshells ); + for( size_t i = 0; i < nshells; ++i ) { + basis_ptr->push_back( detail::convert_shell( shells[i], normalize ) ); + } + basis.ptr = basis_ptr; + return basis; +} + +void gauxc_basisset_delete(GauXCBasisSet basis) { + if(basis.ptr != nullptr) + delete detail::get_basisset_ptr(basis); + basis.ptr = nullptr; +} + +} // extern "C" +} // namespace C +} // namespace GauXC \ No newline at end of file From b13c3614c0ca93814719f2f46253b6843da44806 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Thu, 22 Jan 2026 09:39:41 +0100 Subject: [PATCH 03/15] Add C API for basis set, molecule grid and runtime environment --- CMakeLists.txt | 3 + cmake/gauxc-config.cmake.in | 1 + ...{gauxc_config.hpp.in => gauxc_config.h.in} | 9 +- include/gauxc/gauxc_config.hpp | 20 ++++ include/gauxc/molgrid.h | 62 ++++++++++++ include/gauxc/runtime_environment.h | 89 +++++++++++++++++ include/gauxc/util/mpi.h | 23 +++++ include/gauxc/util/mpi.hpp | 11 +++ src/CMakeLists.txt | 21 ++-- src/c_molgrid.cxx | 58 +++++++++++ src/c_runtime_environment.cxx | 96 +++++++++++++++++++ tests/moltypes_test.cxx | 4 + 12 files changed, 384 insertions(+), 13 deletions(-) rename include/gauxc/{gauxc_config.hpp.in => gauxc_config.h.in} (86%) create mode 100644 include/gauxc/gauxc_config.hpp create mode 100644 include/gauxc/molgrid.h create mode 100644 include/gauxc/runtime_environment.h create mode 100644 include/gauxc/util/mpi.h create mode 100644 src/c_molgrid.cxx create mode 100644 src/c_runtime_environment.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 94efc973..22d7a290 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,7 @@ endif() # GauXC Options +option( GAUXC_ENABLE_C "Enable C API" ON ) option( GAUXC_ENABLE_HOST "Enable Host Integrator" ON ) option( GAUXC_ENABLE_CUDA "Enable CUDA Bindings" OFF ) option( GAUXC_ENABLE_HIP "Enable HIP Bindings" OFF ) @@ -54,6 +55,7 @@ cmake_dependent_option( GAUXC_ENABLE_CUTLASS ) # Default the feature variables +set( GAUXC_HAS_C FALSE CACHE BOOL "" FORCE ) set( GAUXC_HAS_HOST FALSE CACHE BOOL "" FORCE ) set( GAUXC_HAS_CUDA FALSE CACHE BOOL "" FORCE ) set( GAUXC_HAS_HIP FALSE CACHE BOOL "" FORCE ) @@ -67,6 +69,7 @@ set( GAUXC_HAS_CUTLASS FALSE CACHE BOOL "" FORCE ) set( GAUXC_BLAS_IS_LP64 FALSE CACHE BOOL "" FORCE ) mark_as_advanced( FORCE + GAUXC_HAS_C GAUXC_HAS_HOST GAUXC_HAS_CUDA GAUXC_HAS_HIP diff --git a/cmake/gauxc-config.cmake.in b/cmake/gauxc-config.cmake.in index 426b7f10..397cb80a 100644 --- a/cmake/gauxc-config.cmake.in +++ b/cmake/gauxc-config.cmake.in @@ -10,6 +10,7 @@ include(CMakeFindDependencyMacro) find_dependency( ExchCXX ) find_dependency( IntegratorXX ) +set( GAUXC_HAS_C @GAUXC_HAS_C@ ) set( GAUXC_HAS_HOST @GAUXC_HAS_HOST@ ) set( GAUXC_HAS_CUDA @GAUXC_HAS_CUDA@ ) set( GAUXC_HAS_HIP @GAUXC_HAS_HIP@ ) diff --git a/include/gauxc/gauxc_config.hpp.in b/include/gauxc/gauxc_config.h.in similarity index 86% rename from include/gauxc/gauxc_config.hpp.in rename to include/gauxc/gauxc_config.h.in index 86fe7485..992d1b7c 100644 --- a/include/gauxc/gauxc_config.hpp.in +++ b/include/gauxc/gauxc_config.h.in @@ -11,6 +11,7 @@ */ #pragma once +#cmakedefine GAUXC_HAS_C #cmakedefine GAUXC_HAS_HOST #cmakedefine GAUXC_HAS_CUDA #cmakedefine GAUXC_HAS_HIP @@ -31,10 +32,4 @@ #ifdef GAUXC_HAS_DEVICE #cmakedefine GAUXC_GPU_XC_MAX_AM @GAUXC_GPU_XC_MAX_AM@ #cmakedefine GAUXC_GPU_SNLINK_MAX_AM @GAUXC_GPU_SNLINK_MAX_AM@ -#endif - -#if defined(__CUDACC__) || defined(__HIPCC__) - #define HOST_DEVICE_ACCESSIBLE __host__ __device__ -#else - #define HOST_DEVICE_ACCESSIBLE -#endif +#endif \ No newline at end of file diff --git a/include/gauxc/gauxc_config.hpp b/include/gauxc/gauxc_config.hpp new file mode 100644 index 00000000..ac648d07 --- /dev/null +++ b/include/gauxc/gauxc_config.hpp @@ -0,0 +1,20 @@ +/** + * 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 + +#include + +#if defined(__CUDACC__) || defined(__HIPCC__) + #define HOST_DEVICE_ACCESSIBLE __host__ __device__ +#else + #define HOST_DEVICE_ACCESSIBLE +#endif \ No newline at end of file diff --git a/include/gauxc/molgrid.h b/include/gauxc/molgrid.h new file mode 100644 index 00000000..d2ffe929 --- /dev/null +++ b/include/gauxc/molgrid.h @@ -0,0 +1,62 @@ +/** + * 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 + +#include +#include +#ifdef __cplusplus +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC C API MolGrid handle. + */ +typedef struct GauXCMolGrid { + void* ptr; ///< Pointer to the MolGrid instance. +} GauXCMolGrid; + +/** + * @brief Create a new MolGrid instance from atomic grids. + * @param mol Handle to the Molecule. + * @param pruning_scheme Pruning scheme to use. + * @param batchsize Batch size for grid generation. + * @param radial_quad Radial quadrature scheme to use. + * @param grid_size Default atomic grid size to use. + * @return Handle to the created MolGrid. + */ +extern GauXCMolGrid gauxc_molgrid_new_default( + GauXCMolecule mol, + enum GauXC_PruningScheme pruning_scheme, + int64_t batchsize, + enum GauXC_RadialQuad radial_quad, + enum GauXC_AtomicGridSizeDefault grid_size +); + +/** + * @brief Delete a MolGrid instance. + * @param molgrid Handle to the MolGrid to delete. + */ +extern void gauxc_molgrid_delete( + GauXCMolGrid molgrid +); + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif diff --git a/include/gauxc/runtime_environment.h b/include/gauxc/runtime_environment.h new file mode 100644 index 00000000..52366532 --- /dev/null +++ b/include/gauxc/runtime_environment.h @@ -0,0 +1,89 @@ +/** + * 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 + +#include + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC C API RuntimeEnvironment handle. + */ +typedef struct GauXCRuntimeEnvironment { + void* ptr; ///< Pointer to the RuntimeEnvironment instance. +#ifdef GAUXC_HAS_DEVICE + void* device_ptr; ///< Pointer to the DeviceRuntimeEnvironment instance (if applicable). +#endif +} GauXCRuntimeEnvironment; + +/** + * @brief Create a new RuntimeEnvironment instance. + * @param comm MPI Communicator (if applicable). + * @return Handle to the created RuntimeEnvironment. + */ +GauXCRuntimeEnvironment gauxc_runtime_environment_new( + GAUXC_MPI_CODE(MPI_Comm comm) +); + +/** + * @brief Delete a RuntimeEnvironment instance. + * @param env Handle to the RuntimeEnvironment to delete. + */ +extern void gauxc_runtime_environment_delete( GauXCRuntimeEnvironment env ); + +/** + * @brief Get the rank of the current process in the RuntimeEnvironment's communicator. + * @param env Handle to the RuntimeEnvironment. + * @return Rank of the current process. + */ +extern int gauxc_runtime_environment_comm_rank( GauXCRuntimeEnvironment env ); + +/** + * @brief Get the size of the RuntimeEnvironment's communicator. + * @param env Handle to the RuntimeEnvironment. + * @return Size of the communicator. + */ +extern int gauxc_runtime_environment_comm_size( GauXCRuntimeEnvironment env ); + +#ifdef GAUXC_HAS_DEVICE +/** + * @brief Create new DeviceRuntimeEnvironment instance. + * @param comm MPI Communicator (if applicable). + * @param fill_fraction Fraction of device memory to use. + * @return Handle to the created DeviceRuntimeEnvironment. + */ +GauXCRuntimeEnvironment gauxc_device_runtime_environment_new( + GAUXC_MPI_CODE(MPI_Comm comm,) + double fill_fraction +); + +/** + * @brief Create new DeviceRuntimeEnvironment instance. + * @param comm MPI Communicator (if applicable). + * @param mem Pointer to preallocated device memory. + * @param mem_sz Size of preallocated device memory. + * @return Handle to the created DeviceRuntimeEnvironment. + */ +GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( + GAUXC_MPI_CODE(MPI_Comm comm,) + void* mem, + size_t mem_sz +); +#endif + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif \ No newline at end of file diff --git a/include/gauxc/util/mpi.h b/include/gauxc/util/mpi.h new file mode 100644 index 00000000..924d7a74 --- /dev/null +++ b/include/gauxc/util/mpi.h @@ -0,0 +1,23 @@ +/** + * 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 +#include + +#ifdef GAUXC_HAS_MPI + #define GAUXC_MPI_CODE(...) __VA_ARGS__ +#else + #define GAUXC_MPI_CODE(...) +#endif + +#ifdef GAUXC_HAS_MPI +#include +#endif \ No newline at end of file diff --git a/include/gauxc/util/mpi.hpp b/include/gauxc/util/mpi.hpp index 7875dd87..b06a8ac7 100644 --- a/include/gauxc/util/mpi.hpp +++ b/include/gauxc/util/mpi.hpp @@ -1,3 +1,14 @@ +/** + * 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 #include diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dafe0f2e..0639d3fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -31,8 +31,7 @@ endif() include( gauxc-integratorxx ) include( gauxc-exchcxx ) - -add_library( gauxc +set( gauxc_sources grid.cxx grid_impl.cxx grid_factory.cxx @@ -41,10 +40,20 @@ add_library( gauxc molgrid_impl.cxx molgrid_defaults.cxx atomic_radii.cxx - c_molecule.cxx - c_basisset.cxx ) +if( GAUXC_ENABLE_C ) + set( gauxc_sources + ${gauxc_sources} + c_molecule.cxx + c_basisset.cxx + c_molgrid.cxx + c_runtime_environment.cxx + ) +endif() + +add_library( gauxc ${gauxc_sources}) + target_include_directories( gauxc PUBLIC $ @@ -119,8 +128,8 @@ endif() # Generate config file configure_file( - ${PROJECT_SOURCE_DIR}/include/gauxc/gauxc_config.hpp.in - ${PROJECT_BINARY_DIR}/include/gauxc/gauxc_config.hpp + ${PROJECT_SOURCE_DIR}/include/gauxc/gauxc_config.h.in + ${PROJECT_BINARY_DIR}/include/gauxc/gauxc_config.h ) diff --git a/src/c_molgrid.cxx b/src/c_molgrid.cxx new file mode 100644 index 00000000..8efa3b5f --- /dev/null +++ b/src/c_molgrid.cxx @@ -0,0 +1,58 @@ +/** + * 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 +#include + +namespace GauXC { +namespace detail { +static inline Molecule* get_molecule_ptr(C::GauXCMolecule mol) noexcept { + return static_cast(mol.ptr); +} +static inline MolGrid* get_molgrid_ptr(C::GauXCMolGrid molgrid) noexcept { + return static_cast(molgrid.ptr); +} +} // namespace detail + +extern "C" { +namespace C { +GauXCMolGrid gauxc_molgrid_new_default( + GauXCMolecule mol, + enum GauXC_PruningScheme pruning_scheme, + int64_t batchsize, + enum GauXC_RadialQuad radial_quad, + enum GauXC_AtomicGridSizeDefault grid_size +) { + auto grid_map = MolGridFactory::create_default_gridmap( + *detail::get_molecule_ptr(mol), + static_cast(pruning_scheme), + static_cast(batchsize), + static_cast(radial_quad), + static_cast(grid_size) + ); + MolGrid* molgrid = new MolGrid( grid_map ); + GauXCMolGrid mg; + mg.ptr = molgrid; + return mg; +} + +void gauxc_molgrid_delete(GauXCMolGrid mg) { + if(mg.ptr != nullptr) + delete detail::get_molgrid_ptr(mg); + mg.ptr = nullptr; +} + +} // namespace C +} // extern "C" +} // namespace GauXC \ No newline at end of file diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx new file mode 100644 index 00000000..26bf29b4 --- /dev/null +++ b/src/c_runtime_environment.cxx @@ -0,0 +1,96 @@ +/** + * 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 + +namespace GauXC { +namespace detail { +static inline RuntimeEnvironment* get_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { +#if GAUXC_HAS_DEVICE + void* ptr = env.device_ptr ? env.device_ptr : env.ptr; +#else + void* ptr = env.ptr; +#endif + return static_cast(ptr); +} +#ifdef GAUXC_HAS_DEVICE +static inline DeviceRuntimeEnvironment* get_device_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { + return static_cast(env.device_ptr); +} +#endif +} + +extern "C" { +namespace C { + +GauXCRuntimeEnvironment gauxc_runtime_environment_new( + GAUXC_MPI_CODE(MPI_Comm comm) +) { + GauXCRuntimeEnvironment env; + RuntimeEnvironment* env_ptr = new RuntimeEnvironment( GAUXC_MPI_CODE(comm) ); + env.ptr = env_ptr; +#ifdef GAUXC_HAS_DEVICE + DeviceRuntimeEnvironment* dev_env_ptr = env_ptr->as_device_runtime(); + env.device_ptr = dev_env_ptr; +#endif + return env; +} + +void gauxc_runtime_environment_delete(GauXCRuntimeEnvironment env) { + if(env.ptr != nullptr) + delete detail::get_runtime_environment_ptr(env); + env.ptr = nullptr; +#ifdef GAUXC_HAS_DEVICE + if(env.device_ptr != nullptr) + delete detail::get_device_runtime_environment_ptr(env); + env.device_ptr = nullptr; +#endif +} + +int gauxc_runtime_environment_comm_rank(GauXCRuntimeEnvironment env) { + return detail::get_runtime_environment_ptr(env)->comm_rank(); +} + +int gauxc_runtime_environment_comm_size(GauXCRuntimeEnvironment env) { + return detail::get_runtime_environment_ptr(env)->comm_size(); +} + +#ifdef GAUXC_HAS_DEVICE +GauXCRuntimeEnvironment gauxc_device_runtime_environment_new( + GAUXC_MPI_CODE(MPI_Comm comm), + double fill_fraction +) { + GauXCRuntimeEnvironment env; + DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( + GAUXC_MPI_CODE(comm), fill_fraction + ); + env.device_ptr = dev_env_ptr; + return env; +} + +GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( + GAUXC_MPI_CODE(MPI_Comm comm), + void* mem, + size_t mem_sz +) { + GauXCRuntimeEnvironment env; + DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( + GAUXC_MPI_CODE(comm), mem, mem_sz + ); + env.device_ptr = dev_env_ptr; + return env; +} +#endif + +} // namespace C +} // extern "C" +} // namespace GauXC \ No newline at end of file diff --git a/tests/moltypes_test.cxx b/tests/moltypes_test.cxx index 6855ff37..cf645779 100644 --- a/tests/moltypes_test.cxx +++ b/tests/moltypes_test.cxx @@ -42,6 +42,7 @@ TEST_CASE("Atom", "[moltypes]") { CHECK( atom.y == y ); CHECK( atom.z == z ); +#if GAUXC_HAS_C SECTION("C Interop") { C::GauXCAtom c_atom = { Z, x, y, z }; @@ -50,6 +51,7 @@ TEST_CASE("Atom", "[moltypes]") { CHECK( c_atom.y == atom.y ); CHECK( c_atom.z == atom.z ); } +#endif } TEST_CASE("Molecule", "[moltypes]") { @@ -67,12 +69,14 @@ TEST_CASE("Molecule", "[moltypes]") { CHECK(mol.natoms() == 0); } +#if GAUXC_HAS_C SECTION("Default C") { C::GauXCMolecule mol = C::gauxc_molecule_new(); CHECK(C::gauxc_molecule_natoms(mol) == 0); C::gauxc_molecule_delete(mol); } +#endif SECTION("From std::vector") { From 589bbc34e4ea5dcafd1801f61bef3bc3c40fbb7a Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Thu, 22 Jan 2026 10:06:59 +0100 Subject: [PATCH 04/15] Add load balancer to C API --- include/gauxc/basisset.h | 31 ++++++++ include/gauxc/load_balancer.h | 116 ++++++++++++++++++++++++++++ include/gauxc/molecule.h | 14 ++++ include/gauxc/molgrid.h | 9 +++ include/gauxc/runtime_environment.h | 19 +++++ src/CMakeLists.txt | 1 + src/c_basisset.cxx | 32 +------- src/c_load_balancer.cxx | 82 ++++++++++++++++++++ src/c_molecule.cxx | 20 +---- src/c_molgrid.cxx | 16 +--- src/c_runtime_environment.cxx | 22 +----- 11 files changed, 282 insertions(+), 80 deletions(-) create mode 100644 include/gauxc/load_balancer.h create mode 100644 src/c_load_balancer.cxx diff --git a/include/gauxc/basisset.h b/include/gauxc/basisset.h index 3e8e9eae..b8dc61a3 100644 --- a/include/gauxc/basisset.h +++ b/include/gauxc/basisset.h @@ -58,4 +58,35 @@ extern void gauxc_basisset_delete( GauXCBasisSet basis ); #ifdef __cplusplus } // namespace GauXC::C } // extern "C" +#endif + +#ifdef __cplusplus +#include +#include +namespace GauXC::detail { +static inline BasisSet* get_basisset_ptr(C::GauXCBasisSet basis) noexcept { + return static_cast*>(basis.ptr); +} +static inline Shell convert_shell(C::GauXCShell shell, bool normalize) noexcept { + Shell::prim_array alpha{}; + Shell::prim_array coeff{}; + Shell::cart_array O{0.0, 0.0, 0.0}; + + for( int32_t i = 0; i < shell.nprim; ++i ) { + alpha[i] = shell.exponents[i]; + coeff[i] = shell.coefficients[i]; + } + + Shell sh{ PrimSize{shell.nprim}, + AngularMomentum{shell.l}, + SphericalType{shell.pure}, + alpha, coeff, O, normalize }; + + if (shell.shell_tolerance >= 0.0) { + sh.set_shell_tolerance( shell.shell_tolerance ); + } + + return sh; +} +} // namespace GauXC::detail #endif \ No newline at end of file diff --git a/include/gauxc/load_balancer.h b/include/gauxc/load_balancer.h new file mode 100644 index 00000000..638fe289 --- /dev/null +++ b/include/gauxc/load_balancer.h @@ -0,0 +1,116 @@ +/** + * 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 + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +namespace GauXC::C { +#endif + +/** + * @brief GauXC C API LoadBalancer handle. + */ +typedef struct GauXCLoadBalancer { + void* ptr; ///< Pointer to the LoadBalancer instance. + bool owned; ///< Whether this instance owns the LoadBalancer. +} GauXCLoadBalancer; + +/** + * @brief Delete a LoadBalancer instance. + * @param lb Handle to the LoadBalancer to delete. + */ +extern void gauxc_load_balancer_delete( + GauXCLoadBalancer lb +); + +/** + * @brief GauXC C API LoadBalancerFactory handle. + */ +typedef struct GauXCLoadBalancerFactory { + void* ptr; ///< Pointer to the LoadBalancerFactory instance. +} GauXCLoadBalancerFactory; + +/** + * @brief Create a new LoadBalancerFactory instance. + * @param ex Execution space. + * @param kernel_name Name of the load balancing kernel to use. + * @return Handle to the created LoadBalancerFactory. + */ +extern GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( + enum GauXC_ExecutionSpace ex, + const char* kernel_name +); + +/** + * @brief Delete a LoadBalancerFactory instance. + * @param factory Handle to the LoadBalancerFactory to delete. + */ +extern void gauxc_load_balancer_factory_delete( + GauXCLoadBalancerFactory factory +); + +/** + * @brief Create a new LoadBalancer instance from a LoadBalancerFactory. + * @param factory Handle to the LoadBalancerFactory. + * @param env Handle to the RuntimeEnvironment. + * @param mol Handle to the Molecule. + * @param mg Handle to the MolGrid. + * @param basis Handle to the BasisSet. + * @return Handle to the created LoadBalancer. + */ +extern GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( + GauXCLoadBalancerFactory factory, + GauXCRuntimeEnvironment env, + GauXCMolecule mol, + GauXCMolGrid mg, + GauXCBasisSet basis +); + +/** + * @brief Create a new shared LoadBalancer instance from a LoadBalancerFactory. + * @param factory Handle to the LoadBalancerFactory. + * @param env Handle to the RuntimeEnvironment. + * @param mol Handle to the Molecule. + * @param mg Handle to the MolGrid. + * @param basis Handle to the BasisSet. + * @return Handle to the created LoadBalancer. + */ +extern GauXCLoadBalancer gauxc_load_balancer_factory_get_shared_instance( + GauXCLoadBalancerFactory factory, + GauXCRuntimeEnvironment env, + GauXCMolecule mol, + GauXCMolGrid mg, + GauXCBasisSet basis +); + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif + +#ifdef __cplusplus +#include +namespace GauXC::detail { +static inline LoadBalancer* get_load_balancer_ptr(C::GauXCLoadBalancer lb) noexcept { + return static_cast(lb.ptr); +} +static inline LoadBalancerFactory* get_load_balancer_factory_ptr(C::GauXCLoadBalancerFactory lbf) noexcept { + return static_cast(lbf.ptr); +} +} +#endif \ No newline at end of file diff --git a/include/gauxc/molecule.h b/include/gauxc/molecule.h index e3f4bc7c..a497d184 100644 --- a/include/gauxc/molecule.h +++ b/include/gauxc/molecule.h @@ -64,4 +64,18 @@ extern size_t gauxc_molecule_natoms( GauXCMolecule mol ); #ifdef __cplusplus } // namespace GauXC::C } // extern "C" +#endif + + +#ifdef __cplusplus +#include +namespace GauXC::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 }; +} +} #endif \ No newline at end of file diff --git a/include/gauxc/molgrid.h b/include/gauxc/molgrid.h index d2ffe929..644e2246 100644 --- a/include/gauxc/molgrid.h +++ b/include/gauxc/molgrid.h @@ -60,3 +60,12 @@ extern void gauxc_molgrid_delete( } // namespace GauXC::C } // extern "C" #endif + +#ifdef __cplusplus +#include +namespace GauXC::detail { +static inline MolGrid* get_molgrid_ptr(C::GauXCMolGrid molgrid) noexcept { + return static_cast(molgrid.ptr); +} +} +#endif \ No newline at end of file diff --git a/include/gauxc/runtime_environment.h b/include/gauxc/runtime_environment.h index 52366532..367ccef0 100644 --- a/include/gauxc/runtime_environment.h +++ b/include/gauxc/runtime_environment.h @@ -86,4 +86,23 @@ GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( #ifdef __cplusplus } // namespace GauXC::C } // extern "C" +#endif + +#ifdef __cplusplus +#include +namespace GauXC::detail { +static inline RuntimeEnvironment* get_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { +#if GAUXC_HAS_DEVICE + void* ptr = env.device_ptr ? env.device_ptr : env.ptr; +#else + void* ptr = env.ptr; +#endif + return static_cast(ptr); +} +#ifdef GAUXC_HAS_DEVICE +static inline DeviceRuntimeEnvironment* get_device_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { + return static_cast(env.device_ptr); +} +#endif +} // namespace GauXC::detail #endif \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0639d3fe..d67b82ab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,6 +49,7 @@ if( GAUXC_ENABLE_C ) c_basisset.cxx c_molgrid.cxx c_runtime_environment.cxx + c_load_balancer.cxx ) endif() diff --git a/src/c_basisset.cxx b/src/c_basisset.cxx index f596d696..925034e7 100644 --- a/src/c_basisset.cxx +++ b/src/c_basisset.cxx @@ -14,34 +14,7 @@ #include #include -namespace GauXC { -namespace detail { -static inline BasisSet* get_basisset_ptr(C::GauXCBasisSet basis) noexcept { - return static_cast*>(basis.ptr); -} -static inline Shell convert_shell(C::GauXCShell shell, bool normalize) noexcept { - Shell::prim_array alpha{}; - Shell::prim_array coeff{}; - Shell::cart_array O{0.0, 0.0, 0.0}; - - for( int32_t i = 0; i < shell.nprim; ++i ) { - alpha[i] = shell.exponents[i]; - coeff[i] = shell.coefficients[i]; - } - - Shell sh{ PrimSize{shell.nprim}, - AngularMomentum{shell.l}, - SphericalType{shell.pure}, - alpha, coeff, O, normalize }; - - if (shell.shell_tolerance >= 0.0) { - sh.set_shell_tolerance( shell.shell_tolerance ); - } - - return sh; -} -} // namespace detail -namespace C { +namespace GauXC::C { extern "C" { GauXCBasisSet gauxc_basisset_new() { @@ -68,5 +41,4 @@ void gauxc_basisset_delete(GauXCBasisSet basis) { } } // extern "C" -} // namespace C -} // namespace GauXC \ No newline at end of file +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_load_balancer.cxx b/src/c_load_balancer.cxx new file mode 100644 index 00000000..15ab4c36 --- /dev/null +++ b/src/c_load_balancer.cxx @@ -0,0 +1,82 @@ +/** + * 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 + +namespace GauXC::C { +extern "C" { + +void gauxc_load_balancer_delete( + GauXCLoadBalancer lb +) { + if(lb.ptr != nullptr && lb.owned) + delete detail::get_load_balancer_ptr(lb); + lb.ptr = nullptr; +} +GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( + enum GauXC_ExecutionSpace ex, + const char* kernel_name +) { + GauXCLoadBalancerFactory lbf; + LoadBalancerFactory* lbf_ptr = new LoadBalancerFactory( + static_cast(ex), + std::string(kernel_name) + ); + lbf.ptr = lbf_ptr; + return lbf; +} +void gauxc_load_balancer_factory_delete( + GauXCLoadBalancerFactory lbf +) { + if(lbf.ptr != nullptr) + delete detail::get_load_balancer_factory_ptr(lbf); + lbf.ptr = nullptr; +} +GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( + GauXCLoadBalancerFactory lbf, + GauXCRuntimeEnvironment rt, + GauXCMolecule mol, + GauXCMolGrid mg, + GauXCBasisSet bs +) { + LoadBalancer lb_instance = detail::get_load_balancer_factory_ptr(lbf)->get_instance( + *detail::get_runtime_environment_ptr(rt), + *detail::get_molecule_ptr(mol), + *detail::get_molgrid_ptr(mg), + *detail::get_basisset_ptr(bs) + ); + GauXCLoadBalancer lb; + lb.ptr = new LoadBalancer( std::move(lb_instance) ); + lb.owned = true; + return lb; +} +GauXCLoadBalancer gauxc_load_balancer_delete_factory_get_shared_instance( + GauXCLoadBalancerFactory lbf, + GauXCRuntimeEnvironment rt, + GauXCMolecule mol, + GauXCMolGrid mg, + GauXCBasisSet bs +) { + auto lb_instance_ptr = detail::get_load_balancer_factory_ptr(lbf)->get_shared_instance( + *detail::get_runtime_environment_ptr(rt), + *detail::get_molecule_ptr(mol), + *detail::get_molgrid_ptr(mg), + *detail::get_basisset_ptr(bs) + ); + GauXCLoadBalancer lb; + lb.ptr = new std::shared_ptr( std::move(lb_instance_ptr) ); + lb.owned = false; + return lb; +} + +} // extern "C" +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_molecule.cxx b/src/c_molecule.cxx index de4e9e94..4eb21754 100644 --- a/src/c_molecule.cxx +++ b/src/c_molecule.cxx @@ -14,22 +14,9 @@ #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 }; -} - -} +namespace GauXC::C { extern "C" { -namespace C { GauXCMolecule gauxc_molecule_new() { GauXCMolecule mol; @@ -59,6 +46,5 @@ size_t gauxc_molecule_natoms(GauXCMolecule mol) { return detail::get_molecule_ptr(mol)->natoms(); } -} -} -} // namespace GauXC \ No newline at end of file +} // extern "C" +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_molgrid.cxx b/src/c_molgrid.cxx index 8efa3b5f..4b779328 100644 --- a/src/c_molgrid.cxx +++ b/src/c_molgrid.cxx @@ -15,18 +15,9 @@ #include #include -namespace GauXC { -namespace detail { -static inline Molecule* get_molecule_ptr(C::GauXCMolecule mol) noexcept { - return static_cast(mol.ptr); -} -static inline MolGrid* get_molgrid_ptr(C::GauXCMolGrid molgrid) noexcept { - return static_cast(molgrid.ptr); -} -} // namespace detail - +namespace GauXC::C { extern "C" { -namespace C { + GauXCMolGrid gauxc_molgrid_new_default( GauXCMolecule mol, enum GauXC_PruningScheme pruning_scheme, @@ -53,6 +44,5 @@ void gauxc_molgrid_delete(GauXCMolGrid mg) { mg.ptr = nullptr; } -} // namespace C } // extern "C" -} // namespace GauXC \ No newline at end of file +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx index 26bf29b4..caa0afe5 100644 --- a/src/c_runtime_environment.cxx +++ b/src/c_runtime_environment.cxx @@ -12,25 +12,8 @@ #include #include -namespace GauXC { -namespace detail { -static inline RuntimeEnvironment* get_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { -#if GAUXC_HAS_DEVICE - void* ptr = env.device_ptr ? env.device_ptr : env.ptr; -#else - void* ptr = env.ptr; -#endif - return static_cast(ptr); -} -#ifdef GAUXC_HAS_DEVICE -static inline DeviceRuntimeEnvironment* get_device_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { - return static_cast(env.device_ptr); -} -#endif -} - +namespace GauXC::C { extern "C" { -namespace C { GauXCRuntimeEnvironment gauxc_runtime_environment_new( GAUXC_MPI_CODE(MPI_Comm comm) @@ -91,6 +74,5 @@ GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( } #endif -} // namespace C } // extern "C" -} // namespace GauXC \ No newline at end of file +} // namespace GauXC::C \ No newline at end of file From 2e3b64856b401f04ae193308db507903b474c811 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Thu, 22 Jan 2026 13:25:44 +0100 Subject: [PATCH 05/15] Minor fixes --- src/CMakeLists.txt | 2 +- src/c_runtime_environment.cxx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d67b82ab..764515d1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -206,7 +206,7 @@ install( # Install generated headers install( - FILES ${PROJECT_BINARY_DIR}/include/gauxc/gauxc_config.hpp + FILES ${PROJECT_BINARY_DIR}/include/gauxc/gauxc_config.h DESTINATION include/gauxc ) diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx index caa0afe5..22607373 100644 --- a/src/c_runtime_environment.cxx +++ b/src/c_runtime_environment.cxx @@ -49,25 +49,25 @@ int gauxc_runtime_environment_comm_size(GauXCRuntimeEnvironment env) { #ifdef GAUXC_HAS_DEVICE GauXCRuntimeEnvironment gauxc_device_runtime_environment_new( - GAUXC_MPI_CODE(MPI_Comm comm), + GAUXC_MPI_CODE(MPI_Comm comm,) double fill_fraction ) { GauXCRuntimeEnvironment env; DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( - GAUXC_MPI_CODE(comm), fill_fraction + GAUXC_MPI_CODE(comm,) fill_fraction ); env.device_ptr = dev_env_ptr; return env; } GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( - GAUXC_MPI_CODE(MPI_Comm comm), + GAUXC_MPI_CODE(MPI_Comm comm,) void* mem, size_t mem_sz ) { GauXCRuntimeEnvironment env; DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( - GAUXC_MPI_CODE(comm), mem, mem_sz + GAUXC_MPI_CODE(comm,) mem, mem_sz ); env.device_ptr = dev_env_ptr; return env; From af41f32ce1a0a16de06c46d83ba8922570b2b778 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Thu, 22 Jan 2026 13:51:04 +0100 Subject: [PATCH 06/15] Add molecular weights for C API --- include/gauxc/basisset.h | 31 ------ include/gauxc/load_balancer.h | 12 --- include/gauxc/molecular_weights.h | 102 +++++++++++++++++++ include/gauxc/molecule.h | 14 --- include/gauxc/molgrid.h | 9 -- include/gauxc/runtime_environment.h | 19 ---- include/gauxc/util/c_basisset.hpp | 44 ++++++++ include/gauxc/util/c_load_balancer.hpp | 24 +++++ include/gauxc/util/c_molecular_weights.hpp | 31 ++++++ include/gauxc/util/c_molecule.hpp | 24 +++++ include/gauxc/util/c_molgrid.hpp | 21 ++++ include/gauxc/util/c_runtime_environment.hpp | 31 ++++++ src/CMakeLists.txt | 1 + src/c_basisset.cxx | 1 + src/c_load_balancer.cxx | 5 + src/c_molecular_weights.cxx | 53 ++++++++++ src/c_molecule.cxx | 1 + src/c_molgrid.cxx | 2 + src/c_runtime_environment.cxx | 1 + 19 files changed, 341 insertions(+), 85 deletions(-) create mode 100644 include/gauxc/molecular_weights.h create mode 100644 include/gauxc/util/c_basisset.hpp create mode 100644 include/gauxc/util/c_load_balancer.hpp create mode 100644 include/gauxc/util/c_molecular_weights.hpp create mode 100644 include/gauxc/util/c_molecule.hpp create mode 100644 include/gauxc/util/c_molgrid.hpp create mode 100644 include/gauxc/util/c_runtime_environment.hpp create mode 100644 src/c_molecular_weights.cxx diff --git a/include/gauxc/basisset.h b/include/gauxc/basisset.h index b8dc61a3..3e8e9eae 100644 --- a/include/gauxc/basisset.h +++ b/include/gauxc/basisset.h @@ -58,35 +58,4 @@ extern void gauxc_basisset_delete( GauXCBasisSet basis ); #ifdef __cplusplus } // namespace GauXC::C } // extern "C" -#endif - -#ifdef __cplusplus -#include -#include -namespace GauXC::detail { -static inline BasisSet* get_basisset_ptr(C::GauXCBasisSet basis) noexcept { - return static_cast*>(basis.ptr); -} -static inline Shell convert_shell(C::GauXCShell shell, bool normalize) noexcept { - Shell::prim_array alpha{}; - Shell::prim_array coeff{}; - Shell::cart_array O{0.0, 0.0, 0.0}; - - for( int32_t i = 0; i < shell.nprim; ++i ) { - alpha[i] = shell.exponents[i]; - coeff[i] = shell.coefficients[i]; - } - - Shell sh{ PrimSize{shell.nprim}, - AngularMomentum{shell.l}, - SphericalType{shell.pure}, - alpha, coeff, O, normalize }; - - if (shell.shell_tolerance >= 0.0) { - sh.set_shell_tolerance( shell.shell_tolerance ); - } - - return sh; -} -} // namespace GauXC::detail #endif \ No newline at end of file diff --git a/include/gauxc/load_balancer.h b/include/gauxc/load_balancer.h index 638fe289..9e9bdb53 100644 --- a/include/gauxc/load_balancer.h +++ b/include/gauxc/load_balancer.h @@ -101,16 +101,4 @@ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_shared_instance( #ifdef __cplusplus } // namespace GauXC::C } // extern "C" -#endif - -#ifdef __cplusplus -#include -namespace GauXC::detail { -static inline LoadBalancer* get_load_balancer_ptr(C::GauXCLoadBalancer lb) noexcept { - return static_cast(lb.ptr); -} -static inline LoadBalancerFactory* get_load_balancer_factory_ptr(C::GauXCLoadBalancerFactory lbf) noexcept { - return static_cast(lbf.ptr); -} -} #endif \ No newline at end of file diff --git a/include/gauxc/molecular_weights.h b/include/gauxc/molecular_weights.h new file mode 100644 index 00000000..12a5ae96 --- /dev/null +++ b/include/gauxc/molecular_weights.h @@ -0,0 +1,102 @@ +/** + * 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 +#else +#include +#include +#endif +#include + +#ifdef __cplusplus +namespace GauXC::C { +extern "C" { +#endif + +/** + * @brief GauXC C API MolecularWeightsSettings representation. + */ +typedef struct GauXCMolecularWeightsSettings { + enum GauXC_XCWeightAlg weight_alg; ///< Weight partitioning scheme + bool becke_size_adjustment; ///< Whether to use Becke size adjustments +} GauXCMolecularWeightsSettings; + +/** + * @brief GauXC C API MolecularWeights handle. + */ +typedef struct GauXCMolecularWeights { + void* ptr; ///< Pointer to the MolecularWeights instance. + bool owned; ///< Whether this instance owns the MolecularWeights. +} GauXCMolecularWeights; + +/** + * @brief Delete a MolecularWeights instance. + */ +extern void gauxc_molecular_weights_delete( + GauXCMolecularWeights mw +); + +/** + * @brief GauXC C API MolecularWeightsFactory handle. + */ +typedef struct GauXCMolecularWeightsFactory { + void* ptr; ///< Pointer to the MolecularWeightsFactory instance. +} GauXCMolecularWeightsFactory; + +/** + * @brief Create a new MolecularWeightsFactory instance. + * @param ex Execution space. + * @param local_work_kernel_name Name of the LocalWorkDriver kernel to use. + * @param settings Settings for the MolecularWeights calculation. + * @return Handle to the created MolecularWeightsFactory. + */ +extern GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( + enum GauXC_ExecutionSpace ex, + const char* local_work_kernel_name, + GauXCMolecularWeightsSettings settings +); + +/** + * @brief Delete a MolecularWeightsFactory instance. + * @param factory Handle to the MolecularWeightsFactory to delete. + */ +extern void gauxc_molecular_weights_factory_delete( + GauXCMolecularWeightsFactory factory +); + +/** + * @brief Get MolecularWeights instance from a MolecularWeightsFactory. + * @param factory Handle to the MolecularWeightsFactory. + * @return Handle to the created MolecularWeights. + */ +extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( + GauXCMolecularWeightsFactory factory +); + +/** + * @brief Get shared MolecularWeights instance from a MolecularWeightsFactory. + * @param factory Handle to the MolecularWeightsFactory. + * @return Handle to the created MolecularWeights. + */ +extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_shared_instance( + GauXCMolecularWeightsFactory factory +); + + + +#ifdef __cplusplus +} // extern "C" +} // namespace GauXC::C +#endif \ No newline at end of file diff --git a/include/gauxc/molecule.h b/include/gauxc/molecule.h index a497d184..e3f4bc7c 100644 --- a/include/gauxc/molecule.h +++ b/include/gauxc/molecule.h @@ -64,18 +64,4 @@ extern size_t gauxc_molecule_natoms( GauXCMolecule mol ); #ifdef __cplusplus } // namespace GauXC::C } // extern "C" -#endif - - -#ifdef __cplusplus -#include -namespace GauXC::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 }; -} -} #endif \ No newline at end of file diff --git a/include/gauxc/molgrid.h b/include/gauxc/molgrid.h index 644e2246..89d1fc0f 100644 --- a/include/gauxc/molgrid.h +++ b/include/gauxc/molgrid.h @@ -59,13 +59,4 @@ extern void gauxc_molgrid_delete( #ifdef __cplusplus } // namespace GauXC::C } // extern "C" -#endif - -#ifdef __cplusplus -#include -namespace GauXC::detail { -static inline MolGrid* get_molgrid_ptr(C::GauXCMolGrid molgrid) noexcept { - return static_cast(molgrid.ptr); -} -} #endif \ No newline at end of file diff --git a/include/gauxc/runtime_environment.h b/include/gauxc/runtime_environment.h index 367ccef0..52366532 100644 --- a/include/gauxc/runtime_environment.h +++ b/include/gauxc/runtime_environment.h @@ -86,23 +86,4 @@ GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( #ifdef __cplusplus } // namespace GauXC::C } // extern "C" -#endif - -#ifdef __cplusplus -#include -namespace GauXC::detail { -static inline RuntimeEnvironment* get_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { -#if GAUXC_HAS_DEVICE - void* ptr = env.device_ptr ? env.device_ptr : env.ptr; -#else - void* ptr = env.ptr; -#endif - return static_cast(ptr); -} -#ifdef GAUXC_HAS_DEVICE -static inline DeviceRuntimeEnvironment* get_device_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { - return static_cast(env.device_ptr); -} -#endif -} // namespace GauXC::detail #endif \ No newline at end of file diff --git a/include/gauxc/util/c_basisset.hpp b/include/gauxc/util/c_basisset.hpp new file mode 100644 index 00000000..8fb421fa --- /dev/null +++ b/include/gauxc/util/c_basisset.hpp @@ -0,0 +1,44 @@ +/** + * 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 + +#include +#include +#include +#include + +namespace GauXC::detail { +static inline BasisSet* get_basisset_ptr(C::GauXCBasisSet basis) noexcept { + return static_cast*>(basis.ptr); +} +static inline Shell convert_shell(C::GauXCShell shell, bool normalize) noexcept { + Shell::prim_array alpha{}; + Shell::prim_array coeff{}; + Shell::cart_array O{0.0, 0.0, 0.0}; + + for( int32_t i = 0; i < shell.nprim; ++i ) { + alpha[i] = shell.exponents[i]; + coeff[i] = shell.coefficients[i]; + } + + Shell sh{ PrimSize{shell.nprim}, + AngularMomentum{shell.l}, + SphericalType{shell.pure}, + alpha, coeff, O, normalize }; + + if (shell.shell_tolerance >= 0.0) { + sh.set_shell_tolerance( shell.shell_tolerance ); + } + + return sh; +} +} // namespace GauXC::detail \ No newline at end of file diff --git a/include/gauxc/util/c_load_balancer.hpp b/include/gauxc/util/c_load_balancer.hpp new file mode 100644 index 00000000..ee340456 --- /dev/null +++ b/include/gauxc/util/c_load_balancer.hpp @@ -0,0 +1,24 @@ +/** + * 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 + +#include +#include + +namespace GauXC::detail { +static inline LoadBalancer* get_load_balancer_ptr(C::GauXCLoadBalancer lb) noexcept { + return static_cast(lb.ptr); +} +static inline LoadBalancerFactory* get_load_balancer_factory_ptr(C::GauXCLoadBalancerFactory lbf) noexcept { + return static_cast(lbf.ptr); +} +} \ No newline at end of file diff --git a/include/gauxc/util/c_molecular_weights.hpp b/include/gauxc/util/c_molecular_weights.hpp new file mode 100644 index 00000000..490c4ec7 --- /dev/null +++ b/include/gauxc/util/c_molecular_weights.hpp @@ -0,0 +1,31 @@ +/** + * 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 + +#include +#include + +namespace GauXC::detail { +static inline MolecularWeights get_molecular_weights_ptr(C::GauXCMolecularWeights mw) noexcept { + return *static_cast(mw.ptr); +} +static inline MolecularWeightsFactory get_molecular_weights_factory_ptr(C::GauXCMolecularWeightsFactory mwf) noexcept { + return *static_cast(mwf.ptr); +} +static inline MolecularWeightsSettings +convert_molecular_weights_settings( const GauXC::C::GauXCMolecularWeightsSettings& c_settings ) { + MolecularWeightsSettings settings; + settings.weight_alg = static_cast( c_settings.weight_alg ); + settings.becke_size_adjustment = c_settings.becke_size_adjustment; + return settings; +} +} \ No newline at end of file diff --git a/include/gauxc/util/c_molecule.hpp b/include/gauxc/util/c_molecule.hpp new file mode 100644 index 00000000..60794335 --- /dev/null +++ b/include/gauxc/util/c_molecule.hpp @@ -0,0 +1,24 @@ +/** + * 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 +#include +#include + +namespace GauXC::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 }; +} +} \ No newline at end of file diff --git a/include/gauxc/util/c_molgrid.hpp b/include/gauxc/util/c_molgrid.hpp new file mode 100644 index 00000000..402f30f4 --- /dev/null +++ b/include/gauxc/util/c_molgrid.hpp @@ -0,0 +1,21 @@ +/** + * 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 + +#include +#include + +namespace GauXC::detail { +static inline MolGrid* get_molgrid_ptr(C::GauXCMolGrid molgrid) noexcept { + return static_cast(molgrid.ptr); +} +} \ No newline at end of file diff --git a/include/gauxc/util/c_runtime_environment.hpp b/include/gauxc/util/c_runtime_environment.hpp new file mode 100644 index 00000000..9305edba --- /dev/null +++ b/include/gauxc/util/c_runtime_environment.hpp @@ -0,0 +1,31 @@ +/** + * 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 + +#include +#include + +namespace GauXC::detail { +static inline RuntimeEnvironment* get_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { +#ifdef GAUXC_HAS_DEVICE + void* ptr = env.device_ptr ? env.device_ptr : env.ptr; +#else + void* ptr = env.ptr; +#endif + return static_cast(ptr); +} +#ifdef GAUXC_HAS_DEVICE +static inline DeviceRuntimeEnvironment* get_device_runtime_environment_ptr(C::GauXCRuntimeEnvironment env) noexcept { + return static_cast(env.device_ptr); +} +#endif +} // namespace GauXC::detail \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 764515d1..68c022d5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -50,6 +50,7 @@ if( GAUXC_ENABLE_C ) c_molgrid.cxx c_runtime_environment.cxx c_load_balancer.cxx + c_molecular_weights.cxx ) endif() diff --git a/src/c_basisset.cxx b/src/c_basisset.cxx index 925034e7..cb1be3fa 100644 --- a/src/c_basisset.cxx +++ b/src/c_basisset.cxx @@ -13,6 +13,7 @@ #include #include #include +#include namespace GauXC::C { extern "C" { diff --git a/src/c_load_balancer.cxx b/src/c_load_balancer.cxx index 15ab4c36..3b3d8520 100644 --- a/src/c_load_balancer.cxx +++ b/src/c_load_balancer.cxx @@ -11,6 +11,11 @@ */ #include #include +#include +#include +#include +#include +#include namespace GauXC::C { extern "C" { diff --git a/src/c_molecular_weights.cxx b/src/c_molecular_weights.cxx new file mode 100644 index 00000000..c80c6b62 --- /dev/null +++ b/src/c_molecular_weights.cxx @@ -0,0 +1,53 @@ +/** + * 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 + +namespace GauXC::C { +extern "C" { +GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( + enum GauXC_ExecutionSpace ex, + const char* kernel_name, + GauXCMolecularWeightsSettings settings +) { + GauXCMolecularWeightsFactory mwf; + MolecularWeightsFactory* mwf_ptr = new MolecularWeightsFactory( + static_cast(ex), + std::string(kernel_name), + detail::convert_molecular_weights_settings( settings ) + ); + mwf.ptr = mwf_ptr; + return mwf; +} + +GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( + GauXCMolecularWeightsFactory mwf +) { + MolecularWeights mw_instance = detail::get_molecular_weights_factory_ptr(mwf)->get_instance(); + GauXCMolecularWeights mw; + mw.ptr = new MolecularWeights( std::move(mw_instance) ); + mw.owned = true; + return mw; +} + + +void gauxc_molecular_weights_factory_delete( + GauXCMolecularWeightsFactory mwf +) { + if(mwf.ptr != nullptr) + delete detail::get_molecular_weights_factory_ptr(mwf); + mwf.ptr = nullptr; +} + +} // extern "C" +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_molecule.cxx b/src/c_molecule.cxx index 4eb21754..8493a85d 100644 --- a/src/c_molecule.cxx +++ b/src/c_molecule.cxx @@ -13,6 +13,7 @@ #include #include #include +#include namespace GauXC::C { diff --git a/src/c_molgrid.cxx b/src/c_molgrid.cxx index 4b779328..9ada54df 100644 --- a/src/c_molgrid.cxx +++ b/src/c_molgrid.cxx @@ -14,6 +14,8 @@ #include #include #include +#include +#include namespace GauXC::C { extern "C" { diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx index 22607373..fd101280 100644 --- a/src/c_runtime_environment.cxx +++ b/src/c_runtime_environment.cxx @@ -11,6 +11,7 @@ */ #include #include +#include namespace GauXC::C { extern "C" { From c1649981af854999f6bbfa70dae97fef97aab6b3 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Fri, 23 Jan 2026 23:36:24 +0100 Subject: [PATCH 07/15] Add xc integrator and matrix type --- include/gauxc/functional.h | 366 +++++++++++++++++++++ include/gauxc/matrix.h | 56 ++++ include/gauxc/util/c_matrix.hpp | 26 ++ include/gauxc/util/c_molecular_weights.hpp | 8 +- include/gauxc/util/c_molecule.hpp | 3 +- include/gauxc/util/c_xc_integrator.hpp | 29 ++ include/gauxc/xc_integrator.h | 247 ++++++++++++++ src/c_matrix.cxx | 36 ++ src/c_xc_integrator.cxx | 88 +++++ 9 files changed, 853 insertions(+), 6 deletions(-) create mode 100644 include/gauxc/functional.h create mode 100644 include/gauxc/matrix.h create mode 100644 include/gauxc/util/c_matrix.hpp create mode 100644 include/gauxc/util/c_xc_integrator.hpp create mode 100644 include/gauxc/xc_integrator.h create mode 100644 src/c_matrix.cxx create mode 100644 src/c_xc_integrator.cxx diff --git a/include/gauxc/functional.h b/include/gauxc/functional.h new file mode 100644 index 00000000..ecf63711 --- /dev/null +++ b/include/gauxc/functional.h @@ -0,0 +1,366 @@ +/** + * 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 +namespace GauXC::C { +extern "C" { +#endif + +enum GauXC_Functional { + /// @brief Slater exchange & Vosko, Wilk & Nusair correlation (VWN3) + /// - P. A. M. Dirac., Math. Proc. Cambridge Philos. Soc. 26, 376 (1930) (doi: 10.1017/S0305004100016108) + /// - F. Bloch., Z. Phys. 57, 545 (1929) (doi: 10.1007/BF01340281) + /// - S. H. Vosko, L. Wilk, and M. Nusair., Can. J. Phys. 58, 1200 (1980) (doi: 10.1139/p80-159) + /// - libxc names: LDA_X (id=1) and LDA_C_VWN_3 (id=30) + GauXC_Functional_SVWN3, + + /// @brief Slater exchange & Vosko, Wilk & Nusair correlation (VWN5) + /// - P. A. M. Dirac., Math. Proc. Cambridge Philos. Soc. 26, 376 (1930) (doi: 10.1017/S0305004100016108) + /// - F. Bloch., Z. Phys. 57, 545 (1929) (doi: 10.1007/BF01340281) + /// - S. H. Vosko, L. Wilk, and M. Nusair., Can. J. Phys. 58, 1200 (1980) (doi: 10.1139/p80-159) + /// - libxc names: LDA_X (id=1) and LDA_C_VWN (id=7) + /// - xcfun names: SLATERX and VWN5C + GauXC_Functional_SVWN5, + + /// @brief Becke 88 exchange & Lee, Yang & Parr correlation + /// - A. D. Becke., Phys. Rev. A 38, 3098 (1988) (doi: 10.1103/PhysRevA.38.3098) + /// - C. Lee, W. Yang, and R. G. Parr., Phys. Rev. B 37, 785 (1988) (doi: 10.1103/PhysRevB.37.785) + /// - B. Miehlich, A. Savin, H. Stoll, and H. Preuss., Chem. Phys. Lett. 157, 200 (1989) (doi: 10.1016/0009-2614(89)87234-3) + /// - libxc names: GGA_X_B88 (id=106) and GGA_C_LYP (id=131) + /// - xcfun names: BECKEX and LYPC + GauXC_Functional_BLYP, + + /// @brief Becke 88 exchange & Lee, Yang & Parr correlation, 3-parameter hybrid + /// - P. J. Stephens, F. J. Devlin, C. F. Chabalowski, and M. J. Frisch., J. Phys. Chem. 98, 11623 (1994) (doi: 10.1021/j100096a001) + /// - libxc name: HYB_GGA_XC_B3LYP (id=402) + GauXC_Functional_B3LYP, + + /// @brief Perdew-Burke-Ernzerhof exchange & correlation + /// J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc names: GGA_X_PBE (id=101) & GGA_C_PBE (id=130) + /// - xcfun names: PBEEX and PBEC + GauXC_Functional_PBE, + + /// @brief revised Perdew-Burke-Ernzerhof exchange & correlation + GauXC_Functional_revPBE, + + /// @brief Perdew-Burke-Ernzerhof exchange & correlation, 1-parameter hybrid + /// - C. Adamo and V. Barone., J. Chem. Phys. 110, 6158 (1999) (doi: 10.1063/1.478522) + /// - M. Ernzerhof and G. E. Scuseria., J. Chem. Phys. 110, 5029 (1999) (doi: 10.1063/1.478401) + /// - libxc name: HYB_GGA_XC_PBEH (id=406) + GauXC_Functional_PBE0, + + /// @brief Strongly constrained and appropriately normed (SCAN) meta-GGA + /// - J. Sun, A. Ruzsinszky, and J. P. Perdew., Phys. Rev. Lett. 115, 036402 (2015) (doi: 10.1103/PhysRevLett.115.036402) + /// - libxc names: MGGA_X_SCAN (id=263) & MGGA_C_SCAN (id=267) + GauXC_Functional_SCAN, + + /// @brief Regularized & restored strongly constrained and appropriately normed (R2SCAN) meta-GGA + /// - J. W. Furness, A. D. Kaplan, J. Ning, J. P. Perdew, and J. Sun., J. Phys. Chem. Lett. 11, 8208-8215 (2020) (doi: 10.1021/acs.jpclett.0c02405) + /// - J. W. Furness, A. D. Kaplan, J. Ning, J. P. Perdew, and J. Sun., J. Phys. Chem. Lett. 11, 9248-9248 (2020) (doi: 10.1021/acs.jpclett.0c03077) + /// - libxc names: MGGA_X_R2SCAN (id=497) & MGGA_C_R2SCAN (id=498) + GauXC_Functional_R2SCAN, + + /// @brief Regularized & restored strongly constrained and appropriately normed (R2SCAN) meta-GGA, deorbitalized version + /// - D. Mejía-Rodríguez and S. B. Trickey., Phys. Rev. B 102, 121109 (2020) (doi: 10.1103/PhysRevB.102.121109) + /// - J. W. Furness, A. D. Kaplan, J. Ning, J. P. Perdew, and J. Sun., J. Phys. Chem. Lett. 11, 8208-8215 (2020) (doi: 10.1021/acs.jpclett.0c02405) + /// - J. W. Furness, A. D. Kaplan, J. Ning, J. P. Perdew, and J. Sun., J. Phys. Chem. Lett. 11, 9248-9248 (2020) (doi: 10.1021/acs.jpclett.0c03077) + /// - libxc names: MGGA_X_R2SCANL (id=718) & MGGA_C_R2SCANL (id=719) + GauXC_Functional_R2SCANL, + + /// @brief Minnesota 2006 hybrid functional + /// - Y. Zhao and D. G. Truhlar., Theor. Chem. Acc. 120, 215 (2008) (doi: 10.1007/s00214-007-0310-x) + /// - libxc names: HYB_MGGA_X_M06_2X (id=450) & MGGA_C_M06_2X (id=236) + /// - xcfun names: M062X and M062C + GauXC_Functional_M062X, + + /// @brief Perdew, Kurth, Zupan, and Blaha + /// - J. P. Perdew, S. Kurth, A. Zupan, and P. Blaha., Phys. Rev. Lett. 82, 2544 (1999) (doi: 10.1103/PhysRevLett.82.2544) + /// - libxc names: MGGA_X_PKZB (id=213) & MGGA_C_PKZB (id=239) + GauXC_Functional_PKZB, + + /// @brief epc17(-1): electron-proton correlation 2017 + /// - Y. Yang, K. R. Brorsen, T. Culpitt, M. V. Pak, and S. Hammes-Schiffer., J. Chem. Phys. 147, 114113 (2017) (doi: 10.1063/1.4996038) + /// - libxc name: LDA_C_EPC17 (id=328) + GauXC_Functional_EPC17_1, + + /// @brief epc17-2: electron-proton correlation 2017 for proton affinities + /// - K. R. Brorsen, Y. Yang, and S. Hammes-Schiffer., J. Phys. Chem. Lett. 8, 3488-3493 (2017) (doi: 10.1021/acs.jpclett.7b01442) + /// - libxc name: LDA_C_EPC17_2 (id=329) + GauXC_Functional_EPC17_2, + + /// @brief epc18-1: electron-proton correlation 2018 + /// - K. R. Brorsen, P. E. Schneider, and S. Hammes-Schiffer., J. Chem. Phys. 149, 044110 (2018) (doi: 10.1063/1.5037945) + /// - libxc name: LDA_C_EPC18_1 (id=330) + GauXC_Functional_EPC18_1, + + /// @brief epc18-2: electron-proton correlation 2018 for proton affinities + /// - K. R. Brorsen, P. E. Schneider, and S. Hammes-Schiffer., J. Chem. Phys. 149, 044110 (2018) (doi: 10.1063/1.5037945) + /// - libxc name: LDA_C_EPC18_2 (id=331) + GauXC_Functional_EPC18_2, + + /// @brief Grimme's parametrization of the B97 functional + /// - S. Grimme., J. Comput. Chem. 27, 1787 (2006) (doi: 10.1002/jcc.20495) + /// - libxc name: GGA_XC_B97_D (id=170) + GauXC_Functional_B97D, + + /// @brief + GauXC_Functional_B97D3ZERO, + + /// @brief Coulomb-attenuating method range-separated hybrid functional + /// - T. Yanai, D. P. Tew, and N. C. Handy., Chem. Phys. Lett. 393, 51 (2004) (doi: 10.1016/j.cplett.2004.06.011) + /// - libxc name: HYB_GGA_XC_CAM_B3LYP (id=433) + GauXC_Functional_CAMB3LYP, + + /// @brief Slater exchange + /// - P. A. M. Dirac., Math. Proc. Cambridge Philos. Soc. 26, 376 (1930) (doi: 10.1017/S0305004100016108) + /// - F. Bloch., Z. Phys. 57, 545 (1929) (doi: 10.1007/BF01340281) + /// - libxc name: LDA_X (id=1) + /// - xcfun name: SLATERX + GauXC_Functional_LDA, + + /// @brief Minnesota 2006 meta-GGA functional + /// - Y. Zhao and D. G. Truhlar., J. Chem. Phys. 125, 194101 (2006) (doi: 10.1063/1.2370993) + /// - Y. Zhao and D. G. Truhlar., Theor. Chem. Acc. 120, 215 (2008) (doi: 10.1007/s00214-007-0310-x) + /// - libxc names: MGGA_X_M06_L (id=203) & MGGA_C_M06_L (id=233) + GauXC_Functional_M06L, + + /// @brief Strongly constrained and appropriately normed (SCAN) meta-GGA, 1-parameter hybrid + /// - K. Hui and J.-D. Chai., J. Chem. Phys. 144, 044114 (2016) (doi: 10.1063/1.4940734) + /// - J. Sun, A. Ruzsinszky, and J. P. Perdew., Phys. Rev. Lett. 115, 036402 (2015) (doi: 10.1103/PhysRevLett.115.036402) + /// - libxc names: HYB_MGGA_X_SCAN0 (id=264) & MGGA_C_SCAN (id=267) + GauXC_Functional_SCAN0, + + /// @brief Slater exchange & Perdew, Wang 92 correlation + /// - P. A. M. Dirac., Math. Proc. Cambridge Philos. Soc. 26, 376 (1930) (doi: 10.1017/S0305004100016108) + /// - F. Bloch., Z. Phys. 57, 545 (1929) (doi: 10.1007/BF01340281) + /// - libxc names: LDA_X (id=1) and + GauXC_Functional_SPW92, + + /// @brief Tao, Perdew, Staroverov & Scuseria meta-GGA + /// - J. Tao, J. P. Perdew, V. N. Staroverov, and G. E. Scuseria., Phys. Rev. Lett. 91, 146401 (2003) (doi: 10.1103/PhysRevLett.91.146401) + /// - J. P. Perdew, J. Tao, V. N. Staroverov, and G. E. Scuseria., J. Chem. Phys. 120, 6898 (2004) (doi: 10.1063/1.1665298) + /// - libxc names: MGGA_X_TPSS (id=202) and MGGA_C_TPSS (id=231) + GauXC_Functional_TPSS, + + /// @brief Tao, Perdew, Staroverov & Scuseria meta-GGA, 1-parameter hybrid + /// - V. N. Staroverov, G. E. Scuseria, J. Tao, and J. P. Perdew., J. Chem. Phys. 119, 12129 (2003) (doi: 10.1063/1.1626543) + /// - libxc name: HYB_MGGA_XC_TPSSH (id=457) + GauXC_Functional_TPSSh, + + /// @brief Tao, Perdew, Staroverov & Scuseria meta-GGA, 1-parameter hybrid + /// - S. Grimme., J. Phys. Chem. A 109, 3067-3077 (2005) (doi: 10.1021/jp050036j) + /// - libxc name: HYB_MGGA_XC_TPSS0 (id=396) + GauXC_Functional_TPSS0, + + /// @brief Vosko, Wilk & Nusair correlation (VWN3) + /// - S. H. Vosko, L. Wilk, and M. Nusair., Can. J. Phys. 58, 1200 (1980) (doi: 10.1139/p80-159) + /// - libxc name: LDA_C_VWN_3 (id=30) + GauXC_Functional_VWN3, + + /// @brief Vosko, Wilk & Nusair correlation (VWN5) + /// - S. H. Vosko, L. Wilk, and M. Nusair., Can. J. Phys. 58, 1200 (1980) (doi: 10.1139/p80-159) + /// - libxc name: LDA_C_VWN (id=7) + GauXC_Functional_VWN5, + + /// @brief + GauXC_Functional_LRCwPBE, + + /// @brief + GauXC_Functional_LRCwPBEh, + + /// @brief + GauXC_Functional_BP86, + + /// @brief Heyd-Scuseria-Ernzerhof screened hybrid functional (HSE03) + /// - J. Heyd, G. E. Scuseria, and M. Ernzerhof., J. Chem. Phys. 118, 8207 (2003) (doi: 10.1063/1.1564060) + /// - J. Heyd, G. E. Scuseria, and M. Ernzerhof., J. Chem. Phys. 124, 219906 (2006) (doi: 10.1063/1.2204597) + /// - libxc name: HYB_GGA_XC_HSE03 (id=427) + GauXC_Functional_HSE03, + + /// @brief Heyd-Scuseria-Ernzerhof screened hybrid functional (HSE06) + /// - J. Heyd, G. E. Scuseria, and M. Ernzerhof., J. Chem. Phys. 118, 8207 (2003) (doi: 10.1063/1.1564060) + /// - J. Heyd, G. E. Scuseria, and M. Ernzerhof., J. Chem. Phys. 124, 219906 (2006) (doi: 10.1063/1.2204597) + /// - A. V. Krukau, O. A. Vydrov, A. F. Izmaylov, and G. E. Scuseria., J. Chem. Phys. 125, 224106 (2006) (doi: 10.1063/1.2404663) + /// - libxc name: HYB_GGA_XC_HSE06 (id=428) + GauXC_Functional_HSE06, + + /// @brief + GauXC_Functional_revB3LYP, + + /// @brief + GauXC_Functional_revPBE0, + + /// @brief + GauXC_Functional_revTPSS, + + /// @brief + GauXC_Functional_revTPSSh, + + /// @brief + GauXC_Functional_PW91, + + /// @brief + GauXC_Functional_mBEEF, + + /// @brief + GauXC_Functional_B3PW91, + + /// @brief O3LYP + /// - W.-M. Hoe, A. J. Cohen, and N. C. Handy., Chem. Phys. Lett. 341, 319–328 (2001) (doi: 10.1016/S0009-2614(01)00581-4) + /// - A. J. Cohen and N. C. Handy., Mol. Phys. 99, 607 (2001) (doi: 10.1080/00268970010023435) + /// - libxc name: HYB_GGA_XC_O3LYP (id=404) + GauXC_Functional_O3LYP, + + /// @brief + GauXC_Functional_OLYP, + + /// @brief + GauXC_Functional_OPBE, + + /// @brief + GauXC_Functional_MPW1K, + + /// @brief Revised Perdew-Burke-Ernzerhof exchange by Hammer, Hansen, and Norskov + /// - B. Hammer, L. B. Hansen, and J. K. Nørskov., Phys. Rev. B 59, 7413 (1999) (doi: 10.1103/PhysRevB.59.7413) + /// - libxc name: GGA_X_RPBE (id=117) + GauXC_Functional_RPBE, + + /// @brief Becke 88 exchange + /// - A. D. Becke., Phys. Rev. A 38, 3098 (1988) (doi: 10.1103/PhysRevA.38.3098) + /// - libxc name: GGA_X_B88 (id=106) + GauXC_Functional_B88, + + /// @brief modified Perdew-Wang 91 exchange by Adamo & Barone + /// - C. Adamo and V. Barone., J. Chem. Phys. 108, 664 (1998) (doi: 10.1063/1.475428) + /// - libxc name: GGA_X_MPW91 (id=119) + GauXC_Functional_MPW91, + + /// @brief Regularized strongly constrained and appropriately normed (RSCAN) meta-GGA by Bartok and Yates + /// - A. P. Bartók and J. R. Yates., J. Chem. Phys. 150, 161101 (2019) (doi: 10.1063/1.5094646) + /// - libxc names: MGGA_X_RSCAN (id=493) and MGGA_C_RSCAN (id=494) + GauXC_Functional_RSCAN, + + /// @brief + GauXC_Functional_TUNEDCAMB3LYP, + + /// @brief + GauXC_Functional_wB97, + + /// @brief + GauXC_Functional_wB97X, + + /// @brief + GauXC_Functional_wB97XD, + + /// @brief + GauXC_Functional_wB97XD3, + + /// @brief + GauXC_Functional_LCwPBE, + + /// @brief + GauXC_Functional_X3LYP, + + /// @brief + GauXC_Functional_XLYP, + + /// @brief + GauXC_Functional_BHANDH, + + /// @brief + GauXC_Functional_BMK, + + /// @brief + GauXC_Functional_BP86VWN, + + /// @brief + GauXC_Functional_PW86B95, + + /// @brief + GauXC_Functional_PW86PBE, + + /// @brief r2SCAN0: r2SCAN hybrid like PBE0 with 25% exact exchange + /// - M. Bursch, H. Neugebauer, S. Ehlert, and S. Grimme., J. Chem. Phys. 156, 134105 (2022) (doi: 10.1063/5.0086040) + /// - libxc name: HYB_MGGA_XC_R2SCAN0 (id=660) + GauXC_Functional_R2SCAN0, + + /// @brief r2SCANh: r2SCAN hybrid like TPSSh with 10% exact exchange + /// - M. Bursch, H. Neugebauer, S. Ehlert, and S. Grimme., J. Chem. Phys. 156, 134105 (2022) (doi: 10.1063/5.0086040) + /// - libxc name: HYB_MGGA_XC_R2SCANH (id=659) + GauXC_Functional_R2SCANh, + + /// @brief r2SCAN50: r2SCAN hybrid like BHLYP with 50% exact exchange + /// - M. Bursch, H. Neugebauer, S. Ehlert, and S. Grimme., J. Chem. Phys. 156, 134105 (2022) (doi: 10.1063/5.0086040) + /// - libxc name: HYB_MGGA_XC_R2SCAN50 (id=661) + GauXC_Functional_R2SCAN50, + + /// @brief Minnesota 2005 hybrid functional + /// - Y. Zhao, N. E. Schultz, and D. G. Truhlar., J. Chem. Phys. 123, 161103 (2005) (doi: 10.1063/1.2126975) + /// - libxc names: HYB_MGGA_X_M05 (id=438) & MGGA_C_M05 (id=237) + GauXC_Functional_M05, + + /// @brief Minnesota 2008 hybrid functional + /// - Y. Zhao and D. G. Truhlar., Theor. Chem. Acc. 120, 215 (2008) (doi: 10.1007/s00214-007-0310-x) + /// - libxc names: HYB_MGGA_X_M06 (id=449) & MGGA_C_M06 (id=235) + GauXC_Functional_M06, + + /// @brief Minnesota M08 hybrid functional + /// - Y. Zhao and D. G. Truhlar., J. Chem. Theory Comput. 4, 1849 (2008) (doi: 10.1021/ct800246v) + /// - libxc names: HYB_MGGA_X_M08_HX (id=295) & MGGA_C_M08_HX (id=78) + GauXC_Functional_M08HX, + + /// @brief + GauXC_Functional_M08SO, + + /// @brief + GauXC_Functional_M052X, + + /// @brief + GauXC_Functional_M06SX, + + /// @brief + GauXC_Functional_CF22D, + + /// @brief + GauXC_Functional_SOGGA11X, + + /// @brief + GauXC_Functional_M06HF, + + /// @brief + GauXC_Functional_M11, + + /// @brief + GauXC_Functional_MN12L, + + /// @brief + GauXC_Functional_MN12SX, + + /// @brief + GauXC_Functional_MN15, + + /// @brief + GauXC_Functional_MN15L, + + /// @brief Revised Minnesota 2006 meta-GGA functional + /// - Y. Wang, X. Jin, H. S. Yu, D. G. Truhlar, and X. He., Proc. Natl. Acad. Sci. U. S. A. 114, 8487-8492 (2017) (doi: 10.1073/pnas.1705670114) + /// - libxc names: MGGA_X_REVM06_L (id=293) & MGGA_C_REVM06_L (id=294) + GauXC_Functional_revM06L, +}; + +#ifdef __cplusplus +} // extern "C" +} // namespace GauXC::C +#endif \ No newline at end of file diff --git a/include/gauxc/matrix.h b/include/gauxc/matrix.h new file mode 100644 index 00000000..a5fef0b8 --- /dev/null +++ b/include/gauxc/matrix.h @@ -0,0 +1,56 @@ +/** + * 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 +#else +#include +#include +#endif + +#ifdef __cplusplus +namespace GauXC::C { +extern "C" { +#endif + +/** + * @brief GauXC C API Matrix handle. + */ +typedef struct GauXCMatrix { + void* ptr; ///< Pointer to the Matrix instance. +} GauXCMatrix; + +/** + * @brief Create a new Matrix instance. + * @param rows Number of rows in the matrix. + * @param cols Number of columns in the matrix. + * @return Handle to the newly created Matrix. + */ +extern GauXCMatrix gauxc_matrix_new( + size_t rows, + size_t cols +); + +/** + * @brief Delete a Matrix instance. + * @param matrix Handle to the Matrix to delete. + */ +extern void gauxc_matrix_delete( + GauXCMatrix matrix +); + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif \ No newline at end of file diff --git a/include/gauxc/util/c_matrix.hpp b/include/gauxc/util/c_matrix.hpp new file mode 100644 index 00000000..4e4d4934 --- /dev/null +++ b/include/gauxc/util/c_matrix.hpp @@ -0,0 +1,26 @@ +/** + * 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 + +#define EIGEN_DONT_VECTORIZE +#define EIGEN_NO_CUDA +#include + +namespace GauXC::detail { + +using CMatrix = Eigen::MatrixXd; + +static inline CMatrix* get_matrix_ptr(C::GauXCMatrix matrix) noexcept { + return static_cast(matrix.ptr); +} + +} // namespace GauXC::detail \ No newline at end of file diff --git a/include/gauxc/util/c_molecular_weights.hpp b/include/gauxc/util/c_molecular_weights.hpp index 490c4ec7..fef3e82e 100644 --- a/include/gauxc/util/c_molecular_weights.hpp +++ b/include/gauxc/util/c_molecular_weights.hpp @@ -15,11 +15,11 @@ #include namespace GauXC::detail { -static inline MolecularWeights get_molecular_weights_ptr(C::GauXCMolecularWeights mw) noexcept { - return *static_cast(mw.ptr); +static inline MolecularWeights* get_molecular_weights_ptr(C::GauXCMolecularWeights mw) noexcept { + return static_cast(mw.ptr); } -static inline MolecularWeightsFactory get_molecular_weights_factory_ptr(C::GauXCMolecularWeightsFactory mwf) noexcept { - return *static_cast(mwf.ptr); +static inline MolecularWeightsFactory* get_molecular_weights_factory_ptr(C::GauXCMolecularWeightsFactory mwf) noexcept { + return static_cast(mwf.ptr); } static inline MolecularWeightsSettings convert_molecular_weights_settings( const GauXC::C::GauXCMolecularWeightsSettings& c_settings ) { diff --git a/include/gauxc/util/c_molecule.hpp b/include/gauxc/util/c_molecule.hpp index 60794335..acec43dd 100644 --- a/include/gauxc/util/c_molecule.hpp +++ b/include/gauxc/util/c_molecule.hpp @@ -18,7 +18,6 @@ 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 }; + return Atom{AtomicNumber(atom.Z), atom.x, atom.y, atom.z }; } } \ No newline at end of file diff --git a/include/gauxc/util/c_xc_integrator.hpp b/include/gauxc/util/c_xc_integrator.hpp new file mode 100644 index 00000000..df98d279 --- /dev/null +++ b/include/gauxc/util/c_xc_integrator.hpp @@ -0,0 +1,29 @@ +/** + * 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 + +#include +#include +#include +#include + +namespace GauXC::detail { + +static inline XCIntegrator* get_xc_integrator_ptr(C::GauXCIntegrator integrator) noexcept { + return static_cast*>(integrator.ptr); +} + +static inline XCIntegratorFactory* get_xc_integrator_factory_ptr(C::GauXCIntegratorFactory factory) noexcept { + return static_cast*>(factory.ptr); +} + +} // namespace GauXC::detail \ No newline at end of file diff --git a/include/gauxc/xc_integrator.h b/include/gauxc/xc_integrator.h new file mode 100644 index 00000000..fe517c33 --- /dev/null +++ b/include/gauxc/xc_integrator.h @@ -0,0 +1,247 @@ +/** + * 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 +#else +#include +#include +#endif +#include +#include +#include + +#ifdef __cplusplus +namespace GauXC::C { +extern "C" { +#endif + +/** + * @brief GauXC C API XCIntegrator handle. + */ +typedef struct GauXCIntegrator { + void* ptr; ///< Pointer to the XCIntegrator instance. + bool owned; ///< Whether this instance owns the XCIntegrator. +} GauXCIntegrator; + +/** + * @brief Delete an XCIntegrator instance. + * @param integrator Handle to the XCIntegrator to delete. + */ +extern void gauxc_xc_integrator_delete( + GauXCIntegrator integrator +); + +/** + * @brief GauXC C API XCIntegratorFactory handle. + */ +typedef struct GauXCIntegratorFactory { + void* ptr; ///< Pointer to the XCIntegratorFactory instance. +} GauXCIntegratorFactory; + +/** + * @brief Create a new XCIntegratorFactory instance. + * @param execution_space Execution space to use. + * @param integrator_input_type Type of integrator input. + * @param integrator_kernel_name Name of the integrator kernel. + * @param local_work_kernel_name Name of the local work kernel. + * @param reduction_kernel_name Name of the reduction kernel. + * @return Handle to the created XCIntegratorFactory. + */ +extern GauXCIntegratorFactory gauxc_xc_integrator_factory_new( + enum GauXC_ExecutionSpace execution_space, + const char* integrator_input_type, + const char* integrator_kernel_name, + const char* local_work_kernel_name, + const char* reduction_kernel_name +); + +/** + * @brief Delete an XCIntegratorFactory instance. + * @param integrator_factory Handle to the XCIntegratorFactory to delete. + */ +extern void gauxc_xc_integrator_factory_delete( + GauXCIntegratorFactory integrator_factory +); + +/** + * @brief Get an XCIntegrator instance from an XCIntegratorFactory. + * @param integrator_factory Handle to the XCIntegratorFactory. + * @param func Handle to the XCFunctional. + * @param lb Handle to the LoadBalancer. + * @return Handle to the created XCIntegrator. + */ +extern GauXCIntegrator gauxc_xc_integrator_factory_get_instance( + GauXCIntegratorFactory integrator_factory, + enum GauXC_Functional func, + GauXCLoadBalancer lb +); + +/** + * @brief Get a shared XCIntegrator instance from an XCIntegratorFactory. + * @param integrator_factory Handle to the XCIntegratorFactory. + * @param func Handle to the XCFunctional. + * @param lb Handle to the LoadBalancer. + * @return Handle to the created XCIntegrator. + */ +extern GauXCIntegrator gauxc_xc_integrator_factory_get_shared_instance( + GauXCIntegratorFactory integrator_factory, + enum GauXC_Functional func, + GauXCLoadBalancer lb +); + +/** + * @brief Integrate the density matrix to get the number of electrons. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix Density matrix container. + * @param den Pointer to store the number of electrons. + */ +extern void gauxc_integrator_integrate_den( + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* den +); + +/** + * @brief Evaluate the exchange-correlation energy for RKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix Density matrix container for RKS. + * @param exc Pointer to store the exchange-correlation energy. + */ +extern void gauxc_integrator_eval_exc_rks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* exc +); + +/** + * @brief Evaluate the exchange-correlation energy for UKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix_s Density matrix container for total density. + * @param density_matrix_z Density matrix container for spin density. + * @param exc Pointer to store the exchange-correlation energy. + */ +extern void gauxc_integrator_eval_exc_uks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc +); + +/** + * @brief Evaluate the exchange-correlation energy for GKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix_s Density matrix container for total density. + * @param density_matrix_z Density matrix container for spin z density. + * @param density_matrix_x Density matrix container for spin x component. + * @param density_matrix_y Density matrix container for spin y component. + * @param exc Pointer to store the exchange-correlation energy. + */ +extern void gauxc_integrator_eval_exc_gks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc +); + +/** + * @brief Evaluate the exchange-correlation energy and potential for RKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix Density matrix container for RKS. + * @param exc Pointer to store the exchange-correlation energy. + * @param vxc_matrix Matrix container to store the exchange-correlation potential. + */ +extern void gauxc_integrator_eval_exc_vxc_rks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* exc, + GauXCMatrix vxc_matrix +); + +/** + * @brief Evaluate the exchange-correlation energy and potential for UKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix_s Density matrix container for total density. + * @param density_matrix_z Density matrix container for spin density. + * @param exc Pointer to store the exchange-correlation energy. + * @param vxc_matrix_s Matrix container to store the exchange-correlation potential for total density. + * @param vxc_matrix_z Matrix container to store the exchange-correlation potential for spin density + */ +extern void gauxc_integrator_eval_exc_vxc_uks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z +); + +/** + * @brief Evaluate the exchange-correlation energy and potential for GKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix_s Density matrix container for total density. + * @param density_matrix_z Density matrix container for spin z density. + * @param density_matrix_x Density matrix container for spin x component. + * @param density_matrix_y Density matrix container for spin y component. + * @param exc Pointer to store the exchange-correlation energy. + * @param vxc_matrix_s Matrix container to store the exchange-correlation potential for total density. + * @param vxc_matrix_z Matrix container to store the exchange-correlation potential for spin z density. + * @param vxc_matrix_x Matrix container to store the exchange-correlation potential for spin x component. + * @param vxc_matrix_y Matrix container to store the exchange-correlation potential for spin y component. + */ +extern void gauxc_integrator_eval_exc_vxc_gks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z, + GauXCMatrix vxc_matrix_x, + GauXCMatrix vxc_matrix_y +); + +/** + * @brief Evaluate the exchange-correlation energy gradient for RKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix Density matrix container for RKS. + * @param exc_grad Pointer to store the exchange-correlation energy gradient. + */ +extern void gauxc_integrator_eval_exc_grad_rks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* exc_grad +); + +/** + * @brief Evaluate the exchange-correlation energy gradient for UKS. + * @param integrator Handle to the XCIntegrator. + * @param density_matrix_s Density matrix container for total density. + * @param density_matrix_z Density matrix container for spin density. + * @param exc_grad Pointer to store the exchange-correlation energy gradient. + */ +extern void gauxc_integrator_eval_exc_grad_uks( + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_grad +); + +#ifdef __cplusplus +} // extern "C" +} // namespace GauXC::C +#endif \ No newline at end of file diff --git a/src/c_matrix.cxx b/src/c_matrix.cxx new file mode 100644 index 00000000..d094f927 --- /dev/null +++ b/src/c_matrix.cxx @@ -0,0 +1,36 @@ +/** + * 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 + +namespace GauXC::C { + +GauXCMatrix gauxc_matrix_new( + size_t rows, + size_t cols +) { + GauXCMatrix matrix; + matrix.ptr = new detail::CMatrix( rows, cols ); + + return matrix; +} + +void gauxc_matrix_delete( + GauXCMatrix matrix +) { + if(matrix.ptr != nullptr) + delete detail::get_matrix_ptr(matrix); + matrix.ptr = nullptr; +} + +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_xc_integrator.cxx b/src/c_xc_integrator.cxx new file mode 100644 index 00000000..22043ddd --- /dev/null +++ b/src/c_xc_integrator.cxx @@ -0,0 +1,88 @@ +/** + * 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::C { +extern "C" { + +void gauxc_xc_integrator_delete( + GauXCIntegrator integrator +) { + if(integrator.ptr != nullptr && integrator.owned) + delete detail::get_xc_integrator_ptr(integrator); + integrator.ptr = nullptr; +} + +void gauxc_xc_integrator_factory_delete( + GauXCIntegratorFactory factory) +{ + if (factory.ptr != nullptr) + delete detail::get_xc_integrator_factory_ptr(factory); + factory.ptr = nullptr; +} + +GauXCIntegratorFactory gauxc_xc_integrator_factory_new( + enum GauXC_ExecutionSpace execution_space, + const char* integrator_input_type, + const char* integrator_kernel_name, + const char* local_work_kernel_name, + const char* reduction_kernel_name +) { + GauXCIntegratorFactory factory; + XCIntegratorFactory* factory_ptr = + new XCIntegratorFactory( + static_cast(execution_space), + std::string(integrator_input_type), + std::string(integrator_kernel_name), + std::string(local_work_kernel_name), + std::string(reduction_kernel_name) + ); + factory.ptr = factory_ptr; + return factory; +} + +GauXCIntegrator gauxc_xc_integrator_factory_get_instance( + GauXCIntegratorFactory factory, + enum GauXC_Functional functional, + GauXCLoadBalancer lb +) { + auto integrator_instance = detail::get_xc_integrator_factory_ptr(factory)->get_instance( + static_cast(functional), + detail::get_load_balancer_ptr(lb) + ); + GauXCIntegrator integrator; + integrator.ptr = new XCIntegrator( std::move(integrator_instance) ); + integrator.owned = true; + return integrator; +} + +GauXCIntegrator gauxc_xc_integrator_factory_get_shared_instance( + GauXCIntegratorFactory factory, + enum GauXC_Functional functional, + GauXCLoadBalancer lb +) { + auto integrator_instance_ptr = detail::get_xc_integrator_factory_ptr(factory)->get_shared_instance( + static_cast(functional), + detail::get_load_balancer_ptr(lb) + ); + GauXCIntegrator integrator; + integrator.ptr = new std::shared_ptr< XCIntegrator >( std::move(integrator_instance_ptr) ); + integrator.owned = false; + return integrator; +} + +} // extern "C" +} // namespace GauXC::C From b476f369b118f32d422301d9d3b5d967bcdddb9c Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Sun, 25 Jan 2026 10:46:27 +0100 Subject: [PATCH 08/15] Add references for functionals --- include/gauxc/functional.h | 186 +++++++++++++++++++------ include/gauxc/util/c_xc_integrator.hpp | 8 +- 2 files changed, 147 insertions(+), 47 deletions(-) diff --git a/include/gauxc/functional.h b/include/gauxc/functional.h index ecf63711..7ac219b2 100644 --- a/include/gauxc/functional.h +++ b/include/gauxc/functional.h @@ -46,13 +46,17 @@ enum GauXC_Functional { GauXC_Functional_B3LYP, /// @brief Perdew-Burke-Ernzerhof exchange & correlation - /// J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) - /// J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) /// - libxc names: GGA_X_PBE (id=101) & GGA_C_PBE (id=130) /// - xcfun names: PBEEX and PBEC GauXC_Functional_PBE, - /// @brief revised Perdew-Burke-Ernzerhof exchange & correlation + /// @brief revised Perdew-Burke-Ernzerhof exchange & original PBE correlation + /// - Y. Zhang and W. Yang., Phys. Rev. Lett. 80, 890 (1998) (doi: 10.1103/PhysRevLett.80.890) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc names: GGA_X_PBE_R (id=102) & GGA_C_PBE (id=130) GauXC_Functional_revPBE, /// @brief Perdew-Burke-Ernzerhof exchange & correlation, 1-parameter hybrid @@ -110,12 +114,14 @@ enum GauXC_Functional { /// - libxc name: LDA_C_EPC18_2 (id=331) GauXC_Functional_EPC18_2, - /// @brief Grimme's parametrization of the B97 functional + /// @brief Grimme's parametrization of the B97 functional, original D2 variant /// - S. Grimme., J. Comput. Chem. 27, 1787 (2006) (doi: 10.1002/jcc.20495) /// - libxc name: GGA_XC_B97_D (id=170) GauXC_Functional_B97D, - /// @brief + /// @brief Grimme's parametrization of the B97 functional, D3(0) variant + /// - S. Grimme., J. Comput. Chem. 27, 1787 (2006) (doi: 10.1002/jcc.20495) + /// - libxc name: GGA_XC_B97_D (id=170) GauXC_Functional_B97D3ZERO, /// @brief Coulomb-attenuating method range-separated hybrid functional @@ -145,7 +151,8 @@ enum GauXC_Functional { /// @brief Slater exchange & Perdew, Wang 92 correlation /// - P. A. M. Dirac., Math. Proc. Cambridge Philos. Soc. 26, 376 (1930) (doi: 10.1017/S0305004100016108) /// - F. Bloch., Z. Phys. 57, 545 (1929) (doi: 10.1007/BF01340281) - /// - libxc names: LDA_X (id=1) and + /// - J. P. Perdew and Y. Wang., Phys. Rev. B 45, 13244 (1992) (doi: 10.1103/PhysRevB.45.13244) + /// - libxc names: LDA_X (id=1) and LDA_C_PW (id=12) GauXC_Functional_SPW92, /// @brief Tao, Perdew, Staroverov & Scuseria meta-GGA @@ -174,13 +181,24 @@ enum GauXC_Functional { /// - libxc name: LDA_C_VWN (id=7) GauXC_Functional_VWN5, - /// @brief + /// @brief HJS screened PBE exchange & original PBE correlation + /// - T. M. Henderson, B. G. Janesko, and G. E. Scuseria., J. Chem. Phys. 128, 194105 (2008) (doi: 10.1063/1.2921797) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc names: GGA_X_HJS_PBE (id=525) & GGA_C_PBE (id=130) GauXC_Functional_LRCwPBE, - /// @brief + /// @brief HJS screened PBE exchange & original PBE correlation, hybrid version + /// - T. M. Henderson, B. G. Janesko, and G. E. Scuseria., J. Chem. Phys. 128, 194105 (2008) (doi: 10.1063/1.2921797) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc name: HYB_GGA_XC_HJS_PBE (id=429) GauXC_Functional_LRCwPBEh, - /// @brief + /// @brief Becke 88 exchange and Perdew 86 correlation + /// - A. D. Becke., Phys. Rev. A 38, 3098 (1988) (doi: 10.1103/PhysRevA.38.3098) + /// - J. P. Perdew., Phys. Rev. B 33, 8822 (1986) (doi: 10.1103/PhysRevB.33.8822) + /// - libxc names: GGA_X_B88 (id=106) and GGA_C_P86 (id=132) GauXC_Functional_BP86, /// @brief Heyd-Scuseria-Ernzerhof screened hybrid functional (HSE03) @@ -196,25 +214,45 @@ enum GauXC_Functional { /// - libxc name: HYB_GGA_XC_HSE06 (id=428) GauXC_Functional_HSE06, - /// @brief + /// @brief Revised B3LYP + /// - L. Lu, H. Hu, H. Hou, and B. Wang., Comput. Theor. Chem. 1015, 64 (2013) (doi: 10.1016/j.comptc.2013.04.009) + /// - libxc name: HYB_GGA_XC_REVB3LYP (id=454) GauXC_Functional_revB3LYP, - /// @brief + /// @brief revised Perdew-Burke-Ernzerhof exchange & original PBE correlation, hybrid version + /// - Y. Zhang and W. Yang., Phys. Rev. Lett. 80, 890 (1998) (doi: 10.1103/PhysRevLett.80.890) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc names: GGA_X_PBE_R (id=102) & GGA_C_PBE (id=130) GauXC_Functional_revPBE0, - /// @brief + /// @brief revised Tao, Perdew, Staroverov & Scuseria + /// - J. P. Perdew, A. Ruzsinszky, G. I. Csonka, L. A. Constantin, and J. Sun., Phys. Rev. Lett. 103, 026403 (2009) (doi: 10.1103/PhysRevLett.103.026403) + /// - J. P. Perdew, A. Ruzsinszky, G. I. Csonka, L. A. Constantin, and J. Sun., Phys. Rev. Lett. 106, 179902 (2011) (doi: 10.1103/PhysRevLett.106.179902) + /// - libxc names: MGGA_X_REVTPSS (id=212) & MGGA_C_REVTPSS (id=241) GauXC_Functional_revTPSS, - /// @brief + /// @brief revTPSSh + /// - G. I. Csonka, J. P. Perdew, and A. Ruzsinszky., J. Chem. Theory Comput. 6, 3688 (2010) (doi: 10.1021/ct100488v) + /// - libxc name: HYB_MGGA_XC_REVTPSSH (id=458) GauXC_Functional_revTPSSh, - /// @brief + /// @brief Perdew-Wang 91 exchange and correlation + /// - J. P. Perdew. In P. Ziesche and H. Eschrig, editors, Proceedings of the 75. WE-Heraeus-Seminar and 21st Annual International Symposium on Electronic Structure of Solids, 11. Berlin, 1991. Akademie Verlag. + /// - J. P. Perdew, J. A. Chevary, S. H. Vosko, K. A. Jackson, M. R. Pederson, D. J. Singh, and C. Fiolhais., Phys. Rev. B 46, 6671 (1992) (doi: 10.1103/PhysRevB.46.6671) + /// - J. P. Perdew, J. A. Chevary, S. H. Vosko, K. A. Jackson, M. R. Pederson, D. J. Singh, and C. Fiolhais., Phys. Rev. B 48, 4978 (1993) (doi: 10.1103/PhysRevB.48.4978.2) + /// - libxc name: GGA_X_PW91 (id=109) and GGA_C_PW91 (id=134) GauXC_Functional_PW91, - /// @brief + /// @brief mBEEF exchange and Perdew, Burke & Ernzerhof SOL + /// - J. Wellendorff, K. T. Lundgaard, K. W. Jacobsen, and T. Bligaard., J. Chem. Phys. 140, 144107 (2014) (doi: 10.1063/1.4870397) + /// - J. P. Perdew, A. Ruzsinszky, G. I. Csonka, O. A. Vydrov, G. E. Scuseria, L. A. Constantin, X. Zhou, and K. Burke., Phys. Rev. Lett. 100, 136406 (2008) (doi: 10.1103/PhysRevLett.100.136406) + /// - libxc names: MGGA_X_MBEEF (id=249) and GGA_C_PBE_SOL (id=133) GauXC_Functional_mBEEF, - /// @brief + /// @brief The original (ACM, B3PW91) hybrid of Becke + /// - A. D. Becke., J. Chem. Phys. 98, 5648 (1993) (doi: 10.1063/1.464913) + /// - libxc name: HYB_GGA_XC_B3PW91 (id=401) GauXC_Functional_B3PW91, /// @brief O3LYP @@ -223,13 +261,23 @@ enum GauXC_Functional { /// - libxc name: HYB_GGA_XC_O3LYP (id=404) GauXC_Functional_O3LYP, - /// @brief + /// @brief Handy & Cohen OPTX 01 exchange and Lee, Yang & Parr correlation + /// - N. C. Handy and A. J. Cohen., Mol. Phys. 99, 403 (2001) (doi: 10.1080/00268970010018431) + /// - C. Lee, W. Yang, and R. G. Parr., Phys. Rev. B 37, 785 (1988) (doi: 10.1103/PhysRevB.37.785) + /// - B. Miehlich, A. Savin, H. Stoll, and H. Preuss., Chem. Phys. Lett. 157, 200 (1989) (doi: 10.1016/0009-2614(89)87234-3) + /// - libxc names: GGA_X_OPTX (id=110) & GGA_C_LYP (id=131) GauXC_Functional_OLYP, - /// @brief + /// @brief Handy & Cohen OPTX 01 exchange and Perdew, Burke & Ernzerhof correlation + /// - N. C. Handy and A. J. Cohen., Mol. Phys. 99, 403 (2001) (doi: 10.1080/00268970010018431) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc names: GGA_X_OPTX (id=110) & GGA_C_PBE (id=130) GauXC_Functional_OPBE, - /// @brief + /// @brief mPW1K + /// - B. J. Lynch, P. L. Fast, M. Harris, and D. G. Truhlar., J. Phys. Chem. A 104, 4811 (2000) (doi: 10.1021/jp000497z) + /// - libxc name: HYB_GGA_XC_MPW1K (id=405) GauXC_Functional_MPW1K, /// @brief Revised Perdew-Burke-Ernzerhof exchange by Hammer, Hansen, and Norskov @@ -252,43 +300,73 @@ enum GauXC_Functional { /// - libxc names: MGGA_X_RSCAN (id=493) and MGGA_C_RSCAN (id=494) GauXC_Functional_RSCAN, - /// @brief + /// @brief CAM version of B3LYP, tuned for excitations and properties + /// - K. Okuno, Y. Shigeta, R. Kishi, H. Miyasaka, and M. Nakano., J. Photochem. Photobiol., A 235, 29 (2012) (doi: 10.1016/j.jphotochem.2012.03.003) + /// - libxc name: HYB_GGA_XC_TUNED_CAM_B3LYP (id=434) GauXC_Functional_TUNEDCAMB3LYP, - /// @brief + /// @brief wB97 range-separated functional + /// - J.-D. Chai and M. Head-Gordon., J. Chem. Phys. 128, 084106 (2008) (doi: 10.1063/1.2834918) + /// - libxc name: HYB_GGA_XC_WB97 (id=463) GauXC_Functional_wB97, - /// @brief + /// @brief wB97X range-separated functional + /// - J.-D. Chai and M. Head-Gordon., J. Chem. Phys. 128, 084106 (2008) (doi: 10.1063/1.2834918) + /// - libxc name: HYB_GGA_XC_WB97X (id=464) GauXC_Functional_wB97X, - /// @brief + /// @brief wB97X-D range-separated functional + /// - J.-D. Chai and M. Head-Gordon., Phys. Chem. Chem. Phys. 10, 6615-6620 (2008) (doi: 10.1039/B810189B) + /// - libxc name: HYB_GGA_XC_WB97X_D (id=471) GauXC_Functional_wB97XD, - /// @brief + /// @brief wB97X-D3 range-separated functional + /// - Y.-S. Lin, G.-D. Li, S.-P. Mao, and J.-D. Chai., J. Chem. Theory Comput. 9, 263-272 (2013) (doi: 10.1021/ct300715s) + /// - libxc name: HYB_GGA_XC_WB97X_D3 (id=399) GauXC_Functional_wB97XD3, - /// @brief + /// @brief Long-range corrected PBE (LC-wPBE) by Vydrov and Scuseria + /// - O. A. Vydrov and G. E. Scuseria., J. Chem. Phys. 125, 234109 (2006) (doi: 10.1063/1.2409292) + /// - libxc name: HYB_GGA_XC_LC_WPBE (id=478) GauXC_Functional_LCwPBE, - /// @brief + /// @brief X3LYP + /// - X. Xu and W. A. Goddard., Proc. Natl. Acad. Sci. U. S. A. 101, 2673 (2004) (doi: 10.1073/pnas.0308730100) + /// - libxc name: HYB_GGA_XC_X3LYP (id=411) GauXC_Functional_X3LYP, - /// @brief + /// @brief XLYP + /// - X. Xu and W. A. Goddard., Proc. Natl. Acad. Sci. U. S. A. 101, 2673 (2004) (doi: 10.1073/pnas.0308730100) + /// - libxc name: GGA_XC_XLYP (id=166) GauXC_Functional_XLYP, - /// @brief + /// @brief BHandH i.e. BHLYP + /// - A. D. Becke., J. Chem. Phys. 98, 1372 (1993) (doi: 10.1063/1.464304) + /// - Defined through Gaussian implementation. + /// - libxc name: HYB_GGA_XC_BHANDH (id=435) GauXC_Functional_BHANDH, - /// @brief + /// @brief Boese-Martin for kinetics + /// - A. D. Boese and J. M. L. Martin., J. Chem. Phys. 121, 3405 (2004) (doi: 10.1063/1.1774975) + /// - libxc names: HYB_MGGA_X_BMK (id=279) & GGA_C_BMK (id=280) GauXC_Functional_BMK, - /// @brief + /// @brief Becke 88 exchange and Perdew 86 based on VWN5 correlation, with more accurate value for ftilde + /// - A. D. Becke., Phys. Rev. A 38, 3098 (1988) (doi: 10.1103/PhysRevA.38.3098) + /// - J. P. Perdew., Phys. Rev. B 33, 8822 (1986) (doi: 10.1103/PhysRevB.33.8822) + /// - libxc names: GGA_X_B88 (id=106) & GGA_C_P86VWN_FT (id=253) GauXC_Functional_BP86VWN, - /// @brief + /// @brief Mixture of PW86 with BC95 + /// - A. D. Becke., J. Chem. Phys. 104, 1040 (1996) (doi: 10.1063/1.470829) + /// - libxc name: HYB_MGGA_XC_PW86B95 (id=442) GauXC_Functional_PW86B95, - /// @brief + /// @brief Perdew & Wang 86 exchange and PBE correlation + /// - J. P. Perdew and W. Yue., Phys. Rev. B 33, 8800 (1986) (doi: 10.1103/PhysRevB.33.8800) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 77, 3865 (1996) (doi: 10.1103/PhysRevLett.77.3865) + /// - J. P. Perdew, K. Burke, and M. Ernzerhof., Phys. Rev. Lett. 78, 1396 (1997) (doi: 10.1103/PhysRevLett.78.1396) + /// - libxc names: GGA_X_PW86 (id=108) & GGA_C_PBE (id=130) GauXC_Functional_PW86PBE, /// @brief r2SCAN0: r2SCAN hybrid like PBE0 with 25% exact exchange @@ -321,37 +399,59 @@ enum GauXC_Functional { /// - libxc names: HYB_MGGA_X_M08_HX (id=295) & MGGA_C_M08_HX (id=78) GauXC_Functional_M08HX, - /// @brief + /// @brief Minnesota M08-SO hybrid exchange functional + /// - Y. Zhao and D. G. Truhlar., J. Chem. Theory Comput. 4, 1849 (2008) (doi: 10.1021/ct800246v) + /// - libxc names: HYB_MGGA_X_M08_SO (id=296) & MGGA_C_M08_SO (id=77) GauXC_Functional_M08SO, - /// @brief + /// @brief Minnesota M05-2X hybrid exchange functional + /// - Y. Zhao, N. E. Schultz, and D. G. Truhlar., J. Chem. Theory Comput. 2, 364 (2006) (doi: 10.1021/ct0502763) + /// - libxc names: HYB_MGGA_X_M05_2X (id=439) & MGGA_C_M05_2X (id=238) GauXC_Functional_M052X, - /// @brief + /// @brief Minnesota M06-SX short-range hybrid exchange functional + /// - Y. Wang, P. Verma, L. Zhang, Y. Li, Z. Liu, D. G. Truhlar, and X. He., Proc. Natl. Acad. Sci. U. S. A. 117, 2294–2301 (2020) (doi: 10.1073/pnas.1913699117) + /// - libxc names: HYB_MGGA_X_M06_SX (id=310) & MGGA_C_M06_SX (id=311) GauXC_Functional_M06SX, - /// @brief + /// @brief Minnesota CF22D hybrid exchange functional + /// - Y. Liu, C. Zhang, Z. Liu, D. G. Truhlar, Y. Wang, and X. He., Nature Computational Science 3, 48–58 (2022) (doi: 10.1038/s43588-022-00371-5) + /// - libxc names: HYB_MGGA_X_CF22D (id=340) & MGGA_C_CF22D (id=341) GauXC_Functional_CF22D, - /// @brief + /// @brief Hybrid based on SOGGA11 form + /// - R. Peverati and D. G. Truhlar., J. Chem. Phys. 135, 191102 (2011) (doi: 10.1063/1.3663871) + /// - libxc names: HYB_GGA_X_SOGGA11_X (id=426) & GGA_C_SOGGA11_X (id=159) GauXC_Functional_SOGGA11X, - /// @brief + /// @brief Minnesota M06-HF hybrid exchange functional + /// - Y. Zhao and D. G. Truhlar., J. Phys. Chem. A 110, 13126 (2006) (doi: 10.1021/jp066479k) + /// - libxc names: HYB_MGGA_X_M06_HF (id=444) & MGGA_C_M06_HF (id=234) GauXC_Functional_M06HF, - /// @brief + /// @brief Minnesota M11 hybrid exchange functional + /// - R. Peverati and D. G. Truhlar., J. Phys. Chem. Lett. 2, 2810 (2011) (doi: 10.1021/jz201170d) + /// - libxc names: HYB_MGGA_X_M11 (id=297) & MGGA_C_M11 (id=76) GauXC_Functional_M11, - /// @brief + /// @brief Minnesota MN12-L exchange functional + /// - R. Peverati and D. G. Truhlar., Phys. Chem. Chem. Phys. 14, 13171 (2012) (doi: 10.1039/C2CP42025B) + /// - libxc names: MGGA_X_MN12_L (id=227) & MGGA_C_MN12_L (id=74) GauXC_Functional_MN12L, - /// @brief + /// @brief Minnesota MN12-SX hybrid exchange functional + /// - R. Peverati and D. G. Truhlar., Phys. Chem. Chem. Phys. 14, 16187 (2012) (doi: 10.1039/C2CP42576A) + /// - libxc names: HYB_MGGA_X_MN12_SX (id=248) & MGGA_C_MN12_SX (id=73) GauXC_Functional_MN12SX, - /// @brief + /// @brief Minnesota MN15 correlation functional + /// - H. S. Yu, X. He, S. L. Li, and D. G. Truhlar., Chem. Sci. 7, 5032-5051 (2016) (doi: 10.1039/C6SC00705H) + /// - libxc names: HYB_MGGA_X_MN15 (id=268) & MGGA_C_MN15 (id=269) GauXC_Functional_MN15, - /// @brief + /// @brief Minnesota MN15-L exchange functional + /// - H. S. Yu, X. He, and D. G. Truhlar., J. Chem. Theory Comput. 12, 1280-1293 (2016) (doi: 10.1021/acs.jctc.5b01082) + /// - libxc names: MGGA_X_MN15_L (id=260) & MGGA_C_MN15_L (id=261) GauXC_Functional_MN15L, /// @brief Revised Minnesota 2006 meta-GGA functional diff --git a/include/gauxc/util/c_xc_integrator.hpp b/include/gauxc/util/c_xc_integrator.hpp index df98d279..23ce9e53 100644 --- a/include/gauxc/util/c_xc_integrator.hpp +++ b/include/gauxc/util/c_xc_integrator.hpp @@ -18,12 +18,12 @@ namespace GauXC::detail { -static inline XCIntegrator* get_xc_integrator_ptr(C::GauXCIntegrator integrator) noexcept { - return static_cast*>(integrator.ptr); +static inline XCIntegrator* get_xc_integrator_ptr(C::GauXCIntegrator integrator) noexcept { + return static_cast*>(integrator.ptr); } -static inline XCIntegratorFactory* get_xc_integrator_factory_ptr(C::GauXCIntegratorFactory factory) noexcept { - return static_cast*>(factory.ptr); +static inline XCIntegratorFactory* get_xc_integrator_factory_ptr(C::GauXCIntegratorFactory factory) noexcept { + return static_cast*>(factory.ptr); } } // namespace GauXC::detail \ No newline at end of file From 758ed2036e50ec8f702584166b4db71c509fd759 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 07:29:00 +0100 Subject: [PATCH 09/15] Add stddef header for runtime environment --- include/gauxc/runtime_environment.h | 5 +++++ src/c_runtime_environment.cxx | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/gauxc/runtime_environment.h b/include/gauxc/runtime_environment.h index 52366532..17ed65ea 100644 --- a/include/gauxc/runtime_environment.h +++ b/include/gauxc/runtime_environment.h @@ -11,6 +11,11 @@ */ #pragma once +#ifdef __cplusplus +#include +#else +#include +#endif #include #ifdef __cplusplus diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx index fd101280..f9307044 100644 --- a/src/c_runtime_environment.cxx +++ b/src/c_runtime_environment.cxx @@ -22,10 +22,6 @@ GauXCRuntimeEnvironment gauxc_runtime_environment_new( GauXCRuntimeEnvironment env; RuntimeEnvironment* env_ptr = new RuntimeEnvironment( GAUXC_MPI_CODE(comm) ); env.ptr = env_ptr; -#ifdef GAUXC_HAS_DEVICE - DeviceRuntimeEnvironment* dev_env_ptr = env_ptr->as_device_runtime(); - env.device_ptr = dev_env_ptr; -#endif return env; } From 0f1722ed3943086edea9b288758afea9718951e0 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 08:33:18 +0100 Subject: [PATCH 10/15] Add error handling --- include/gauxc/basisset.h | 15 +- include/gauxc/load_balancer.h | 19 ++ include/gauxc/matrix.h | 5 + include/gauxc/molecular_weights.h | 25 ++ include/gauxc/molecule.h | 13 +- include/gauxc/molgrid.h | 5 + include/gauxc/runtime_environment.h | 28 ++- include/gauxc/status.h | 26 ++ include/gauxc/xc_integrator.h | 62 +++-- src/c_basisset.cxx | 25 +- src/c_load_balancer.cxx | 98 ++++---- src/c_matrix.cxx | 12 +- src/c_molecular_weights.cxx | 74 ++++-- src/c_molecule.cxx | 28 ++- src/c_molgrid.cxx | 5 +- src/c_runtime_environment.cxx | 41 +-- src/c_xc_integrator.cxx | 372 +++++++++++++++++++++++++--- 17 files changed, 666 insertions(+), 187 deletions(-) create mode 100644 include/gauxc/status.h diff --git a/include/gauxc/basisset.h b/include/gauxc/basisset.h index 3e8e9eae..4dc9c3bd 100644 --- a/include/gauxc/basisset.h +++ b/include/gauxc/basisset.h @@ -20,6 +20,7 @@ #include #include #endif +#include #include #ifdef __cplusplus @@ -36,24 +37,32 @@ typedef struct GauXCBasisSet { /** * @brief Create a new BasisSet instance. + * @param status Status object to capture any errors. * @return Handle to the created BasisSet. */ -extern GauXCBasisSet gauxc_basisset_new(); +extern GauXCBasisSet gauxc_basisset_new( GauXCStatus* status ); /** * @brief Create a new BasisSet instance from arrays of shells. + * @param status Status object to capture any errors. * @param shells Pointer to an array of GauXCShell. * @param nshells Number of shells in the array. * @param normalize Whether to normalize the basis functions. * @return Handle to the created BasisSet. */ -extern GauXCBasisSet gauxc_basisset_new_from_shells( GauXCShell* shells, size_t nshells, bool normalize ); +extern GauXCBasisSet gauxc_basisset_new_from_shells( + GauXCStatus* status, + GauXCShell* shells, + size_t nshells, + bool normalize +); /** * @brief Delete a BasisSet instance. + * @param status Status object to capture any errors. * @param basis Handle to the BasisSet to delete. */ -extern void gauxc_basisset_delete( GauXCBasisSet basis ); +extern void gauxc_basisset_delete( GauXCStatus* status, GauXCBasisSet basis ); #ifdef __cplusplus } // namespace GauXC::C diff --git a/include/gauxc/load_balancer.h b/include/gauxc/load_balancer.h index 9e9bdb53..ab027f34 100644 --- a/include/gauxc/load_balancer.h +++ b/include/gauxc/load_balancer.h @@ -11,6 +11,16 @@ */ #pragma once +#ifdef __cplusplus +#include +#include +#include +#else +#include +#include +#include +#endif +#include #include #include #include @@ -32,9 +42,11 @@ typedef struct GauXCLoadBalancer { /** * @brief Delete a LoadBalancer instance. + * @param status Status object to capture any errors. * @param lb Handle to the LoadBalancer to delete. */ extern void gauxc_load_balancer_delete( + GauXCStatus* status, GauXCLoadBalancer lb ); @@ -47,25 +59,30 @@ typedef struct GauXCLoadBalancerFactory { /** * @brief Create a new LoadBalancerFactory instance. + * @param status Status object to capture any errors. * @param ex Execution space. * @param kernel_name Name of the load balancing kernel to use. * @return Handle to the created LoadBalancerFactory. */ extern GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( + GauXCStatus* status, enum GauXC_ExecutionSpace ex, const char* kernel_name ); /** * @brief Delete a LoadBalancerFactory instance. + * @param status Status object to capture any errors. * @param factory Handle to the LoadBalancerFactory to delete. */ extern void gauxc_load_balancer_factory_delete( + GauXCStatus* status, GauXCLoadBalancerFactory factory ); /** * @brief Create a new LoadBalancer instance from a LoadBalancerFactory. + * @param status Status object to capture any errors. * @param factory Handle to the LoadBalancerFactory. * @param env Handle to the RuntimeEnvironment. * @param mol Handle to the Molecule. @@ -74,6 +91,7 @@ extern void gauxc_load_balancer_factory_delete( * @return Handle to the created LoadBalancer. */ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( + GauXCStatus* status, GauXCLoadBalancerFactory factory, GauXCRuntimeEnvironment env, GauXCMolecule mol, @@ -91,6 +109,7 @@ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( * @return Handle to the created LoadBalancer. */ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_shared_instance( + GauXCStatus* status, GauXCLoadBalancerFactory factory, GauXCRuntimeEnvironment env, GauXCMolecule mol, diff --git a/include/gauxc/matrix.h b/include/gauxc/matrix.h index a5fef0b8..abe40c0c 100644 --- a/include/gauxc/matrix.h +++ b/include/gauxc/matrix.h @@ -18,6 +18,7 @@ #include #include #endif +#include #ifdef __cplusplus namespace GauXC::C { @@ -33,20 +34,24 @@ typedef struct GauXCMatrix { /** * @brief Create a new Matrix instance. + * @param status Status object to capture any errors. * @param rows Number of rows in the matrix. * @param cols Number of columns in the matrix. * @return Handle to the newly created Matrix. */ extern GauXCMatrix gauxc_matrix_new( + GauXCStatus* status, size_t rows, size_t cols ); /** * @brief Delete a Matrix instance. + * @param status Status object to capture any errors. * @param matrix Handle to the Matrix to delete. */ extern void gauxc_matrix_delete( + GauXCStatus* status, GauXCMatrix matrix ); diff --git a/include/gauxc/molecular_weights.h b/include/gauxc/molecular_weights.h index 12a5ae96..115b3619 100644 --- a/include/gauxc/molecular_weights.h +++ b/include/gauxc/molecular_weights.h @@ -18,7 +18,9 @@ #include #include #endif +#include #include +#include #ifdef __cplusplus namespace GauXC::C { @@ -43,11 +45,26 @@ typedef struct GauXCMolecularWeights { /** * @brief Delete a MolecularWeights instance. + * @param status Status object to capture any errors. + * @param mw Handle to the MolecularWeights to delete. */ extern void gauxc_molecular_weights_delete( + GauXCStatus* status, GauXCMolecularWeights mw ); +/** + * @brief Apply molecular weights to a LoadBalancer's tasks. + * @param status Status object to capture any errors. + * @param mw Handle to the MolecularWeights. + * @param lb Handle to the LoadBalancer. + */ +extern void gauxc_molecular_weights_modify_weights( + GauXCStatus* status, + GauXCMolecularWeights mw, + GauXCLoadBalancer lb +); + /** * @brief GauXC C API MolecularWeightsFactory handle. */ @@ -57,12 +74,14 @@ typedef struct GauXCMolecularWeightsFactory { /** * @brief Create a new MolecularWeightsFactory instance. + * @param status Status object to capture any errors. * @param ex Execution space. * @param local_work_kernel_name Name of the LocalWorkDriver kernel to use. * @param settings Settings for the MolecularWeights calculation. * @return Handle to the created MolecularWeightsFactory. */ extern GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( + GauXCStatus* status, enum GauXC_ExecutionSpace ex, const char* local_work_kernel_name, GauXCMolecularWeightsSettings settings @@ -70,27 +89,33 @@ extern GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( /** * @brief Delete a MolecularWeightsFactory instance. + * @param status Status object to capture any errors. * @param factory Handle to the MolecularWeightsFactory to delete. */ extern void gauxc_molecular_weights_factory_delete( + GauXCStatus* status, GauXCMolecularWeightsFactory factory ); /** * @brief Get MolecularWeights instance from a MolecularWeightsFactory. + * @param status Status object to capture any errors. * @param factory Handle to the MolecularWeightsFactory. * @return Handle to the created MolecularWeights. */ extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( + GauXCStatus* status, GauXCMolecularWeightsFactory factory ); /** * @brief Get shared MolecularWeights instance from a MolecularWeightsFactory. + * @param status Status object to capture any errors. * @param factory Handle to the MolecularWeightsFactory. * @return Handle to the created MolecularWeights. */ extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_shared_instance( + GauXCStatus* status, GauXCMolecularWeightsFactory factory ); diff --git a/include/gauxc/molecule.h b/include/gauxc/molecule.h index e3f4bc7c..4d5db27e 100644 --- a/include/gauxc/molecule.h +++ b/include/gauxc/molecule.h @@ -20,6 +20,7 @@ #include #include #endif +#include #include #ifdef __cplusplus @@ -36,30 +37,34 @@ typedef struct GauXCMolecule { /** * @brief Create a new empty Molecule instance. + * @param status Status object to capture any errors. * @return Handle to the created Molecule. */ -extern GauXCMolecule gauxc_molecule_new(); +extern GauXCMolecule gauxc_molecule_new(GauXCStatus* status); /** * @brief Create a new Molecule instance from an array of Atoms. + * @param status Status object to capture any errors. * @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 ); +extern GauXCMolecule gauxc_molecule_new_from_atoms(GauXCStatus* status, GauXCAtom* atoms, size_t natoms ); /** * @brief Delete a Molecule instance. + * @param status Status object to capture any errors. * @param mol Handle to the Molecule to delete. */ -extern void gauxc_molecule_delete( GauXCMolecule mol ); +extern void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule mol ); /** * @brief Get the number of atoms in the Molecule. + * @param status Status object to capture any errors. * @param mol Handle to the Molecule. * @return Number of atoms in the Molecule. */ -extern size_t gauxc_molecule_natoms( GauXCMolecule mol ); +extern size_t gauxc_molecule_natoms(GauXCStatus* status, GauXCMolecule mol ); #ifdef __cplusplus } // namespace GauXC::C diff --git a/include/gauxc/molgrid.h b/include/gauxc/molgrid.h index 89d1fc0f..d324eb35 100644 --- a/include/gauxc/molgrid.h +++ b/include/gauxc/molgrid.h @@ -18,6 +18,7 @@ #else #include #endif +#include #ifdef __cplusplus extern "C" { @@ -33,6 +34,7 @@ typedef struct GauXCMolGrid { /** * @brief Create a new MolGrid instance from atomic grids. + * @param status Status object to capture any errors. * @param mol Handle to the Molecule. * @param pruning_scheme Pruning scheme to use. * @param batchsize Batch size for grid generation. @@ -41,6 +43,7 @@ typedef struct GauXCMolGrid { * @return Handle to the created MolGrid. */ extern GauXCMolGrid gauxc_molgrid_new_default( + GauXCStatus* status, GauXCMolecule mol, enum GauXC_PruningScheme pruning_scheme, int64_t batchsize, @@ -50,9 +53,11 @@ extern GauXCMolGrid gauxc_molgrid_new_default( /** * @brief Delete a MolGrid instance. + * @param status Status object to capture any errors. * @param molgrid Handle to the MolGrid to delete. */ extern void gauxc_molgrid_delete( + GauXCStatus* status, GauXCMolGrid molgrid ); diff --git a/include/gauxc/runtime_environment.h b/include/gauxc/runtime_environment.h index 17ed65ea..46afa491 100644 --- a/include/gauxc/runtime_environment.h +++ b/include/gauxc/runtime_environment.h @@ -16,6 +16,7 @@ #else #include #endif +#include #include #ifdef __cplusplus @@ -35,53 +36,70 @@ typedef struct GauXCRuntimeEnvironment { /** * @brief Create a new RuntimeEnvironment instance. + * @param status Status object to capture any errors. * @param comm MPI Communicator (if applicable). * @return Handle to the created RuntimeEnvironment. */ GauXCRuntimeEnvironment gauxc_runtime_environment_new( - GAUXC_MPI_CODE(MPI_Comm comm) + GauXCStatus* status + GAUXC_MPI_CODE(, MPI_Comm comm) ); /** * @brief Delete a RuntimeEnvironment instance. + * @param status Status object to capture any errors. * @param env Handle to the RuntimeEnvironment to delete. */ -extern void gauxc_runtime_environment_delete( GauXCRuntimeEnvironment env ); +extern void gauxc_runtime_environment_delete( + GauXCStatus* status, + GauXCRuntimeEnvironment env +); /** * @brief Get the rank of the current process in the RuntimeEnvironment's communicator. + * @param status Status object to capture any errors. * @param env Handle to the RuntimeEnvironment. * @return Rank of the current process. */ -extern int gauxc_runtime_environment_comm_rank( GauXCRuntimeEnvironment env ); - +extern int gauxc_runtime_environment_comm_rank( + GauXCStatus* status, + GauXCRuntimeEnvironment env +); /** * @brief Get the size of the RuntimeEnvironment's communicator. + * @param status Status object to capture any errors. * @param env Handle to the RuntimeEnvironment. * @return Size of the communicator. */ -extern int gauxc_runtime_environment_comm_size( GauXCRuntimeEnvironment env ); +extern int gauxc_runtime_environment_comm_size( + GauXCStatus* status, + GauXCRuntimeEnvironment env +); #ifdef GAUXC_HAS_DEVICE /** * @brief Create new DeviceRuntimeEnvironment instance. + * @param status Status object to capture any errors. * @param comm MPI Communicator (if applicable). * @param fill_fraction Fraction of device memory to use. * @return Handle to the created DeviceRuntimeEnvironment. */ GauXCRuntimeEnvironment gauxc_device_runtime_environment_new( + GauXCStatus* status, GAUXC_MPI_CODE(MPI_Comm comm,) double fill_fraction ); /** * @brief Create new DeviceRuntimeEnvironment instance. + * @param status Status object to capture any errors. * @param comm MPI Communicator (if applicable). * @param mem Pointer to preallocated device memory. * @param mem_sz Size of preallocated device memory. * @return Handle to the created DeviceRuntimeEnvironment. */ GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( + GauXCStatus* status, GAUXC_MPI_CODE(MPI_Comm comm,) void* mem, size_t mem_sz diff --git a/include/gauxc/status.h b/include/gauxc/status.h new file mode 100644 index 00000000..7adc9b25 --- /dev/null +++ b/include/gauxc/status.h @@ -0,0 +1,26 @@ +/** + * 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 + +typedef struct GauXCStatus { + int code; +} GauXCStatus; + +#ifdef __cplusplus +} // namespace GauXC::C +} // extern "C" +#endif \ No newline at end of file diff --git a/include/gauxc/xc_integrator.h b/include/gauxc/xc_integrator.h index fe517c33..30625d4c 100644 --- a/include/gauxc/xc_integrator.h +++ b/include/gauxc/xc_integrator.h @@ -18,6 +18,7 @@ #include #include #endif +#include #include #include #include @@ -37,9 +38,10 @@ typedef struct GauXCIntegrator { /** * @brief Delete an XCIntegrator instance. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator to delete. */ -extern void gauxc_xc_integrator_delete( +extern void gauxc_integrator_delete( GauXCIntegrator integrator ); @@ -52,6 +54,7 @@ typedef struct GauXCIntegratorFactory { /** * @brief Create a new XCIntegratorFactory instance. + * @param status Status object to capture any errors. * @param execution_space Execution space to use. * @param integrator_input_type Type of integrator input. * @param integrator_kernel_name Name of the integrator kernel. @@ -59,7 +62,8 @@ typedef struct GauXCIntegratorFactory { * @param reduction_kernel_name Name of the reduction kernel. * @return Handle to the created XCIntegratorFactory. */ -extern GauXCIntegratorFactory gauxc_xc_integrator_factory_new( +extern GauXCIntegratorFactory gauxc_integrator_factory_new( + GauXCStatus* status, enum GauXC_ExecutionSpace execution_space, const char* integrator_input_type, const char* integrator_kernel_name, @@ -69,20 +73,24 @@ extern GauXCIntegratorFactory gauxc_xc_integrator_factory_new( /** * @brief Delete an XCIntegratorFactory instance. + * @param status Status object to capture any errors. * @param integrator_factory Handle to the XCIntegratorFactory to delete. */ -extern void gauxc_xc_integrator_factory_delete( - GauXCIntegratorFactory integrator_factory +extern void gauxc_integrator_factory_delete( + GauXCStatus* status, + GauXCIntegratorFactory integrator_factory ); /** * @brief Get an XCIntegrator instance from an XCIntegratorFactory. + * @param status Status object to capture any errors. * @param integrator_factory Handle to the XCIntegratorFactory. * @param func Handle to the XCFunctional. * @param lb Handle to the LoadBalancer. * @return Handle to the created XCIntegrator. */ -extern GauXCIntegrator gauxc_xc_integrator_factory_get_instance( +extern GauXCIntegrator gauxc_integrator_factory_get_instance( + GauXCStatus* status, GauXCIntegratorFactory integrator_factory, enum GauXC_Functional func, GauXCLoadBalancer lb @@ -90,12 +98,14 @@ extern GauXCIntegrator gauxc_xc_integrator_factory_get_instance( /** * @brief Get a shared XCIntegrator instance from an XCIntegratorFactory. + * @param status Status object to capture any errors. * @param integrator_factory Handle to the XCIntegratorFactory. * @param func Handle to the XCFunctional. * @param lb Handle to the LoadBalancer. * @return Handle to the created XCIntegrator. */ -extern GauXCIntegrator gauxc_xc_integrator_factory_get_shared_instance( +extern GauXCIntegrator gauxc_integrator_factory_get_shared_instance( + GauXCStatus* status, GauXCIntegratorFactory integrator_factory, enum GauXC_Functional func, GauXCLoadBalancer lb @@ -103,11 +113,13 @@ extern GauXCIntegrator gauxc_xc_integrator_factory_get_shared_instance( /** * @brief Integrate the density matrix to get the number of electrons. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix Density matrix container. * @param den Pointer to store the number of electrons. */ extern void gauxc_integrator_integrate_den( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix, double* den @@ -115,11 +127,13 @@ extern void gauxc_integrator_integrate_den( /** * @brief Evaluate the exchange-correlation energy for RKS. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix Density matrix container for RKS. * @param exc Pointer to store the exchange-correlation energy. */ extern void gauxc_integrator_eval_exc_rks( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix, double* exc @@ -127,12 +141,14 @@ extern void gauxc_integrator_eval_exc_rks( /** * @brief Evaluate the exchange-correlation energy for UKS. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix_s Density matrix container for total density. * @param density_matrix_z Density matrix container for spin density. * @param exc Pointer to store the exchange-correlation energy. */ extern void gauxc_integrator_eval_exc_uks( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix_s, GauXCMatrix density_matrix_z, @@ -141,6 +157,7 @@ extern void gauxc_integrator_eval_exc_uks( /** * @brief Evaluate the exchange-correlation energy for GKS. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix_s Density matrix container for total density. * @param density_matrix_z Density matrix container for spin z density. @@ -149,6 +166,7 @@ extern void gauxc_integrator_eval_exc_uks( * @param exc Pointer to store the exchange-correlation energy. */ extern void gauxc_integrator_eval_exc_gks( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix_s, GauXCMatrix density_matrix_z, @@ -159,12 +177,14 @@ extern void gauxc_integrator_eval_exc_gks( /** * @brief Evaluate the exchange-correlation energy and potential for RKS. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix Density matrix container for RKS. * @param exc Pointer to store the exchange-correlation energy. * @param vxc_matrix Matrix container to store the exchange-correlation potential. */ extern void gauxc_integrator_eval_exc_vxc_rks( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix, double* exc, @@ -173,6 +193,7 @@ extern void gauxc_integrator_eval_exc_vxc_rks( /** * @brief Evaluate the exchange-correlation energy and potential for UKS. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix_s Density matrix container for total density. * @param density_matrix_z Density matrix container for spin density. @@ -181,6 +202,7 @@ extern void gauxc_integrator_eval_exc_vxc_rks( * @param vxc_matrix_z Matrix container to store the exchange-correlation potential for spin density */ extern void gauxc_integrator_eval_exc_vxc_uks( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix_s, GauXCMatrix density_matrix_z, @@ -191,6 +213,7 @@ extern void gauxc_integrator_eval_exc_vxc_uks( /** * @brief Evaluate the exchange-correlation energy and potential for GKS. + * @param status Status object to capture any errors. * @param integrator Handle to the XCIntegrator. * @param density_matrix_s Density matrix container for total density. * @param density_matrix_z Density matrix container for spin z density. @@ -203,6 +226,7 @@ extern void gauxc_integrator_eval_exc_vxc_uks( * @param vxc_matrix_y Matrix container to store the exchange-correlation potential for spin y component. */ extern void gauxc_integrator_eval_exc_vxc_gks( + GauXCStatus* status, GauXCIntegrator integrator, GauXCMatrix density_matrix_s, GauXCMatrix density_matrix_z, @@ -215,32 +239,6 @@ extern void gauxc_integrator_eval_exc_vxc_gks( GauXCMatrix vxc_matrix_y ); -/** - * @brief Evaluate the exchange-correlation energy gradient for RKS. - * @param integrator Handle to the XCIntegrator. - * @param density_matrix Density matrix container for RKS. - * @param exc_grad Pointer to store the exchange-correlation energy gradient. - */ -extern void gauxc_integrator_eval_exc_grad_rks( - GauXCIntegrator integrator, - GauXCMatrix density_matrix, - double* exc_grad -); - -/** - * @brief Evaluate the exchange-correlation energy gradient for UKS. - * @param integrator Handle to the XCIntegrator. - * @param density_matrix_s Density matrix container for total density. - * @param density_matrix_z Density matrix container for spin density. - * @param exc_grad Pointer to store the exchange-correlation energy gradient. - */ -extern void gauxc_integrator_eval_exc_grad_uks( - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - double* exc_grad -); - #ifdef __cplusplus } // extern "C" } // namespace GauXC::C diff --git a/src/c_basisset.cxx b/src/c_basisset.cxx index cb1be3fa..f0e6f8b3 100644 --- a/src/c_basisset.cxx +++ b/src/c_basisset.cxx @@ -18,24 +18,27 @@ namespace GauXC::C { extern "C" { -GauXCBasisSet gauxc_basisset_new() { +GauXCBasisSet gauxc_basisset_new(GauXCStatus* status) { + status->code = 0; GauXCBasisSet basis; basis.ptr = new BasisSet(); return basis; } -GauXCBasisSet gauxc_basisset_new_from_shells(GauXCShell* shells, size_t nshells, bool normalize) { - GauXCBasisSet basis; - BasisSet* basis_ptr = new BasisSet(); - basis_ptr->reserve( nshells ); - for( size_t i = 0; i < nshells; ++i ) { - basis_ptr->push_back( detail::convert_shell( shells[i], normalize ) ); - } - basis.ptr = basis_ptr; - return basis; +GauXCBasisSet gauxc_basisset_new_from_shells(GauXCStatus* status, GauXCShell* shells, size_t nshells, bool normalize) { + status->code = 0; + GauXCBasisSet basis; + BasisSet* basis_ptr = new BasisSet(); + basis_ptr->reserve( nshells ); + for( size_t i = 0; i < nshells; ++i ) { + basis_ptr->push_back( detail::convert_shell( shells[i], normalize ) ); + } + basis.ptr = basis_ptr; + return basis; } -void gauxc_basisset_delete(GauXCBasisSet basis) { +void gauxc_basisset_delete(GauXCStatus* status, GauXCBasisSet basis) { + status->code = 0; if(basis.ptr != nullptr) delete detail::get_basisset_ptr(basis); basis.ptr = nullptr; diff --git a/src/c_load_balancer.cxx b/src/c_load_balancer.cxx index 3b3d8520..f9f52be9 100644 --- a/src/c_load_balancer.cxx +++ b/src/c_load_balancer.cxx @@ -21,66 +21,76 @@ namespace GauXC::C { extern "C" { void gauxc_load_balancer_delete( - GauXCLoadBalancer lb + GauXCStatus* status, + GauXCLoadBalancer lb ) { + status->code = 0; if(lb.ptr != nullptr && lb.owned) delete detail::get_load_balancer_ptr(lb); lb.ptr = nullptr; } GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( - enum GauXC_ExecutionSpace ex, - const char* kernel_name + GauXCStatus* status, + enum GauXC_ExecutionSpace ex, + const char* kernel_name ) { - GauXCLoadBalancerFactory lbf; - LoadBalancerFactory* lbf_ptr = new LoadBalancerFactory( - static_cast(ex), - std::string(kernel_name) - ); - lbf.ptr = lbf_ptr; - return lbf; + status->code = 0; + GauXCLoadBalancerFactory lbf; + LoadBalancerFactory* lbf_ptr = new LoadBalancerFactory( + static_cast(ex), + std::string(kernel_name) + ); + lbf.ptr = lbf_ptr; + return lbf; } void gauxc_load_balancer_factory_delete( - GauXCLoadBalancerFactory lbf + GauXCStatus* status, + GauXCLoadBalancerFactory lbf ) { - if(lbf.ptr != nullptr) - delete detail::get_load_balancer_factory_ptr(lbf); - lbf.ptr = nullptr; + status->code = 0; + if(lbf.ptr != nullptr) + delete detail::get_load_balancer_factory_ptr(lbf); + lbf.ptr = nullptr; } GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( - GauXCLoadBalancerFactory lbf, - GauXCRuntimeEnvironment rt, - GauXCMolecule mol, - GauXCMolGrid mg, - GauXCBasisSet bs + GauXCStatus* status, + GauXCLoadBalancerFactory lbf, + GauXCRuntimeEnvironment rt, + GauXCMolecule mol, + GauXCMolGrid mg, + GauXCBasisSet bs ) { - LoadBalancer lb_instance = detail::get_load_balancer_factory_ptr(lbf)->get_instance( - *detail::get_runtime_environment_ptr(rt), - *detail::get_molecule_ptr(mol), - *detail::get_molgrid_ptr(mg), - *detail::get_basisset_ptr(bs) - ); - GauXCLoadBalancer lb; - lb.ptr = new LoadBalancer( std::move(lb_instance) ); - lb.owned = true; - return lb; + status->code = 0; + LoadBalancer lb_instance = detail::get_load_balancer_factory_ptr(lbf)->get_instance( + *detail::get_runtime_environment_ptr(rt), + *detail::get_molecule_ptr(mol), + *detail::get_molgrid_ptr(mg), + *detail::get_basisset_ptr(bs) + ); + GauXCLoadBalancer lb; + lb.ptr = new LoadBalancer( std::move(lb_instance) ); + lb.owned = true; + return lb; } GauXCLoadBalancer gauxc_load_balancer_delete_factory_get_shared_instance( - GauXCLoadBalancerFactory lbf, - GauXCRuntimeEnvironment rt, - GauXCMolecule mol, - GauXCMolGrid mg, - GauXCBasisSet bs + GauXCStatus* status, + GauXCLoadBalancerFactory lbf, + GauXCRuntimeEnvironment rt, + GauXCMolecule mol, + GauXCMolGrid mg, + GauXCBasisSet bs ) { - auto lb_instance_ptr = detail::get_load_balancer_factory_ptr(lbf)->get_shared_instance( - *detail::get_runtime_environment_ptr(rt), - *detail::get_molecule_ptr(mol), - *detail::get_molgrid_ptr(mg), - *detail::get_basisset_ptr(bs) - ); - GauXCLoadBalancer lb; - lb.ptr = new std::shared_ptr( std::move(lb_instance_ptr) ); - lb.owned = false; - return lb; + status->code = 0; + auto lb_instance_ptr = detail::get_load_balancer_factory_ptr(lbf)->get_shared_instance( + *detail::get_runtime_environment_ptr(rt), + *detail::get_molecule_ptr(mol), + *detail::get_molgrid_ptr(mg), + *detail::get_basisset_ptr(bs) + ); + GauXCLoadBalancer lb; + lb.ptr = new std::shared_ptr( std::move(lb_instance_ptr) ); + lb.owned = false; + return lb; } } // extern "C" diff --git a/src/c_matrix.cxx b/src/c_matrix.cxx index d094f927..cf7c412d 100644 --- a/src/c_matrix.cxx +++ b/src/c_matrix.cxx @@ -16,18 +16,22 @@ namespace GauXC::C { GauXCMatrix gauxc_matrix_new( + GauXCStatus* status, size_t rows, size_t cols ) { - GauXCMatrix matrix; - matrix.ptr = new detail::CMatrix( rows, cols ); + status->code = 0; + GauXCMatrix matrix; + matrix.ptr = new detail::CMatrix( rows, cols ); - return matrix; + return matrix; } void gauxc_matrix_delete( - GauXCMatrix matrix + GauXCStatus* status, + GauXCMatrix matrix ) { + status->code = 0; if(matrix.ptr != nullptr) delete detail::get_matrix_ptr(matrix); matrix.ptr = nullptr; diff --git a/src/c_molecular_weights.cxx b/src/c_molecular_weights.cxx index c80c6b62..79e74f8c 100644 --- a/src/c_molecular_weights.cxx +++ b/src/c_molecular_weights.cxx @@ -11,42 +11,74 @@ */ #include #include +#include +#include #include +#include namespace GauXC::C { extern "C" { GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( - enum GauXC_ExecutionSpace ex, - const char* kernel_name, - GauXCMolecularWeightsSettings settings + GauXCStatus* status, + enum GauXC_ExecutionSpace ex, + const char* kernel_name, + GauXCMolecularWeightsSettings settings ) { - GauXCMolecularWeightsFactory mwf; - MolecularWeightsFactory* mwf_ptr = new MolecularWeightsFactory( - static_cast(ex), - std::string(kernel_name), - detail::convert_molecular_weights_settings( settings ) - ); - mwf.ptr = mwf_ptr; - return mwf; + status->code = 0; + GauXCMolecularWeightsFactory mwf; + MolecularWeightsFactory* mwf_ptr = new MolecularWeightsFactory( + static_cast(ex), + std::string(kernel_name), + detail::convert_molecular_weights_settings( settings ) + ); + mwf.ptr = mwf_ptr; + return mwf; } GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( - GauXCMolecularWeightsFactory mwf + GauXCStatus* status, + GauXCMolecularWeightsFactory mwf ) { - MolecularWeights mw_instance = detail::get_molecular_weights_factory_ptr(mwf)->get_instance(); - GauXCMolecularWeights mw; - mw.ptr = new MolecularWeights( std::move(mw_instance) ); - mw.owned = true; - return mw; + status->code = 0; + MolecularWeights mw_instance = detail::get_molecular_weights_factory_ptr(mwf)->get_instance(); + GauXCMolecularWeights mw; + mw.ptr = new MolecularWeights( std::move(mw_instance) ); + mw.owned = true; + return mw; +} + + +void gauxc_molecular_weights_modify_weights( + GauXCStatus* status, + GauXCMolecularWeights mw, + GauXCLoadBalancer lb +) { + status->code = 0; + detail::get_molecular_weights_ptr(mw)->modify_weights( + *detail::get_load_balancer_ptr(lb) + ); +} + + +void gauxc_molecular_weights_delete( + GauXCStatus* status, + GauXCMolecularWeights mw +) { + status->code = 0; + if(mw.ptr != nullptr && mw.owned) + delete detail::get_molecular_weights_ptr(mw); + mw.ptr = nullptr; } void gauxc_molecular_weights_factory_delete( - GauXCMolecularWeightsFactory mwf + GauXCStatus* status, + GauXCMolecularWeightsFactory mwf ) { - if(mwf.ptr != nullptr) - delete detail::get_molecular_weights_factory_ptr(mwf); - mwf.ptr = nullptr; + status->code = 0; + if(mwf.ptr != nullptr) + delete detail::get_molecular_weights_factory_ptr(mwf); + mwf.ptr = nullptr; } } // extern "C" diff --git a/src/c_molecule.cxx b/src/c_molecule.cxx index 8493a85d..cd8876d8 100644 --- a/src/c_molecule.cxx +++ b/src/c_molecule.cxx @@ -19,30 +19,34 @@ namespace GauXC::C { extern "C" { -GauXCMolecule gauxc_molecule_new() { +GauXCMolecule gauxc_molecule_new(GauXCStatus* status) { + status->code = 0; 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; +GauXCMolecule gauxc_molecule_new_from_atoms(GauXCStatus* status, GauXCAtom* atoms, size_t natoms) { + status->code = 0; + 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) { +void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule mol) { + status->code = 0; if(mol.ptr != nullptr) delete detail::get_molecule_ptr(mol); mol.ptr = nullptr; } -size_t gauxc_molecule_natoms(GauXCMolecule mol) { +size_t gauxc_molecule_natoms(GauXCStatus* status, GauXCMolecule mol) { + status->code = 0; if(mol.ptr == nullptr) return 0; return detail::get_molecule_ptr(mol)->natoms(); } diff --git a/src/c_molgrid.cxx b/src/c_molgrid.cxx index 9ada54df..23ef2274 100644 --- a/src/c_molgrid.cxx +++ b/src/c_molgrid.cxx @@ -21,12 +21,14 @@ namespace GauXC::C { extern "C" { GauXCMolGrid gauxc_molgrid_new_default( + GauXCStatus* status, GauXCMolecule mol, enum GauXC_PruningScheme pruning_scheme, int64_t batchsize, enum GauXC_RadialQuad radial_quad, enum GauXC_AtomicGridSizeDefault grid_size ) { + status->code = 0; auto grid_map = MolGridFactory::create_default_gridmap( *detail::get_molecule_ptr(mol), static_cast(pruning_scheme), @@ -40,7 +42,8 @@ GauXCMolGrid gauxc_molgrid_new_default( return mg; } -void gauxc_molgrid_delete(GauXCMolGrid mg) { +void gauxc_molgrid_delete(GauXCStatus* status, GauXCMolGrid mg) { + status->code = 0; if(mg.ptr != nullptr) delete detail::get_molgrid_ptr(mg); mg.ptr = nullptr; diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx index f9307044..ab30914a 100644 --- a/src/c_runtime_environment.cxx +++ b/src/c_runtime_environment.cxx @@ -17,15 +17,18 @@ namespace GauXC::C { extern "C" { GauXCRuntimeEnvironment gauxc_runtime_environment_new( - GAUXC_MPI_CODE(MPI_Comm comm) + GauXCStatus* status + GAUXC_MPI_CODE(, MPI_Comm comm) ) { + status->code = 0; GauXCRuntimeEnvironment env; RuntimeEnvironment* env_ptr = new RuntimeEnvironment( GAUXC_MPI_CODE(comm) ); env.ptr = env_ptr; return env; } -void gauxc_runtime_environment_delete(GauXCRuntimeEnvironment env) { +void gauxc_runtime_environment_delete(GauXCStatus* status, GauXCRuntimeEnvironment env) { + status->code = 0; if(env.ptr != nullptr) delete detail::get_runtime_environment_ptr(env); env.ptr = nullptr; @@ -36,38 +39,44 @@ void gauxc_runtime_environment_delete(GauXCRuntimeEnvironment env) { #endif } -int gauxc_runtime_environment_comm_rank(GauXCRuntimeEnvironment env) { +int gauxc_runtime_environment_comm_rank(GauXCStatus* status, GauXCRuntimeEnvironment env) { + status->code = 0; return detail::get_runtime_environment_ptr(env)->comm_rank(); } -int gauxc_runtime_environment_comm_size(GauXCRuntimeEnvironment env) { +int gauxc_runtime_environment_comm_size(GauXCStatus* status, GauXCRuntimeEnvironment env) { + status->code = 0; return detail::get_runtime_environment_ptr(env)->comm_size(); } #ifdef GAUXC_HAS_DEVICE GauXCRuntimeEnvironment gauxc_device_runtime_environment_new( + GauXCStatus* status, GAUXC_MPI_CODE(MPI_Comm comm,) double fill_fraction ) { - GauXCRuntimeEnvironment env; - DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( - GAUXC_MPI_CODE(comm,) fill_fraction - ); - env.device_ptr = dev_env_ptr; - return env; + status->code = 0; + GauXCRuntimeEnvironment env; + DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( + GAUXC_MPI_CODE(comm,) fill_fraction + ); + env.device_ptr = dev_env_ptr; + return env; } GauXCRuntimeEnvironment gauxc_device_runtime_environment_new_mem( + GauXCStatus* status, GAUXC_MPI_CODE(MPI_Comm comm,) void* mem, size_t mem_sz ) { - GauXCRuntimeEnvironment env; - DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( - GAUXC_MPI_CODE(comm,) mem, mem_sz - ); - env.device_ptr = dev_env_ptr; - return env; + status->code = 0; + GauXCRuntimeEnvironment env; + DeviceRuntimeEnvironment* dev_env_ptr = new DeviceRuntimeEnvironment( + GAUXC_MPI_CODE(comm,) mem, mem_sz + ); + env.device_ptr = dev_env_ptr; + return env; } #endif diff --git a/src/c_xc_integrator.cxx b/src/c_xc_integrator.cxx index 22043ddd..67cf0e79 100644 --- a/src/c_xc_integrator.cxx +++ b/src/c_xc_integrator.cxx @@ -18,70 +18,374 @@ namespace GauXC::C { extern "C" { -void gauxc_xc_integrator_delete( - GauXCIntegrator integrator +void gauxc_integrator_delete( + void gauxc_integrator_eval_exc_vxc_uks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z ) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); +} + +void gauxc_integrator_eval_exc_vxc_gks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z, + GauXCMatrix vxc_matrix_x, + GauXCMatrix vxc_matrix_y +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); +} + +void + GauXCStatus* status, + GauXCIntegrator integrator +) { + status->code = 0; if(integrator.ptr != nullptr && integrator.owned) delete detail::get_xc_integrator_ptr(integrator); integrator.ptr = nullptr; } -void gauxc_xc_integrator_factory_delete( - GauXCIntegratorFactory factory) +void gauxc_integrator_factory_delete( + void gauxc_integrator_eval_exc_vxc_uks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); +} + +void gauxc_integrator_eval_exc_vxc_gks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z, + GauXCMatrix vxc_matrix_x, + GauXCMatrix vxc_matrix_y +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); +} + +void + GauXCStatus* status, + GauXCIntegratorFactory factory) { + status->code = 0; if (factory.ptr != nullptr) delete detail::get_xc_integrator_factory_ptr(factory); factory.ptr = nullptr; } -GauXCIntegratorFactory gauxc_xc_integrator_factory_new( +GauXCIntegratorFactory gauxc_integrator_factory_new( + void gauxc_integrator_eval_exc_vxc_uks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); +} + +void gauxc_integrator_eval_exc_vxc_gks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z, + GauXCMatrix vxc_matrix_x, + GauXCMatrix vxc_matrix_y +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); +} + +void + GauXCStatus* status, enum GauXC_ExecutionSpace execution_space, const char* integrator_input_type, const char* integrator_kernel_name, const char* local_work_kernel_name, const char* reduction_kernel_name ) { + status->code = 0; GauXCIntegratorFactory factory; - XCIntegratorFactory* factory_ptr = - new XCIntegratorFactory( - static_cast(execution_space), - std::string(integrator_input_type), - std::string(integrator_kernel_name), - std::string(local_work_kernel_name), - std::string(reduction_kernel_name) - ); + XCIntegratorFactory* factory_ptr = + new XCIntegratorFactory( + static_cast(execution_space), + std::string(integrator_input_type), + std::string(integrator_kernel_name), + std::string(local_work_kernel_name), + std::string(reduction_kernel_name) + ); factory.ptr = factory_ptr; return factory; } -GauXCIntegrator gauxc_xc_integrator_factory_get_instance( - GauXCIntegratorFactory factory, - enum GauXC_Functional functional, - GauXCLoadBalancer lb +GauXCIntegrator gauxc_integrator_factory_get_instance( + void gauxc_integrator_eval_exc_vxc_uks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); +} + +void gauxc_integrator_eval_exc_vxc_gks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z, + GauXCMatrix vxc_matrix_x, + GauXCMatrix vxc_matrix_y ) { - auto integrator_instance = detail::get_xc_integrator_factory_ptr(factory)->get_instance( - static_cast(functional), - detail::get_load_balancer_ptr(lb) - ); - GauXCIntegrator integrator; - integrator.ptr = new XCIntegrator( std::move(integrator_instance) ); - integrator.owned = true; - return integrator; + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); } -GauXCIntegrator gauxc_xc_integrator_factory_get_shared_instance( +void + GauXCStatus* status, GauXCIntegratorFactory factory, enum GauXC_Functional functional, GauXCLoadBalancer lb ) { - auto integrator_instance_ptr = detail::get_xc_integrator_factory_ptr(factory)->get_shared_instance( - static_cast(functional), - detail::get_load_balancer_ptr(lb) - ); - GauXCIntegrator integrator; - integrator.ptr = new std::shared_ptr< XCIntegrator >( std::move(integrator_instance_ptr) ); - integrator.owned = false; - return integrator; + status->code = 0; + auto integrator_instance = detail::get_xc_integrator_factory_ptr(factory)->get_instance( + static_cast(functional), + detail::get_load_balancer_ptr(lb) + ); + GauXCIntegrator integrator; + integrator.ptr = new XCIntegrator( std::move(integrator_instance) ); + integrator.owned = true; + return integrator; +} + +GauXCIntegrator gauxc_integrator_factory_get_shared_instance( + GauXCStatus* status, + GauXCIntegratorFactory factory, + enum GauXC_Functional functional, + GauXCLoadBalancer lb +) { + status->code = 0; + auto integrator_instance_ptr = detail::get_xc_integrator_factory_ptr(factory)->get_shared_instance( + static_cast(functional), + detail::get_load_balancer_ptr(lb) + ); + GauXCIntegrator integrator; + integrator.ptr = new std::shared_ptr< XCIntegrator >( std::move(integrator_instance_ptr) ); + integrator.owned = false; + return integrator; +} + +void gauxc_integrator_integrate_den( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* den_out +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm = *detail::get_matrix_ptr(density_matrix); + *den_out = xc_integrator.integrate_den( dm ); +} + +void gauxc_integrator_eval_exc_rks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* exc_out +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm = *detail::get_matrix_ptr(density_matrix); + *exc_out = xc_integrator.eval_exc( dm ); +} + +void gauxc_integrator_eval_exc_uks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_out +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + *exc_out = xc_integrator.eval_exc( dm_s, dm_z ); +} + +void gauxc_integrator_eval_exc_gks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_tx, + GauXCMatrix density_matrix_ty, + double* exc_out +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_tx = *detail::get_matrix_ptr(density_matrix_tx); + auto& dm_ty = *detail::get_matrix_ptr(density_matrix_ty); + *exc_out = xc_integrator.eval_exc( dm_s, dm_z, dm_tx, dm_ty ); +} + +void gauxc_integrator_eval_exc_vxc_rks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix, + double* exc_out, + GauXCMatrix vxc_matrix +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm = *detail::get_matrix_ptr(density_matrix); + auto& vxc = *detail::get_matrix_ptr(vxc_matrix); + std::tie(*exc_out, vxc) = xc_integrator.eval_exc_vxc( dm ); +} + +void gauxc_integrator_eval_exc_vxc_uks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); +} + +void gauxc_integrator_eval_exc_vxc_gks( + GauXCStatus* status, + GauXCIntegrator integrator, + GauXCMatrix density_matrix_s, + GauXCMatrix density_matrix_z, + GauXCMatrix density_matrix_x, + GauXCMatrix density_matrix_y, + double* exc_out, + GauXCMatrix vxc_matrix_s, + GauXCMatrix vxc_matrix_z, + GauXCMatrix vxc_matrix_x, + GauXCMatrix vxc_matrix_y +) { + status->code = 0; + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); } } // extern "C" From f0bb5eb10284517df1582399a5230bc7de160cc8 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 09:48:40 +0100 Subject: [PATCH 11/15] Add functional class wrapping ExchCXX --- include/gauxc/functional.h | 45 ++++++ include/gauxc/util/c_functional.hpp | 20 +++ include/gauxc/util/c_matrix.hpp | 31 +++- include/gauxc/xc_integrator.h | 7 +- src/CMakeLists.txt | 3 + src/c_functional.cxx | 108 +++++++++++++ src/c_matrix.cxx | 4 +- src/c_xc_integrator.cxx | 226 +++------------------------- 8 files changed, 233 insertions(+), 211 deletions(-) create mode 100644 include/gauxc/util/c_functional.hpp create mode 100644 src/c_functional.cxx diff --git a/include/gauxc/functional.h b/include/gauxc/functional.h index 7ac219b2..7333f539 100644 --- a/include/gauxc/functional.h +++ b/include/gauxc/functional.h @@ -11,6 +11,8 @@ */ #pragma once +#include + #ifdef __cplusplus namespace GauXC::C { extern "C" { @@ -460,6 +462,49 @@ enum GauXC_Functional { GauXC_Functional_revM06L, }; +/** + * @brief GauXC C API Functional handle. + */ +typedef struct GauXCFunctional { + void* ptr; ///< Pointer to the Functional instance. +} GauXCFunctional; + +/** + * @brief Create a GauXCFunctional from a string specification. + * @param status Pointer to GauXCStatus for error handling. + * @param functional_spec String specification of the functional. + * @param polarized Whether the functional is spin-polarized. + * @return A handle to the created GauXCFunctional. + */ +GauXCFunctional gauxc_functional_from_string( + GauXCStatus* status, + const char* functional_spec, + bool polarized +); + +/** + * @brief Create a GauXCFunctional from a GauXC_Functional enum. + * @param status Pointer to GauXCStatus for error handling. + * @param functional_type The type of functional to create. + * @param polarized Whether the functional is spin-polarized. + * @return A handle to the created GauXCFunctional. + */ +GauXCFunctional gauxc_functional_from_enum( + GauXCStatus* status, + enum GauXC_Functional functional_type, + bool polarized +); + +/** + * @brief Delete a GauXCFunctional handle. + * @param status Pointer to GauXCStatus for error handling. + * @param functional The GauXCFunctional handle to delete. + */ +void gauxc_functional_delete( + GauXCStatus* status, + GauXCFunctional functional +); + #ifdef __cplusplus } // extern "C" } // namespace GauXC::C diff --git a/include/gauxc/util/c_functional.hpp b/include/gauxc/util/c_functional.hpp new file mode 100644 index 00000000..a23623db --- /dev/null +++ b/include/gauxc/util/c_functional.hpp @@ -0,0 +1,20 @@ +/** + * 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 +#include +#include + +namespace GauXC::detail { +static inline functional_type* get_functional_ptr(C::GauXCFunctional mol) noexcept { + return static_cast(mol.ptr); +} +} \ No newline at end of file diff --git a/include/gauxc/util/c_matrix.hpp b/include/gauxc/util/c_matrix.hpp index 4e4d4934..b45b4ddc 100644 --- a/include/gauxc/util/c_matrix.hpp +++ b/include/gauxc/util/c_matrix.hpp @@ -11,16 +11,37 @@ */ #pragma once -#define EIGEN_DONT_VECTORIZE -#define EIGEN_NO_CUDA -#include - namespace GauXC::detail { -using CMatrix = Eigen::MatrixXd; +class CMatrix { +public: + using value_type = double; + CMatrix( size_t rows, size_t cols ) { + rows_ = rows; + cols_ = cols; + data_ = new value_type[ rows * cols ](); + } + ~CMatrix() noexcept { + delete[] data_; + } + value_type * data() { return data_; } + const value_type * data() const { return data_; } + size_t rows() const { return rows_; } + size_t cols() const { return cols_; } + void setZero() { + for( size_t i = 0; i < rows_ * cols_; ++i ) + data_[i] = value_type(0); + } + +private: + size_t rows_; + size_t cols_; + value_type* data_; +}; static inline CMatrix* get_matrix_ptr(C::GauXCMatrix matrix) noexcept { return static_cast(matrix.ptr); } + } // namespace GauXC::detail \ No newline at end of file diff --git a/include/gauxc/xc_integrator.h b/include/gauxc/xc_integrator.h index 30625d4c..29770c38 100644 --- a/include/gauxc/xc_integrator.h +++ b/include/gauxc/xc_integrator.h @@ -42,7 +42,8 @@ typedef struct GauXCIntegrator { * @param integrator Handle to the XCIntegrator to delete. */ extern void gauxc_integrator_delete( - GauXCIntegrator integrator + GauXCStatus* status, + GauXCIntegrator integrator ); /** @@ -92,7 +93,7 @@ extern void gauxc_integrator_factory_delete( extern GauXCIntegrator gauxc_integrator_factory_get_instance( GauXCStatus* status, GauXCIntegratorFactory integrator_factory, - enum GauXC_Functional func, + GauXCFunctional func, GauXCLoadBalancer lb ); @@ -107,7 +108,7 @@ extern GauXCIntegrator gauxc_integrator_factory_get_instance( extern GauXCIntegrator gauxc_integrator_factory_get_shared_instance( GauXCStatus* status, GauXCIntegratorFactory integrator_factory, - enum GauXC_Functional func, + GauXCFunctional func, GauXCLoadBalancer lb ); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 68c022d5..fac5b158 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -51,6 +51,9 @@ if( GAUXC_ENABLE_C ) c_runtime_environment.cxx c_load_balancer.cxx c_molecular_weights.cxx + c_matrix.cxx + c_functional.cxx + c_xc_integrator.cxx ) endif() diff --git a/src/c_functional.cxx b/src/c_functional.cxx new file mode 100644 index 00000000..d5f05050 --- /dev/null +++ b/src/c_functional.cxx @@ -0,0 +1,108 @@ +/** + * 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 +#include + +namespace GauXC::detail { +/** + * Splits a string into tokens based on a delimiter + * + * \param [out] tokens std::vector of std::string objects which hold + * the split tokens + * \param [in] str std::string to split + * \param [in] delimiters Delimiters on which to split str + */ +static inline void split(std::vector& tokens, + const std::string& str, const std::string& delimiters = " ") { + + tokens.clear(); + // Skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } +}; // split +} // namespace GauXC::detail + +namespace GauXC::C { +extern "C" { + +GauXCFunctional gauxc_functional_from_string( + GauXCStatus* status, + const char* functional_spec, + bool polarized +) { + status->code = 0; + + auto polar = polarized ? ExchCXX::Spin::Polarized : ExchCXX::Spin::Unpolarized; + functional_type func; + if(ExchCXX::functional_map.key_exists(functional_spec)) { + func = functional_type( ExchCXX::Backend::builtin, ExchCXX::functional_map.value(functional_spec), + polar ); + } +#ifdef EXCHCXX_ENABLE_LIBXC + else { + std::vector> funcs; + std::vector libxc_names; + detail::split(libxc_names, functional_spec, ","); + for( auto n : libxc_names ) { + funcs.push_back( {1.0, ExchCXX::XCKernel(ExchCXX::libxc_name_string(n), polar)} ); + } + func = functional_type(funcs); + } +#endif + + GauXCFunctional functional; + functional.ptr = new functional_type( std::move(func) ); + return functional; +} + +GauXCFunctional gauxc_functional_from_enum( + GauXCStatus* status, + enum GauXC_Functional functional_enum, + bool polarized +) { + status->code = 0; + + auto polar = polarized ? ExchCXX::Spin::Polarized : ExchCXX::Spin::Unpolarized; + functional_type func( ExchCXX::Backend::builtin, + static_cast(functional_enum), polar ); + + GauXCFunctional functional; + functional.ptr = new functional_type( std::move(func) ); + return functional; +} + +void gauxc_functional_delete( + GauXCStatus* status, + GauXCFunctional functional +) { + status->code = 0; + if(functional.ptr != nullptr) + delete detail::get_functional_ptr(functional); + functional.ptr = nullptr; +} + +} // extern "C" +} // namespace GauXC::C \ No newline at end of file diff --git a/src/c_matrix.cxx b/src/c_matrix.cxx index cf7c412d..902e37f3 100644 --- a/src/c_matrix.cxx +++ b/src/c_matrix.cxx @@ -17,8 +17,8 @@ namespace GauXC::C { GauXCMatrix gauxc_matrix_new( GauXCStatus* status, - size_t rows, - size_t cols + size_t rows, + size_t cols ) { status->code = 0; GauXCMatrix matrix; diff --git a/src/c_xc_integrator.cxx b/src/c_xc_integrator.cxx index 67cf0e79..e90c1077 100644 --- a/src/c_xc_integrator.cxx +++ b/src/c_xc_integrator.cxx @@ -13,167 +13,37 @@ #include #include #include +#include #include namespace GauXC::C { extern "C" { void gauxc_integrator_delete( - void gauxc_integrator_eval_exc_vxc_uks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); -} - -void gauxc_integrator_eval_exc_vxc_gks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z, - GauXCMatrix vxc_matrix_x, - GauXCMatrix vxc_matrix_y -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); - auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); - std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); -} - -void GauXCStatus* status, GauXCIntegrator integrator ) { status->code = 0; - if(integrator.ptr != nullptr && integrator.owned) - delete detail::get_xc_integrator_ptr(integrator); + if(integrator.ptr != nullptr) { + if(integrator.owned) + delete detail::get_xc_integrator_ptr(integrator); + else + delete static_cast >*>(integrator.ptr); + } integrator.ptr = nullptr; } void gauxc_integrator_factory_delete( - void gauxc_integrator_eval_exc_vxc_uks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); -} - -void gauxc_integrator_eval_exc_vxc_gks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z, - GauXCMatrix vxc_matrix_x, - GauXCMatrix vxc_matrix_y + GauXCIntegratorFactory factory ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); - auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); - std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); -} - -void - GauXCStatus* status, - GauXCIntegratorFactory factory) -{ - status->code = 0; - if (factory.ptr != nullptr) + if(factory.ptr != nullptr) delete detail::get_xc_integrator_factory_ptr(factory); factory.ptr = nullptr; } GauXCIntegratorFactory gauxc_integrator_factory_new( - void gauxc_integrator_eval_exc_vxc_uks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); -} - -void gauxc_integrator_eval_exc_vxc_gks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z, - GauXCMatrix vxc_matrix_x, - GauXCMatrix vxc_matrix_y -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); - auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); - std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); -} - -void GauXCStatus* status, enum GauXC_ExecutionSpace execution_space, const char* integrator_input_type, @@ -183,73 +53,27 @@ void ) { status->code = 0; GauXCIntegratorFactory factory; - XCIntegratorFactory* factory_ptr = - new XCIntegratorFactory( - static_cast(execution_space), - std::string(integrator_input_type), - std::string(integrator_kernel_name), - std::string(local_work_kernel_name), - std::string(reduction_kernel_name) - ); - factory.ptr = factory_ptr; + factory.ptr = new XCIntegratorFactory( + static_cast(execution_space), + std::string(integrator_input_type), + std::string(integrator_kernel_name), + std::string(local_work_kernel_name), + std::string(reduction_kernel_name) + ); return factory; } -GauXCIntegrator gauxc_integrator_factory_get_instance( - void gauxc_integrator_eval_exc_vxc_uks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); -} -void gauxc_integrator_eval_exc_vxc_gks( - GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, - double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z, - GauXCMatrix vxc_matrix_x, - GauXCMatrix vxc_matrix_y -) { - status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); - auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); - std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); -} - -void +GauXCIntegrator gauxc_integrator_factory_get_instance( GauXCStatus* status, - GauXCIntegratorFactory factory, - enum GauXC_Functional functional, - GauXCLoadBalancer lb + GauXCIntegratorFactory factory, + GauXCFunctional functional, + GauXCLoadBalancer lb ) { status->code = 0; auto integrator_instance = detail::get_xc_integrator_factory_ptr(factory)->get_instance( - static_cast(functional), - detail::get_load_balancer_ptr(lb) + *detail::get_functional_ptr(functional), + *detail::get_load_balancer_ptr(lb) ); GauXCIntegrator integrator; integrator.ptr = new XCIntegrator( std::move(integrator_instance) ); @@ -260,13 +84,13 @@ void GauXCIntegrator gauxc_integrator_factory_get_shared_instance( GauXCStatus* status, GauXCIntegratorFactory factory, - enum GauXC_Functional functional, + GauXCFunctional functional, GauXCLoadBalancer lb ) { status->code = 0; auto integrator_instance_ptr = detail::get_xc_integrator_factory_ptr(factory)->get_shared_instance( - static_cast(functional), - detail::get_load_balancer_ptr(lb) + *detail::get_functional_ptr(functional), + *detail::get_load_balancer_ptr(lb) ); GauXCIntegrator integrator; integrator.ptr = new std::shared_ptr< XCIntegrator >( std::move(integrator_instance_ptr) ); From 5881a76d5c15134fe1eb6895e1a343685e73f149 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 10:47:22 +0100 Subject: [PATCH 12/15] Update to work with shared pointers --- include/gauxc/util/c_load_balancer.hpp | 3 + include/gauxc/util/c_molecular_weights.hpp | 3 + include/gauxc/util/c_xc_integrator.hpp | 38 +++++- src/c_load_balancer.cxx | 11 +- src/c_molecular_weights.cxx | 41 +++++- src/c_xc_integrator.cxx | 143 ++++++++++++++------- 6 files changed, 184 insertions(+), 55 deletions(-) diff --git a/include/gauxc/util/c_load_balancer.hpp b/include/gauxc/util/c_load_balancer.hpp index ee340456..2c701357 100644 --- a/include/gauxc/util/c_load_balancer.hpp +++ b/include/gauxc/util/c_load_balancer.hpp @@ -18,6 +18,9 @@ namespace GauXC::detail { static inline LoadBalancer* get_load_balancer_ptr(C::GauXCLoadBalancer lb) noexcept { return static_cast(lb.ptr); } +static inline std::shared_ptr* get_load_balancer_shared(C::GauXCLoadBalancer lb) noexcept { + return static_cast*>(lb.ptr); +} static inline LoadBalancerFactory* get_load_balancer_factory_ptr(C::GauXCLoadBalancerFactory lbf) noexcept { return static_cast(lbf.ptr); } diff --git a/include/gauxc/util/c_molecular_weights.hpp b/include/gauxc/util/c_molecular_weights.hpp index fef3e82e..87fa65ab 100644 --- a/include/gauxc/util/c_molecular_weights.hpp +++ b/include/gauxc/util/c_molecular_weights.hpp @@ -18,6 +18,9 @@ namespace GauXC::detail { static inline MolecularWeights* get_molecular_weights_ptr(C::GauXCMolecularWeights mw) noexcept { return static_cast(mw.ptr); } +static inline std::shared_ptr* get_molecular_weights_shared(C::GauXCMolecularWeights mw) noexcept { + return static_cast*>(mw.ptr); +} static inline MolecularWeightsFactory* get_molecular_weights_factory_ptr(C::GauXCMolecularWeightsFactory mwf) noexcept { return static_cast(mwf.ptr); } diff --git a/include/gauxc/util/c_xc_integrator.hpp b/include/gauxc/util/c_xc_integrator.hpp index 23ce9e53..9a456be9 100644 --- a/include/gauxc/util/c_xc_integrator.hpp +++ b/include/gauxc/util/c_xc_integrator.hpp @@ -15,15 +15,51 @@ #include #include #include +#include +#include namespace GauXC::detail { static inline XCIntegrator* get_xc_integrator_ptr(C::GauXCIntegrator integrator) noexcept { return static_cast*>(integrator.ptr); } - +static inline std::shared_ptr>* get_xc_integrator_shared(C::GauXCIntegrator integrator) noexcept { + return static_cast>*>(integrator.ptr); +} static inline XCIntegratorFactory* get_xc_integrator_factory_ptr(C::GauXCIntegratorFactory factory) noexcept { return static_cast*>(factory.ptr); } +static inline XCIntegrator get_integrator_instance( + C::GauXCIntegratorFactory factory, + C::GauXCFunctional functional, + C::GauXCLoadBalancer lb +) { + if (lb.owned) + return get_xc_integrator_factory_ptr(factory)->get_instance( + *get_functional_ptr(functional), + *get_load_balancer_ptr(lb) + ); + else + return get_xc_integrator_factory_ptr(factory)->get_instance( + *get_functional_ptr(functional), + **get_load_balancer_shared(lb) + ); +} +static inline std::shared_ptr> get_shared_integrator_instance( + C::GauXCIntegratorFactory factory, + C::GauXCFunctional functional, + C::GauXCLoadBalancer lb +) { + if (lb.owned) + return get_xc_integrator_factory_ptr(factory)->get_shared_instance( + *get_functional_ptr(functional), + *get_load_balancer_ptr(lb) + ); + else + return get_xc_integrator_factory_ptr(factory)->get_shared_instance( + *get_functional_ptr(functional), + **get_load_balancer_shared(lb) + ); +} } // namespace GauXC::detail \ No newline at end of file diff --git a/src/c_load_balancer.cxx b/src/c_load_balancer.cxx index f9f52be9..1de72d45 100644 --- a/src/c_load_balancer.cxx +++ b/src/c_load_balancer.cxx @@ -25,8 +25,12 @@ void gauxc_load_balancer_delete( GauXCLoadBalancer lb ) { status->code = 0; - if(lb.ptr != nullptr && lb.owned) - delete detail::get_load_balancer_ptr(lb); + if(lb.ptr != nullptr) { + if (lb.owned) + delete detail::get_load_balancer_ptr(lb); + else + delete detail::get_load_balancer_shared(lb); + } lb.ptr = nullptr; } GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( @@ -72,7 +76,8 @@ GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( lb.owned = true; return lb; } -GauXCLoadBalancer gauxc_load_balancer_delete_factory_get_shared_instance( + +GauXCLoadBalancer gauxc_load_balancer_factory_get_shared_instance( GauXCStatus* status, GauXCLoadBalancerFactory lbf, GauXCRuntimeEnvironment rt, diff --git a/src/c_molecular_weights.cxx b/src/c_molecular_weights.cxx index 79e74f8c..be1acd97 100644 --- a/src/c_molecular_weights.cxx +++ b/src/c_molecular_weights.cxx @@ -47,6 +47,17 @@ GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( return mw; } +GauXCMolecularWeights gauxc_molecular_weights_factory_get_shared_instance( + GauXCStatus* status, + GauXCMolecularWeightsFactory mwf +) { + status->code = 0; + auto mw_instance_ptr = detail::get_molecular_weights_factory_ptr(mwf)->get_shared_instance(); + GauXCMolecularWeights mw; + mw.ptr = new std::shared_ptr( std::move(mw_instance_ptr) ); + mw.owned = false; + return mw; +} void gauxc_molecular_weights_modify_weights( GauXCStatus* status, @@ -54,9 +65,25 @@ void gauxc_molecular_weights_modify_weights( GauXCLoadBalancer lb ) { status->code = 0; - detail::get_molecular_weights_ptr(mw)->modify_weights( - *detail::get_load_balancer_ptr(lb) - ); + if (mw.owned) { + if (lb.owned) + detail::get_molecular_weights_ptr(mw)->modify_weights( + *detail::get_load_balancer_ptr(lb) + ); + else + detail::get_molecular_weights_ptr(mw)->modify_weights( + **detail::get_load_balancer_shared(lb) + ); + } else { + if (lb.owned) + detail::get_molecular_weights_shared(mw)->get()->modify_weights( + *detail::get_load_balancer_ptr(lb) + ); + else + detail::get_molecular_weights_shared(mw)->get()->modify_weights( + **detail::get_load_balancer_shared(lb) + ); + } } @@ -65,8 +92,12 @@ void gauxc_molecular_weights_delete( GauXCMolecularWeights mw ) { status->code = 0; - if(mw.ptr != nullptr && mw.owned) - delete detail::get_molecular_weights_ptr(mw); + if(mw.ptr != nullptr) { + if (mw.owned) + delete detail::get_molecular_weights_ptr(mw); + else + delete detail::get_molecular_weights_shared(mw); + } mw.ptr = nullptr; } diff --git a/src/c_xc_integrator.cxx b/src/c_xc_integrator.cxx index e90c1077..2435fb2f 100644 --- a/src/c_xc_integrator.cxx +++ b/src/c_xc_integrator.cxx @@ -28,7 +28,7 @@ void gauxc_integrator_delete( if(integrator.owned) delete detail::get_xc_integrator_ptr(integrator); else - delete static_cast >*>(integrator.ptr); + delete detail::get_xc_integrator_shared(integrator); } integrator.ptr = nullptr; } @@ -71,10 +71,7 @@ GauXCIntegrator gauxc_integrator_factory_get_instance( GauXCLoadBalancer lb ) { status->code = 0; - auto integrator_instance = detail::get_xc_integrator_factory_ptr(factory)->get_instance( - *detail::get_functional_ptr(functional), - *detail::get_load_balancer_ptr(lb) - ); + auto integrator_instance = detail::get_integrator_instance(factory, functional, lb); GauXCIntegrator integrator; integrator.ptr = new XCIntegrator( std::move(integrator_instance) ); integrator.owned = true; @@ -88,12 +85,9 @@ GauXCIntegrator gauxc_integrator_factory_get_shared_instance( GauXCLoadBalancer lb ) { status->code = 0; - auto integrator_instance_ptr = detail::get_xc_integrator_factory_ptr(factory)->get_shared_instance( - *detail::get_functional_ptr(functional), - *detail::get_load_balancer_ptr(lb) - ); + auto integrator_instance = detail::get_shared_integrator_instance(factory, functional, lb); GauXCIntegrator integrator; - integrator.ptr = new std::shared_ptr< XCIntegrator >( std::move(integrator_instance_ptr) ); + integrator.ptr = new std::shared_ptr< XCIntegrator >( std::move(integrator_instance) ); integrator.owned = false; return integrator; } @@ -105,9 +99,15 @@ void gauxc_integrator_integrate_den( double* den_out ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm = *detail::get_matrix_ptr(density_matrix); - *den_out = xc_integrator.integrate_den( dm ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm = *detail::get_matrix_ptr(density_matrix); + *den_out = xc_integrator.integrate_den( dm ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm = *detail::get_matrix_ptr(density_matrix); + *den_out = xc_integrator.integrate_den( dm ); + } } void gauxc_integrator_eval_exc_rks( @@ -117,9 +117,15 @@ void gauxc_integrator_eval_exc_rks( double* exc_out ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm = *detail::get_matrix_ptr(density_matrix); - *exc_out = xc_integrator.eval_exc( dm ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm = *detail::get_matrix_ptr(density_matrix); + *exc_out = xc_integrator.eval_exc( dm ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm = *detail::get_matrix_ptr(density_matrix); + *exc_out = xc_integrator.eval_exc( dm ); + } } void gauxc_integrator_eval_exc_uks( @@ -130,10 +136,17 @@ void gauxc_integrator_eval_exc_uks( double* exc_out ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - *exc_out = xc_integrator.eval_exc( dm_s, dm_z ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + *exc_out = xc_integrator.eval_exc( dm_s, dm_z ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + *exc_out = xc_integrator.eval_exc( dm_s, dm_z ); + } } void gauxc_integrator_eval_exc_gks( @@ -146,12 +159,21 @@ void gauxc_integrator_eval_exc_gks( double* exc_out ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_tx = *detail::get_matrix_ptr(density_matrix_tx); - auto& dm_ty = *detail::get_matrix_ptr(density_matrix_ty); - *exc_out = xc_integrator.eval_exc( dm_s, dm_z, dm_tx, dm_ty ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_tx = *detail::get_matrix_ptr(density_matrix_tx); + auto& dm_ty = *detail::get_matrix_ptr(density_matrix_ty); + *exc_out = xc_integrator.eval_exc( dm_s, dm_z, dm_tx, dm_ty ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_tx = *detail::get_matrix_ptr(density_matrix_tx); + auto& dm_ty = *detail::get_matrix_ptr(density_matrix_ty); + *exc_out = xc_integrator.eval_exc( dm_s, dm_z, dm_tx, dm_ty ); + } } void gauxc_integrator_eval_exc_vxc_rks( @@ -162,10 +184,17 @@ void gauxc_integrator_eval_exc_vxc_rks( GauXCMatrix vxc_matrix ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm = *detail::get_matrix_ptr(density_matrix); - auto& vxc = *detail::get_matrix_ptr(vxc_matrix); - std::tie(*exc_out, vxc) = xc_integrator.eval_exc_vxc( dm ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm = *detail::get_matrix_ptr(density_matrix); + auto& vxc = *detail::get_matrix_ptr(vxc_matrix); + std::tie(*exc_out, vxc) = xc_integrator.eval_exc_vxc( dm ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm = *detail::get_matrix_ptr(density_matrix); + auto& vxc = *detail::get_matrix_ptr(vxc_matrix); + std::tie(*exc_out, vxc) = xc_integrator.eval_exc_vxc( dm ); + } } void gauxc_integrator_eval_exc_vxc_uks( @@ -178,12 +207,21 @@ void gauxc_integrator_eval_exc_vxc_uks( GauXCMatrix vxc_matrix_z ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); + } } void gauxc_integrator_eval_exc_vxc_gks( @@ -200,16 +238,29 @@ void gauxc_integrator_eval_exc_vxc_gks( GauXCMatrix vxc_matrix_y ) { status->code = 0; - auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); - auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); - auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); - auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); - std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); + if (integrator.owned) { + auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); + } else { + auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); + auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); + auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); + auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); + auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); + auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); + auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); + auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); + std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); + } } } // extern "C" From 376bd83a9f04f601074bc7ad3926674ab29fb5e1 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 13:17:12 +0100 Subject: [PATCH 13/15] Add support for reading and writing from HDF5 in C --- include/gauxc/external/hdf5.h | 108 ++++++++++++++++++++++++++++++++ include/gauxc/util/c_matrix.hpp | 7 +++ src/external/CMakeLists.txt | 3 + src/external/c_hdf5_read.cxx | 94 +++++++++++++++++++++++++++ src/external/c_hdf5_write.cxx | 92 +++++++++++++++++++++++++++ 5 files changed, 304 insertions(+) create mode 100644 include/gauxc/external/hdf5.h create mode 100644 src/external/c_hdf5_read.cxx create mode 100644 src/external/c_hdf5_write.cxx diff --git a/include/gauxc/external/hdf5.h b/include/gauxc/external/hdf5.h new file mode 100644 index 00000000..89e807e9 --- /dev/null +++ b/include/gauxc/external/hdf5.h @@ -0,0 +1,108 @@ +/** + * 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 +#ifdef GAUXC_HAS_HDF5 +#include +#include +#include +#include + +namespace GauXC::C { +extern "C" { + +/** + * @brief Write a Molecule record to an HDF5 file. + * @param status Status object to capture any errors. + * @param mol Handle to the Molecule to write. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +extern void gauxc_molecule_write_hdf5_record( + GauXCStatus* status, + GauXCMolecule mol, + const char* fname, + const char* dset +); + +/** + * @brief Write a BasisSet record to an HDF5 file. + * @param status Status object to capture any errors. + * @param basis Handle to the BasisSet to write. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +extern void gauxc_basisset_write_hdf5_record( + GauXCStatus* status, + GauXCBasisSet basis, + const char* fname, + const char* dset +); + +/** + * @brief Write a CMatrix record to an HDF5 file. + * @param status Status object to capture any errors. + * @param matrix Handle to the CMatrix to write. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +extern void gauxc_matrix_write_hdf5_record( + GauXCStatus* status, + GauXCMatrix matrix, + const char* fname, + const char* dset +); + +/** + * @brief Read a Molecule record from an HDF5 file. + * @param status Status object to capture any errors. + * @param mol Handle to the Molecule to read into. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +extern void gauxc_molecule_read_hdf5_record( + GauXCStatus* status, + GauXCMolecule mol, + const char* fname, + const char* dset +); + +/** + * @brief Read a BasisSet record from an HDF5 file. + * @param status Status object to capture any errors. + * @param basis Handle to the BasisSet to read into. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +extern void gauxc_basisset_read_hdf5_record( + GauXCStatus* status, + GauXCBasisSet basis, + const char* fname, + const char* dset +); + +/** + * @brief Read a CMatrix record from an HDF5 file. + * @param status Status object to capture any errors. + * @param matrix Handle to the CMatrix to read into. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +extern void gauxc_matrix_read_hdf5_record( + GauXCStatus* status, + GauXCMatrix matrix, + const char* fname, + const char* dset +); + +} // extern "C" +} // namespace GauXC::C +#endif \ No newline at end of file diff --git a/include/gauxc/util/c_matrix.hpp b/include/gauxc/util/c_matrix.hpp index b45b4ddc..4f18fb2a 100644 --- a/include/gauxc/util/c_matrix.hpp +++ b/include/gauxc/util/c_matrix.hpp @@ -32,6 +32,13 @@ class CMatrix { for( size_t i = 0; i < rows_ * cols_; ++i ) data_[i] = value_type(0); } + void resize( size_t rows, size_t cols ) { + if( rows == rows_ && cols == cols_ ) return; + delete[] data_; + rows_ = rows; + cols_ = cols; + data_ = new value_type[ rows * cols ](); + } private: size_t rows_; diff --git a/src/external/CMakeLists.txt b/src/external/CMakeLists.txt index 46612c81..a5394d6d 100644 --- a/src/external/CMakeLists.txt +++ b/src/external/CMakeLists.txt @@ -33,6 +33,9 @@ if( GAUXC_ENABLE_HDF5 ) endif() target_sources( gauxc PRIVATE hdf5_write.cxx hdf5_read.cxx ) + if( GAUXC_ENABLE_C ) + target_sources( gauxc PRIVATE c_hdf5_read.cxx c_hdf5_write.cxx ) + endif() target_link_libraries( gauxc PUBLIC HighFive ) else() message(WARNING "GAUXC_ENABLE_HDF5 was enabled, but HDF5 was not found, Disabling HDF5 Bindings") diff --git a/src/external/c_hdf5_read.cxx b/src/external/c_hdf5_read.cxx new file mode 100644 index 00000000..beb89164 --- /dev/null +++ b/src/external/c_hdf5_read.cxx @@ -0,0 +1,94 @@ +/** + * 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 +#include +#include "hdf5_util.hpp" + +namespace GauXC::C { +extern "C" { + +/** + * @brief Read a Molecule record from an HDF5 file. + * @param status Status object to capture any errors. + * @param mol Handle to the Molecule to read into. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +void gauxc_molecule_read_hdf5_record( + GauXCStatus* status, + GauXCMolecule mol, + const char* fname, + const char* dset +) { + status->code = 0; + try { + read_hdf5_record( *detail::get_molecule_ptr(mol), std::string(fname), std::string(dset) ); + } catch(...) { + status->code = 1; + } +} + +/** + * @brief Read a BasisSet record from an HDF5 file. + * @param status Status object to capture any errors. + * @param basis Handle to the BasisSet to read into. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +void gauxc_basisset_read_hdf5_record( + GauXCStatus* status, + GauXCBasisSet basis, + const char* fname, + const char* dset +) { + status->code = 0; + try { + read_hdf5_record( *detail::get_basisset_ptr(basis), std::string(fname), std::string(dset) ); + } catch(...) { + status->code = 1; + } +} + +/** + * @brief Read a CMatrix record from an HDF5 file. + * @param status Status object to capture any errors. + * @param matrix Handle to the CMatrix to read into. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +void gauxc_matrix_read_hdf5_record( + GauXCStatus* status, + GauXCMatrix matrix, + const char* fname, + const char* dset +) { + status->code = 0; + detail::CMatrix& mat = *detail::get_matrix_ptr(matrix); + try { + HighFive::File file( std::string(fname), HighFive::File::ReadOnly ); + + auto dataset = file.getDataSet(std::string(dset)); + auto dims = dataset.getDimensions(); + + mat.resize( dims[0], dims[1] ); + + dataset.read(mat.data()); + } catch(...) { + status->code = 1; + } +} + +} // extern "C" +} // namespace GauXC::C \ No newline at end of file diff --git a/src/external/c_hdf5_write.cxx b/src/external/c_hdf5_write.cxx new file mode 100644 index 00000000..94ce6ef2 --- /dev/null +++ b/src/external/c_hdf5_write.cxx @@ -0,0 +1,92 @@ +/** + * 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 +#include +#include "hdf5_util.hpp" + +namespace GauXC::C { +extern "C" { + +/** + * @brief Write a Molecule record to an HDF5 file. + * @param status Status object to capture any errors. + * @param mol Handle to the Molecule to write. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +void gauxc_molecule_write_hdf5_record( + GauXCStatus* status, + GauXCMolecule mol, + const char* fname, + const char* dset +) { + status->code = 0; + try { + write_hdf5_record( *detail::get_molecule_ptr(mol), std::string(fname), std::string(dset) ); + } catch(...) { + status->code = 1; + } +} + +/** + * @brief Write a BasisSet record to an HDF5 file. + * @param status Status object to capture any errors. + * @param basis Handle to the BasisSet to write. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +void gauxc_basisset_write_hdf5_record( + GauXCStatus* status, + GauXCBasisSet basis, + const char* fname, + const char* dset +) { + status->code = 0; + try { + write_hdf5_record( *detail::get_basisset_ptr(basis), std::string(fname), std::string(dset) ); + } catch(...) { + status->code = 1; + } +} + +/** + * @brief Write a CMatrix record to an HDF5 file. + * @param status Status object to capture any errors. + * @param matrix Handle to the CMatrix to write. + * @param fname Name of the HDF5 file. + * @param dset Name of the dataset within the HDF5 file. + */ +void gauxc_matrix_write_hdf5_record( + GauXCStatus* status, + GauXCMatrix matrix, + const char* fname, + const char* dset +) { + status->code = 0; + detail::CMatrix& mat = *detail::get_matrix_ptr(matrix); + try { + HighFive::File file( std::string(fname), HighFive::File::OpenOrCreate ); + + HighFive::DataSpace dataspace({ mat.rows(), mat.cols() }); + auto dataset = file.createDataSet(std::string(dset), dataspace); + + dataset.write_raw(mat.data()); + } catch(...) { + status->code = 1; + } +} + +} // extern "C" +} // namespace GauXC::C \ No newline at end of file From 6c312fa41e397ea452b3d602d4eae51565e133ec Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 13:30:29 +0100 Subject: [PATCH 14/15] Export matrix API --- include/gauxc/external/hdf5.h | 4 +++ include/gauxc/matrix.h | 57 +++++++++++++++++++++++++++++++++ include/gauxc/util/c_matrix.hpp | 14 ++++---- src/c_matrix.cxx | 42 ++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 7 deletions(-) diff --git a/include/gauxc/external/hdf5.h b/include/gauxc/external/hdf5.h index 89e807e9..bdd5d98c 100644 --- a/include/gauxc/external/hdf5.h +++ b/include/gauxc/external/hdf5.h @@ -16,8 +16,10 @@ #include #include +#ifdef __cplusplus namespace GauXC::C { extern "C" { +#endif /** * @brief Write a Molecule record to an HDF5 file. @@ -103,6 +105,8 @@ extern void gauxc_matrix_read_hdf5_record( const char* dset ); +#ifdef __cplusplus } // extern "C" } // namespace GauXC::C +#endif #endif \ No newline at end of file diff --git a/include/gauxc/matrix.h b/include/gauxc/matrix.h index abe40c0c..15a77b82 100644 --- a/include/gauxc/matrix.h +++ b/include/gauxc/matrix.h @@ -45,6 +45,63 @@ extern GauXCMatrix gauxc_matrix_new( size_t cols ); +/** + * @brief Resize an existing Matrix instance. + * @param status Status object to capture any errors. + * @param matrix Handle to the Matrix to resize. + * @param rows New number of rows in the matrix. + * @param cols New number of columns in the matrix. + */ +extern void gauxc_matrix_resize( + GauXCStatus* status, + GauXCMatrix matrix, + size_t rows, + size_t cols +); + +/** + * @brief Set all elements of the Matrix to zero. + * @param status Status object to capture any errors. + * @param matrix Handle to the Matrix to set to zero. + */ +extern void gauxc_matrix_set_zero( + GauXCStatus* status, + GauXCMatrix matrix +); + +/** + * @brief Get the number of rows in the Matrix. + * @param status Status object to capture any errors. + * @param matrix Handle to the Matrix. + * @return Number of rows in the Matrix. + */ +extern size_t gauxc_matrix_rows( + GauXCStatus* status, + GauXCMatrix matrix +); + +/** + * @brief Get the number of columns in the Matrix. + * @param status Status object to capture any errors. + * @param matrix Handle to the Matrix. + * @return Number of columns in the Matrix. + */ +extern size_t gauxc_matrix_cols( + GauXCStatus* status, + GauXCMatrix matrix +); + +/** + * @brief Get a pointer to the underlying data of the Matrix. + * @param status Status object to capture any errors. + * @param matrix Handle to the Matrix. + * @return Pointer to the underlying data of the Matrix. + */ +extern double* gauxc_matrix_data( + GauXCStatus* status, + GauXCMatrix matrix +); + /** * @brief Delete a Matrix instance. * @param status Status object to capture any errors. diff --git a/include/gauxc/util/c_matrix.hpp b/include/gauxc/util/c_matrix.hpp index 4f18fb2a..05bf3b8a 100644 --- a/include/gauxc/util/c_matrix.hpp +++ b/include/gauxc/util/c_matrix.hpp @@ -16,7 +16,7 @@ namespace GauXC::detail { class CMatrix { public: using value_type = double; - CMatrix( size_t rows, size_t cols ) { + CMatrix( size_t rows, size_t cols ) noexcept { rows_ = rows; cols_ = cols; data_ = new value_type[ rows * cols ](); @@ -24,15 +24,15 @@ class CMatrix { ~CMatrix() noexcept { delete[] data_; } - value_type * data() { return data_; } - const value_type * data() const { return data_; } - size_t rows() const { return rows_; } - size_t cols() const { return cols_; } - void setZero() { + value_type * data() noexcept { return data_; } + const value_type * data() const noexcept { return data_; } + size_t rows() const noexcept { return rows_; } + size_t cols() const noexcept { return cols_; } + void setZero() noexcept { for( size_t i = 0; i < rows_ * cols_; ++i ) data_[i] = value_type(0); } - void resize( size_t rows, size_t cols ) { + void resize( size_t rows, size_t cols ) noexcept { if( rows == rows_ && cols == cols_ ) return; delete[] data_; rows_ = rows; diff --git a/src/c_matrix.cxx b/src/c_matrix.cxx index 902e37f3..215b5962 100644 --- a/src/c_matrix.cxx +++ b/src/c_matrix.cxx @@ -27,6 +27,48 @@ GauXCMatrix gauxc_matrix_new( return matrix; } +extern void gauxc_matrix_resize( + GauXCStatus* status, + GauXCMatrix matrix, + size_t rows, + size_t cols +) { + status->code = 0; + detail::get_matrix_ptr(matrix)->resize( rows, cols ); +} + +extern void gauxc_matrix_set_zero( + GauXCStatus* status, + GauXCMatrix matrix +) { + status->code = 0; + detail::get_matrix_ptr(matrix)->setZero(); +} + +extern size_t gauxc_matrix_rows( + GauXCStatus* status, + GauXCMatrix matrix +) { + status->code = 0; + return detail::get_matrix_ptr(matrix)->rows(); +} + +extern size_t gauxc_matrix_cols( + GauXCStatus* status, + GauXCMatrix matrix +) { + status->code = 0; + return detail::get_matrix_ptr(matrix)->cols(); +} + +extern double* gauxc_matrix_data( + GauXCStatus* status, + GauXCMatrix matrix +) { + status->code = 0; + return detail::get_matrix_ptr(matrix)->data(); +} + void gauxc_matrix_delete( GauXCStatus* status, GauXCMatrix matrix From 7efb7e22d0ef53afaf716d8a4737b1bf65914245 Mon Sep 17 00:00:00 2001 From: Sebastian Ehlert Date: Mon, 26 Jan 2026 15:23:04 +0100 Subject: [PATCH 15/15] Update API for deleting object --- include/gauxc/basisset.h | 2 +- include/gauxc/functional.h | 2 +- include/gauxc/load_balancer.h | 24 +++--- include/gauxc/matrix.h | 11 ++- include/gauxc/molecular_weights.h | 12 +-- include/gauxc/molecule.h | 4 +- include/gauxc/molgrid.h | 4 +- include/gauxc/runtime_environment.h | 6 +- include/gauxc/util/c_matrix.hpp | 6 +- include/gauxc/xc_integrator.h | 74 ++++++++--------- src/c_basisset.cxx | 8 +- src/c_functional.cxx | 8 +- src/c_load_balancer.cxx | 40 ++++----- src/c_matrix.cxx | 48 +++++++---- src/c_molecular_weights.cxx | 30 +++---- src/c_molecule.cxx | 10 +-- src/c_molgrid.cxx | 18 ++-- src/c_runtime_environment.cxx | 18 ++-- src/c_xc_integrator.cxx | 122 ++++++++++++++-------------- 19 files changed, 233 insertions(+), 214 deletions(-) diff --git a/include/gauxc/basisset.h b/include/gauxc/basisset.h index 4dc9c3bd..352d7b1a 100644 --- a/include/gauxc/basisset.h +++ b/include/gauxc/basisset.h @@ -62,7 +62,7 @@ extern GauXCBasisSet gauxc_basisset_new_from_shells( * @param status Status object to capture any errors. * @param basis Handle to the BasisSet to delete. */ -extern void gauxc_basisset_delete( GauXCStatus* status, GauXCBasisSet basis ); +extern void gauxc_basisset_delete( GauXCStatus* status, GauXCBasisSet* basis ); #ifdef __cplusplus } // namespace GauXC::C diff --git a/include/gauxc/functional.h b/include/gauxc/functional.h index 7333f539..d19ba81a 100644 --- a/include/gauxc/functional.h +++ b/include/gauxc/functional.h @@ -502,7 +502,7 @@ GauXCFunctional gauxc_functional_from_enum( */ void gauxc_functional_delete( GauXCStatus* status, - GauXCFunctional functional + GauXCFunctional* functional ); #ifdef __cplusplus diff --git a/include/gauxc/load_balancer.h b/include/gauxc/load_balancer.h index ab027f34..da0f14cf 100644 --- a/include/gauxc/load_balancer.h +++ b/include/gauxc/load_balancer.h @@ -47,7 +47,7 @@ typedef struct GauXCLoadBalancer { */ extern void gauxc_load_balancer_delete( GauXCStatus* status, - GauXCLoadBalancer lb + GauXCLoadBalancer* lb ); /** @@ -77,7 +77,7 @@ extern GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( */ extern void gauxc_load_balancer_factory_delete( GauXCStatus* status, - GauXCLoadBalancerFactory factory + GauXCLoadBalancerFactory* factory ); /** @@ -92,11 +92,11 @@ extern void gauxc_load_balancer_factory_delete( */ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( GauXCStatus* status, - GauXCLoadBalancerFactory factory, - GauXCRuntimeEnvironment env, - GauXCMolecule mol, - GauXCMolGrid mg, - GauXCBasisSet basis + const GauXCLoadBalancerFactory factory, + const GauXCRuntimeEnvironment env, + const GauXCMolecule mol, + const GauXCMolGrid mg, + const GauXCBasisSet basis ); /** @@ -110,11 +110,11 @@ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( */ extern GauXCLoadBalancer gauxc_load_balancer_factory_get_shared_instance( GauXCStatus* status, - GauXCLoadBalancerFactory factory, - GauXCRuntimeEnvironment env, - GauXCMolecule mol, - GauXCMolGrid mg, - GauXCBasisSet basis + const GauXCLoadBalancerFactory factory, + const GauXCRuntimeEnvironment env, + const GauXCMolecule mol, + const GauXCMolGrid mg, + const GauXCBasisSet basis ); #ifdef __cplusplus diff --git a/include/gauxc/matrix.h b/include/gauxc/matrix.h index 15a77b82..f4190c30 100644 --- a/include/gauxc/matrix.h +++ b/include/gauxc/matrix.h @@ -32,6 +32,15 @@ typedef struct GauXCMatrix { void* ptr; ///< Pointer to the Matrix instance. } GauXCMatrix; +/** + * @brief Create a new Matrix instance. + * @param status Status object to capture any errors. + * @return Handle to the newly created Matrix. + */ +extern GauXCMatrix gauxc_matrix_empty( + GauXCStatus* status +); + /** * @brief Create a new Matrix instance. * @param status Status object to capture any errors. @@ -109,7 +118,7 @@ extern double* gauxc_matrix_data( */ extern void gauxc_matrix_delete( GauXCStatus* status, - GauXCMatrix matrix + GauXCMatrix* matrix ); #ifdef __cplusplus diff --git a/include/gauxc/molecular_weights.h b/include/gauxc/molecular_weights.h index 115b3619..72b8381d 100644 --- a/include/gauxc/molecular_weights.h +++ b/include/gauxc/molecular_weights.h @@ -50,7 +50,7 @@ typedef struct GauXCMolecularWeights { */ extern void gauxc_molecular_weights_delete( GauXCStatus* status, - GauXCMolecularWeights mw + GauXCMolecularWeights* mw ); /** @@ -61,8 +61,8 @@ extern void gauxc_molecular_weights_delete( */ extern void gauxc_molecular_weights_modify_weights( GauXCStatus* status, - GauXCMolecularWeights mw, - GauXCLoadBalancer lb + const GauXCMolecularWeights mw, + const GauXCLoadBalancer lb ); /** @@ -94,7 +94,7 @@ extern GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( */ extern void gauxc_molecular_weights_factory_delete( GauXCStatus* status, - GauXCMolecularWeightsFactory factory + GauXCMolecularWeightsFactory* factory ); /** @@ -105,7 +105,7 @@ extern void gauxc_molecular_weights_factory_delete( */ extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( GauXCStatus* status, - GauXCMolecularWeightsFactory factory + const GauXCMolecularWeightsFactory factory ); /** @@ -116,7 +116,7 @@ extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( */ extern GauXCMolecularWeights gauxc_molecular_weights_factory_get_shared_instance( GauXCStatus* status, - GauXCMolecularWeightsFactory factory + const GauXCMolecularWeightsFactory factory ); diff --git a/include/gauxc/molecule.h b/include/gauxc/molecule.h index 4d5db27e..646312c2 100644 --- a/include/gauxc/molecule.h +++ b/include/gauxc/molecule.h @@ -56,7 +56,7 @@ extern GauXCMolecule gauxc_molecule_new_from_atoms(GauXCStatus* status, GauXCAto * @param status Status object to capture any errors. * @param mol Handle to the Molecule to delete. */ -extern void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule mol ); +extern void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule* mol ); /** * @brief Get the number of atoms in the Molecule. @@ -64,7 +64,7 @@ extern void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule mol ); * @param mol Handle to the Molecule. * @return Number of atoms in the Molecule. */ -extern size_t gauxc_molecule_natoms(GauXCStatus* status, GauXCMolecule mol ); +extern size_t gauxc_molecule_natoms(GauXCStatus* status, const GauXCMolecule mol ); #ifdef __cplusplus } // namespace GauXC::C diff --git a/include/gauxc/molgrid.h b/include/gauxc/molgrid.h index d324eb35..94038b5d 100644 --- a/include/gauxc/molgrid.h +++ b/include/gauxc/molgrid.h @@ -44,7 +44,7 @@ typedef struct GauXCMolGrid { */ extern GauXCMolGrid gauxc_molgrid_new_default( GauXCStatus* status, - GauXCMolecule mol, + const GauXCMolecule mol, enum GauXC_PruningScheme pruning_scheme, int64_t batchsize, enum GauXC_RadialQuad radial_quad, @@ -58,7 +58,7 @@ extern GauXCMolGrid gauxc_molgrid_new_default( */ extern void gauxc_molgrid_delete( GauXCStatus* status, - GauXCMolGrid molgrid + GauXCMolGrid* molgrid ); #ifdef __cplusplus diff --git a/include/gauxc/runtime_environment.h b/include/gauxc/runtime_environment.h index 46afa491..4e4bfeec 100644 --- a/include/gauxc/runtime_environment.h +++ b/include/gauxc/runtime_environment.h @@ -52,7 +52,7 @@ GauXCRuntimeEnvironment gauxc_runtime_environment_new( */ extern void gauxc_runtime_environment_delete( GauXCStatus* status, - GauXCRuntimeEnvironment env + GauXCRuntimeEnvironment* env ); /** @@ -63,7 +63,7 @@ extern void gauxc_runtime_environment_delete( */ extern int gauxc_runtime_environment_comm_rank( GauXCStatus* status, - GauXCRuntimeEnvironment env + const GauXCRuntimeEnvironment env ); /** * @brief Get the size of the RuntimeEnvironment's communicator. @@ -73,7 +73,7 @@ extern int gauxc_runtime_environment_comm_rank( */ extern int gauxc_runtime_environment_comm_size( GauXCStatus* status, - GauXCRuntimeEnvironment env + const GauXCRuntimeEnvironment env ); #ifdef GAUXC_HAS_DEVICE diff --git a/include/gauxc/util/c_matrix.hpp b/include/gauxc/util/c_matrix.hpp index 05bf3b8a..a6bf22b3 100644 --- a/include/gauxc/util/c_matrix.hpp +++ b/include/gauxc/util/c_matrix.hpp @@ -16,13 +16,15 @@ namespace GauXC::detail { class CMatrix { public: using value_type = double; + CMatrix( ) noexcept : rows_(0), cols_(0), data_(nullptr) {} CMatrix( size_t rows, size_t cols ) noexcept { rows_ = rows; cols_ = cols; data_ = new value_type[ rows * cols ](); } ~CMatrix() noexcept { - delete[] data_; + if (data_) delete[] data_; + data_ = nullptr; } value_type * data() noexcept { return data_; } const value_type * data() const noexcept { return data_; } @@ -34,7 +36,7 @@ class CMatrix { } void resize( size_t rows, size_t cols ) noexcept { if( rows == rows_ && cols == cols_ ) return; - delete[] data_; + if (data_) delete[] data_; rows_ = rows; cols_ = cols; data_ = new value_type[ rows * cols ](); diff --git a/include/gauxc/xc_integrator.h b/include/gauxc/xc_integrator.h index 29770c38..e2a54b53 100644 --- a/include/gauxc/xc_integrator.h +++ b/include/gauxc/xc_integrator.h @@ -43,7 +43,7 @@ typedef struct GauXCIntegrator { */ extern void gauxc_integrator_delete( GauXCStatus* status, - GauXCIntegrator integrator + GauXCIntegrator* integrator ); /** @@ -79,7 +79,7 @@ extern GauXCIntegratorFactory gauxc_integrator_factory_new( */ extern void gauxc_integrator_factory_delete( GauXCStatus* status, - GauXCIntegratorFactory integrator_factory + GauXCIntegratorFactory* integrator_factory ); /** @@ -92,9 +92,9 @@ extern void gauxc_integrator_factory_delete( */ extern GauXCIntegrator gauxc_integrator_factory_get_instance( GauXCStatus* status, - GauXCIntegratorFactory integrator_factory, - GauXCFunctional func, - GauXCLoadBalancer lb + const GauXCIntegratorFactory integrator_factory, + const GauXCFunctional func, + const GauXCLoadBalancer lb ); /** @@ -107,9 +107,9 @@ extern GauXCIntegrator gauxc_integrator_factory_get_instance( */ extern GauXCIntegrator gauxc_integrator_factory_get_shared_instance( GauXCStatus* status, - GauXCIntegratorFactory integrator_factory, - GauXCFunctional func, - GauXCLoadBalancer lb + const GauXCIntegratorFactory integrator_factory, + const GauXCFunctional func, + const GauXCLoadBalancer lb ); /** @@ -121,8 +121,8 @@ extern GauXCIntegrator gauxc_integrator_factory_get_shared_instance( */ extern void gauxc_integrator_integrate_den( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix, double* den ); @@ -135,8 +135,8 @@ extern void gauxc_integrator_integrate_den( */ extern void gauxc_integrator_eval_exc_rks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix, double* exc ); @@ -150,9 +150,9 @@ extern void gauxc_integrator_eval_exc_rks( */ extern void gauxc_integrator_eval_exc_uks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, double* exc ); @@ -168,11 +168,11 @@ extern void gauxc_integrator_eval_exc_uks( */ extern void gauxc_integrator_eval_exc_gks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, + const GauXCMatrix density_matrix_x, + const GauXCMatrix density_matrix_y, double* exc ); @@ -186,10 +186,10 @@ extern void gauxc_integrator_eval_exc_gks( */ extern void gauxc_integrator_eval_exc_vxc_rks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix, double* exc, - GauXCMatrix vxc_matrix + GauXCMatrix* vxc_matrix ); /** @@ -204,12 +204,12 @@ extern void gauxc_integrator_eval_exc_vxc_rks( */ extern void gauxc_integrator_eval_exc_vxc_uks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, double* exc, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z + GauXCMatrix* vxc_matrix_s, + GauXCMatrix* vxc_matrix_z ); /** @@ -228,16 +228,16 @@ extern void gauxc_integrator_eval_exc_vxc_uks( */ extern void gauxc_integrator_eval_exc_vxc_gks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, + const GauXCMatrix density_matrix_x, + const GauXCMatrix density_matrix_y, double* exc, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z, - GauXCMatrix vxc_matrix_x, - GauXCMatrix vxc_matrix_y + GauXCMatrix* vxc_matrix_s, + GauXCMatrix* vxc_matrix_z, + GauXCMatrix* vxc_matrix_x, + GauXCMatrix* vxc_matrix_y ); #ifdef __cplusplus diff --git a/src/c_basisset.cxx b/src/c_basisset.cxx index f0e6f8b3..1a8d35b7 100644 --- a/src/c_basisset.cxx +++ b/src/c_basisset.cxx @@ -37,11 +37,11 @@ GauXCBasisSet gauxc_basisset_new_from_shells(GauXCStatus* status, GauXCShell* sh return basis; } -void gauxc_basisset_delete(GauXCStatus* status, GauXCBasisSet basis) { +void gauxc_basisset_delete(GauXCStatus* status, GauXCBasisSet* basis) { status->code = 0; - if(basis.ptr != nullptr) - delete detail::get_basisset_ptr(basis); - basis.ptr = nullptr; + if(basis->ptr != nullptr) + delete detail::get_basisset_ptr(*basis); + basis->ptr = nullptr; } } // extern "C" diff --git a/src/c_functional.cxx b/src/c_functional.cxx index d5f05050..646a6bcd 100644 --- a/src/c_functional.cxx +++ b/src/c_functional.cxx @@ -96,12 +96,12 @@ GauXCFunctional gauxc_functional_from_enum( void gauxc_functional_delete( GauXCStatus* status, - GauXCFunctional functional + GauXCFunctional* functional ) { status->code = 0; - if(functional.ptr != nullptr) - delete detail::get_functional_ptr(functional); - functional.ptr = nullptr; + if(functional->ptr != nullptr) + delete detail::get_functional_ptr(*functional); + functional->ptr = nullptr; } } // extern "C" diff --git a/src/c_load_balancer.cxx b/src/c_load_balancer.cxx index 1de72d45..982d41f1 100644 --- a/src/c_load_balancer.cxx +++ b/src/c_load_balancer.cxx @@ -22,16 +22,16 @@ extern "C" { void gauxc_load_balancer_delete( GauXCStatus* status, - GauXCLoadBalancer lb + GauXCLoadBalancer* lb ) { status->code = 0; - if(lb.ptr != nullptr) { - if (lb.owned) - delete detail::get_load_balancer_ptr(lb); + if(lb->ptr != nullptr) { + if (lb->owned) + delete detail::get_load_balancer_ptr(*lb); else - delete detail::get_load_balancer_shared(lb); + delete detail::get_load_balancer_shared(*lb); } - lb.ptr = nullptr; + lb->ptr = nullptr; } GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( GauXCStatus* status, @@ -49,20 +49,20 @@ GauXCLoadBalancerFactory gauxc_load_balancer_factory_new( } void gauxc_load_balancer_factory_delete( GauXCStatus* status, - GauXCLoadBalancerFactory lbf + GauXCLoadBalancerFactory* lbf ) { status->code = 0; - if(lbf.ptr != nullptr) - delete detail::get_load_balancer_factory_ptr(lbf); - lbf.ptr = nullptr; + if(lbf->ptr != nullptr) + delete detail::get_load_balancer_factory_ptr(*lbf); + lbf->ptr = nullptr; } GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( GauXCStatus* status, - GauXCLoadBalancerFactory lbf, - GauXCRuntimeEnvironment rt, - GauXCMolecule mol, - GauXCMolGrid mg, - GauXCBasisSet bs + const GauXCLoadBalancerFactory lbf, + const GauXCRuntimeEnvironment rt, + const GauXCMolecule mol, + const GauXCMolGrid mg, + const GauXCBasisSet bs ) { status->code = 0; LoadBalancer lb_instance = detail::get_load_balancer_factory_ptr(lbf)->get_instance( @@ -79,11 +79,11 @@ GauXCLoadBalancer gauxc_load_balancer_factory_get_instance( GauXCLoadBalancer gauxc_load_balancer_factory_get_shared_instance( GauXCStatus* status, - GauXCLoadBalancerFactory lbf, - GauXCRuntimeEnvironment rt, - GauXCMolecule mol, - GauXCMolGrid mg, - GauXCBasisSet bs + const GauXCLoadBalancerFactory lbf, + const GauXCRuntimeEnvironment rt, + const GauXCMolecule mol, + const GauXCMolGrid mg, + const GauXCBasisSet bs ) { status->code = 0; auto lb_instance_ptr = detail::get_load_balancer_factory_ptr(lbf)->get_shared_instance( diff --git a/src/c_matrix.cxx b/src/c_matrix.cxx index 215b5962..d26c68e8 100644 --- a/src/c_matrix.cxx +++ b/src/c_matrix.cxx @@ -14,11 +14,22 @@ #include namespace GauXC::C { +extern "C" { + +GauXCMatrix gauxc_matrix_empty( + GauXCStatus* status +) { + status->code = 0; + GauXCMatrix matrix; + matrix.ptr = new detail::CMatrix(); + + return matrix; +} GauXCMatrix gauxc_matrix_new( GauXCStatus* status, - size_t rows, - size_t cols + const size_t rows, + const size_t cols ) { status->code = 0; GauXCMatrix matrix; @@ -27,43 +38,43 @@ GauXCMatrix gauxc_matrix_new( return matrix; } -extern void gauxc_matrix_resize( +void gauxc_matrix_resize( GauXCStatus* status, - GauXCMatrix matrix, - size_t rows, - size_t cols + const GauXCMatrix matrix, + const size_t rows, + const size_t cols ) { status->code = 0; detail::get_matrix_ptr(matrix)->resize( rows, cols ); } -extern void gauxc_matrix_set_zero( +void gauxc_matrix_set_zero( GauXCStatus* status, - GauXCMatrix matrix + const GauXCMatrix matrix ) { status->code = 0; detail::get_matrix_ptr(matrix)->setZero(); } -extern size_t gauxc_matrix_rows( +size_t gauxc_matrix_rows( GauXCStatus* status, - GauXCMatrix matrix + const GauXCMatrix matrix ) { status->code = 0; return detail::get_matrix_ptr(matrix)->rows(); } -extern size_t gauxc_matrix_cols( +size_t gauxc_matrix_cols( GauXCStatus* status, - GauXCMatrix matrix + const GauXCMatrix matrix ) { status->code = 0; return detail::get_matrix_ptr(matrix)->cols(); } -extern double* gauxc_matrix_data( +detail::CMatrix::value_type* gauxc_matrix_data( GauXCStatus* status, - GauXCMatrix matrix + const GauXCMatrix matrix ) { status->code = 0; return detail::get_matrix_ptr(matrix)->data(); @@ -71,12 +82,13 @@ extern double* gauxc_matrix_data( void gauxc_matrix_delete( GauXCStatus* status, - GauXCMatrix matrix + GauXCMatrix* matrix ) { status->code = 0; - if(matrix.ptr != nullptr) - delete detail::get_matrix_ptr(matrix); - matrix.ptr = nullptr; + if(matrix->ptr != nullptr) + delete detail::get_matrix_ptr(*matrix); + matrix->ptr = nullptr; } +} // extern "C" } // namespace GauXC::C \ No newline at end of file diff --git a/src/c_molecular_weights.cxx b/src/c_molecular_weights.cxx index be1acd97..4069189e 100644 --- a/src/c_molecular_weights.cxx +++ b/src/c_molecular_weights.cxx @@ -22,7 +22,7 @@ GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( GauXCStatus* status, enum GauXC_ExecutionSpace ex, const char* kernel_name, - GauXCMolecularWeightsSettings settings + const GauXCMolecularWeightsSettings settings ) { status->code = 0; GauXCMolecularWeightsFactory mwf; @@ -37,7 +37,7 @@ GauXCMolecularWeightsFactory gauxc_molecular_weights_factory_new( GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( GauXCStatus* status, - GauXCMolecularWeightsFactory mwf + const GauXCMolecularWeightsFactory mwf ) { status->code = 0; MolecularWeights mw_instance = detail::get_molecular_weights_factory_ptr(mwf)->get_instance(); @@ -49,7 +49,7 @@ GauXCMolecularWeights gauxc_molecular_weights_factory_get_instance( GauXCMolecularWeights gauxc_molecular_weights_factory_get_shared_instance( GauXCStatus* status, - GauXCMolecularWeightsFactory mwf + const GauXCMolecularWeightsFactory mwf ) { status->code = 0; auto mw_instance_ptr = detail::get_molecular_weights_factory_ptr(mwf)->get_shared_instance(); @@ -61,8 +61,8 @@ GauXCMolecularWeights gauxc_molecular_weights_factory_get_shared_instance( void gauxc_molecular_weights_modify_weights( GauXCStatus* status, - GauXCMolecularWeights mw, - GauXCLoadBalancer lb + const GauXCMolecularWeights mw, + const GauXCLoadBalancer lb ) { status->code = 0; if (mw.owned) { @@ -89,27 +89,27 @@ void gauxc_molecular_weights_modify_weights( void gauxc_molecular_weights_delete( GauXCStatus* status, - GauXCMolecularWeights mw + GauXCMolecularWeights* mw ) { status->code = 0; - if(mw.ptr != nullptr) { - if (mw.owned) - delete detail::get_molecular_weights_ptr(mw); + if(mw->ptr != nullptr) { + if (mw->owned) + delete detail::get_molecular_weights_ptr(*mw); else - delete detail::get_molecular_weights_shared(mw); + delete detail::get_molecular_weights_shared(*mw); } - mw.ptr = nullptr; + mw->ptr = nullptr; } void gauxc_molecular_weights_factory_delete( GauXCStatus* status, - GauXCMolecularWeightsFactory mwf + GauXCMolecularWeightsFactory* mwf ) { status->code = 0; - if(mwf.ptr != nullptr) - delete detail::get_molecular_weights_factory_ptr(mwf); - mwf.ptr = nullptr; + if(mwf->ptr != nullptr) + delete detail::get_molecular_weights_factory_ptr(*mwf); + mwf->ptr = nullptr; } } // extern "C" diff --git a/src/c_molecule.cxx b/src/c_molecule.cxx index cd8876d8..9039ebfc 100644 --- a/src/c_molecule.cxx +++ b/src/c_molecule.cxx @@ -38,14 +38,14 @@ GauXCMolecule gauxc_molecule_new_from_atoms(GauXCStatus* status, GauXCAtom* atom return mol; } -void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule mol) { +void gauxc_molecule_delete(GauXCStatus* status, GauXCMolecule* mol) { status->code = 0; - if(mol.ptr != nullptr) - delete detail::get_molecule_ptr(mol); - mol.ptr = nullptr; + if(mol->ptr != nullptr) + delete detail::get_molecule_ptr(*mol); + mol->ptr = nullptr; } -size_t gauxc_molecule_natoms(GauXCStatus* status, GauXCMolecule mol) { +size_t gauxc_molecule_natoms(GauXCStatus* status, const GauXCMolecule mol) { status->code = 0; if(mol.ptr == nullptr) return 0; return detail::get_molecule_ptr(mol)->natoms(); diff --git a/src/c_molgrid.cxx b/src/c_molgrid.cxx index 23ef2274..21082a6d 100644 --- a/src/c_molgrid.cxx +++ b/src/c_molgrid.cxx @@ -22,11 +22,11 @@ extern "C" { GauXCMolGrid gauxc_molgrid_new_default( GauXCStatus* status, - GauXCMolecule mol, - enum GauXC_PruningScheme pruning_scheme, - int64_t batchsize, - enum GauXC_RadialQuad radial_quad, - enum GauXC_AtomicGridSizeDefault grid_size + const GauXCMolecule mol, + const enum GauXC_PruningScheme pruning_scheme, + const int64_t batchsize, + const enum GauXC_RadialQuad radial_quad, + const enum GauXC_AtomicGridSizeDefault grid_size ) { status->code = 0; auto grid_map = MolGridFactory::create_default_gridmap( @@ -42,11 +42,11 @@ GauXCMolGrid gauxc_molgrid_new_default( return mg; } -void gauxc_molgrid_delete(GauXCStatus* status, GauXCMolGrid mg) { +void gauxc_molgrid_delete(GauXCStatus* status, GauXCMolGrid* mg) { status->code = 0; - if(mg.ptr != nullptr) - delete detail::get_molgrid_ptr(mg); - mg.ptr = nullptr; + if(mg->ptr != nullptr) + delete detail::get_molgrid_ptr(*mg); + mg->ptr = nullptr; } } // extern "C" diff --git a/src/c_runtime_environment.cxx b/src/c_runtime_environment.cxx index ab30914a..5809fdff 100644 --- a/src/c_runtime_environment.cxx +++ b/src/c_runtime_environment.cxx @@ -27,24 +27,24 @@ GauXCRuntimeEnvironment gauxc_runtime_environment_new( return env; } -void gauxc_runtime_environment_delete(GauXCStatus* status, GauXCRuntimeEnvironment env) { +void gauxc_runtime_environment_delete(GauXCStatus* status, GauXCRuntimeEnvironment* env) { status->code = 0; - if(env.ptr != nullptr) - delete detail::get_runtime_environment_ptr(env); - env.ptr = nullptr; + if(env->ptr != nullptr) + delete detail::get_runtime_environment_ptr(*env); + env->ptr = nullptr; #ifdef GAUXC_HAS_DEVICE - if(env.device_ptr != nullptr) - delete detail::get_device_runtime_environment_ptr(env); - env.device_ptr = nullptr; + if(env->device_ptr != nullptr) + delete detail::get_device_runtime_environment_ptr(*env); + env->device_ptr = nullptr; #endif } -int gauxc_runtime_environment_comm_rank(GauXCStatus* status, GauXCRuntimeEnvironment env) { +int gauxc_runtime_environment_comm_rank(GauXCStatus* status, const GauXCRuntimeEnvironment env) { status->code = 0; return detail::get_runtime_environment_ptr(env)->comm_rank(); } -int gauxc_runtime_environment_comm_size(GauXCStatus* status, GauXCRuntimeEnvironment env) { +int gauxc_runtime_environment_comm_size(GauXCStatus* status, const GauXCRuntimeEnvironment env) { status->code = 0; return detail::get_runtime_environment_ptr(env)->comm_size(); } diff --git a/src/c_xc_integrator.cxx b/src/c_xc_integrator.cxx index 2435fb2f..6190f65e 100644 --- a/src/c_xc_integrator.cxx +++ b/src/c_xc_integrator.cxx @@ -21,26 +21,26 @@ extern "C" { void gauxc_integrator_delete( GauXCStatus* status, - GauXCIntegrator integrator + GauXCIntegrator* integrator ) { status->code = 0; - if(integrator.ptr != nullptr) { - if(integrator.owned) - delete detail::get_xc_integrator_ptr(integrator); + if(integrator->ptr != nullptr) { + if(integrator->owned) + delete detail::get_xc_integrator_ptr(*integrator); else - delete detail::get_xc_integrator_shared(integrator); + delete detail::get_xc_integrator_shared(*integrator); } - integrator.ptr = nullptr; + integrator->ptr = nullptr; } void gauxc_integrator_factory_delete( GauXCStatus* status, - GauXCIntegratorFactory factory + GauXCIntegratorFactory* factory ) { status->code = 0; - if(factory.ptr != nullptr) - delete detail::get_xc_integrator_factory_ptr(factory); - factory.ptr = nullptr; + if(factory->ptr != nullptr) + delete detail::get_xc_integrator_factory_ptr(*factory); + factory->ptr = nullptr; } GauXCIntegratorFactory gauxc_integrator_factory_new( @@ -66,9 +66,9 @@ GauXCIntegratorFactory gauxc_integrator_factory_new( GauXCIntegrator gauxc_integrator_factory_get_instance( GauXCStatus* status, - GauXCIntegratorFactory factory, - GauXCFunctional functional, - GauXCLoadBalancer lb + const GauXCIntegratorFactory factory, + const GauXCFunctional functional, + const GauXCLoadBalancer lb ) { status->code = 0; auto integrator_instance = detail::get_integrator_instance(factory, functional, lb); @@ -80,9 +80,9 @@ GauXCIntegrator gauxc_integrator_factory_get_instance( GauXCIntegrator gauxc_integrator_factory_get_shared_instance( GauXCStatus* status, - GauXCIntegratorFactory factory, - GauXCFunctional functional, - GauXCLoadBalancer lb + const GauXCIntegratorFactory factory, + const GauXCFunctional functional, + const GauXCLoadBalancer lb ) { status->code = 0; auto integrator_instance = detail::get_shared_integrator_instance(factory, functional, lb); @@ -94,8 +94,8 @@ GauXCIntegrator gauxc_integrator_factory_get_shared_instance( void gauxc_integrator_integrate_den( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix, double* den_out ) { status->code = 0; @@ -112,8 +112,8 @@ void gauxc_integrator_integrate_den( void gauxc_integrator_eval_exc_rks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix, double* exc_out ) { status->code = 0; @@ -130,9 +130,9 @@ void gauxc_integrator_eval_exc_rks( void gauxc_integrator_eval_exc_uks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, double* exc_out ) { status->code = 0; @@ -151,11 +151,11 @@ void gauxc_integrator_eval_exc_uks( void gauxc_integrator_eval_exc_gks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_tx, - GauXCMatrix density_matrix_ty, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, + const GauXCMatrix density_matrix_x, + const GauXCMatrix density_matrix_y, double* exc_out ) { status->code = 0; @@ -163,91 +163,87 @@ void gauxc_integrator_eval_exc_gks( auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_tx = *detail::get_matrix_ptr(density_matrix_tx); - auto& dm_ty = *detail::get_matrix_ptr(density_matrix_ty); + auto& dm_tx = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_ty = *detail::get_matrix_ptr(density_matrix_y); *exc_out = xc_integrator.eval_exc( dm_s, dm_z, dm_tx, dm_ty ); } else { auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& dm_tx = *detail::get_matrix_ptr(density_matrix_tx); - auto& dm_ty = *detail::get_matrix_ptr(density_matrix_ty); + auto& dm_tx = *detail::get_matrix_ptr(density_matrix_x); + auto& dm_ty = *detail::get_matrix_ptr(density_matrix_y); *exc_out = xc_integrator.eval_exc( dm_s, dm_z, dm_tx, dm_ty ); } } void gauxc_integrator_eval_exc_vxc_rks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix, double* exc_out, - GauXCMatrix vxc_matrix + GauXCMatrix* vxc_matrix ) { status->code = 0; + detail::CMatrix vxc; if (integrator.owned) { auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); auto& dm = *detail::get_matrix_ptr(density_matrix); - auto& vxc = *detail::get_matrix_ptr(vxc_matrix); std::tie(*exc_out, vxc) = xc_integrator.eval_exc_vxc( dm ); } else { auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); auto& dm = *detail::get_matrix_ptr(density_matrix); - auto& vxc = *detail::get_matrix_ptr(vxc_matrix); std::tie(*exc_out, vxc) = xc_integrator.eval_exc_vxc( dm ); } + vxc_matrix->ptr = new detail::CMatrix(std::move(vxc)); } void gauxc_integrator_eval_exc_vxc_uks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z + GauXCMatrix* vxc_matrix_s, + GauXCMatrix* vxc_matrix_z ) { status->code = 0; + detail::CMatrix vxc_s, vxc_z; if (integrator.owned) { auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); } else { auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); std::tie(*exc_out, vxc_s, vxc_z) = xc_integrator.eval_exc_vxc( dm_s, dm_z ); } + vxc_matrix_s->ptr = new detail::CMatrix(std::move(vxc_s)); + vxc_matrix_z->ptr = new detail::CMatrix(std::move(vxc_z)); } void gauxc_integrator_eval_exc_vxc_gks( GauXCStatus* status, - GauXCIntegrator integrator, - GauXCMatrix density_matrix_s, - GauXCMatrix density_matrix_z, - GauXCMatrix density_matrix_x, - GauXCMatrix density_matrix_y, + const GauXCIntegrator integrator, + const GauXCMatrix density_matrix_s, + const GauXCMatrix density_matrix_z, + const GauXCMatrix density_matrix_x, + const GauXCMatrix density_matrix_y, double* exc_out, - GauXCMatrix vxc_matrix_s, - GauXCMatrix vxc_matrix_z, - GauXCMatrix vxc_matrix_x, - GauXCMatrix vxc_matrix_y + GauXCMatrix* vxc_matrix_s, + GauXCMatrix* vxc_matrix_z, + GauXCMatrix* vxc_matrix_x, + GauXCMatrix* vxc_matrix_y ) { status->code = 0; + detail::CMatrix vxc_s, vxc_z, vxc_x, vxc_y; if (integrator.owned) { auto& xc_integrator = *detail::get_xc_integrator_ptr(integrator); auto& dm_s = *detail::get_matrix_ptr(density_matrix_s); auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); } else { auto& xc_integrator = *detail::get_xc_integrator_shared(integrator)->get(); @@ -255,12 +251,12 @@ void gauxc_integrator_eval_exc_vxc_gks( auto& dm_z = *detail::get_matrix_ptr(density_matrix_z); auto& dm_x = *detail::get_matrix_ptr(density_matrix_x); auto& dm_y = *detail::get_matrix_ptr(density_matrix_y); - auto& vxc_s = *detail::get_matrix_ptr(vxc_matrix_s); - auto& vxc_z = *detail::get_matrix_ptr(vxc_matrix_z); - auto& vxc_x = *detail::get_matrix_ptr(vxc_matrix_x); - auto& vxc_y = *detail::get_matrix_ptr(vxc_matrix_y); std::tie(*exc_out, vxc_s, vxc_z, vxc_x, vxc_y) = xc_integrator.eval_exc_vxc( dm_s, dm_z, dm_x, dm_y ); } + vxc_matrix_s->ptr = new detail::CMatrix(std::move(vxc_s)); + vxc_matrix_z->ptr = new detail::CMatrix(std::move(vxc_z)); + vxc_matrix_x->ptr = new detail::CMatrix(std::move(vxc_x)); + vxc_matrix_y->ptr = new detail::CMatrix(std::move(vxc_y)); } } // extern "C"