Skip to content
This repository was archived by the owner on Mar 28, 2023. It is now read-only.

Commit 49bd916

Browse files
committed
[SYCL][ESIMD][EMU] tolerated mismatch rate in binary files comparison (e.g. for cases resulted from deviations in GPU vs host-based FP computations).
1 parent 85d5a7c commit 49bd916

File tree

2 files changed

+67
-11
lines changed

2 files changed

+67
-11
lines changed

SYCL/ESIMD/esimd_test_utils.hpp

Lines changed: 55 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <chrono>
1717
#include <cstring>
1818
#include <fstream>
19+
#include <iomanip>
1920
#include <iostream>
2021
#include <iterator>
2122
#include <string>
@@ -99,26 +100,73 @@ bool write_binary_file(const char *fname, const std::vector<T> &vec,
99100
}
100101

101102
template <typename T>
102-
bool cmp_binary_files(const char *fname1, const char *fname2, T tolerance) {
103+
bool cmp_binary_files(const char *fname1, const char *fname2, const T tolerance,
104+
const double toleratedMismatchRate = 0,
105+
const int mismatchReportThrottleLimit = 5) {
106+
107+
if (toleratedMismatchRate) {
108+
if (toleratedMismatchRate >= 1 || toleratedMismatchRate < 0) {
109+
std::cerr << "Tolerated mismatch rate (" << toleratedMismatchRate
110+
<< ") must be set within [0, 1) range" << std::endl;
111+
return false;
112+
}
113+
114+
std::cerr << "Tolerated mismatch rate set to " << toleratedMismatchRate
115+
<< std::endl;
116+
}
117+
103118
const auto vec1 = read_binary_file<T>(fname1);
104119
const auto vec2 = read_binary_file<T>(fname2);
120+
105121
if (vec1.size() != vec2.size()) {
106122
std::cerr << fname1 << " size is " << vec1.size();
107123
std::cerr << " whereas " << fname2 << " size is " << vec2.size()
108124
<< std::endl;
109125
return false;
110126
}
111-
for (size_t i = 0; i < vec1.size(); i++) {
127+
128+
double totalMismatches = 0;
129+
const double size = vec1.size();
130+
for (size_t i = 0; i < size; i++) {
112131
if (abs(vec1[i] - vec2[i]) > tolerance) {
113-
std::cerr << "Mismatch at " << i << ' ';
114-
if (sizeof(T) == 1) {
115-
std::cerr << (int)vec1[i] << " vs " << (int)vec2[i] << std::endl;
116-
} else {
117-
std::cerr << vec1[i] << " vs " << vec2[i] << std::endl;
132+
if (!toleratedMismatchRate ||
133+
(totalMismatches < mismatchReportThrottleLimit)) {
134+
135+
std::cerr << "Mismatch at " << i << ' ';
136+
if (sizeof(T) == 1) {
137+
std::cerr << (int)vec1[i] << " vs " << (int)vec2[i];
138+
} else {
139+
std::cerr << vec1[i] << " vs " << vec2[i];
140+
}
141+
142+
if (!toleratedMismatchRate) {
143+
std::cerr << std::endl;
144+
return false;
145+
} else {
146+
std::cerr << ". Current mismatch rate: " << std::setprecision(8)
147+
<< std::fixed << totalMismatches / size << std::endl;
148+
}
149+
150+
} else if (totalMismatches == mismatchReportThrottleLimit) {
151+
std::cerr << "Mismatch output throttled ... " << std::endl;
118152
}
153+
154+
totalMismatches++;
155+
}
156+
}
157+
158+
if (totalMismatches) {
159+
const auto totalMismatchRate = totalMismatches / size;
160+
if (totalMismatchRate > toleratedMismatchRate) {
161+
std::cerr << "Mismatch rate of " << totalMismatchRate
162+
<< " has exceeded the tolerated amount of "
163+
<< toleratedMismatchRate << std::endl;
119164
return false;
120165
}
166+
167+
std::cerr << "Total mismatch rate is " << totalMismatchRate << std::endl;
121168
}
169+
122170
return true;
123171
}
124172

SYCL/ESIMD/mandelbrot/mandelbrot.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ using namespace sycl::ext::intel::experimental::esimd;
3636
#define WIDTH 800
3737
#define HEIGHT 602
3838

39+
#define EMU_TOTAL_MISMATCH_RATE_TOLERANCE \
40+
0.0027 // the observed total mismatch rate (due to inherent divergency in host
41+
// vs GPU FP computations)
42+
3943
template <typename ACC>
4044
ESIMD_INLINE void mandelbrot(ACC out_image, int ix, int iy, int crunch,
4145
float xOff, float yOff, float scale) {
@@ -94,6 +98,9 @@ int main(int argc, char *argv[]) {
9498
double kernel_times = 0;
9599
unsigned num_iters = 10;
96100

101+
queue q(esimd_test::ESIMDSelector{}, esimd_test::createExceptionHandler(),
102+
property::queue::enable_profiling{});
103+
97104
try {
98105
cl::sycl::image<2> imgOutput((unsigned int *)buf, image_channel_order::rgba,
99106
image_channel_type::unsigned_int8,
@@ -107,9 +114,6 @@ int main(int argc, char *argv[]) {
107114
// Number of workitems in a workgroup
108115
cl::sycl::range<2> LocalRange{1, 1};
109116

110-
queue q(esimd_test::ESIMDSelector{}, esimd_test::createExceptionHandler(),
111-
property::queue::enable_profiling{});
112-
113117
auto dev = q.get_device();
114118
auto ctxt = q.get_context();
115119
std::cout << "Running on " << dev.get_info<info::device::name>() << "\n";
@@ -164,7 +168,11 @@ int main(int argc, char *argv[]) {
164168
fclose(dumpfile);
165169

166170
bool passed = true;
167-
if (!esimd_test::cmp_binary_files<unsigned char>(out_file, argv[2], 0)) {
171+
if (!esimd_test::cmp_binary_files<unsigned char>(
172+
out_file, argv[2], 0,
173+
q.get_backend() == cl::sycl::backend::ext_intel_esimd_emulator
174+
? EMU_TOTAL_MISMATCH_RATE_TOLERANCE
175+
: 0)) {
168176
std::cerr << out_file << " does not match the reference file " << argv[2]
169177
<< std::endl;
170178
passed = false;

0 commit comments

Comments
 (0)