#include #include #include // for assert() #include // for malloc(), free(), rand(), srand(), abort() #include // for typedef bool #include // for printf() #include // for nan(), fabs() #include // for DBL_EPSILON #include // for strcmp #ifndef DGETRF #define DGETRF dgetrf #endif #ifndef SEED_RAND #define SEED_RAND 0 #endif #ifndef TOL_ERR #define TOL_ERR 1 #endif //-- reference implementation and numerical test ------------------------------- double dgetrf_err(size_t m, size_t n, const double *A, ptrdiff_t incRowA, ptrdiff_t incColA, double *LU, ptrdiff_t incRowLU, ptrdiff_t incColLU, const size_t *p, ptrdiff_t incP) { if (m==0 || n==0) { return 0; } size_t k = m=i ? LU[i*incRowLU+j*incColLU] : 0; } } for (size_t i=0; i0; ) { if (p[i*incP]!=i) { dswap(n, &LU[i*incRowLU], incColLU, &LU[p[i*incP]*incRowLU], incColLU); } } double nrmA = dgenrm_inf(m, n, A, incRowA, incColA); dgeaxpy(m, n, -1, A, incRowA, incColA, LU, incRowLU, incColLU); double err = dgenrm_inf(m, n, LU, incRowLU, incColLU) / (k*nrmA*DBL_EPSILON); free(L); free(U); return err; } //-- tests for dgetrf ---------------------------------------------------------- // Get parameters for testing. Returns true if more test parameters are // available, and otherwise false. bool get_next_param(bool reset, size_t *m, size_t *n, ptrdiff_t *incRowA, ptrdiff_t *incColA, ptrdiff_t *incP) { // static variables defined in a function are technically global variables // that are only visible to the function. So by default these static // variables are initialized with zero when the program starts execution. static size_t dim[] = {5, 0, 1, 32, 31}; static ptrdiff_t inc[] = {1, 2, -1, -2}; static bool colMajor; static size_t idx_m; static size_t idx_n; static size_t idx_incRowA; static size_t idx_incColA; static size_t idx_incP; if (reset) { colMajor = false; idx_m = 0; idx_n = 0; idx_incRowA = 0; idx_incColA = 0; idx_incP = 0; } *m = dim[idx_m]; *n = dim[idx_n]; *incP = inc[idx_incP]; if (colMajor) { *incRowA = inc[idx_incRowA]; *incColA = dim[idx_m]*ptrdiff_abs(inc[idx_incRowA]*inc[idx_incColA]); } else { *incRowA = dim[idx_n]*ptrdiff_abs(inc[idx_incRowA]*inc[idx_incColA]); *incColA = inc[idx_incColA]; } if (!colMajor) { colMajor = true; return true; } colMajor = false; if (++idx_incRowA < sizeof(inc)/sizeof(ptrdiff_t)) { return true; } idx_incRowA = 0; if (++idx_incColA < sizeof(inc)/sizeof(ptrdiff_t)) { return true; } idx_incColA = 0; if (++idx_m < sizeof(dim)/sizeof(size_t)) { return true; } idx_m = 0; if (++idx_n < sizeof(dim)/sizeof(size_t)) { return true; } idx_n = 0; if (++idx_incP < sizeof(inc)/sizeof(ptrdiff_t)) { return true; } idx_incP = 0; return false; } int check_dgetrf(int argc, char **argv) { size_t m, n; ptrdiff_t incRowA, incColA, incP; bool more, reset = true; unsigned seed_rand = SEED_RAND; for (int i=0; i]" "\n", argv[0]); return 1; } if (!strcmp(argv[1], "check")) { return check_dgetrf(argc-2, argv+2); } if (!strcmp(argv[1], "bench")) { bench_dgetrf(argc-2, argv+2); } }