Skip to content

Commit e6d7f0d

Browse files
committed
math_brute_force: Refactor input generation & reduce default test size
This patch addresses execution time and input coverage in the math_brute_force tests by centralizing input generation and scaling down the default number of tested values. Key changes: * Abstracted input generation: Replaced duplicated array-filling logic across test files with shared `fill*Input` helper functions (for unary, binary, and ternary operations). This ensures that special edge-case values (NaNs, Infs, denormals) and random payloads are consistently injected across all tests. * Reduced default test size: The default loop bounds have been reduced from an exhaustive `1ULL << 32` values to a randomized subset of `1ULL << 27` inputs. This drastically speeds up standard test runs. * Added exhaustive `-a` flag: Introduced a new `-a` command-line option that restores the exhaustive testing behavior, allowing validation against all 2^32 sequential values when needed. * Improved wimpy mode scaling: Removed the `scale` and `step` skip logic, which could inadvertently skip combinations of special values. Instead, the patch now directly reduces the total `input_count_power_of_two` by using a De Bruijn sequence bit-hack to calculate the `log2` of the `wimpyReductionFactor`. Fixes: #2669 [run-test: test_bruteforce -w -1]
1 parent 7e3fedc commit e6d7f0d

43 files changed

Lines changed: 417 additions & 1126 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

test_conformance/math_brute_force/binary_double.cpp

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ cl_int BuildKernelFn(cl_uint job_id, cl_uint thread_id UNUSED, void *p)
3737
return BuildKernels(info, job_id, generator);
3838
}
3939

