• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stillwater-sc / universal / 21373593817

26 Jan 2026 08:52PM UTC coverage: 84.006%. First build
21373593817

Pull #499

github

Ravenwater
Add comprehensive BLAS regression tests for coverage

Convert generators.cpp and matrix_ops.cpp from demos to proper
regression tests with assertions:

generators.cpp:
- Add VerifyIdentityGenerator, VerifyRowOrderIndex, VerifyColumnOrderIndex
- Add VerifyLaplace2D, VerifyMinij, VerifyMagicSquare
- Add VerifyUniformRandom, VerifyGaussianRandom
- Add VerifyHilbert (scaled and unscaled), VerifyTridiag
- Test with double, float, posit<32,2>, posit<16,1>

matrix_ops.cpp:
- Add VerifyTranspose, VerifyMatrixVectorProduct, VerifyMatrixMatrixProduct
- Add VerifyFusedMatrixOps for posit fused operations
- Add VerifyOperators (eye, diag, tril, triu)
- Add VerifyNorm (1-norm, 2-norm, inf-norm)
- Add VerifyMatnorm (matrix 1-norm and inf-norm)
- Add VerifyVmath (sqrt, square, power, sin, cos, tan)
- Test with float, double, posit<32,2>, bfloat16

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Pull Request #499: V3.93: UBSan fixes, image demo, and coverage workflow

588 of 852 new or added lines in 9 files covered. (69.01%)

33478 of 39852 relevant lines covered (84.01%)

6562329.44 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.21
/linalg/data/summary_statistics.cpp
1
// summary_statistics.cpp: test suite for summary statistics function for data preprocessing
2
//
3
// Copyright (C) 2017 Stillwater Supercomputing, Inc.
4
// SPDX-License-Identifier: MIT
5
//
6
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
7
#include <universal/utility/directives.hpp>
8
#include <cmath>
9
#include <sstream>
10
#include <universal/number/integer/integer.hpp>
11
#include <universal/number/fixpnt/fixpnt.hpp>
12
#include <universal/number/cfloat/cfloat.hpp>
13
#include <universal/number/posit/posit.hpp>
14
#include <universal/number/lns/lns.hpp>
15

16
// Stillwater BLAS library
17
#include <blas/blas.hpp>
18
#include <universal/verification/test_suite.hpp>
19

20

21
// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
22
#define MANUAL_TESTING 0
23
// REGRESSION_LEVEL_OVERRIDE is set by the cmake file to drive a specific regression intensity
24
// It is the responsibility of the regression test to organize the tests in a quartile progression.
25
//#undef REGRESSION_LEVEL_OVERRIDE
26
#ifndef REGRESSION_LEVEL_OVERRIDE
27
#undef REGRESSION_LEVEL_1
28
#undef REGRESSION_LEVEL_2
29
#undef REGRESSION_LEVEL_3
30
#undef REGRESSION_LEVEL_4
31
#define REGRESSION_LEVEL_1 1
32
#define REGRESSION_LEVEL_2 1
33
#define REGRESSION_LEVEL_3 1
34
#define REGRESSION_LEVEL_4 1
35
#endif
36

