diff options
Diffstat (limited to 'ml/dlib/dlib/test/blas_bindings')
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/CMakeLists.txt | 33 | ||||
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/blas_bindings_dot.cpp | 314 | ||||
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/blas_bindings_gemm.cpp | 311 | ||||
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/blas_bindings_gemv.cpp | 226 | ||||
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/blas_bindings_ger.cpp | 200 | ||||
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/blas_bindings_scal_axpy.cpp | 261 | ||||
-rw-r--r-- | ml/dlib/dlib/test/blas_bindings/vector.cpp | 115 |
7 files changed, 1460 insertions, 0 deletions
diff --git a/ml/dlib/dlib/test/blas_bindings/CMakeLists.txt b/ml/dlib/dlib/test/blas_bindings/CMakeLists.txt new file mode 100644 index 000000000..5deddee04 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/CMakeLists.txt @@ -0,0 +1,33 @@ +# +# This is a CMake makefile. You can find the cmake utility and +# information about it at http://www.cmake.org +# + +cmake_minimum_required(VERSION 2.8.12) + +# This variable contains a list of all the tests we are building +# into the regression test suite. +set (tests + blas_bindings_gemm.cpp + blas_bindings_gemv.cpp + blas_bindings_ger.cpp + blas_bindings_dot.cpp + blas_bindings_scal_axpy.cpp + vector.cpp + ) + +# create a variable called target_name and set it to the string "test" +set (target_name dtest) + +PROJECT(${target_name}) + +# add all the cpp files we want to compile to this list. This tells +# cmake that they are part of our target (which is the executable named test) +ADD_EXECUTABLE(${target_name} ../main.cpp ../tester.cpp ${tests}) + +ADD_DEFINITIONS(-DDLIB_TEST_BLAS_BINDINGS) + +# Tell cmake to link our target executable to dlib +include(../../cmake) +TARGET_LINK_LIBRARIES(${target_name} dlib ) + diff --git a/ml/dlib/dlib/test/blas_bindings/blas_bindings_dot.cpp b/ml/dlib/dlib/test/blas_bindings/blas_bindings_dot.cpp new file mode 100644 index 000000000..0571b0685 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/blas_bindings_dot.cpp @@ -0,0 +1,314 @@ +// Copyright (C) 2009 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. + +#include "../tester.h" +#include <dlib/matrix.h> + +#ifndef DLIB_USE_BLAS +#error "BLAS bindings must be used for this test to make any sense" +#endif + +namespace dlib +{ + namespace blas_bindings + { + // This is a little screwy. This function is used inside the BLAS + // bindings to count how many times each of the BLAS functions get called. +#ifdef DLIB_TEST_BLAS_BINDINGS + int& counter_dot() { static int counter = 0; return counter; } +#endif + + } +} + +namespace +{ + using namespace test; + using namespace std; + // Declare the logger we will use in this test. The name of the logger + // should start with "test." + dlib::logger dlog("test.dot"); + + + class blas_bindings_dot_tester : public tester + { + public: + blas_bindings_dot_tester ( + ) : + tester ( + "test_dot", // the command line argument name for this test + "Run tests for DOT routines.", // the command line argument description + 0 // the number of command line arguments for this test + ) + {} + + void test_mat_bindings() + { + using namespace dlib; + using namespace dlib::blas_bindings; + matrix<double,1,0> rv(10); + matrix<double,0,1> cv(10); + double val; + + rv = 1; cv = 1; + counter_dot() = 0; + val = rv*cv; + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + + rv = 1; cv = 1; + counter_dot() = 0; + val = rv*mat(&cv(0),cv.size()); + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + + rv = 1; cv = 1; + counter_dot() = 0; + val = trans(mat(&rv(0),rv.size()))*mat(&cv(0),cv.size()); + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + + std::vector<double> sv(10,1); + rv = 1; + counter_dot() = 0; + val = trans(mat(&rv(0),rv.size()))*mat(sv); + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + + + counter_dot() = 0; + val = trans(mat(sv))*mat(sv); + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + + std_vector_c<double> svc(10,1); + counter_dot() = 0; + val = trans(mat(svc))*mat(svc); + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + + + dlib::array<double> arr(10); + for (unsigned int i = 0; i < arr.size(); ++i) + arr[i] = 1; + counter_dot() = 0; + val = trans(mat(arr))*mat(arr); + DLIB_TEST(val == 10); + DLIB_TEST(counter_dot() == 1); + } + + template <typename matrix_type, typename cv_type, typename rv_type> + void test_dot_stuff( + matrix_type& m, + rv_type& rv, + cv_type& cv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + rv_type rv2; + cv_type cv2; + matrix_type m2; + typedef typename matrix_type::type scalar_type; + scalar_type val; + + counter_dot() = 0; + m2 = rv*cv; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = rv*cv; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = rv*3*cv; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = rv*trans(rv)*3; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = trans(rv*trans(rv)*3 + trans(cv)*cv); + DLIB_TEST(counter_dot() == 2); + + + counter_dot() = 0; + val = trans(cv)*cv; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = trans(cv)*trans(rv); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(rv,cv); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(rv,colm(cv,0)); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(cv,cv); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(colm(cv,0,cv.size()),colm(cv,0)); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(rv,rv); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(rv,trans(rv)); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(trans(cv),cv); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = dot(trans(cv),trans(rv)); + DLIB_TEST(counter_dot() == 1); + + + // This does one dot and one gemv + counter_dot() = 0; + val = trans(cv)*m*trans(rv); + DLIB_TEST_MSG(counter_dot() == 1, counter_dot()); + + // This does one dot and two gemv + counter_dot() = 0; + val = (trans(cv)*m)*(m*trans(rv)); + DLIB_TEST_MSG(counter_dot() == 1, counter_dot()); + + // This does one dot and two gemv + counter_dot() = 0; + val = trans(cv)*m*trans(m)*trans(rv); + DLIB_TEST_MSG(counter_dot() == 1, counter_dot()); + } + + + template <typename matrix_type, typename cv_type, typename rv_type> + void test_dot_stuff_conj( + matrix_type& , + rv_type& rv, + cv_type& cv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + rv_type rv2; + cv_type cv2; + matrix_type m2; + typedef typename matrix_type::type scalar_type; + scalar_type val; + + counter_dot() = 0; + val = conj(rv)*cv; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = trans(conj(cv))*cv; + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = trans(conj(cv))*trans(rv); + DLIB_TEST(counter_dot() == 1); + + counter_dot() = 0; + val = trans(conj(cv))*3*trans(rv); + DLIB_TEST(counter_dot() == 1); + } + + void perform_test ( + ) + { + using namespace dlib; + typedef dlib::memory_manager<char>::kernel_1a mm; + + dlog << dlib::LINFO << "test double"; + { + matrix<double> m = randm(4,4); + matrix<double,1,0> rv = randm(1,4); + matrix<double,0,1> cv = randm(4,1); + test_dot_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test float"; + { + matrix<float> m = matrix_cast<float>(randm(4,4)); + matrix<float,1,0> rv = matrix_cast<float>(randm(1,4)); + matrix<float,0,1> cv = matrix_cast<float>(randm(4,1)); + test_dot_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<complex<double> > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,1,0> rv = complex_matrix(randm(1,4), randm(1,4)); + matrix<complex<double>,0,1> cv = complex_matrix(randm(4,1), randm(4,1)); + test_dot_stuff(m,rv,cv); + test_dot_stuff_conj(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<complex<float> > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,1,0> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + matrix<complex<float>,0,1> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + test_dot_stuff(m,rv,cv); + test_dot_stuff_conj(m,rv,cv); + } + + + dlog << dlib::LINFO << "test double, column major"; + { + matrix<double,0,0,mm,column_major_layout> m = randm(4,4); + matrix<double,1,0,mm,column_major_layout> rv = randm(1,4); + matrix<double,0,1,mm,column_major_layout> cv = randm(4,1); + test_dot_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test float, column major"; + { + matrix<float,0,0,mm,column_major_layout> m = matrix_cast<float>(randm(4,4)); + matrix<float,1,0,mm,column_major_layout> rv = matrix_cast<float>(randm(1,4)); + matrix<float,0,1,mm,column_major_layout> cv = matrix_cast<float>(randm(4,1)); + test_dot_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<double>, column major"; + { + matrix<complex<double>,0,0,mm,column_major_layout > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,1,0,mm,column_major_layout> rv = complex_matrix(randm(1,4), randm(1,4)); + matrix<complex<double>,0,1,mm,column_major_layout> cv = complex_matrix(randm(4,1), randm(4,1)); + test_dot_stuff(m,rv,cv); + test_dot_stuff_conj(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<float>, column major"; + { + matrix<complex<float>,0,0,mm,column_major_layout > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,1,0,mm,column_major_layout> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + matrix<complex<float>,0,1,mm,column_major_layout> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + test_dot_stuff(m,rv,cv); + test_dot_stuff_conj(m,rv,cv); + } + + + test_mat_bindings(); + + print_spinner(); + } + }; + + blas_bindings_dot_tester a; + +} + + diff --git a/ml/dlib/dlib/test/blas_bindings/blas_bindings_gemm.cpp b/ml/dlib/dlib/test/blas_bindings/blas_bindings_gemm.cpp new file mode 100644 index 000000000..83d41edd1 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/blas_bindings_gemm.cpp @@ -0,0 +1,311 @@ +// Copyright (C) 2009 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. + +#include "../tester.h" +#include <dlib/matrix.h> + +#ifndef DLIB_USE_BLAS +#error "BLAS bindings must be used for this test to make any sense" +#endif + +namespace dlib +{ + namespace blas_bindings + { + // This is a little screwy. This function is used inside the BLAS + // bindings to count how many times each of the BLAS functions get called. +#ifdef DLIB_TEST_BLAS_BINDINGS + int& counter_gemm() { static int counter = 0; return counter; } +#endif + + } +} + +namespace +{ + using namespace test; + using namespace std; + // Declare the logger we will use in this test. The name of the logger + // should start with "test." + dlib::logger dlog("test.gemm"); + + + class blas_bindings_gemm_tester : public tester + { + public: + blas_bindings_gemm_tester ( + ) : + tester ( + "test_gemm", // the command line argument name for this test + "Run tests for GEMM routines.", // the command line argument description + 0 // the number of command line arguments for this test + ) + {} + + template <typename matrix_type> + void test_gemm_stuff( + const matrix_type& c + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + matrix_type b, a; + a = c; + + counter_gemm() = 0; + b = a*a; + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = a/2*a; + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = a*trans(a) + a; + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = (a+a)*(a+a); + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = a*(a-a); + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = trans(a)*trans(a) + a; + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = trans(trans(trans(a)*a + a)); + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = a*a*a*a; + DLIB_TEST(counter_gemm() == 3); + b = c; + + counter_gemm() = 0; + a = a*a*a*a; + DLIB_TEST(counter_gemm() == 3); + a = c; + + counter_gemm() = 0; + a = (b + a*trans(a)*a*3*a)*trans(b); + DLIB_TEST(counter_gemm() == 4); + a = c; + + counter_gemm() = 0; + a = trans((trans(b) + trans(a)*trans(a)*a*3*a)*trans(b)); + DLIB_TEST(counter_gemm() == 4); + a = c; + + counter_gemm() = 0; + a = trans((trans(b) + trans(a)*(a)*trans(a)*3*a)*trans(b)); + DLIB_TEST(counter_gemm() == 4); + a = c; + + counter_gemm() = 0; + a = trans((trans(b) + trans(a)*(a + b)*trans(a)*3*a)*trans(b)); + DLIB_TEST_MSG(counter_gemm() == 4, counter_gemm()); + a = c; + + counter_gemm() = 0; + a = trans((trans(b) + trans(a)*(a*8 + b+b+b+b)*trans(a)*3*a)*trans(b)); + DLIB_TEST_MSG(counter_gemm() == 4, counter_gemm()); + a = c; + } + + template <typename matrix_type> + void test_gemm_stuff_conj( + const matrix_type& c + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + matrix_type b, a; + a = c; + + counter_gemm() = 0; + b = a*conj(a); + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = a*trans(conj(a)) + a; + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = conj(trans(a))*trans(a) + a; + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = trans(trans(trans(a)*conj(a) + conj(a))); + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + b = a*a*conj(a)*a; + DLIB_TEST(counter_gemm() == 3); + b = c; + + counter_gemm() = 0; + a = a*trans(conj(a))*a*a; + DLIB_TEST(counter_gemm() == 3); + a = c; + + counter_gemm() = 0; + a = (b + a*trans(conj(a))*a*3*a)*trans(b); + DLIB_TEST(counter_gemm() == 4); + a = c; + + counter_gemm() = 0; + a = (trans((conj(trans(b)) + trans(a)*conj(trans(a))*a*3*a)*trans(b))); + DLIB_TEST(counter_gemm() == 4); + a = c; + + counter_gemm() = 0; + a = ((trans(b) + trans(a)*(a)*trans(a)*3*a)*trans(conj(b))); + DLIB_TEST(counter_gemm() == 4); + a = c; + + counter_gemm() = 0; + a = trans((trans(b) + trans(a)*conj(a + b)*trans(a)*3*a)*trans(b)); + DLIB_TEST_MSG(counter_gemm() == 4, counter_gemm()); + a = c; + + counter_gemm() = 0; + a = trans((trans(b) + trans(a)*(a*8 + b+b+b+b)*trans(a)*3*conj(a))*trans(b)); + DLIB_TEST_MSG(counter_gemm() == 4, counter_gemm()); + a = c; + } + + void perform_test ( + ) + { + using namespace dlib; + typedef dlib::memory_manager<char>::kernel_1a mm; + + print_spinner(); + + dlog << dlib::LINFO << "test double"; + { + matrix<double> a = randm(4,4); + test_gemm_stuff(a); + } + + print_spinner(); + dlog << dlib::LINFO << "test float"; + { + matrix<float> a = matrix_cast<float>(randm(4,4)); + test_gemm_stuff(a); + } + + print_spinner(); + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<float> a = matrix_cast<float>(randm(4,4)); + matrix<float> b = matrix_cast<float>(randm(4,4)); + matrix<complex<float> > c = complex_matrix(a,b); + test_gemm_stuff(c); + test_gemm_stuff_conj(c); + } + + print_spinner(); + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<double> a = matrix_cast<double>(randm(4,4)); + matrix<double> b = matrix_cast<double>(randm(4,4)); + matrix<complex<double> > c = complex_matrix(a,b); + test_gemm_stuff(c); + test_gemm_stuff_conj(c); + } + + + print_spinner(); + + dlog << dlib::LINFO << "test double, column major"; + { + matrix<double,100,100,mm,column_major_layout> a = randm(100,100); + test_gemm_stuff(a); + } + + print_spinner(); + dlog << dlib::LINFO << "test float, column major"; + { + matrix<float,100,100,mm,column_major_layout> a = matrix_cast<float>(randm(100,100)); + test_gemm_stuff(a); + } + + print_spinner(); + dlog << dlib::LINFO << "test complex<double>, column major"; + { + matrix<double,100,100,mm,column_major_layout> a = matrix_cast<double>(randm(100,100)); + matrix<double,100,100,mm,column_major_layout> b = matrix_cast<double>(randm(100,100)); + matrix<complex<double>,100,100,mm,column_major_layout > c = complex_matrix(a,b); + test_gemm_stuff(c); + test_gemm_stuff_conj(c); + } + + print_spinner(); + + dlog << dlib::LINFO << "test complex<float>, column major"; + { + matrix<float,100,100,mm,column_major_layout> a = matrix_cast<float>(randm(100,100)); + matrix<float,100,100,mm,column_major_layout> b = matrix_cast<float>(randm(100,100)); + matrix<complex<float>,100,100,mm,column_major_layout > c = complex_matrix(a,b); + test_gemm_stuff(c); + test_gemm_stuff_conj(c); + } + + { + using namespace dlib; + using namespace dlib::blas_bindings; + array2d<double> a(100,100); + array2d<double> b(100,100); + matrix<double> c; + + counter_gemm() = 0; + c = mat(a)*mat(b); + DLIB_TEST(counter_gemm() == 1); + + counter_gemm() = 0; + c = trans(2*mat(a)*mat(b)); + DLIB_TEST(counter_gemm() == 1); + } + + { + using namespace dlib; + using namespace dlib::blas_bindings; + array2d<double> a(100,100); + array2d<double> b(100,100); + matrix<double> aa(100,100); + matrix<double> bb(100,100); + matrix<double> c; + + counter_gemm() = 0; + c = mat(&a[0][0],100,100)*mat(&b[0][0],100,100); + DLIB_TEST(counter_gemm() == 1); + set_ptrm(&c(0,0),100,100) = mat(&a[0][0],100,100)*mat(&b[0][0],100,100); + DLIB_TEST(counter_gemm() == 2); + set_ptrm(&c(0,0),100,100) = aa*bb; + DLIB_TEST(counter_gemm() == 3); + + counter_gemm() = 0; + c = trans(2*mat(&a[0][0],100,100)*mat(&b[0][0],100,100)); + DLIB_TEST(counter_gemm() == 1); + set_ptrm(&c(0,0),100,100) = trans(2*mat(&a[0][0],100,100)*mat(&b[0][0],100,100)); + DLIB_TEST(counter_gemm() == 2); + set_ptrm(&c(0,0),100,100) = trans(2*mat(a)*mat(b)); + DLIB_TEST(counter_gemm() == 3); + } + + print_spinner(); + } + }; + + blas_bindings_gemm_tester a; + +} + + diff --git a/ml/dlib/dlib/test/blas_bindings/blas_bindings_gemv.cpp b/ml/dlib/dlib/test/blas_bindings/blas_bindings_gemv.cpp new file mode 100644 index 000000000..322438313 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/blas_bindings_gemv.cpp @@ -0,0 +1,226 @@ +// Copyright (C) 2009 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. + +#include "../tester.h" +#include <dlib/matrix.h> + +#ifndef DLIB_USE_BLAS +#error "BLAS bindings must be used for this test to make any sense" +#endif + +namespace dlib +{ + namespace blas_bindings + { + // This is a little screwy. This function is used inside the BLAS + // bindings to count how many times each of the BLAS functions get called. +#ifdef DLIB_TEST_BLAS_BINDINGS + int& counter_gemv() { static int counter = 0; return counter; } +#endif + + } +} + +namespace +{ + using namespace test; + using namespace std; + // Declare the logger we will use in this test. The name of the logger + // should start with "test." + dlib::logger dlog("test.gemv"); + + + class blas_bindings_gemv_tester : public tester + { + public: + blas_bindings_gemv_tester ( + ) : + tester ( + "test_gemv", // the command line argument name for this test + "Run tests for GEMV routines.", // the command line argument description + 0 // the number of command line arguments for this test + ) + {} + + template <typename matrix_type, typename rv_type, typename cv_type> + void test_gemv_stuff( + matrix_type& m, + cv_type& cv, + rv_type& rv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + cv_type cv2; + rv_type rv2; + typedef typename matrix_type::type scalar_type; + scalar_type val; + + counter_gemv() = 0; + cv2 = m*cv; + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + cv2 = m*2*cv; + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + cv2 = m*2*trans(rv); + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + rv2 = trans(m*2*cv); + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + rv2 = rv*m; + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + rv2 = (rv + rv)*m; + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + rv2 = trans(cv)*m; + DLIB_TEST(counter_gemv() == 1); + dlog << dlib::LTRACE << 1; + + counter_gemv() = 0; + rv2 = trans(cv)*trans(m) + rv*trans(m); + DLIB_TEST(counter_gemv() == 2); + dlog << dlib::LTRACE << 2; + + counter_gemv() = 0; + cv2 = m*trans(trans(cv)*trans(m) + 3*rv*trans(m)); + DLIB_TEST(counter_gemv() == 3); + + // This does one dot and one gemv + counter_gemv() = 0; + val = trans(cv)*m*trans(rv); + DLIB_TEST_MSG(counter_gemv() == 1, counter_gemv()); + + // This does one dot and two gemv + counter_gemv() = 0; + val = (trans(cv)*m)*(m*trans(rv)); + DLIB_TEST_MSG(counter_gemv() == 2, counter_gemv()); + + // This does one dot and two gemv + counter_gemv() = 0; + val = trans(cv)*m*trans(m)*trans(rv); + DLIB_TEST_MSG(counter_gemv() == 2, counter_gemv()); + } + + + template <typename matrix_type, typename rv_type, typename cv_type> + void test_gemv_stuff_conj( + matrix_type& m, + cv_type& cv, + rv_type& rv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + cv_type cv2; + rv_type rv2; + + counter_gemv() = 0; + cv2 = trans(cv)*conj(m); + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + cv2 = conj(trans(m))*rv; + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + cv2 = conj(trans(m))*trans(cv); + DLIB_TEST(counter_gemv() == 1); + + counter_gemv() = 0; + cv2 = trans(trans(cv)*conj(2*m) + conj(3*trans(m))*rv + conj(trans(m)*3)*trans(cv)); + DLIB_TEST(counter_gemv() == 3); + + } + + void perform_test ( + ) + { + using namespace dlib; + typedef dlib::memory_manager<char>::kernel_1a mm; + + dlog << dlib::LINFO << "test double"; + { + matrix<double> m = randm(4,4); + matrix<double,0,1> cv = randm(4,1); + matrix<double,1,0> rv = randm(1,4); + test_gemv_stuff(m,cv,rv); + } + + dlog << dlib::LINFO << "test float"; + { + matrix<float> m = matrix_cast<float>(randm(4,4)); + matrix<float,0,1> cv = matrix_cast<float>(randm(4,1)); + matrix<float,1,0> rv = matrix_cast<float>(randm(1,4)); + test_gemv_stuff(m,cv,rv); + } + + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<complex<double> > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,0,1> cv = complex_matrix(randm(4,1), randm(4,1)); + matrix<complex<double>,1,0> rv = complex_matrix(randm(1,4), randm(1,4)); + test_gemv_stuff(m,cv,rv); + } + + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<complex<float> > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,0,1> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + matrix<complex<float>,1,0> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + test_gemv_stuff(m,cv,rv); + } + + + dlog << dlib::LINFO << "test double"; + { + matrix<double,0,0,mm,column_major_layout> m = randm(4,4); + matrix<double,0,1,mm,column_major_layout> cv = randm(4,1); + matrix<double,1,0,mm,column_major_layout> rv = randm(1,4); + test_gemv_stuff(m,cv,rv); + } + + dlog << dlib::LINFO << "test float"; + { + matrix<float,0,0,mm,column_major_layout> m = matrix_cast<float>(randm(4,4)); + matrix<float,0,1,mm,column_major_layout> cv = matrix_cast<float>(randm(4,1)); + matrix<float,1,0,mm,column_major_layout> rv = matrix_cast<float>(randm(1,4)); + test_gemv_stuff(m,cv,rv); + } + + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<complex<double>,0,0,mm,column_major_layout > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,0,1,mm,column_major_layout> cv = complex_matrix(randm(4,1), randm(4,1)); + matrix<complex<double>,1,0,mm,column_major_layout> rv = complex_matrix(randm(1,4), randm(1,4)); + test_gemv_stuff(m,cv,rv); + } + + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<complex<float>,0,0,mm,column_major_layout > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,0,1,mm,column_major_layout> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + matrix<complex<float>,1,0,mm,column_major_layout> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + test_gemv_stuff(m,cv,rv); + } + + + print_spinner(); + } + }; + + blas_bindings_gemv_tester a; + +} + + diff --git a/ml/dlib/dlib/test/blas_bindings/blas_bindings_ger.cpp b/ml/dlib/dlib/test/blas_bindings/blas_bindings_ger.cpp new file mode 100644 index 000000000..2aac834d2 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/blas_bindings_ger.cpp @@ -0,0 +1,200 @@ +// Copyright (C) 2009 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. + +#include "../tester.h" +#include <dlib/matrix.h> + +#ifndef DLIB_USE_BLAS +#error "BLAS bindings must be used for this test to make any sense" +#endif + +namespace dlib +{ + namespace blas_bindings + { + // This is a little screwy. This function is used inside the BLAS + // bindings to count how many times each of the BLAS functions get called. +#ifdef DLIB_TEST_BLAS_BINDINGS + int& counter_ger() { static int counter = 0; return counter; } +#endif + + } +} + +namespace +{ + using namespace test; + using namespace std; + // Declare the logger we will use in this test. The name of the logger + // should start with "test." + dlib::logger dlog("test.ger"); + + + class blas_bindings_ger_tester : public tester + { + public: + blas_bindings_ger_tester ( + ) : + tester ( + "test_ger", // the command line argument name for this test + "Run tests for GER routines.", // the command line argument description + 0 // the number of command line arguments for this test + ) + {} + + template <typename matrix_type, typename cv_type, typename rv_type> + void test_ger_stuff( + matrix_type& m, + rv_type& rv, + cv_type& cv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + rv_type rv2; + cv_type cv2; + matrix_type m2; + + counter_ger() = 0; + m2 = m + cv*rv; + DLIB_TEST_MSG(counter_ger() == 1, counter_ger()); + + counter_ger() = 0; + m += trans(rv)*rv; + DLIB_TEST(counter_ger() == 1); + + counter_ger() = 0; + m += trans(rv)*trans(cv); + DLIB_TEST(counter_ger() == 1); + + counter_ger() = 0; + m += cv*trans(cv); + DLIB_TEST(counter_ger() == 1); + + counter_ger() = 0; + m += trans(rv)*rv + trans(cv*3*rv); + DLIB_TEST(counter_ger() == 2); + } + + + template <typename matrix_type, typename cv_type, typename rv_type> + void test_ger_stuff_conj( + matrix_type& m, + rv_type& rv, + cv_type& cv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + rv_type rv2; + cv_type cv2; + matrix_type m2; + + counter_ger() = 0; + m += cv*conj(rv); + DLIB_TEST_MSG(counter_ger() == 1, counter_ger()); + + counter_ger() = 0; + m += trans(rv)*conj(rv); + DLIB_TEST(counter_ger() == 1); + + counter_ger() = 0; + m += trans(rv)*conj(trans(cv)); + DLIB_TEST(counter_ger() == 1); + + counter_ger() = 0; + m += cv*trans(conj(cv)); + DLIB_TEST(counter_ger() == 1); + + counter_ger() = 0; + m += trans(rv)*rv + trans(cv*3*conj(rv)); + DLIB_TEST(counter_ger() == 2); + } + + void perform_test ( + ) + { + using namespace dlib; + typedef dlib::memory_manager<char>::kernel_1a mm; + + dlog << dlib::LINFO << "test double"; + { + matrix<double> m = randm(4,4); + matrix<double,1,0> rv = randm(1,4); + matrix<double,0,1> cv = randm(4,1); + test_ger_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test float"; + { + matrix<float> m = matrix_cast<float>(randm(4,4)); + matrix<float,1,0> rv = matrix_cast<float>(randm(1,4)); + matrix<float,0,1> cv = matrix_cast<float>(randm(4,1)); + test_ger_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<complex<double> > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,1,0> rv = complex_matrix(randm(1,4), randm(1,4)); + matrix<complex<double>,0,1> cv = complex_matrix(randm(4,1), randm(4,1)); + test_ger_stuff(m,rv,cv); + test_ger_stuff_conj(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<complex<float> > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,1,0> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + matrix<complex<float>,0,1> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + test_ger_stuff(m,rv,cv); + test_ger_stuff_conj(m,rv,cv); + } + + + dlog << dlib::LINFO << "test double"; + { + matrix<double,0,0,mm,column_major_layout> m = randm(4,4); + matrix<double,1,0,mm,column_major_layout> rv = randm(1,4); + matrix<double,0,1,mm,column_major_layout> cv = randm(4,1); + test_ger_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test float"; + { + matrix<float,0,0,mm,column_major_layout> m = matrix_cast<float>(randm(4,4)); + matrix<float,1,0,mm,column_major_layout> rv = matrix_cast<float>(randm(1,4)); + matrix<float,0,1,mm,column_major_layout> cv = matrix_cast<float>(randm(4,1)); + test_ger_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<complex<double>,0,0,mm,column_major_layout > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,1,0,mm,column_major_layout> rv = complex_matrix(randm(1,4), randm(1,4)); + matrix<complex<double>,0,1,mm,column_major_layout> cv = complex_matrix(randm(4,1), randm(4,1)); + test_ger_stuff(m,rv,cv); + test_ger_stuff_conj(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<complex<float>,0,0,mm,column_major_layout > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,1,0,mm,column_major_layout> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + matrix<complex<float>,0,1,mm,column_major_layout> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + test_ger_stuff(m,rv,cv); + test_ger_stuff_conj(m,rv,cv); + } + + + print_spinner(); + } + }; + + blas_bindings_ger_tester a; + +} + + diff --git a/ml/dlib/dlib/test/blas_bindings/blas_bindings_scal_axpy.cpp b/ml/dlib/dlib/test/blas_bindings/blas_bindings_scal_axpy.cpp new file mode 100644 index 000000000..d1a7b99e4 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/blas_bindings_scal_axpy.cpp @@ -0,0 +1,261 @@ +// Copyright (C) 2009 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. + +#include "../tester.h" +#include <dlib/matrix.h> + +#ifndef DLIB_USE_BLAS +#error "BLAS bindings must be used for this test to make any sense" +#endif + +namespace dlib +{ + namespace blas_bindings + { + // This is a little screwy. This function is used inside the BLAS + // bindings to count how many times each of the BLAS functions get called. +#ifdef DLIB_TEST_BLAS_BINDINGS + int& counter_axpy() { static int counter = 0; return counter; } + int& counter_scal() { static int counter = 0; return counter; } +#endif + + } +} + +namespace +{ + using namespace test; + using namespace std; + // Declare the logger we will use in this test. The name of the logger + // should start with "test." + dlib::logger dlog("test.scal_axpy"); + + + class blas_bindings_scal_axpy_tester : public tester + { + public: + blas_bindings_scal_axpy_tester ( + ) : + tester ( + "test_scal_axpy", // the command line argument name for this test + "Run tests for DOT routines.", // the command line argument description + 0 // the number of command line arguments for this test + ) + {} + + template <typename matrix_type, typename cv_type, typename rv_type> + void test_scal_axpy_stuff( + matrix_type& m, + rv_type& rv, + cv_type& cv + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + rv_type rv2 = rv; + cv_type cv2 = cv; + matrix_type m2 = m; + typedef typename matrix_type::type scalar_type; + scalar_type val; + + counter_scal() = 0; + m = 5*m; + DLIB_TEST(counter_scal() == 1); + + counter_scal() = 0; + rv = 5*rv; + DLIB_TEST(counter_scal() == 1); + + counter_scal() = 0; + rv = 5*rv; + DLIB_TEST(counter_scal() == 1); + + + counter_axpy() = 0; + m2 += 5*m; + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + rv2 += 5*rv; + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + rv2 += 5*rv; + DLIB_TEST(counter_axpy() == 1); + + + + counter_scal() = 0; + m = m*5; + DLIB_TEST(counter_scal() == 1); + + counter_scal() = 0; + rv = rv*5; + DLIB_TEST(counter_scal() == 1); + + counter_scal() = 0; + cv = cv*5; + DLIB_TEST(counter_scal() == 1); + + + counter_axpy() = 0; + m2 += m*5; + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + rv2 += rv*5; + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + cv2 += cv*5; + DLIB_TEST(counter_axpy() == 1); + + + + + counter_axpy() = 0; + m2 = m2 + m*5; + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + rv2 = rv2 + rv*5; + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + cv2 = cv2 + cv*5; + DLIB_TEST(counter_axpy() == 1); + + + counter_axpy() = 0; + cv2 = 1; + cv = 1; + cv2 = 2*cv2 + cv*5; + DLIB_TEST(counter_axpy() == 1); + DLIB_TEST(max(abs(cv2 - 7)) == 0); + + + counter_axpy() = 0; + rv2 = 1; + rv = 1; + rv2 = 2*rv2 + rv*5; + DLIB_TEST(counter_axpy() == 1); + DLIB_TEST(max(abs(rv2 - 7)) == 0); + + counter_axpy() = 0; + m2 = 1; + m = 1; + m2 = 2*m2 + m*5; + DLIB_TEST(counter_axpy() == 1); + DLIB_TEST(max(abs(m2 - 7)) == 0); + + + if (is_same_type<typename matrix_type::layout_type, row_major_layout>::value) + { + counter_axpy() = 0; + m2 = 1; + m = 1; + set_ptrm(&m2(0,0),m2.nr(),m2.nc()) = 2*m2 + m*5; + DLIB_TEST(max(abs(m2 - 7)) == 0); + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + m2 = 1; + m = 1; + set_ptrm(&m2(0,0),m2.nr(),m2.nc()) = 2*mat(&m2(0,0),m2.nr(),m2.nc()) + mat(&m(0,0),m.nr(),m.nc())*5; + DLIB_TEST(max(abs(m2 - 7)) == 0); + DLIB_TEST(counter_axpy() == 1); + + counter_axpy() = 0; + m2 = 1; + m = 1; + m2 = 2*mat(&m2(0,0),m2.nr(),m2.nc()) + mat(&m(0,0),m.nr(),m.nc())*5; + DLIB_TEST(max(abs(m2 - 7)) == 0); + DLIB_TEST(counter_axpy() == 1); + } + + } + + + + void perform_test ( + ) + { + using namespace dlib; + typedef dlib::memory_manager<char>::kernel_1a mm; + + dlog << dlib::LINFO << "test double"; + { + matrix<double> m = randm(4,4); + matrix<double,1,0> rv = randm(1,4); + matrix<double,0,1> cv = randm(4,1); + test_scal_axpy_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test float"; + { + matrix<float> m = matrix_cast<float>(randm(4,4)); + matrix<float,1,0> rv = matrix_cast<float>(randm(1,4)); + matrix<float,0,1> cv = matrix_cast<float>(randm(4,1)); + test_scal_axpy_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<double>"; + { + matrix<complex<double> > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,1,0> rv = complex_matrix(randm(1,4), randm(1,4)); + matrix<complex<double>,0,1> cv = complex_matrix(randm(4,1), randm(4,1)); + test_scal_axpy_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<float>"; + { + matrix<complex<float> > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,1,0> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + matrix<complex<float>,0,1> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + test_scal_axpy_stuff(m,rv,cv); + } + + + dlog << dlib::LINFO << "test double, column major"; + { + matrix<double,0,0,mm,column_major_layout> m = randm(4,4); + matrix<double,1,0,mm,column_major_layout> rv = randm(1,4); + matrix<double,0,1,mm,column_major_layout> cv = randm(4,1); + test_scal_axpy_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test float, column major"; + { + matrix<float,0,0,mm,column_major_layout> m = matrix_cast<float>(randm(4,4)); + matrix<float,1,0,mm,column_major_layout> rv = matrix_cast<float>(randm(1,4)); + matrix<float,0,1,mm,column_major_layout> cv = matrix_cast<float>(randm(4,1)); + test_scal_axpy_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<double>, column major"; + { + matrix<complex<double>,0,0,mm,column_major_layout > m = complex_matrix(randm(4,4), randm(4,4)); + matrix<complex<double>,1,0,mm,column_major_layout> rv = complex_matrix(randm(1,4), randm(1,4)); + matrix<complex<double>,0,1,mm,column_major_layout> cv = complex_matrix(randm(4,1), randm(4,1)); + test_scal_axpy_stuff(m,rv,cv); + } + + dlog << dlib::LINFO << "test complex<float>, column major"; + { + matrix<complex<float>,0,0,mm,column_major_layout > m = matrix_cast<complex<float> >(complex_matrix(randm(4,4), randm(4,4))); + matrix<complex<float>,1,0,mm,column_major_layout> rv = matrix_cast<complex<float> >(complex_matrix(randm(1,4), randm(1,4))); + matrix<complex<float>,0,1,mm,column_major_layout> cv = matrix_cast<complex<float> >(complex_matrix(randm(4,1), randm(4,1))); + test_scal_axpy_stuff(m,rv,cv); + } + + + print_spinner(); + } + }; + + blas_bindings_scal_axpy_tester a; + +} + + diff --git a/ml/dlib/dlib/test/blas_bindings/vector.cpp b/ml/dlib/dlib/test/blas_bindings/vector.cpp new file mode 100644 index 000000000..0a6f5f301 --- /dev/null +++ b/ml/dlib/dlib/test/blas_bindings/vector.cpp @@ -0,0 +1,115 @@ +// Copyright (C) 2009 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. + +#include "../tester.h" +#include <dlib/geometry.h> +#include <dlib/matrix.h> + +#ifndef DLIB_USE_BLAS +#error "BLAS bindings must be used for this test to make any sense" +#endif + +namespace dlib +{ + namespace blas_bindings + { + +#ifdef DLIB_TEST_BLAS_BINDINGS + extern int& counter_gemm(); + extern int& counter_gemv(); + extern int& counter_ger(); + extern int& counter_dot(); +#endif + + } +} + +namespace +{ + using namespace test; + using namespace std; + // Declare the logger we will use in this test. The name of the logger + // should start with "test." + dlib::logger dlog("test.vector"); + + + class vector_tester : public tester + { + public: + vector_tester ( + ) : + tester ( + "test_vector", // the command line argument name for this test + "Run tests on dlib::vector.", // the command line argument description + 0 // the number of command line arguments for this test + ) + {} + + template <typename type> + void test_vector( + ) const + { + using namespace dlib; + using namespace dlib::blas_bindings; + + dlib::vector<type,2> a2, b2, c2; + dlib::vector<type,3> a3, b3, c3; + + matrix<type> mat2(2,2), mat3(3,3); + mat2 = 0; + mat3 = 0; + + type var = 0; + + // We want to make sure that the BLAS bindings are being called for the 2D and 3D vectors. That would + // be very slow. + counter_gemm() = 0; + counter_gemv() = 0; + counter_ger() = 0; + counter_dot() = 0; + + var = trans(a2)*(a2); + var = dot(a2,a2); + + a2 = mat2*b2; + var = trans(b2)*mat2*b2; + + var = trans(a3)*(a3); + var = dot(a3,a3); + + a3 = mat3*b3; + var = trans(b3)*mat3*b3; + + mat3 = c3*trans(a3); + mat2 = c2*trans(a2); + + DLIB_TEST(counter_gemm() == 0 && counter_gemv() == 0 && counter_ger() == 0 && counter_dot() == 0); + + } + + void perform_test ( + ) + { + using namespace dlib; + + dlog << dlib::LINFO << "test double"; + test_vector<double>(); + + dlog << dlib::LINFO << "test float"; + test_vector<float>(); + + dlog << dlib::LINFO << "test int"; + test_vector<int>(); + + dlog << dlib::LINFO << "test short"; + test_vector<short>(); + + print_spinner(); + } + }; + + vector_tester a; + +} + + |