static void randomly_set_extreme_ints (const DBusString *orig_data, DBusString *mutated) { int i; int byte_order; const char *d; dbus_uint32_t orig; static int which = 0; unsigned int extreme_ints[] = { _DBUS_INT_MAX, _DBUS_UINT_MAX, _DBUS_INT_MAX - 1, _DBUS_UINT_MAX - 1, _DBUS_INT_MAX - 2, _DBUS_UINT_MAX - 2, _DBUS_INT_MAX - 17, _DBUS_UINT_MAX - 17, _DBUS_INT_MAX / 2, _DBUS_INT_MAX / 3, _DBUS_UINT_MAX / 2, _DBUS_UINT_MAX / 3, 0, 1, 2, 3, (unsigned int) -1, (unsigned int) -2, (unsigned int) -3 }; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } if (_dbus_string_get_length (mutated) < 12) return; d = _dbus_string_get_const_data (mutated); if (!(*d == DBUS_LITTLE_ENDIAN || *d == DBUS_BIG_ENDIAN)) return; byte_order = *d; i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8); i = _DBUS_ALIGN_VALUE (i, 4); orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL); which = random_int_in_range (0, _DBUS_N_ELEMENTS (extreme_ints)); _dbus_assert (which >= 0); _dbus_assert (which < _DBUS_N_ELEMENTS (extreme_ints)); _dbus_marshal_set_uint32 (mutated, byte_order, i, extreme_ints[which]); }
/* Using the Knuth-Fisher-Yates algorithm */ void shuffle(int n, int t[]) { int i, j, x; for (i = 0 ; i < n ; i++) { j = random_int_in_range(i, n-1); x = t[i]; t[i] = t[j]; t[j] = x; } }
static void randomly_add_one_byte (const DBusString *orig_data, DBusString *mutated) { int i; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } i = random_int_in_range (0, _dbus_string_get_length (mutated)); _dbus_string_insert_bytes (mutated, i, 1, random_int_in_range (0, 256)); }
static void randomly_modify_length (const DBusString *orig_data, DBusString *mutated) { int i; int byte_order; const char *d; dbus_uint32_t orig; int delta; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } if (_dbus_string_get_length (mutated) < 12) return; d = _dbus_string_get_const_data (mutated); if (!(*d == DBUS_LITTLE_ENDIAN || *d == DBUS_BIG_ENDIAN)) return; byte_order = *d; i = random_int_in_range (4, _dbus_string_get_length (mutated) - 8); i = _DBUS_ALIGN_VALUE (i, 4); orig = _dbus_demarshal_uint32 (mutated, byte_order, i, NULL); delta = random_int_in_range (-10, 10); _dbus_marshal_set_uint32 (mutated, byte_order, i, (unsigned) (orig + delta)); }
static void randomly_shorten_or_lengthen (const DBusString *orig_data, DBusString *mutated) { int delta; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } if (_dbus_string_get_length (mutated) == 0) delta = random_int_in_range (0, 10); else delta = random_int_in_range (- _dbus_string_get_length (mutated), _dbus_string_get_length (mutated) * 3); if (delta < 0) _dbus_string_shorten (mutated, - delta); else if (delta > 0) { int i = 0; i = _dbus_string_get_length (mutated); if (!_dbus_string_lengthen (mutated, delta)) _dbus_assert_not_reached ("couldn't lengthen string"); while (i < _dbus_string_get_length (mutated)) { _dbus_string_set_byte (mutated, i, random_int_in_range (0, 256)); ++i; } } }
static void randomly_remove_one_byte (const DBusString *orig_data, DBusString *mutated) { int i; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } if (_dbus_string_get_length (mutated) == 0) return; i = random_int_in_range (0, _dbus_string_get_length (mutated)); _dbus_string_delete (mutated, i, 1); }
static void randomly_do_n_things (const DBusString *orig_data, DBusString *mutated, int n) { int i; void (* functions[]) (const DBusString *orig_data, DBusString *mutated) = { randomly_shorten_or_lengthen, randomly_change_one_byte, randomly_add_one_byte, randomly_remove_one_byte, randomly_modify_length, randomly_set_extreme_ints, randomly_change_one_type }; _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); i = 0; while (i < n) { int which; which = random_int_in_range (0, _DBUS_N_ELEMENTS (functions)); (* functions[which]) (mutated, mutated); times_we_did_each_thing[which] += 1; ++i; } }
static void randomly_change_one_type (const DBusString *orig_data, DBusString *mutated) { int i; int len; if (orig_data != mutated) { _dbus_string_set_length (mutated, 0); if (!_dbus_string_copy (orig_data, 0, mutated, 0)) _dbus_assert_not_reached ("out of mem"); } if (_dbus_string_get_length (mutated) == 0) return; len = _dbus_string_get_length (mutated); i = random_int_in_range (0, len); /* Look for a type starting at a random location, * and replace with a different type */ while (i < len) { int b; b = _dbus_string_get_byte (mutated, i); if (dbus_type_is_valid (b)) { _dbus_string_set_byte (mutated, i, random_type ()); return; } ++i; } }
static int random_type (void) { const char types[] = { DBUS_TYPE_INVALID, DBUS_TYPE_NIL, DBUS_TYPE_BYTE, DBUS_TYPE_BOOLEAN, DBUS_TYPE_INT32, DBUS_TYPE_UINT32, DBUS_TYPE_INT64, DBUS_TYPE_UINT64, DBUS_TYPE_DOUBLE, DBUS_TYPE_STRING, DBUS_TYPE_CUSTOM, DBUS_TYPE_ARRAY, DBUS_TYPE_DICT, DBUS_TYPE_OBJECT_PATH }; _dbus_assert (_DBUS_N_ELEMENTS (types) == DBUS_NUMBER_OF_TYPES + 1); return types[ random_int_in_range (0, _DBUS_N_ELEMENTS (types)) ]; }
int main(int argc, char *argv[]) { int i, rc, done, rand_work_unit_len, total_work_units_handled, nworkthrds; int my_world_rank, nranks, num_work_units, provided; int work_prio, work_type, work_handle[ADLB_HANDLE_SIZE], work_len, answer_rank; int *num_handled_by_rank, num_handled_by_me; int dbgprintf_flag = 1, use_prio_for_reserve_flag = 0; int req_types[3]; int num_types = 1; int type_vect[2] = {WORK}; char thread_type[32]; double adlb_dbls_args[ADLB_NUM_INIT_ARGS]; double temptime, fake_work_time, fake_work_time_per_thrd; double start_job_time, end_put_time, start_work_time, end_work_time; double total_work_time, total_loop_time; double total_reserve_time, total_get_time; double min_work_unit_time, max_work_unit_time, min_work_unit_len, max_work_unit_len; double rand_work_unit_time, *work_unit_buf; total_work_units_handled = 0; total_work_time = 0.0; total_loop_time = 0.0; total_reserve_time = 0.0; total_get_time = 0.0; num_work_units = 0; min_work_unit_time = DEFAULT_NSECS_FAKE_WORK; max_work_unit_time = DEFAULT_NSECS_FAKE_WORK; min_work_unit_len = DEFAULT_WORK_UNIT_LEN; max_work_unit_len = DEFAULT_WORK_UNIT_LEN; for (i=1; i < argc; i++) { // printf("av %s\n",argv[i]); if (strcmp(argv[i],"-n") == 0) num_work_units = atoi(argv[++i]); else if (strcmp(argv[i],"-t") == 0) { min_work_unit_time = atof(argv[++i]); max_work_unit_time = atof(argv[++i]); } else if (strcmp(argv[i],"-l") == 0) { min_work_unit_len = atoi(argv[++i]); max_work_unit_len = atoi(argv[++i]); } else { printf("st4: unrecognized cmd-line arg at %d :%s:\n",i,argv[i]); exit(-1); } } if (min_work_unit_len < sizeof(double)) { printf("st4: min len must be at least size of double %d\n",sizeof(double)); exit(-1); } rc = MPI_Init_thread(NULL,NULL,MPI_THREAD_MULTIPLE,&provided); if (rc != MPI_SUCCESS) { printf("st4: MPI_Init_thread failed with rc=%d\n",rc); exit(-1); } switch (provided) { case MPI_THREAD_SINGLE: strcpy(thread_type,"MPI_THREAD_SINGLE"); break; case MPI_THREAD_FUNNELED: strcpy(thread_type,"MPI_THREAD_FUNNELED"); break; case MPI_THREAD_SERIALIZED: strcpy(thread_type,"MPI_THREAD_SERIALIZED"); break; case MPI_THREAD_MULTIPLE: strcpy(thread_type,"MPI_THREAD_MULTIPLE"); break; default: strcpy(thread_type,"UNKNOWN"); break; } printf("st4: MPI provides %s\n",thread_type); MPI_Comm_size(MPI_COMM_WORLD,&nranks); MPI_Comm_rank(MPI_COMM_WORLD,&my_world_rank); num_handled_by_me = 0; if (my_world_rank == 0) num_handled_by_rank = malloc(nranks * sizeof(int)); else num_handled_by_rank = NULL; work_unit_buf = malloc(max_work_unit_len); adlb_dbls_args[0] = (double) SRVR_MALLOC_AMT; adlb_dbls_args[1] = (double) dbgprintf_flag; adlb_dbls_args[2] = (double) use_prio_for_reserve_flag; adlb_dbls_args[3] = (double) num_types; for (i=0; i < num_types; i++) adlb_dbls_args[i+4] = (double) type_vect[i]; rc = ADLB_Init(adlb_dbls_args); rc = MPI_Barrier( MPI_COMM_WORLD ); start_job_time = MPI_Wtime(); end_work_time = MPI_Wtime(); /* dummy val until set below */ if ( my_world_rank == 0 ) /* if master app, put work */ { for (i=0; i < num_work_units; i++) { memset(work_unit_buf,'X',max_work_unit_len); rand_work_unit_len = random_int_in_range(min_work_unit_len,max_work_unit_len); rand_work_unit_time = random_dbl_in_range(min_work_unit_time,max_work_unit_time); work_unit_buf[0] = rand_work_unit_time; // dbgprintf( 1, "putting work_unit %d len %d time %f\n", // i, rand_work_unit_len,rand_work_unit_time); rc = ADLB_Put( work_unit_buf, rand_work_unit_len, -1, -1, WORK, 1 ); // dbgprintf( 1, "put work_unit %d rc %d\n", i, rc ); } dbgprintf(1,"st4: all work submitted after %f secs\n",MPI_Wtime()-start_job_time); } rc = MPI_Barrier( MPI_COMM_WORLD ); end_put_time = start_work_time = MPI_Wtime(); # ifdef USE_OMP nworkthrds = omp_get_max_threads() - 1; /* 1 for server */ # else nworkthrds = 1; /* default */ # endif done = 0; while ( !done ) { req_types[0] = -1; req_types[1] = -1; req_types[2] = -1; // dbgprintf( 1, "st4: reserving work\n" ); temptime = MPI_Wtime(); rc = ADLB_Reserve(req_types,&work_type,&work_prio,work_handle,&work_len,&answer_rank); // dbgprintf( 1, "st4: after reserve rc %d len %d type %d\n", rc, work_len, work_type ); if ( rc == ADLB_DONE_BY_EXHAUSTION ) { dbgprintf( 1, "st4: done by exhaustion\n" ); break; } else if ( rc == ADLB_NO_MORE_WORK ) { dbgprintf( 1, "st4: done by no more work\n" ); break; } else if (rc < 0) { dbgprintf( 1, "st4: ** reserve failed, rc = %d\n", rc ); ADLB_Abort(-1); } else if (work_type == WORK) { total_reserve_time += MPI_Wtime() - temptime; /* only count for work */ temptime = MPI_Wtime(); rc = ADLB_Get_reserved( work_unit_buf, work_handle ); total_get_time += MPI_Wtime() - temptime; if (rc == ADLB_NO_MORE_WORK) { dbgprintf( 1, "st4: no more work on get_reserved\n" ); break; } else /* got good work */ { /* do dummy/fake work */ num_handled_by_me++; fake_work_time = work_unit_buf[0]; if (fake_work_time == 0.0) { dbgprintf(1,"st4: fakeworktime 0.0\n"); } else { fake_work_time_per_thrd = fake_work_time / nworkthrds; // dbgprintf(1,"st4: fakeworktime %f %f\n", // fake_work_time,fake_work_time_per_thrd); temptime = MPI_Wtime(); # ifdef USE_OMP // #pragma omp parallel private(tid) num_threads(nworkthrds) #pragma omp parallel num_threads(nworkthrds) # endif { while (1) { for (i=0; i < 1000000; i++) ; if (MPI_Wtime()-temptime > fake_work_time_per_thrd) break; } } dbgprintf(1,"st4: fakeworktime %f perthrd %f looptime %f\n", fake_work_time,fake_work_time_per_thrd,MPI_Wtime()-temptime); } } end_work_time = MPI_Wtime(); /* chgs on each work unit */ } else { dbgprintf( 1, "st4: ** unexpected work type %d\n", work_type ); ADLB_Abort( -1 ); } } rc = MPI_Barrier( MPI_COMM_WORLD ); // total_loop_time can be misleading since we have to wait for exhaustion // total_loop_time = MPI_Wtime() - start_work_time; // dbgprintf(1,"st4: total loop time %f\n",total_loop_time); total_work_time = end_work_time - start_work_time; dbgprintf(1,"st4: num handled by me %d\n",num_handled_by_me); dbgprintf(1,"st4: last end_work_time %f\n",end_work_time); dbgprintf(1,"st4: total work_time %f ; avg work time %f\n", total_work_time,total_work_time/((float)num_handled_by_me)); dbgprintf(1,"st4: total reserve time %f ; avg reserve time %f\n", total_reserve_time,total_reserve_time/((float)num_handled_by_me)); dbgprintf(1,"st4: total get time %f ; avg get time %f\n", total_get_time,total_get_time/((float)num_handled_by_me)); MPI_Gather(&num_handled_by_me,1,MPI_INT, num_handled_by_rank,1,MPI_INT, 0,MPI_COMM_WORLD); if (my_world_rank == 0) { for (i=0; i < nranks; i++) { if (num_handled_by_rank[i] > 0) { dbgprintf(1,"st4: num handled by rank %d : total %d avg work time %f\n", i,num_handled_by_rank[i], (total_work_time/(float)num_handled_by_rank[i])); total_work_units_handled += num_handled_by_rank[i]; } else dbgprintf(1,"st4: num handled by rank %d : total 0 avg work time 0.0\n",i); } if (total_work_units_handled != num_work_units) { dbgprintf( 1, "st4: ** wrong number of work units handled: %d of %d\n", total_work_units_handled, num_work_units); ADLB_Abort( -1 ); } } ADLB_Finalize(); // printf("st4: calling mpi_finalize\n"); MPI_Finalize(); // printf("st4: past mpi_finalize\n"); return 0; }