void NM_gemm(const double alpha, NumericsMatrix* A, NumericsMatrix* B, const double beta, NumericsMatrix* C) { switch(A->storageType) { case NM_DENSE: { cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans, A->size0, B->size1, B->size1, alpha, A->matrix0, A->size0, B->matrix0, B->size0, beta, C->matrix0, A->size0); NM_clearSparseBlock(C); NM_clearSparseStorage(C); break; } case NM_SPARSE_BLOCK: { prodNumericsMatrixNumericsMatrix(alpha, A, B, beta, C); NM_clearDense(C); NM_clearSparseStorage(C); break; } case NM_SPARSE: { CSparseMatrix* result = cs_add(cs_multiply(NM_csc(A), NM_csc(B)), NM_csc(C), alpha, beta); NM_clearDense(C); NM_clearSparseBlock(C); NM_clearSparseStorage(C); NM_sparse(C)->csc = result; C->size0 = (int)C->matrix2->csc->m; C->size1 = (int)C->matrix2->csc->n; break; } } }
int test_prodNumericsMatrixNumericsMatrix(NumericsMatrix** MM) { NumericsMatrix * M1 = MM[0]; NumericsMatrix * M2 = MM[1]; NumericsMatrix * M3 = MM[2]; NumericsMatrix * M4 = MM[3]; int info = -1; printf("== Numerics tests: prodNumericsMatrixNumericsMatrix(NumericsMatrix,NumericsMatrix) == \n"); int i, j, k; double alpha = 1.0, beta = 0.0; double tol = 1e-12; NumericsMatrix C; C.storageType = 0; C.size0 = M1->size0; C.size1 = M1->size1; C.matrix0 = (double *)malloc(C.size0 * C.size1 * sizeof(double)); C.matrix1 = NULL; C.matrix2 = NULL; C.internalData = NULL; prodNumericsMatrixNumericsMatrix(alpha, M1, M1, beta, &C); double * Cref = (double *)malloc(C.size0 * C.size1 * sizeof(double)); double sum; for (i = 0; i < C.size0; i++) { for (j = 0; j < C.size1; j++) { sum = 0.0; for (k = 0; k < M1->size1; k++) { sum = sum + M1->matrix0[i + k * M1->size0] * M1->matrix0[k + j * M1->size0]; } Cref[i + j * C.size0] = sum; } } double err = 0.0; for (i = 0; i < C.size0; i++) { for (j = 0; j < C.size1; j++) { printf("Cref[%i+%i*%i]= %lf\t\t", i, j, C.size0, Cref[i + j * C.size0]); printf("Cmatrix0[%i+%i*%i]= %lf\t", i, j, C.size0, C.matrix0[i + j * C.size0]); err += (Cref[i + j * C.size0] - C.matrix0[i + j * C.size0]) * (Cref[i + j * C.size0] - C.matrix0[i + j * C.size0]); printf("err = %lf\n", err); } } if (err < tol) { info = 0; } if (info == 0) printf("Step 0 ( C = alpha*A*B + beta*C, double* storage, square matrix ) ok ...\n"); else { printf("Step 0 ( C = alpha*A*B + beta*C, double* storage, square matrix) failed ...\n"); goto exit_1; } NumericsMatrix C2; C2.storageType = 0; C2.size0 = M1->size0; C2.size1 = M3->size1; C2.matrix0 = (double *)malloc(C2.size0 * C2.size1 * sizeof(double)); C2.matrix1 = NULL; C2.matrix2 = NULL; C2.internalData = NULL; prodNumericsMatrixNumericsMatrix(alpha, M1, M3, beta, &C2); double * C2ref = (double *)malloc(C2.size0 * C2.size1 * sizeof(double)); for (i = 0; i < C2.size0; i++) { for (j = 0; j < C2.size1; j++) { sum = 0.0; for (k = 0; k < M1->size1; k++) { sum = sum + M1->matrix0[i + k * M1->size0] * M3->matrix0[k + j * M3->size0]; } C2ref[i + j * C2.size0] = sum; /* printf("C2ref(%i,%i)=%f\n", i,j,C2ref[i+j*C2.size0] ); */ } } err = 0.0; for (i = 0; i < C2.size0; i++) { for (j = 0; j < C2.size1; j++) { err += (C2ref[i + j * C2.size0] - C2.matrix0[i + j * C2.size0]) * (C2ref[i + j * C2.size0] - C2.matrix0[i + j * C2.size0]); } } if (err < tol) { info = 0; } if (info == 0) printf("Step 1 ( C = alpha*A*B + beta*C, double* storage, non square) ok ...\n"); else { printf("Step 1 ( C = alpha*A*B + beta*C, double* storage, non square) failed ...\n"); goto exit_2; } NumericsMatrix C3; C3.storageType = 1; C3.size0 = M2->size0; C3.size1 = M2->size1; SparseBlockStructuredMatrix * SBM3 = (SparseBlockStructuredMatrix *)malloc(sizeof(SparseBlockStructuredMatrix)); C3.matrix1 = SBM3; C3.matrix2 = NULL; C3.internalData = NULL; beta = 1.0; i = 1; // while (i > 0) allocateMemoryForProdSBMSBM(M2->matrix1, M2->matrix1, SBM3); /* printSBM(SBM3); */ prodNumericsMatrixNumericsMatrix(alpha, M2, M2, beta, &C3); //freeSBM(SBM3); printf("i= %i\n", i++); /* Check if it is correct */ /* C3 and CRef must have the same values.*/ for (i = 0; i < C3.size0; i++) { for (j = 0; j < C3.size1; j++) { if (fabs(Cref[i + j * C3.size0] - getValueSBM(C3.matrix1, i, j)) > tol) info = 1; /* printf("%i\t%i\n",i,j); */ /* printf("%lf\n",fabs(Cref[i+j*C3.size0]-getValueSBM(C3.matrix1,i,j) )); */ /* printf("%lf\n",Cref[i+j*C3.size0]); */ /* printf("%lf\n",getValueSBM(C3.matrix1,i,j)); */ if (info == 1) break; } if (info == 1) break ; } if (info == 0) printf("Step 2 ( C = alpha*A*B + beta*C, sparse storage) ok ...\n"); else { printf("Step 2 ( C = alpha*A*B + beta*C, sparse storage) failed ...\n"); goto exit_3; } NumericsMatrix C4; C4.storageType = 1; C4.size0 = M2->size0; C4.size1 = M4->size1; SparseBlockStructuredMatrix * SBM4 = (SparseBlockStructuredMatrix *)malloc(sizeof(SparseBlockStructuredMatrix)); C4.matrix1 = SBM4; C4.matrix2 = NULL; C4.internalData = NULL; allocateMemoryForProdSBMSBM(M2->matrix1, M4->matrix1, SBM4); /* printSBM(SBM4); */ prodNumericsMatrixNumericsMatrix(alpha, M2, M4, beta, &C4); /* Check if it is correct */ /* C4 and C2Ref must have the same values.*/ for (i = 0; i < C4.size0; i++) { for (j = 0; j < C4.size1; j++) { if (fabs(C2ref[i + j * C4.size0] - getValueSBM(C4.matrix1, i, j)) > tol) info = 1; /* printf("%i\t%i\n",i,j); */ /* printf("%lf\n",fabs(C2ref[i+j*C4.size0]-getValueSBM(C4.matrix1,i,j) )); */ /* printf("%lf\n",C2ref[i+j*C4.size0]); */ /* printf("%lf\n",getValueSBM(C4.matrix1,i,j)); */ if (info == 1) break; } if (info == 1) break ; } if (info == 0) printf("Step 3 ( C = alpha*A*B + beta*C, sparse storage) ok ...\n"); else { printf("Step 3 ( C = alpha*A*B + beta*C, sparse storage) failed ...\n"); } freeNumericsMatrix(&C4); exit_3: freeNumericsMatrix(&C3); exit_2: free(C2.matrix0); free(C2ref); exit_1: free(Cref); free(C.matrix0); return info; }