From b84d2296b87ac212474af855d916b12adf96bdb7 Mon Sep 17 00:00:00 2001 From: Cedric Nugteren Date: Sat, 1 Apr 2017 13:36:24 +0200 Subject: Separated host-device and device-host memory copies from execution of the CBLAS reference code; for fair timing and code de-duplication --- src/utilities/utilities.cpp | 48 +++++++++++++++++++++++++++++++++++++++++++++ src/utilities/utilities.hpp | 31 +++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) (limited to 'src') 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 &vector, std::mt19937 &mt, std::uniform_re // ================================================================================================= +template +void DeviceToHost(const Arguments &args, Buffers &buffers, BuffersHost &buffers_host, + Queue &queue, const std::vector &names) { + for (auto &name: names) { + if (name == kBufVecX) {buffers_host.x_vec = std::vector(args.x_size, static_cast(0)); buffers.x_vec.Read(queue, args.x_size, buffers_host.x_vec); } + else if (name == kBufVecY) { buffers_host.y_vec = std::vector(args.y_size, static_cast(0)); buffers.y_vec.Read(queue, args.y_size, buffers_host.y_vec); } + else if (name == kBufMatA) { buffers_host.a_mat = std::vector(args.a_size, static_cast(0)); buffers.a_mat.Read(queue, args.a_size, buffers_host.a_mat); } + else if (name == kBufMatB) { buffers_host.b_mat = std::vector(args.b_size, static_cast(0)); buffers.b_mat.Read(queue, args.b_size, buffers_host.b_mat); } + else if (name == kBufMatC) { buffers_host.c_mat = std::vector(args.c_size, static_cast(0)); buffers.c_mat.Read(queue, args.c_size, buffers_host.c_mat); } + else if (name == kBufMatAP) { buffers_host.ap_mat = std::vector(args.ap_size, static_cast(0)); buffers.ap_mat.Read(queue, args.ap_size, buffers_host.ap_mat); } + else if (name == kBufScalar) { buffers_host.scalar = std::vector(args.scalar_size, static_cast(0)); buffers.scalar.Read(queue, args.scalar_size, buffers_host.scalar); } + else { throw std::runtime_error("Invalid buffer name"); } + } +} + +template +void HostToDevice(const Arguments &args, Buffers &buffers, BuffersHost &buffers_host, + Queue &queue, const std::vector &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&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void DeviceToHost(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void DeviceToHost(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void DeviceToHost(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void DeviceToHost(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void DeviceToHost(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void DeviceToHost(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); +template void HostToDevice(const Arguments&, Buffers&, BuffersHost&, Queue&, const std::vector&); + +// ================================================================================================= + // Conversion between half and single-precision std::vector HalfToFloatBuffer(const std::vector& source) { auto result = std::vector(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 ap_mat; Buffer scalar; }; +template +struct BuffersHost { + std::vector x_vec; + std::vector y_vec; + std::vector a_mat; + std::vector b_mat; + std::vector c_mat; + std::vector ap_mat; + std::vector scalar; +}; // ================================================================================================= @@ -250,6 +269,18 @@ void PopulateVector(std::vector &vector, std::mt19937 &mt, std::uniform_real_ // ================================================================================================= +// Copies buffers from the OpenCL device to the host +template +void DeviceToHost(const Arguments &args, Buffers &buffers, BuffersHost &buffers_host, + Queue &queue, const std::vector &names); + +// Copies buffers from the host to the OpenCL device +template +void HostToDevice(const Arguments &args, Buffers &buffers, BuffersHost &buffers_host, + Queue &queue, const std::vector &names); + +// ================================================================================================= + // Conversion between half and single-precision std::vector HalfToFloatBuffer(const std::vector& source); void FloatToHalfBuffer(std::vector& result, const std::vector& source); -- cgit v1.2.3