Skip to content

Commit

Permalink
Add Kokkos unittests
Browse files Browse the repository at this point in the history
  • Loading branch information
gojakuch committed Mar 19, 2024
1 parent 2cd0b32 commit abf6043
Show file tree
Hide file tree
Showing 6 changed files with 627 additions and 22 deletions.
3 changes: 2 additions & 1 deletion unittests/Kokkos/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_clad_unittest(KokkosTests
parallel_for.cpp
main.cpp
ParallelFor.cpp
ViewBasics.cpp
)

# If llvm does not require rtti, kokkos does.
Expand Down
101 changes: 101 additions & 0 deletions unittests/Kokkos/ParallelFor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include <Kokkos_Core.hpp>
#include "clad/Differentiator/Differentiator.h"
#include "gtest/gtest.h"
#include "TestUtils.hpp"
#include "parallel_sum.hpp"

TEST(ParallelFor, HelloWorldLambdaLoopForward) {
// check finite difference and forward mode similarity

// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

std::function<double(double)> _f = [](double x) {
double res = 0.;
Kokkos::parallel_for("HelloWorld-1", 5, [&res, x](const int i){ res = x*x; });
// res = x*x;
return res;
};

// TODO: uncomment this once it has been implemented
// auto f_diff = clad::differentiate(_f, 0/*x*/);
// for (double x = -2; x <= 2; x += 1) {
// double f_diff_ex = f_diff.execute(x);
// double dx_f_FD = finite_difference_tangent(_f, x, eps);
// EXPECT_NEAR(f_diff_ex, dx_f_FD, abs(tau*dx_f_FD));
// }
}

TEST(ParallelFor, HelloWorldLambdaLoopReverse) {
// check finite difference and reverse mode similarity

// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

std::function<double(double)> _f = [](double x) {
double res = 0.;
Kokkos::parallel_for("HelloWorld-2", 5, [&res, x](const int i){ res = x*x; });
// res = x*x;
return res;
};

// TODO: uncomment this once it has been implemented
// auto f_grad = clad::gradient(_f);
// for (double x = -2; x <= 2; x += 1) {
// double dx_f_FD = finite_difference_tangent(_f, x, eps);
// double dx;
// f_grad.execute(x, &dx);
// EXPECT_NEAR(dx_f_FD, dx, abs(tau*dx));
// }
}

double parallel_polynomial(double x) {
Kokkos::View <double[1]> res("res");
res(0) = 0;
Kokkos::parallel_for("polycalc", 5, KOKKOS_LAMBDA(const int i) {
res(0) += pow(x, i+1)/(i+1);
});
// for (int i = 0; i < 6; ++i) { // standard C++ alternative
// res(0) += pow(x, i+1)/(i+1);
// }
return res(0);
}

double parallel_polynomial_true_derivative(double x) {
double res = 0;
double x_c = 1;
for (unsigned i = 0; i < 6; ++i) {
res += x_c;
x_c *= x;
}
return res;
}

TEST(ParallelFor, ParallelPolynomialForward) {
// check true derivative and forward mode similarity

// const double tau = 1e-5; // tolerance

// TODO: uncomment this once it has been implemented
// auto f_diff = clad::differentiate(parallel_polynomial, "x");
// for (double x = -2; x <= 2; x += 1) {
// double f_diff_ex = f_diff.execute(x);
// double dx_f_true = parallel_polynomial_true_derivative(x);
// EXPECT_NEAR(f_diff_ex, dx_f_true, abs(tau*dx_f_true));
// }
}

TEST(ParallelFor, ParallelPolynomialReverse) {
// check true derivative and reverse mode similarity

// const double tau = 1e-5; // tolerance

// TODO: uncomment this once it has been implemented
// auto f_grad = clad::gradient(parallel_polynomial);
// for (double x = -2; x <= 2; x += 1) {
// double dx_f_true = parallel_polynomial_true_derivative(x);
// double dx = 0;
// f_grad.execute(x, &dx);
// EXPECT_NEAR(dx_f_true, dx, abs(tau*dx));
// }
}
11 changes: 11 additions & 0 deletions unittests/Kokkos/TestUtils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Useful things

#ifndef KOKKOS_UNITTEST_UTILS
#define KOKKOS_UNITTEST_UTILS

template <typename T> // comparison with the finite difference approx. has been tested in the initial PR for Kokkos-aware Clad by Kim Liegeois
T finite_difference_tangent(std::function<T(T)> func, const T& x, const T& epsilon) {
return (func(x+epsilon)-func(x-epsilon)) / (2 * epsilon);
}

#endif
165 changes: 165 additions & 0 deletions unittests/Kokkos/ViewBasics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// Very basic Kokkos::View usage test that should work by all means
// inspired by https://github.com/kliegeois/clad/blob/kokkos-PR/unittests/Kokkos/view_access.cpp
// it has been modified to match gtest guidelines and improve readability

#include <Kokkos_Core.hpp>
#include "clad/Differentiator/Differentiator.h"
#include "gtest/gtest.h"
#include "TestUtils.hpp"
#include "parallel_sum.hpp"

double f(double x, double y) {
const int N = 2;

Kokkos::View<double*[N]> a("a", N);
Kokkos::View<double*[N]> b("b", N);

a(0,0) = x;
b(0,0) = y*x;

return a(0,0) + a(0,0)*b(0,0) + b(0,0);
}

