diff --git a/CMakeLists.txt b/CMakeLists.txt index 33d7b0dcd5..4e8d03b9aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,18 @@ include(CMakePackageConfigHelpers) include(compiler) +# Helper: creates SeQuant-${module} target, sets EXPORT_NAME, creates SeQuant::${module} alias, +# and applies warning flags (for non-INTERFACE targets) +macro(sequant_add_library _module) + add_library(SeQuant-${_module} ${ARGN}) + set_target_properties(SeQuant-${_module} PROPERTIES EXPORT_NAME ${_module}) + add_library(SeQuant::${_module} ALIAS SeQuant-${_module}) + get_target_property(_type SeQuant-${_module} TYPE) + if (NOT _type STREQUAL "INTERFACE_LIBRARY") + target_set_warning_flags(SeQuant-${_module}) + endif() +endmacro() + # extract git metadata include(GetGitMetadata) vgkit_cmake_git_metadata() @@ -237,6 +249,8 @@ add_library(SeQuant-bliss SeQuant/external/bliss/bliss_C.cc SeQuant/external/bliss/bliss_C.h ) +set_target_properties(SeQuant-bliss PROPERTIES EXPORT_NAME bliss) +add_library(SeQuant::bliss ALIAS SeQuant-bliss) target_link_libraries(SeQuant-bliss PUBLIC range-v3::range-v3 Boost::headers) if (SEQUANT_USE_SYSTEM_BOOST_HASH) target_compile_definitions(SeQuant-bliss PUBLIC SEQUANT_USE_SYSTEM_BOOST_HASH=1) @@ -252,8 +266,12 @@ if (Boost_IS_MODULARIZED) ) endif() -set(SeQuant_src - ${PROJECT_BINARY_DIR}/SeQuant/version.hpp +########################## +# Partitioned source lists +########################## + +# Symbolic layer sources (no eval/export dependencies) +set(SeQuant_symb_src SeQuant/core/algorithm.hpp SeQuant/core/asy_cost.cpp SeQuant/core/asy_cost.hpp @@ -265,28 +283,6 @@ set(SeQuant_src SeQuant/core/container.hpp SeQuant/core/context.cpp SeQuant/core/context.hpp - SeQuant/core/eval/eval_expr.cpp - SeQuant/core/eval/eval_expr.hpp - SeQuant/core/eval/eval_node.hpp - SeQuant/core/export/compute_selection.cpp - SeQuant/core/export/compute_selection.hpp - SeQuant/core/export/context.cpp - SeQuant/core/export/context.hpp - SeQuant/core/export/export.cpp - SeQuant/core/export/export.hpp - SeQuant/core/export/export_expr.cpp - SeQuant/core/export/export_expr.hpp - SeQuant/core/export/generator.cpp - SeQuant/core/export/generator.hpp - SeQuant/core/export/itf.cpp - SeQuant/core/export/itf.hpp - SeQuant/core/export/julia_itensor.hpp - SeQuant/core/export/julia_tensor_kit.hpp - SeQuant/core/export/julia_tensor_operations.cpp - SeQuant/core/export/julia_tensor_operations.hpp - SeQuant/core/export/reordering_context.cpp - SeQuant/core/export/reordering_context.hpp - SeQuant/core/export/text_generator.hpp SeQuant/core/expressions/abstract_tensor.cpp SeQuant/core/expressions/abstract_tensor.hpp SeQuant/core/expressions/expr.cpp @@ -317,11 +313,6 @@ set(SeQuant_src SeQuant/core/op.hpp SeQuant/core/options.cpp SeQuant/core/options.hpp - SeQuant/core/optimize.hpp - SeQuant/core/optimize/common_subexpression_elimination.hpp - SeQuant/core/optimize/fusion.cpp - SeQuant/core/optimize/fusion.hpp - SeQuant/core/optimize/optimize.cpp SeQuant/core/parse.hpp SeQuant/core/parse/ast.cpp SeQuant/core/parse/deparse.cpp @@ -356,6 +347,7 @@ set(SeQuant_src SeQuant/core/utility/expr.cpp SeQuant/core/utility/expr.hpp SeQuant/core/utility/indices.hpp + SeQuant/core/utility/macros.cpp SeQuant/core/utility/macros.hpp SeQuant/core/utility/memoize.hpp SeQuant/core/utility/nodiscard.hpp @@ -371,8 +363,13 @@ set(SeQuant_src SeQuant/core/reserved.hpp SeQuant/core/wick.hpp SeQuant/core/wick.impl.hpp + SeQuant/core/wick.cpp SeQuant/core/wolfram.hpp SeQuant/core/wstring.hpp +) + +# MBPT domain sources +set(SeQuant_mbpt_src SeQuant/domain/mbpt/antisymmetrizer.cpp SeQuant/domain/mbpt/antisymmetrizer.hpp SeQuant/domain/mbpt/biorthogonalization.cpp @@ -403,6 +400,69 @@ set(SeQuant_src SeQuant/domain/mbpt/vac_av.cpp SeQuant/domain/mbpt/utils.hpp SeQuant/domain/mbpt/utils.cpp +) + +# Eval framework sources (backend-agnostic) +set(SeQuant_eval_src + SeQuant/core/eval/cache_manager.cpp + SeQuant/core/eval/cache_manager.hpp + SeQuant/core/eval/eval.hpp + SeQuant/core/eval/eval_expr.cpp + SeQuant/core/eval/eval_expr.hpp + SeQuant/core/eval/eval_node.hpp + SeQuant/core/eval/result.cpp + SeQuant/core/eval/result.hpp + SeQuant/core/eval/fwd.hpp +) + +# Optimize sources (depends on eval) +set(SeQuant_optimize_src + SeQuant/core/eval/optimize.hpp + SeQuant/core/eval/optimize/common_subexpression_elimination.hpp + SeQuant/core/eval/optimize/fusion.cpp + SeQuant/core/eval/optimize/fusion.hpp + SeQuant/core/eval/optimize/optimize.cpp +) + +# Export sources (depends on eval) +set(SeQuant_export_src + SeQuant/core/export/compute_selection.cpp + SeQuant/core/export/compute_selection.hpp + SeQuant/core/export/context.cpp + SeQuant/core/export/context.hpp + SeQuant/core/export/export.cpp + SeQuant/core/export/export.hpp + SeQuant/core/export/export_expr.cpp + SeQuant/core/export/export_expr.hpp + SeQuant/core/export/generator.cpp + SeQuant/core/export/generator.hpp + SeQuant/core/export/itf.cpp + SeQuant/core/export/itf.hpp + SeQuant/core/export/julia_itensor.hpp + SeQuant/core/export/julia_tensor_kit.hpp + SeQuant/core/export/julia_tensor_operations.cpp + SeQuant/core/export/julia_tensor_operations.hpp + SeQuant/core/export/reordering_context.cpp + SeQuant/core/export/reordering_context.hpp + SeQuant/core/export/text_generator.hpp +) + +# TiledArray backend sources +set(SeQuant_eval_ta_src + SeQuant/core/eval/backends/tiledarray/eval_expr.hpp + SeQuant/core/eval/backends/tiledarray/result.hpp + SeQuant/core/eval/backends/tiledarray/result.cpp +) + +# BTAS backend sources (header-only) +set(SeQuant_eval_btas_src + SeQuant/core/eval/backends/btas/eval_expr.hpp + SeQuant/core/eval/backends/btas/result.hpp +) + +# Core sources (just version info) +set(SeQuant_core_src + ${PROJECT_BINARY_DIR}/SeQuant/version.hpp SeQuant/version.cpp ) @@ -414,66 +474,59 @@ set_source_files_properties( ) ### optional prereqs -set(SEQUANT_HAS_EVAL OFF) # do not build SQ/eval unless there is a backend if (SEQUANT_TILEDARRAY) if (NOT TARGET tiledarray) include(FindOrFetchTiledArray) endif() - set(SEQUANT_HAS_EVAL ON) set(SEQUANT_HAS_TILEDARRAY ON) endif () if (SEQUANT_BTAS) if (NOT TARGET BTAS::BTAS) include(FindOrFetchBTAS) endif() - set(SEQUANT_HAS_EVAL ON) set(SEQUANT_HAS_BTAS ON) endif () -if (SEQUANT_HAS_EVAL) - list(APPEND SeQuant_src - SeQuant/core/eval/cache_manager.cpp - SeQuant/core/eval/cache_manager.hpp - SeQuant/core/eval/eval.hpp - SeQuant/core/eval/result.cpp - SeQuant/core/eval/result.hpp - SeQuant/core/eval/fwd.hpp - ) - if (SEQUANT_HAS_TILEDARRAY) - list(APPEND SeQuant_src - SeQuant/core/eval/backends/tiledarray/eval_expr.hpp - SeQuant/core/eval/backends/tiledarray/result.hpp - SeQuant/core/eval/backends/tiledarray/result.cpp - ) - endif () - if (SEQUANT_HAS_BTAS) - list(APPEND SeQuant_src - SeQuant/core/eval/backends/btas/eval_expr.hpp - SeQuant/core/eval/backends/btas/result.hpp - ) - endif () -endif () +if (NOT PROJECT_IS_TOP_LEVEL) + set(SEQUANT_SYSTEM "SYSTEM") +endif() -add_library(SeQuant - ${SeQuant_src} - ) -# feed SEQUANT_GIT_REVISION and SEQUANT_GIT_DESCRIPTION to SeQuant/version.cpp only to avoid recompiling everything -set_source_files_properties( - SeQuant/version.cpp - PROPERTIES COMPILE_DEFINITIONS - "SEQUANT_GIT_REVISION=\"${SEQUANT_GIT_REVISION}\";SEQUANT_GIT_DESCRIPTION=\"${SEQUANT_GIT_DESCRIPTION}\"" -) +########################## +# SeQuant-symb: core symbolic layer +########################## +sequant_add_library(symb ${SeQuant_symb_src}) +target_compile_definitions(SeQuant-symb PRIVATE SEQUANT_ASSERT_BEHAVIOR_=${SEQUANT_ASSERT_BEHAVIOR}) +if (NOT SEQUANT_ASSERT_BEHAVIOR STREQUAL "IGNORE") + target_compile_definitions(SeQuant-symb PUBLIC SEQUANT_ASSERT_ENABLED) +endif() if (SEQUANT_CONTEXT_MANIPULATION_THREADSAFE) - target_compile_definitions(SeQuant PUBLIC SEQUANT_CONTEXT_MANIPULATION_THREADSAFE) + target_compile_definitions(SeQuant-symb PRIVATE SEQUANT_CONTEXT_MANIPULATION_THREADSAFE) endif() -target_compile_definitions(SeQuant PUBLIC SEQUANT_ASSERT_BEHAVIOR_=${SEQUANT_ASSERT_BEHAVIOR}) - -target_link_libraries(SeQuant PUBLIC range-v3::range-v3 Boost::regex Boost::locale Boost::headers SeQuant-bliss Threads::Threads) -target_link_libraries(SeQuant PRIVATE libperm::libperm $ Eigen3::Eigen) -target_link_libraries(SeQuant PUBLIC polymorphic_variant::polymorphic_variant) -# modularized Boost has finer grained targets than just Boost::headers +if (SEQUANT_USE_SYSTEM_BOOST_HASH) + target_compile_definitions(SeQuant-symb PUBLIC SEQUANT_USE_SYSTEM_BOOST_HASH=1) +endif() +if (SEQUANT_HAS_EXECUTION_HEADER_STANDALONE OR SEQUANT_HAS_EXECUTION_HEADER_WITH_TBB) + target_compile_definitions(SeQuant-symb PUBLIC SEQUANT_HAS_EXECUTION_HEADER) + if (SEQUANT_HAS_EXECUTION_HEADER_WITH_TBB) + target_link_libraries(SeQuant-symb PRIVATE ${TBB_LIBRARIES}) + endif() +endif() +target_link_libraries(SeQuant-symb + PUBLIC + range-v3::range-v3 + Boost::headers + Boost::locale + polymorphic_variant::polymorphic_variant + PRIVATE + SeQuant-bliss + Threads::Threads +) +target_link_libraries(SeQuant-symb PRIVATE + libperm::libperm + $ + Eigen3::Eigen) if (Boost_IS_MODULARIZED) - target_link_libraries(SeQuant PUBLIC + target_link_libraries(SeQuant-symb PUBLIC Boost::container Boost::container_hash Boost::hana @@ -481,64 +534,120 @@ if (Boost_IS_MODULARIZED) Boost::numeric_conversion Boost::numeric_interval Boost::range - Boost::spirit - ) -endif() -if (SEQUANT_HAS_EVAL) - target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_EVAL=1) - if (SEQUANT_HAS_TILEDARRAY) - target_link_libraries(SeQuant PUBLIC tiledarray) - target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_TILEDARRAY=1) - endif () - if (SEQUANT_HAS_BTAS) - target_link_libraries(SeQuant PUBLIC BTAS::BTAS) - target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_BTAS=1) - endif () -endif() -if (SEQUANT_HAS_EXECUTION_HEADER_STANDALONE OR SEQUANT_HAS_EXECUTION_HEADER_WITH_TBB) - target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_EXECUTION_HEADER) - if (SEQUANT_HAS_EXECUTION_HEADER_WITH_TBB) - target_link_libraries(SeQuant PUBLIC ${TBB_LIBRARIES}) - target_include_directories(SeQuant SYSTEM PUBLIC ${TBB_INCLUDE_DIRS}) - endif () -endif () -if (NOT PROJECT_IS_TOP_LEVEL) - set(SEQUANT_SYSTEM "SYSTEM") + Boost::spirit) endif() -target_include_directories(SeQuant ${SEQUANT_SYSTEM} PUBLIC +target_include_directories(SeQuant-symb ${SEQUANT_SYSTEM} PUBLIC $ $) -target_include_directories(SeQuant SYSTEM PUBLIC +target_include_directories(SeQuant-symb SYSTEM PUBLIC $) -target_compile_features(SeQuant INTERFACE "cxx_std_20") +target_compile_features(SeQuant-symb INTERFACE "cxx_std_20") + +########################## +# SeQuant-eval: backend-agnostic evaluation framework +########################## +sequant_add_library(eval ${SeQuant_eval_src}) +target_link_libraries(SeQuant-eval PUBLIC SeQuant-symb PRIVATE SeQuant-bliss) if (SEQUANT_EVAL_TRACE) - target_compile_definitions(SeQuant PUBLIC SEQUANT_EVAL_TRACE=1) -endif () -if (SEQUANT_USE_SYSTEM_BOOST_HASH) - target_compile_definitions(SeQuant PUBLIC SEQUANT_USE_SYSTEM_BOOST_HASH=1) + target_compile_definitions(SeQuant-eval PUBLIC SEQUANT_EVAL_TRACE=1) endif() -target_set_warning_flags(SeQuant) +########################## +# SeQuant-optimize: expression optimization (STO, CSE, fusion) +########################## +sequant_add_library(optimize ${SeQuant_optimize_src}) +target_link_libraries(SeQuant-optimize PUBLIC SeQuant-eval SeQuant-bliss) -install(TARGETS SeQuant-bliss EXPORT sequant COMPONENT sequant LIBRARY DESTINATION ${SEQUANT_INSTALL_LIBDIR}) -install(TARGETS SeQuant EXPORT sequant COMPONENT sequant LIBRARY DESTINATION ${SEQUANT_INSTALL_LIBDIR}) +########################## +# SeQuant-eval-ta: TiledArray backend +########################## +if (SEQUANT_HAS_TILEDARRAY) + add_library(SeQuant-eval-ta ${SeQuant_eval_ta_src}) + set_target_properties(SeQuant-eval-ta PROPERTIES EXPORT_NAME eval::ta) + add_library(SeQuant::eval::ta ALIAS SeQuant-eval-ta) + target_link_libraries(SeQuant-eval-ta PUBLIC SeQuant-eval tiledarray) + target_compile_definitions(SeQuant-eval-ta PUBLIC SEQUANT_HAS_TILEDARRAY=1) +endif() + +########################## +# SeQuant-eval-btas: BTAS backend (header-only) +########################## +if (SEQUANT_HAS_BTAS) + add_library(SeQuant-eval-btas INTERFACE) + set_target_properties(SeQuant-eval-btas PROPERTIES EXPORT_NAME eval::btas) + add_library(SeQuant::eval::btas ALIAS SeQuant-eval-btas) + target_link_libraries(SeQuant-eval-btas INTERFACE SeQuant-eval BTAS::BTAS) + target_compile_definitions(SeQuant-eval-btas INTERFACE SEQUANT_HAS_BTAS=1) +endif() + +########################## +# SeQuant-export: code generation/export (depends on eval) +########################## +sequant_add_library(export ${SeQuant_export_src}) +target_link_libraries(SeQuant-export PUBLIC SeQuant-eval) + +########################## +# SeQuant-core: version info, links symb + export +########################## +sequant_add_library(core ${SeQuant_core_src}) +target_link_libraries(SeQuant-core PUBLIC SeQuant-symb SeQuant-eval SeQuant-optimize SeQuant-export) +# feed SEQUANT_GIT_REVISION and SEQUANT_GIT_DESCRIPTION to SeQuant/version.cpp only to avoid recompiling everything +set_source_files_properties( + SeQuant/version.cpp + PROPERTIES COMPILE_DEFINITIONS + "SEQUANT_GIT_REVISION=\"${SEQUANT_GIT_REVISION}\";SEQUANT_GIT_DESCRIPTION=\"${SEQUANT_GIT_DESCRIPTION}\"" +) + +########################## +# SeQuant-mbpt: MBPT domain code +########################## +sequant_add_library(mbpt ${SeQuant_mbpt_src}) +target_link_libraries(SeQuant-mbpt PUBLIC SeQuant-core SeQuant-optimize) +target_link_libraries(SeQuant-mbpt PRIVATE Eigen3::Eigen libperm::libperm) +if (SEQUANT_CONTEXT_MANIPULATION_THREADSAFE) + target_compile_definitions(SeQuant-mbpt PRIVATE SEQUANT_CONTEXT_MANIPULATION_THREADSAFE) +endif() + +########################## +# All SeQuant modules (used for install, IWYU, etc.) +########################## +set(SEQUANT_MODULES SeQuant-bliss SeQuant-symb SeQuant-eval SeQuant-optimize SeQuant-export SeQuant-core SeQuant-mbpt SeQuant) +if (SEQUANT_HAS_TILEDARRAY) + list(APPEND SEQUANT_MODULES SeQuant-eval-ta) +endif() +if (SEQUANT_HAS_BTAS) + list(APPEND SEQUANT_MODULES SeQuant-eval-btas) +endif() + +########################## +# SeQuant: umbrella INTERFACE target (backwards compatibility) +########################## +add_library(SeQuant INTERFACE) +target_link_libraries(SeQuant INTERFACE ${SEQUANT_MODULES}) +set_target_properties(SeQuant PROPERTIES EXPORT_NAME SeQuant) +add_library(SeQuant::SeQuant ALIAS SeQuant) + +########################## +# Installation +########################## +install(TARGETS ${SEQUANT_MODULES} + EXPORT sequant COMPONENT sequant + LIBRARY DESTINATION ${SEQUANT_INSTALL_LIBDIR}) install(DIRECTORY SeQuant COMPONENT sequant DESTINATION "${SEQUANT_INSTALL_INCLUDEDIR}" FILES_MATCHING PATTERN "*.hpp" - PATTERN "*.hh" - ) -add_library(SeQuant::SeQuant ALIAS SeQuant) # to be able to use as subproject + PATTERN "*.hh") if (SEQUANT_MIMALLOC) find_package(mimalloc REQUIRED) - target_link_libraries(SeQuant PUBLIC mimalloc) - target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_MIMALLOC=1) + target_link_libraries(SeQuant-symb PUBLIC mimalloc) + target_compile_definitions(SeQuant-symb PUBLIC SEQUANT_HAS_MIMALLOC=1) endif () -# build all of boost before SeQuant, including parts it does not use +# build all of boost before SeQuant-symb, including parts it does not use if (Boost_BUILT_FROM_SOURCE AND TARGET build-boost-in-SeQuant) - add_dependencies(SeQuant build-boost-in-SeQuant) + add_dependencies(SeQuant-symb build-boost-in-SeQuant) endif() if (SEQUANT_IWYU) @@ -550,7 +659,12 @@ if (SEQUANT_IWYU) -Xiwyu --cxx20ns -Xiwyu --no_comments ) - set_property(TARGET SeQuant PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_options_and_path}) + foreach(_target ${SEQUANT_MODULES}) + get_target_property(_type ${_target} TYPE) + if (NOT _type STREQUAL "INTERFACE_LIBRARY") + set_property(TARGET ${_target} PROPERTY CXX_INCLUDE_WHAT_YOU_USE ${iwyu_options_and_path}) + endif() + endforeach() endif() endif() diff --git a/SeQuant/core/context.cpp b/SeQuant/core/context.cpp index a012485da8..ca198d6d41 100644 --- a/SeQuant/core/context.cpp +++ b/SeQuant/core/context.cpp @@ -8,6 +8,14 @@ namespace sequant { +bool default_context_manipulation_threadsafe() { +#ifdef SEQUANT_CONTEXT_MANIPULATION_THREADSAFE + return true; +#else + return false; +#endif +} + bool operator==(const Context& ctx1, const Context& ctx2) { if (&ctx1 == &ctx2) return true; diff --git a/SeQuant/core/context.hpp b/SeQuant/core/context.hpp index 42a458c684..3f60dc5f6d 100644 --- a/SeQuant/core/context.hpp +++ b/SeQuant/core/context.hpp @@ -222,13 +222,7 @@ bool operator!=(const Context& ctx1, const Context& ctx2); /// @{ /// \return whether context manipulation functions are thread-safe -inline constexpr bool default_context_manipulation_threadsafe() { -#ifdef SEQUANT_CONTEXT_MANIPULATION_THREADSAFE - return true; -#else - return false; -#endif -} +bool default_context_manipulation_threadsafe(); /// @brief access default Context for the given Statistics /// @param s Statistics diff --git a/SeQuant/core/optimize.hpp b/SeQuant/core/eval/optimize.hpp similarity index 98% rename from SeQuant/core/optimize.hpp rename to SeQuant/core/eval/optimize.hpp index 42879fb04b..d7aa8fefc7 100644 --- a/SeQuant/core/optimize.hpp +++ b/SeQuant/core/eval/optimize.hpp @@ -388,7 +388,7 @@ ExprPtr optimize(ExprPtr const& expr, IdxToSize const& idx2size, } // namespace opt /// -/// Optimize the expression using IndexSpace::aproximate_size() for reference +/// Optimize the expression using IndexSpace::approximate_size() for reference /// index extent. /// /// \param expr Expression to be optimized. @@ -398,7 +398,7 @@ ExprPtr optimize(ExprPtr const& expr, IdxToSize const& idx2size, /// \return Optimized expression for lower evaluation cost. ExprPtr optimize(ExprPtr const& expr, bool reorder_sum = true); -/// Optimize the expression using IndexSpace::aproximate_size() for reference +/// Optimize the expression using IndexSpace::approximate_size() for reference /// index extent. /// /// \param expr Expression to be optimized. @@ -408,7 +408,7 @@ ExprPtr optimize(ExprPtr const& expr, bool reorder_sum = true); /// \return Optimized expression for lower evaluation cost. ResultExpr& optimize(ResultExpr& expr, bool reorder_sum = true); -/// Optimize the expression using IndexSpace::aproximate_size() for reference +/// Optimize the expression using IndexSpace::approximate_size() for reference /// index extent. /// /// \param expr Expression to be optimized. diff --git a/SeQuant/core/optimize/common_subexpression_elimination.hpp b/SeQuant/core/eval/optimize/common_subexpression_elimination.hpp similarity index 100% rename from SeQuant/core/optimize/common_subexpression_elimination.hpp rename to SeQuant/core/eval/optimize/common_subexpression_elimination.hpp diff --git a/SeQuant/core/optimize/fusion.cpp b/SeQuant/core/eval/optimize/fusion.cpp similarity index 98% rename from SeQuant/core/optimize/fusion.cpp rename to SeQuant/core/eval/optimize/fusion.cpp index 0a663a29ca..b4c37d9834 100644 --- a/SeQuant/core/optimize/fusion.cpp +++ b/SeQuant/core/eval/optimize/fusion.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include diff --git a/SeQuant/core/optimize/fusion.hpp b/SeQuant/core/eval/optimize/fusion.hpp similarity index 100% rename from SeQuant/core/optimize/fusion.hpp rename to SeQuant/core/eval/optimize/fusion.hpp diff --git a/SeQuant/core/optimize/optimize.cpp b/SeQuant/core/eval/optimize/optimize.cpp similarity index 98% rename from SeQuant/core/optimize/optimize.cpp rename to SeQuant/core/eval/optimize/optimize.cpp index 099e002367..ab7ef05f65 100644 --- a/SeQuant/core/optimize/optimize.cpp +++ b/SeQuant/core/eval/optimize/optimize.cpp @@ -2,10 +2,9 @@ #include #include #include -#include +#include #include #include -#include #include #include diff --git a/SeQuant/core/expressions/result_expr.cpp b/SeQuant/core/expressions/result_expr.cpp index ce8f9f947b..c924a03e05 100644 --- a/SeQuant/core/expressions/result_expr.cpp +++ b/SeQuant/core/expressions/result_expr.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include namespace sequant { diff --git a/SeQuant/core/utility/macros.cpp b/SeQuant/core/utility/macros.cpp new file mode 100644 index 0000000000..348f25249f --- /dev/null +++ b/SeQuant/core/utility/macros.cpp @@ -0,0 +1,43 @@ +// +// Created by Eduard Valeyev on 7/31/23 +// + +#include + +#include +#include +#include + +#define SEQUANT_ASSERT_BEHAVIOR \ + SEQUANT_CONCAT(SEQUANT_ASSERT_, SEQUANT_ASSERT_BEHAVIOR_) + +namespace sequant { + +#ifdef SEQUANT_ASSERT_ENABLED +void assert_failed(const std::string &errmsg, + const std::source_location location) { +#if SEQUANT_ASSERT_BEHAVIOR == SEQUANT_ASSERT_THROW + std::ostringstream oss; + oss << errmsg << " at " << location.file_name() << ":" << location.line() + << " in function '" << location.function_name() << "'"; + throw sequant::Exception(oss.str()); +#elif SEQUANT_ASSERT_BEHAVIOR == SEQUANT_ASSERT_ABORT + std::cerr << errmsg << " at " << location.file_name() << ":" + << location.line() << " in function '" << location.function_name() + << "'" << std::endl; + std::abort(); +#endif +} +#else +void assert_failed(const std::string &, const std::source_location) {} +#endif + +[[noreturn]] void abort_msg(const std::string &errmsg, + const std::source_location location) { + std::cerr << errmsg << " at " << location.file_name() << ":" + << location.line() << " in function '" << location.function_name() + << "'"; + std::abort(); +} + +} // namespace sequant diff --git a/SeQuant/core/utility/macros.hpp b/SeQuant/core/utility/macros.hpp index 571a406839..fd2bc357f7 100644 --- a/SeQuant/core/utility/macros.hpp +++ b/SeQuant/core/utility/macros.hpp @@ -8,10 +8,8 @@ #include #include -#include #include -#include -#include +#include /* detect C++ compiler id: - ids taken from CMake @@ -71,38 +69,15 @@ #define SEQUANT_ASSERT_ABORT 3 #define SEQUANT_ASSERT_IGNORE 4 #define SEQUANT_STRINGIFY(x) #x -#define SEQUANT_ASSERT_BEHAVIOR \ - SEQUANT_CONCAT(SEQUANT_ASSERT_, SEQUANT_ASSERT_BEHAVIOR_) -#if SEQUANT_ASSERT_BEHAVIOR != SEQUANT_ASSERT_IGNORE -#define SEQUANT_ASSERT_ENABLED -#endif namespace sequant { #ifdef SEQUANT_ASSERT_ENABLED [[noreturn]] #endif -inline void -assert_failed([[maybe_unused]] const std::string &errmsg, - [[maybe_unused]] const std::source_location location = - std::source_location::current()) { -#ifdef SEQUANT_ASSERT_ENABLED -#if SEQUANT_ASSERT_BEHAVIOR == SEQUANT_ASSERT_THROW - std::ostringstream oss; - oss -#elif SEQUANT_ASSERT_BEHAVIOR == SEQUANT_ASSERT_ABORT - std::cerr -#endif // SEQUANT_ASSERT_BEHAVIOR - << errmsg << " at " << location.file_name() << ":" << location.line() - << " in function '" << location.function_name() << "'"; -#if SEQUANT_ASSERT_BEHAVIOR == SEQUANT_ASSERT_THROW - throw sequant::Exception(oss.str()); -#elif SEQUANT_ASSERT_BEHAVIOR == SEQUANT_ASSERT_ABORT - std::cerr << std::endl; - std::abort(); -#endif // SEQUANT_ASSERT_BEHAVIOR -#endif // SEQUANT_ASSERT_ENABLED -} +void assert_failed( + const std::string &errmsg, + std::source_location location = std::source_location::current()); } // namespace sequant #ifdef SEQUANT_ASSERT_ENABLED @@ -123,14 +98,9 @@ assert_failed([[maybe_unused]] const std::string &errmsg, #endif namespace sequant { -[[noreturn]] inline void abort_msg( +[[noreturn]] void abort_msg( const std::string &errmsg, - const std::source_location location = std::source_location::current()) { - std::cerr << errmsg << " at " << location.file_name() << ":" - << location.line() << " in function '" << location.function_name() - << "'"; - std::abort(); -} + std::source_location location = std::source_location::current()); } // namespace sequant #define SEQUANT_ABORT(msg) sequant::abort_msg(msg) diff --git a/SeQuant/core/wick.cpp b/SeQuant/core/wick.cpp new file mode 100644 index 0000000000..881bee2a49 --- /dev/null +++ b/SeQuant/core/wick.cpp @@ -0,0 +1,14 @@ +// +// Created by Eduard Valeyev on 10/9/25. +// + +#include + +#include + +namespace sequant { + +template class WickTheorem; +template class WickTheorem; + +} // namespace sequant diff --git a/SeQuant/core/wick.hpp b/SeQuant/core/wick.hpp index 32fda728f0..712fac780e 100644 --- a/SeQuant/core/wick.hpp +++ b/SeQuant/core/wick.hpp @@ -1611,6 +1611,9 @@ class WickTheorem { void reduce(ExprPtr &expr) const; }; +extern template class WickTheorem; +extern template class WickTheorem; + using BWickTheorem = WickTheorem; using FWickTheorem = WickTheorem; diff --git a/SeQuant/domain/mbpt/spin.cpp b/SeQuant/domain/mbpt/spin.cpp index bcb171aee0..2cf559c60c 100644 --- a/SeQuant/domain/mbpt/spin.cpp +++ b/SeQuant/domain/mbpt/spin.cpp @@ -3,9 +3,9 @@ #include #include +#include #include #include -#include #include #include #include diff --git a/cmake/sequant-config.cmake.in b/cmake/sequant-config.cmake.in index a2c639f7ad..7597f69fbf 100644 --- a/cmake/sequant-config.cmake.in +++ b/cmake/sequant-config.cmake.in @@ -7,7 +7,13 @@ # # and the following imported targets # -# SeQuant::SeQuant - the SeQuant library +# SeQuant::SeQuant - umbrella SeQuant target (links all modules) +# SeQuant::symb - symbolic core +# SeQuant::eval - evaluation framework +# SeQuant::optimize - expression optimization (STO, CSE, fusion) +# SeQuant::export - code generation/export +# SeQuant::core - version info + symb + eval + export +# SeQuant::mbpt - MBPT domain code # # Set package version @@ -72,9 +78,19 @@ endif (NOT TARGET Threads::Threads) # Include library IMPORT targets if(NOT TARGET SeQuant::SeQuant) include("${CMAKE_CURRENT_LIST_DIR}/sequant-targets.cmake") - if(NOT TARGET SeQuant::SeQuant) - message(FATAL_ERROR "expected SeQuant::SeQuant among imported SeQuant targets") + # Verify expected targets exist + set(grandTargetList symb eval optimize export core mbpt SeQuant) + if (SEQUANT_HAS_TILEDARRAY) + list(APPEND grandTargetList eval::ta) endif() + if (SEQUANT_HAS_BTAS) + list(APPEND grandTargetList eval::btas) + endif() + foreach(_target ${grandTargetList}) + if(NOT TARGET SeQuant::${_target}) + message(FATAL_ERROR "expected SeQuant::${_target} among imported SeQuant targets") + endif() + endforeach() endif() set(SEQUANT_FOUND TRUE) diff --git a/doc/user/guide/operator.rst b/doc/user/guide/operator.rst index 8f959040b2..326b60c17f 100644 --- a/doc/user/guide/operator.rst +++ b/doc/user/guide/operator.rst @@ -47,7 +47,7 @@ only the non-zero contributions. ``mbpt::Operator`` is constructed from 3 callables (e.g., lambdas): -- ``void -> std::wstring_view``: returns the operator label such as "T" or "Λ" +- ``void -> std::wstring_view``: returns the operator label such as "t" or "λ" - ``void -> ExptPtr``: returns the tensor form of the operator, and - ``QuantumNumberChange<>& -> void``: encodes the action on the given input state by mutating its quantum numbers given as the argument to the lambda. diff --git a/tests/integration/eval/calc_info.hpp b/tests/integration/eval/calc_info.hpp index 835059d6bf..e5f6e790b0 100644 --- a/tests/integration/eval/calc_info.hpp +++ b/tests/integration/eval/calc_info.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index 0c341696e1..bc3b9f67b0 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -1,36 +1,26 @@ include(FindOrFetchCatch2) include(Catch) -add_executable(unit_tests-sequant ${BUILD_BY_DEFAULT} +########################## +# OBJECT library: Symbolic layer tests (SeQuant-symb) +########################## +set(symb_test_sources "test_abstract_tensor.cpp" "test_asy_cost.cpp" "test_binary_node.cpp" - "test_biorthogonalization.cpp" "test_bliss.cpp" "test_canonicalize.cpp" - "test_eval_expr.cpp" - "test_eval_node.cpp" - "test_export.cpp" - "test_export.hpp" - "test_export_python.cpp" "test_expr.cpp" - "test_expr.cpp" - "test_fusion.cpp" "test_index.cpp" "test_iterator.cpp" "test_latex.cpp" - "test_main.cpp" "test_macros.cpp" "test_math.cpp" - "test_mbpt.cpp" - "test_mbpt_cc.cpp" "test_meta.cpp" "test_op.cpp" - "test_optimize.cpp" "test_parse.cpp" "test_runtime.cpp" "test_space.cpp" - "test_spin.cpp" "test_string.cpp" "test_tensor.cpp" "test_tensor_network.cpp" @@ -38,8 +28,140 @@ add_executable(unit_tests-sequant ${BUILD_BY_DEFAULT} "test_wick.cpp" ) -target_compile_definitions(unit_tests-sequant PRIVATE SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") -target_link_libraries(unit_tests-sequant PRIVATE Boost::boost Eigen3::Eigen) +add_library(unit_tests-sequant-symb-obj OBJECT ${symb_test_sources}) +target_link_libraries(unit_tests-sequant-symb-obj + PUBLIC SeQuant::symb SeQuant::bliss + PRIVATE Catch2::Catch2 dtl::dtl) +target_compile_definitions(unit_tests-sequant-symb-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +########################## +# OBJECT library: Eval framework tests (SeQuant-eval) +########################## +set(eval_test_sources + "test_eval_expr.cpp" + "test_eval_node.cpp" +) +add_library(unit_tests-sequant-eval-obj OBJECT ${eval_test_sources}) +target_link_libraries(unit_tests-sequant-eval-obj + PUBLIC SeQuant::eval + PRIVATE Catch2::Catch2 dtl::dtl) +target_compile_definitions(unit_tests-sequant-eval-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +########################## +# OBJECT library: Optimize tests (SeQuant-optimize) +########################## +set(optimize_test_sources + "test_fusion.cpp" + "test_optimize.cpp" +) +add_library(unit_tests-sequant-optimize-obj OBJECT ${optimize_test_sources}) +target_link_libraries(unit_tests-sequant-optimize-obj + PUBLIC SeQuant::optimize SeQuant::bliss + PRIVATE Catch2::Catch2 dtl::dtl) +target_compile_definitions(unit_tests-sequant-optimize-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +########################## +# OBJECT library: Export tests (SeQuant-export) +########################## +set(export_test_sources + "test_export.cpp" + "test_export.hpp" + "test_export_python.cpp" +) +add_library(unit_tests-sequant-export-obj OBJECT ${export_test_sources}) +target_link_libraries(unit_tests-sequant-export-obj + PUBLIC SeQuant::export SeQuant::optimize + PRIVATE Catch2::Catch2 dtl::dtl Eigen3::Eigen) +target_compile_definitions(unit_tests-sequant-export-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +########################## +# OBJECT library: MBPT tests +########################## +set(mbpt_test_sources + "test_biorthogonalization.cpp" + "test_mbpt.cpp" + "test_mbpt_cc.cpp" + "test_spin.cpp" +) + +add_library(unit_tests-sequant-mbpt-obj OBJECT ${mbpt_test_sources}) +target_link_libraries(unit_tests-sequant-mbpt-obj + PUBLIC SeQuant::mbpt + PRIVATE Catch2::Catch2 dtl::dtl) +target_compile_definitions(unit_tests-sequant-mbpt-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +########################## +# OBJECT library: TiledArray backend tests (conditional) +########################## +if (SEQUANT_HAS_TILEDARRAY) + set(eval_ta_test_sources + "test_eval_ta.cpp" + "test_cache_manager.cpp" + ) + add_library(unit_tests-sequant-eval-ta-obj OBJECT ${eval_ta_test_sources}) + target_link_libraries(unit_tests-sequant-eval-ta-obj + PUBLIC SeQuant::eval::ta SeQuant::mbpt + PRIVATE Catch2::Catch2 dtl::dtl) + target_compile_definitions(unit_tests-sequant-eval-ta-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + set_source_files_properties(${eval_ta_test_sources} + PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) +endif() + +########################## +# OBJECT library: BTAS backend tests (conditional) +########################## +if (SEQUANT_HAS_BTAS) + set(eval_btas_test_sources "test_eval_btas.cpp") + # Include cache_manager test if TA is not available (avoid duplicate) + if (NOT SEQUANT_HAS_TILEDARRAY) + list(APPEND eval_btas_test_sources "test_cache_manager.cpp") + endif() + add_library(unit_tests-sequant-eval-btas-obj OBJECT ${eval_btas_test_sources}) + target_link_libraries(unit_tests-sequant-eval-btas-obj + PUBLIC SeQuant::eval::btas SeQuant::mbpt + PRIVATE Catch2::Catch2 dtl::dtl) + target_compile_definitions(unit_tests-sequant-eval-btas-obj PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + set_source_files_properties(${eval_btas_test_sources} + PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) +endif() + +########################## +# Single executable combining all OBJECT libraries +# NB linking OBJECT libraries (since CMake 3.21) both includes their object +# files AND propagates their PUBLIC/INTERFACE usage requirements, so the +# SeQuant module link deps flow through automatically. +########################## +add_executable(unit_tests-sequant ${BUILD_BY_DEFAULT} + "test_main.cpp" +) +target_link_libraries(unit_tests-sequant PRIVATE + unit_tests-sequant-symb-obj + unit_tests-sequant-eval-obj + unit_tests-sequant-optimize-obj + unit_tests-sequant-export-obj + unit_tests-sequant-mbpt-obj + Catch2::Catch2 + dtl::dtl) +if (SEQUANT_HAS_TILEDARRAY) + target_link_libraries(unit_tests-sequant PRIVATE unit_tests-sequant-eval-ta-obj) +endif() +if (SEQUANT_HAS_BTAS) + target_link_libraries(unit_tests-sequant PRIVATE unit_tests-sequant-eval-btas-obj) +endif() + +target_compile_definitions(unit_tests-sequant PRIVATE + SEQUANT_UNIT_TESTS_SOURCE_DIR="${CMAKE_CURRENT_SOURCE_DIR}") + +# Skip unity build for test_main.cpp +set_source_files_properties("test_main.cpp" + PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON) # Optional: Find Python for PythonEinsumGenerator validation tests find_package(Python 3 COMPONENTS Interpreter QUIET) @@ -57,7 +179,7 @@ if(Python_Interpreter_FOUND) if(_numpy_status EQUAL 0) message(STATUS "NumPy ${_numpy_version} found for export validation tests") - target_compile_definitions(unit_tests-sequant PRIVATE + target_compile_definitions(unit_tests-sequant-export-obj PRIVATE SEQUANT_HAS_NUMPY_FOR_VALIDATION=1) else() message(STATUS "NumPy not found - PythonEinsumGenerator NumPy validation tests will be disabled") @@ -74,44 +196,25 @@ if(Python_Interpreter_FOUND) if(_torch_status EQUAL 0) message(STATUS "PyTorch ${_torch_version} found for export validation tests") - target_compile_definitions(unit_tests-sequant PRIVATE SEQUANT_HAS_TORCH_FOR_VALIDATION=1) + target_compile_definitions(unit_tests-sequant-export-obj PRIVATE + SEQUANT_HAS_TORCH_FOR_VALIDATION=1) else() message(STATUS "PyTorch not found - PythonEinsumGenerator PyTorch validation tests will be disabled") endif() if (_numpy_status EQUAL 0 OR _torch_status EQUAL 0) - target_compile_definitions(unit_tests-sequant PRIVATE - SEQUANT_UNITTESTS_PYTHON_EXECUTABLE="${Python_EXECUTABLE}") + target_compile_definitions(unit_tests-sequant-export-obj PRIVATE + SEQUANT_UNITTESTS_PYTHON_EXECUTABLE="${Python_EXECUTABLE}") endif() else() message(STATUS "Python not found - PythonEinsumGenerator validation tests will be disabled") endif() if (SEQUANT_SKIP_LONG_TESTS) - target_compile_definitions(unit_tests-sequant PRIVATE SEQUANT_SKIP_LONG_TESTS=1) + target_compile_definitions(unit_tests-sequant-symb-obj PRIVATE SEQUANT_SKIP_LONG_TESTS=1) + target_compile_definitions(unit_tests-sequant-mbpt-obj PRIVATE SEQUANT_SKIP_LONG_TESTS=1) endif() -if (SEQUANT_HAS_EVAL) - set(sq_ut_eval_src "test_cache_manager.cpp") - if (SEQUANT_HAS_TILEDARRAY) - list(APPEND sq_ut_eval_src "test_eval_ta.cpp") - endif() - if (SEQUANT_HAS_BTAS) - list(APPEND sq_ut_eval_src "test_eval_btas.cpp") - endif() - target_sources(unit_tests-sequant - PRIVATE - ${sq_ut_eval_src} - ) - set_source_files_properties( - ${sq_ut_eval_src} - "test_main.cpp" - PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON - ) -endif (SEQUANT_HAS_EVAL) - -target_link_libraries(unit_tests-sequant PRIVATE SeQuant::SeQuant Catch2::Catch2 dtl::dtl) - target_set_warning_flags(unit_tests-sequant) if (SEQUANT_TESTS) diff --git a/tests/unit/gwt.hpp b/tests/unit/gwt.hpp index b755560381..4324c2fa2d 100644 --- a/tests/unit/gwt.hpp +++ b/tests/unit/gwt.hpp @@ -60,7 +60,9 @@ class GWT { bool done = false; while (!done) { result_t next_wf_terms; - for (const auto& [oper, contrs] : current_wf_terms) { + for (auto&& o_c : current_wf_terms) { + const auto& oper = o_c.oper; + const auto& contrs = o_c.contrs; // return true if op_it is first op of its type (cre or ann) in its // nop auto first_in_nop = [this, &oper](const auto& op_it) { diff --git a/tests/unit/test_eval_btas.cpp b/tests/unit/test_eval_btas.cpp index eec460d604..6d950859ac 100644 --- a/tests/unit/test_eval_btas.cpp +++ b/tests/unit/test_eval_btas.cpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include diff --git a/tests/unit/test_eval_expr.cpp b/tests/unit/test_eval_expr.cpp index 48fef17f35..6e858378c5 100644 --- a/tests/unit/test_eval_expr.cpp +++ b/tests/unit/test_eval_expr.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include diff --git a/tests/unit/test_eval_node.cpp b/tests/unit/test_eval_node.cpp index 4b742d36a8..71c1f4319a 100644 --- a/tests/unit/test_eval_node.cpp +++ b/tests/unit/test_eval_node.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include diff --git a/tests/unit/test_export.cpp b/tests/unit/test_export.cpp index a3d1731063..b0f07c5895 100644 --- a/tests/unit/test_export.cpp +++ b/tests/unit/test_export.cpp @@ -3,6 +3,7 @@ #include "test_export.hpp" +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/tests/unit/test_fusion.cpp b/tests/unit/test_fusion.cpp index b7259ccb95..73e8668f65 100644 --- a/tests/unit/test_fusion.cpp +++ b/tests/unit/test_fusion.cpp @@ -2,8 +2,8 @@ #include "catch2_sequant.hpp" +#include #include -#include #include #include diff --git a/tests/unit/test_optimize.cpp b/tests/unit/test_optimize.cpp index 951e286aaf..41b906a539 100644 --- a/tests/unit/test_optimize.cpp +++ b/tests/unit/test_optimize.cpp @@ -6,10 +6,10 @@ #include #include #include +#include +#include #include #include -#include -#include #include #include #include diff --git a/utilities/external-interface/CMakeLists.txt b/utilities/external-interface/CMakeLists.txt index 779332e6aa..e144b4cbcb 100644 --- a/utilities/external-interface/CMakeLists.txt +++ b/utilities/external-interface/CMakeLists.txt @@ -12,7 +12,8 @@ add_executable(external_interface target_link_libraries(external_interface PRIVATE - SeQuant::SeQuant + SeQuant::mbpt + SeQuant::export nlohmann_json::nlohmann_json CLI11::CLI11 Boost::headers diff --git a/utilities/external-interface/external_interface.cpp b/utilities/external-interface/external_interface.cpp index 441b1896e1..a735d6f359 100644 --- a/utilities/external-interface/external_interface.cpp +++ b/utilities/external-interface/external_interface.cpp @@ -3,6 +3,7 @@ #include "utils.hpp" #include +#include #include #include #include @@ -10,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/utilities/external-interface/processing.cpp b/utilities/external-interface/processing.cpp index 100f413ca5..9e200d14d6 100644 --- a/utilities/external-interface/processing.cpp +++ b/utilities/external-interface/processing.cpp @@ -3,9 +3,9 @@ #include "utils.hpp" #include +#include #include #include -#include #include #include #include