The problem with the prism tests is that, on rare occasions, they might generate a very ill-conditioned problem (very sensitive to floating-point errors), so no matter what tolerance we set there is some probability of failure. Indeed, we see that the tests occasionally fail for just this reason.
A typical workaround is to use deterministic pseudo-random numbers, by using a fixed seed. However, it is further complicated in our case by the fact that we now have multi-threaded tests using OpenMP. Currently, we use the rand() function, which (apparently) uses a global shared state across all threads, so that even if we fixed the seed, different parallel execution orders will lead to inequivalent tests.
The alternative is to use a thread-safe random number generator with a per-thread seed. Apparently POSIX provides a rand_r function for this purpose. So:
- Modify all of the random functions to take an
unsigned *seed argument, and pass it all the way down to drand, which calls rand and can then be changed to call rand_r(seed).
- At the beginning, set
seed to be a thread-local variable, e.g. an array seed[tid] indexed by the thread index, where seed[tid] = tid (or some per-thread value, we don't care which).
- In the test loops, pass
seed[omp_get_thread_num()]
The problem with the prism tests is that, on rare occasions, they might generate a very ill-conditioned problem (very sensitive to floating-point errors), so no matter what tolerance we set there is some probability of failure. Indeed, we see that the tests occasionally fail for just this reason.
A typical workaround is to use deterministic pseudo-random numbers, by using a fixed seed. However, it is further complicated in our case by the fact that we now have multi-threaded tests using OpenMP. Currently, we use the
rand()function, which (apparently) uses a global shared state across all threads, so that even if we fixed the seed, different parallel execution orders will lead to inequivalent tests.The alternative is to use a thread-safe random number generator with a per-thread seed. Apparently POSIX provides a
rand_rfunction for this purpose. So:unsigned *seedargument, and pass it all the way down todrand, which callsrandand can then be changed to callrand_r(seed).seedto be a thread-local variable, e.g. an arrayseed[tid]indexed by the thread index, whereseed[tid] = tid(or some per-thread value, we don't care which).seed[omp_get_thread_num()]