37
namespace sw { namespace blas {
38

39
        ////////////////////////////////////////////////////////////////////////
40
        // Test summaryStatistics() function
41
        template<typename Scalar>
42
        int VerifySummaryStatistics(bool reportTestCases) {
1✔
43
                int nrOfFailedTests = 0;
1✔
44

45
                // Test with known data: [1, 2, 3, 4, 5]
46
                // mean = 3.0, stddev = sqrt(10/4) = 1.5811...
47
                {
48
                        std::vector<Scalar> data = { Scalar(1), Scalar(2), Scalar(3), Scalar(4), Scalar(5) };
2✔
49
                        auto stats = summaryStatistics(data);
1✔
50

51
                        if (std::abs(double(stats.mean) - 3.0) > 0.001) {
1✔
NEW
52
                                ++nrOfFailedTests;
×
NEW
53
                                if (reportTestCases) std::cerr << "FAIL: mean of [1,2,3,4,5] = " << stats.mean << " (expected 3.0)\n";
×
54
                        }
55

56
                        // Sample stddev: sqrt(sum((x-mean)^2)/(N-1)) = sqrt(10/4) = 1.5811...
57
                        double expectedStddev = std::sqrt(10.0 / 4.0);
1✔
58
                        if (std::abs(double(stats.stddev) - expectedStddev) > 0.01) {
1✔
NEW
59
                                ++nrOfFailedTests;
×
NEW
60
                                if (reportTestCases) std::cerr << "FAIL: stddev of [1,2,3,4,5] = " << stats.stddev << " (expected " << expectedStddev << ")\n";
×
61
                        }
62

63
                        // Quantiles: min=1, q1=2, median=3, q3=4, max=5
64
                        if (double(stats.quantiles.q[0]) != 1.0 || double(stats.quantiles.q[4]) != 5.0) {
1✔
NEW
65
                                ++nrOfFailedTests;
×
NEW
66
                                if (reportTestCases) std::cerr << "FAIL: quantiles min/max incorrect\n";
×
67
                        }
68
                }
1✔
69

70
                // Test with two elements (edge case for sample stddev formula)
71
                {
72
                        std::vector<Scalar> data = { Scalar(0), Scalar(2) };
2✔
73
                        auto stats = summaryStatistics(data);
1✔
74

75
                        if (std::abs(double(stats.mean) - 1.0) > 0.001) {
1✔
NEW
76
                                ++nrOfFailedTests;
×
NEW
77
                                if (reportTestCases) std::cerr << "FAIL: mean of [0,2] = " << stats.mean << " (expected 1.0)\n";
×
78
                        }
79

80
                        // Sample stddev: sqrt(2/(2-1)) = sqrt(2) = 1.4142...
81
                        double expectedStddev = std::sqrt(2.0);
1✔
82
                        if (std::abs(double(stats.stddev) - expectedStddev) > 0.01) {
1✔
NEW
83
                                ++nrOfFailedTests;
×
NEW
84
                                if (reportTestCases) std::cerr << "FAIL: stddev of [0,2] = " << stats.stddev << " (expected " << expectedStddev << ")\n";
×
85
                        }
86
                }
1✔
87

88
                // Test with negative values
89
                {
90
                        std::vector<Scalar> data = { Scalar(-2), Scalar(-1), Scalar(0), Scalar(1), Scalar(2) };
2✔
91
                        auto stats = summaryStatistics(data);
1✔
92

93
                        if (std::abs(double(stats.mean)) > 0.001) {
1✔
NEW
94
                                ++nrOfFailedTests;
×
NEW
95
                                if (reportTestCases) std::cerr << "FAIL: mean of [-2,-1,0,1,2] = " << stats.mean << " (expected 0.0)\n";
×
96
                        }
97
                }
1✔
98

99
                // Test with uniform data (stddev should be 0)
100
                {
101
                        std::vector<Scalar> data = { Scalar(5), Scalar(5), Scalar(5), Scalar(5) };
2✔
102
                        auto stats = summaryStatistics(data);
1✔
103

104
                        if (std::abs(double(stats.mean) - 5.0) > 0.001) {
1✔
NEW
105
                                ++nrOfFailedTests;
×
NEW
106
                                if (reportTestCases) std::cerr << "FAIL: mean of [5,5,5,5] = " << stats.mean << " (expected 5.0)\n";
×
107
                        }
108

109
                        if (std::abs(double(stats.stddev)) > 0.001) {
1✔
NEW
110
                                ++nrOfFailedTests;
×
NEW
111
                                if (reportTestCases) std::cerr << "FAIL: stddev of [5,5,5,5] = " << stats.stddev << " (expected 0.0)\n";
×
112
                        }
113
                }
1✔
114

115
                return nrOfFailedTests;
1✔
116
        }
117

118
        ////////////////////////////////////////////////////////////////////////
119
        // Test quantiles() function directly
120
        template<typename Scalar>
121
        int VerifyQuantiles(bool reportTestCases) {
1✔
122
                int nrOfFailedTests = 0;
1✔
123

124
                // Test with 8 elements: [1,2,3,4,5,6,7,8]
125
                {
126
                        std::vector<Scalar> data = { Scalar(1), Scalar(2), Scalar(3), Scalar(4),
2✔
127
                                                      Scalar(5), Scalar(6), Scalar(7), Scalar(8) };
128
                        auto q = quantiles(data);
1✔
129

130
                        // min = 1, q1 = v[2] = 3, median = v[4] = 5, q3 = v[6] = 7, max = 8
131
                        if (double(q.q[0]) != 1.0) {
1✔
NEW
132
                                ++nrOfFailedTests;
×
NEW
133
                                if (reportTestCases) std::cerr << "FAIL: quantiles min = " << q.q[0] << " (expected 1)\n";
×
134
                        }
135
                        if (double(q.q[4]) != 8.0) {
1✔
NEW
136
                                ++nrOfFailedTests;
×
NEW
137
                                if (reportTestCases) std::cerr << "FAIL: quantiles max = " << q.q[4] << " (expected 8)\n";
×
138
                        }
139
                }
1✔
140

141
                // Test with unsorted data
142
                {
143
                        std::vector<Scalar> data = { Scalar(5), Scalar(1), Scalar(8), Scalar(3),
2✔
144
                                                      Scalar(7), Scalar(2), Scalar(6), Scalar(4) };
145
                        auto q = quantiles(data);
1✔
146

147
                        // After sorting: [1,2,3,4,5,6,7,8]
148
                        if (double(q.q[0]) != 1.0 || double(q.q[4]) != 8.0) {
1✔
NEW
149
                                ++nrOfFailedTests;
×
NEW
150
                                if (reportTestCases) std::cerr << "FAIL: quantiles on unsorted data incorrect\n";
×
151
                        }
152
                }
1✔
153

154
                // Test Quantiles struct constructors
155
                {
156
                        Quantiles<Scalar> q1;  // default constructor
157
                        Quantiles<Scalar> q2(Scalar(1), Scalar(2), Scalar(3), Scalar(4), Scalar(5));
1✔
158

159
                        if (double(q2.q[0]) != 1.0 || double(q2.q[2]) != 3.0 || double(q2.q[4]) != 5.0) {
1✔
NEW
160
                                ++nrOfFailedTests;
×
NEW
161
                                if (reportTestCases) std::cerr << "FAIL: Quantiles parameterized constructor\n";
×
162
                        }
163

164
                        // Test set() method
165
                        q1.set(Scalar(10), Scalar(20), Scalar(30), Scalar(40), Scalar(50));
1✔
166
                        if (double(q1.q[0]) != 10.0 || double(q1.q[4]) != 50.0) {
1✔
NEW
167
                                ++nrOfFailedTests;
×
NEW
168
                                if (reportTestCases) std::cerr << "FAIL: Quantiles::set() method\n";
×
169
                        }
170
                }
171

172
                return nrOfFailedTests;
1✔
173
        }
174

175
        ////////////////////////////////////////////////////////////////////////
176
        // Test gaussian_random() with std::vector
177
        template<typename Scalar>
178
        int VerifyGaussianRandomStdVector(bool reportTestCases) {
1✔
179
                int nrOfFailedTests = 0;
1✔
180

181
                // Generate gaussian random data and verify basic properties
182
                {
183
                        size_t N = 10000;
1✔
184
                        std::vector<Scalar> data(N);
1✔
185
                        gaussian_random(data, 0.0, 1.0);
1✔
186

187
                        auto stats = summaryStatistics(data);
1✔
188

189
                        // With 10000 samples, mean should be close to 0 (within ~0.05 typically)
190
                        if (std::abs(double(stats.mean)) > 0.1) {
1✔
NEW
191
                                ++nrOfFailedTests;
×
NEW
192
                                if (reportTestCases) std::cerr << "FAIL: gaussian mean = " << stats.mean << " (expected ~0.0)\n";
×
193
                        }
194

195
                        // stddev should be close to 1 (within ~0.05 typically)
196
                        if (std::abs(double(stats.stddev) - 1.0) > 0.1) {
1✔
NEW
197
                                ++nrOfFailedTests;
×
NEW
198
                                if (reportTestCases) std::cerr << "FAIL: gaussian stddev = " << stats.stddev << " (expected ~1.0)\n";
×
199
                        }
200
                }
1✔
201

202
                // Test with different mean and stddev
203
                {
204
                        size_t N = 10000;
1✔
205
                        std::vector<Scalar> data(N);
1✔
206
                        gaussian_random(data, 100.0, 10.0);
1✔
207

208
                        auto stats = summaryStatistics(data);
1✔
209

210
                        if (std::abs(double(stats.mean) - 100.0) > 2.0) {
1✔
NEW
211
                                ++nrOfFailedTests;
×
NEW
212
                                if (reportTestCases) std::cerr << "FAIL: gaussian mean = " << stats.mean << " (expected ~100.0)\n";
×
213
                        }
214

215
                        if (std::abs(double(stats.stddev) - 10.0) > 1.0) {
1✔
NEW
216
                                ++nrOfFailedTests;
×
NEW
217
                                if (reportTestCases) std::cerr << "FAIL: gaussian stddev = " << stats.stddev << " (expected ~10.0)\n";
×
218
                        }
219
                }
1✔
220

221
                return nrOfFailedTests;
1✔
222
        }
223

224
        ////////////////////////////////////////////////////////////////////////
225
        // Test gaussian_random() with blas::vector
226
        template<typename Scalar>
227
        int VerifyGaussianRandomBlasVector(bool reportTestCases) {
228
                int nrOfFailedTests = 0;
229

230
                // Generate gaussian random data using blas::vector
231
                {
232
                        size_t N = 1000;
233
                        sw::numeric::containers::vector<Scalar> v(N);
234
                        gaussian_random(v, 0.0, 1.0);
235

236
                        // Compute mean manually
237
                        Scalar sum{0};
238
                        for (size_t i = 0; i < N; ++i) {
239
                                sum += v[i];
240
                        }
241
                        Scalar mean = sum / Scalar(N);
242

243
                        // Mean should be close to 0
244
                        if (std::abs(double(mean)) > 0.2) {
245
                                ++nrOfFailedTests;
246
                                if (reportTestCases) std::cerr << "FAIL: blas::vector gaussian mean = " << mean << " (expected ~0.0)\n";
247
                        }
248
                }
249

250
                // Test gaussian_random_vector factory function
251
                {
252
                        auto v = gaussian_random_vector<Scalar>(1000, 50.0, 5.0);
253

254
                        Scalar sum{0};
255
                        for (size_t i = 0; i < size(v); ++i) {
256
                                sum += v[i];
257
                        }
258
                        Scalar mean = sum / Scalar(size(v));
259

260
                        if (std::abs(double(mean) - 50.0) > 2.0) {
261
                                ++nrOfFailedTests;
262
                                if (reportTestCases) std::cerr << "FAIL: gaussian_random_vector mean = " << mean << " (expected ~50.0)\n";
263
                        }
264
                }
265

266
                return nrOfFailedTests;
267
        }
268

269
        ////////////////////////////////////////////////////////////////////////
270
        // Test gaussian_random() with blas::matrix
271
        template<typename Scalar>
272
        int VerifyGaussianRandomMatrix(bool reportTestCases) {
273
                int nrOfFailedTests = 0;
274

275
                // Generate gaussian random matrix
276
                {
277
                        sw::numeric::containers::matrix<Scalar> A(50, 50);
278
                        gaussian_random(A, 0.0, 1.0);
279

280
                        // Compute mean of all elements
281
                        Scalar sum{0};
282
                        for (size_t i = 0; i < num_rows(A); ++i) {
283
                                for (size_t j = 0; j < num_cols(A); ++j) {
284
                                        sum += A[i][j];
285
                                }
286
                        }
287
                        Scalar mean = sum / Scalar(num_rows(A) * num_cols(A));
288

289
                        if (std::abs(double(mean)) > 0.2) {
290
                                ++nrOfFailedTests;
291
                                if (reportTestCases) std::cerr << "FAIL: matrix gaussian mean = " << mean << " (expected ~0.0)\n";
292
                        }
293
                }
294

295
                // Test gaussian_random_matrix factory function
296
                {
297
                        auto A = gaussian_random_matrix<Scalar>(30, 30, 100.0, 10.0);
298

299
                        if (num_rows(A) != 30 || num_cols(A) != 30) {
300
                                ++nrOfFailedTests;
301
                                if (reportTestCases) std::cerr << "FAIL: gaussian_random_matrix dimensions incorrect\n";
302
                        }
303

304
                        Scalar sum{0};
305
                        for (size_t i = 0; i < num_rows(A); ++i) {
306
                                for (size_t j = 0; j < num_cols(A); ++j) {
307
                                        sum += A[i][j];
308
                                }
309
                        }
310
                        Scalar mean = sum / Scalar(num_rows(A) * num_cols(A));
311

312
                        if (std::abs(double(mean) - 100.0) > 5.0) {
313
                                ++nrOfFailedTests;
314
                                if (reportTestCases) std::cerr << "FAIL: gaussian_random_matrix mean = " << mean << " (expected ~100.0)\n";
315
                        }
316
                }
317

318
                return nrOfFailedTests;
319
        }
320

321
        ////////////////////////////////////////////////////////////////////////
322
        // Test SummaryStats and Quantiles operator<<
323
        int VerifyStreamOperators(bool reportTestCases) {
1✔
324
                int nrOfFailedTests = 0;
1✔
325

326
                // Test Quantiles operator<<
327
                {
328
                        Quantiles<double> q(1.0, 2.0, 3.0, 4.0, 5.0);
1✔
329
                        std::ostringstream oss;
1✔
330
                        oss << q;
1✔
331
                        std::string output = oss.str();
1✔
332

333
                        if (output.find("quantiles:") == std::string::npos) {
1✔
NEW
334
                                ++nrOfFailedTests;
×
NEW
335
                                if (reportTestCases) std::cerr << "FAIL: Quantiles operator<< missing 'quantiles:'\n";
×
336
                        }
337
                        if (output.find("1") == std::string::npos || output.find("5") == std::string::npos) {
1✔
NEW
338
                                ++nrOfFailedTests;
×
NEW
339
                                if (reportTestCases) std::cerr << "FAIL: Quantiles operator<< missing values\n";
×
340
                        }
341
                }
1✔
342

343
                // Test SummaryStats operator<<
344
                {
345
                        SummaryStats<double> stats;
346
                        stats.mean = 10.0;
1✔
347
                        stats.stddev = 2.0;
1✔
348
                        stats.quantiles.set(1.0, 5.0, 10.0, 15.0, 20.0);
1✔
349

350
                        std::ostringstream oss;
1✔
351
                        oss << stats;
1✔
352
                        std::string output = oss.str();
1✔
353

354
                        if (output.find("mean") == std::string::npos) {
1✔
NEW
355
                                ++nrOfFailedTests;
×
NEW
356
                                if (reportTestCases) std::cerr << "FAIL: SummaryStats operator<< missing 'mean'\n";
×
357
                        }
358
                        if (output.find("stddev") == std::string::npos) {
1✔
NEW
359
                                ++nrOfFailedTests;
×
NEW
360
                                if (reportTestCases) std::cerr << "FAIL: SummaryStats operator<< missing 'stddev'\n";
×
361
                        }
362
                }
1✔
363

364
                return nrOfFailedTests;
1✔
365
        }
366

367
}} // namespace sw::blas
368

369
/*
370
 
371
 stats for a couple of 1M element runs:
372
 mean     : -0.000105222
373
 stddev   : 0.999774
374
 quartiles
375
 [ -4.40803, -0.673688, 0.00028514, 0.672469, 4.67264]
376
 mean     : -0.000603408
377
 stddev   : 1.00284
378
 quartiles
379
 [ -5.29692, -0.675401, -0.000193462, 0.674231, 4.90644]
380
 mean     : -0.0010701
381
 stddev   : 0.997858
382
 quartiles
383
 [ -4.99329, -0.674899, -0.00123088, 0.673464, 4.73132]
384

385
 */
386

387

388
int main()
1✔
389
try {
390
        using namespace sw::universal;
391
        using namespace sw::blas;
392

393
        std::string test_suite  = "summary statistics";
2✔
394
        std::string test_tag    = "sumstat";
1✔
395
        bool reportTestCases    = true;
1✔
396
        int nrOfFailedTestCases = 0;
1✔
397

398
        ReportTestSuiteHeader(test_suite, reportTestCases);
1✔
399

400
#if MANUAL_TESTING
401

402
        size_t N = 1024*1024;
403
        std::vector<double> data(N);
404
        gaussian_random(data, 0.0, 1.0);
405
        auto stats = summaryStatistics(data);
406

407
        std::cout << "Summary statistics:\n" << stats << '\n';
408

409
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
410
        return EXIT_SUCCESS;
411
#else
412

413
#if REGRESSION_LEVEL_1
414
        // Test summaryStatistics() with double
415
        nrOfFailedTestCases += ReportTestResult(VerifySummaryStatistics<double>(reportTestCases), "double", "summaryStatistics");
4✔
416

417
        // Test quantiles() function directly
418
        nrOfFailedTestCases += ReportTestResult(VerifyQuantiles<double>(reportTestCases), "double", "quantiles");
4✔
419

420
        // Test gaussian_random with std::vector<double>
421
        nrOfFailedTestCases += ReportTestResult(VerifyGaussianRandomStdVector<double>(reportTestCases), "std::vector<double>", "gaussian_random");
4✔
422

423
        // Test stream operators
424
        nrOfFailedTestCases += ReportTestResult(VerifyStreamOperators(reportTestCases), "SummaryStats/Quantiles", "operator<<");
3✔
425
#endif
426

427
#if REGRESSION_LEVEL_2
428
        // Test with float
429
        nrOfFailedTestCases += ReportTestResult(VerifySummaryStatistics<float>(reportTestCases), "float", "summaryStatistics");
430
        nrOfFailedTestCases += ReportTestResult(VerifyQuantiles<float>(reportTestCases), "float", "quantiles");
431
        nrOfFailedTestCases += ReportTestResult(VerifyGaussianRandomStdVector<float>(reportTestCases), "std::vector<float>", "gaussian_random");
432

433
        // Test gaussian_random with blas::vector
434
        nrOfFailedTestCases += ReportTestResult(VerifyGaussianRandomBlasVector<double>(reportTestCases), "blas::vector<double>", "gaussian_random");
435
#endif
436

437
#if REGRESSION_LEVEL_3
438
        // Test gaussian_random with blas::matrix
439
        nrOfFailedTestCases += ReportTestResult(VerifyGaussianRandomMatrix<double>(reportTestCases), "blas::matrix<double>", "gaussian_random");
440
        nrOfFailedTestCases += ReportTestResult(VerifyGaussianRandomMatrix<float>(reportTestCases), "blas::matrix<float>", "gaussian_random");
441
#endif
442

443
#if REGRESSION_LEVEL_4
444
        // Stress test with larger dataset
445
        {
446
                size_t N = 100000;
447
                std::vector<double> data(N);
448
                gaussian_random(data, 0.0, 1.0);
449
                auto stats = summaryStatistics(data);
450

451
                // With 100k samples, statistics should be very close to target
452
                if (std::abs(stats.mean) > 0.02) {
453
                        ++nrOfFailedTestCases;
454
                        if (reportTestCases) std::cerr << "FAIL: large dataset mean = " << stats.mean << "\n";
455
                }
456
                if (std::abs(stats.stddev - 1.0) > 0.02) {
457
                        ++nrOfFailedTestCases;
458
                        if (reportTestCases) std::cerr << "FAIL: large dataset stddev = " << stats.stddev << "\n";
459
                }
460
        }
461
        nrOfFailedTestCases += ReportTestResult(0, "stress test", "100k samples");
462
#endif
463

464
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
1✔
465
        return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
1✔
466
#endif
467
}
1✔
468
catch (char const* msg) {
×
469
        std::cerr << msg << std::endl;
×
470
        return EXIT_FAILURE;
×
471
}
×
472
catch (const sw::universal::universal_arithmetic_exception& err) {
×
473
        std::cerr << "Uncaught universal arithmetic exception: " << err.what() << std::endl;
×
474
        return EXIT_FAILURE;
×
475
}
×
476
catch (const sw::universal::universal_internal_exception& err) {
×
477
        std::cerr << "Uncaught universal internal exception: " << err.what() << std::endl;
×
478
        return EXIT_FAILURE;
×
479
}
×
480
catch (const std::runtime_error& err) {
×
481
        std::cerr << "Uncaught runtime exception: " << err.what() << std::endl;
×
482
        return EXIT_FAILURE;
×
483
}
×
484
catch (...) {
×
485
        std::cerr << "Caught unknown exception" << std::endl;
×
486
        return EXIT_FAILURE;
×
487
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc