2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// =================================================================================================
|
|
|
|
// 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>
|
2017-03-05 11:13:47 +01:00
|
|
|
#include <random>
|
2015-05-30 12:30:43 +02:00
|
|
|
|
2016-11-26 11:42:18 +01:00
|
|
|
#include "clpp11.hpp"
|
2015-05-30 12:30:43 +02:00
|
|
|
#include "clblast.h"
|
2016-05-15 20:13:57 +02:00
|
|
|
#include "clblast_half.h"
|
2016-10-22 15:36:48 +02:00
|
|
|
#include "utilities/clblast_exceptions.hpp"
|
|
|
|
#include "utilities/msvc.hpp"
|
2016-10-10 20:37:45 +02:00
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
namespace clblast {
|
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
// Shorthands for complex data-types
|
|
|
|
using float2 = std::complex<float>;
|
|
|
|
using double2 = std::complex<double>;
|
|
|
|
|
2015-06-20 14:13:54 +02:00
|
|
|
// Khronos OpenCL extensions
|
|
|
|
const std::string kKhronosHalfPrecision = "cl_khr_fp16";
|
|
|
|
const std::string kKhronosDoublePrecision = "cl_khr_fp64";
|
|
|
|
|
2016-04-02 20:58:00 +02:00
|
|
|
// Catched an unknown error
|
|
|
|
constexpr auto kUnknownError = -999;
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
// The routine-specific arguments in string form
|
|
|
|
constexpr auto kArgM = "m";
|
|
|
|
constexpr auto kArgN = "n";
|
|
|
|
constexpr auto kArgK = "k";
|
2015-09-18 15:25:20 +02:00
|
|
|
constexpr auto kArgKL = "kl";
|
|
|
|
constexpr auto kArgKU = "ku";
|
2015-05-30 12:30:43 +02:00
|
|
|
constexpr auto kArgLayout = "layout";
|
|
|
|
constexpr auto kArgATransp = "transA";
|
|
|
|
constexpr auto kArgBTransp = "transB";
|
|
|
|
constexpr auto kArgSide = "side";
|
|
|
|
constexpr auto kArgTriangle = "triangle";
|
2015-07-01 09:39:41 +02:00
|
|
|
constexpr auto kArgDiagonal = "diagonal";
|
2015-05-30 12:30:43 +02:00
|
|
|
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";
|
2015-09-19 17:37:42 +02:00
|
|
|
constexpr auto kArgAPOffset = "offap";
|
2015-09-14 12:28:50 +02:00
|
|
|
constexpr auto kArgDotOffset = "offdot";
|
2016-03-28 23:00:44 +02:00
|
|
|
constexpr auto kArgNrm2Offset = "offnrm2";
|
2016-04-15 03:58:26 +02:00
|
|
|
constexpr auto kArgAsumOffset = "offasum";
|
2016-04-21 06:12:51 +02:00
|
|
|
constexpr auto kArgImaxOffset = "offimax";
|
2015-05-30 12:30:43 +02:00
|
|
|
constexpr auto kArgAlpha = "alpha";
|
|
|
|
constexpr auto kArgBeta = "beta";
|
2017-03-05 16:44:16 +01:00
|
|
|
constexpr auto kArgBatchCount = "batch_num";
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// The tuner-specific arguments in string form
|
|
|
|
constexpr auto kArgFraction = "fraction";
|
|
|
|
|
|
|
|
// The client-specific arguments in string form
|
|
|
|
constexpr auto kArgCompareclblas = "clblas";
|
2016-04-02 20:58:00 +02:00
|
|
|
constexpr auto kArgComparecblas = "cblas";
|
2015-05-30 12:30:43 +02:00
|
|
|
constexpr auto kArgStepSize = "step";
|
|
|
|
constexpr auto kArgNumSteps = "num_steps";
|
|
|
|
constexpr auto kArgNumRuns = "runs";
|
2016-07-06 21:25:55 +02:00
|
|
|
constexpr auto kArgWarmUp = "warm_up";
|
2015-05-30 12:30:43 +02:00
|
|
|
|
2016-07-06 21:25:55 +02:00
|
|
|
// The test-specific arguments in string form
|
2015-06-20 13:33:50 +02:00
|
|
|
constexpr auto kArgFullTest = "full_test";
|
2016-04-27 14:38:30 +02:00
|
|
|
constexpr auto kArgVerbose = "verbose";
|
2015-06-20 13:33:50 +02:00
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// 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";
|
|
|
|
|
|
|
|
// =================================================================================================
|
|
|
|
|
2017-03-04 15:21:33 +01:00
|
|
|
// Converts a regular or complex type to it's base type (e.g. float2 to float)
|
|
|
|
template <typename T> struct BaseType { using Type = T; };
|
|
|
|
template <> struct BaseType<float2> { using Type = float; };
|
|
|
|
template <> struct BaseType<double2> { using Type = double; };
|
|
|
|
|
|
|
|
// =================================================================================================
|
|
|
|
|
2016-05-15 20:13:57 +02:00
|
|
|
// Returns a scalar with a default value
|
2017-02-25 12:23:04 +01:00
|
|
|
template <typename T> T GetScalar();
|
2016-05-15 20:13:57 +02:00
|
|
|
|
2017-02-25 12:23:04 +01:00
|
|
|
// Fixed value scalars
|
|
|
|
template <typename T> T ConstantZero();
|
|
|
|
template <typename T> T ConstantOne();
|
|
|
|
template <typename T> T ConstantNegOne();
|
2017-03-04 15:21:33 +01:00
|
|
|
template <typename T> T Constant(const double val);
|
2017-02-25 12:23:04 +01:00
|
|
|
template <typename T> T SmallConstant();
|
2017-01-18 21:29:59 +01:00
|
|
|
|
2017-03-04 15:21:33 +01:00
|
|
|
// Returns the absolute value of a scalar (modulus in case of complex numbers)
|
|
|
|
template <typename T> typename BaseType<T>::Type AbsoluteValue(const T value);
|
2017-02-25 12:23:04 +01:00
|
|
|
|
|
|
|
// Returns whether a scalar is close to zero
|
|
|
|
template <typename T> bool IsCloseToZero(const T value);
|
2017-02-19 17:43:26 +01:00
|
|
|
|
2016-05-15 20:13:57 +02:00
|
|
|
// =================================================================================================
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// Structure containing all possible arguments for test clients, including their default values
|
|
|
|
template <typename T>
|
|
|
|
struct Arguments {
|
|
|
|
// Routine-specific arguments
|
2015-09-18 15:25:20 +02:00
|
|
|
size_t m = 1;
|
|
|
|
size_t n = 1;
|
|
|
|
size_t k = 1;
|
|
|
|
size_t ku = 1;
|
|
|
|
size_t kl = 1;
|
2015-05-30 12:30:43 +02:00
|
|
|
Layout layout = Layout::kRowMajor;
|
|
|
|
Transpose a_transpose = Transpose::kNo;
|
|
|
|
Transpose b_transpose = Transpose::kNo;
|
|
|
|
Side side = Side::kLeft;
|
|
|
|
Triangle triangle = Triangle::kUpper;
|
2015-07-01 09:39:41 +02:00
|
|
|
Diagonal diagonal = Diagonal::kUnit;
|
2015-05-30 12:30:43 +02:00
|
|
|
size_t x_inc = 1;
|
|
|
|
size_t y_inc = 1;
|
|
|
|
size_t x_offset = 0;
|
|
|
|
size_t y_offset = 0;
|
2015-09-18 15:25:20 +02:00
|
|
|
size_t a_ld = 1;
|
|
|
|
size_t b_ld = 1;
|
|
|
|
size_t c_ld = 1;
|
2015-05-30 12:30:43 +02:00
|
|
|
size_t a_offset = 0;
|
|
|
|
size_t b_offset = 0;
|
|
|
|
size_t c_offset = 0;
|
2015-09-19 17:37:42 +02:00
|
|
|
size_t ap_offset = 0;
|
2015-09-14 12:28:50 +02:00
|
|
|
size_t dot_offset = 0;
|
2016-03-28 23:00:44 +02:00
|
|
|
size_t nrm2_offset = 0;
|
2016-04-15 03:58:26 +02:00
|
|
|
size_t asum_offset = 0;
|
2016-04-21 06:12:51 +02:00
|
|
|
size_t imax_offset = 0;
|
2016-05-15 20:13:57 +02:00
|
|
|
T alpha = ConstantOne<T>();
|
|
|
|
T beta = ConstantOne<T>();
|
2017-03-08 20:10:20 +01:00
|
|
|
// Batch-specific arguments
|
2017-03-05 15:04:16 +01:00
|
|
|
size_t batch_count = 1;
|
2017-03-08 20:10:20 +01:00
|
|
|
std::vector<size_t> x_offsets = {0};
|
|
|
|
std::vector<size_t> y_offsets = {0};
|
|
|
|
std::vector<size_t> a_offsets = {0};
|
|
|
|
std::vector<size_t> b_offsets = {0};
|
|
|
|
std::vector<size_t> c_offsets = {0};
|
2017-03-10 20:49:59 +01:00
|
|
|
std::vector<T> alphas = {ConstantOne<T>()};
|
|
|
|
std::vector<T> betas = {ConstantOne<T>()};
|
2017-03-05 15:04:16 +01:00
|
|
|
// Sizes
|
2015-06-28 15:37:38 +02:00
|
|
|
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;
|
2015-09-19 17:37:42 +02:00
|
|
|
size_t ap_size = 1;
|
2016-03-28 23:00:44 +02:00
|
|
|
size_t scalar_size = 1;
|
2015-05-30 12:30:43 +02:00
|
|
|
// Tuner-specific arguments
|
|
|
|
double fraction = 1.0;
|
|
|
|
// Client-specific arguments
|
2016-02-06 10:53:44 +01:00
|
|
|
int compare_clblas = 1;
|
2016-04-02 20:58:00 +02:00
|
|
|
int compare_cblas = 1;
|
2015-05-30 12:30:43 +02:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
2015-06-28 15:37:38 +02:00
|
|
|
// Structure containing all possible buffers for test clients
|
2015-07-27 07:18:06 +02:00
|
|
|
template <typename T>
|
2015-06-28 15:37:38 +02:00
|
|
|
struct Buffers {
|
2015-07-27 07:18:06 +02:00
|
|
|
Buffer<T> x_vec;
|
|
|
|
Buffer<T> y_vec;
|
|
|
|
Buffer<T> a_mat;
|
|
|
|
Buffer<T> b_mat;
|
|
|
|
Buffer<T> c_mat;
|
2015-09-19 17:37:42 +02:00
|
|
|
Buffer<T> ap_mat;
|
2016-03-28 23:00:44 +02:00
|
|
|
Buffer<T> scalar;
|
2015-06-28 15:37:38 +02:00
|
|
|
};
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
|
|
// =================================================================================================
|
|
|
|
|
2016-11-27 11:00:29 +01:00
|
|
|
// Parses command-line and environmental-variable arguments into a std::vector of strings
|
|
|
|
std::vector<std::string> RetrieveCommandLineArguments(int argc, char *argv[]);
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// Helper for the function "GetArgument"
|
|
|
|
template <typename T>
|
|
|
|
T ConvertArgument(const char* value);
|
|
|
|
|
2016-07-02 01:38:48 +02:00
|
|
|
// Variant of "ConvertArgument" with default values
|
|
|
|
template <typename T>
|
|
|
|
T ConvertArgument(const char* value, T default_value);
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// Basic argument parser, matching patterns in the form of "-option value" and "--option value"
|
|
|
|
template <typename T>
|
2016-11-27 11:00:29 +01:00
|
|
|
T GetArgument(const std::vector<std::string> &arguments, std::string &help,
|
2015-05-30 12:30:43 +02:00
|
|
|
const std::string &option, const T default_value);
|
|
|
|
|
|
|
|
// Returns the precision only
|
2016-11-27 11:00:29 +01:00
|
|
|
Precision GetPrecision(const std::vector<std::string> &arguments,
|
2016-02-20 14:41:53 +01:00
|
|
|
const Precision default_precision = Precision::kSingle);
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// As in "GetArgument", but now only checks whether an argument is given or not
|
2016-11-27 11:00:29 +01:00
|
|
|
bool CheckArgument(const std::vector<std::string> &arguments, std::string &help, const std::string &option);
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
// Returns a random number to be used as a seed
|
|
|
|
unsigned int GetRandomSeed();
|
|
|
|
|
2015-06-20 10:58:21 +02:00
|
|
|
// Test/example data lower and upper limit
|
|
|
|
constexpr auto kTestDataLowerLimit = -2.0;
|
|
|
|
constexpr auto kTestDataUpperLimit = 2.0;
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// Populates a vector with random data
|
|
|
|
template <typename T>
|
2017-03-05 11:13:47 +01:00
|
|
|
void PopulateVector(std::vector<T> &vector, std::mt19937 &mt, std::uniform_real_distribution<double> &dist);
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// =================================================================================================
|
|
|
|
|
2016-05-26 23:36:19 +02:00
|
|
|
// 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);
|
|
|
|
|
2016-07-10 20:32:01 +02:00
|
|
|
// Converts a 'real' value to a 'real argument' value to be passed to a kernel. Normally there is
|
|
|
|
// no conversion, but half-precision is not supported as kernel argument so it is converted to float.
|
|
|
|
template <typename T> struct RealArg { using Type = T; };
|
|
|
|
template <> struct RealArg<half> { using Type = float; };
|
|
|
|
template <typename T> typename RealArg<T>::Type GetRealArg(const T value);
|
|
|
|
|
2016-05-26 23:36:19 +02:00
|
|
|
// =================================================================================================
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// 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);
|
|
|
|
|
2016-06-17 14:30:37 +02:00
|
|
|
// Convert the template argument into a precision value
|
|
|
|
template <typename T>
|
|
|
|
Precision PrecisionValue();
|
|
|
|
|
2015-08-19 19:34:29 +02:00
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
// Returns false is this precision is not supported by the device
|
|
|
|
template <typename T>
|
|
|
|
bool PrecisionSupported(const Device &device);
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// =================================================================================================
|
|
|
|
} // namespace clblast
|
|
|
|
|
|
|
|
// CLBLAST_UTILITIES_H_
|
|
|
|
#endif
|