Skip to content

Commit

Permalink
Merge branch 'master' into kmp5/feature/cpB
Browse files Browse the repository at this point in the history
  • Loading branch information
kmp5VT committed Sep 28, 2024
2 parents 22b2fcf + c25b0a1 commit 6433b71
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 82 deletions.
40 changes: 16 additions & 24 deletions .github/workflows/cmake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ jobs:
fail-fast: false
matrix:
build_type : [ Release, Debug ]
os : [ macos-latest, ubuntu-20.04 ]
os : [ macos-latest, ubuntu-22.04 ]
linalg : [netlib, vendor]
include:
- os: ubuntu-20.04
cxx: /usr/bin/g++-9
- os: ubuntu-22.04
cc: /usr/bin/gcc-12
cxx: /usr/bin/g++-12
- os: macos-latest
cc: clang
cxx: clang++

name: "${{ matrix.os }}: ${{ matrix.cxx }} ${{ matrix.build_type }} linalg=${{ matrix.linalg }}"
runs-on: ${{ matrix.os }}
env:
CXX : ${{ matrix.cxx }}
DOXYGEN_VERSION : 1.9.2
DOXYGEN_VERSION : 1.12.0
CCACHE_DIR : ${{github.workspace}}/build/.ccache
CCACHE_COMPRESS : true
CCACHE_COMPRESSLEVEL : 6
Expand All @@ -45,7 +47,7 @@ jobs:
- name: Install prerequisite MacOS packages
if: ${{ matrix.os == 'macos-latest' }}
run: |
brew install ninja gcc@10 boost eigen open-mpi bison ccache
brew install ninja boost eigen open-mpi bison ccache
# install Netlib if want generic linalg
if [ "${{matrix.linalg}}" = "netlib" ]; then
brew install lapack
Expand All @@ -55,17 +57,17 @@ jobs:
fi
- name: Install prerequisites Ubuntu packages
if: ${{ matrix.os == 'ubuntu-20.04' }}
if: ${{ matrix.os == 'ubuntu-22.04' }}
run: |
sudo apt-get update
sudo apt-get install ninja-build g++-9 liblapack-dev libboost-dev libboost-serialization-dev libboost-random-dev libeigen3-dev openmpi-bin libopenmpi-dev libtbb-dev ccache
sudo apt-get install ninja-build g++-12 liblapack-dev libboost-dev libboost-serialization-dev libboost-random-dev libeigen3-dev openmpi-bin libopenmpi-dev libtbb-dev ccache
if [ "${{matrix.build_type}}" = "Release" ]; then
sudo apt-get install libclang1-9 libclang-cpp9 graphviz fonts-liberation
sudo apt-get install graphviz fonts-liberation
cd ${{github.workspace}}/build
# If we fail getting doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz from sourceforge,
# use EFV's gdrive mirror of 1.9.2 to work around the unreliable sourceforge
# the sharing link: https://drive.google.com/file/d/16GXpH4YOEUxGXQrXOKdAIibhdfzATY0d/view?usp=sharing
wget https://downloads.sourceforge.net/project/doxygen/rel-${DOXYGEN_VERSION}/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz || wget -4 --no-check-certificate -O doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz "https://drive.google.com/uc?export=download&id=16GXpH4YOEUxGXQrXOKdAIibhdfzATY0d"
wget https://www.doxygen.nl/files/doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz
tar xzf ./doxygen-${DOXYGEN_VERSION}.linux.bin.tar.gz
export DOXYGEN_DIR=${{github.workspace}}/build/doxygen-${DOXYGEN_VERSION}
${DOXYGEN_DIR}/bin/doxygen --version
Expand All @@ -85,20 +87,10 @@ jobs:
echo "BLAS_PREFERENCE_LIST=ReferenceBLAS" >> $GITHUB_ENV
fi
- name: Prepare ccache timestamp
id: ccache_cache_timestamp
shell: cmake -P {0}
run: |
string(TIMESTAMP current_date "%Y-%m-%d-%H;%M;%S" UTC)
message("::set-output name=timestamp::${current_date}")
- name: Setup ccache cache files
uses: actions/[email protected]
- name: Setup ccache
uses: hendrikmuhs/[email protected]
with:
path: ${{github.workspace}}/build/.ccache
key: ${{ matrix.config.name }}-ccache-${{ steps.ccache_cache_timestamp.outputs.timestamp }}
restore-keys: |
${{ matrix.config.name }}-ccache-
key: ccache-${{ matrix.os }}-${{ matrix.build_type }}-${{ matrix.linalg }}

