Skip to content

Commit

Permalink
Fix compilation errors by updating tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Thoemi09 committed May 25, 2024
1 parent 7dd1934 commit 5007166
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 97 deletions.
2 changes: 1 addition & 1 deletion c++/nda/basic_functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ namespace nda {
bool operator==(LHS const &lhs, RHS const &rhs) {
// FIXME not implemented in clang
#ifndef __clang__
static_assert(std::equality_comparable_with<get_value_t<A>, get_value_t<B>>,
static_assert(std::equality_comparable_with<get_value_t<LHS>, get_value_t<RHS>>,
"Error in nda::operator==: Only defined when elements are comparable");
#endif
if (lhs.shape() != rhs.shape()) return false;
Expand Down
166 changes: 97 additions & 69 deletions c++/nda/gtest_tools.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2019-2024 Simons Foundation
// Copyright (c) 2019-2021 Simons Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -14,126 +14,154 @@
//
// Authors: Olivier Parcollet, Nils Wentzell

/**
* @file
* @brief Provides convenient tools for testing nda::basic_array and nda::basic_array_view
* objects with googletest.
*/

#pragma once

#ifndef NDA_DEBUG
#define NDA_DEBUG
#endif

#include "nda/basic_array.hpp"
#include <iostream>
#include <sstream>
#include <gtest/gtest.h> // NOLINT
#include "./nda.hpp"

/*#if H5_VERSION_GE(1, 8, 9)*/
//#include <h5/serialization.hpp>
//#endif
#include <gtest/gtest.h>

//using dcomplex = std::complex<double>;
#include <cstdlib>
#include <iostream>
#include <sstream>

// Complex are close
/**
* @brief Check the absolute difference of two (complex) numbers.
*
* @tparam X Type of the first number.
* @tparam Y Type of the second number.
* @param x First number.
* @param y Second number.
* @param precision Required precision for the comparison to be considered successful.
* @return ::testing::AssertionSuccess() if the absolute difference is less than the given
* precision, ::testing::AssertionFailure() otherwise.
*/
template <typename X, typename Y>
::testing::AssertionResult complex_are_close(X const &x, Y const &y, double precision = 1.e-10) {
using std::abs;
if (abs(x - y) < precision)
return ::testing::AssertionSuccess();
else
return ::testing::AssertionFailure() << "abs(x-y) = " << abs(x - y) << "\n X = " << x << "\n Y = " << y;
return ::testing::AssertionFailure() << "abs(x - y) = " << abs(x - y) << "\n x = " << x << "\n y = " << y;
}

// Macro that uses complex_are_close.
#define EXPECT_COMPLEX_NEAR(X, ...) EXPECT_TRUE(complex_are_close(X, __VA_ARGS__))

// Arrays are equal
/**
* @brief Check that two arrays/views are equal, i.e. that they have the same shape and the
* same elements.
*
* @tparam X Type of the first array/view.
* @tparam Y Type of the second array/view.
* @param x First array/view.
* @param y Second array/view.
* @return ::testing::AssertionSuccess() if the arrays/view have the same shape and the same
* elements, ::testing::AssertionFailure() otherwise.
*/
template <typename X, typename Y>
::testing::AssertionResult array_are_equal(X const &x, Y const &y) {
if (x.shape() != y.shape()) return ::testing::AssertionFailure() << "Comparing two arrays of different size " << "\n X = " << x << "\n Y = " << y;
if (x.shape() != y.shape())
return ::testing::AssertionFailure() << "Comparing two arrays of different size "
<< "\n X = " << x << "\n Y = " << y;
if (x == y)
return ::testing::AssertionSuccess();
else
return ::testing::AssertionFailure() << "Arrays have different elements\n X = " << x << "\n Y = " << y;
}

// Macros that use array_are_equal.
#define EXPECT_EQ_ARRAY(X, Y) EXPECT_TRUE(array_are_equal(X, Y));
#define EXPECT_ARRAY_EQ(X, Y) EXPECT_TRUE(array_are_equal(X, Y));

// Arrays are close
/**
* @brief Check that two arrays/views are close, i.e. that they have the same shape and that
* the largest element of their absolute difference is less than a given precision.
*
* @tparam X Type of the first array/view.
* @tparam Y Type of the second array/view.
* @param x First array/view.
* @param y Second array/view.
* @param precision Required precision for the comparison to be considered successful.
* @return ::testing::AssertionSuccess() if the arrays/view have the same shape and largest
* element of their absolute difference is less than a given precision.
* ::testing::AssertionFailure() otherwise.
*/
template <typename X, typename Y>
::testing::AssertionResult array_are_close(X const &x1, Y const &y1, double precision = 1.e-10) {
nda::array<nda::get_value_t<X>, nda::get_rank<X>> x = x1;
nda::array<nda::get_value_t<X>, nda::get_rank<X>> y = y1;
::testing::AssertionResult array_are_close(X const &x, Y const &y, double precision = 1.e-10) {
nda::array<nda::get_value_t<X>, nda::get_rank<X>> x_reg = x;
nda::array<nda::get_value_t<X>, nda::get_rank<X>> y_reg = y;

if (x.shape() != y.shape()) return ::testing::AssertionFailure() << "Comparing two arrays of different size " << "\n X = " << x << "\n Y = " << y;
// check their shapes
if (x_reg.shape() != y_reg.shape())
return ::testing::AssertionFailure() << "Comparing two arrays of different size "
<< "\n X = " << x_reg << "\n Y = " << y_reg;

// both x, y are contiguous, I check with basic tools instead of max_element(abs(x - y))
if (x.size() == 0) return ::testing::AssertionSuccess();
auto xx = make_regular(x);
auto yy = make_regular(y);
auto maxdiff = max_element(abs(make_regular(xx - yy)));
// empty arrays are considered equal
if (x_reg.size() == 0) return ::testing::AssertionSuccess();

// check their difference
const auto maxdiff = max_element(abs(make_regular(x_reg - y_reg)));
if (maxdiff < precision)
return ::testing::AssertionSuccess();
else
return ::testing::AssertionFailure() << "max_element(abs(x-y)) = " << maxdiff << "\n X = " << x << "\n Y = " << y;
return ::testing::AssertionFailure() << "max_element(abs(X - Y)) = " << maxdiff << "\n X = " << x_reg << "\n Y = " << y_reg;
}

// Macro that uses array_are_close.
#define EXPECT_ARRAY_NEAR(X, ...) EXPECT_TRUE(array_are_close(X, __VA_ARGS__))

// Arrays is almost 0
/**
* @brief Check that an array/view is close to zero, i.e. that its largest absolute element
* is less than 1e-10.
*
* @tparam X Type of the array/view.
* @param x Array/View.
* @return ::testing::AssertionSuccess() if the absolute value of every element is less than
* 1e-10. ::testing::AssertionFailure() otherwise.
*/
template <typename X>
::testing::AssertionResult array_almost_zero(X const &x1) {
double precision = 1.e-10;
nda::array<nda::get_value_t<X>, nda::get_rank<X>> x = x1;
::testing::AssertionResult array_almost_zero(X const &x) {
nda::array<nda::get_value_t<X>, nda::get_rank<X>> x_reg = x;

if (x.size() == 0 || max_element(abs(x)) < precision)
constexpr double eps = 1.e-10;
const auto maxdiff = max_element(abs(x_reg));
if (x_reg.size() == 0 || maxdiff < eps)
return ::testing::AssertionSuccess();
else
return ::testing::AssertionFailure() << "max_element(abs(x-y)) = " << max_element(abs(x)) << "\n X = " << x;
return ::testing::AssertionFailure() << "max_element(abs(X)) = " << maxdiff << "\n X = " << x_reg;
}

// Macro that uses array_almost_zero.
#define EXPECT_ARRAY_ZERO(X) EXPECT_TRUE(array_almost_zero(X))
//

/**
* @brief Check that that two generic objects are close, i.e. that their absolute difference is
* less than 1e-12.
*
* @tparam X Type of the first object.
* @tparam Y Type of the second object.
* @param x First object.
* @param y Second object.
* @return ::testing::AssertionSuccess() if the absolute value of their difference is less than
* 1e-12. ::testing::AssertionFailure() otherwise.
*/
template <typename X, typename Y>
::testing::AssertionResult generic_are_near(X const &x, Y const &y) {
double precision = 1.e-12;
using std::abs;
if (abs(x - y) > precision)
return ::testing::AssertionFailure() << "X = " << x << " and Y = " << y << " are different. \n Difference is : " << abs(x - y);
return ::testing::AssertionFailure() << "X = " << x << " and Y = " << y << " are different. \n Difference is: " << abs(x - y);
return ::testing::AssertionSuccess();
}
#define EXPECT_CLOSE(X, Y) EXPECT_TRUE(generic_are_near(X, Y));

// ------------------ HDF5 --------------------
//
// We serialize to H5, deserialize, compare

//template <typename T> T rw_h5(T const &x, std::string filename = "ess", std::string name = "x") {

//namespace h5 = h5;
//T y; // must be default constructible

//{
//h5::file file(filename + ".h5", 'w');
//h5_write(file, name, x);
//}

//{
//h5::file file(filename + ".h5", 'r');
//h5_read(file, name, y);
//}

//#if H5_VERSION_GE(1, 8, 9)

////#define TRIQS_TEST_USE_H5_SERIA
//#ifdef TRIQS_TEST_USE_H5_SERIA

//std::cerr << "Checking H5 serialization/deserialization of \n " << triqs::utility::demangle(typeid(x).name()) << std::endl;
//auto s = h5::serialize(x);
//T x2 = h5::deserialize<T>(s);
//auto s2 = h5::serialize(x);
//std::cerr << "Length of serialization string " << first_dim(s) << std::endl;
//EXPECT_EQ_ARRAY(s, s2); // << "Test h5 save, load, save, compare has failed !";
//#endif

//#endif

//return y;
//}
#define EXPECT_CLOSE(X, Y) EXPECT_TRUE(generic_are_near(X, Y));
2 changes: 1 addition & 1 deletion c++/nda/sym_grp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ namespace nda {
for (long i : range(vec.size())) {
for (auto const &[lin_idx, op] : sym_classes[i]) { std::apply(a, a.indexmap().to_idx(lin_idx)) = op(vec[i]); }
}
};
}

/// Default constructor for a symmetry group.
sym_grp() = default;
Expand Down
1 change: 1 addition & 0 deletions test/c++/clef/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include <nda/clef/clef.hpp>
#include <nda/clef/io.hpp>
#include <complex>
#include <sstream>
#include <string>

Expand Down
6 changes: 3 additions & 3 deletions test/c++/nda_basic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ TEST(Assign, Strided) { //NOLINT

// P =0 to force out of the first test of slice_layout_prop. We want to test the real algorithm
EXPECT_EQ(
nda::slice_static::slice_layout_prop(0, true, std::array<bool, 3>{1, 0, 0}, std::array<int, 3>{0, 1, 2}, nda::layout_prop_e::contiguous, 128, 0),
nda::slice_static::detail::slice_layout_prop(0, true, std::array<bool, 3>{1, 0, 0}, std::array<int, 3>{0, 1, 2}, nda::layout_prop_e::contiguous, 128, 0),
nda::layout_prop_e::strided_1d);
EXPECT_EQ(
nda::slice_static::slice_layout_prop(0, true, std::array<bool, 3>{0, 1, 0}, std::array<int, 3>{0, 1, 2}, nda::layout_prop_e::contiguous, 128, 0),
nda::slice_static::detail::slice_layout_prop(0, true, std::array<bool, 3>{0, 1, 0}, std::array<int, 3>{0, 1, 2}, nda::layout_prop_e::contiguous, 128, 0),
nda::layout_prop_e::strided_1d);
EXPECT_EQ(
nda::slice_static::slice_layout_prop(0, true, std::array<bool, 3>{0, 0, 1}, std::array<int, 3>{0, 1, 2}, nda::layout_prop_e::contiguous, 128, 0),
nda::slice_static::detail::slice_layout_prop(0, true, std::array<bool, 3>{0, 0, 1}, std::array<int, 3>{0, 1, 2}, nda::layout_prop_e::contiguous, 128, 0),
nda::layout_prop_e::contiguous);

static_assert(nda::get_layout_info<decltype(A(1, 3, _))>.prop == nda::layout_prop_e::contiguous);
Expand Down
2 changes: 1 addition & 1 deletion test/c++/nda_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ TEST(reshape, checkView) { //NOLINT
//================================================

TEST(GroupIndices, check) { //NOLINT
nda::details::is_partition_of_indices<4>(std::array{0, 1}, std::array{2, 3});
nda::detail::is_partition_of_indices<4>(std::array{0, 1}, std::array{2, 3});
}

TEST(GroupIndices, v1) { //NOLINT
Expand Down
16 changes: 8 additions & 8 deletions test/c++/nda_idx_map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

auto _ = nda::range::all;
auto ___ = nda::ellipsis{};
using nda::slice_static::slice_stride_order;
using nda::slice_static::slice_idx_map;

using namespace nda;

Expand Down Expand Up @@ -90,7 +90,7 @@ TEST(idxstat, slicemat) { // NOLINT

idx_map<2, 0, C_stride_order<2>, layout_prop_e::none> i1{{10, 10}};

auto [offset2, i2] = slice_stride_order(i1, range(0, 2), 2);
auto [offset2, i2] = slice_idx_map(i1, range(0, 2), 2);

static_assert(decltype(i2)::layout_prop == layout_prop_e::strided_1d, "000");
}
Expand All @@ -101,7 +101,7 @@ TEST(idxstat, slice) { // NOLINT

idx_map<3, 0, C_stride_order<3>, layout_prop_e::none> i1{{1, 2, 3}};

auto [offset2, i2] = slice_stride_order(i1, 0, _, 2);
auto [offset2, i2] = slice_idx_map(i1, 0, _, 2);

idx_map<1, 0, C_stride_order<1>, layout_prop_e::strided_1d> c2{{2}, {3}};

Expand All @@ -110,7 +110,7 @@ TEST(idxstat, slice) { // NOLINT
EXPECT_TRUE(i2 == c2); //NOLINT
EXPECT_EQ(offset2, 2); //NOLINT

auto [offset3, i3] = slice_stride_order(i1, _, _, _);
auto [offset3, i3] = slice_idx_map(i1, _, _, _);
EXPECT_TRUE(i3 == i1); //NOLINT
EXPECT_EQ(offset3, 0); //NOLINT
}
Expand All @@ -119,10 +119,10 @@ TEST(idxstat, slice) { // NOLINT

TEST(idxstat, ellipsis) { // NOLINT

EXPECT_EQ(16, encode(nda::slice_static::sliced_mem_stride_order(std::array<int, 3>{0, 1, 2}, std::array<int, 2>{1, 2})));
EXPECT_EQ(16, encode(nda::slice_static::detail::slice_stride_order(std::array<int, 3>{0, 1, 2}, std::array<int, 2>{1, 2})));

idx_map<3, 0, C_stride_order<3>, layout_prop_e::none> i1{{1, 2, 3}};
auto [offset2, i2] = slice_stride_order(i1, 0, ___);
auto [offset2, i2] = slice_idx_map(i1, 0, ___);

idx_map<2, 0, C_stride_order<2>, layout_prop_e::none> c2{{2, 3}, {3, 1}};

Expand All @@ -131,7 +131,7 @@ TEST(idxstat, ellipsis) { // NOLINT
EXPECT_TRUE(i2 == c2); //NOLINT
EXPECT_EQ(offset2, 0); //NOLINT

auto [offset3, i3] = slice_stride_order(i1, ___);
auto [offset3, i3] = slice_idx_map(i1, ___);
EXPECT_TRUE(i3 == i1); //NOLINT
EXPECT_EQ(offset3, 0); //NOLINT
}
Expand All @@ -143,7 +143,7 @@ TEST(idxstat, ellipsis2) { // NOLINT
idx_map<5, 0, C_stride_order<5>, layout_prop_e::none> i1{{1, 2, 3, 4, 5}};
std::cerr << i1 << std::endl;

auto [offset2, i2] = slice_stride_order(i1, 0, ___, 3, 2);
auto [offset2, i2] = slice_idx_map(i1, 0, ___, 3, 2);
idx_map<2, 0, C_stride_order<2>, layout_prop_e::none> c2{{2, 3}, {60, 20}};

std::cerr << i2 << std::endl;
Expand Down
24 changes: 12 additions & 12 deletions test/c++/nda_layout_for_each.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,26 @@
TEST(NDA, ForEachIndexFromStrideOrder) {
constexpr auto order_arr = std::array{1, 2, 0};
constexpr auto order_code = nda::encode(order_arr);
static_assert(nda::details::index_from_stride_order<3>(order_code, 0) == 1);
static_assert(nda::details::index_from_stride_order<3>(order_code, 1) == 2);
static_assert(nda::details::index_from_stride_order<3>(order_code, 2) == 0);
EXPECT_EQ(nda::details::index_from_stride_order<3>(order_code, 0), 1);
EXPECT_EQ(nda::details::index_from_stride_order<3>(order_code, 1), 2);
EXPECT_EQ(nda::details::index_from_stride_order<3>(order_code, 2), 0);
static_assert(nda::detail::index_from_stride_order<3>(order_code, 0) == 1);
static_assert(nda::detail::index_from_stride_order<3>(order_code, 1) == 2);
static_assert(nda::detail::index_from_stride_order<3>(order_code, 2) == 0);
EXPECT_EQ(nda::detail::index_from_stride_order<3>(order_code, 0), 1);
EXPECT_EQ(nda::detail::index_from_stride_order<3>(order_code, 1), 2);
EXPECT_EQ(nda::detail::index_from_stride_order<3>(order_code, 2), 0);
}

TEST(NDA, ForEachGetExtent) {
constexpr auto shape_arr = std::array{2, 3, 4};
constexpr auto shape_code = nda::encode(shape_arr);
constexpr auto zeros = nda::stdutil::make_initialized_array<std::size(shape_arr)>(0l);
static_assert(nda::details::get_extent<0, 3, shape_code>(zeros) == 2);
static_assert(nda::details::get_extent<1, 3, shape_code>(zeros) == 3);
static_assert(nda::details::get_extent<2, 3, shape_code>(zeros) == 4);
static_assert(nda::detail::get_extent<0, 3, shape_code>(zeros) == 2);
static_assert(nda::detail::get_extent<1, 3, shape_code>(zeros) == 3);
static_assert(nda::detail::get_extent<2, 3, shape_code>(zeros) == 4);

auto shape_dyn = shape_arr;
auto e1 = nda::details::get_extent<0, 3, 0>(shape_dyn);
auto e2 = nda::details::get_extent<1, 3, 0>(shape_dyn);
auto e3 = nda::details::get_extent<2, 3, 0>(shape_dyn);
auto e1 = nda::detail::get_extent<0, 3, 0>(shape_dyn);
auto e2 = nda::detail::get_extent<1, 3, 0>(shape_dyn);
auto e3 = nda::detail::get_extent<2, 3, 0>(shape_dyn);
EXPECT_EQ(e1, 2);
EXPECT_EQ(e2, 3);
EXPECT_EQ(e3, 4);
Expand Down
Loading

0 comments on commit 5007166

Please sign in to comment.