TEST(ViewBasics, TestAccessForward) {
// check finite difference and forward mode similarity

// TODO: uncomment this once it has been implemented
// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

// auto f_x = clad::differentiate(f, "x");
// for (double y = 3; y <= 5; y += 1) {
// std::function<double(double)> f_tmp = [y](double t){ return f(t, y); };
// for (double x = 3; x <= 5; x += 1) {
// double f_x_ex = f_x.execute(x, y);
// double dx_f_FD = finite_difference_tangent(f_tmp, x, eps);
// EXPECT_NEAR(f_x_ex, dx_f_FD, abs(tau*dx_f_FD));
// }
// }
}

TEST(ViewBasics, TestAccessReverse) {
// check reverse mode and forward mode similarity

// TODO: uncomment this once it has been implemented
// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

// auto f_grad_exe = clad::gradient(f);
// for (double y = 3; y <= 5; y += 1) {
// std::function<double(double)> f_tmp = [y](double t){ return f(t, y); };
// for (double x = 3; x <= 5; x += 1) {
// double dx_f_FD = finite_difference_tangent(f_tmp, x, eps);
// double dx, dy;
// f_grad_exe.execute(x, y, &dx, &dy);
// EXPECT_NEAR(dx_f_FD, dx, abs(tau*dx));
// }
// }
}

double f_2(double x, double y) {
const int N = 2;

Kokkos::View<double*[4], Kokkos::LayoutLeft, Kokkos::HostSpace> a("a", N);
Kokkos::View<double*[4], Kokkos::LayoutLeft, Kokkos::HostSpace> b("b", N);

Kokkos::deep_copy(a, 3*x+y);
b(0,0) = x;
Kokkos::deep_copy(b, a);

b(0,0) = b(0,0) + a(0,0) * b(0,0);

return a(0,0); // derivative of this wrt x is constantly 3
}

TEST(ViewBasics, TestDeepCopyForward) {
// check finite difference and forward mode similarity

// TODO: uncomment this once it has been implemented
// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

// auto f_x = clad::differentiate(f_2, "x");
// for (double y = 3; y <= 5; y += 1) {
// std::function<double(double)> f_tmp = [y](double t){ return f_2(t, y); };
// for (double x = 3; x <= 5; x += 1) {
// double f_x_ex = f_x.execute(x, y);
// double dx_f_FD = finite_difference_tangent(f_tmp, x, eps);
// EXPECT_NEAR(f_x_ex, dx_f_FD, abs(tau*dx_f_FD));
// }
// }
}

TEST(ViewBasics, TestDeepCopyReverse) {
// check reverse mode and forward mode similarity

// TODO: uncomment this once it has been implemented
// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

// auto f_grad_exe = clad::gradient(f_2);
// for (double y = 3; y <= 5; y += 1) {
// std::function<double(double)> f_tmp = [y](double t){ return f_2(t, y); };
// for (double x = 3; x <= 5; x += 1) {
// double dx_f_FD = finite_difference_tangent(f_tmp, x, eps);
// double dx, dy;
// f_grad_exe.execute(x, y, &dx, &dy);
// EXPECT_NEAR(dx_f_FD, dx, abs(tau*dx));
// }
// }
}

double f_3(double x, double y) {
const int N = 2;

Kokkos::View<double*, Kokkos::LayoutLeft, Kokkos::HostSpace> a("a", N);
Kokkos::View<double*, Kokkos::LayoutLeft, Kokkos::HostSpace> b("b", N);

Kokkos::deep_copy(a, 3*y+x+50);
b(1) = x*y;
Kokkos::deep_copy(b, a);

b(1) = b(1) + a(0) * b(1);

a(1) = x*x*x;
a(0) += a(1);

return a(0); // derivative of this wrt y is constantly 3
}

TEST(ViewBasics, TestDeepCopy2Forward) {
// check finite difference and forward mode similarity

// TODO: uncomment this once it has been implemented
// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

// auto f_y = clad::differentiate(f_3, "y");
// for (double x = 3; x <= 5; x += 1) {
// std::function<double(double)> f_tmp = [x](double t){ return f_3(x, t); };
// for (double y = 3; y <= 5; y += 1) {
// double f_y_ex = f_y.execute(x, y);
// double dy_f_FD = finite_difference_tangent(f_tmp, y, eps);
// EXPECT_NEAR(f_y_ex, dy_f_FD, abs(tau*dy_f_FD));
// }
// }
}

TEST(ViewBasics, TestDeepCopy2Reverse) {
// check reverse mode and forward mode similarity

// TODO: uncomment this once it has been implemented
// const double eps = 1e-5;
// const double tau = 1e-6; // tolerance

// auto f_grad_exe = clad::gradient(f_3);
// for (double x = 3; x <= 5; x += 1) {
// std::function<double(double)> f_tmp = [x](double t){ return f_3(x, t); };
// for (double y = 3; y <= 5; y += 1) {
// double dy_f_FD = finite_difference_tangent(f_tmp, y, eps);
// double dx, dy;
// f_grad_exe.execute(x, y, &dx, &dy);
// EXPECT_NEAR(dy_f_FD, dy, abs(tau*dy));
// }
// }
}
21 changes: 0 additions & 21 deletions unittests/Kokkos/parallel_for.cpp

This file was deleted.

Loading

0 comments on commit abf6043

Please sign in to comment.