Skip to content

Commit

Permalink
[OpenMP][Tests] Test omp_get_wtime for invariants
Browse files Browse the repository at this point in the history
As discussed in D108488, testing for invariants of omp_get_wtime would be more
reliable than testing for duration of sleep, as return from sleep might be
delayed due to system load.

Alternatively/in addition, we could compare the time measured by omp_get_wtime
 to time measured with C++11 chrono (for portability?).

Differential Revision: https://reviews.llvm.org/D112458
  • Loading branch information
jprotze committed Oct 25, 2021
1 parent 3f229f4 commit 7368227
Showing 1 changed file with 14 additions and 60 deletions.
74 changes: 14 additions & 60 deletions openmp/runtime/test/api/omp_get_wtime.c
Expand Up @@ -6,71 +6,25 @@

#define NTIMES 100

// This is the error % threshold. Be generous with the error threshold since
// this test may be run in parallel with many other tests it may throw off the
// sleep timing.
#define THRESHOLD 100.0

double test_omp_get_wtime(double desired_wait_time) {
double start;
double end;
start = 0;
end = 0;
start = omp_get_wtime();
my_sleep(desired_wait_time);
end = omp_get_wtime();
return end - start;
}

int compare_times(const void *lhs, const void *rhs) {
const double *a = (const double *)lhs;
const double *b = (const double *)rhs;
return *a - *b;
}
#define ASSERT_CMP(lhs, cmp, rhs) \
if (!((lhs)cmp(rhs))) { \
printf("Expected: (" #lhs ") " #cmp " (" #rhs "), actual: %e vs. %e", lhs, \
rhs); \
return EXIT_FAILURE; \
}

int main() {
int i, final_count;
double percent_off;
double *begin, *end, *ptr;
double wait_time = 0.01;
double average = 0.0;
double n = 0.0;
double *times = (double *)malloc(sizeof(double) * NTIMES);
int i;

// Get each timing
for (i = 0; i < NTIMES; i++) {
times[i] = test_omp_get_wtime(wait_time);
double start = omp_get_wtime(), end;
ASSERT_CMP(start, >=, 0.0);
for (end = omp_get_wtime(); end == start; end = omp_get_wtime()) {
ASSERT_CMP(end, >=, 0.0);
}
ASSERT_CMP(end, >=, 0.0);
ASSERT_CMP(end, >, start);
}

// Remove approx the "worst" tenth of the timings
qsort(times, NTIMES, sizeof(double), compare_times);
begin = times;
end = times + NTIMES;
for (i = 0; i < NTIMES / 10; ++i) {
if (i % 2 == 0)
begin++;
else
end--;
}

// Get the average of the remaining timings
for (ptr = begin, final_count = 0; ptr != end; ++ptr, ++final_count)
average += times[i];
average /= (double)final_count;
free(times);

// Calculate the percent off of desired wait time
percent_off = (average - wait_time) / wait_time * 100.0;
// Should always be positive, but just in case
if (percent_off < 0)
percent_off = -percent_off;

if (percent_off > (double)THRESHOLD) {
fprintf(stderr, "error: average of %d runs (%lf) is of by %lf%%\n", NTIMES,
average, percent_off);
return EXIT_FAILURE;
}
printf("pass: average of %d runs (%lf) is only off by %lf%%\n", NTIMES,
average, percent_off);
return EXIT_SUCCESS;
}

0 comments on commit 7368227

Please sign in to comment.