int addmul_test_equality(rci_t m, rci_t l, rci_t n, int k, int cutoff) { int ret = 0; mzd_t *A, *B, *C, *D, *E, *F; printf("addmul: m: %4d, l: %4d, n: %4d, k: %2d, cutoff: %4d", m, l, n, k, cutoff); /* we create two random matrices */ A = mzd_init(m, l); B = mzd_init(l, n); C = mzd_init(m, n); mzd_randomize(A); mzd_randomize(B); mzd_randomize(C); /* D = C + A*B via M4RM, temporary buffers are managed internally */ D = mzd_copy(NULL, C); D = mzd_addmul_m4rm(D, A, B, k); /* E = C + A*B via naiv cubic multiplication */ E = mzd_mul_m4rm(NULL, A, B, k); mzd_add(E, E, C); /* F = C + A*B via naiv cubic multiplication */ F = mzd_copy(NULL, C); F = mzd_addmul(F, A, B, cutoff); mzd_free(A); mzd_free(B); mzd_free(C); if (mzd_equal(D, E) != TRUE) { printf(" M4RM != add,mul"); ret -=1; } if (mzd_equal(E, F) != TRUE) { printf(" add,mul = addmul"); ret -=1; } if (mzd_equal(F, D) != TRUE) { printf(" M4RM != addmul"); ret -=1; } if (ret==0) printf(" ... passed\n"); else printf(" ... FAILED\n"); mzd_free(D); mzd_free(E); mzd_free(F); return ret; }
/** * Check that the results of all implemented multiplication algorithms * match up. * * \param m Number of rows of A * \param l Number of columns of A/number of rows of B * \param n Number of columns of B * \param k Parameter k of M4RM algorithm, may be 0 for automatic choice. * \param cutoff Cut off parameter at which dimension to switch from * Strassen to M4RM */ int mul_test_equality(rci_t m, rci_t l, rci_t n, int k, int cutoff) { int ret = 0; mzd_t *A, *B, *C, *D, *E; printf(" mul: m: %4d, l: %4d, n: %4d, k: %2d, cutoff: %4d", m, l, n, k, cutoff); /* we create two random matrices */ A = mzd_init(m, l); B = mzd_init(l, n); mzd_randomize(A); mzd_randomize(B); /* C = A*B via Strassen */ C = mzd_mul(NULL, A, B, cutoff); /* D = A*B via M4RM, temporary buffers are managed internally */ D = mzd_mul_m4rm( NULL, A, B, k); /* E = A*B via naive cubic multiplication */ E = mzd_mul_naive( NULL, A, B); mzd_free(A); mzd_free(B); if (mzd_equal(C, D) != TRUE) { printf(" Strassen != M4RM"); ret -=1; } if (mzd_equal(D, E) != TRUE) { printf(" M4RM != Naiv"); ret -= 1; } if (mzd_equal(C, E) != TRUE) { printf(" Strassen != Naiv"); ret -= 1; } mzd_free(C); mzd_free(D); mzd_free(E); if(ret==0) { printf(" ... passed\n"); } else { printf(" ... FAILED\n"); } return ret; }
/* * Class: m4rjni_Mzd * Method: mzd_equal * Signature: (JJ)I */ JNIEXPORT jint JNICALL Java_m4rjni_Mzd_mzd_1equal(JNIEnv *env, jclass obj, jlong Aptr, jlong Bptr) { mzd_t *A = (mzd_t*)Aptr; mzd_t *B = (mzd_t*)Bptr; if (A==NULL || B==NULL) return 0; return mzd_equal(A,B); }
int smallops_test_add(rci_t M, rci_t N, rci_t m, rci_t n, rci_t offset, word pattern) { int ret = 0; printf(" mzd_add: M: %4d, N: %4d, m: %4d, n: %4d, offset: %4d, pattern: 0x%" PRIx64 " ", M, N, m, n, offset, pattern); mzd_t *AA; mzd_t *A = mzd_init_test_matrix_random(M, N, m, n, offset, pattern, &AA); mzd_t *BB; mzd_t *B = mzd_init_test_matrix_random(M, N, m, n, offset, pattern, &BB); mzd_t *CC; mzd_t *C = mzd_init_test_matrix_random(M, N, m, n, offset, pattern, &CC); mzd_t *DD; mzd_t *D = mzd_init_test_matrix_random(M, N, m, n, offset, pattern, &DD); /* Creation went okay? */ ret += mzd_check_pattern(AA, m, n, offset, pattern); ret += mzd_check_pattern(BB, m, n, offset, pattern); ret += mzd_check_pattern(CC, m, n, offset, pattern); ret += mzd_check_pattern(DD, m, n, offset, pattern); /* Testing equality A+A == 0 */ mzd_add(C, A, A); if(!mzd_is_zero(C)) { ret +=1; } ret += mzd_check_pattern(AA, m, n, offset, pattern); ret += mzd_check_pattern(BB, m, n, offset, pattern); ret += mzd_check_pattern(CC, m, n, offset, pattern); /* Testing equality A+A == 0 but this time C is already zero */ mzd_add(C, B, B); if(!mzd_is_zero(C)) { ret +=1; } ret += mzd_check_pattern(AA, m, n, offset, pattern); ret += mzd_check_pattern(BB, m, n, offset, pattern); ret += mzd_check_pattern(CC, m, n, offset, pattern); /* Testing in place add. C is zero, so afterwards C == A */ mzd_add(C, C, A); if(!mzd_equal(C,A)) { ret +=1; } ret += mzd_check_pattern(AA, m, n, offset, pattern); ret += mzd_check_pattern(BB, m, n, offset, pattern); ret += mzd_check_pattern(CC, m, n, offset, pattern); /* Testing equality C (== A) + A == 0 */ mzd_add(B, C, A); if(!mzd_is_zero(B)) { ret +=1; } if(m == n) { /* Testing equality (A + B)^2 == A^2 + BA + AB + B^2 */ mzd_randomize(A); mzd_randomize(B); mzd_add(C,A,B); mzd_mul(D,C,C, 0); // (A+B)^2 mzd_mul(C,A,A, 0); mzd_addmul(C, B, A, 0); mzd_addmul(C, A, B, 0); mzd_addmul(C, B, B, 0); if(!mzd_equal(C,D)) { ret += 1; } ret += mzd_check_pattern(AA, m, n, offset, pattern); ret += mzd_check_pattern(BB, m, n, offset, pattern); ret += mzd_check_pattern(CC, m, n, offset, pattern); ret += mzd_check_pattern(DD, m, n, offset, pattern); } mzd_free_test_matrix_random(AA, A); mzd_free_test_matrix_random(BB, B); mzd_free_test_matrix_random(CC, C); mzd_free_test_matrix_random(DD, D); if(ret == 0) { printf(" ... passed\n"); } else { printf(" ... FAILED\n"); } #ifdef ABORT_ON_FAIL if (ret) abort(); #endif return ret; }