summaryrefslogtreecommitdiff
path: root/src/utilities.hpp
diff options
context:
space:
mode:
authorCedric Nugteren <web@cedricnugteren.nl>2016-06-18 20:20:13 +0200
committerCedric Nugteren <web@cedricnugteren.nl>2016-06-18 20:20:13 +0200
commitf726fbdc9fef937fbe32222f0e66aac8d7e2678c (patch)
treecb62cc877ea239052fb1882f7bf327aace3e7776 /src/utilities.hpp
parentbacb5d2bb2ea7b141034878090aca850db8f9d00 (diff)
Moved all headers into the source tree, changed headers to .hpp extension
Diffstat (limited to 'src/utilities.hpp')
-rw-r--r--src/utilities.hpp257
1 files changed, 257 insertions, 0 deletions
diff --git a/src/utilities.hpp b/src/utilities.hpp
new file mode 100644
index 00000000..9a2b9ffc
--- /dev/null
+++ b/src/utilities.hpp
@@ -0,0 +1,257 @@
+
+// =================================================================================================
+// This file is part of the CLBlast project. The project is licensed under Apache Version 2.0. This
+// project loosely follows the Google C++ styleguide and uses a tab-size of two spaces and a max-
+// width of 100 characters per line.
+//
+// Author(s):
+// Cedric Nugteren <www.cedricnugteren.nl>
+//
+// This file provides declarations for the common (test) utility functions such as a command-line
+// argument parser. On top of this, it serves as the 'common' header, including the C++ OpenCL
+// wrapper. These utilities are not only used for CLBlast, but also included as part of the tuners,
+// the performance client and the correctness testers.
+//
+// =================================================================================================
+
+#ifndef CLBLAST_UTILITIES_H_
+#define CLBLAST_UTILITIES_H_
+
+#include <string>
+#include <functional>
+#include <complex>
+
+#include "clblast.h"
+#include "clblast_half.h"
+#include "clpp11.hpp"
+
+namespace clblast {
+// =================================================================================================
+
+// Shorthands for complex data-types
+using float2 = std::complex<float>;
+using double2 = std::complex<double>;
+
+// Khronos OpenCL extensions
+const std::string kKhronosHalfPrecision = "cl_khr_fp16";
+const std::string kKhronosDoublePrecision = "cl_khr_fp64";
+
+// Catched an unknown error
+constexpr auto kUnknownError = -999;
+
+// =================================================================================================
+
+// The routine-specific arguments in string form
+constexpr auto kArgM = "m";
+constexpr auto kArgN = "n";
+constexpr auto kArgK = "k";
+constexpr auto kArgKL = "kl";
+constexpr auto kArgKU = "ku";
+constexpr auto kArgLayout = "layout";
+constexpr auto kArgATransp = "transA";
+constexpr auto kArgBTransp = "transB";
+constexpr auto kArgSide = "side";
+constexpr auto kArgTriangle = "triangle";
+constexpr auto kArgDiagonal = "diagonal";
+constexpr auto kArgXInc = "incx";
+constexpr auto kArgYInc = "incy";
+constexpr auto kArgXOffset = "offx";
+constexpr auto kArgYOffset = "offy";
+constexpr auto kArgALeadDim = "lda";
+constexpr auto kArgBLeadDim = "ldb";
+constexpr auto kArgCLeadDim = "ldc";
+constexpr auto kArgAOffset = "offa";
+constexpr auto kArgBOffset = "offb";
+constexpr auto kArgCOffset = "offc";
+constexpr auto kArgAPOffset = "offap";
+constexpr auto kArgDotOffset = "offdot";
+constexpr auto kArgNrm2Offset = "offnrm2";
+constexpr auto kArgAsumOffset = "offasum";
+constexpr auto kArgImaxOffset = "offimax";
+constexpr auto kArgAlpha = "alpha";
+constexpr auto kArgBeta = "beta";
+
+// The tuner-specific arguments in string form
+constexpr auto kArgFraction = "fraction";
+
+// The client-specific arguments in string form
+constexpr auto kArgCompareclblas = "clblas";
+constexpr auto kArgComparecblas = "cblas";
+constexpr auto kArgStepSize = "step";
+constexpr auto kArgNumSteps = "num_steps";
+constexpr auto kArgNumRuns = "runs";
+
+// The client-specific arguments in string form
+constexpr auto kArgFullTest = "full_test";
+constexpr auto kArgVerbose = "verbose";
+
+// The common arguments in string form
+constexpr auto kArgPlatform = "platform";
+constexpr auto kArgDevice = "device";
+constexpr auto kArgPrecision = "precision";
+constexpr auto kArgHelp = "h";
+constexpr auto kArgQuiet = "q";
+constexpr auto kArgNoAbbreviations = "no_abbrv";
+
+// =================================================================================================
+
+// Returns a scalar with a default value
+template <typename T>
+T GetScalar();
+
+// Returns a scalar of value 1
+template <typename T>
+T ConstantOne();
+
+// =================================================================================================
+
+// Structure containing all possible arguments for test clients, including their default values
+template <typename T>
+struct Arguments {
+ // Routine-specific arguments
+ size_t m = 1;
+ size_t n = 1;
+ size_t k = 1;
+ size_t ku = 1;
+ size_t kl = 1;
+ Layout layout = Layout::kRowMajor;
+ Transpose a_transpose = Transpose::kNo;
+ Transpose b_transpose = Transpose::kNo;
+ Side side = Side::kLeft;
+ Triangle triangle = Triangle::kUpper;
+ Diagonal diagonal = Diagonal::kUnit;
+ size_t x_inc = 1;
+ size_t y_inc = 1;
+ size_t x_offset = 0;
+ size_t y_offset = 0;
+ size_t a_ld = 1;
+ size_t b_ld = 1;
+ size_t c_ld = 1;
+ size_t a_offset = 0;
+ size_t b_offset = 0;
+ size_t c_offset = 0;
+ size_t ap_offset = 0;
+ size_t dot_offset = 0;
+ size_t nrm2_offset = 0;
+ size_t asum_offset = 0;
+ size_t imax_offset = 0;
+ T alpha = ConstantOne<T>();
+ T beta = ConstantOne<T>();
+ size_t x_size = 1;
+ size_t y_size = 1;
+ size_t a_size = 1;
+ size_t b_size = 1;
+ size_t c_size = 1;
+ size_t ap_size = 1;
+ size_t scalar_size = 1;
+ // Tuner-specific arguments
+ double fraction = 1.0;
+ // Client-specific arguments
+ int compare_clblas = 1;
+ int compare_cblas = 1;
+ size_t step = 1;
+ size_t num_steps = 0;
+ size_t num_runs = 10;
+ // Common arguments
+ size_t platform_id = 0;
+ size_t device_id = 0;
+ Precision precision = Precision::kSingle;
+ bool print_help = false;
+ bool silent = false;
+ bool no_abbrv = false;
+};
+
+// Structure containing all possible buffers for test clients
+template <typename T>
+struct Buffers {
+ Buffer<T> x_vec;
+ Buffer<T> y_vec;
+ Buffer<T> a_mat;
+ Buffer<T> b_mat;
+ Buffer<T> c_mat;
+ Buffer<T> ap_mat;
+ Buffer<T> scalar;
+};
+
+// =================================================================================================
+
+// Converts a value (e.g. an integer) to a string. This also covers special cases for CLBlast
+// data-types such as the Layout and Transpose data-types.
+template <typename T>
+std::string ToString(T value);
+
+// =================================================================================================
+
+// Helper for the function "GetArgument"
+template <typename T>
+T ConvertArgument(const char* value);
+
+// Basic argument parser, matching patterns in the form of "-option value" and "--option value"
+template <typename T>
+T GetArgument(const int argc, char *argv[], std::string &help,
+ const std::string &option, const T default_value);
+
+// Returns the precision only
+Precision GetPrecision(const int argc, char *argv[],
+ const Precision default_precision = Precision::kSingle);
+
+// As in "GetArgument", but now only checks whether an argument is given or not
+bool CheckArgument(const int argc, char *argv[], std::string &help, const std::string &option);
+
+// =================================================================================================
+
+// Helper function to check for errors in the status code
+constexpr bool ErrorIn(const StatusCode s) { return (s != StatusCode::kSuccess); }
+
+// =================================================================================================
+
+// Returns a random number to be used as a seed
+unsigned int GetRandomSeed();
+
+// Test/example data lower and upper limit
+constexpr auto kTestDataLowerLimit = -2.0;
+constexpr auto kTestDataUpperLimit = 2.0;
+
+// Populates a vector with random data
+template <typename T>
+void PopulateVector(std::vector<T> &vector);
+
+// =================================================================================================
+
+// 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);
+
+// As above, but now for OpenCL data-types instead of std::vectors
+Buffer<float> HalfToFloatBuffer(const Buffer<half>& source, cl_command_queue queue_raw);
+void FloatToHalfBuffer(Buffer<half>& result, const Buffer<float>& source, cl_command_queue queue_raw);
+
+// =================================================================================================
+
+// Rounding functions
+size_t CeilDiv(const size_t x, const size_t y);
+size_t Ceil(const size_t x, const size_t y);
+
+// Returns whether or not 'a' is a multiple of 'b'
+bool IsMultiple(const size_t a, const size_t b);
+
+// =================================================================================================
+
+// Convert the precision enum into bytes, e.g. a double takes up 8 bytes
+size_t GetBytes(const Precision precision);
+
+// Convert the template argument into a precision value
+template <typename T>
+Precision PrecisionValue();
+
+// =================================================================================================
+
+// Returns false is this precision is not supported by the device
+template <typename T>
+bool PrecisionSupported(const Device &device);
+
+// =================================================================================================
+} // namespace clblast
+
+// CLBLAST_UTILITIES_H_
+#endif