Page MenuHomec4science

test_loop.cpp
No OneTemporary

File Metadata

Created
Wed, Jun 26, 01:08

test_loop.cpp

/**
*
* @author Lucas Frérot <lucas.frerot@epfl.ch>
*
* @section LICENSE
*
* Copyright (©) 2017 EPFL (Ecole Polytechnique Fédérale de
* Lausanne) Laboratory (LSMS - Laboratoire de Simulation en Mécanique des
* Solides)
*
* Tamaas is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* Tamaas 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 Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Tamaas. If not, see <http://www.gnu.org/licenses/>.
*
*/
/* -------------------------------------------------------------------------- */
#include "test.hh"
#include "grid.hh"
#include "static_types.hh"
#include "loop.hh"
/* -------------------------------------------------------------------------- */
using namespace tamaas;
TestSuite(loops, .init = tamaas_init, .fini = tamaas_teardown);
// Testing loops on one grid
Test(loops, one_arg) {
Grid<Real, 1> grid({20}, 1);
Grid<Real, 1> solution({20}, 1);
auto add_one = [] CUDA_LAMBDA (Real & x) { return x + 1; };
std::iota(grid.begin(), grid.end(), 1);
// Makeing solution
std::transform(grid.begin(), grid.end(), solution.begin(), add_one);
auto add_one_inplace = [] CUDA_LAMBDA (Real & x) { x += 1; };
Loop::loop(add_one_inplace, grid);
cr_assert(compare(grid, solution, AreFloatEqual()), "One argument loop failed");
}
// Testing loops on two grids
Test(loops, two_args) {
// Why no ints?
Grid<Int, 2> grid({20, 20}, 1);
Grid<Int, 2> primal({20, 20}, 1);
Grid<Int, 2> solution({20, 20}, 1);
primal(0, 0) = 1; primal(0, 1) = 1;
primal(1, 0) = 1; primal(1, 1) = 1;
std::transform(primal.begin(), primal.end(), solution.begin(),
[] CUDA_LAMBDA (Int & primal) {
return (primal > 0)? -1:1;
});
Loop::loop([] CUDA_LAMBDA (Int & primal, Int & val) {
val = (primal > 0)? -1:1;
}, primal, grid);
cr_assert(compare(solution, grid), "Two argument loop failed");
}
// Testing an enumeration
Test(loops, enumeration) {
Grid<UInt, 1> grid({100}, 1);
Grid<UInt, 1> solution({100}, 1);
std::iota(solution.begin(), solution.end(), 0);
Loop::loop([] CUDA_LAMBDA (UInt & x, UInt i) {
x = i;
}, grid, Loop::arange<UInt>(100));
cr_assert(compare(solution, grid), "Enumeration loop failed");
}
/* -------------------------------------------------------------------------- */
TestSuite(reductions, .init = tamaas_init, .fini = tamaas_teardown);
// Testing one grid reductions
Test(reductions, one_arg) {
Grid<UInt, 1> grid({6}, 1);
std::iota(grid.begin(), grid.end(), 1);
const auto id = [] CUDA_LAMBDA (UInt & x) {return x;};
// Sum reduction
UInt sol = std::accumulate(grid.begin(), grid.end(), 0, std::plus<UInt>());
UInt red = Loop::reduce<operation::plus>(id, grid);
cr_assert(sol == red, "Addition reduction failed on one argument");
// Product reduction
sol = std::accumulate(grid.begin(), grid.end(), 1, std::multiplies<UInt>());
red = Loop::reduce<operation::times>(id, grid);
cr_assert(sol == red, "Multiplication reduction failed on one argument");
// Min reduction
sol = *std::min_element(grid.begin(), grid.end());
red = Loop::reduce<operation::min>(id, grid);
cr_assert(sol == red, "Min reduction failed on one argument");
// Max reduction
sol = *std::max_element(grid.begin(), grid.end());
red = Loop::reduce<operation::max>(id, grid);
cr_assert(sol == red, "Max reduction failed on one argument");
}
Test(reductions, two_args) {
Grid<UInt, 1> grid({20}, 1);
Grid<UInt, 1> primal({20}, 1);
grid = 1;
primal(0) = 1;
primal(1) = 1;
// Reduce on values where primal > 0
UInt red = Loop::reduce<operation::plus>([] CUDA_LAMBDA (UInt & p, UInt & val) {
return (p > 0)? val:0;
}, primal, grid);
cr_assert(red == 2, "Two args reduction failed");
}
/* -------------------------------------------------------------------------- */
TestSuite(strided_loops, .init = tamaas_init, .fini = tamaas_teardown);
Test(strided_loops, one_arg) {
Grid<UInt, 2> grid({10, 10}, 2);
std::iota(grid.begin(), grid.end(), 1);
Grid<UInt, 2> solution({10, 10}, 2);
solution = grid;
std::for_each(solution.begin(), solution.end(), [] CUDA_LAMBDA (UInt & x) {
if (x % 2 == 1)
x += 1;
});
Loop::stridedLoop([] CUDA_LAMBDA (UInt & x) {
x += 1;
}, grid);
cr_assert(compare(solution, grid), "One argument strided loop failed");
}
template <typename T> using Vector = StaticVector<T, 2>;
Test(strided_loops, static_vector) {
Grid<UInt, 2> grid({10, 10}, 2);
std::iota(grid.begin(), grid.end(), 1);
Grid<UInt, 2> solution({10, 10}, 2);
solution = grid;
std::for_each(solution.begin(), solution.end(), [] CUDA_LAMBDA (UInt & x) {
if (x % 2 == 1)
x += 1;
});
Loop::stridedLoop([] CUDA_LAMBDA (Vector<UInt>&& x) {
x(0) += 1;
}, grid);
cr_assert(compare(solution, grid), "Static vector strided loop failed");
}
template <typename T> using Matrix = StaticMatrix<T, 2, 2>;
Test(strided_loops, static_matrix) {
Grid<UInt, 2> grid({10, 10}, 4);
Grid<UInt, 2> solution({10, 10}, 4);
std::iota(solution.begin(), solution.end(), 0);
std::for_each(solution.begin(), solution.end(), [] CUDA_LAMBDA (UInt & x) {
if (x % 4 == 0 || x % 4 == 3)
x = 1;
else
x = 0;
});
Loop::stridedLoop([] CUDA_LAMBDA (Matrix<UInt>&& x) {
x(0, 0) = 1;
x(1, 1) = 1;
}, grid);
cr_assert(compare(solution, grid), "Static matrix strided loop failed");
}

Event Timeline