summaryrefslogtreecommitdiff
path: root/test/correctness/testblas.h
diff options
context:
space:
mode:
Diffstat (limited to 'test/correctness/testblas.h')
-rw-r--r--test/correctness/testblas.h170
1 files changed, 170 insertions, 0 deletions
diff --git a/test/correctness/testblas.h b/test/correctness/testblas.h
index af8a4d0e..8a86c65e 100644
--- a/test/correctness/testblas.h
+++ b/test/correctness/testblas.h
@@ -19,6 +19,7 @@
#include <vector>
#include <string>
+#include <algorithm>
#include "correctness/tester.h"
@@ -100,6 +101,175 @@ class TestBlas: public Tester<T,U> {
};
// =================================================================================================
+
+// The interface to the correctness tester. This is a separate function in the header such that it
+// is automatically compiled for each routine, templated by the parameter "C".
+template <typename C, typename T, typename U>
+void RunTests(int argc, char *argv[], const bool silent, const std::string &name) {
+
+ // Creates a tester
+ auto options = C::GetOptions();
+ TestBlas<T,U> tester{argc, argv, silent, name, options, C::RunRoutine, C::RunReference,
+ C::DownloadResult, C::GetResultIndex, C::ResultID1, C::ResultID2};
+
+ // This variable holds the arguments relevant for this routine
+ auto args = Arguments<U>{};
+
+ // Initializes the vectors with a single element. If this particular option is relevant for this
+ // routine, this vector is overridden. Otherwise, it is unused - the value here does not matter.
+ auto ms = std::vector<size_t>{args.m};
+ auto ns = std::vector<size_t>{args.n};
+ auto ks = std::vector<size_t>{args.k};
+ auto layouts = std::vector<Layout>{args.layout};
+ auto a_transposes = std::vector<Transpose>{args.a_transpose};
+ auto b_transposes = std::vector<Transpose>{args.b_transpose};
+ auto sides = std::vector<Side>{args.side};
+ auto triangles = std::vector<Triangle>{args.triangle};
+ auto diagonals = std::vector<Diagonal>{args.diagonal};
+ auto x_incs = std::vector<size_t>{args.x_inc};
+ auto y_incs = std::vector<size_t>{args.y_inc};
+ auto x_offsets = std::vector<size_t>{args.x_offset};
+ auto y_offsets = std::vector<size_t>{args.y_offset};
+ auto a_lds = std::vector<size_t>{args.a_ld};
+ auto b_lds = std::vector<size_t>{args.b_ld};
+ auto c_lds = std::vector<size_t>{args.c_ld};
+ auto a_offsets = std::vector<size_t>{args.a_offset};
+ auto b_offsets = std::vector<size_t>{args.b_offset};
+ auto c_offsets = std::vector<size_t>{args.c_offset};
+ auto alphas = std::vector<U>{args.alpha};
+ auto betas = std::vector<U>{args.beta};
+ auto x_sizes = std::vector<size_t>{args.x_size};
+ auto y_sizes = std::vector<size_t>{args.y_size};
+ auto a_sizes = std::vector<size_t>{args.a_size};
+ auto b_sizes = std::vector<size_t>{args.b_size};
+ auto c_sizes = std::vector<size_t>{args.c_size};
+
+ // Sets the dimensions of the matrices or vectors depending on the BLAS level
+ auto dimensions = (C::BLASLevel() == 3) ? tester.kMatrixDims :
+ (C::BLASLevel() == 2) ? tester.kMatrixVectorDims :
+ tester.kVectorDims; // else: level 1
+
+ // For the options relevant to this routine, sets the vectors to proper values
+ for (auto &option: options) {
+ if (option == kArgM) { ms = dimensions; }
+ if (option == kArgN) { ns = dimensions; }
+ if (option == kArgK) { ks = dimensions; }
+ if (option == kArgLayout) { layouts = tester.kLayouts; }
+ if (option == kArgATransp) { a_transposes = C::GetATransposes(tester.kTransposes); }
+ if (option == kArgBTransp) { b_transposes = C::GetBTransposes(tester.kTransposes); }
+ if (option == kArgSide) { sides = tester.kSides; }
+ if (option == kArgTriangle) { triangles = tester.kTriangles; }
+ if (option == kArgDiagonal) { diagonals = tester.kDiagonals; }
+ if (option == kArgXInc) { x_incs = tester.kIncrements; }
+ if (option == kArgYInc) { y_incs = tester.kIncrements; }
+ if (option == kArgXOffset) { x_offsets = tester.kOffsets; }
+ if (option == kArgYOffset) { y_offsets = tester.kOffsets; }
+ if (option == kArgALeadDim) { a_lds = dimensions; }
+ if (option == kArgBLeadDim) { b_lds = dimensions; }
+ if (option == kArgCLeadDim) { c_lds = dimensions; }
+ if (option == kArgAOffset) { a_offsets = tester.kOffsets; }
+ if (option == kArgBOffset) { b_offsets = tester.kOffsets; }
+ if (option == kArgCOffset) { c_offsets = tester.kOffsets; }
+ if (option == kArgAlpha) { alphas = tester.kAlphaValues; }
+ if (option == kArgBeta) { betas = tester.kBetaValues; }
+
+ if (option == kArgXOffset) { x_sizes = tester.kVecSizes; }
+ if (option == kArgYOffset) { y_sizes = tester.kVecSizes; }
+ if (option == kArgAOffset) { a_sizes = tester.kMatSizes; }
+ if (option == kArgBOffset) { b_sizes = tester.kMatSizes; }
+ if (option == kArgCOffset) { c_sizes = tester.kMatSizes; }
+ }
+
+ // Loops over the test-cases from a data-layout point of view
+ for (auto &layout: layouts) { args.layout = layout;
+ for (auto &a_transpose: a_transposes) { args.a_transpose = a_transpose;
+ for (auto &b_transpose: b_transposes) { args.b_transpose = b_transpose;
+ for (auto &side: sides) { args.side = side;
+ for (auto &triangle: triangles) { args.triangle = triangle;
+ for (auto &diagonal: diagonals) { args.diagonal = diagonal;
+
+ // Creates the arguments vector for the regular tests
+ auto regular_test_vector = std::vector<Arguments<U>>{};
+ auto r_args = args;
+ for (auto &m: ms) { r_args.m = m;
+ for (auto &n: ns) { r_args.n = n;
+ for (auto &k: ks) { r_args.k = k;
+ for (auto &x_inc: x_incs) { r_args.x_inc = x_inc;
+ for (auto &x_offset: x_offsets) { r_args.x_offset = x_offset;
+ for (auto &y_inc: y_incs) { r_args.y_inc = y_inc;
+ for (auto &y_offset: y_offsets) { r_args.y_offset = y_offset;
+ for (auto &a_ld: a_lds) { r_args.a_ld = a_ld;
+ for (auto &a_offset: a_offsets) { r_args.a_offset = a_offset;
+ for (auto &b_ld: b_lds) { r_args.b_ld = b_ld;
+ for (auto &b_offset: b_offsets) { r_args.b_offset = b_offset;
+ for (auto &c_ld: c_lds) { r_args.c_ld = c_ld;
+ for (auto &c_offset: c_offsets) { r_args.c_offset = c_offset;
+ for (auto &alpha: alphas) { r_args.alpha = alpha;
+ for (auto &beta: betas) { r_args.beta = beta;
+ C::SetSizes(r_args);
+ regular_test_vector.push_back(r_args);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Creates the arguments vector for the invalid-buffer tests
+ auto invalid_test_vector = std::vector<Arguments<U>>{};
+ auto i_args = args;
+ i_args.m = i_args.n = i_args.k = tester.kBufferSize;
+ i_args.a_ld = i_args.b_ld = i_args.c_ld = tester.kBufferSize;
+ for (auto &x_size: x_sizes) { i_args.x_size = x_size;
+ for (auto &y_size: y_sizes) { i_args.y_size = y_size;
+ for (auto &a_size: a_sizes) { i_args.a_size = a_size;
+ for (auto &b_size: b_sizes) { i_args.b_size = b_size;
+ for (auto &c_size: c_sizes) { i_args.c_size = c_size;
+ invalid_test_vector.push_back(i_args);
+ }
+ }
+ }
+ }
+ }
+
+ // Sets the name of this test-case
+ auto names = std::vector<std::string>{};
+ for (auto &option: options) {
+ if (option == kArgLayout) { names.push_back(ToString(layout)); }
+ if (option == kArgATransp) { names.push_back(ToString(a_transpose)); }
+ if (option == kArgBTransp) { names.push_back(ToString(b_transpose)); }
+ if (option == kArgSide) { names.push_back(ToString(side)); }
+ if (option == kArgTriangle) { names.push_back(ToString(triangle)); }
+ if (option == kArgDiagonal) { names.push_back(ToString(diagonal)); }
+ }
+ if (names.size() == 0) { names.push_back("default"); }
+ auto case_name = std::string{};
+ for (auto i=size_t{0}; i<names.size(); ++i) {
+ case_name += names[i];
+ if (i != names.size()-1) { case_name += " "; }
+ }
+
+ // Runs the tests
+ tester.TestRegular(regular_test_vector, case_name);
+ tester.TestInvalid(invalid_test_vector, case_name);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// =================================================================================================
} // namespace clblast
// CLBLAST_TEST_CORRECTNESS_TESTBLAS_H_