Matrix serialMult(const Matrix& matA, const Matrix& matB){ Matrix matC(matA.getRows(), matB.getCols()); for(int i = 0; i < matA.getRows(); i++){ for(int j = 0; j < matB.getCols(); j++){ for(int k = 0; k < matA.getCols(); k++){ matC.m_mat[i][j]+= matA.m_mat[i][k] * matB.m_mat[k][j]; } } } return matC; }
double serial(const Matrix* matA, const Matrix* matB){ gettimeofday(&serialT1, NULL); Matrix matC((*matA) * (*matB)); printf("CALCULATING SERIALLY:\n"); matC.printMat(); //printf("\n"); gettimeofday(&serialT2, NULL); serialTime = (serialT2.tv_sec - serialT1.tv_sec) * 1000.0; // sec to ms serialTime += (serialT2.tv_usec - serialT1.tv_usec) / 1000.0; return serialTime; }
int main() { int ii = 4; int jj = 3; int kk = 2; int ll = 5; int mm = 6; int nn = 7; quad_type matA(ll,kk,jj,ii); quad_type matB(nn,mm,jj,ii); quad_type matC(ll,kk,nn,mm); fill_random(matB); fill_random(matC); //fill_from_file(matB, "B.mat"); //fill_from_file(matC, "C.mat"); libmda::cindex<'i'> i; libmda::cindex<'j'> j; libmda::cindex<'k'> k; libmda::cindex<'l'> l; libmda::cindex<'m'> m; libmda::cindex<'n'> n; auto start = std::chrono::steady_clock::now(); matA(l,k,j,i) = matB(n,m,j,i) * matC(l,k,n,m); auto stop = std::chrono::steady_clock::now(); auto diff = stop - start; std::cout << std::chrono::duration<double, std::milli>(diff).count() << "ms" << std::endl; print(matA, "A.data"); print(matB, "B.data"); print(matC, "C.data"); return 0; }
void popblas::testBlas::test_gemm() { pop::F32 alpha = 1; pop::F32 beta = 1; pop::F32 dataA[] = {0, 3, 2, 1, -2, 3, 5, 6, 2, 0, 1, 2, 3, 6, 1}; pop::F32 dataB[] = {1, 3, 2, 4, 2, 2, 0, 5, 0, 1, 7, 2}; pop::MatN<2, pop::F32> matA(pop::VecN<2, int>(5, 3), dataA); pop::MatN<2, pop::F32> opMatA = matA.transpose(); pop::MatN<2, pop::F32> matB(pop::VecN<2, int>(3, 4), dataB); pop::MatN<2, pop::F32> opMatB = matB.transpose(); pop::MatN<2, pop::F32> matC(5, 4); matC = 0; blas::gemm(alpha, opMatA, 'T', opMatB, 'T', beta, matC); std::cout << matC << std::endl; }
ViennaCLStatus ViennaCLHostgemm_impl(ViennaCLBackend /*backend*/, ViennaCLOrder orderA, ViennaCLTranspose transA, ViennaCLOrder orderB, ViennaCLTranspose transB, ViennaCLOrder orderC, ViennaCLInt m, ViennaCLInt n, ViennaCLInt k, NumericT alpha, NumericT *A, ViennaCLInt offA_row, ViennaCLInt offA_col, ViennaCLInt incA_row, ViennaCLInt incA_col, ViennaCLInt lda, NumericT *B, ViennaCLInt offB_row, ViennaCLInt offB_col, ViennaCLInt incB_row, ViennaCLInt incB_col, ViennaCLInt ldb, NumericT beta, NumericT *C, ViennaCLInt offC_row, ViennaCLInt offC_col, ViennaCLInt incC_row, ViennaCLInt incC_col, ViennaCLInt ldc) { typedef typename viennacl::matrix_base<NumericT>::size_type size_type; typedef typename viennacl::matrix_base<NumericT>::difference_type difference_type; size_type A_size1 = static_cast<size_type>((transA == ViennaCLTrans) ? k : m); size_type A_size2 = static_cast<size_type>((transA == ViennaCLTrans) ? m : k); size_type B_size1 = static_cast<size_type>((transB == ViennaCLTrans) ? n : k); size_type B_size2 = static_cast<size_type>((transB == ViennaCLTrans) ? k : n); bool A_row_major = (orderA == ViennaCLRowMajor); bool B_row_major = (orderB == ViennaCLRowMajor); bool C_row_major = (orderC == ViennaCLRowMajor); viennacl::matrix_base<NumericT> matA(A, viennacl::MAIN_MEMORY, A_size1, size_type(offA_row), difference_type(incA_row), size_type(A_row_major ? m : lda), A_size2, size_type(offA_col), difference_type(incA_col), size_type(A_row_major ? lda : k), A_row_major); viennacl::matrix_base<NumericT> matB(B, viennacl::MAIN_MEMORY, B_size1, size_type(offB_row), difference_type(incB_row), size_type(B_row_major ? k : ldb), B_size2, size_type(offB_col), difference_type(incB_col), size_type(B_row_major ? ldb : n), B_row_major); viennacl::matrix_base<NumericT> matC(C, viennacl::MAIN_MEMORY, size_type(m), size_type(offC_row), difference_type(incC_row), size_type(C_row_major ? m : ldc), size_type(n), size_type(offC_col), difference_type(incC_col), size_type(C_row_major ? ldc : n), C_row_major); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); return ViennaCLSuccess; }
// Helper rotation function. mat3 Transform::rotate(const float degrees, const vec3& axis) { // YOUR CODE FOR HW1 HERE float rad = glm::radians(degrees); mat3 matA( 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 ); mat3 matB( axis.x*axis.x, axis.x*axis.y, axis.x*axis.z, axis.x*axis.y, axis.y*axis.y, axis.y*axis.z, axis.x*axis.z, axis.y*axis.z, axis.z*axis.z ); mat3 matC( 0.0, axis.z, -axis.y, -axis.z, 0.0, axis.x, axis.y, -axis.x, 0.0 ); mat3 rot = cos(rad) * matA + (1-cos(rad))*matB + sin(rad)*matC; // You will change this return call return rot; }
ViennaCLStatus ViennaCLOpenCLgemm_impl(ViennaCLBackend backend, ViennaCLOrder orderA, ViennaCLTranspose transA, ViennaCLOrder orderB, ViennaCLTranspose transB, ViennaCLOrder orderC, ViennaCLInt m, ViennaCLInt n, ViennaCLInt k, NumericT alpha, cl_mem A, ViennaCLInt offA_row, ViennaCLInt offA_col, ViennaCLInt incA_row, ViennaCLInt incA_col, ViennaCLInt lda, cl_mem B, ViennaCLInt offB_row, ViennaCLInt offB_col, ViennaCLInt incB_row, ViennaCLInt incB_col, ViennaCLInt ldb, NumericT beta, cl_mem C, ViennaCLInt offC_row, ViennaCLInt offC_col, ViennaCLInt incC_row, ViennaCLInt incC_col, ViennaCLInt ldc) { ViennaCLInt A_size1 = (transA == ViennaCLTrans) ? k : m; ViennaCLInt A_size2 = (transA == ViennaCLTrans) ? m : k; ViennaCLInt B_size1 = (transB == ViennaCLTrans) ? n : k; ViennaCLInt B_size2 = (transB == ViennaCLTrans) ? k : n; bool A_row_major = (orderA == ViennaCLRowMajor); bool B_row_major = (orderB == ViennaCLRowMajor); bool C_row_major = (orderC == ViennaCLRowMajor); viennacl::matrix_base<NumericT> matA(A, viennacl::ocl::get_context(backend->opencl_backend.context_id), A_size1, offA_row, incA_row, A_row_major ? m : lda, A_size2, offA_col, incA_col, A_row_major ? lda : k, A_row_major); viennacl::matrix_base<NumericT> matB(B, viennacl::ocl::get_context(backend->opencl_backend.context_id), B_size1, offB_row, incB_row, B_row_major ? k : ldb, B_size2, offB_col, incB_col, B_row_major ? ldb : n, B_row_major); viennacl::matrix_base<NumericT> matC(C, viennacl::ocl::get_context(backend->opencl_backend.context_id), m, offC_row, incC_row, C_row_major ? m : ldc, n, offC_col, incC_col, C_row_major ? ldc : n, C_row_major); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); return ViennaCLSuccess; }
ViennaCLStatus ViennaCLHostgemm_impl(ViennaCLBackend /*backend*/, ViennaCLOrder orderA, ViennaCLTranspose transA, ViennaCLOrder orderB, ViennaCLTranspose transB, ViennaCLOrder orderC, ViennaCLInt m, ViennaCLInt n, ViennaCLInt k, NumericT alpha, NumericT *A, ViennaCLInt offA_row, ViennaCLInt offA_col, ViennaCLInt incA_row, ViennaCLInt incA_col, ViennaCLInt lda, NumericT *B, ViennaCLInt offB_row, ViennaCLInt offB_col, ViennaCLInt incB_row, ViennaCLInt incB_col, ViennaCLInt ldb, NumericT beta, NumericT *C, ViennaCLInt offC_row, ViennaCLInt offC_col, ViennaCLInt incC_row, ViennaCLInt incC_col, ViennaCLInt ldc) { ViennaCLInt A_size1 = (transA == ViennaCLTrans) ? k : m; ViennaCLInt A_size2 = (transA == ViennaCLTrans) ? m : k; ViennaCLInt B_size1 = (transB == ViennaCLTrans) ? n : k; ViennaCLInt B_size2 = (transB == ViennaCLTrans) ? k : n; /////// A row-major if (orderA == ViennaCLRowMajor && orderB == ViennaCLRowMajor && orderC == ViennaCLRowMajor) { viennacl::matrix_base<NumericT> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, m, A_size2, offA_col, incA_col, lda); viennacl::matrix_base<NumericT> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, k, B_size2, offB_col, incB_col, ldb); viennacl::matrix_base<NumericT> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, m, n, offC_col, incC_col, ldc); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } else if (orderA == ViennaCLRowMajor && orderB == ViennaCLRowMajor && orderC == ViennaCLColumnMajor) { viennacl::matrix_base<NumericT> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, m, A_size2, offA_col, incA_col, lda); viennacl::matrix_base<NumericT> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, k, B_size2, offB_col, incB_col, ldb); viennacl::matrix_base<NumericT, viennacl::column_major> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, ldc, n, offC_col, incC_col, n); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } else if (orderA == ViennaCLRowMajor && orderB == ViennaCLColumnMajor && orderC == ViennaCLRowMajor) { viennacl::matrix_base<NumericT> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, m, A_size2, offA_col, incA_col, lda); viennacl::matrix_base<NumericT, viennacl::column_major> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, ldb, B_size2, offB_col, incB_col, n); viennacl::matrix_base<NumericT> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, m, n, offC_col, incC_col, ldc); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } else if (orderA == ViennaCLRowMajor && orderB == ViennaCLColumnMajor && orderC == ViennaCLColumnMajor) { viennacl::matrix_base<NumericT> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, m, A_size2, offA_col, incA_col, lda); viennacl::matrix_base<NumericT, viennacl::column_major> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, ldb, B_size2, offB_col, incB_col, n); viennacl::matrix_base<NumericT, viennacl::column_major> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, ldc, n, offC_col, incC_col, n); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } /////// A column-major else if (orderA == ViennaCLColumnMajor && orderB == ViennaCLRowMajor && orderC == ViennaCLRowMajor) { viennacl::matrix_base<NumericT, viennacl::column_major> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, lda, A_size2, offA_col, incA_col, k); viennacl::matrix_base<NumericT> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, k, B_size2, offB_col, incB_col, ldb); viennacl::matrix_base<NumericT> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, m, n, offC_col, incC_col, ldc); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } else if (orderA == ViennaCLColumnMajor && orderB == ViennaCLRowMajor && orderC == ViennaCLColumnMajor) { viennacl::matrix_base<NumericT, viennacl::column_major> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, lda, A_size2, offA_col, incA_col, k); viennacl::matrix_base<NumericT> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, k, B_size2, offB_col, incB_col, ldb); viennacl::matrix_base<NumericT, viennacl::column_major> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, ldc, n, offC_col, incC_col, n); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } else if (orderA == ViennaCLColumnMajor && orderB == ViennaCLColumnMajor && orderC == ViennaCLRowMajor) { viennacl::matrix_base<NumericT, viennacl::column_major> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, lda, A_size2, offA_col, incA_col, k); viennacl::matrix_base<NumericT, viennacl::column_major> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, ldb, B_size2, offB_col, incB_col, n); viennacl::matrix_base<NumericT> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, m, n, offC_col, incC_col, ldc); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } else if (orderA == ViennaCLColumnMajor && orderB == ViennaCLColumnMajor && orderC == ViennaCLColumnMajor) { viennacl::matrix_base<NumericT, viennacl::column_major> matA(A, viennacl::MAIN_MEMORY, A_size1, offA_row, incA_row, lda, A_size2, offA_col, incA_col, k); viennacl::matrix_base<NumericT, viennacl::column_major> matB(B, viennacl::MAIN_MEMORY, B_size1, offB_row, incB_row, ldb, B_size2, offB_col, incB_col, n); viennacl::matrix_base<NumericT, viennacl::column_major> matC(C, viennacl::MAIN_MEMORY, m, offC_row, incC_row, ldc, n, offC_col, incC_col, n); detail::gemm_dispatch(alpha, matA, transA, matB, transB, beta, matC); } return ViennaCLSuccess; }