Bugfix in elementwise operations for matrices
This commit is contained in:
@@ -67,6 +67,7 @@ public:
|
||||
array& operator/=(array_expression const &);
|
||||
|
||||
//Indexing operators
|
||||
const scalar operator[](int_t) const;
|
||||
scalar operator[](int_t);
|
||||
array operator[](slice const &);
|
||||
array operator()(slice const &, slice const &);
|
||||
|
@@ -333,6 +333,14 @@ std::ostream & operator<<(std::ostream & os, scalar const & s)
|
||||
|
||||
/*--- Binary Operators ----*/
|
||||
//-----------------------------------
|
||||
template<class U, class V>
|
||||
size4 elementwise_size(U const & u, V const & v)
|
||||
{
|
||||
if(max(u.shape())==1)
|
||||
return v.shape();
|
||||
return u.shape();
|
||||
}
|
||||
|
||||
template<class U, class V>
|
||||
bool check_elementwise(U const & u, V const & v)
|
||||
{
|
||||
@@ -342,19 +350,19 @@ bool check_elementwise(U const & u, V const & v)
|
||||
#define DEFINE_ELEMENT_BINARY_OPERATOR(OP, OPNAME) \
|
||||
array_expression OPNAME (array_expression const & x, array_expression const & y) \
|
||||
{ assert(check_elementwise(x, y));\
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), std::max(max(x.shape()), max(y.shape())) ); } \
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), elementwise_size(x, y) ); } \
|
||||
\
|
||||
array_expression OPNAME (array const & x, array_expression const & y) \
|
||||
{ assert(check_elementwise(x, y));\
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), std::max(max(x.shape()), max(y.shape()))); } \
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), elementwise_size(x, y)); } \
|
||||
\
|
||||
array_expression OPNAME (array_expression const & x, array const & y) \
|
||||
{ assert(check_elementwise(x, y));\
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), std::max(max(x.shape()), max(y.shape()))); } \
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), elementwise_size(x, y)); } \
|
||||
\
|
||||
array_expression OPNAME (array const & x, array const & y) \
|
||||
{ assert(check_elementwise(x, y));\
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), x.context(), x.dtype(), std::max(max(x.shape()), max(y.shape()))); }\
|
||||
return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), x.context(), x.dtype(), elementwise_size(x, y)); }\
|
||||
\
|
||||
array_expression OPNAME (array_expression const & x, value_scalar const & y) \
|
||||
{ return array_expression(x, y, op_element(OPERATOR_BINARY_TYPE_FAMILY, OP), x.shape()); } \
|
||||
|
@@ -1,5 +1,5 @@
|
||||
get_property(ATIDLAS_PATH TARGET atidlas PROPERTY LOCATION)
|
||||
foreach(PROG vaxpy reduction mreduction mproduct)
|
||||
foreach(PROG maxpy vaxpy reduction mreduction mproduct)
|
||||
add_executable(${PROG}-test ${PROG}.cpp)
|
||||
add_test(${PROG} ${PROG}-test)
|
||||
target_link_libraries(${PROG}-test atidlas ${OPENCL_LIBRARIES})
|
||||
|
182
tests/maxpy.cpp
182
tests/maxpy.cpp
@@ -1,87 +1,86 @@
|
||||
#include "common.hpp"
|
||||
#include <cmath>
|
||||
#include "viennacl/matrix.hpp"
|
||||
#include <iostream>
|
||||
#include "common.hpp"
|
||||
#include "atidlas/array.h"
|
||||
|
||||
#include "atidlas/templates/matrix_axpy.hpp"
|
||||
#include "atidlas/execute.hpp"
|
||||
namespace ad = atidlas;
|
||||
typedef atidlas::int_t int_t;
|
||||
|
||||
template<typename NumericT, class AType, class BType, class CType>
|
||||
void test_element_wise_matrix(NumericT epsilon, AType & cA, BType & cB, CType & cC)
|
||||
template<typename T>
|
||||
void test(T epsilon, simple_matrix_base<T> & cA, simple_matrix_base<T>& cB, simple_matrix_base<T>& cC,
|
||||
ad::array& A, ad::array& B, ad::array& C)
|
||||
{
|
||||
using namespace viennacl::linalg;
|
||||
using namespace std;
|
||||
|
||||
atidlas::matrix_axpy_parameters parameters(1, 8, 8, 32, 32, atidlas::FETCH_FROM_GLOBAL_STRIDED);
|
||||
int failure_count = 0;
|
||||
CType tmp = cC;
|
||||
|
||||
NumericT a = 3.12, b = 3.5;
|
||||
viennacl::scalar<NumericT> da(a), db(b);
|
||||
int_t M = cC.size1();
|
||||
int_t N = cC.size2();
|
||||
|
||||
viennacl::matrix<NumericT, viennacl::column_major> Atmp(cA.internal_size1(), cA.internal_size2());
|
||||
typename matrix_maker<AType, viennacl::column_major>::result_type A = matrix_maker<AType, viennacl::column_major>::make(Atmp, cA);
|
||||
viennacl::matrix<NumericT, viennacl::column_major> Btmp(cB.internal_size1(), cB.internal_size2());
|
||||
typename matrix_maker<BType, viennacl::column_major>::result_type B = matrix_maker<BType, viennacl::column_major>::make(Btmp, cB);
|
||||
viennacl::matrix<NumericT, viennacl::column_major> Ctmp(cC.internal_size1(), cC.internal_size2());
|
||||
typename matrix_maker<CType, viennacl::column_major>::result_type C = matrix_maker<CType, viennacl::column_major>::make(Ctmp, cC);
|
||||
T aa = 3.12, bb=3.5;
|
||||
atidlas::value_scalar a(aa), b(bb);
|
||||
atidlas::scalar da(a), db(b);
|
||||
|
||||
|
||||
#define RUN_TEST(NAME, CPU_LOOP, GPU_STATEMENT) \
|
||||
cout << NAME "..." << flush;\
|
||||
for(int_t i = 0 ; i < cC.size1() ; ++i)\
|
||||
for(int_t j = 0 ; j < cC.size2() ; ++j)\
|
||||
simple_vector<T> buffer(M*N);
|
||||
#define RUN_TEST(NAME, CPU_LOOP, GPU_EXPR) \
|
||||
{\
|
||||
std::cout << NAME "..." << std::flush;\
|
||||
for(int_t i = 0 ; i < M ; ++i)\
|
||||
for(int_t j = 0 ; j < N ; ++j)\
|
||||
CPU_LOOP;\
|
||||
atidlas::execute(atidlas::matrix_axpy_template(parameters),\
|
||||
GPU_STATEMENT,\
|
||||
viennacl::ocl::current_context(), true);\
|
||||
viennacl::copy(C, tmp);\
|
||||
if(failure_matrix(cC, tmp, epsilon))\
|
||||
GPU_EXPR;\
|
||||
atidlas::copy(C, buffer.data());\
|
||||
std::vector<T> cCbuffer(M*N);\
|
||||
for(int i = 0 ; i < M ; ++i)\
|
||||
for(int j = 0 ; j < N ; ++j)\
|
||||
cCbuffer[i + j*M] = cC(i,j);\
|
||||
if(failure_vector(cCbuffer, buffer, epsilon))\
|
||||
{\
|
||||
failure_count++;\
|
||||
cout << " [Failure!]" << endl;\
|
||||
std::cout << " [Failure!]" << std::endl;\
|
||||
}\
|
||||
else\
|
||||
cout << endl;
|
||||
std::cout << std::endl;\
|
||||
}
|
||||
|
||||
RUN_TEST("C = A", cC(i,j) = cA(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), A))
|
||||
RUN_TEST("C = A + B", cC(i,j) = cA(i,j) + cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), A + B))
|
||||
RUN_TEST("C = A - B", cC(i,j) = cA(i,j) - cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), A - B))
|
||||
RUN_TEST("C = A + B + C", cC(i,j) = cA(i,j) + cB(i,j) + cC(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), A + B + C))
|
||||
RUN_TEST("C = A", cC(i,j) = cA(i,j), C = A)
|
||||
RUN_TEST("C = A + B", cC(i,j) = cA(i,j) + cB(i,j), C = A + B)
|
||||
RUN_TEST("C = A - B", cC(i,j) = cA(i,j) - cB(i,j), C = A - B)
|
||||
RUN_TEST("C = A + B + C", cC(i,j) = cA(i,j) + cB(i,j) + cC(i,j), C = A + B + C)
|
||||
|
||||
RUN_TEST("C = a*A", cC(i,j) = a*cA(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), a*A))
|
||||
RUN_TEST("C = da*A", cC(i,j) = a*cA(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), da*A))
|
||||
RUN_TEST("C = a*A + b*B", cC(i,j) = a*cA(i,j) + b*cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), a*A + b*B))
|
||||
RUN_TEST("C = da*A + b*B", cC(i,j) = a*cA(i,j) + b*cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), da*A + b*B))
|
||||
RUN_TEST("C = a*A + db*B", cC(i,j) = a*cA(i,j) + b*cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), a*A + db*B))
|
||||
RUN_TEST("C = da*A + db*B", cC(i,j) = a*cA(i,j) + b*cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), da*A + db*B))
|
||||
RUN_TEST("C = a*A", cC(i,j) = aa*cA(i,j), C = a*A)
|
||||
RUN_TEST("C = da*A", cC(i,j) = aa*cA(i,j), C = da*A)
|
||||
RUN_TEST("C = a*A + b*B", cC(i,j) = aa*cA(i,j) + bb*cB(i,j), C= a*A + b*B)
|
||||
RUN_TEST("C = da*A + b*B", cC(i,j) = aa*cA(i,j) + bb*cB(i,j), C= da*A + b*B)
|
||||
RUN_TEST("C = a*A + db*B", cC(i,j) = aa*cA(i,j) + bb*cB(i,j), C= a*A + db*B)
|
||||
RUN_TEST("C = da*A + db*B", cC(i,j) = aa*cA(i,j) + bb*cB(i,j), C= da*A + db*B)
|
||||
|
||||
// RUN_TEST("C = abs(A)", cC(i,j) = abs(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_abs(A)))
|
||||
RUN_TEST("C = acos(A)", cC(i,j) = acos(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_acos(A)))
|
||||
RUN_TEST("C = asin(A)", cC(i,j) = asin(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_asin(A)))
|
||||
RUN_TEST("C = atan(A)", cC(i,j) = atan(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_atan(A)))
|
||||
RUN_TEST("C = ceil(A)", cC(i,j) = ceil(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_ceil(A)))
|
||||
RUN_TEST("C = cos(A)", cC(i,j) = cos(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_cos(A)))
|
||||
RUN_TEST("C = cosh(A)", cC(i,j) = cosh(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_cosh(A)))
|
||||
RUN_TEST("C = exp(A)", cC(i,j) = exp(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_exp(A)))
|
||||
RUN_TEST("C = fabs(A)", cC(i,j) = fabs(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_fabs(A)))
|
||||
RUN_TEST("C = floor(A)", cC(i,j) = floor(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_floor(A)))
|
||||
RUN_TEST("C = log(A)", cC(i,j) = log(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_log(A)))
|
||||
RUN_TEST("C = log10(A)", cC(i,j) = log10(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_log10(A)))
|
||||
RUN_TEST("C = sin(A)", cC(i,j) = sin(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_sin(A)))
|
||||
RUN_TEST("C = sinh(A)", cC(i,j) = sinh(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_sinh(A)))
|
||||
RUN_TEST("C = sqrt(A)", cC(i,j) = sqrt(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_sqrt(A)))
|
||||
RUN_TEST("C = tan(A)", cC(i,j) = tan(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_tan(A)))
|
||||
RUN_TEST("C = tanh(A)", cC(i,j) = tanh(cA(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_tanh(A)))
|
||||
RUN_TEST("C = exp(A)", cC(i,j) = exp(cA(i,j)), C= exp(A))
|
||||
RUN_TEST("C = abs(A)", cC(i,j) = abs(cA(i,j)), C= abs(A))
|
||||
RUN_TEST("C = acos(A)", cC(i,j) = acos(cA(i,j)), C= acos(A))
|
||||
RUN_TEST("C = asin(A)", cC(i,j) = asin(cA(i,j)), C= asin(A))
|
||||
RUN_TEST("C = atan(A)", cC(i,j) = atan(cA(i,j)), C= atan(A))
|
||||
RUN_TEST("C = ceil(A)", cC(i,j) = ceil(cA(i,j)), C= ceil(A))
|
||||
RUN_TEST("C = cos(A)", cC(i,j) = cos(cA(i,j)), C= cos(A))
|
||||
RUN_TEST("C = cosh(A)", cC(i,j) = cosh(cA(i,j)), C= cosh(A))
|
||||
RUN_TEST("C = floor(A)", cC(i,j) = floor(cA(i,j)), C= floor(A))
|
||||
RUN_TEST("C = log(A)", cC(i,j) = log(cA(i,j)), C= log(A))
|
||||
RUN_TEST("C = log10(A)", cC(i,j) = log10(cA(i,j)), C= log10(A))
|
||||
RUN_TEST("C = sin(A)", cC(i,j) = sin(cA(i,j)), C= sin(A))
|
||||
RUN_TEST("C = sinh(A)", cC(i,j) = sinh(cA(i,j)), C= sinh(A))
|
||||
RUN_TEST("C = sqrt(A)", cC(i,j) = sqrt(cA(i,j)), C= sqrt(A))
|
||||
RUN_TEST("C = tan(A)", cC(i,j) = tan(cA(i,j)), C= tan(A))
|
||||
RUN_TEST("C = tanh(A)", cC(i,j) = tanh(cA(i,j)), C= tanh(A))
|
||||
|
||||
RUN_TEST("C = A./B", cC(i,j) = cA(i,j)/cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_div(A,B)))
|
||||
RUN_TEST("C = A==B", cC(i,j) = cA(i,j)==cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_eq(A,B)))
|
||||
RUN_TEST("C = A>=B", cC(i,j) = cA(i,j)>=cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_geq(A,B)))
|
||||
RUN_TEST("C = A>B", cC(i,j) = cA(i,j)>cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_greater(A,B)))
|
||||
RUN_TEST("C = A<=B", cC(i,j) = cA(i,j)<=cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_leq(A,B)))
|
||||
RUN_TEST("C = A<B", cC(i,j) = cA(i,j)<cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_less(A,B)))
|
||||
RUN_TEST("C = A!=B", cC(i,j) = cA(i,j)!=cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_neq(A,B)))
|
||||
RUN_TEST("C = pow(A,B)", cC(i,j) = pow(cA(i,j), cB(i,j)), viennacl::symbolic_expression(C, viennacl::op_assign(), element_pow(A,B)))
|
||||
RUN_TEST("C = A.*B", cC(i,j) = cA(i,j)*cB(i,j), viennacl::symbolic_expression(C, viennacl::op_assign(), element_prod(A,B)))
|
||||
RUN_TEST("z = x.*y", cC(i,j) = cA(i,j)*cB(i,j), C= A*B)
|
||||
RUN_TEST("z = x./y", cC(i,j) = cA(i,j)/cB(i,j), C= A/B)
|
||||
RUN_TEST("z = x==y", cC(i,j) = cA(i,j)==cB(i,j), C= A==B)
|
||||
RUN_TEST("z = x>=y", cC(i,j) = cA(i,j)>=cB(i,j), C= A>=B)
|
||||
RUN_TEST("z = x>y", cC(i,j) = cA(i,j)>cB(i,j), C= A>B)
|
||||
RUN_TEST("z = x<=y", cC(i,j) = cA(i,j)<=cB(i,j), C= A<=B)
|
||||
RUN_TEST("z = x<y", cC(i,j) = cA(i,j)<cB(i,j), C= A<B)
|
||||
RUN_TEST("z = x!=y", cC(i,j) = cA(i,j)!=cB(i,j), C= A!=B)
|
||||
RUN_TEST("z = pow(x,y)", cC(i,j) = pow(cA(i,j), cB(i,j)), C= pow(A,B))
|
||||
|
||||
#undef RUN_TEST
|
||||
|
||||
@@ -89,48 +88,27 @@ void test_element_wise_matrix(NumericT epsilon, AType & cA, BType & cB, CType &
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
template<typename NumericT>
|
||||
void test_impl(NumericT epsilon)
|
||||
template<typename T>
|
||||
void test_impl(T epsilon)
|
||||
{
|
||||
int_t M = 241;
|
||||
int_t N = 278;
|
||||
INIT_MATRIX_AND_PROXIES(M, 4, 5, N, 7, 6, C);
|
||||
INIT_MATRIX_AND_PROXIES(M, 2, 4, N, 5, 8, A);
|
||||
INIT_MATRIX_AND_PROXIES(M, 2, 3, N, 3, 4, B);
|
||||
using atidlas::_;
|
||||
|
||||
#define TEST_OPERATIONS(CTYPE, ATYPE, BTYPE)\
|
||||
std::cout << "> C : " #CTYPE " | A : " #ATYPE " | B : " #BTYPE << std::endl;\
|
||||
test_element_wise_matrix(epsilon, A_ ## ATYPE, B_ ## BTYPE, C_ ## CTYPE);\
|
||||
int_t M = 1324;
|
||||
int_t N = 1143;
|
||||
int_t SUBM = 184;
|
||||
int_t SUBN = 145;
|
||||
|
||||
TEST_OPERATIONS(matrix, matrix, matrix)
|
||||
TEST_OPERATIONS(matrix, matrix, range)
|
||||
TEST_OPERATIONS(matrix, matrix, slice)
|
||||
TEST_OPERATIONS(matrix, range, matrix)
|
||||
TEST_OPERATIONS(matrix, range, range)
|
||||
TEST_OPERATIONS(matrix, range, slice)
|
||||
TEST_OPERATIONS(matrix, slice, matrix)
|
||||
TEST_OPERATIONS(matrix, slice, range)
|
||||
TEST_OPERATIONS(matrix, slice, slice)
|
||||
INIT_MATRIX(M, SUBM, 5, 3, N, SUBN, 7, 2, cA, A);
|
||||
INIT_MATRIX(M, SUBM, 5, 3, N, SUBN, 7, 2, cB, B);
|
||||
INIT_MATRIX(M, SUBM, 5, 3, N, SUBN, 7, 2, cC, C);
|
||||
|
||||
TEST_OPERATIONS(range, matrix, matrix)
|
||||
TEST_OPERATIONS(range, matrix, range)
|
||||
TEST_OPERATIONS(range, matrix, slice)
|
||||
TEST_OPERATIONS(range, range, matrix)
|
||||
TEST_OPERATIONS(range, range, range)
|
||||
TEST_OPERATIONS(range, range, slice)
|
||||
TEST_OPERATIONS(range, slice, matrix)
|
||||
TEST_OPERATIONS(range, slice, range)
|
||||
TEST_OPERATIONS(range, slice, slice)
|
||||
#define TEST_OPERATIONS(XTYPE, YTYPE, ZTYPE)\
|
||||
test(epsilon, cA_ ## XTYPE, cB_ ## YTYPE, cC_ ## ZTYPE, A_ ## XTYPE, B_ ## YTYPE, C_ ## ZTYPE);\
|
||||
|
||||
TEST_OPERATIONS(slice, matrix, matrix)
|
||||
TEST_OPERATIONS(slice, matrix, range)
|
||||
TEST_OPERATIONS(slice, matrix, slice)
|
||||
TEST_OPERATIONS(slice, range, matrix)
|
||||
TEST_OPERATIONS(slice, range, range)
|
||||
TEST_OPERATIONS(slice, range, slice)
|
||||
TEST_OPERATIONS(slice, slice, matrix)
|
||||
TEST_OPERATIONS(slice, slice, range)
|
||||
TEST_OPERATIONS(slice, slice, slice)
|
||||
std::cout << "> standard..." << std::endl;
|
||||
TEST_OPERATIONS(matrix, matrix, matrix);
|
||||
std::cout << "> slice..." << std::endl;
|
||||
TEST_OPERATIONS(slice, slice, slice);
|
||||
}
|
||||
|
||||
int main()
|
||||
|
Reference in New Issue
Block a user