Skip to content

Commit

Permalink
Merge pull request #176 from ValeevGroup/evaleev/feature/modularized-…
Browse files Browse the repository at this point in the history
…boost

modularized Boost v2
  • Loading branch information
evaleev authored Jan 26, 2024
2 parents a80a16c + 3e2082d commit 42558e9
Show file tree
Hide file tree
Showing 15 changed files with 277 additions and 104 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
2 changes: 1 addition & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ prerequisites:
* [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 954d861f553e938c3cfc4892fce9234bf4bf7193
* for building `stcc*` example programs
* [Eigen](http://eigen.tuxfamily.org/), version 3

Expand Down
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
3 changes: 2 additions & 1 deletion SeQuant/core/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
#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
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
62 changes: 33 additions & 29 deletions SeQuant/core/space.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,50 @@ namespace sequant {
/// This class models a host (complete) space partitioned into disjoint
/// subspaces. To simplify implementation of set operations
/// (intersection, union, etc.) it is encoded as a fixed-width (32) bitset.
/// By default, all bits are used, but user can disable some bits from being
/// used for comparison
struct TypeAttr {
/// @brief used_bits is a bitset of bits that are used for comparison
static int32_t used_bits;
int32_t bitset = 0;

constexpr explicit TypeAttr(int32_t value) noexcept : bitset(value) {}

constexpr explicit operator int64_t() const {
[[nodiscard]] constexpr explicit operator int64_t() const {
return static_cast<int64_t>(bitset);
}
constexpr int32_t to_int32() const { return bitset; }
constexpr TypeAttr intersection(TypeAttr other) const {
[[nodiscard]] constexpr int32_t to_int32() const { return bitset; }
[[nodiscard]] int32_t to_int32_used() const { return used_bits & bitset; }
[[nodiscard]] constexpr TypeAttr intersection(TypeAttr other) const {
return TypeAttr(this->to_int32() & other.to_int32());
}
constexpr TypeAttr unIon(TypeAttr other) const {
[[nodiscard]] constexpr TypeAttr unIon(TypeAttr other) const {
return TypeAttr(this->to_int32() | other.to_int32());
}

friend constexpr bool operator==(TypeAttr, TypeAttr);
friend constexpr bool operator!=(TypeAttr, TypeAttr);
[[nodiscard]] friend bool operator==(TypeAttr lhs, TypeAttr rhs) {
return lhs.to_int32_used() == rhs.to_int32_used();
}

[[nodiscard]] friend bool operator!=(TypeAttr lhs, TypeAttr rhs) {
return !(lhs == rhs);
}

/// @return true if \c other is included in this object
constexpr bool includes(TypeAttr other) const {
[[nodiscard]] bool includes(TypeAttr other) const {
return intersection(other) == other;
}
/// @return true if in canonical order this object preceeds \c other
constexpr bool operator<(TypeAttr other) const {
return this->to_int32() < other.to_int32();
[[nodiscard]] bool operator<(TypeAttr other) const {
return this->to_int32_used() < other.to_int32_used();
}

/// @return an invalid TypeAttr
static constexpr TypeAttr invalid() noexcept { return TypeAttr(0xffff); }
[[nodiscard]] static constexpr TypeAttr invalid() noexcept {
return TypeAttr(0xffff);
}
};

constexpr bool operator==(TypeAttr lhs, TypeAttr rhs) {
return lhs.to_int32() == rhs.to_int32();
}

constexpr bool operator!=(TypeAttr lhs, TypeAttr rhs) { return !(lhs == rhs); }

/// denotes other quantum numbers (particle type, spin, etc.)
struct QuantumNumbersAttr {
int32_t bitset = 0;
Expand All @@ -75,8 +81,14 @@ struct QuantumNumbersAttr {
return QuantumNumbersAttr(this->to_int32() | other.to_int32());
}

friend constexpr bool operator==(QuantumNumbersAttr, QuantumNumbersAttr);
friend constexpr bool operator!=(QuantumNumbersAttr, QuantumNumbersAttr);
friend constexpr bool operator==(QuantumNumbersAttr lhs,
QuantumNumbersAttr rhs) {
return lhs.to_int32() == rhs.to_int32();
}
friend constexpr bool operator!=(QuantumNumbersAttr lhs,
QuantumNumbersAttr rhs) {
return !(lhs == rhs);
}

/// @return true if \c other is included in this object
constexpr bool includes(QuantumNumbersAttr other) const {
Expand All @@ -93,14 +105,6 @@ struct QuantumNumbersAttr {
}
};

constexpr bool operator==(QuantumNumbersAttr lhs, QuantumNumbersAttr rhs) {
return lhs.to_int32() == rhs.to_int32();
}

constexpr bool operator!=(QuantumNumbersAttr lhs, QuantumNumbersAttr rhs) {
return !(lhs == rhs);
}

/// @brief space of Index objects
///
/// IndexSpace is a set of attributes associated 1-to-1 with keys
Expand Down Expand Up @@ -154,10 +158,10 @@ class IndexSpace {
this->qns().includes(other.qns());
}

bool operator==(Attr other) const {
return this->type() == other.type() && this->qns() == other.qns();
friend bool operator==(Attr a, Attr b) {
return a.type() == b.type() && a.qns() == b.qns();
}
bool operator!=(Attr other) const { return !(*this == other); }
friend bool operator!=(Attr a, Attr b) { return !(a == b); }

static Attr null() noexcept { return Attr{nulltype, nullqns}; }
static Attr invalid() noexcept {
Expand Down
94 changes: 94 additions & 0 deletions bin/admin/clang-format.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/bin/bash

# these are the versions of clang-format that are supported required
# should be ordered from oldest to newest to make sure the newest is picked
supported_clang_format_versions="16 17"
preferred_clang_format_version="" # prefer most recent supported clang-format version
for v in $supported_clang_format_versions; do
preferred_clang_format_version=$v
done

# append common locations of clang-format to PATH
unameOut="$(uname -s)"
case "${unameOut}" in
Darwin*)
extra_path=""
# this prefers more recent versions
for v in $supported_clang_format_versions; do
extra_path=/opt/homebrew/opt/llvm@$v/bin:/opt/homebrew/opt/clang-format@$v/bin:$extra_path
done
# prepend paths
export PATH=$extra_path:$PATH:/opt/homebrew/bin
;;
esac

path_to_clang_format=`which clang-format`
have_supported_clang_format_version=0
if [[ "X$path_to_clang_format" != "X" ]]; then

# check clang-format version
clang_format_version=`clang-format --version | sed 's/.* version //' | awk -F'[.]' '{print $1}'`

#echo "supported_clang_format_versions=\"$supported_clang_format_versions\" clang_format_version=$clang_format_version"

# if found clang-format, but wrong version, check if docker is available
for v in $supported_clang_format_versions; do
if [[ $clang_format_version -eq $v ]]; then
have_supported_clang_format_version=1
break
fi
done
fi

if [[ $have_supported_clang_format_version -eq 0 ]]; then
echo "WARNING: found clang-format with unsupported version $clang_format_version (supported versions: $supported_clang_format_versions)"

# look for docker
path_to_docker=`which docker`
if [[ "X$path_to_docker" = "X" ]]; then
echo "ERROR: docker is not found either, PATH=$PATH, install one of supported clang-format versions (any of these: $supported_clang_format_versions) or install docker"
exit 1
fi

# if docker up?
docker info >/dev/null 2>&1
if [[ $? -ne 0 ]]; then
echo "ERROR: docker is found but not running, start it"
exit 1
fi

# use docker to run clang-format
mount_path=$(readlink -f "$HOME")

# convert file names in the arguments to relative paths
args=""
for i in "$@"; do
# skip options
if [[ "$i" == -* ]]; then
args="$args $i"
continue
fi
abs_file_path=$(readlink -f "$i")
if [[ "X$abs_file_path" = "X" ]]; then
echo "ERROR: given file $i is not found"
exit 1
fi

dir=$(dirname $abs_file_path)
file_path_relative_to_project_root=$(basename $abs_file_path)
while [[ "$dir" != "$mount_path" && "$dir" != "/" ]]; do
file_path_relative_to_project_root="$(basename $dir)/$file_path_relative_to_project_root"
dir=$(dirname $dir)
#echo "dir=$dir file_path_relative_to_project_root=$file_path_relative_to_project_root"
done
if [[ "$dir" == "/" ]]; then
echo "ERROR: given file $i (absolute path $abs_file_path) is not under \$HOME=$mount_path, cannot use docker-based clang-format in this case"
exit 1
fi
args="$args /hostHOME/$file_path_relative_to_project_root"
done
docker run --platform linux/x86_64 -v $mount_path:/hostHOME xianpengshen/clang-tools:$preferred_clang_format_version clang-format $args
else
#echo "found $path_to_clang_format with required version $clang_format_version"
clang-format $*
fi
10 changes: 1 addition & 9 deletions bin/admin/dependency-versions-update-hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,7 @@ def replace_dep_id(topsrc, file_ext, dep_name, old_id, new_id, search_prefix = '
tokens = line.split()
if len(tokens) < 3:
continue
if tokens[1].find('TRACKED_BOOST') != -1:
if tokens[1].find('PREVIOUS') != -1:
boost_old_version = tokens[2]
else:
boost_new_version = tokens[2]
elif tokens[1].find('TRACKED_TILEDARRAY') != -1:
if tokens[1].find('TRACKED_TILEDARRAY') != -1:
if tokens[1].find('PREVIOUS') != -1:
ta_old_tag = tokens[2]
else:
Expand All @@ -77,9 +72,6 @@ def replace_dep_id(topsrc, file_ext, dep_name, old_id, new_id, search_prefix = '

any_files_changed = False

# Boost version in INSTALL.md
any_files_changed |= replace_dep_id(topsrc, 'md', 'Boost', boost_old_version, boost_new_version, ', version ', ' or higher (N.B.')

# replace TA tag in INSTALL.md
any_files_changed |= replace_dep_id(topsrc, 'md', 'TiledArray', ta_old_tag, ta_new_tag, '', '')

Expand Down
Loading

0 comments on commit 42558e9

Please sign in to comment.