#ifndef __UPC_ATOMIC__ #error pre-defined __UPC_ATOMIC__ is undefined. #endif #if __UPC_ATOMIC__ != 1 #error pre-defined __UPC_ATOMIC__ is != 1. #endif #include #include #include #include #if DEBUG && !defined(NDEBUG) int debug = 1; #else int debug = 0; #endif #define NO_RESULT_CHECK 0 #define RESULT_CHECK 1 shared int failures = 0; upc_atomicdomain_t *d; /* Parallel test number of loops. */ #ifndef LOOPCNT #define LOOPCNT 10 #endif #define ARITH_OPS \ UPC_SET|UPC_GET|UPC_ADD|UPC_SUB|UPC_MULT|UPC_INC|UPC_DEC|UPC_MAX|UPC_MIN #define ARITH_TEST(_type,_code) \ static shared _type var_##_code; \ _type evar_##_code, fvar_##_code; \ void set_##_code(shared _type *sp, _type val, int check) \ { \ _type lval = val; \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_SET, sp, &lval, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_SET returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ evar_##_code = val; \ } \ void get_##_code(shared _type *sp, int check) \ { \ upc_atomic_relaxed (d, &fvar_##_code, UPC_GET, \ sp, NULL, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_GET returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ evar_##_code = fvar_##_code; \ } \ void add_##_code(shared _type *sp, _type val, int check) \ { \ _type lval = val; \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_ADD, sp, &lval, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_ADD returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ evar_##_code = evar_##_code + val; \ } \ void sub_##_code(shared _type *sp, _type val, int check) \ { \ _type lval = val; \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_SUB, sp, &lval, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_SUB returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ evar_##_code = evar_##_code - val; \ } \ void mult_##_code(shared _type *sp, _type val, int check) \ { \ _type lval = val; \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_MULT, sp, &lval, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_MULT returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ evar_##_code = evar_##_code * val; \ } \ void inc_##_code(shared _type *sp, int check) \ { \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_INC, sp, NULL, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_INC returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ ++evar_##_code; \ } \ void dec_##_code(shared _type *sp, int check) \ { \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_DEC, sp, NULL, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_DEC returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ --evar_##_code; \ } \ void min_##_code(shared _type *sp, _type val, int check) \ { \ _type lval = val; \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_MIN, sp, &lval, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_MIN returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ if (val < evar_##_code) \ evar_##_code = val; \ } \ void max_##_code(shared _type *sp, _type val, int check) \ { \ _type lval = val; \ _type *sval = (check==RESULT_CHECK) ? &fvar_##_code : NULL; \ upc_atomic_relaxed (d, sval, UPC_MAX, sp, &lval, NULL); \ if (check == RESULT_CHECK && fvar_##_code != evar_##_code) \ { \ printf("ERROR: " #_code " UPC_MAX returned %d (%d)\n", \ (int)fvar_##_code, (int)evar_##_code); \ ++failures; \ } \ if (val > evar_##_code) \ evar_##_code = val; \ } \ void test_##_code(void) \ { \ int prev_failures = failures; \ int atomic_perf; \ int i, j; \ \ atomic_perf = upc_atomic_isfast (_code, ARITH_OPS, &var_##_code); \ \ /* Create atomic domain. */ \ d = upc_all_atomicdomain_alloc (_code, ARITH_OPS, 0); \ \ if (debug && !MYTHREAD) \ { \ printf ("+ UPC arithmetic atomics (" #_code ")\n"); \ fflush(stdout); \ } \ \ for (i=0; i iter) myiter = (MYTHREAD >= iter?0:1); \ else { myiter = iter/THREADS; iter = myiter*THREADS; } \ volatile int limit = (iter>LOOPCNT)?iter:LOOPCNT; \ for (i=0; i < limit; ++i) \ mult_##_code (&var_##_code, (i