40-
4140
struct TestInfo : public TestInfoBase
4241
{
4342
// Programs for various vector sizes.
@@ -56,7 +55,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
5655
TestInfo *job = (TestInfo *)data;
5756
size_t buffer_elements = job->subBufferSize;
5857
size_t buffer_size = buffer_elements * sizeof(cl_double);
59-
cl_uint base = job_id * (cl_uint)job->step;
58+
cl_uint base = job_id * (cl_uint)buffer_elements;
6059
ThreadInfoBinary *tinfo = &(job->tinfo[thread_id]);
6160
float ulps = job->ulps;
6261
dptr func = job->f->dfunc;
@@ -100,42 +99,8 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
10099
// Init input array
101100
cl_ulong *p = (cl_ulong *)gIn + thread_id * buffer_elements;
102101
cl_ulong *p2 = (cl_ulong *)gIn2 + thread_id * buffer_elements;
103-
cl_uint idx = 0;
104-
105-
const std::vector<double> &specialValues = getDoubleSpecialValues();
106-
size_t specialValuesCount = specialValues.size();
107-
int totalSpecialValueCount = specialValuesCount * specialValuesCount;
108-
int lastSpecialJobIndex = (totalSpecialValueCount - 1) / buffer_elements;
109-
110-
// Test edge cases
111-
if (job_id <= (cl_uint)lastSpecialJobIndex)
112-
{
113-
cl_double *fp = (cl_double *)p;
114-
cl_double *fp2 = (cl_double *)p2;
115-
uint32_t x, y;
116-
117-
x = (job_id * buffer_elements) % specialValuesCount;
118-
y = (job_id * buffer_elements) / specialValuesCount;
119-
120-
for (; idx < buffer_elements; idx++)
121-
{
122-
fp[idx] = specialValues[x];
123-
fp2[idx] = specialValues[y];
124-
if (++x >= specialValuesCount)
125-
{
126-
x = 0;
127-
y++;
128-
if (y >= specialValuesCount) break;
129-
}
130-
}
131-
}
132-
133-
// Init any remaining values
134-
for (; idx < buffer_elements; idx++)
135-
{
136-
p[idx] = genrand_int64(d);
137-
p2[idx] = genrand_int64(d);
138-
}
102+
fillDoubleBinaryInput((cl_double *)p, (cl_double *)p2, buffer_elements,
103+
base, d);
139104

140105
if ((error = clEnqueueWriteBuffer(tinfo->tQueue, tinfo->inBuf, CL_FALSE, 0,
141106
buffer_size, p, 0, NULL, NULL)))
@@ -415,10 +380,9 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
415380
{
416381
if (gVerboseBruteForce)
417382
{
418-
vlog("base:%14u step:%10u scale:%10u buf_elements:%10zu ulps:%5.3f "
383+
vlog("base:%14u buf_elements:%10zu ulps:%5.3f "
419384
"ThreadCount:%2u\n",
420-
base, job->step, job->scale, buffer_elements, job->ulps,
421-
job->threadCount);
385+
base, buffer_elements, job->ulps, job->threadCount);
422386
}
423387
else
424388
{
@@ -446,18 +410,8 @@ int TestFunc_Double_Double_Double(const Func *f, MTdata d, bool relaxedMode)
446410
test_info.threadCount = GetThreadCount();
447411
test_info.subBufferSize = BUFFER_SIZE
448412
/ (sizeof(cl_double) * RoundUpToNextPowerOfTwo(test_info.threadCount));
449-
test_info.scale = getTestScale(sizeof(cl_double));
450-
451-
test_info.step = (cl_uint)test_info.subBufferSize * test_info.scale;
452-
if (test_info.step / test_info.subBufferSize != test_info.scale)
453-
{
454-
// there was overflow
455-
test_info.jobCount = 1;
456-
}
457-
else
458-
{
459-
test_info.jobCount = (cl_uint)((1ULL << 32) / test_info.step);
460-
}
413+
test_info.jobCount = std::max(
414+
(cl_uint)1, (cl_uint)(getInputCount() / test_info.subBufferSize));
461415

462416
test_info.f = f;
463417
test_info.ulps = getAllowedUlpError(f, kdouble, relaxedMode);

test_conformance/math_brute_force/binary_float.cpp

Lines changed: 6 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
5555
TestInfo *job = (TestInfo *)data;
5656
size_t buffer_elements = job->subBufferSize;
5757
size_t buffer_size = buffer_elements * sizeof(cl_float);
58-
cl_uint base = job_id * (cl_uint)job->step;
58+
cl_uint base = job_id * (cl_uint)buffer_elements;
5959
ThreadInfoBinary *tinfo = &(job->tinfo[thread_id]);
6060
fptr func = job->f->func;
6161
int ftz = job->ftz;
@@ -111,43 +111,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
111111
// Init input array
112112
cl_uint *p = (cl_uint *)gIn + thread_id * buffer_elements;
113113
cl_uint *p2 = (cl_uint *)gIn2 + thread_id * buffer_elements;
114-
cl_uint idx = 0;
115-
116-
const std::vector<float> &specialValues = getFloatSpecialValues();
117-
size_t specialValuesCount = specialValues.size();
118-
int totalSpecialValueCount = specialValuesCount * specialValuesCount;
119-
int lastSpecialJobIndex = (totalSpecialValueCount - 1) / buffer_elements;
120-
121-
// Test edge cases
122-
if (job_id <= (cl_uint)lastSpecialJobIndex)
123-
{
124-
float *fp = (float *)p;
125-
float *fp2 = (float *)p2;
126-
uint32_t x, y;
127-
128-
x = (job_id * buffer_elements) % specialValuesCount;
129-
y = (job_id * buffer_elements) / specialValuesCount;
130-
131-
for (; idx < buffer_elements; idx++)
132-
{
133-
fp[idx] = specialValues[x];
134-
fp2[idx] = specialValues[y];
135-
++x;
136-
if (x >= specialValuesCount)
137-
{
138-
x = 0;
139-
y++;
140-
if (y >= specialValuesCount) break;
141-
}
142-
}
143-
}
144-
145-
// Init any remaining values
146-
for (; idx < buffer_elements; idx++)
147-
{
148-
p[idx] = genrand_int32(d);
149-
p2[idx] = genrand_int32(d);
150-
}
114+
fillFloatBinaryInput((float *)p, (float *)p2, buffer_elements, base, d);
151115

152116
if ((error = clEnqueueWriteBuffer(tinfo->tQueue, tinfo->inBuf, CL_FALSE, 0,
153117
buffer_size, p, 0, NULL, NULL)))
@@ -576,10 +540,9 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
576540
{
577541
if (gVerboseBruteForce)
578542
{
579-
vlog("base:%14u step:%10u scale:%10u buf_elements:%10zu ulps:%5.3f "
543+
vlog("base:%14u buf_elements:%10zu ulps:%5.3f "
580544
"ThreadCount:%2u\n",
581-
base, job->step, job->scale, buffer_elements, job->ulps,
582-
job->threadCount);
545+
base, buffer_elements, job->ulps, job->threadCount);
583546
}
584547
else
585548
{
@@ -607,18 +570,8 @@ int TestFunc_Float_Float_Float(const Func *f, MTdata d, bool relaxedMode)
607570
test_info.threadCount = GetThreadCount();
608571
test_info.subBufferSize = BUFFER_SIZE
609572
/ (sizeof(cl_float) * RoundUpToNextPowerOfTwo(test_info.threadCount));
610-
test_info.scale = getTestScale(sizeof(cl_float));
611-
612-
test_info.step = (cl_uint)test_info.subBufferSize * test_info.scale;
613-
if (test_info.step / test_info.subBufferSize != test_info.scale)
614-
{
615-
// there was overflow
616-
test_info.jobCount = 1;
617-
}
618-
else
619-
{
620-
test_info.jobCount = (cl_uint)((1ULL << 32) / test_info.step);
621-
}
573+
test_info.jobCount = std::max(
574+
(cl_uint)1, (cl_uint)(getInputCount() / test_info.subBufferSize));
622575

623576
test_info.f = f;
624577
test_info.ulps = gIsEmbedded ? f->float_embedded_ulps : f->float_ulps;

test_conformance/math_brute_force/binary_half.cpp

Lines changed: 6 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ cl_int TestHalf(cl_uint job_id, cl_uint thread_id, void *data)
5757
TestInfo *job = (TestInfo *)data;
5858
size_t buffer_elements = job->subBufferSize;
5959
size_t buffer_size = buffer_elements * sizeof(cl_half);
60-
cl_uint base = job_id * (cl_uint)job->step;
60+
cl_uint base = job_id * (cl_uint)buffer_elements;
6161
ThreadInfoBinary *tinfo = &(job->tinfo[thread_id]);
6262
float ulps = job->ulps;
6363
fptr func = job->f->func;
@@ -105,39 +105,7 @@ cl_int TestHalf(cl_uint job_id, cl_uint thread_id, void *data)
105105
cl_ushort *p = (cl_ushort *)gIn + thread_id * buffer_elements;
106106
cl_ushort *p2 = (cl_ushort *)gIn2 + thread_id * buffer_elements;
107107
j = 0;
108-
109-
const std::vector<cl_half> &specialValuesHalf = getHalfSpecialValues();
110-
size_t specialValuesHalfCount = specialValuesHalf.size();
111-
int totalSpecialValueCount =
112-
specialValuesHalfCount * specialValuesHalfCount;
113-
int indx = (totalSpecialValueCount - 1) / buffer_elements;
114-
115-
if (job_id <= (cl_uint)indx)
116-
{ // test edge cases
117-
uint32_t x, y;
118-
119-
x = (job_id * buffer_elements) % specialValuesHalfCount;
120-
y = (job_id * buffer_elements) / specialValuesHalfCount;
121-
122-
for (; j < buffer_elements; j++)
123-
{
124-
p[j] = specialValuesHalf[x];
125-
p2[j] = specialValuesHalf[y];
126-
if (++x >= specialValuesHalfCount)
127-
{
128-
x = 0;
129-
y++;
130-
if (y >= specialValuesHalfCount) break;
131-
}
132-
}
133-
}
134-
135-
// Init any remaining values.
136-
for (; j < buffer_elements; j++)
137-
{
138-
p[j] = (cl_ushort)genrand_int32(d);
139-
p2[j] = (cl_ushort)genrand_int32(d);
140-
}
108+
fillHalfBinaryInput((cl_half *)p, (cl_half *)p2, buffer_elements, base, d);
141109

142110
if ((error = clEnqueueWriteBuffer(tinfo->tQueue, tinfo->inBuf, CL_FALSE, 0,
143111
buffer_size, p, 0, NULL, NULL)))
@@ -565,10 +533,9 @@ cl_int TestHalf(cl_uint job_id, cl_uint thread_id, void *data)
565533
{
566534
if (gVerboseBruteForce)
567535
{
568-
vlog("base:%14u step:%10u scale:%10u buf_elements:%10zu ulps:%5.3f "
536+
vlog("base:%14u buf_elements:%10zu ulps:%5.3f "
569537
"ThreadCount:%2u\n",
570-
base, job->step, job->scale, buffer_elements, job->ulps,
571-
job->threadCount);
538+
base, buffer_elements, job->ulps, job->threadCount);
572539
}
573540
else
574541
{
@@ -597,18 +564,8 @@ int TestFunc_Half_Half_Half_common(const Func *f, MTdata d, int isNextafter,
597564
test_info.threadCount = GetThreadCount();
598565
test_info.subBufferSize = BUFFER_SIZE
599566
/ (sizeof(cl_half) * RoundUpToNextPowerOfTwo(test_info.threadCount));
600-
test_info.scale = getTestScale(sizeof(cl_half));
601-
602-
test_info.step = (cl_uint)test_info.subBufferSize * test_info.scale;
603-
if (test_info.step / test_info.subBufferSize != test_info.scale)
604-
{
605-
// there was overflow
606-
test_info.jobCount = 1;
607-
}
608-
else
609-
{
610-
test_info.jobCount = (cl_uint)((1ULL << 32) / test_info.step);
611-
}
567+
test_info.jobCount = std::max(
568+
(cl_uint)1, (cl_uint)(getInputCount() / test_info.subBufferSize));
612569

613570
test_info.f = f;
614571
test_info.ulps = getAllowedUlpError(f, khalf, relaxedMode);

test_conformance/math_brute_force/binary_i_double.cpp

Lines changed: 7 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
5656
TestInfo *job = (TestInfo *)data;
5757
size_t buffer_elements = job->subBufferSize;
5858
size_t buffer_size = buffer_elements * sizeof(cl_double);
59-
cl_uint base = job_id * (cl_uint)job->step;
59+
cl_uint base = job_id * (cl_uint)buffer_elements;
6060
ThreadInfoBinaryFPInt *tinfo = &(job->tinfo[thread_id]);
6161
float ulps = job->ulps;
6262
dptr func = job->f->dfunc;
@@ -97,43 +97,8 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
9797
// Init input array
9898
cl_double *p = (cl_double *)gIn + thread_id * buffer_elements;
9999
cl_int *p2 = (cl_int *)gIn2 + thread_id * buffer_elements;
100-
size_t idx = 0;
101-
102-
const std::vector<double> &specialValues = getDoubleSpecialValues();
103-
size_t specialValuesCount = specialValues.size();
104-
const std::vector<int> &specialValuesInt = getInt3SpecialValues();
105-
size_t specialValuesIntCount = specialValuesInt.size();
106-
int totalSpecialValueCount = specialValuesCount * specialValuesIntCount;
107-
int lastSpecialJobIndex = (totalSpecialValueCount - 1) / buffer_elements;
108-
109-
// Test edge cases
110-
if (job_id <= (cl_uint)lastSpecialJobIndex)
111-
{
112-
cl_int *ip2 = (cl_int *)p2;
113-
uint32_t x, y;
114-
115-
x = (job_id * buffer_elements) % specialValuesCount;
116-
y = (job_id * buffer_elements) / specialValuesCount;
117-
118-
for (; idx < buffer_elements; idx++)
119-
{
120-
p[idx] = specialValues[x];
121-
ip2[idx] = specialValuesInt[y];
122-
if (++x >= specialValuesCount)
123-
{
124-
x = 0;
125-
y++;
126-
if (y >= specialValuesIntCount) break;
127-
}
128-
}
129-
}
130-
131-
// Init any remaining values.
132-
for (; idx < buffer_elements; idx++)
133-
{
134-
p[idx] = DoubleFromUInt32(genrand_int32(d));
135-
p2[idx] = genrand_int32(d);
136-
}
100+
fillIntDoubleBinaryInput((cl_int *)p2, (cl_double *)p, buffer_elements,
101+
base, d);
137102

138103
if ((error = clEnqueueWriteBuffer(tinfo->tQueue, tinfo->inBuf, CL_FALSE, 0,
139104
buffer_size, p, 0, NULL, NULL)))
@@ -328,10 +293,9 @@ cl_int Test(cl_uint job_id, cl_uint thread_id, void *data)
328293
{
329294
if (gVerboseBruteForce)
330295
{
331-
vlog("base:%14u step:%10u scale:%10u buf_elements:%10zd ulps:%5.3f "
296+
vlog("base:%14u buf_elements:%10zd ulps:%5.3f "
332297
"ThreadCount:%2u\n",
333-
base, job->step, job->scale, buffer_elements, job->ulps,
334-
job->threadCount);
298+
base, buffer_elements, job->ulps, job->threadCount);
335299
}
336300
else
337301
{
@@ -359,18 +323,8 @@ int TestFunc_Double_Double_Int(const Func *f, MTdata d, bool relaxedMode)
359323
test_info.threadCount = GetThreadCount();
360324
test_info.subBufferSize = BUFFER_SIZE
361325
/ (sizeof(cl_double) * RoundUpToNextPowerOfTwo(test_info.threadCount));
362-
test_info.scale = getTestScale(sizeof(cl_double));
363-
364-
test_info.step = (cl_uint)test_info.subBufferSize * test_info.scale;
365-
if (test_info.step / test_info.subBufferSize != test_info.scale)
366-
{
367-
// there was overflow
368-
test_info.jobCount = 1;
369-
}
370-
else
371-
{
372-
test_info.jobCount = (cl_uint)((1ULL << 32) / test_info.step);
373-
}
326+
test_info.jobCount = std::max(
327+
(cl_uint)1, (cl_uint)(getInputCount() / test_info.subBufferSize));
374328

375329
test_info.f = f;
376330
test_info.ulps = getAllowedUlpError(f, kdouble, relaxedMode);

0 commit comments

Comments
 (0)