Skip to content

Commit

Permalink
Add basic Kokkos support for the original tests of #783
Browse files Browse the repository at this point in the history
This commit adds a test from the original Kokkos PR #783
and provides the implementation of the simplest Kokkos
features in the form of custom pushforwards. This commit
only addresses the forward mode.
  • Loading branch information
gojakuch committed Jul 10, 2024
1 parent 036eb67 commit 7fa0c09
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 161 deletions.
2 changes: 1 addition & 1 deletion unittests/Kokkos/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
add_clad_unittest(KokkosTests
main.cpp
ViewBasics.cpp
ViewAccess.cpp
ParallelReduce.cpp
ParallelFor.cpp
)
Expand Down
45 changes: 45 additions & 0 deletions unittests/Kokkos/KokkosImplementation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// This header file contains the implementation of the Kokkos framework differentiation support in Clad in the form of custom pushforwards and pullbacks.

#ifndef KOKKOS_IMPLEMENTATION
#define KOKKOS_IMPLEMENTATION

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

namespace clad {
namespace custom_derivatives {
namespace class_functions {
/// Kokkos arrays
template <typename ArrayT, typename Space>
clad::ValueAndPushforward<Kokkos::View<ArrayT, Space>, Kokkos::View<ArrayT, Space>>
constructor_pushforward(clad::ConstructorPushforwardTag<Kokkos::View<ArrayT, Space>>, const ::std::string &name, const size_t& idx0, const size_t& idx1, const size_t& idx2, const size_t& idx3, const size_t& idx4, const size_t& idx5, const size_t& idx6, const size_t& idx7, const ::std::string &_d_name, const size_t& _d_idx0, const size_t& _d_idx1, const size_t& _d_idx2, const size_t& _d_idx3, const size_t& _d_idx4, const size_t& _d_idx5, const size_t& _d_idx6, const size_t& _d_idx7) {
return {Kokkos::View<ArrayT, Space>(name, idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7),
Kokkos::View<ArrayT, Space>("_diff_"+name, idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7)};
};

template <typename ArrayT, typename Layout, typename Space>
clad::ValueAndPushforward<Kokkos::View<ArrayT, Layout, Space>, Kokkos::View<ArrayT, Layout, Space>>
constructor_pushforward(clad::ConstructorPushforwardTag<Kokkos::View<ArrayT, Layout, Space>>, const ::std::string &name, const size_t& idx0, const size_t& idx1, const size_t& idx2, const size_t& idx3, const size_t& idx4, const size_t& idx5, const size_t& idx6, const size_t& idx7, const ::std::string &_d_name, const size_t& _d_idx0, const size_t& _d_idx1, const size_t& _d_idx2, const size_t& _d_idx3, const size_t& _d_idx4, const size_t& _d_idx5, const size_t& _d_idx6, const size_t& _d_idx7) {
return {Kokkos::View<ArrayT, Layout, Space>(name, idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7),
Kokkos::View<ArrayT, Layout, Space>("_diff_"+name, idx0, idx1, idx2, idx3, idx4, idx5, idx6, idx7)};
}
} // namespace class_functions

/// Kokkos functions
namespace Kokkos {
template <typename View1, typename View2, typename T>
inline void deep_copy_pushforward(const View1 &dst, const View2 &src, T param, const View1 &_d_dst, const View2 &_d_src, T _d_param) {
deep_copy(dst, src);
deep_copy(_d_dst, _d_src);
}


template<class ExecPolicy, class FunctorType>
inline void parallel_for_pushforward(const ::std::string &str, const ExecPolicy &policy, const FunctorType &functor, const ::std::string &_d_str, const ExecPolicy &_d_policy, const FunctorType &_d_functor) {
// TODO: implement parallel_for_pushforward
return;
}
}
}}

#endif // #ifndef KOKKOS_IMPLEMENTATION
75 changes: 75 additions & 0 deletions unittests/Kokkos/ViewAccess.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// Source: https://github.com/vgvassilev/clad/pull/783/files#diff-c919937640674e1911d1f17d3df2b65426d152400589873ff9ba2f0391048d78
// Source: https://github.com/kliegeois/clad/tree/kokkos-PR
// Originally created by Kim Liegeois

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

double f(double x, double y) {

const int N1 = 4;

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

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

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

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

double f_2(double x, double y) {

const int N1 = 4;

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

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

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

return a(0,0);
}

TEST(ViewAccess, Test1) {
EXPECT_NEAR(f(0,1), 1, 1e-8);
EXPECT_NEAR(f(0,2), 2, 1e-8);
}

TEST(ViewAccess, Test2) {

double tolerance = 1e-8;
double epsilon = 1e-6;

auto f_x = clad::differentiate(f, "x");

std::function<double(double)> f_tmp = [](double x){ return f(x,4.); };
double dx_f_FD = finite_difference_tangent(f_tmp, 3., epsilon);

EXPECT_NEAR(f_x.execute(3, 4),dx_f_FD,tolerance*dx_f_FD);

auto f_2_x = clad::differentiate(f_2, "x");

std::function<double(double)> f_2_tmp = [](double x){ return f_2(x,4.); };
double dx_f_2_FD = finite_difference_tangent(f_2_tmp, 3., epsilon);
EXPECT_NEAR(f_2_x.execute(3, 4),dx_f_2_FD,tolerance*dx_f_2_FD);

// TODO: uncomment this once it has been implemented
// auto f_grad_exe = clad::gradient(f);
// double dx, dy;
// f_grad_exe.execute(3., 4., &dx, &dy);
// EXPECT_NEAR(f_x.execute(3, 4),dx,tolerance*dx);

// double dx_2, dy_2;
// auto f_2_grad_exe = clad::gradient(f_2);
// f_2_grad_exe.execute(3., 4., &dx_2, &dy_2);
// EXPECT_NEAR(f_2_x.execute(3, 4),dx_2,tolerance*dx_2);
}
160 changes: 0 additions & 160 deletions unittests/Kokkos/ViewBasics.cpp

This file was deleted.

0 comments on commit 7fa0c09

Please sign in to comment.