Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into ajay/feature/eom-cc
Browse files Browse the repository at this point in the history
  • Loading branch information
ajay-mk committed Feb 15, 2024
2 parents 1f0fd88 + 4b5cc99 commit 3f0d94a
Show file tree
Hide file tree
Showing 23 changed files with 1,451 additions and 1,603 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ jobs:
if: ${{ matrix.os == 'ubuntu-22.04' }}
run: |
sudo apt-get update
sudo apt-get install ninja-build liblapack-dev libboost-dev libboost-locale-dev libboost-regex-dev libeigen3-dev openmpi-bin libopenmpi-dev ccache
sudo apt-get install ninja-build liblapack-dev libboost-dev libboost-locale-dev libboost-random-dev libboost-regex-dev libeigen3-dev openmpi-bin libopenmpi-dev ccache
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ repos:
name: Format C/C++ code using clang-format.
language: system
files: \.(c|cc|cxx|cpp|h|hpp|hxx)$
entry: clang-format -i
args: [--style=file]
entry: bin/admin/clang-format.sh
args: [--style=file -i]
62 changes: 35 additions & 27 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,26 +138,8 @@ check_cxx_execution_header(SEQUANT)
# Ranges-V3
include(FindOrFetchRangeV3)

# need header-only Boost + (compiled) Boost.Regex and Boost.Locale
# NB Boost.Container is broken in v1.70
if (NOT TARGET Boost::boost OR NOT TARGET Boost::regex OR NOT TARGET Boost::locale)
find_package(Boost ${SEQUANT_TRACKED_BOOST_VERSION} CONFIG COMPONENTS regex locale)
if (Boost_VERSION_STRING VERSION_LESS ${SEQUANT_TRACKED_BOOST_VERSION} OR NOT TARGET Boost::boost OR NOT TARGET Boost::regex OR NOT TARGET Boost::locale)
find_package(Boost ${SEQUANT_TRACKED_BOOST_VERSION} REQUIRED COMPONENTS regex locale)
message(STATUS "Found Boost (version ${Boost_VERSION}) via FindBoost module")
set(Boost_USE_CONFIG FALSE)
else ()
message(STATUS "Found Boost (version ${Boost_VERSION}) via CONFIG ${Boost_CONFIG}")
set(Boost_USE_CONFIG TRUE)
endif ()
# Boost.Move is broken in 1.77 and 1.78 unless using c++20
# fixed in 1.79 via https://github.com/boostorg/move/commit/78f26da1f3a5a3831e9e70efe83f9c56eef94e8c
if (CMAKE_CXX_STANDARD LESS 20)
if (Boost_VERSION_MACRO GREATER_EQUAL 107700 AND Boost_VERSION_MACRO LESS 107900)
message(FATAL_ERROR "Found Boost 1.77 <= version < 1.79, but its Boost.Move is broken with pre-C++20: use a version older than 1.77 or newer than 1.78")
endif ()
endif ()
endif ()
# Boost will be added after defining SeQuant
include(external/boost.cmake)

