diff --git a/KOKKOSStream.cpp b/KOKKOSStream.cpp new file mode 100644 index 0000000..c4d548b --- /dev/null +++ b/KOKKOSStream.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2015-16 Tom Deakin, Simon McIntosh-Smith, +// University of Bristol HPC +// +// For full license terms please see the LICENSE file distributed with this +// source code + + +#include "KOKKOSStream.hpp" + +using Kokkos::parallel_for; + +template +KOKKOSStream::KOKKOSStream( + const unsigned int ARRAY_SIZE, const int device_index) + : array_size(ARRAY_SIZE) +{ + Kokkos::initialize(); + + new(d_a) Kokkos::View("d_a", ARRAY_SIZE); + new(d_b) Kokkos::View("d_b", ARRAY_SIZE); + new(d_c) Kokkos::View("d_c", ARRAY_SIZE); + new(hm_a) Kokkos::View::HostMirror(); + new(hm_b) Kokkos::View::HostMirror(); + new(hm_c) Kokkos::View::HostMirror(); + hm_a = Kokkos::create_mirror_view(d_a); + hm_b = Kokkos::create_mirror_view(d_b); + hm_c = Kokkos::create_mirror_view(d_c); +} + +template +KOKKOSStream::~KOKKOSStream() +{ + Kokkos::finalize(); +} + +template +void KOKKOSStream::write_arrays( + const std::vector& a, const std::vector& b, const std::vector& c) +{ + for(int ii = 0; ii < array_size; ++ii) + { + hm_a(ii) = a[ii]; + hm_b(ii) = b[ii]; + hm_c(ii) = c[ii]; + } + Kokkos::deep_copy(hm_a, d_a); + Kokkos::deep_copy(hm_b, d_b); + Kokkos::deep_copy(hm_c, d_c); +} + +template +void KOKKOSStream::read_arrays( + std::vector& a, std::vector& b, std::vector& c) +{ + Kokkos::deep_copy(d_a, hm_a); + Kokkos::deep_copy(d_a, hm_b); + Kokkos::deep_copy(d_a, hm_c); + for(int ii = 0; ii < array_size; ++ii) + { + a[ii] = hm_a(ii); + b[ii] = hm_b(ii); + c[ii] = hm_c(ii); + } +} + +template +void KOKKOSStream::copy() +{ + Kokkos::parallel_for(array_size, KOKKOS_LAMBDA (const int index) + { + d_c[index] = d_a[index]; + }); +} + +template +void KOKKOSStream::mul() +{ + const T scalar = 3.0; + parallel_for(array_size, KOKKOS_LAMBDA (const int index) + { + d_b[index] = scalar*d_c[index]; + }); +} + +template +void KOKKOSStream::add() +{ + parallel_for(array_size, KOKKOS_LAMBDA (const int index) + { + d_c[index] = d_a[index] + d_b[index]; + }); +} + +template +void KOKKOSStream::triad() +{ + const T scalar = 3.0; + parallel_for(array_size, KOKKOS_LAMBDA (const int index) + { + d_a[index] = d_b[index] + scalar*d_c[index]; + }); +} + +void listDevices(void) +{ + std::cout << "This is not the device you are looking for."; +} + + +std::string getDeviceName(const int device) +{ + return "Kokkos"; +} + + +std::string getDeviceDriver(const int device) +{ + return "Kokkos"; +} + +template class KOKKOSStream; +template class KOKKOSStream; + diff --git a/KOKKOSStream.hpp b/KOKKOSStream.hpp new file mode 100644 index 0000000..632ca20 --- /dev/null +++ b/KOKKOSStream.hpp @@ -0,0 +1,53 @@ +// Copyright (c) 2015-16 Tom Deakin, Simon McIntosh-Smith, +// University of Bristol HPC +// +// For full license terms please see the LICENSE file distributed with this +// source code + +#pragma once + +#include +#include + +#include +#include +#include + +#include "Stream.h" + +#define IMPLEMENTATION_STRING "KOKKOS" + +#define DEVICE Kokkos::OpenMP + + +template +class KOKKOSStream : public Stream +{ + protected: + // Size of arrays + unsigned int array_size; + + // Device side pointers to arrays + Kokkos::View d_a; + Kokkos::View d_b; + Kokkos::View d_c; + Kokkos::View::HostMirror hm_a; + Kokkos::View::HostMirror hm_b; + Kokkos::View::HostMirror hm_c; + + public: + + KOKKOSStream(const unsigned int, const int); + ~KOKKOSStream(); + + virtual void copy() override; + virtual void add() override; + virtual void mul() override; + virtual void triad() override; + + virtual void write_arrays( + const std::vector& a, const std::vector& b, const std::vector& c) override; + virtual void read_arrays( + std::vector& a, std::vector& b, std::vector& c) override; +}; + diff --git a/RAJAStream.cpp b/RAJAStream.cpp new file mode 100644 index 0000000..5b1c980 --- /dev/null +++ b/RAJAStream.cpp @@ -0,0 +1,105 @@ + +// Copyright (c) 2015-16 Tom Deakin, Simon McIntosh-Smith, +// University of Bristol HPC +// +// For full license terms please see the LICENSE file distributed with this +// source code + +#include "RAJAStream.hpp" + +using RAJA::forall; +using RAJA::RangeSegment; + +template +RAJAStream::RAJAStream(const unsigned int ARRAY_SIZE, const int device_index) + : array_size(ARRAY_SIZE) +{ + RangeSegment seg(0, ARRAY_SIZE); + index_set.push_back(seg); + d_a = new T[ARRAY_SIZE]; + d_b = new T[ARRAY_SIZE]; + d_c = new T[ARRAY_SIZE]; +} + +template +RAJAStream::~RAJAStream() +{ + delete[] d_a; + delete[] d_b; + delete[] d_c; +} + +template +void RAJAStream::write_arrays(const std::vector& a, const std::vector& b, const std::vector& c) +{ + std::copy(a.begin(), a.end(), d_a); + std::copy(b.begin(), b.end(), d_b); + std::copy(c.begin(), c.end(), d_c); +} + +template +void RAJAStream::read_arrays(std::vector& a, std::vector& b, std::vector& c) +{ + std::copy(d_a, d_a + array_size - 1, a.data()); + std::copy(d_b, d_b + array_size - 1, b.data()); + std::copy(d_c, d_c + array_size - 1, c.data()); +} + +template +void RAJAStream::copy() +{ + forall(index_set, [=] RAJA_DEVICE (int index) + { + d_c[index] = d_a[index]; + }); +} + +template +void RAJAStream::mul() +{ + const T scalar = 3.0; + forall(index_set, [=] RAJA_DEVICE (int index) + { + d_b[index] = scalar*d_c[index]; + }); +} + +template +void RAJAStream::add() +{ + forall(index_set, [=] RAJA_DEVICE (int index) + { + d_c[index] = d_a[index] + d_b[index]; + }); +} + +template +void RAJAStream::triad() +{ + const T scalar = 3.0; + forall(index_set, [=] RAJA_DEVICE (int index) + { + d_a[index] = d_b[index] + scalar*d_c[index]; + }); +} + +void listDevices(void) +{ + std::cout << "This is not the device you are looking for."; +} + + +std::string getDeviceName(const int device) +{ + return "RAJA"; +} + + +std::string getDeviceDriver(const int device) +{ + return "RAJA"; +} + +template class RAJAStream; +template class RAJAStream; + diff --git a/RAJAStream.hpp b/RAJAStream.hpp new file mode 100644 index 0000000..a41c60e --- /dev/null +++ b/RAJAStream.hpp @@ -0,0 +1,58 @@ +// Copyright (c) 2015-16 Tom Deakin, Simon McIntosh-Smith, +// University of Bristol HPC +// +// For full license terms please see the LICENSE file distributed with this +// source code + +#pragma once + +#include +#include +#include "RAJA/RAJA.hxx" + +#include "Stream.h" + +#define IMPLEMENTATION_STRING "RAJA" + +#ifdef RAJA_USE_CUDA +const size_t block_size = 128; +typedef RAJA::IndexSet::ExecPolicy< + RAJA::seq_segit, + RAJA::cuda_exec_async> policy; +#else +typedef RAJA::IndexSet::ExecPolicy< + RAJA::seq_segit, + RAJA::omp_parallel_for_exec> policy; +#endif + +template +class RAJAStream : public Stream +{ + protected: + // Size of arrays + unsigned int array_size; + + // Contains iteration space + RAJA::IndexSet index_set; + + // Device side pointers to arrays + T* d_a; + T* d_b; + T* d_c; + + public: + + RAJAStream(const unsigned int, const int); + ~RAJAStream(); + + virtual void copy() override; + virtual void add() override; + virtual void mul() override; + virtual void triad() override; + + virtual void write_arrays( + const std::vector& a, const std::vector& b, const std::vector& c) override; + virtual void read_arrays( + std::vector& a, std::vector& b, std::vector& c) override; +}; +