diff options
author | Cedric Nugteren <web@cedricnugteren.nl> | 2017-04-02 14:59:39 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-02 14:59:39 +0200 |
commit | 5079fbaeffe38cd26ea2fa878bdbb2de5b140bcf (patch) | |
tree | 0f2e85e1e1acef1d22f046499dd0b8a30e5da4f9 /src | |
parent | a98c00a2671b8981579f3a73dca8fb3365a95e53 (diff) | |
parent | b84d2296b87ac212474af855d916b12adf96bdb7 (diff) |
Merge pull request #143 from CNugteren/test_cblas_timing
CBLAS reference code is now separated from device-host copies
Diffstat (limited to 'src')
-rw-r--r-- | src/utilities/utilities.cpp | 48 | ||||
-rw-r--r-- | src/utilities/utilities.hpp | 31 |
2 files changed, 79 insertions, 0 deletions
diff --git a/src/utilities/utilities.cpp b/src/utilities/utilities.cpp index 3d091b64..0f2661ad 100644 --- a/src/utilities/utilities.cpp +++ b/src/utilities/utilities.cpp @@ -353,6 +353,54 @@ void PopulateVector(std::vector<half> &vector, std::mt19937 &mt, std::uniform_re // ================================================================================================= +template <typename T, typename U> +void DeviceToHost(const Arguments<U> &args, Buffers<T> &buffers, BuffersHost<T> &buffers_host, + Queue &queue, const std::vector<std::string> &names) { + for (auto &name: names) { + if (name == kBufVecX) {buffers_host.x_vec = std::vector<T>(args.x_size, static_cast<T>(0)); buffers.x_vec.Read(queue, args.x_size, buffers_host.x_vec); } + else if (name == kBufVecY) { buffers_host.y_vec = std::vector<T>(args.y_size, static_cast<T>(0)); buffers.y_vec.Read(queue, args.y_size, buffers_host.y_vec); } + else if (name == kBufMatA) { buffers_host.a_mat = std::vector<T>(args.a_size, static_cast<T>(0)); buffers.a_mat.Read(queue, args.a_size, buffers_host.a_mat); } + else if (name == kBufMatB) { buffers_host.b_mat = std::vector<T>(args.b_size, static_cast<T>(0)); buffers.b_mat.Read(queue, args.b_size, buffers_host.b_mat); } + else if (name == kBufMatC) { buffers_host.c_mat = std::vector<T>(args.c_size, static_cast<T>(0)); buffers.c_mat.Read(queue, args.c_size, buffers_host.c_mat); } + else if (name == kBufMatAP) { buffers_host.ap_mat = std::vector<T>(args.ap_size, static_cast<T>(0)); buffers.ap_mat.Read(queue, args.ap_size, buffers_host.ap_mat); } + else if (name == kBufScalar) { buffers_host.scalar = std::vector<T>(args.scalar_size, static_cast<T>(0)); buffers.scalar.Read(queue, args.scalar_size, buffers_host.scalar); } + else { throw std::runtime_error("Invalid buffer name"); } + } +} + +template <typename T, typename U> +void HostToDevice(const Arguments<U> &args, Buffers<T> &buffers, BuffersHost<T> &buffers_host, + Queue &queue, const std::vector<std::string> &names) { + for (auto &name: names) { + if (name == kBufVecX) { buffers.x_vec.Write(queue, args.x_size, buffers_host.x_vec); } + else if (name == kBufVecY) { buffers.y_vec.Write(queue, args.y_size, buffers_host.y_vec); } + else if (name == kBufMatA) { buffers.a_mat.Write(queue, args.a_size, buffers_host.a_mat); } + else if (name == kBufMatB) { buffers.b_mat.Write(queue, args.b_size, buffers_host.b_mat); } + else if (name == kBufMatC) { buffers.c_mat.Write(queue, args.c_size, buffers_host.c_mat); } + else if (name == kBufMatAP) { buffers.ap_mat.Write(queue, args.ap_size, buffers_host.ap_mat); } + else if (name == kBufScalar) { buffers.scalar.Write(queue, args.scalar_size, buffers_host.scalar); } + else { throw std::runtime_error("Invalid buffer name"); } + } +} + +// Compiles the above functions +template void DeviceToHost(const Arguments<half>&, Buffers<half>&, BuffersHost<half>&, Queue&, const std::vector<std::string>&); +template void DeviceToHost(const Arguments<float>&, Buffers<float>&, BuffersHost<float>&, Queue&, const std::vector<std::string>&); +template void DeviceToHost(const Arguments<double>&, Buffers<double>&, BuffersHost<double>&, Queue&, const std::vector<std::string>&); +template void DeviceToHost(const Arguments<float>&, Buffers<float2>&, BuffersHost<float2>&, Queue&, const std::vector<std::string>&); +template void DeviceToHost(const Arguments<double>&, Buffers<double2>&, BuffersHost<double2>&, Queue&, const std::vector<std::string>&); +template void DeviceToHost(const Arguments<float2>&, Buffers<float2>&, BuffersHost<float2>&, Queue&, const std::vector<std::string>&); +template void DeviceToHost(const Arguments<double2>&, Buffers<double2>&, BuffersHost<double2>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<half>&, Buffers<half>&, BuffersHost<half>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<float>&, Buffers<float>&, BuffersHost<float>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<double>&, Buffers<double>&, BuffersHost<double>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<float>&, Buffers<float2>&, BuffersHost<float2>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<double>&, Buffers<double2>&, BuffersHost<double2>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<float2>&, Buffers<float2>&, BuffersHost<float2>&, Queue&, const std::vector<std::string>&); +template void HostToDevice(const Arguments<double2>&, Buffers<double2>&, BuffersHost<double2>&, Queue&, const std::vector<std::string>&); + +// ================================================================================================= + // Conversion between half and single-precision std::vector<float> HalfToFloatBuffer(const std::vector<half>& source) { auto result = std::vector<float>(source.size()); diff --git a/src/utilities/utilities.hpp b/src/utilities/utilities.hpp index b3db8c22..535560a3 100644 --- a/src/utilities/utilities.hpp +++ b/src/utilities/utilities.hpp @@ -98,6 +98,15 @@ constexpr auto kArgHelp = "h"; constexpr auto kArgQuiet = "q"; constexpr auto kArgNoAbbreviations = "no_abbrv"; +// The buffer names +constexpr auto kBufVecX = "X"; +constexpr auto kBufVecY = "Y"; +constexpr auto kBufMatA = "A"; +constexpr auto kBufMatB = "B"; +constexpr auto kBufMatC = "C"; +constexpr auto kBufMatAP = "AP"; +constexpr auto kBufScalar = "Scalar"; + // ================================================================================================= // Converts a regular or complex type to it's base type (e.g. float2 to float) @@ -202,6 +211,16 @@ struct Buffers { Buffer<T> ap_mat; Buffer<T> scalar; }; +template <typename T> +struct BuffersHost { + std::vector<T> x_vec; + std::vector<T> y_vec; + std::vector<T> a_mat; + std::vector<T> b_mat; + std::vector<T> c_mat; + std::vector<T> ap_mat; + std::vector<T> scalar; +}; // ================================================================================================= @@ -250,6 +269,18 @@ void PopulateVector(std::vector<T> &vector, std::mt19937 &mt, std::uniform_real_ // ================================================================================================= +// Copies buffers from the OpenCL device to the host +template <typename T, typename U> +void DeviceToHost(const Arguments<U> &args, Buffers<T> &buffers, BuffersHost<T> &buffers_host, + Queue &queue, const std::vector<std::string> &names); + +// Copies buffers from the host to the OpenCL device +template <typename T, typename U> +void HostToDevice(const Arguments<U> &args, Buffers<T> &buffers, BuffersHost<T> &buffers_host, + Queue &queue, const std::vector<std::string> &names); + +// ================================================================================================= + // Conversion between half and single-precision std::vector<float> HalfToFloatBuffer(const std::vector<half>& source); void FloatToHalfBuffer(std::vector<half>& result, const std::vector<float>& source); |