Page MenuHomec4science

test_grid.cpp
No OneTemporary

File Metadata

Created
Sun, Apr 28, 12:58

test_grid.cpp

/**
* @file
* @section LICENSE
*
* Copyright (©) 2016-19 EPFL (École Polytechnique Fédérale de Lausanne),
* Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test.hh"
#include "grid.hh"
#include "grid_view.hh"
using namespace tamaas;
/* -------------------------------------------------------------------------- */
// Testing 1D creation
TEST(TestGridCreation, Creation1d) {
Grid<Real, 1> grid{{5}, 2};
std::array<UInt, 1> correct_size{{5}};
ASSERT_TRUE(grid.sizes() == correct_size) << "Wrong sizes";
std::array<UInt, 2> correct_strides{{2, 1}};
ASSERT_TRUE(grid.getStrides() == correct_strides) << "Wrong strides";
}
// Testing 2D creation
TEST(TestGridCreation, Creation2d) {
Grid<Real, 2> grid({5, 2}, 3);
std::array<UInt, 2> correct_size{{5, 2}};
ASSERT_TRUE(grid.sizes() == correct_size) << "Wrong sizes";
std::array<UInt, 3> correct_strides{{6, 3, 1}};
ASSERT_TRUE(grid.getStrides() == correct_strides) << "Wrong strides";
}
// Testing 3D creation
TEST(TestGridCreation, Creation3d) {
Grid<Real, 3> grid({8, 5, 2}, 3);
std::array<UInt, 3> correct_size{{8, 5, 2}};
ASSERT_TRUE(grid.sizes() == correct_size) << "Wrong sizes";
std::array<UInt, 4> correct_strides{{30, 15, 3, 1}};
ASSERT_TRUE(grid.getStrides() == correct_strides) << "Wrong strides";
}
/* -------------------------------------------------------------------------- */
// Testing iterators in STL function iota
TEST(TestGridIterators, Iota) {
constexpr UInt N = 20;
Grid<UInt, 1> grid({N}, 1);
std::iota(grid.begin(), grid.end(), 0);
const UInt * p = grid.getInternalData();
for (UInt i = 0 ; i < N ; ++i)
ASSERT_TRUE(p[i] == i) << "Iota fill failed";
}
// Testing filling grid with OpenMP loop
TEST(TestGridIterators, OpenMPLoops) {
Grid<UInt, 1> grid({20}, 1);
#ifndef USE_CUDA
#pragma omp parallel for
#endif
for (auto it = grid.begin() ; it < grid.end() ; ++it) {
UInt i = it - grid.begin();
*it = i;
}
std::vector<UInt> correct(20);
std::iota(correct.begin(), correct.end(), 0);
ASSERT_TRUE(compare(grid, correct)) << "Fill using OpenMP loop failed";
}
/* -------------------------------------------------------------------------- */
// Testing scalar simple loop-based operators
TEST(TestGridOperators, LoopOperators) {
Grid<UInt, 1> grid({20}, 1);
grid = 1;
EXPECT_TRUE(std::all_of(grid.begin(), grid.end(), [](UInt x) {
return x == 1;
})) << "Assignement operator failed";
grid += 1;
EXPECT_TRUE(std::all_of(grid.begin(), grid.end(), [](UInt x) {
return x == 2;
})) << "Plus-equal operator failed";
}
// Testing loop-based functions with reductions
TEST(TestGridOperators, Stats) {
constexpr UInt N = 20;
Grid<Real, 1> grid({N}, 1);
std::iota(grid.begin(), grid.end(), 0);
auto b = grid.begin(), e = grid.end();
Real min = *std::min_element(b, e);
Real max = *std::max_element(b, e);
Real acc = std::accumulate(b, e, 0);
Real mea = acc / N;
Real var = 35;
EXPECT_DOUBLE_EQ(grid.min(), min) << "Minimum function failed";
EXPECT_DOUBLE_EQ(grid.max(), max) << "Maximum function failed";
EXPECT_DOUBLE_EQ(grid.sum(), acc) <<"Sum function failed";
EXPECT_DOUBLE_EQ(grid.mean(), mea) << "Mean function failed";
EXPECT_DOUBLE_EQ(grid.var(), var) << "Var function failed";
}
/* -------------------------------------------------------------------------- */
TEST(TestGridView, View2D) {
Grid<UInt, 3> grid3d({10, 10, 10}, 3);
std::iota(grid3d.begin(), grid3d.end(), 0);
for (UInt i : Loop::range(10)) {
auto grid_view = make_view(grid3d, i);
std::vector<UInt> reference(300);
std::iota(reference.begin(), reference.end(), 300 * i);
EXPECT_TRUE(
std::equal(grid_view.begin(), grid_view.end(), reference.begin()))
<< "View on slice fail";
}
}
TEST(TestGridView, ViewOnComponent) {
Grid<UInt, 3> grid3d({10, 10, 10}, 3), solution({10, 10, 10}, 3);
grid3d = solution = 0;
auto view = make_component_view(grid3d, 2u);
std::iota(view.begin(), view.end(), 0);
for (UInt i = 0; i < solution.getNbPoints(); ++i)
solution(3 * i + 2) = i;
EXPECT_TRUE(std::equal(grid3d.begin(), grid3d.end(), solution.begin()))
<< "View on components fail";
}
TEST(TestGridView, ViewCopy) {
Grid<UInt, 3> grid3d({10, 10, 10}, 2);
Grid<UInt, 1> copy, solution({10}, 1);
auto view_on_slice = make_view(grid3d, 3, 4);
Grid<UInt, 1> * view_on_slice_ptr = &view_on_slice;
auto view = make_component_view(*view_on_slice_ptr, 1u);
std::iota(view.begin(), view.end(), 0);
std::iota(solution.begin(), solution.end(), 0);
copy = view;
EXPECT_TRUE(std::equal(copy.begin(), copy.end(), solution.begin()))
<< "Copy of view fail";
}
TEST(TestGridView, HigherOrderView) {
Grid<UInt, 2> grid({10, 10}, 2);
std::iota(grid.begin(), grid.end(), 0);
GridView<Grid, UInt, 2, 3> view(grid, {}, -1);
EXPECT_TRUE(std::equal(grid.begin(), grid.end(), view.begin()))
<< "Higher order view fail";
}
/* -------------------------------------------------------------------------- */
struct BroadcastSet123 {
CUDA_LAMBDA inline void operator()(VectorProxy<UInt, 3> v) {
v(0) = 1;
v(1) = 2;
v(2) = 3;
}
};
TEST(TestGridOperators, BroadcastOperators) {
Grid<UInt, 2> grid({10, 10}, 3), solution({10, 10}, 3);
auto set = BroadcastSet123();
// Filling up solution
Loop::loop(set, range<VectorProxy<UInt, 3>>(solution));
Vector<UInt, 3> v;
v(0) = 1;
v(1) = 2;
v(2) = 3;
grid = v;
EXPECT_TRUE(std::equal(grid.begin(), grid.end(), solution.begin()))
<< "Broadcast assignement failure";
v(1) = 1;
v(2) = 1;
solution += 1;
grid += v;
EXPECT_TRUE(std::equal(grid.begin(), grid.end(), solution.begin()))
<< "Broadcast += failure";
solution -= 1;
grid -= v;
EXPECT_TRUE(std::equal(grid.begin(), grid.end(), solution.begin()))
<< "Broadcast -= failure";
v(1) = 2;
v(2) = 3;
solution *= solution;
grid *= v;
EXPECT_TRUE(std::equal(grid.begin(), grid.end(), solution.begin()))
<< "Broadcast *= failure";
Loop::loop(set, range<VectorProxy<UInt, 3>>(solution));
grid /= v;
EXPECT_TRUE(std::equal(grid.begin(), grid.end(), solution.begin()))
<< "Broadcast /= failure";
}

Event Timeline