From 76ed161a3a773964e7fc785073a3a321b28c208d Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Tue, 5 Sep 2023 14:32:36 -0400 Subject: [PATCH 1/7] update Python detection --- .github/workflows/cmake.yml | 2 +- INSTALL | 2 +- export/cmake/CMakeLists.txt.export | 32 ++++++++++++++++++------------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index b123d1695..0e88d5424 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -113,7 +113,7 @@ jobs: tar -xzf ../compiler/libint-2*.tgz cd libint-2* echo "LIBINT_EXPORTED_DIR=`pwd`" >> $GITHUB_ENV - cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPYTHON_EXECUTABLE=`which python3` $BUILD_CONFIG + cmake -S . -B build -DCMAKE_BUILD_TYPE=$BUILD_TYPE $BUILD_CONFIG cmake --build build --target check cmake --build build --target install diff --git a/INSTALL b/INSTALL index 1445e76be..d73eb3d46 100644 --- a/INSTALL +++ b/INSTALL @@ -26,7 +26,7 @@ then either choose path a or b: Building the Python module --------------------------- Configure libint (Step 2) with `--enable-eri2 --enable-eri3`, export (Step 3b), untar exported archive: - $ cmake -DPYTHON_EXECUTABLE=`which python3` -DLIBINT2_PYTHON=ON -DCMAKE_PREFIX_PATH=$EIGEN_INSTALL_PATH -DCMAKE_INSTALL_PREFIX= . + $ cmake -DPython_EXECUTABLE=`which python3` -DLIBINT2_PYTHON=ON -DCMAKE_PREFIX_PATH=$EIGEN_INSTALL_PATH -DCMAKE_INSTALL_PREFIX= . $ cd python $ make $ cd .. && make install diff --git a/export/cmake/CMakeLists.txt.export b/export/cmake/CMakeLists.txt.export index 0d10e4b21..fd82f6cc8 100644 --- a/export/cmake/CMakeLists.txt.export +++ b/export/cmake/CMakeLists.txt.export @@ -1,4 +1,6 @@ -cmake_minimum_required(VERSION 3.8) # introduced C++ standards as features +cmake_minimum_required(VERSION 3.16) # 3.15: new Python detection; 3.16 to make the final leap + # 3.8: introduced C++ standards as features +cmake_policy(SET CMP0079 NEW) project(Libint LANGUAGES CXX C) @@ -149,12 +151,16 @@ if (NOT LIBINT_HAS_SYSTEM_BOOST_PREPROCESSOR_VARIADICS OR LIBINT_USE_BUNDLED_BOO endif() endif() -# Python is optional, unless ... -if (ENABLE_FORTRAN) # ... need fortran - find_package(PythonInterp REQUIRED) -else(ENABLE_FORTRAN) - find_package(PythonInterp) -endif(ENABLE_FORTRAN) +# Python is optionally used for testing. +# * But for Fortran, it's additionally required for preprocessing. +# * And for Python bindings, it's required along with its headers. +if (LIBINT2_PYTHON) + find_package(Python COMPONENTS Interpreter Development REQUIRED) +elseif (ENABLE_FORTRAN) + find_package(Python COMPONENTS Interpreter REQUIRED) +else() + find_package(Python COMPONENTS Interpreter) +endif() # Set install paths ==================================================================================================== @@ -349,14 +355,14 @@ if (LIBINT_HAS_CXX_API) target_link_libraries(hf-libint2 libint2_cxx) add_test(libint2/hf/build "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target hf-libint2) set_tests_properties(libint2/hf/build PROPERTIES FIXTURES_SETUP LIBINT2_HFTEST_EXEC) - if (PYTHONINTERP_FOUND) + if (Python_Interpreter_FOUND) add_test(NAME libint2/hf/run COMMAND ${CMAKE_COMMAND} -DtestName=hf-libint2 -DfileName=hartree-fock -DtestArgs=${PROJECT_SOURCE_DIR}/tests/hartree-fock/h2o.xyz -DsrcDir=${PROJECT_SOURCE_DIR} - -DpythonExec=${PYTHON_EXECUTABLE} + -DpythonExec=${Python_EXECUTABLE} -P ${PROJECT_SOURCE_DIR}/cmake/hftest.cmake) else() add_test(NAME libint2/hf/run @@ -370,14 +376,14 @@ if (LIBINT_HAS_CXX_API) target_link_libraries(hf++-libint2 libint2_cxx Threads::Threads) add_test(libint2/hf++/build "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target hf++-libint2) set_tests_properties(libint2/hf++/build PROPERTIES FIXTURES_SETUP LIBINT2_HFXXTEST_EXEC) - if (PYTHONINTERP_FOUND) + if (Python_Interpreter_FOUND) add_test(NAME libint2/hf++/run COMMAND ${CMAKE_COMMAND} -DtestName=hf++-libint2 -DfileName=hartree-fock++ -DtestArgs=${PROJECT_SOURCE_DIR}/tests/hartree-fock/h2o_rotated.xyz -DsrcDir=${PROJECT_SOURCE_DIR} - -DpythonExec=${PYTHON_EXECUTABLE} + -DpythonExec=${Python_EXECUTABLE} -P ${PROJECT_SOURCE_DIR}/cmake/hftest.cmake) else() add_test(NAME libint2/hf++/run @@ -411,14 +417,14 @@ if (ENABLE_FORTRAN) # translated Libint_t add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/fortran/libint2_types_f.h - COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/fortran/c_to_f.py ${CMAKE_BINARY_DIR}/fortran/libint2.h.i ${CMAKE_BINARY_DIR}/fortran/libint2_types_f.h Libint_t + COMMAND ${Python_EXECUTABLE} ${PROJECT_SOURCE_DIR}/fortran/c_to_f.py ${CMAKE_BINARY_DIR}/fortran/libint2.h.i ${CMAKE_BINARY_DIR}/fortran/libint2_types_f.h Libint_t DEPENDS ${CMAKE_BINARY_DIR}/fortran/libint2.h.i COMMENT "Generating libint2_types_f.h" ) # extracted defines from libint2_types.h add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/fortran/fortran_incldefs.h - COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/fortran/make_defs.py ${PROJECT_SOURCE_DIR}/include/libint2_types.h ${PROJECT_BINARY_DIR}/fortran/fortran_incldefs.h + COMMAND ${Python_EXECUTABLE} ${PROJECT_SOURCE_DIR}/fortran/make_defs.py ${PROJECT_SOURCE_DIR}/include/libint2_types.h ${PROJECT_BINARY_DIR}/fortran/fortran_incldefs.h DEPENDS ${PROJECT_SOURCE_DIR}/include/libint2_types.h COMMENT "Generating fortran_incldefs.h" ) From 128be86b04258ba4343f8c5300536a3c37be162e Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Tue, 5 Sep 2023 14:35:56 -0400 Subject: [PATCH 2/7] add configuration header and src. not yet used and not compiled into lib until later commit --- export/cmake/CMakeLists.txt.export | 5 +++ include/libint2.h | 1 + include/libint2/cxxapi.h | 2 +- include/libint2/util/configuration.h | 44 ++++++++++++++++++++++++ src/lib/MakeRules.in | 1 + src/lib/libint/configuration.cc.cmake.in | 29 ++++++++++++++++ 6 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 include/libint2/util/configuration.h create mode 100644 src/lib/libint/configuration.cc.cmake.in diff --git a/export/cmake/CMakeLists.txt.export b/export/cmake/CMakeLists.txt.export index fd82f6cc8..b053d28c1 100644 --- a/export/cmake/CMakeLists.txt.export +++ b/export/cmake/CMakeLists.txt.export @@ -480,6 +480,11 @@ configure_file( @ONLY ) +# In the future CMake switchover, configuration.h/cc define a string summary of capabilities. @ONLY is maximally deferred in case config2 changes the +# summary (as it used to when LIBINT_SHGSHELL_ORDERING was library-config-time selected). +#configure_file(${PROJECT_SOURCE_DIR}/include/libint2/util/configuration.h.cmake.in ${PROJECT_BINARY_DIR}/include/libint2/util/configuration.h @ONLY) +configure_file(src/configuration.cc.cmake.in ${PROJECT_BINARY_DIR}/src/configuration.cc @ONLY) + configure_file( include/libint2/basis.h.in ${PROJECT_BINARY_DIR}/include/libint2/basis.h diff --git a/include/libint2.h b/include/libint2.h index 429e19768..ce0a2eec2 100644 --- a/include/libint2.h +++ b/include/libint2.h @@ -33,6 +33,7 @@ #include #include #include +#include #if defined(__cplusplus) #include diff --git a/include/libint2/cxxapi.h b/include/libint2/cxxapi.h index acf0f3b8a..5fe91b2c0 100644 --- a/include/libint2/cxxapi.h +++ b/include/libint2/cxxapi.h @@ -26,7 +26,7 @@ # error "Libint2 C++ API requires C++11 support" #endif -#include // NB this loads libint2/config.h +#include // NB this loads libint2/config.h and libint2/util/configuration.h #ifdef LIBINT_USER_DEFINED_REAL # error "C++11 API does not support with user-defined real types yet; omit --with-real-type when configuring" diff --git a/include/libint2/util/configuration.h b/include/libint2/util/configuration.h new file mode 100644 index 000000000..cfa1e119e --- /dev/null +++ b/include/libint2/util/configuration.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2004-2023 Edward F. Valeev + * + * This file is part of Libint. + * + * Libint is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libint is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Libint. If not, see . + * + */ + +#ifndef _libint2_include_libint2_util_configuration_h_ +#define _libint2_include_libint2_util_configuration_h_ + +/* Runtime accessor for the library configuration: + integral derivatives, AM, orderings, etc. + @return the semicolon-separated strings from CMake components */ +const char * configuration_accessor(); + +#ifdef _libint2_src_lib_libint_cxxapi_h_ +#include + +namespace libint2 { + + /// Runtime accessor for the library configuration: + /// integral derivatives, AM, orderings, etc. + /// @return the semicolon-separated strings from CMake components + inline std::string configuration_accessor() { + std::string components = ::configuration_accessor(); + return components; + } +} +#endif /* cxxapi guard */ + +#endif /* header guard */ diff --git a/src/lib/MakeRules.in b/src/lib/MakeRules.in index 1817125d2..dd780bc8e 100644 --- a/src/lib/MakeRules.in +++ b/src/lib/MakeRules.in @@ -14,6 +14,7 @@ export:: source for i in $(LIBSRCDIR)/*.h; do \ $(INSTALL) $(INSTALLLIBOPT) $${i} $(TOPDIR)/$(EXPORTDIR)/include; \ done + $(INSTALL) $(INSTALLLIBOPT) $(SRCTOPDIR)/src/lib/libint/configuration.cc.cmake.in $(TOPDIR)/$(EXPORTDIR)/src/configuration.cc.cmake.in $(TOPDIR)/lib/$(TARGET): source cd $(LIBSRCLINK); $(MAKE) TO_TOPDIR=$(TO_TOPDIR) TOPDIR=$(TOPOBJDIR) SRCDIR=$(SRCDIR) diff --git a/src/lib/libint/configuration.cc.cmake.in b/src/lib/libint/configuration.cc.cmake.in new file mode 100644 index 000000000..28e9c3705 --- /dev/null +++ b/src/lib/libint/configuration.cc.cmake.in @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2004-2023 Edward F. Valeev + * + * This file is part of Libint. + * + * Libint is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Libint is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Libint. If not, see . + * + */ + + +/* Runtime accessor for the library configuration: + integral derivatives, AM, orderings, etc. + @return the semicolon-separated strings from CMake components */ +const char * configuration_accessor() { + //return "@Libint2_CONFIG_COMPONENTS@"; + return "(nyi)"; +} + From a15500aef7f7cfeea795eb47d9e4e0230909f071 Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Tue, 5 Sep 2023 14:37:16 -0400 Subject: [PATCH 3/7] runtime switchable solid harmonics ordering --- export/cmake/CMakeLists.txt.export | 1 + include/libint2/initialize.h | 20 +++++++++++ include/libint2/shgshell_ordering.h | 56 ++++++++++++++++++----------- include/libint2/solidharmonics.h | 20 +++++++---- python/src/libint2/libint2.cc | 6 ++++ src/bin/libint/build_libint.cc | 8 ++++- 6 files changed, 82 insertions(+), 29 deletions(-) diff --git a/export/cmake/CMakeLists.txt.export b/export/cmake/CMakeLists.txt.export index b053d28c1..b343cd72f 100644 --- a/export/cmake/CMakeLists.txt.export +++ b/export/cmake/CMakeLists.txt.export @@ -49,6 +49,7 @@ endif(ENABLE_FORTRAN) # these are known orderings, must match config.h set(LIBINT_SHGSHELL_ORDERING_STANDARD 1) set(LIBINT_SHGSHELL_ORDERING_GAUSSIAN 2) +# August 2023: the following variable has an effect on `INT_SOLIDHARMINDEX(l, m)` but otherwise the choice can be deferred to runtime. set(LIBINT2_SHGAUSS_ORDERING "standard" CACHE STRING "Use one of the following known orderings for shells of solid harmonic Gaussians: standard -- standard ordering (-l, -l+1 ... l) gaussian -- the Gaussian ordering (0, 1, -1, 2, -2, ... l, -l) diff --git a/include/libint2/initialize.h b/include/libint2/initialize.h index 0ccf62a98..2d855b6a6 100644 --- a/include/libint2/initialize.h +++ b/include/libint2/initialize.h @@ -34,6 +34,7 @@ #include #include #include +#include namespace libint2 { @@ -56,6 +57,10 @@ namespace libint2 { static std::ostream* value = &std::clog; return value; } + inline std::atomic& solid_harmonics_ordering_accessor() { + static std::atomic value{libint2::SHGShellOrdering_Standard}; + return value; + } } // namespace libint2::detail /// checks if the libint has been initialized. @@ -74,6 +79,11 @@ namespace libint2 { (void) x; // to suppress unused variable warning (not guaranteed to work) TODO revise when upgrade to C++17 assert(x != nullptr); verbose_accessor() = verbose; + + // initialize() functions that take `SHGShellOrdering sho` as an argument aren't provided because + // * (a) with casting, it's hard to disentangle from `bool verbose` + // * (b) a separate setter is needed anyways for cases like the Python module, where initialize(sho) lives in libint code + // * code in initializer would go here as `solid_harmonics_ordering_accessor() = sho;` } } @@ -93,8 +103,18 @@ namespace libint2 { managed_singleton<__initializer>::delete_instance(); verbose_accessor() = true; verbose_stream_accessor() = &std::clog; + solid_harmonics_ordering_accessor() = libint2::SHGShellOrdering_Standard; } } + /// Setter for the SHGShellOrdering + inline void set_solid_harmonics_ordering(SHGShellOrdering sho) { + detail::solid_harmonics_ordering_accessor() = sho; + } + /// Accessor for the SHGShellOrdering + /// @return the val for Operator::nucleus + inline SHGShellOrdering solid_harmonics_ordering() { + return detail::solid_harmonics_ordering_accessor(); + } /// Accessor for the disgnostics stream /// @return the stream to which the diagnostics will be written if verbose() returns true inline std::ostream& verbose_stream() { diff --git a/include/libint2/shgshell_ordering.h b/include/libint2/shgshell_ordering.h index a23ca16ac..f9e4c3fe7 100644 --- a/include/libint2/shgshell_ordering.h +++ b/include/libint2/shgshell_ordering.h @@ -39,54 +39,41 @@ enum SHGShellOrdering { // Macros that define orderings // -#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD - /* Computes an index to a Cartesian function within a shell given * l = total angular momentum * m = real solid harmonic index (|m| = the absolute value of the projection of * the angular momentum on the z axis) m runs from -l to l */ namespace libint2 { -inline int INT_SOLIDHARMINDEX(int l, int m) { return m + l; } +inline int INT_SOLIDHARMINDEX_STANDARD(int l, int m) { return m + l; } } -LIBINT_DEPRECATED("please use libint2::INT_SOLIDHARMINDEX instead") -inline int INT_SOLIDHARMINDEX(int l, int m) { return libint2::INT_SOLIDHARMINDEX(l, m); } /* This sets up the above loop over cartesian exponents as follows * int m; - * FOR_SOLIDHARM(l,m) + * FOR_SOLIDHARM_STANDARD(l,m) * END_FOR_SOLIDHARM */ -#define FOR_SOLIDHARM(l, m) for ((m) = -(l); (m) <= (l); ++(m)) { +#define FOR_SOLIDHARM_STANDARD(l, m) for ((m) = -(l); (m) <= (l); ++(m)) { #define END_FOR_SOLIDHARM } -#endif // Standard ordering - -#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN - /* Computes an index to a Cartesian function within a shell given * l = total angular momentum * m = real solid harmonic index (|m| = the absolute value of the projection of * the angular momentum on the z axis) m runs as 0, +1, -1, +2, -2 ... +l, -l */ namespace libint2 { -inline int INT_SOLIDHARMINDEX(int l, int m) { +inline int INT_SOLIDHARMINDEX_GAUSSIAN(int l, int m) { return 2 * std::abs(m) + (m > 0 ? -1 : 0); } } -LIBINT_DEPRECATED("please use libint2::INT_SOLIDHARMINDEX instead") -inline int INT_SOLIDHARMINDEX(int l, int m) { return libint2::INT_SOLIDHARMINDEX(l, m); } /* This sets up the above loop over cartesian exponents as follows * int m; - * FOR_SOLIDHARM(l,m) + * FOR_SOLIDHARM_GAUSSIAN(l,m) * END_FOR_SOLIDHARM */ -#define FOR_SOLIDHARM(l, m) \ +#define FOR_SOLIDHARM_GAUSSIAN(l, m) \ for ((m) = 0; (m) != (l) + 1; (m) = ((m) > 0 ? -(m) : 1 - (m))) { -#define END_FOR_SOLIDHARM } - -#endif // Gaussian ordering /// these always-available macros encode orderings assumed by Molden @@ -95,11 +82,38 @@ inline int INT_SOLIDHARMINDEX_MOLDEN(int l, int m) { return 2 * std::abs(m) + (m > 0 ? -1 : 0); } } -LIBINT_DEPRECATED("please use libint2::INT_SOLIDHARMINDEX_MOLDEN instead") -inline int INT_SOLIDHARMINDEX_MOLDEN(int l, int m) { return libint2::INT_SOLIDHARMINDEX_MOLDEN(l, m); } #define FOR_SOLIDHARM_MOLDEN(l, m) \ for ((m) = 0; (m) != (l) + 1; (m) = ((m) > 0 ? -(m) : 1 - (m))) { #define END_FOR_SOLIDHARM_MOLDEN } +namespace libint2 { + LIBINT_DEPRECATED("please use libint2::INT_SOLIDHARMINDEX(libint2::solid_harmonics_ordering(), l, m) instead. Current function returns the standard or gaussian index based on build configuration, not on libint2::set_solid_harmonics_ordering() argument.") + inline int INT_SOLIDHARMINDEX(int l, int m) { +#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD + return libint2::INT_SOLIDHARMINDEX_STANDARD(l, m); +#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN + return libint2::INT_SOLIDHARMINDEX_GAUSSIAN(l, m); +#else +# error "unknown value of macro LIBINT_SHGSHELL_ORDERING" +#endif + } + + inline int INT_SOLIDHARMINDEX(int sho, int l, int m) { + if (sho == LIBINT_SHGSHELL_ORDERING_STANDARD) + return libint2::INT_SOLIDHARMINDEX_STANDARD(l, m); + else + return libint2::INT_SOLIDHARMINDEX_GAUSSIAN(l, m); + } +} + +// continue providing a generic FOR_SOLIDHARM? +//#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD +//#define FOR_SOLIDHARM FOR_SOLIDHARM_STANDARD +//#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN +//#define FOR_SOLIDHARM FOR_SOLIDHARM_GAUSSIAN +//#else +//# error "unknown value of macro LIBINT_SHGSHELL_ORDERING" +//#endif + #endif // _libint2_src_bin_libint_shgshellordering_h_ diff --git a/include/libint2/solidharmonics.h b/include/libint2/solidharmonics.h index 541cd790e..e39f242db 100644 --- a/include/libint2/solidharmonics.h +++ b/include/libint2/solidharmonics.h @@ -171,13 +171,19 @@ namespace libint2 { const unsigned short ncart = (l_ + 1) * (l_ + 2) / 2; std::vector full_coeff(npure * ncart); -#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD - for(signed char pure_idx=0, m=-l_; pure_idx!=npure; ++pure_idx, ++m) { -#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN - for(signed char pure_idx=0, m=0; pure_idx!=npure; ++pure_idx, m=(m>0?-m:1-m)) { -#else -# error "unknown value of macro LIBINT_SHGSHELL_ORDERING" -#endif + std::vector shg_indices; + if (libint2::solid_harmonics_ordering() == libint2::SHGShellOrdering_Standard) { + for(signed char pure_idx=0, m=-l_; pure_idx!=npure; ++pure_idx, ++m) + shg_indices.push_back(m); + } else if (libint2::solid_harmonics_ordering() == libint2::SHGShellOrdering_Gaussian) { + for(signed char pure_idx=0, m=0; pure_idx!=npure; ++pure_idx, m=(m>0?-m:1-m)) + shg_indices.push_back(m); + } else { + throw std::invalid_argument(std::string("libint2::solid_harmonics_ordering() value not recognized.")); + } + + for(signed char pure_idx=0; pure_idx!=npure; ++pure_idx) { + int m = shg_indices[pure_idx]; signed char cart_idx = 0; signed char lx, ly, lz; FOR_CART(lx, ly, lz, l_) diff --git a/python/src/libint2/libint2.cc b/python/src/libint2/libint2.cc index a2d6a2f41..58bb97019 100644 --- a/python/src/libint2/libint2.cc +++ b/python/src/libint2/libint2.cc @@ -137,6 +137,12 @@ std::vector coeffs_normalized(const Shell &s) { PYBIND11_MODULE(libint2, m) { + py::enum_(m, "SHGShellOrdering") + .value("SHGShellOrdering_Standard", libint2::SHGShellOrdering_Standard) + .value("SHGShellOrdering_Gaussian", libint2::SHGShellOrdering_Gaussian) + .value("SHGShellOrdering_MOLDEN", libint2::SHGShellOrdering_Gaussian) + ; + libint2::initialize(); m.attr("MAX_AM") = LIBINT2_MAX_AM; diff --git a/src/bin/libint/build_libint.cc b/src/bin/libint/build_libint.cc index 4fd253132..1b5cd0389 100644 --- a/src/bin/libint/build_libint.cc +++ b/src/bin/libint/build_libint.cc @@ -366,7 +366,13 @@ build_onebody_1b_1k(std::ostream& os, std::string label, const SafePtr(l,m)); END_FOR_SOLIDHARM } From c85cdad33374d58e76ed74ef1d7d658eaf93b792 Mon Sep 17 00:00:00 2001 From: "Lori A. Burns" Date: Tue, 5 Sep 2023 14:39:44 -0400 Subject: [PATCH 4/7] add isolated gcc, mac, intel SCF test of export to GHA. bump GHA gcc from v9 to v10 --- .github/workflows/cmake.yml | 145 +++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 4 deletions(-) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 0e88d5424..14d37eb13 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -5,7 +5,7 @@ on: [push, pull_request] #env: jobs: - build: + build_repo: strategy: fail-fast: false matrix: @@ -13,7 +13,7 @@ jobs: os : [ macos-latest, ubuntu-20.04 ] include: - os: ubuntu-20.04 - cxx: /usr/bin/g++-9 + cxx: g++-10 - os: macos-latest cxx: clang++ @@ -65,8 +65,8 @@ jobs: if: ${{ steps.skip_check.outputs.should_skip != 'true' && matrix.os == 'ubuntu-20.04' }} run: | sudo apt-get update - sudo apt-get install ninja-build g++-9 gfortran-9 liblapack-dev libboost-dev libeigen3-dev ccache python3-numpy python3-scipy - echo "FC=/usr/bin/gfortran-9" >> $GITHUB_ENV + sudo apt-get install ninja-build g++-10 gfortran-10 liblapack-dev libboost-dev libeigen3-dev ccache python3-numpy python3-scipy + echo "FC=/usr/bin/gfortran-10" >> $GITHUB_ENV echo "EIGEN3_INCLUDE_DIR=/usr/include/eigen3" >> $GITHUB_ENV - name: Prepare ccache timestamp @@ -104,6 +104,16 @@ jobs: make check cd src/bin/test_eri && ./stdtests.pl && cd ../../.. make export + echo "ARTIFACT=`ls -1 libint*tgz`" >> $GITHUB_ENV + + - name: Archive Library Tarball + if: ${{ steps.skip_check.outputs.should_skip != 'true' && matrix.build_type == 'Release'}} + uses: actions/upload-artifact@v3 + with: + if-no-files-found: error + name: ${{ runner.os }}-${{ matrix.cxx }} + path: ${{github.workspace}}/build/compiler/${{ env.ARTIFACT }} + retention-days: 1 - name: Build+test+install Libint library if: ${{ steps.skip_check.outputs.should_skip != 'true' }} @@ -145,4 +155,131 @@ jobs: cmake --build . --target libint2-python cmake --build . --target libint2-python-test + build_export: + # to debug the second stage, it is handy to short-circuit the first stage down to ~6 minutes: + # * run only the Linux/Release (remove items from matrix.build_type and matrix.os) + # * don't generate any derivative ints (edit CPPFLAGS) + # * turn off generator testing (comment out "make check" and "stdtests.pl" lines) + # * suppress last two (test library and bindings) steps ("if: false") + needs: build_repo + strategy: + fail-fast: false + matrix: + cfg: + - runs-on: ubuntu-latest + lane: ubuntu-gnu + libargs: > + -DBUILD_SHARED_LIBS=ON + testargs: "" + # note full paths depend on setup-miniconda: + # * Miniforge is miniconda3 vs. Miniconda is miniconda + + - runs-on: macos-latest + lane: macos-clang + libargs: > + -DBUILD_SHARED_LIBS=ON + testargs: "" + + - runs-on: ubuntu-latest + lane: ubuntu-intel + libargs: > + -DCMAKE_CXX_COMPILER=icpx + -DCMAKE_CXX_FLAGS="--gcc-toolchain=/usr/share/miniconda3/envs/test --sysroot=/usr/share/miniconda3/envs/test/x86_64-conda-linux-gnu/sysroot -target x86_64-conda-linux-gnu" + # flags are long-form of below (envvars not available at spinup) + # -DCMAKE_CXX_FLAGS="--gcc-toolchain=${CONDA_PREFIX} --sysroot=${CONDA_PREFIX}/${HOST}/sysroot -target ${HOST}" + testargs: > + -DCMAKE_CXX_COMPILER=icpx + -DCMAKE_CXX_FLAGS="--gcc-toolchain=/usr/share/miniconda3/envs/test --sysroot=/usr/share/miniconda3/envs/test/x86_64-conda-linux-gnu/sysroot -target x86_64-conda-linux-gnu" + + name: "Export • ${{ matrix.cfg.lane }} • ${{ matrix.cfg.libargs }}" + runs-on: ${{ matrix.cfg.runs-on }} + + steps: + # Note we're not checking out the repo. All src from Linux tarball generated above. + + - name: Write a Conda Env File + shell: bash -l {0} + run: | + cat > export.yaml < CMakeLists.txt < Date: Tue, 5 Sep 2023 15:29:21 -0400 Subject: [PATCH 5/7] integrate two-job GHA with job CI conservation --- .github/workflows/cmake.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index 14d37eb13..1ee42a783 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -162,6 +162,7 @@ jobs: # * turn off generator testing (comment out "make check" and "stdtests.pl" lines) # * suppress last two (test library and bindings) steps ("if: false") needs: build_repo + if: always() && (needs.build_repo.steps.skip_check.outputs.should_skip != 'true') strategy: fail-fast: false matrix: From cdbb9f32ae1b3d471e12bd2b028d2ab6e43ee795 Mon Sep 17 00:00:00 2001 From: Eduard Valeyev Date: Sun, 17 Sep 2023 15:31:57 -0400 Subject: [PATCH 6/7] spherical (electric) multipole operators are ordered according to standard solid harmonic order, regardless of LIBINT_SHGSHELL_ORDERING --- src/bin/libint/build_libint.cc | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/bin/libint/build_libint.cc b/src/bin/libint/build_libint.cc index 1b5cd0389..448350e3b 100644 --- a/src/bin/libint/build_libint.cc +++ b/src/bin/libint/build_libint.cc @@ -364,15 +364,9 @@ build_onebody_1b_1k(std::ostream& os, std::string label, const SafePtr(l,m)); END_FOR_SOLIDHARM } From 78c00e1a26dd24325458bc8bd6eed3f730d18d0a Mon Sep 17 00:00:00 2001 From: Eduard Valeyev Date: Sun, 17 Sep 2023 18:40:25 -0400 Subject: [PATCH 7/7] re-enable FOR_SOLIDHARM to be able to write code that works with a Libint2 library configured with any solid-harmonic order --- include/libint2/shgshell_ordering.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/include/libint2/shgshell_ordering.h b/include/libint2/shgshell_ordering.h index f9e4c3fe7..7d04e2d61 100644 --- a/include/libint2/shgshell_ordering.h +++ b/include/libint2/shgshell_ordering.h @@ -75,17 +75,17 @@ inline int INT_SOLIDHARMINDEX_GAUSSIAN(int l, int m) { #define FOR_SOLIDHARM_GAUSSIAN(l, m) \ for ((m) = 0; (m) != (l) + 1; (m) = ((m) > 0 ? -(m) : 1 - (m))) { -/// these always-available macros encode orderings assumed by Molden +/// these always-available macros encode orderings assumed by Molden ... useful for writing Molden-specific code +/// @note Molden and Gaussian ordering coincide namespace libint2 { inline int INT_SOLIDHARMINDEX_MOLDEN(int l, int m) { - return 2 * std::abs(m) + (m > 0 ? -1 : 0); + return INT_SOLIDHARMINDEX_GAUSSIAN(l, m); } } -#define FOR_SOLIDHARM_MOLDEN(l, m) \ - for ((m) = 0; (m) != (l) + 1; (m) = ((m) > 0 ? -(m) : 1 - (m))) { -#define END_FOR_SOLIDHARM_MOLDEN } +#define FOR_SOLIDHARM_MOLDEN(l, m) FOR_SOLIDHARM_GAUSSIAN(l, m) +#define END_FOR_SOLIDHARM_MOLDEN END_FOR_SOLIDHARM namespace libint2 { LIBINT_DEPRECATED("please use libint2::INT_SOLIDHARMINDEX(libint2::solid_harmonics_ordering(), l, m) instead. Current function returns the standard or gaussian index based on build configuration, not on libint2::set_solid_harmonics_ordering() argument.") @@ -107,13 +107,13 @@ namespace libint2 { } } -// continue providing a generic FOR_SOLIDHARM? -//#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD -//#define FOR_SOLIDHARM FOR_SOLIDHARM_STANDARD -//#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN -//#define FOR_SOLIDHARM FOR_SOLIDHARM_GAUSSIAN -//#else -//# error "unknown value of macro LIBINT_SHGSHELL_ORDERING" -//#endif +// FOR_SOLIDHARM dispatches to the appropriate FOR_SOLIDHARM_ macro +#if LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_STANDARD +#define FOR_SOLIDHARM FOR_SOLIDHARM_STANDARD +#elif LIBINT_SHGSHELL_ORDERING == LIBINT_SHGSHELL_ORDERING_GAUSSIAN +#define FOR_SOLIDHARM FOR_SOLIDHARM_GAUSSIAN +#else +# error "unknown value of macro LIBINT_SHGSHELL_ORDERING" +#endif #endif // _libint2_src_bin_libint_shgshellordering_h_