Add OpenACC version
This commit is contained in:
parent
530b2adda2
commit
1a38b18954
113
ACCStream.cpp
Normal file
113
ACCStream.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
|
||||||
|
#include "ACCStream.h"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
ACCStream<T>::ACCStream(const unsigned int ARRAY_SIZE, T *a, T *b, T *c)
|
||||||
|
{
|
||||||
|
array_size = ARRAY_SIZE;
|
||||||
|
|
||||||
|
// Set up data region on device
|
||||||
|
this->a = a;
|
||||||
|
this->b = b;
|
||||||
|
this->c = c;
|
||||||
|
#pragma acc enter data create(a[0:array_size], b[0:array_size], c[0:array_size])
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
ACCStream<T>::~ACCStream()
|
||||||
|
{
|
||||||
|
// End data region on device
|
||||||
|
unsigned int array_size = this->array_size;
|
||||||
|
T *a = this->a;
|
||||||
|
T *b = this->b;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc exit data delete(a[0:array_size], b[0:array_size], c[0:array_size])
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ACCStream<T>::write_arrays(const std::vector<T>& h_a, const std::vector<T>& h_b, const std::vector<T>& h_c)
|
||||||
|
{
|
||||||
|
T *a = this->a;
|
||||||
|
T *b = this->b;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc update device(a[0:array_size], b[0:array_size], c[0:array_size])
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ACCStream<T>::read_arrays(std::vector<T>& h_a, std::vector<T>& h_b, std::vector<T>& h_c)
|
||||||
|
{
|
||||||
|
T *a = this->a;
|
||||||
|
T *b = this->b;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc update host(a[0:array_size], b[0:array_size], c[0:array_size])
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ACCStream<T>::copy()
|
||||||
|
{
|
||||||
|
unsigned int array_size = this->array_size;
|
||||||
|
T *a = this->a;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc kernels present(a[0:array_size], c[0:array_size]) wait
|
||||||
|
for (int i = 0; i < array_size; i++)
|
||||||
|
{
|
||||||
|
c[i] = a[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ACCStream<T>::mul()
|
||||||
|
{
|
||||||
|
const T scalar = 3.0;
|
||||||
|
|
||||||
|
unsigned int array_size = this->array_size;
|
||||||
|
T *b = this->b;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc kernels present(b[0:array_size], c[0:array_size]) wait
|
||||||
|
for (int i = 0; i < array_size; i++)
|
||||||
|
{
|
||||||
|
b[i] = scalar * c[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ACCStream<T>::add()
|
||||||
|
{
|
||||||
|
unsigned int array_size = this->array_size;
|
||||||
|
T *a = this->a;
|
||||||
|
T *b = this->b;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc kernels present(a[0:array_size], b[0:array_size], c[0:array_size]) wait
|
||||||
|
for (int i = 0; i < array_size; i++)
|
||||||
|
{
|
||||||
|
c[i] = a[i] + b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void ACCStream<T>::triad()
|
||||||
|
{
|
||||||
|
const T scalar = 3.0;
|
||||||
|
|
||||||
|
unsigned int array_size = this->array_size;
|
||||||
|
T *a = this->a;
|
||||||
|
T *b = this->b;
|
||||||
|
T *c = this->c;
|
||||||
|
#pragma acc kernels present(a[0:array_size], b[0:array_size], c[0:array_size]) wait
|
||||||
|
for (int i = 0; i < array_size; i++)
|
||||||
|
{
|
||||||
|
a[i] = b[i] + scalar * c[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void listDevices(void)
|
||||||
|
{
|
||||||
|
// Get number of devices
|
||||||
|
}
|
||||||
|
|
||||||
|
template class ACCStream<float>;
|
||||||
|
template class ACCStream<double>;
|
||||||
|
|
||||||
39
ACCStream.h
Normal file
39
ACCStream.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include "Stream.h"
|
||||||
|
|
||||||
|
#include <openacc.h>
|
||||||
|
|
||||||
|
#define IMPLEMENTATION_STRING "OpenACC"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class ACCStream : public Stream<T>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
// Size of arrays
|
||||||
|
unsigned int array_size;
|
||||||
|
// Device side pointers
|
||||||
|
T *a;
|
||||||
|
T *b;
|
||||||
|
T *c;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ACCStream(const unsigned int, T*, T*, T*);
|
||||||
|
~ACCStream();
|
||||||
|
|
||||||
|
virtual void copy() override;
|
||||||
|
virtual void add() override;
|
||||||
|
virtual void mul() override;
|
||||||
|
virtual void triad() override;
|
||||||
|
|
||||||
|
virtual void write_arrays(const std::vector<T>& a, const std::vector<T>& b, const std::vector<T>& c) override;
|
||||||
|
virtual void read_arrays(std::vector<T>& a, std::vector<T>& b, std::vector<T>& c) override;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
7
main.cpp
7
main.cpp
@ -22,6 +22,9 @@
|
|||||||
#include "CUDAStream.h"
|
#include "CUDAStream.h"
|
||||||
#elif defined(OCL)
|
#elif defined(OCL)
|
||||||
#include "OCLStream.h"
|
#include "OCLStream.h"
|
||||||
|
#elif defined(ACC)
|
||||||
|
#include "ACCStream.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -80,6 +83,10 @@ void run()
|
|||||||
// Use the OpenCL implementation
|
// Use the OpenCL implementation
|
||||||
stream = new OCLStream<T>(ARRAY_SIZE, deviceIndex);
|
stream = new OCLStream<T>(ARRAY_SIZE, deviceIndex);
|
||||||
|
|
||||||
|
#elif defined(ACC)
|
||||||
|
// Use the OpenACC implementation
|
||||||
|
stream = new ACCStream<T>(ARRAY_SIZE, a.data(), b.data(), c.data());
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
stream->write_arrays(a, b, c);
|
stream->write_arrays(a, b, c);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user