summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/internal/routine.h2
-rw-r--r--include/internal/utilities.h4
-rw-r--r--src/routine.cc15
-rw-r--r--test/correctness/testblas.cc20
-rw-r--r--test/correctness/testblas.h13
-rw-r--r--test/correctness/tester.cc1
-rw-r--r--test/performance/client.cc10
7 files changed, 56 insertions, 9 deletions
diff --git a/include/internal/routine.h b/include/internal/routine.h
index 367917fd..c5b253b4 100644
--- a/include/internal/routine.h
+++ b/include/internal/routine.h
@@ -78,6 +78,8 @@ class Routine {
const size_t inc, const size_t data_size);
StatusCode TestVectorY(const size_t n, const Buffer<T> &buffer, const size_t offset,
const size_t inc, const size_t data_size);
+ StatusCode TestVectorDot(const size_t n, const Buffer<T> &buffer, const size_t offset,
+ const size_t data_size);
// Copies/transposes a matrix and padds/unpads it with zeroes. This method is also able to write
// to symmetric and triangular matrices through optional arguments.
diff --git a/include/internal/utilities.h b/include/internal/utilities.h
index d9fdb9ab..466ac810 100644
--- a/include/internal/utilities.h
+++ b/include/internal/utilities.h
@@ -57,6 +57,7 @@ constexpr auto kArgCLeadDim = "ldc";
constexpr auto kArgAOffset = "offa";
constexpr auto kArgBOffset = "offb";
constexpr auto kArgCOffset = "offc";
+constexpr auto kArgDotOffset = "offdot";
constexpr auto kArgAlpha = "alpha";
constexpr auto kArgBeta = "beta";
@@ -105,6 +106,7 @@ struct Arguments {
size_t a_offset = 0;
size_t b_offset = 0;
size_t c_offset = 0;
+ size_t dot_offset = 0;
T alpha = T{1.0};
T beta = T{1.0};
size_t x_size = 1;
@@ -112,6 +114,7 @@ struct Arguments {
size_t a_size = 1;
size_t b_size = 1;
size_t c_size = 1;
+ size_t dot_size = 1;
// Tuner-specific arguments
double fraction = 1.0;
// Client-specific arguments
@@ -138,6 +141,7 @@ struct Buffers {
Buffer<T> a_mat;
Buffer<T> b_mat;
Buffer<T> c_mat;
+ Buffer<T> dot;
};
// =================================================================================================
diff --git a/src/routine.cc b/src/routine.cc
index 31476c42..05a03683 100644
--- a/src/routine.cc
+++ b/src/routine.cc
@@ -223,6 +223,21 @@ StatusCode Routine<T>::TestVectorY(const size_t n, const Buffer<T> &buffer, cons
// =================================================================================================
+// Tests vector dot for validity: checks for a valid increment, a valid OpenCL buffer, and for a
+// sufficient buffer size.
+template <typename T>
+StatusCode Routine<T>::TestVectorDot(const size_t n, const Buffer<T> &buffer, const size_t offset,
+ const size_t data_size) {
+ try {
+ auto required_size = (n + offset)*data_size;
+ auto buffer_size = buffer.GetSize();
+ if (buffer_size < required_size) { return StatusCode::kInsufficientMemoryDot; }
+ } catch (...) { return StatusCode::kInvalidVectorDot; }
+ return StatusCode::kSuccess;
+}
+
+// =================================================================================================
+
// Copies or transposes a matrix and pads/unpads it with zeros
template <typename T>
StatusCode Routine<T>::PadCopyTransposeMatrix(const size_t src_one, const size_t src_two,
diff --git a/test/correctness/testblas.cc b/test/correctness/testblas.cc
index ff81f4c3..839ac3b1 100644
--- a/test/correctness/testblas.cc
+++ b/test/correctness/testblas.cc
@@ -57,11 +57,13 @@ TestBlas<T,U>::TestBlas(int argc, char *argv[], const bool silent,
a_source_.resize(std::max(max_mat, max_matvec)*std::max(max_ld, max_matvec) + max_offset);
b_source_.resize(std::max(max_mat, max_matvec)*std::max(max_ld, max_matvec) + max_offset);
c_source_.resize(std::max(max_mat, max_matvec)*std::max(max_ld, max_matvec) + max_offset);
+ dot_source_.resize(std::max(max_mat, max_matvec) + max_offset);
PopulateVector(x_source_);
PopulateVector(y_source_);
PopulateVector(a_source_);
PopulateVector(b_source_);
PopulateVector(c_source_);
+ PopulateVector(dot_source_);
}
// ===============================================================================================
@@ -81,12 +83,14 @@ void TestBlas<T,U>::TestRegular(std::vector<Arguments<U>> &test_vector, const st
auto a_mat1 = Buffer<T>(context_, args.a_size);
auto b_mat1 = Buffer<T>(context_, args.b_size);
auto c_mat1 = Buffer<T>(context_, args.c_size);
+ auto dot1 = Buffer<T>(context_, args.dot_size);
x_vec1.Write(queue_, args.x_size, x_source_);
y_vec1.Write(queue_, args.y_size, y_source_);
a_mat1.Write(queue_, args.a_size, a_source_);
b_mat1.Write(queue_, args.b_size, b_source_);
c_mat1.Write(queue_, args.c_size, c_source_);
- auto buffers1 = Buffers<T>{x_vec1, y_vec1, a_mat1, b_mat1, c_mat1};
+ dot1.Write(queue_, args.dot_size, dot_source_);
+ auto buffers1 = Buffers<T>{x_vec1, y_vec1, a_mat1, b_mat1, c_mat1, dot1};
auto status1 = run_reference_(args, buffers1, queue_);
// Runs the CLBlast code
@@ -95,12 +99,14 @@ void TestBlas<T,U>::TestRegular(std::vector<Arguments<U>> &test_vector, const st
auto a_mat2 = Buffer<T>(context_, args.a_size);
auto b_mat2 = Buffer<T>(context_, args.b_size);
auto c_mat2 = Buffer<T>(context_, args.c_size);
+ auto dot2 = Buffer<T>(context_, args.dot_size);
x_vec2.Write(queue_, args.x_size, x_source_);
y_vec2.Write(queue_, args.y_size, y_source_);
a_mat2.Write(queue_, args.a_size, a_source_);
b_mat2.Write(queue_, args.b_size, b_source_);
c_mat2.Write(queue_, args.c_size, c_source_);
- auto buffers2 = Buffers<T>{x_vec2, y_vec2, a_mat2, b_mat2, c_mat2};
+ dot2.Write(queue_, args.dot_size, dot_source_);
+ auto buffers2 = Buffers<T>{x_vec2, y_vec2, a_mat2, b_mat2, c_mat2, dot2};
auto status2 = run_routine_(args, buffers2, queue_);
// Tests for equality of the two status codes
@@ -149,25 +155,31 @@ void TestBlas<T,U>::TestInvalid(std::vector<Arguments<U>> &test_vector, const st
auto a1 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.a_size*sizeof(T), nullptr,nullptr);
auto b1 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.b_size*sizeof(T), nullptr,nullptr);
auto c1 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.c_size*sizeof(T), nullptr,nullptr);
+ auto d1 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.dot_size*sizeof(T), nullptr,nullptr);
auto x_vec1 = Buffer<T>(x1);
auto y_vec1 = Buffer<T>(y1);
auto a_mat1 = Buffer<T>(a1);
auto b_mat1 = Buffer<T>(b1);
auto c_mat1 = Buffer<T>(c1);
+ auto dot1 = Buffer<T>(d1);
auto x2 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.x_size*sizeof(T), nullptr,nullptr);
auto y2 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.y_size*sizeof(T), nullptr,nullptr);
auto a2 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.a_size*sizeof(T), nullptr,nullptr);
auto b2 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.b_size*sizeof(T), nullptr,nullptr);
auto c2 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.c_size*sizeof(T), nullptr,nullptr);
+ auto d2 = clCreateBuffer(context_(), CL_MEM_READ_WRITE, args.dot_size*sizeof(T), nullptr,nullptr);
auto x_vec2 = Buffer<T>(x2);
auto y_vec2 = Buffer<T>(y2);
auto a_mat2 = Buffer<T>(a2);
auto b_mat2 = Buffer<T>(b2);
auto c_mat2 = Buffer<T>(c2);
+ auto dot2 = Buffer<T>(d2);
// Runs the two routines
- auto status1 = run_reference_(args, Buffers<T>{x_vec1, y_vec1, a_mat1, b_mat1, c_mat1}, queue_);
- auto status2 = run_routine_(args, Buffers<T>{x_vec2, y_vec2, a_mat2, b_mat2, c_mat2}, queue_);
+ auto buffers1 = Buffers<T>{x_vec1, y_vec1, a_mat1, b_mat1, c_mat1, dot1};
+ auto buffers2 = Buffers<T>{x_vec2, y_vec2, a_mat2, b_mat2, c_mat2, dot2};
+ auto status1 = run_reference_(args, buffers1, queue_);
+ auto status2 = run_routine_(args, buffers2, queue_);
// Tests for equality of the two status codes
TestErrorCodes(status1, status2, args);
diff --git a/test/correctness/testblas.h b/test/correctness/testblas.h
index 8a86c65e..9e1d110c 100644
--- a/test/correctness/testblas.h
+++ b/test/correctness/testblas.h
@@ -90,6 +90,7 @@ class TestBlas: public Tester<T,U> {
std::vector<T> a_source_;
std::vector<T> b_source_;
std::vector<T> c_source_;
+ std::vector<T> dot_source_;
// The routine-specific functions passed to the tester
Routine run_routine_;
@@ -136,6 +137,7 @@ void RunTests(int argc, char *argv[], const bool silent, const std::string &name
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 dot_offsets = std::vector<size_t>{args.dot_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};
@@ -170,6 +172,7 @@ void RunTests(int argc, char *argv[], const bool silent, const std::string &name
if (option == kArgAOffset) { a_offsets = tester.kOffsets; }
if (option == kArgBOffset) { b_offsets = tester.kOffsets; }
if (option == kArgCOffset) { c_offsets = tester.kOffsets; }
+ if (option == kArgDotOffset) { dot_offsets = tester.kOffsets; }
if (option == kArgAlpha) { alphas = tester.kAlphaValues; }
if (option == kArgBeta) { betas = tester.kBetaValues; }
@@ -204,10 +207,12 @@ void RunTests(int argc, char *argv[], const bool silent, const std::string &name
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);
+ for (auto &dot_offset: dot_offsets) { r_args.dot_offset = dot_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);
+ }
}
}
}
diff --git a/test/correctness/tester.cc b/test/correctness/tester.cc
index a52142c4..f792925e 100644
--- a/test/correctness/tester.cc
+++ b/test/correctness/tester.cc
@@ -148,6 +148,7 @@ void Tester<T,U>::TestEnd() {
if (o == kArgAOffset) { fprintf(stdout, "%s=%lu ", kArgAOffset, entry.args.a_offset);}
if (o == kArgBOffset) { fprintf(stdout, "%s=%lu ", kArgBOffset, entry.args.b_offset);}
if (o == kArgCOffset) { fprintf(stdout, "%s=%lu ", kArgCOffset, entry.args.c_offset);}
+ if (o == kArgDotOffset){ fprintf(stdout, "%s=%lu ", kArgDotOffset, entry.args.dot_offset);}
}
fprintf(stdout, "\n");
}
diff --git a/test/performance/client.cc b/test/performance/client.cc
index 10560f2c..9faa4dca 100644
--- a/test/performance/client.cc
+++ b/test/performance/client.cc
@@ -74,6 +74,9 @@ Arguments<U> Client<T,U>::ParseArguments(int argc, char *argv[], const GetMetric
if (o == kArgBOffset) { args.b_offset = GetArgument(argc, argv, help, kArgBOffset, size_t{0}); }
if (o == kArgCOffset) { args.c_offset = GetArgument(argc, argv, help, kArgCOffset, size_t{0}); }
+ // Dot arguments
+ if (o == kArgDotOffset) { args.dot_offset = GetArgument(argc, argv, help, kArgDotOffset, size_t{0}); }
+
// Scalar values
if (o == kArgAlpha) { args.alpha = GetArgument(argc, argv, help, kArgAlpha, GetScalar<U>()); }
if (o == kArgBeta) { args.beta = GetArgument(argc, argv, help, kArgBeta, GetScalar<U>()); }
@@ -128,11 +131,13 @@ void Client<T,U>::PerformanceTest(Arguments<U> &args, const SetMetric set_sizes)
std::vector<T> a_source(args.a_size);
std::vector<T> b_source(args.b_size);
std::vector<T> c_source(args.c_size);
+ std::vector<T> dot_source(args.dot_size);
PopulateVector(x_source);
PopulateVector(y_source);
PopulateVector(a_source);
PopulateVector(b_source);
PopulateVector(c_source);
+ PopulateVector(dot_source);
// Creates the matrices on the device
auto x_vec = Buffer<T>(context, args.x_size);
@@ -140,12 +145,14 @@ void Client<T,U>::PerformanceTest(Arguments<U> &args, const SetMetric set_sizes)
auto a_mat = Buffer<T>(context, args.a_size);
auto b_mat = Buffer<T>(context, args.b_size);
auto c_mat = Buffer<T>(context, args.c_size);
+ auto dot = Buffer<T>(context, args.dot_size);
x_vec.Write(queue, args.x_size, x_source);
y_vec.Write(queue, args.y_size, y_source);
a_mat.Write(queue, args.a_size, a_source);
b_mat.Write(queue, args.b_size, b_source);
c_mat.Write(queue, args.c_size, c_source);
- auto buffers = Buffers<T>{x_vec, y_vec, a_mat, b_mat, c_mat};
+ dot.Write(queue, args.dot_size, dot_source);
+ auto buffers = Buffers<T>{x_vec, y_vec, a_mat, b_mat, c_mat, dot};
// Runs the routines and collects the timings
auto ms_clblast = TimedExecution(args.num_runs, args, buffers, queue, run_routine_, "CLBlast");
@@ -236,6 +243,7 @@ void Client<T,U>::PrintTableRow(const Arguments<U>& args, const double ms_clblas
else if (o == kArgAOffset) { integers.push_back(args.a_offset); }
else if (o == kArgBOffset) { integers.push_back(args.b_offset); }
else if (o == kArgCOffset) { integers.push_back(args.c_offset); }
+ else if (o == kArgDotOffset) {integers.push_back(args.dot_offset); }
}
auto strings = std::vector<std::string>{};
for (auto &o: options_) {