mirror of
https://github.com/CNugteren/CLBlast.git
synced 2024-08-20 20:12:26 +02:00
Merge pull request #5 from CNugteren/improved_testing
Improved testing infrastructure
This commit is contained in:
commit
e19893ff15
15
CHANGELOG
15
CHANGELOG
|
@ -1,17 +1,18 @@
|
||||||
|
|
||||||
Development version (next release)
|
Development version (next release)
|
||||||
- Added support for complex conjugate transpose
|
- Added support for complex conjugate transpose
|
||||||
- Some host-code performance improvements
|
- Several host-code performance improvements
|
||||||
|
- Improved testing infrastructure and coverage
|
||||||
- Added level-2 routines:
|
- Added level-2 routines:
|
||||||
SGEMV/DGEMV/CGEMV/ZGEMV
|
* SGEMV/DGEMV/CGEMV/ZGEMV
|
||||||
- Added level-3 routines:
|
- Added level-3 routines:
|
||||||
CGEMM/ZGEMM
|
* CGEMM/ZGEMM
|
||||||
CSYMM/ZSYMM
|
* CSYMM/ZSYMM
|
||||||
|
|
||||||
Version 0.1.0
|
Version 0.1.0
|
||||||
- Initial preview version release to GitHub
|
- Initial preview version release to GitHub
|
||||||
- Supported level-1 routines:
|
- Supported level-1 routines:
|
||||||
SAXPY/DAXPY/CAXPY/ZAXPY
|
* SAXPY/DAXPY/CAXPY/ZAXPY
|
||||||
- Supported level-3 routines:
|
- Supported level-3 routines:
|
||||||
SGEMM/DGEMM
|
* SGEMM/DGEMM
|
||||||
SSYMM/DSYMM
|
* SSYMM/DSYMM
|
||||||
|
|
|
@ -225,5 +225,4 @@ To-do list before release of version 1.0
|
||||||
- Further reduce the likelihood of crashes:
|
- Further reduce the likelihood of crashes:
|
||||||
* Add checks for proper command-line arguments in the tuner, tester and client
|
* Add checks for proper command-line arguments in the tuner, tester and client
|
||||||
* Add checks for valid database parameters
|
* Add checks for valid database parameters
|
||||||
* Distinguish between short (smoke) and long tests
|
|
||||||
* Test in multi-threaded environments
|
* Test in multi-threaded environments
|
||||||
|
|
|
@ -29,10 +29,6 @@ namespace clblast {
|
||||||
class Routine {
|
class Routine {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Khronos OpenCL extensions
|
|
||||||
const std::string kKhronosHalfPrecision = "cl_khr_fp16";
|
|
||||||
const std::string kKhronosDoublePrecision = "cl_khr_fp64";
|
|
||||||
|
|
||||||
// The cache of compiled OpenCL programs, along with some meta-data
|
// The cache of compiled OpenCL programs, along with some meta-data
|
||||||
struct ProgramCache {
|
struct ProgramCache {
|
||||||
Program program;
|
Program program;
|
||||||
|
|
|
@ -31,6 +31,10 @@ namespace clblast {
|
||||||
using float2 = std::complex<float>;
|
using float2 = std::complex<float>;
|
||||||
using double2 = std::complex<double>;
|
using double2 = std::complex<double>;
|
||||||
|
|
||||||
|
// Khronos OpenCL extensions
|
||||||
|
const std::string kKhronosHalfPrecision = "cl_khr_fp16";
|
||||||
|
const std::string kKhronosDoublePrecision = "cl_khr_fp64";
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
|
||||||
// The routine-specific arguments in string form
|
// The routine-specific arguments in string form
|
||||||
|
@ -64,6 +68,9 @@ constexpr auto kArgStepSize = "step";
|
||||||
constexpr auto kArgNumSteps = "num_steps";
|
constexpr auto kArgNumSteps = "num_steps";
|
||||||
constexpr auto kArgNumRuns = "runs";
|
constexpr auto kArgNumRuns = "runs";
|
||||||
|
|
||||||
|
// The client-specific arguments in string form
|
||||||
|
constexpr auto kArgFullTest = "full_test";
|
||||||
|
|
||||||
// The common arguments in string form
|
// The common arguments in string form
|
||||||
constexpr auto kArgPlatform = "platform";
|
constexpr auto kArgPlatform = "platform";
|
||||||
constexpr auto kArgDevice = "device";
|
constexpr auto kArgDevice = "device";
|
||||||
|
@ -105,6 +112,8 @@ struct Arguments {
|
||||||
size_t step = 1;
|
size_t step = 1;
|
||||||
size_t num_steps = 0;
|
size_t num_steps = 0;
|
||||||
size_t num_runs = 10;
|
size_t num_runs = 10;
|
||||||
|
// Tester-specific arguments
|
||||||
|
bool full_test = false;
|
||||||
// Common arguments
|
// Common arguments
|
||||||
size_t platform_id = 0;
|
size_t platform_id = 0;
|
||||||
size_t device_id = 0;
|
size_t device_id = 0;
|
||||||
|
@ -143,6 +152,10 @@ bool CheckArgument(const int argc, char *argv[], std::string &help, const std::s
|
||||||
// Returns a random number to be used as a seed
|
// Returns a random number to be used as a seed
|
||||||
unsigned int GetRandomSeed();
|
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
|
// Populates a vector with random data
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PopulateVector(std::vector<T> &vector);
|
void PopulateVector(std::vector<T> &vector);
|
||||||
|
|
|
@ -159,16 +159,21 @@ Precision GetPrecision(const int argc, char *argv[]) {
|
||||||
bool CheckArgument(const int argc, char *argv[], std::string &help,
|
bool CheckArgument(const int argc, char *argv[], std::string &help,
|
||||||
const std::string &option) {
|
const std::string &option) {
|
||||||
|
|
||||||
// Updates the help message
|
|
||||||
help += " -"+option+"\n";
|
|
||||||
|
|
||||||
// Parses the argument. Note that this supports both the given option (e.g. -device) and one with
|
// Parses the argument. Note that this supports both the given option (e.g. -device) and one with
|
||||||
// an extra dash in front (e.g. --device).
|
// an extra dash in front (e.g. --device).
|
||||||
|
auto return_value = false;
|
||||||
for (int c=0; c<argc; ++c) {
|
for (int c=0; c<argc; ++c) {
|
||||||
auto item = std::string{argv[c]};
|
auto item = std::string{argv[c]};
|
||||||
if (item.compare("-"+option) == 0 || item.compare("--"+option) == 0) { ++c; return true; }
|
if (item.compare("-"+option) == 0 || item.compare("--"+option) == 0) {
|
||||||
|
++c;
|
||||||
|
return_value = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
|
// Updates the help message and returns
|
||||||
|
help += " -"+option+" ";
|
||||||
|
help += (return_value) ? "[true]\n" : "[false]\n";
|
||||||
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
@ -182,8 +187,10 @@ unsigned int GetRandomSeed() {
|
||||||
// Create a random number generator and populates a vector with samples from a random distribution
|
// Create a random number generator and populates a vector with samples from a random distribution
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void PopulateVector(std::vector<T> &vector) {
|
void PopulateVector(std::vector<T> &vector) {
|
||||||
|
auto lower_limit = static_cast<T>(kTestDataLowerLimit);
|
||||||
|
auto upper_limit = static_cast<T>(kTestDataUpperLimit);
|
||||||
std::mt19937 mt(GetRandomSeed());
|
std::mt19937 mt(GetRandomSeed());
|
||||||
std::uniform_real_distribution<T> dist(static_cast<T>(-2.0), static_cast<T>(2.0));
|
std::uniform_real_distribution<T> dist(lower_limit, upper_limit);
|
||||||
for (auto &element: vector) { element = dist(mt); }
|
for (auto &element: vector) { element = dist(mt); }
|
||||||
}
|
}
|
||||||
template void PopulateVector<float>(std::vector<float>&);
|
template void PopulateVector<float>(std::vector<float>&);
|
||||||
|
@ -192,14 +199,18 @@ template void PopulateVector<double>(std::vector<double>&);
|
||||||
// Specialized versions of the above for complex data-types
|
// Specialized versions of the above for complex data-types
|
||||||
template <>
|
template <>
|
||||||
void PopulateVector(std::vector<float2> &vector) {
|
void PopulateVector(std::vector<float2> &vector) {
|
||||||
|
auto lower_limit = static_cast<float>(kTestDataLowerLimit);
|
||||||
|
auto upper_limit = static_cast<float>(kTestDataUpperLimit);
|
||||||
std::mt19937 mt(GetRandomSeed());
|
std::mt19937 mt(GetRandomSeed());
|
||||||
std::uniform_real_distribution<float> dist(-2.0f, 2.0f);
|
std::uniform_real_distribution<float> dist(lower_limit, upper_limit);
|
||||||
for (auto &element: vector) { element.real(dist(mt)); element.imag(dist(mt)); }
|
for (auto &element: vector) { element.real(dist(mt)); element.imag(dist(mt)); }
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
void PopulateVector(std::vector<double2> &vector) {
|
void PopulateVector(std::vector<double2> &vector) {
|
||||||
|
auto lower_limit = static_cast<double>(kTestDataLowerLimit);
|
||||||
|
auto upper_limit = static_cast<double>(kTestDataUpperLimit);
|
||||||
std::mt19937 mt(GetRandomSeed());
|
std::mt19937 mt(GetRandomSeed());
|
||||||
std::uniform_real_distribution<double> dist(-2.0, 2.0);
|
std::uniform_real_distribution<double> dist(lower_limit, upper_limit);
|
||||||
for (auto &element: vector) { element.real(dist(mt)); element.imag(dist(mt)); }
|
for (auto &element: vector) { element.real(dist(mt)); element.imag(dist(mt)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,19 +46,13 @@ void XaxpyTest(int argc, char *argv[], const bool silent, const std::string &nam
|
||||||
return static_cast<StatusCode>(status);
|
return static_cast<StatusCode>(status);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selects the platform and device on which to test (command-line options)
|
// Initializes the arguments relevant for this routine
|
||||||
auto help = std::string{"Options given/available:\n"};
|
|
||||||
const auto platform_id = GetArgument(argc, argv, help, kArgPlatform, size_t{0});
|
|
||||||
const auto device_id = GetArgument(argc, argv, help, kArgDevice, size_t{0});
|
|
||||||
if (!silent) { fprintf(stdout, "\n* %s\n", help.c_str()); }
|
|
||||||
|
|
||||||
// Initializes the other arguments relevant for this routine
|
|
||||||
auto args = Arguments<T>{};
|
auto args = Arguments<T>{};
|
||||||
const auto options = std::vector<std::string>{kArgN, kArgXInc, kArgYInc,
|
const auto options = std::vector<std::string>{kArgN, kArgXInc, kArgYInc,
|
||||||
kArgXOffset, kArgYOffset, kArgAlpha};
|
kArgXOffset, kArgYOffset, kArgAlpha};
|
||||||
|
|
||||||
// Creates a tester
|
// Creates a tester
|
||||||
TestXY<T> tester{platform_id, device_id, name, options, clblast_lambda, clblas_lambda};
|
TestXY<T> tester{argc, argv, silent, name, options, clblast_lambda, clblas_lambda};
|
||||||
|
|
||||||
// Runs the tests
|
// Runs the tests
|
||||||
const auto case_name = "default";
|
const auto case_name = "default";
|
||||||
|
|
|
@ -56,13 +56,7 @@ void XgemmTest(int argc, char *argv[], const bool silent, const std::string &nam
|
||||||
return static_cast<StatusCode>(status);
|
return static_cast<StatusCode>(status);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selects the platform and device on which to test (command-line options)
|
// Initializes the arguments relevant for this routine
|
||||||
auto help = std::string{"Options given/available:\n"};
|
|
||||||
const auto platform_id = GetArgument(argc, argv, help, kArgPlatform, size_t{0});
|
|
||||||
const auto device_id = GetArgument(argc, argv, help, kArgDevice, size_t{0});
|
|
||||||
if (!silent) { fprintf(stdout, "\n* %s\n", help.c_str()); }
|
|
||||||
|
|
||||||
// Initializes the other arguments relevant for this routine
|
|
||||||
auto args = Arguments<T>{};
|
auto args = Arguments<T>{};
|
||||||
const auto options = std::vector<std::string>{kArgM, kArgN, kArgK, kArgLayout,
|
const auto options = std::vector<std::string>{kArgM, kArgN, kArgK, kArgLayout,
|
||||||
kArgATransp, kArgBTransp,
|
kArgATransp, kArgBTransp,
|
||||||
|
@ -70,7 +64,7 @@ void XgemmTest(int argc, char *argv[], const bool silent, const std::string &nam
|
||||||
kArgAOffset, kArgBOffset, kArgCOffset};
|
kArgAOffset, kArgBOffset, kArgCOffset};
|
||||||
|
|
||||||
// Creates a tester
|
// Creates a tester
|
||||||
TestABC<T> tester{platform_id, device_id, name, options, clblast_lambda, clblas_lambda};
|
TestABC<T> tester{argc, argv, silent, name, options, clblast_lambda, clblas_lambda};
|
||||||
|
|
||||||
// Loops over the test-cases from a data-layout point of view
|
// Loops over the test-cases from a data-layout point of view
|
||||||
for (auto &layout: tester.kLayouts) {
|
for (auto &layout: tester.kLayouts) {
|
||||||
|
|
|
@ -50,20 +50,14 @@ void XgemvTest(int argc, char *argv[], const bool silent, const std::string &nam
|
||||||
return static_cast<StatusCode>(status);
|
return static_cast<StatusCode>(status);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selects the platform and device on which to test (command-line options)
|
// Initializes the arguments relevant for this routine
|
||||||
auto help = std::string{"Options given/available:\n"};
|
|
||||||
const auto platform_id = GetArgument(argc, argv, help, kArgPlatform, size_t{0});
|
|
||||||
const auto device_id = GetArgument(argc, argv, help, kArgDevice, size_t{0});
|
|
||||||
if (!silent) { fprintf(stdout, "\n* %s\n", help.c_str()); }
|
|
||||||
|
|
||||||
// Initializes the other arguments relevant for this routine
|
|
||||||
auto args = Arguments<T>{};
|
auto args = Arguments<T>{};
|
||||||
const auto options = std::vector<std::string>{kArgM, kArgN, kArgLayout, kArgATransp,
|
const auto options = std::vector<std::string>{kArgM, kArgN, kArgLayout, kArgATransp,
|
||||||
kArgALeadDim, kArgXInc, kArgYInc,
|
kArgALeadDim, kArgXInc, kArgYInc,
|
||||||
kArgAOffset, kArgXOffset, kArgYOffset};
|
kArgAOffset, kArgXOffset, kArgYOffset};
|
||||||
|
|
||||||
// Creates a tester
|
// Creates a tester
|
||||||
TestAXY<T> tester{platform_id, device_id, name, options, clblast_lambda, clblas_lambda};
|
TestAXY<T> tester{argc, argv, silent, name, options, clblast_lambda, clblas_lambda};
|
||||||
|
|
||||||
// Loops over the test-cases from a data-layout point of view
|
// Loops over the test-cases from a data-layout point of view
|
||||||
for (auto &layout: tester.kLayouts) {
|
for (auto &layout: tester.kLayouts) {
|
||||||
|
|
|
@ -56,13 +56,7 @@ void XsymmTest(int argc, char *argv[], const bool silent, const std::string &nam
|
||||||
return static_cast<StatusCode>(status);
|
return static_cast<StatusCode>(status);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selects the platform and device on which to test (command-line options)
|
// Initializes the arguments relevant for this routine
|
||||||
auto help = std::string{"Options given/available:\n"};
|
|
||||||
const auto platform_id = GetArgument(argc, argv, help, kArgPlatform, size_t{0});
|
|
||||||
const auto device_id = GetArgument(argc, argv, help, kArgDevice, size_t{0});
|
|
||||||
if (!silent) { fprintf(stdout, "\n* %s\n", help.c_str()); }
|
|
||||||
|
|
||||||
// Initializes the other arguments relevant for this routine
|
|
||||||
auto args = Arguments<T>{};
|
auto args = Arguments<T>{};
|
||||||
const auto options = std::vector<std::string>{kArgM, kArgN, kArgLayout,
|
const auto options = std::vector<std::string>{kArgM, kArgN, kArgLayout,
|
||||||
kArgSide, kArgTriangle,
|
kArgSide, kArgTriangle,
|
||||||
|
@ -70,7 +64,7 @@ void XsymmTest(int argc, char *argv[], const bool silent, const std::string &nam
|
||||||
kArgAOffset, kArgBOffset, kArgCOffset};
|
kArgAOffset, kArgBOffset, kArgCOffset};
|
||||||
|
|
||||||
// Creates a tester
|
// Creates a tester
|
||||||
TestABC<T> tester{platform_id, device_id, name, options, clblast_lambda, clblas_lambda};
|
TestABC<T> tester{argc, argv, silent, name, options, clblast_lambda, clblas_lambda};
|
||||||
|
|
||||||
// Loops over the test-cases from a data-layout point of view
|
// Loops over the test-cases from a data-layout point of view
|
||||||
for (auto &layout: tester.kLayouts) {
|
for (auto &layout: tester.kLayouts) {
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace clblast {
|
||||||
|
|
||||||
// Constructor, initializes the base class tester and input data
|
// Constructor, initializes the base class tester and input data
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TestABC<T>::TestABC(const size_t platform_id, const size_t device_id,
|
TestABC<T>::TestABC(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options,
|
const std::string &name, const std::vector<std::string> &options,
|
||||||
const Routine clblast_lambda, const Routine clblas_lambda):
|
const Routine clblast_lambda, const Routine clblas_lambda):
|
||||||
Tester<T>{platform_id, device_id, name, options},
|
Tester<T>{argc, argv, silent, name, options},
|
||||||
clblast_lambda_(clblast_lambda),
|
clblast_lambda_(clblast_lambda),
|
||||||
clblas_lambda_(clblas_lambda) {
|
clblas_lambda_(clblas_lambda) {
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ TestABC<T>::TestABC(const size_t platform_id, const size_t device_id,
|
||||||
// Tests the routine for a wide variety of parameters
|
// Tests the routine for a wide variety of parameters
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestABC<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
void TestABC<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
|
if (!PrecisionSupported()) { return; }
|
||||||
TestStart("regular behaviour", name);
|
TestStart("regular behaviour", name);
|
||||||
|
|
||||||
// Computes whether or not the matrices are transposed. Note that we assume a default of
|
// Computes whether or not the matrices are transposed. Note that we assume a default of
|
||||||
|
@ -133,7 +134,7 @@ void TestABC<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
auto index = (args.layout == Layout::kRowMajor) ?
|
auto index = (args.layout == Layout::kRowMajor) ?
|
||||||
idm*args.c_ld + idn + args.c_offset:
|
idm*args.c_ld + idn + args.c_offset:
|
||||||
idn*args.c_ld + idm + args.c_offset;
|
idn*args.c_ld + idm + args.c_offset;
|
||||||
if (!TestSimilarity(r_result[index], s_result[index], kErrorMargin)) {
|
if (!TestSimilarity(r_result[index], s_result[index])) {
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,6 +162,7 @@ void TestABC<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
// does not test for results (if any).
|
// does not test for results (if any).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestABC<T>::TestInvalidBufferSizes(Arguments<T> &args, const std::string &name) {
|
void TestABC<T>::TestInvalidBufferSizes(Arguments<T> &args, const std::string &name) {
|
||||||
|
if (!PrecisionSupported()) { return; }
|
||||||
TestStart("invalid buffer sizes", name);
|
TestStart("invalid buffer sizes", name);
|
||||||
|
|
||||||
// Sets example test parameters
|
// Sets example test parameters
|
||||||
|
|
|
@ -31,7 +31,6 @@ class TestABC: public Tester<T> {
|
||||||
// Uses several variables from the Tester class
|
// Uses several variables from the Tester class
|
||||||
using Tester<T>::context_;
|
using Tester<T>::context_;
|
||||||
using Tester<T>::queue_;
|
using Tester<T>::queue_;
|
||||||
using Tester<T>::kErrorMargin;
|
|
||||||
using Tester<T>::kLayouts;
|
using Tester<T>::kLayouts;
|
||||||
using Tester<T>::kTransposes;
|
using Tester<T>::kTransposes;
|
||||||
|
|
||||||
|
@ -42,10 +41,12 @@ class TestABC: public Tester<T> {
|
||||||
using Tester<T>::TestErrorCount;
|
using Tester<T>::TestErrorCount;
|
||||||
using Tester<T>::TestErrorCodes;
|
using Tester<T>::TestErrorCodes;
|
||||||
using Tester<T>::GetExampleScalars;
|
using Tester<T>::GetExampleScalars;
|
||||||
|
using Tester<T>::GetOffsets;
|
||||||
|
using Tester<T>::PrecisionSupported;
|
||||||
|
|
||||||
// Test settings for the regular test. Append to this list in case more tests are required.
|
// Test settings for the regular test. Append to this list in case more tests are required.
|
||||||
const std::vector<size_t> kMatrixDims = { 7, 64 };
|
const std::vector<size_t> kMatrixDims = { 7, 64 };
|
||||||
const std::vector<size_t> kOffsets = { 0 };
|
const std::vector<size_t> kOffsets = GetOffsets();
|
||||||
const std::vector<T> kAlphaValues = GetExampleScalars();
|
const std::vector<T> kAlphaValues = GetExampleScalars();
|
||||||
const std::vector<T> kBetaValues = GetExampleScalars();
|
const std::vector<T> kBetaValues = GetExampleScalars();
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ class TestABC: public Tester<T> {
|
||||||
CommandQueue&)>;
|
CommandQueue&)>;
|
||||||
|
|
||||||
// Constructor, initializes the base class tester and input data
|
// Constructor, initializes the base class tester and input data
|
||||||
TestABC(const size_t platform_id, const size_t device_id,
|
TestABC(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options,
|
const std::string &name, const std::vector<std::string> &options,
|
||||||
const Routine clblast_lambda, const Routine clblas_lambda);
|
const Routine clblast_lambda, const Routine clblas_lambda);
|
||||||
|
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace clblast {
|
||||||
|
|
||||||
// Constructor, initializes the base class tester and input data
|
// Constructor, initializes the base class tester and input data
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TestAXY<T>::TestAXY(const size_t platform_id, const size_t device_id,
|
TestAXY<T>::TestAXY(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options,
|
const std::string &name, const std::vector<std::string> &options,
|
||||||
const Routine clblast_lambda, const Routine clblas_lambda):
|
const Routine clblast_lambda, const Routine clblas_lambda):
|
||||||
Tester<T>{platform_id, device_id, name, options},
|
Tester<T>{argc, argv, silent, name, options},
|
||||||
clblast_lambda_(clblast_lambda),
|
clblast_lambda_(clblast_lambda),
|
||||||
clblas_lambda_(clblas_lambda) {
|
clblas_lambda_(clblas_lambda) {
|
||||||
|
|
||||||
|
@ -47,6 +47,7 @@ TestAXY<T>::TestAXY(const size_t platform_id, const size_t device_id,
|
||||||
// Tests the routine for a wide variety of parameters
|
// Tests the routine for a wide variety of parameters
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestAXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
void TestAXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
|
if (!PrecisionSupported()) { return; }
|
||||||
TestStart("regular behaviour", name);
|
TestStart("regular behaviour", name);
|
||||||
|
|
||||||
// Iterates over the dimension for the matrix and vectors
|
// Iterates over the dimension for the matrix and vectors
|
||||||
|
@ -125,7 +126,7 @@ void TestAXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
auto errors = size_t{0};
|
auto errors = size_t{0};
|
||||||
for (auto idm=size_t{0}; idm<m_real; ++idm) {
|
for (auto idm=size_t{0}; idm<m_real; ++idm) {
|
||||||
auto index = idm*y_inc + y_offset;
|
auto index = idm*y_inc + y_offset;
|
||||||
if (!TestSimilarity(r_result[index], s_result[index], kErrorMargin)) {
|
if (!TestSimilarity(r_result[index], s_result[index])) {
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +152,7 @@ void TestAXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
// does not test for results (if any).
|
// does not test for results (if any).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestAXY<T>::TestInvalidBufferSizes(Arguments<T> &args, const std::string &name) {
|
void TestAXY<T>::TestInvalidBufferSizes(Arguments<T> &args, const std::string &name) {
|
||||||
|
if (!PrecisionSupported()) { return; }
|
||||||
TestStart("invalid buffer sizes", name);
|
TestStart("invalid buffer sizes", name);
|
||||||
|
|
||||||
// Sets example test parameters
|
// Sets example test parameters
|
||||||
|
|
|
@ -31,7 +31,6 @@ class TestAXY: public Tester<T> {
|
||||||
// Uses several variables from the Tester class
|
// Uses several variables from the Tester class
|
||||||
using Tester<T>::context_;
|
using Tester<T>::context_;
|
||||||
using Tester<T>::queue_;
|
using Tester<T>::queue_;
|
||||||
using Tester<T>::kErrorMargin;
|
|
||||||
using Tester<T>::kLayouts;
|
using Tester<T>::kLayouts;
|
||||||
using Tester<T>::kTransposes;
|
using Tester<T>::kTransposes;
|
||||||
|
|
||||||
|
@ -42,10 +41,12 @@ class TestAXY: public Tester<T> {
|
||||||
using Tester<T>::TestErrorCount;
|
using Tester<T>::TestErrorCount;
|
||||||
using Tester<T>::TestErrorCodes;
|
using Tester<T>::TestErrorCodes;
|
||||||
using Tester<T>::GetExampleScalars;
|
using Tester<T>::GetExampleScalars;
|
||||||
|
using Tester<T>::GetOffsets;
|
||||||
|
using Tester<T>::PrecisionSupported;
|
||||||
|
|
||||||
// Test settings for the regular test. Append to this list in case more tests are required.
|
// Test settings for the regular test. Append to this list in case more tests are required.
|
||||||
const std::vector<size_t> kMatrixVectorDims = { 61, 512 };
|
const std::vector<size_t> kMatrixVectorDims = { 61, 512 };
|
||||||
const std::vector<size_t> kOffsets = { 0, 10 };
|
const std::vector<size_t> kOffsets = GetOffsets();
|
||||||
const std::vector<size_t> kIncrements = { 1, 2 };
|
const std::vector<size_t> kIncrements = { 1, 2 };
|
||||||
const std::vector<T> kAlphaValues = GetExampleScalars();
|
const std::vector<T> kAlphaValues = GetExampleScalars();
|
||||||
const std::vector<T> kBetaValues = GetExampleScalars();
|
const std::vector<T> kBetaValues = GetExampleScalars();
|
||||||
|
@ -60,7 +61,7 @@ class TestAXY: public Tester<T> {
|
||||||
CommandQueue&)>;
|
CommandQueue&)>;
|
||||||
|
|
||||||
// Constructor, initializes the base class tester and input data
|
// Constructor, initializes the base class tester and input data
|
||||||
TestAXY(const size_t platform_id, const size_t device_id,
|
TestAXY(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options,
|
const std::string &name, const std::vector<std::string> &options,
|
||||||
const Routine clblast_lambda, const Routine clblas_lambda);
|
const Routine clblast_lambda, const Routine clblas_lambda);
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
namespace clblast {
|
namespace clblast {
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
@ -35,25 +34,41 @@ template <> const std::vector<Transpose> Tester<double2>::kTransposes = {Transpo
|
||||||
// General constructor for all CLBlast testers. It prints out the test header to stdout and sets-up
|
// General constructor for all CLBlast testers. It prints out the test header to stdout and sets-up
|
||||||
// the clBLAS library for reference.
|
// the clBLAS library for reference.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Tester<T>::Tester(const size_t platform_id, const size_t device_id,
|
Tester<T>::Tester(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options):
|
const std::string &name, const std::vector<std::string> &options):
|
||||||
platform_(Platform(platform_id)),
|
help_("Options given/available:\n"),
|
||||||
device_(Device(platform_, kDeviceType, device_id)),
|
platform_(Platform(GetArgument(argc, argv, help_, kArgPlatform, size_t{0}))),
|
||||||
|
device_(Device(platform_, kDeviceType, GetArgument(argc, argv, help_, kArgDevice, size_t{0}))),
|
||||||
context_(Context(device_)),
|
context_(Context(device_)),
|
||||||
queue_(CommandQueue(context_, device_)),
|
queue_(CommandQueue(context_, device_)),
|
||||||
|
full_test_(CheckArgument(argc, argv, help_, kArgFullTest)),
|
||||||
error_log_{},
|
error_log_{},
|
||||||
num_passed_{0},
|
num_passed_{0},
|
||||||
num_skipped_{0},
|
num_skipped_{0},
|
||||||
num_errors_{0},
|
num_failed_{0},
|
||||||
print_count_{0},
|
print_count_{0},
|
||||||
tests_failed_{0},
|
|
||||||
tests_passed_{0},
|
tests_passed_{0},
|
||||||
|
tests_skipped_{0},
|
||||||
|
tests_failed_{0},
|
||||||
options_{options} {
|
options_{options} {
|
||||||
|
|
||||||
|
// Prints the help message (command-line arguments)
|
||||||
|
if (!silent) { fprintf(stdout, "\n* %s\n", help_.c_str()); }
|
||||||
|
|
||||||
// Prints the header
|
// Prints the header
|
||||||
fprintf(stdout, "* Running on OpenCL device '%s'.\n", device_.Name().c_str());
|
fprintf(stdout, "* Running on OpenCL device '%s'.\n", device_.Name().c_str());
|
||||||
fprintf(stdout, "* Starting tests for the %s'%s'%s routine. Legend:\n",
|
fprintf(stdout, "* Starting tests for the %s'%s'%s routine.",
|
||||||
kPrintMessage.c_str(), name.c_str(), kPrintEnd.c_str());
|
kPrintMessage.c_str(), name.c_str(), kPrintEnd.c_str());
|
||||||
|
|
||||||
|
// Checks whether the precision is supported
|
||||||
|
if (!PrecisionSupported()) {
|
||||||
|
fprintf(stdout, "\n* All tests skipped: %sUnsupported precision%s\n",
|
||||||
|
kPrintWarning.c_str(), kPrintEnd.c_str());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prints the legend
|
||||||
|
fprintf(stdout, " Legend:\n");
|
||||||
fprintf(stdout, " %s -> Test produced correct results\n", kSuccessData.c_str());
|
fprintf(stdout, " %s -> Test produced correct results\n", kSuccessData.c_str());
|
||||||
fprintf(stdout, " %s -> Test returned the correct error code\n", kSuccessStatus.c_str());
|
fprintf(stdout, " %s -> Test returned the correct error code\n", kSuccessStatus.c_str());
|
||||||
fprintf(stdout, " %s -> Test produced incorrect results\n", kErrorData.c_str());
|
fprintf(stdout, " %s -> Test produced incorrect results\n", kErrorData.c_str());
|
||||||
|
@ -73,14 +88,13 @@ Tester<T>::Tester(const size_t platform_id, const size_t device_id,
|
||||||
// Destructor prints the summary of the test cases and cleans-up the clBLAS library
|
// Destructor prints the summary of the test cases and cleans-up the clBLAS library
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Tester<T>::~Tester() {
|
Tester<T>::~Tester() {
|
||||||
fprintf(stdout, "* Completed all test-cases for this routine. Results:\n");
|
if (PrecisionSupported()) {
|
||||||
fprintf(stdout, " %lu test(s) succeeded\n", tests_passed_);
|
fprintf(stdout, "* Completed all test-cases for this routine. Results:\n");
|
||||||
if (tests_failed_ != 0) {
|
fprintf(stdout, " %lu test(s) passed\n", tests_passed_);
|
||||||
fprintf(stdout, " %s%lu test(s) failed%s\n",
|
if (tests_skipped_ > 0) { fprintf(stdout, "%s", kPrintWarning.c_str()); }
|
||||||
kPrintError.c_str(), tests_failed_, kPrintEnd.c_str());
|
fprintf(stdout, " %lu test(s) skipped%s\n", tests_skipped_, kPrintEnd.c_str());
|
||||||
}
|
if (tests_failed_ > 0) { fprintf(stdout, "%s", kPrintError.c_str()); }
|
||||||
else {
|
fprintf(stdout, " %lu test(s) failed%s\n", tests_failed_, kPrintEnd.c_str());
|
||||||
fprintf(stdout, " %lu test(s) failed\n", tests_failed_);
|
|
||||||
}
|
}
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
clblasTeardown();
|
clblasTeardown();
|
||||||
|
@ -103,7 +117,7 @@ void Tester<T>::TestStart(const std::string &test_name, const std::string &test_
|
||||||
error_log_.clear();
|
error_log_.clear();
|
||||||
num_passed_ = 0;
|
num_passed_ = 0;
|
||||||
num_skipped_ = 0;
|
num_skipped_ = 0;
|
||||||
num_errors_ = 0;
|
num_failed_ = 0;
|
||||||
print_count_ = 0;
|
print_count_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +126,9 @@ void Tester<T>::TestStart(const std::string &test_name, const std::string &test_
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Tester<T>::TestEnd() {
|
void Tester<T>::TestEnd() {
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
if (error_log_.size() == 0) { tests_passed_++; } else { tests_failed_++; }
|
tests_passed_ += num_passed_;
|
||||||
|
tests_failed_ += num_skipped_;
|
||||||
|
tests_failed_ += num_failed_;
|
||||||
|
|
||||||
// Prints details of all error occurences for these tests
|
// Prints details of all error occurences for these tests
|
||||||
for (auto &entry: error_log_) {
|
for (auto &entry: error_log_) {
|
||||||
|
@ -146,7 +162,7 @@ void Tester<T>::TestEnd() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prints a test summary
|
// Prints a test summary
|
||||||
auto pass_rate = 100*num_passed_ / static_cast<float>(num_passed_ + num_skipped_ + num_errors_);
|
auto pass_rate = 100*num_passed_ / static_cast<float>(num_passed_ + num_skipped_ + num_failed_);
|
||||||
fprintf(stdout, " Pass rate %s%5.1lf%%%s:", kPrintMessage.c_str(), pass_rate, kPrintEnd.c_str());
|
fprintf(stdout, " Pass rate %s%5.1lf%%%s:", kPrintMessage.c_str(), pass_rate, kPrintEnd.c_str());
|
||||||
fprintf(stdout, " %lu passed /", num_passed_);
|
fprintf(stdout, " %lu passed /", num_passed_);
|
||||||
if (num_skipped_ != 0) {
|
if (num_skipped_ != 0) {
|
||||||
|
@ -155,11 +171,11 @@ void Tester<T>::TestEnd() {
|
||||||
else {
|
else {
|
||||||
fprintf(stdout, " %lu skipped /", num_skipped_);
|
fprintf(stdout, " %lu skipped /", num_skipped_);
|
||||||
}
|
}
|
||||||
if (num_errors_ != 0) {
|
if (num_failed_ != 0) {
|
||||||
fprintf(stdout, " %s%lu failed%s\n", kPrintError.c_str(), num_errors_, kPrintEnd.c_str());
|
fprintf(stdout, " %s%lu failed%s\n", kPrintError.c_str(), num_failed_, kPrintEnd.c_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stdout, " %lu failed\n", num_errors_);
|
fprintf(stdout, " %lu failed\n", num_failed_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,34 +184,34 @@ void Tester<T>::TestEnd() {
|
||||||
// Compares two floating point values and returns whether they are within an acceptable error
|
// Compares two floating point values and returns whether they are within an acceptable error
|
||||||
// margin. This replaces GTest's EXPECT_NEAR().
|
// margin. This replaces GTest's EXPECT_NEAR().
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Tester<T>::TestSimilarity(const T val1, const T val2, const double margin) {
|
bool Tester<T>::TestSimilarity(const T val1, const T val2) {
|
||||||
const auto difference = std::fabs(val1 - val2);
|
const auto difference = std::fabs(val1 - val2);
|
||||||
|
|
||||||
// Shortcut, handles infinities
|
// Shortcut, handles infinities
|
||||||
if (val1 == val2) {
|
if (val1 == val2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// The values are zero or both are extremely close to it relative error is less meaningful
|
// The values are zero or very small: the relative error is less meaningful
|
||||||
else if (val1 == 0 || val2 == 0 || difference < std::numeric_limits<T>::min()) {
|
else if (val1 == 0 || val2 == 0 || difference < static_cast<T>(kErrorMarginAbsolute)) {
|
||||||
return difference < (static_cast<T>(margin) * std::numeric_limits<T>::min());
|
return (difference < static_cast<T>(kErrorMarginAbsolute));
|
||||||
}
|
}
|
||||||
// Use relative error
|
// Use relative error
|
||||||
else {
|
else {
|
||||||
return (difference / (std::fabs(val1) + std::fabs(val2))) < static_cast<T>(margin);
|
return (difference / (std::fabs(val1)+std::fabs(val2))) < static_cast<T>(kErrorMarginRelative);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialisations for complex data-types
|
// Specialisations for complex data-types
|
||||||
template <>
|
template <>
|
||||||
bool Tester<float2>::TestSimilarity(const float2 val1, const float2 val2, const double margin) {
|
bool Tester<float2>::TestSimilarity(const float2 val1, const float2 val2) {
|
||||||
auto real = Tester<float>::TestSimilarity(val1.real(), val2.real(), margin);
|
auto real = Tester<float>::TestSimilarity(val1.real(), val2.real());
|
||||||
auto imag = Tester<float>::TestSimilarity(val1.imag(), val2.imag(), margin);
|
auto imag = Tester<float>::TestSimilarity(val1.imag(), val2.imag());
|
||||||
return (real && imag);
|
return (real && imag);
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
bool Tester<double2>::TestSimilarity(const double2 val1, const double2 val2, const double margin) {
|
bool Tester<double2>::TestSimilarity(const double2 val1, const double2 val2) {
|
||||||
auto real = Tester<double>::TestSimilarity(val1.real(), val2.real(), margin);
|
auto real = Tester<double>::TestSimilarity(val1.real(), val2.real());
|
||||||
auto imag = Tester<double>::TestSimilarity(val1.imag(), val2.imag(), margin);
|
auto imag = Tester<double>::TestSimilarity(val1.imag(), val2.imag());
|
||||||
return (real && imag);
|
return (real && imag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,19 +274,43 @@ void Tester<T>::TestErrorCodes(const StatusCode clblas_status, const StatusCode
|
||||||
// routines. This function is specialised for the different data-types.
|
// routines. This function is specialised for the different data-types.
|
||||||
template <>
|
template <>
|
||||||
const std::vector<float> Tester<float>::GetExampleScalars() {
|
const std::vector<float> Tester<float>::GetExampleScalars() {
|
||||||
return {0.0f, 1.0f, 3.14f};
|
if (full_test_) { return {0.0f, 1.0f, 3.14f}; }
|
||||||
|
else { return {3.14f}; }
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
const std::vector<double> Tester<double>::GetExampleScalars() {
|
const std::vector<double> Tester<double>::GetExampleScalars() {
|
||||||
return {0.0, 1.0, 3.14};
|
if (full_test_) { return {0.0, 1.0, 3.14}; }
|
||||||
|
else { return {3.14}; }
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
const std::vector<float2> Tester<float2>::GetExampleScalars() {
|
const std::vector<float2> Tester<float2>::GetExampleScalars() {
|
||||||
return {{0.0f, 0.0f}, {1.0f, 1.3f}, {2.42f, 3.14f}};
|
if (full_test_) { return {{0.0f, 0.0f}, {1.0f, 1.3f}, {2.42f, 3.14f}}; }
|
||||||
|
else { return {{2.42f, 3.14f}}; }
|
||||||
}
|
}
|
||||||
template <>
|
template <>
|
||||||
const std::vector<double2> Tester<double2>::GetExampleScalars() {
|
const std::vector<double2> Tester<double2>::GetExampleScalars() {
|
||||||
return {{0.0, 0.0}, {1.0, 1.3}, {2.42, 3.14}};
|
if (full_test_) { return {{0.0, 0.0}, {1.0, 1.3}, {2.42, 3.14}}; }
|
||||||
|
else { return {{2.42, 3.14}}; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieves the offset values to test with
|
||||||
|
template <typename T>
|
||||||
|
const std::vector<size_t> Tester<T>::GetOffsets() {
|
||||||
|
if (full_test_) { return {0, 10}; }
|
||||||
|
else { return {0}; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// =================================================================================================
|
||||||
|
|
||||||
|
template <> bool Tester<float>::PrecisionSupported() const { return true; }
|
||||||
|
template <> bool Tester<float2>::PrecisionSupported() const { return true; }
|
||||||
|
template <> bool Tester<double>::PrecisionSupported() const {
|
||||||
|
auto extensions = device_.Extensions();
|
||||||
|
return (extensions.find(kKhronosDoublePrecision) == std::string::npos) ? false : true;
|
||||||
|
}
|
||||||
|
template <> bool Tester<double2>::PrecisionSupported() const {
|
||||||
|
auto extensions = device_.Extensions();
|
||||||
|
return (extensions.find(kKhronosDoublePrecision) == std::string::npos) ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
@ -287,7 +327,7 @@ void Tester<T>::ReportSkipped() {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Tester<T>::ReportError(const ErrorLogEntry &error_log_entry) {
|
void Tester<T>::ReportError(const ErrorLogEntry &error_log_entry) {
|
||||||
error_log_.push_back(error_log_entry);
|
error_log_.push_back(error_log_entry);
|
||||||
num_errors_++;
|
num_failed_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
|
|
|
@ -44,7 +44,8 @@ class Tester {
|
||||||
static constexpr auto kStatusError = -1.0f;
|
static constexpr auto kStatusError = -1.0f;
|
||||||
|
|
||||||
// Set the allowed error margin for floating-point comparisons
|
// Set the allowed error margin for floating-point comparisons
|
||||||
static constexpr auto kErrorMargin = 1.0e-2;
|
static constexpr auto kErrorMarginRelative = 1.0e-2;
|
||||||
|
static constexpr auto kErrorMarginAbsolute = 1.0e-10;
|
||||||
|
|
||||||
// Constants holding start and end strings for terminal-output in colour
|
// Constants holding start and end strings for terminal-output in colour
|
||||||
const std::string kPrintError{"\x1b[31m"};
|
const std::string kPrintError{"\x1b[31m"};
|
||||||
|
@ -75,7 +76,7 @@ class Tester {
|
||||||
|
|
||||||
// Creates an instance of the tester, running on a particular OpenCL platform and device. It
|
// Creates an instance of the tester, running on a particular OpenCL platform and device. It
|
||||||
// takes the routine's names as an additional parameter.
|
// takes the routine's names as an additional parameter.
|
||||||
explicit Tester(const size_t platform_id, const size_t device_id,
|
explicit Tester(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options);
|
const std::string &name, const std::vector<std::string> &options);
|
||||||
~Tester();
|
~Tester();
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ class Tester {
|
||||||
void TestEnd();
|
void TestEnd();
|
||||||
|
|
||||||
// Compares two floating point values for similarity. Allows for a certain relative error margin.
|
// Compares two floating point values for similarity. Allows for a certain relative error margin.
|
||||||
static bool TestSimilarity(const T val1, const T val2, const double margin);
|
static bool TestSimilarity(const T val1, const T val2);
|
||||||
|
|
||||||
// Tests either an error count (should be zero) or two error codes (must match)
|
// Tests either an error count (should be zero) or two error codes (must match)
|
||||||
void TestErrorCount(const size_t errors, const size_t size, const Arguments<T> &args);
|
void TestErrorCount(const size_t errors, const size_t size, const Arguments<T> &args);
|
||||||
|
@ -96,6 +97,15 @@ class Tester {
|
||||||
// Retrieves a list of example scalars of the right type
|
// Retrieves a list of example scalars of the right type
|
||||||
const std::vector<T> GetExampleScalars();
|
const std::vector<T> GetExampleScalars();
|
||||||
|
|
||||||
|
// Retrieves a list of offset values to test
|
||||||
|
const std::vector<size_t> GetOffsets();
|
||||||
|
|
||||||
|
// Returns false is this precision is not supported by the device
|
||||||
|
bool PrecisionSupported() const;
|
||||||
|
|
||||||
|
// The help-message
|
||||||
|
std::string help_;
|
||||||
|
|
||||||
// The OpenCL objects (accessible by derived classes)
|
// The OpenCL objects (accessible by derived classes)
|
||||||
Platform platform_;
|
Platform platform_;
|
||||||
Device device_;
|
Device device_;
|
||||||
|
@ -112,18 +122,22 @@ class Tester {
|
||||||
// Prints the error or success symbol to screen
|
// Prints the error or success symbol to screen
|
||||||
void PrintTestResult(const std::string &message);
|
void PrintTestResult(const std::string &message);
|
||||||
|
|
||||||
|
// Whether or not to run the full test-suite or just a smoke test
|
||||||
|
bool full_test_;
|
||||||
|
|
||||||
// Logging and counting occurrences of errors
|
// Logging and counting occurrences of errors
|
||||||
std::vector<ErrorLogEntry> error_log_;
|
std::vector<ErrorLogEntry> error_log_;
|
||||||
size_t num_passed_;
|
size_t num_passed_;
|
||||||
size_t num_skipped_;
|
size_t num_skipped_;
|
||||||
size_t num_errors_;
|
size_t num_failed_;
|
||||||
|
|
||||||
// Counting the amount of errors printed on this row
|
// Counting the amount of errors printed on this row
|
||||||
size_t print_count_;
|
size_t print_count_;
|
||||||
|
|
||||||
// Counting the number of test-cases with and without failures
|
// Counting the number of test-cases with and without failures
|
||||||
size_t tests_failed_;
|
|
||||||
size_t tests_passed_;
|
size_t tests_passed_;
|
||||||
|
size_t tests_skipped_;
|
||||||
|
size_t tests_failed_;
|
||||||
|
|
||||||
// Arguments relevant for a specific routine
|
// Arguments relevant for a specific routine
|
||||||
std::vector<std::string> options_;
|
std::vector<std::string> options_;
|
||||||
|
|
|
@ -20,10 +20,10 @@ namespace clblast {
|
||||||
|
|
||||||
// Constructor, initializes the base class tester and input data
|
// Constructor, initializes the base class tester and input data
|
||||||
template <typename T>
|
template <typename T>
|
||||||
TestXY<T>::TestXY(const size_t platform_id, const size_t device_id,
|
TestXY<T>::TestXY(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options,
|
const std::string &name, const std::vector<std::string> &options,
|
||||||
const Routine clblast_lambda, const Routine clblas_lambda):
|
const Routine clblast_lambda, const Routine clblas_lambda):
|
||||||
Tester<T>{platform_id, device_id, name, options},
|
Tester<T>{argc, argv, silent, name, options},
|
||||||
clblast_lambda_(clblast_lambda),
|
clblast_lambda_(clblast_lambda),
|
||||||
clblas_lambda_(clblas_lambda) {
|
clblas_lambda_(clblas_lambda) {
|
||||||
|
|
||||||
|
@ -44,6 +44,7 @@ TestXY<T>::TestXY(const size_t platform_id, const size_t device_id,
|
||||||
// Tests the routine for a wide variety of parameters
|
// Tests the routine for a wide variety of parameters
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
void TestXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
|
if (!PrecisionSupported()) { return; }
|
||||||
TestStart("regular behaviour", name);
|
TestStart("regular behaviour", name);
|
||||||
|
|
||||||
// Iterates over the vector dimension
|
// Iterates over the vector dimension
|
||||||
|
@ -100,7 +101,7 @@ void TestXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
auto errors = size_t{0};
|
auto errors = size_t{0};
|
||||||
for (auto idn=size_t{0}; idn<n; ++idn) {
|
for (auto idn=size_t{0}; idn<n; ++idn) {
|
||||||
auto index = idn*y_inc + y_offset;
|
auto index = idn*y_inc + y_offset;
|
||||||
if (!TestSimilarity(r_result[index], s_result[index], kErrorMargin)) {
|
if (!TestSimilarity(r_result[index], s_result[index])) {
|
||||||
errors++;
|
errors++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,6 +123,7 @@ void TestXY<T>::TestRegular(Arguments<T> &args, const std::string &name) {
|
||||||
// does not test for results (if any).
|
// does not test for results (if any).
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestXY<T>::TestInvalidBufferSizes(Arguments<T> &args, const std::string &name) {
|
void TestXY<T>::TestInvalidBufferSizes(Arguments<T> &args, const std::string &name) {
|
||||||
|
if (!PrecisionSupported()) { return; }
|
||||||
TestStart("invalid buffer sizes", name);
|
TestStart("invalid buffer sizes", name);
|
||||||
|
|
||||||
// Sets example test parameters
|
// Sets example test parameters
|
||||||
|
|
|
@ -31,7 +31,6 @@ class TestXY: public Tester<T> {
|
||||||
// Uses several variables from the Tester class
|
// Uses several variables from the Tester class
|
||||||
using Tester<T>::context_;
|
using Tester<T>::context_;
|
||||||
using Tester<T>::queue_;
|
using Tester<T>::queue_;
|
||||||
using Tester<T>::kErrorMargin;
|
|
||||||
|
|
||||||
// Uses several helper functions from the Tester class
|
// Uses several helper functions from the Tester class
|
||||||
using Tester<T>::TestStart;
|
using Tester<T>::TestStart;
|
||||||
|
@ -40,11 +39,13 @@ class TestXY: public Tester<T> {
|
||||||
using Tester<T>::TestErrorCount;
|
using Tester<T>::TestErrorCount;
|
||||||
using Tester<T>::TestErrorCodes;
|
using Tester<T>::TestErrorCodes;
|
||||||
using Tester<T>::GetExampleScalars;
|
using Tester<T>::GetExampleScalars;
|
||||||
|
using Tester<T>::GetOffsets;
|
||||||
|
using Tester<T>::PrecisionSupported;
|
||||||
|
|
||||||
// Test settings for the regular test. Append to this list in case more tests are required.
|
// Test settings for the regular test. Append to this list in case more tests are required.
|
||||||
const std::vector<size_t> kVectorDims = { 7, 93, 4096 };
|
const std::vector<size_t> kVectorDims = { 7, 93, 4096 };
|
||||||
const std::vector<size_t> kOffsets = { 0, 10 };
|
const std::vector<size_t> kOffsets = GetOffsets();
|
||||||
const std::vector<size_t> kIncrements = { 1, 2 };
|
const std::vector<size_t> kIncrements = { 1, 2, 7 };
|
||||||
const std::vector<T> kAlphaValues = GetExampleScalars();
|
const std::vector<T> kAlphaValues = GetExampleScalars();
|
||||||
|
|
||||||
// Test settings for the invalid test
|
// Test settings for the invalid test
|
||||||
|
@ -57,7 +58,7 @@ class TestXY: public Tester<T> {
|
||||||
CommandQueue&)>;
|
CommandQueue&)>;
|
||||||
|
|
||||||
// Constructor, initializes the base class tester and input data
|
// Constructor, initializes the base class tester and input data
|
||||||
TestXY(const size_t platform_id, const size_t device_id,
|
TestXY(int argc, char *argv[], const bool silent,
|
||||||
const std::string &name, const std::vector<std::string> &options,
|
const std::string &name, const std::vector<std::string> &options,
|
||||||
const Routine clblast_lambda, const Routine clblas_lambda);
|
const Routine clblast_lambda, const Routine clblas_lambda);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue