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 implements the Tester class, providing a test-framework. GTest was used before, but
|
|
|
|
// was not able to handle certain cases (e.g. template type + parameters). This is its (basic)
|
|
|
|
// custom replacement.
|
2015-07-08 07:21:44 +02:00
|
|
|
// Typename T: the data-type of the routine's memory buffers (==precision)
|
|
|
|
// Typename U: the data-type of the alpha and beta arguments
|
2015-05-30 12:30:43 +02:00
|
|
|
//
|
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
#ifndef CLBLAST_TEST_CORRECTNESS_TESTER_H_
|
|
|
|
#define CLBLAST_TEST_CORRECTNESS_TESTER_H_
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
#include <memory>
|
|
|
|
|
2017-10-15 13:56:19 +02:00
|
|
|
#include "utilities/utilities.hpp"
|
2017-08-12 15:38:17 +02:00
|
|
|
#include "test/test_utilities.hpp"
|
2016-11-26 11:42:18 +01:00
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// The libraries
|
2016-04-02 20:58:00 +02:00
|
|
|
#ifdef CLBLAST_REF_CLBLAS
|
|
|
|
#include <clBLAS.h>
|
|
|
|
#endif
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
namespace clblast {
|
|
|
|
// =================================================================================================
|
|
|
|
|
|
|
|
// See comment at top of file for a description of the class
|
2015-07-08 07:21:44 +02:00
|
|
|
template <typename T, typename U>
|
2015-05-30 12:30:43 +02:00
|
|
|
class Tester {
|
|
|
|
public:
|
|
|
|
|
|
|
|
// Maximum number of test results printed on a single line
|
2016-10-18 10:19:03 +02:00
|
|
|
static const size_t kResultsPerLine;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// Error percentage is not applicable: error was caused by an incorrect status
|
2016-10-18 10:19:03 +02:00
|
|
|
static const float kStatusError;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// Constants holding start and end strings for terminal-output in colour
|
2016-10-18 10:19:03 +02:00
|
|
|
static const std::string kPrintError;
|
|
|
|
static const std::string kPrintSuccess;
|
|
|
|
static const std::string kPrintWarning;
|
|
|
|
static const std::string kPrintMessage;
|
|
|
|
static const std::string kPrintEnd;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// Sets the output error coding
|
2016-10-18 10:19:03 +02:00
|
|
|
static const std::string kSuccessData;
|
|
|
|
static const std::string kSuccessStatus;
|
|
|
|
static const std::string kErrorData;
|
|
|
|
static const std::string kErrorStatus;
|
|
|
|
static const std::string kSkippedCompilation;
|
|
|
|
static const std::string kUnsupportedPrecision;
|
|
|
|
static const std::string kUnsupportedReference;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// This structure combines the above log-entry with a status code an error percentage
|
|
|
|
struct ErrorLogEntry {
|
|
|
|
StatusCode status_expect;
|
|
|
|
StatusCode status_found;
|
|
|
|
float error_percentage;
|
2015-07-08 07:21:44 +02:00
|
|
|
Arguments<U> args;
|
2015-05-30 12:30:43 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Creates an instance of the tester, running on a particular OpenCL platform and device. It
|
|
|
|
// takes the routine's names as an additional parameter.
|
2016-11-27 11:00:29 +01:00
|
|
|
explicit Tester(const std::vector<std::string> &arguments, const bool silent,
|
2015-05-30 12:30:43 +02:00
|
|
|
const std::string &name, const std::vector<std::string> &options);
|
|
|
|
~Tester();
|
|
|
|
|
|
|
|
// These methods start and end a test-case. Within a test-case, multiple tests can be run.
|
|
|
|
void TestStart(const std::string &test_name, const std::string &test_configuration);
|
|
|
|
void TestEnd();
|
|
|
|
|
|
|
|
// Tests either an error count (should be zero) or two error codes (must match)
|
2015-07-08 07:21:44 +02:00
|
|
|
void TestErrorCount(const size_t errors, const size_t size, const Arguments<U> &args);
|
2015-05-30 12:30:43 +02:00
|
|
|
void TestErrorCodes(const StatusCode clblas_status, const StatusCode clblast_status,
|
2015-07-08 07:21:44 +02:00
|
|
|
const Arguments<U> &args);
|
2015-05-30 12:30:43 +02:00
|
|
|
|
2016-06-02 16:24:22 +02:00
|
|
|
// Returns the number of failed tests
|
|
|
|
size_t NumFailedTests() const { return tests_failed_; }
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
protected:
|
|
|
|
|
2015-06-20 11:26:01 +02:00
|
|
|
// The help-message
|
|
|
|
std::string help_;
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// The OpenCL objects (accessible by derived classes)
|
|
|
|
Platform platform_;
|
|
|
|
Device device_;
|
|
|
|
Context context_;
|
2015-07-27 07:18:06 +02:00
|
|
|
Queue queue_;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
2015-07-08 07:21:44 +02:00
|
|
|
// Whether or not to run the full test-suite or just a smoke test
|
2016-04-02 20:58:00 +02:00
|
|
|
const bool full_test_;
|
2015-07-08 07:21:44 +02:00
|
|
|
|
2016-04-27 14:38:30 +02:00
|
|
|
// Whether or not to print extra information when testing
|
|
|
|
const bool verbose_;
|
|
|
|
|
2015-07-08 07:21:44 +02:00
|
|
|
// Retrieves the offset values to test with
|
|
|
|
const std::vector<size_t> GetOffsets() const;
|
|
|
|
|
2016-05-30 20:07:09 +02:00
|
|
|
// Retrieves the list of options as a string
|
2016-06-06 12:20:42 +02:00
|
|
|
std::string GetOptionsString(const Arguments<U> &args); // for regular tests
|
|
|
|
std::string GetSizesString(const Arguments<U> &args); // for invalid buffer sizes
|
2016-05-30 20:07:09 +02:00
|
|
|
|
2016-05-07 12:22:06 +02:00
|
|
|
// Testing against reference implementations
|
|
|
|
int compare_cblas_;
|
|
|
|
int compare_clblas_;
|
2017-04-02 18:06:15 +02:00
|
|
|
int compare_cublas_;
|
2016-05-07 12:22:06 +02:00
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
private:
|
|
|
|
|
|
|
|
// Internal methods to report a passed, skipped, or failed test
|
|
|
|
void ReportPass();
|
|
|
|
void ReportSkipped();
|
|
|
|
void ReportError(const ErrorLogEntry &log_entry);
|
|
|
|
|
|
|
|
// Prints the error or success symbol to screen
|
|
|
|
void PrintTestResult(const std::string &message);
|
|
|
|
|
2016-04-27 14:38:30 +02:00
|
|
|
// Prints an error log
|
|
|
|
void PrintErrorLog(const std::vector<ErrorLogEntry> &error_log);
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// Logging and counting occurrences of errors
|
|
|
|
std::vector<ErrorLogEntry> error_log_;
|
|
|
|
size_t num_passed_;
|
|
|
|
size_t num_skipped_;
|
2015-06-20 16:43:50 +02:00
|
|
|
size_t num_failed_;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// Counting the amount of errors printed on this row
|
|
|
|
size_t print_count_;
|
|
|
|
|
|
|
|
// Counting the number of test-cases with and without failures
|
|
|
|
size_t tests_passed_;
|
2015-06-20 16:43:50 +02:00
|
|
|
size_t tests_skipped_;
|
|
|
|
size_t tests_failed_;
|
2015-05-30 12:30:43 +02:00
|
|
|
|
|
|
|
// Arguments relevant for a specific routine
|
|
|
|
std::vector<std::string> options_;
|
|
|
|
};
|
|
|
|
|
2017-06-27 21:05:16 +02:00
|
|
|
// Maximum number of test results printed on a single line
|
|
|
|
template <typename T, typename U> const size_t Tester<T,U>::kResultsPerLine = size_t{64};
|
|
|
|
|
|
|
|
// Error percentage is not applicable: error was caused by an incorrect status
|
|
|
|
template <typename T, typename U> const float Tester<T,U>::kStatusError = -1.0f;
|
|
|
|
|
|
|
|
// Constants holding start and end strings for terminal-output in colour
|
2017-07-09 20:04:13 +02:00
|
|
|
#if defined(_WIN32)
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintError = "";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintSuccess = "";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintWarning = "";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintMessage = "";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintEnd = "";
|
|
|
|
#else
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintError = "\x1b[31m";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintSuccess = "\x1b[32m";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintWarning = "\x1b[35m";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintMessage = "\x1b[1m";
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kPrintEnd = "\x1b[0m";
|
|
|
|
#endif
|
2017-06-27 21:05:16 +02:00
|
|
|
|
|
|
|
// Sets the output error coding
|
2017-07-09 20:04:13 +02:00
|
|
|
#if defined(_WIN32)
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kSuccessData = ":"; // success
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kSuccessStatus = "."; // success
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kErrorData = "X"; // error
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kErrorStatus = "/"; // error
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kSkippedCompilation = "\\"; // warning
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kUnsupportedPrecision = "o"; // warning
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kUnsupportedReference = "-"; // warning
|
|
|
|
#else
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kSuccessData = "\x1b[32m:\x1b[0m"; // success
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kSuccessStatus = "\x1b[32m.\x1b[0m"; // success
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kErrorData = "\x1b[31mX\x1b[0m"; // error
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kErrorStatus = "\x1b[31m/\x1b[0m"; // error
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kSkippedCompilation = "\x1b[35m\\\x1b[0m"; // warning
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kUnsupportedPrecision = "\x1b[35mo\x1b[0m"; // warning
|
|
|
|
template <typename T, typename U> const std::string Tester<T,U>::kUnsupportedReference = "\x1b[35m-\x1b[0m"; // warning
|
|
|
|
#endif
|
2017-06-27 21:05:16 +02:00
|
|
|
|
2015-07-08 07:21:44 +02:00
|
|
|
// =================================================================================================
|
|
|
|
// Below are the non-member functions (separated because of otherwise required partial class
|
|
|
|
// template specialization)
|
|
|
|
// =================================================================================================
|
|
|
|
|
2017-02-27 21:49:20 +01:00
|
|
|
// Error margins
|
|
|
|
template <typename T> float getRelativeErrorMargin();
|
|
|
|
template <typename T> float getAbsoluteErrorMargin();
|
|
|
|
template <typename T> double getL2ErrorMargin();
|
|
|
|
|
2015-07-08 07:21:44 +02:00
|
|
|
// Compares two floating point values and returns whether they are within an acceptable error
|
|
|
|
// margin. This replaces GTest's EXPECT_NEAR().
|
|
|
|
template <typename T>
|
|
|
|
bool TestSimilarity(const T val1, const T val2);
|
|
|
|
|
|
|
|
// Retrieves a list of example scalar values, used for the alpha and beta arguments for the various
|
|
|
|
// routines. This function is specialised for the different data-types.
|
|
|
|
template <typename T>
|
|
|
|
const std::vector<T> GetExampleScalars(const bool full_test);
|
|
|
|
|
2015-05-30 12:30:43 +02:00
|
|
|
// =================================================================================================
|
|
|
|
} // namespace clblast
|
|
|
|
|
|
|
|
// CLBLAST_TEST_CORRECTNESS_TESTER_H_
|
|
|
|
#endif
|