- name: Configure CMake
# Use a bash shell so we can use the same syntax for environment variable
Expand All @@ -109,7 +101,7 @@ jobs:
# and build directories, but this is only available with CMake 3.13 and higher.
# The CMake binaries on the Github Actions machines are (as of this writing) 3.12
run: |
cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBLAS_PREFERENCE_LIST=$BLAS_PREFERENCE_LIST $BUILD_CONFIG
cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBLAS_PREFERENCE_LIST=$BLAS_PREFERENCE_LIST $BUILD_CONFIG || (cat CMakeFiles/CMakeConfigureLog.yaml)
- name: Build
working-directory: ${{github.workspace}}/build
Expand Down Expand Up @@ -138,7 +130,7 @@ jobs:
cmake --build test_install
- name: Build+Deploy Dox
if: ${{ matrix.os == 'ubuntu-20.04' && matrix.build_type == 'Release' && github.ref == 'refs/heads/master' }}
if: ${{ matrix.os == 'ubuntu-22.04' && matrix.build_type == 'Release' && github.ref == 'refs/heads/master' }}
working-directory: ${{github.workspace}}/build
shell: bash
run: |
Expand Down
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,15 @@ install(DIRECTORY btas
##########################
# external dependencies
##########################
# optional dependency: ccache, but need to be defined first so that mandatory dependencies can inherit it
find_program(CCACHE ccache)
if(CCACHE)
mark_as_advanced(CCACHE)
message (STATUS "Found ccache: ${CCACHE}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE}" CACHE STRING "Compiler launcher to use for compiling C++")
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE}" CACHE STRING "Compiler launcher to use for compiling C")
endif(CCACHE)

if( BTAS_USE_BLAS_LAPACK )
include(external/linalgpp.cmake)
endif()
Expand Down
2 changes: 2 additions & 0 deletions btas/array_adaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ namespace btas {
static array construct(std::size_t n) {
assert(n <= N);
array result;
// fill elements n+1 ... N-1 with zeroes
std::fill_n(result.begin() + n, N - n, value_type{});
return result;
}
static array construct(std::size_t n, T value) {
Expand Down
2 changes: 1 addition & 1 deletion btas/index_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class has_integral_value_type {
/// test _Index conforms the TWG.Index concept
/// check only value_type and operator[]
template<typename ...>
class is_index;
class is_index : public std::false_type {};

template<typename _Index>
class is_index<_Index> {
Expand Down
16 changes: 1 addition & 15 deletions btas/range.h
Original file line number Diff line number Diff line change
Expand Up @@ -956,27 +956,13 @@ namespace btas {

/// calculates the ordinal value of \c i

/// Convert an index to its ordinal.
/// \tparam Index A coordinate index type (array type)
/// \param index The index to be converted to an ordinal index
/// \return The ordinal index of \c index
/// \throw When \c index is not included in this range.
template <typename Index>
typename std::enable_if<btas::is_index<Index>::value, ordinal_type>::type
ordinal(const Index& index) const {
return ordinal_(index);
}

/// calculates the ordinal value of \c i

/// Convert an index to its ordinal.
/// \tparam Index A coordinate index type (array type)
/// \param index The index to be converted to an ordinal index
/// \return The ordinal index of \c index
/// \throw When \c index is not included in this range.
template <typename ... Index>
typename std::enable_if<not btas::is_index<typename std::decay<Index>::type...>::value, ordinal_type>::type
ordinal(Index&& ... index) const {
ordinal_type ordinal(Index&& ... index) const {
return ordinal_(std::forward<Index>(index)...);
}

Expand Down
6 changes: 5 additions & 1 deletion btas/tensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,11 @@ namespace btas {
/// copy constructor
/// It will accept Tensors and TensorViews
template <class _Tensor, class = typename std::enable_if<is_boxtensor<_Tensor>::value>::type>
Tensor(const _Tensor& x) : range_(x.range().lobound(), x.range().upbound()), storage_(x.cbegin(), x.cend()) {}
Tensor(const _Tensor& x) : range_(x.range().lobound(), x.range().upbound()){
auto size = range_.area();
array_adaptor<storage_type>::resize(storage_, size);
std::copy(x.cbegin(), x.cend(), storage_.begin());
}

/// copy constructor
/// @note this makes a shallow copy of @п х if `storage_type` has shallow-copy semantics; if need a deep copy
Expand Down
25 changes: 2 additions & 23 deletions btas/tensor_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,6 @@

namespace btas {

/// test T has data() member
/// this will be used to detect whether or not the storage is consecutive
template<class T>
class has_data {
/// true case
template<class U>
static auto __test(U* p) -> decltype(p->data(), std::true_type());
/// false case
template<class>
static std::false_type __test(...);
public:
static constexpr const bool value = std::is_same<std::true_type, decltype(__test<T>(0))>::value;
};

/// test T has range_type
template<class T>
class has_range_type {
Expand Down Expand Up @@ -83,15 +69,8 @@ class is_boxtensor {

/// checks _Tensor meets the TWG.BoxTensor concept requirements
template<class _Tensor>
class boxtensor_storage_order {
public:
enum {row_major = boxrange_iteration_order<typename _Tensor::range_type>::row_major,
other = boxrange_iteration_order<typename _Tensor::range_type>::other,
column_major = boxrange_iteration_order<typename _Tensor::range_type>::column_major
};
static constexpr const int
value = boxrange_iteration_order<typename _Tensor::range_type>::value;
};
class boxtensor_storage_order : public boxrange_iteration_order<typename _Tensor::range_type> {};


} // namespace btas

Expand Down
40 changes: 26 additions & 14 deletions btas/type_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,35 +125,47 @@ namespace btas {
template <typename T>
constexpr inline bool has_squarebraket_v = has_squarebraket<T>::value;

template <typename S, typename Enabler = void>
constexpr static bool has_data_v = false;
template <typename S>
constexpr static bool has_data_v<S, std::void_t<decltype(std::declval<S&>().data())>> = true;
/// test T has data() member
/// this will be used to detect whether or not the storage is consecutive
template<class T>
class has_data {
/// true case
template<class U>
static auto __test(U* p) -> decltype(p->data(), std::true_type());
/// false case
template<class>
static std::false_type __test(...);
public:
static constexpr const bool value = std::is_same<std::true_type, decltype(__test<T>(0))>::value;
};

template <typename T>
inline constexpr bool has_data_v = has_data<T>::value;

template <typename S, typename Enabler = void>
constexpr static bool has_size_v = false;
inline constexpr bool has_size_v = false;
template <typename S>
constexpr static bool has_size_v<S, std::void_t<decltype(std::declval<const S&>().size())>> = true;
inline constexpr bool has_size_v<S, std::void_t<decltype(std::declval<const S&>().size())>> = true;

template <typename S, typename Enabler = void>
constexpr static bool has_nonmember_begin_v = has_begin_v<S>; // if have member begin, std::begin will apply
inline constexpr bool has_nonmember_begin_v = has_begin_v<S>; // if have member begin, std::begin will apply
template <typename S>
constexpr static bool has_nonmember_begin_v<S, std::void_t<decltype(begin(std::declval<S&>()))>> = true;
inline constexpr bool has_nonmember_begin_v<S, std::void_t<decltype(begin(std::declval<S&>()))>> = true;

template <typename S, typename Enabler = void>
constexpr static bool has_nonmember_end_v = has_end_v<S>; // if have member end, std::end will apply
inline constexpr bool has_nonmember_end_v = has_end_v<S>; // if have member end, std::end will apply
template <typename S>
constexpr static bool has_nonmember_end_v<S, std::void_t<decltype(end(std::declval<S&>()))>> = true;
inline constexpr bool has_nonmember_end_v<S, std::void_t<decltype(end(std::declval<S&>()))>> = true;

template <typename S, typename Enabler = void>
constexpr static bool has_nonmember_data_v = has_data_v<S>; // if have member data, std::data will apply
inline constexpr bool has_nonmember_data_v = has_data_v<S>; // if have member data, std::data will apply
template <typename S>
constexpr static bool has_nonmember_data_v<S, std::void_t<decltype(data(std::declval<S&>()))>> = true;
inline constexpr bool has_nonmember_data_v<S, std::void_t<decltype(data(std::declval<S&>()))>> = true;

template <typename S, typename Enabler = void>
constexpr static bool has_nonmember_size_v = has_end_v<S>; // if have member size, std::size will apply
inline constexpr bool has_nonmember_size_v = has_end_v<S>; // if have member size, std::size will apply
template <typename S>
constexpr static bool has_nonmember_size_v<S, std::void_t<decltype(size(std::declval<const S&>()))>> = true;
inline constexpr bool has_nonmember_size_v<S, std::void_t<decltype(size(std::declval<const S&>()))>> = true;

// Checks if an iterator is random access
template <typename _Iterator>
Expand Down
4 changes: 4 additions & 0 deletions unittest/range_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ TEST_CASE("Range")
typedef RangeNd<blas::Layout::RowMajor, std::array<size_t, 3>> Range3d;
Range3d x;
CHECK(x.rank()== 3);
CHECK(x.area()== 0);
Range3d x1(std::array<int,0>{},std::array<int,0>{});
CHECK(x1.rank()== 3);
CHECK(x1.area()== 0);
}
SECTION("Col-major std::vector-based Range")
{
Expand Down
4 changes: 2 additions & 2 deletions unittest/tensor_cp_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ TEST_CASE("CP")
btas::TUCKER_CP_ALS<tensor, conv_class> A1(d, 1e-3);
conv.set_norm(norm4);
double diff = A1.compute_rank(55, conv, 1, true, 55);
CHECK(std::abs(diff) <= epsilon);
CHECK(std::abs(diff) <= /* NB error too large with netlib blas on linux */ 3 * epsilon);
}
#endif
#if BTAS_ENABLE_RANDOM_CP_UT
Expand Down Expand Up @@ -222,7 +222,7 @@ TEST_CASE("CP")
btas::TUCKER_CP_RALS<tensor, conv_class> A1(d, 1e-3);
conv.set_norm(norm4);
double diff = A1.compute_rank(55, conv, 1, true, 55);
CHECK(std::abs(diff) <= epsilon);
CHECK(std::abs(diff) <= /* NB error too large with netlib blas on linux */ 3 * epsilon);
}
#endif
#if BTAS_ENABLE_RANDOM_CP_UT
Expand Down
4 changes: 2 additions & 2 deletions unittest/ztensor_cp_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -102,13 +102,13 @@ TEST_CASE("ZCP") {
CP_ALS<ztensor, zconv_class> A1(Z4);
conv.set_norm(norm4.real());
double diff = A1.compute_error(conv, 1e-2, 1, 100, true, 57);
CHECK(std::abs(diff) <= epsilon);
CHECK(std::abs(diff) <= /* NB error too large with netlib blas on linux */ 3 * epsilon);
}
SECTION("ALS MODE = 4, Finite rank") {
CP_ALS<ztensor, zconv_class> A1(Z4);
conv.set_norm(norm4.real());
double diff = A1.compute_rank(57, conv, 1, true, 57);
CHECK(std::abs(diff) <= epsilon);
CHECK(std::abs(diff) <= /* NB error too large with netlib blas on linux */ 3 * epsilon);
}
#if BTAS_ENABLE_TUCKER_CP_UT
SECTION("ALS MODE = 4, Tucker + CP") {
Expand Down

0 comments on commit 6433b71

Please sign in to comment.