# embedded bliss-0.73
add_library(SeQuant-bliss
Expand Down Expand Up @@ -269,16 +251,25 @@ set_source_files_properties(
SeQuant/domain/mbpt/op.cpp SeQuant/domain/mbpt/sr.cpp SeQuant/domain/mbpt/mr.cpp PROPERTIES SKIP_UNITY_BUILD_INCLUSION ON)

### optional prereqs
if (NOT TARGET Eigen3::Eigen)
# re:NO_CMAKE_PACKAGE_REGISTRY: eigen3 registers its *build* tree with the user package registry ...
# to avoid issues with wiped build directory look for installed eigen
find_package(Eigen3 3.0 NO_MODULE NO_CMAKE_PACKAGE_REGISTRY)
endif()
if (SEQUANT_EVAL_TESTS)
include(FindOrFetchTiledArray)
endif (SEQUANT_EVAL_TESTS)
if (NOT TARGET Eigen3::Eigen)
# use TA's Eigen, if available
if (TARGET TiledArray_Eigen)
add_library(Eigen3::Eigen ALIAS TiledArray_Eigen)
else()
# re:NO_CMAKE_PACKAGE_REGISTRY: eigen3 registers its *build* tree with the user package registry ...
# to avoid issues with wiped build directory look for installed eigen
find_package(Eigen3 3.0 NO_MODULE NO_CMAKE_PACKAGE_REGISTRY)
endif()
endif()
if (TARGET Eigen3::Eigen)
set(SEQUANT_HAS_EIGEN ON)
endif()

if (TARGET tiledarray)
set(SEQUANT_HAS_TILEDARRAY ON)
list(APPEND SeQuant_src
SeQuant/domain/eval/cache_manager.cpp
SeQuant/domain/eval/cache_manager.hpp
Expand All @@ -299,7 +290,19 @@ set_source_files_properties(
"SEQUANT_GIT_REVISION=\"${SEQUANT_GIT_REVISION}\";SEQUANT_GIT_DESCRIPTION=\"${SEQUANT_GIT_DESCRIPTION}\""
)

target_link_libraries(SeQuant PUBLIC range-v3::range-v3 Boost::regex Boost::locale Boost::boost SeQuant-bliss Threads::Threads)
target_link_libraries(SeQuant PUBLIC range-v3::range-v3 Boost::regex Boost::locale Boost::headers SeQuant-bliss Threads::Threads)
# modularized Boost has finer grained targets than just Boost::headers
if (Boost_IS_MODULARIZED)
target_link_libraries(SeQuant PUBLIC
Boost::container
Boost::container_hash
Boost::multiprecision
Boost::numeric_conversion
Boost::numeric_interval
Boost::range
Boost::spirit
)
endif()
if (TARGET tiledarray)
target_link_libraries(SeQuant PUBLIC tiledarray)
endif ()
Expand Down Expand Up @@ -359,6 +362,11 @@ if (SEQUANT_MIMALLOC)
target_compile_definitions(SeQuant PUBLIC SEQUANT_HAS_MIMALLOC=1)
endif ()

# build all of boost before SeQuant, including parts it does not use
if (Boost_BUILT_FROM_SOURCE AND TARGET build-boost-in-SeQuant)
add_dependencies(SeQuant build-boost-in-SeQuant)
endif()

### unit tests
include(CTest)

Expand Down Expand Up @@ -498,7 +506,7 @@ if (BUILD_TESTING)
examples/eval/btas/data_world_btas.hpp
examples/eval/btas/scf_btas.hpp
examples/eval/btas/main.cpp)
target_include_directories(${example7} PUBLIC ${BTAS_SOURCE_DIR} ${Boost_INCLUDE_DIRS})
target_include_directories(${example7} PUBLIC ${BTAS_SOURCE_DIR})
target_link_libraries(${example7} SeQuant)
endif (BTAS_SOURCE_DIR)

Expand Down
11 changes: 6 additions & 5 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ prerequisites:
* mandatory:
* CMake 3.15 or later
* a C++17 compiler
* [Boost](https://www.boost.org/), version 1.67 or higher (N.B. critical bugs make the following versions unusable: 1.70, 1.77, 1.78); the following non-header-only Boost libraries are required:
* [Boost](https://www.boost.org/), version 1.81 or higher (N.B. older compilers _may_ work with older Boost releases). *SeQuant can download and build Boost if configured with `Boost_FETCH_IF_MISSING=ON`, but this is not recommended.* The following non-header-only Boost libraries are required, hence Boost must be configured/built:
- [Boost.Regex](https://www.boost.org/doc/libs/master/libs/regex/doc/html/index.html)
- [Boost.Locale](https://www.boost.org/doc/libs/master/libs/locale/doc/html/index.html)
* [Range-V3](https://github.com/ericniebler/range-v3.git), tag 0.12.0, *if not found, SeQuant will download and build Range-V3*
* optional:
* for building coupled-cluster evaluation tests:
* [TiledArray](https://github.com/ValeevGroup/tiledarray.git), tag 81bafdc39568d7d5f981d4453e4a2f49a9c0c428
* [TiledArray](https://github.com/ValeevGroup/tiledarray.git), tag 3f6629db047417e814b75ad5069b7f4ce26428e7
* for building `stcc*` example programs
* [Eigen](http://eigen.tuxfamily.org/), version 3

Expand All @@ -20,8 +20,9 @@ for the impatient (from the top of the SeQuant source directory):
* `cmake --build build --target check-sequant`

useful CMake variables:
* `BUILD_TESTING` --- enables unit tests targets, e.g. `check-sequant` [default=ON]
* `CMAKE_CXX_COMPILER` --- specifies the C++ compiler to use
* `CMAKE_PREFIX_PATH` --- this semicolon-separated list specifies search paths for dependencies (Boost, Range-V3, etc.)
* [`BUILD_TESTING`](https://cmake.org/cmake/help/latest/module/CTest.html) --- enables unit tests targets, e.g. `check-sequant` [default=ON]
* [`CMAKE_CXX_COMPILER`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER.html#variable:CMAKE_%3CLANG%3E_COMPILER) --- specifies the C++ compiler to use
* [`CMAKE_PREFIX_PATH`](https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html) --- this semicolon-separated list specifies search paths for dependencies (Boost, Range-V3, etc.)
* `SEQUANT_MIMALLOC` --- use [mimalloc](https://github.com/microsoft/mimalloc) for fast memory allocation
* `SEQUANT_EVAL_TRACE` --- enables tracing of expression interpretation; especially useful in combination with TiledArray's memory tracing mechanism (configure TiledArray with `TA_TENSOR_MEM_PROFILE=ON` to enable that)
* `Boost_FETCH_IF_MISSING` --- if set to `ON`, SeQuant will download and build Boost if it is not found by `find_package(Boost ...)`; this is not recommended. [default=OFF]
4 changes: 2 additions & 2 deletions SeQuant/core/algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@ void bubble_sort(ForwardIter begin, Sentinel end, Compare comp) {
static_assert(std::tuple_size_v<decltype(val0)> == 2,
"need to generalize comparer to handle tuples");
auto composite_compare = [](auto&& c0, auto&& c1) {
if (std::get<0>(c0) < std::get<0>(c1)) { // c0[0] < c1[1]
if (std::get<0>(c0) < std::get<0>(c1)) { // c0[0] < c1[0]
return true;
} else if (!(std::get<0>(c1) < std::get<0>(c0))) { // c0[0] == c1[0]
return std::get<1>(c0) < std::get<1>(c1);
} else { // c0[0] > c1[0]
} else { // c0[0] > c1[0]
return false;
}
};
Expand Down
125 changes: 34 additions & 91 deletions SeQuant/core/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
#define SEQUANT_HASH_HPP

#ifdef SEQUANT_USE_SYSTEM_BOOST_HASH
#include <boost/version.hpp>
#define SEQUANT_BOOST_VERSION BOOST_VERSION
#include <boost/container_hash/hash.hpp>
namespace sequant_boost = boost;
#define SEQUANT_BOOST_VERSION BOOST_VERSION
#else
#include <SeQuant/external/boost/container_hash/hash.hpp>
#endif

#if SEQUANT_BOOST_VERSION < 108100
#error "SeQuant requires Boost 1.81 or later for hashing"
#endif

#include "meta.hpp"

namespace sequant {
Expand All @@ -26,19 +31,7 @@ enum class Impl { BoostPre181 = 1, Boost181OrLater = 2 };

/// @return the version of hashing used by SeQuant, depends on the version of
/// Boost
constexpr hash::Impl hash_version() {
#ifdef SEQUANT_USE_SYSTEM_BOOST_HASH
#if SEQUANT_BOOST_VERSION < 108100
return hash::Impl::BoostPre181;
#else
return hash::Impl::Boost181OrLater;
#endif
#else
return hash::Impl::Boost181OrLater;
#endif
}

class Expr;
constexpr hash::Impl hash_version() { return hash::Impl::Boost181OrLater; }

namespace detail {
template <typename T, typename Enabler = void>
Expand All @@ -53,30 +46,15 @@ template <typename T>
static constexpr bool has_hash_value_member_fn_v =
detail::has_hash_value_member_fn_helper<T>::value;

#ifdef SEQUANT_USE_SYSTEM_BOOST_HASH
#if SEQUANT_BOOST_VERSION < 108100
template <typename T,
typename = std::enable_if_t<has_hash_value_member_fn_v<T>>>
auto hash_value(const T& obj) {
return obj.hash_value();
}
#endif
#endif // SEQUANT_USE_SYSTEM_BOOST_HASH

namespace detail {

template <typename T, typename = std::void_t<>>
struct has_boost_hash_value : std::false_type {};

#ifdef SEQUANT_USE_SYSTEM_BOOST_HASH
template <typename T>
struct has_boost_hash_value<
T, std::void_t<decltype(sequant_boost::hash_value(std::declval<T>()))>>
struct has_boost_hash_value<T, std::void_t<decltype(sequant_boost::hash_value(
std::declval<const T&>()))>>
: std::true_type {};
#endif // SEQUANT_USE_SYSTEM_BOOST_HASH

template <typename T>
constexpr bool has_boost_hash_value_v = has_boost_hash_value<const T&>::value;

template <typename T, typename = std::void_t<>>
struct has_hash_value : std::false_type {};
Expand All @@ -86,12 +64,30 @@ struct has_hash_value<
T, std::void_t<decltype(hash_value(std::declval<const T&>()))>>
: std::true_type {};

} // namespace detail

template <typename T>
constexpr bool has_hash_value_v = has_hash_value<T>::value;
constexpr bool has_boost_hash_value_v =
detail::has_boost_hash_value<const T&>::value;

} // namespace detail
template <typename T>
constexpr bool has_hash_value_v = detail::has_hash_value<T>::value;

using sequant_boost::hash_value;
// hash_value specialization for types that have a hash_value member function
template <typename T,
std::enable_if_t<has_hash_value_member_fn_v<T>, short> = 0>
auto hash_value(const T& obj) {
return obj.hash_value();
}

// hash_value specialization that don't have a hash_value member function but
// have an applicable boost::hash_value function
template <typename T, std::enable_if_t<!has_hash_value_member_fn_v<T> &&
has_boost_hash_value_v<T>,
int> = 0>
auto hash_value(const T& obj) {
return sequant_boost::hash_value(obj);
}

// clang-format off
// rationale:
Expand All @@ -114,45 +110,7 @@ template <class T>
inline void combine(std::size_t& seed, T const& v) {
_<T> hasher;

#ifdef SEQUANT_USE_SYSTEM_BOOST_HASH
#if SEQUANT_BOOST_VERSION >= 108100
boost::hash_combine(seed, hasher(v));
#else // older boost workarounds
// in boost 1.78 hash_combine_impl implementation changed
// https://github.com/boostorg/container_hash/commit/21f2b5e1db1a118c83a3690055c110d0f5637da3
// probably no longer need these acrobatics
if constexpr (sizeof(std::size_t) == sizeof(boost::uint32_t) &&
sizeof(decltype(hasher(v))) == sizeof(boost::uint32_t)) {
const boost::uint32_t value = hasher(v);
#if SEQUANT_BOOST_VERSION >= 107800
seed = boost::hash_detail::hash_combine_impl<32>::fn(
static_cast<boost::uint32_t>(seed), value);
#else
// N.B. seed passed by reference
boost::hash_detail::hash_combine_impl(
reinterpret_cast<boost::uint32_t&>(seed), value);
#endif
return;
} else if constexpr (sizeof(std::size_t) == sizeof(boost::uint64_t) &&
sizeof(decltype(hasher(v))) == sizeof(boost::uint64_t)) {
const boost::uint64_t value = hasher(v);

#if SEQUANT_BOOST_VERSION >= 107800
seed = boost::hash_detail::hash_combine_impl<64>::fn(
static_cast<boost::uint64_t>(seed), value);
#else
// N.B. seed passed by reference
boost::hash_detail::hash_combine_impl(
reinterpret_cast<boost::uint64_t&>(seed), value);
#endif
return;
} else {
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
#endif // older boost workarounds
#else // !defined(SEQUANT_USE_SYSTEM_BOOST_HASH)
sequant_boost::hash_combine(seed, hasher(v));
#endif

// assert(seed == seed_ref);
}
Expand Down Expand Up @@ -186,13 +144,7 @@ inline void range(std::size_t& seed, It first, It last) {
template <typename It>
std::size_t hash_range(It begin, It end) {
if (begin != end) {
std::size_t seed;
if constexpr (has_hash_value_member_fn_v<std::decay_t<decltype(*begin)>>)
seed = begin->hash_value();
else {
using sequant_boost::hash_value;
[[maybe_unused]] std::size_t seed = hash_value(*begin);
}
std::size_t seed = hash_value(*begin);
sequant_boost::hash_range(seed, begin + 1, end);
return seed;
} else
Expand All @@ -206,22 +158,13 @@ void hash_range(size_t& seed, It begin, It end) {
}

template <typename T>
struct _<
T, std::enable_if_t<!(detail::has_hash_value_v<T>)&&meta::is_range_v<T>>> {
struct _<T, std::enable_if_t<!(has_hash_value_v<T>)&&meta::is_range_v<T>>> {
std::size_t operator()(T const& v) const { return range(begin(v), end(v)); }
};

template <typename T>
struct _<T, std::enable_if_t<!(
!(detail::has_hash_value_v<T>)&&meta::is_range_v<T>)>> {
std::size_t operator()(T const& v) const {
if constexpr (has_hash_value_member_fn_v<T>)
return v.hash_value();
else {
using sequant_boost::hash_value;
return hash_value(v);
}
}
struct _<T, std::enable_if_t<!(!(has_hash_value_v<T>)&&meta::is_range_v<T>)>> {
std::size_t operator()(T const& v) const { return hash_value(v); }
};

template <typename T>
Expand Down
2 changes: 2 additions & 0 deletions SeQuant/core/space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "space.hpp"

int32_t sequant::TypeAttr::used_bits = 0xffff;

sequant::container::map<sequant::IndexSpace::Attr, std::wstring>
sequant::IndexSpace::attr2basekey_{};
sequant::container::map<std::wstring, sequant::IndexSpace::Attr,
Expand Down
Loading

0 comments on commit 3f0d94a

Please sign in to comment.