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

stillwater-sc / universal / 23218775201

17 Mar 2026 10:11PM UTC coverage: 84.305% (+0.2%) from 84.112%
23218775201

push

github

web-flow
feat(blas): add serialization regression tests and verify #509 fix (#589)

Add regression level 1 tests for the serialization facility:

serialization.cpp:
- Exercise ReportFormats for lns and dbns (the lns::fraction() stub
  that caused #509 is now implemented)
- Native float vector save/restore round-trip

typed_serialization.cpp:
- lns<8,2> vector round-trip (directly exercises #509 scenario)
- dbns<8,3> vector round-trip
- integer<32> vector round-trip
- Plus existing float, double, half, type-mismatch, multi-dataset tests

The lns::fraction() function is no longer a stub -- it correctly
extracts the lower rbits as the fractional part of the fixed-point
exponent. This means #509 is resolved.

Resolves #585
Relates to #509

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

51 of 69 new or added lines in 2 files covered. (73.91%)

1 existing line in 1 file now uncovered.

44180 of 52405 relevant lines covered (84.3%)

6014239.75 hits per line

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

69.74
/linalg/data/typed_serialization.cpp
1
// typed_serialization.cpp: test suite for client-directed serialization
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 <iostream>
9
#include <sstream>
10
#include <universal/number_systems.hpp>
11
#include <blas/blas.hpp>
12
#include <blas/generators.hpp>
13
#include <blas/serialization/datafile.hpp>
14
#include <blas/serialization/typed_datafile.hpp>
15
#include <universal/verification/test_suite.hpp>
16

17
#define MANUAL_TESTING 0
18
#ifndef REGRESSION_LEVEL_OVERRIDE
19
#undef REGRESSION_LEVEL_1
20
#define REGRESSION_LEVEL_1 1
21
#endif
22

23
int main()
1✔
24
try {
25
        using namespace sw::universal;
26
        using namespace sw::numeric::containers;
27
        using namespace sw::blas;
28

29
        std::string test_suite = "client-directed typed serialization";
2✔
30
        std::string test_tag = "typed_datafile";
1✔
31
        bool reportTestCases = true;
1✔
32
        int nrOfFailedTestCases = 0;
1✔
33

34
        ReportTestSuiteHeader(test_suite, reportTestCases);
1✔
35

36
#if MANUAL_TESTING
37

38
        {
39
                // declare a client type list
40
                using ClientTypes = type_list<float, double, half>;
41

42
                // create and populate a vector
43
                vector<float> v(5);
44
                for (unsigned i = 0; i < 5; ++i) v[i] = float(i) * 1.5f;
45

46
                // save
47
                typed_datafile<ClientTypes> df;
48
                df.add(v, "test_vector");
49
                std::stringstream ss;
50
                df.save(ss);
51

52
                std::cout << "Saved datafile:\n" << ss.str() << '\n';
53

54
                // restore
55
                typed_datafile<ClientTypes> df2;
56
                if (df2.restore(ss)) {
57
                        std::cout << "Restored successfully, " << df2.size() << " datasets\n";
58
                        std::cout << "Dataset name: " << df2.name(0) << '\n';
59
                }
60
                else {
61
                        std::cout << "Restore failed\n";
62
                }
63
        }
64

65
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
66
        return EXIT_SUCCESS;
67
#else
68

69
#if REGRESSION_LEVEL_1
70

71
        // Test 1: float vector round-trip
72
        {
73
                int start = nrOfFailedTestCases;
1✔
74
                using ClientTypes = type_list<float, double>;
75

76
                vector<float> original(10);
1✔
77
                for (unsigned i = 0; i < 10; ++i) original[i] = float(i) * 0.5f;
11✔
78

79
                typed_datafile<ClientTypes> saver;
1✔
80
                saver.add(original, "float_vec");
1✔
81
                std::stringstream ss;
1✔
82
                saver.save(ss);
1✔
83

84
                typed_datafile<ClientTypes> loader;
1✔
85
                if (!loader.restore(ss)) {
1✔
86
                        ++nrOfFailedTestCases;
×
87
                        if (reportTestCases) std::cerr << "FAIL: float vector restore failed\n";
×
88
                }
89
                if (loader.size() != 1) {
1✔
90
                        ++nrOfFailedTestCases;
×
91
                        if (reportTestCases) std::cerr << "FAIL: expected 1 dataset, got " << loader.size() << '\n';
×
92
                }
93
                if (nrOfFailedTestCases - start > 0) {
1✔
94
                        std::cout << "FAIL: float vector round-trip\n";
×
95
                }
96
        }
1✔
97

98
        // Test 2: double vector round-trip
99
        {
100
                int start = nrOfFailedTestCases;
1✔
101
                using ClientTypes = type_list<float, double>;
102

103
                vector<double> original(8);
1✔
104
                for (unsigned i = 0; i < 8; ++i) original[i] = double(i) * 1.25;
9✔
105

106
                typed_datafile<ClientTypes> saver;
1✔
107
                saver.add(original, "double_vec");
1✔
108
                std::stringstream ss;
1✔
109
                saver.save(ss);
1✔
110

111
                typed_datafile<ClientTypes> loader;
1✔
112
                if (!loader.restore(ss)) {
1✔
113
                        ++nrOfFailedTestCases;
×
114
                        if (reportTestCases) std::cerr << "FAIL: double vector restore failed\n";
×
115
                }
116
                if (nrOfFailedTestCases - start > 0) {
1✔
117
                        std::cout << "FAIL: double vector round-trip\n";
×
118
                }
119
        }
1✔
120

121
        // Test 3: cfloat (half) vector round-trip
122
        {
123
                int start = nrOfFailedTestCases;
1✔
124
                using ClientTypes = type_list<float, double, half>;
125

126
                vector<half> original(6);
1✔
127
                for (unsigned i = 0; i < 6; ++i) original[i] = half(float(i) * 0.25f);
7✔
128

129
                typed_datafile<ClientTypes> saver;
1✔
130
                saver.add(original, "half_vec");
1✔
131
                std::stringstream ss;
1✔
132
                saver.save(ss);
1✔
133

134
                typed_datafile<ClientTypes> loader;
1✔
135
                if (!loader.restore(ss)) {
1✔
136
                        ++nrOfFailedTestCases;
×
137
                        if (reportTestCases) std::cerr << "FAIL: half vector restore failed\n";
×
138
                }
139
                if (nrOfFailedTestCases - start > 0) {
1✔
140
                        std::cout << "FAIL: half vector round-trip\n";
×
141
                }
142
        }
1✔
143

144
        // Test 4: type mismatch -- save with half, restore without half in registry
145
        {
146
                int start = nrOfFailedTestCases;
1✔
147
                using SaveTypes = type_list<float, double, half>;
148
                using LoadTypes = type_list<float, double>;  // no half!
149

150
                vector<half> original(4);
1✔
151
                for (unsigned i = 0; i < 4; ++i) original[i] = half(float(i));
5✔
152

153
                typed_datafile<SaveTypes> saver;
1✔
154
                saver.add(original, "half_data");
1✔
155
                std::stringstream ss;
1✔
156
                saver.save(ss);
1✔
157

158
                // restore with a registry that lacks half -- should report unsupported type
159
                typed_datafile<LoadTypes> loader;
1✔
160
                // restore returns true even if some types are unsupported (skipped)
161
                loader.restore(ss);
1✔
162
                // the dataset should not have been restored
163
                if (loader.size() != 0) {
1✔
164
                        ++nrOfFailedTestCases;
×
165
                        if (reportTestCases) std::cerr << "FAIL: type mismatch should result in 0 restored datasets\n";
×
166
                }
167
                if (nrOfFailedTestCases - start > 0) {
1✔
168
                        std::cout << "FAIL: type mismatch test\n";
×
169
                }
170
        }
1✔
171

172
        // Test 5: multiple datasets in one file
173
        {
174
                int start = nrOfFailedTestCases;
1✔
175
                using ClientTypes = type_list<float, double>;
176

177
                vector<float> fv(3);
1✔
178
                fv[0] = 1.0f; fv[1] = 2.0f; fv[2] = 3.0f;
1✔
179
                vector<double> dv(2);
1✔
180
                dv[0] = 4.5; dv[1] = 5.5;
1✔
181

182
                typed_datafile<ClientTypes> saver;
1✔
183
                saver.add(fv, "floats");
2✔
184
                saver.add(dv, "doubles");
1✔
185
                std::stringstream ss;
1✔
186
                saver.save(ss);
1✔
187

188
                typed_datafile<ClientTypes> loader;
1✔
189
                if (!loader.restore(ss)) {
1✔
190
                        ++nrOfFailedTestCases;
×
191
                        if (reportTestCases) std::cerr << "FAIL: multi-dataset restore failed\n";
×
192
                }
193
                if (loader.size() != 2) {
1✔
194
                        ++nrOfFailedTestCases;
×
195
                        if (reportTestCases) std::cerr << "FAIL: expected 2 datasets, got " << loader.size() << '\n';
×
196
                }
197
                if (nrOfFailedTestCases - start > 0) {
1✔
198
                        std::cout << "FAIL: multiple datasets\n";
×
199
                }
200
        }
1✔
201

202
        // Test 6: lns vector round-trip (exercises lns serialization that caused #509)
203
        {
204
                int start = nrOfFailedTestCases;
1✔
205
                using ClientTypes = type_list<float, lns<8, 2, uint8_t>>;
206

207
                vector<lns<8, 2, uint8_t>> v(4);
1✔
208
                v[0] = 1.0; v[1] = 2.0; v[2] = 0.5; v[3] = -1.0;
1✔
209

210
                typed_datafile<ClientTypes> saver;
1✔
211
                saver.add(v, "lns_vec");
1✔
212
                std::stringstream ss;
1✔
213
                saver.save(ss);
1✔
214

215
                typed_datafile<ClientTypes> loader;
1✔
216
                if (!loader.restore(ss)) {
1✔
NEW
217
                        ++nrOfFailedTestCases;
×
NEW
218
                        if (reportTestCases) std::cerr << "FAIL: lns vector restore failed\n";
×
219
                }
220
                if (loader.size() != 1) {
1✔
NEW
221
                        ++nrOfFailedTestCases;
×
NEW
222
                        if (reportTestCases) std::cerr << "FAIL: expected 1 lns dataset\n";
×
223
                }
224
                if (nrOfFailedTestCases - start > 0) {
1✔
NEW
225
                        std::cout << "FAIL: lns vector round-trip\n";
×
226
                }
227
        }
1✔
228

229
        // Test 7: dbns vector round-trip
230
        {
231
                int start = nrOfFailedTestCases;
1✔
232
                using ClientTypes = type_list<float, dbns<8, 3, uint8_t>>;
233

234
                vector<dbns<8, 3, uint8_t>> v(3);
1✔
235
                v[0] = 1.0; v[1] = 2.0; v[2] = 4.0;
1✔
236

237
                typed_datafile<ClientTypes> saver;
1✔
238
                saver.add(v, "dbns_vec");
1✔
239
                std::stringstream ss;
1✔
240
                saver.save(ss);
1✔
241

242
                typed_datafile<ClientTypes> loader;
1✔
243
                if (!loader.restore(ss)) {
1✔
NEW
244
                        ++nrOfFailedTestCases;
×
NEW
245
                        if (reportTestCases) std::cerr << "FAIL: dbns vector restore failed\n";
×
246
                }
247
                if (loader.size() != 1) {
1✔
NEW
248
                        ++nrOfFailedTestCases;
×
NEW
249
                        if (reportTestCases) std::cerr << "FAIL: expected 1 dbns dataset\n";
×
250
                }
251
                if (nrOfFailedTestCases - start > 0) {
1✔
NEW
252
                        std::cout << "FAIL: dbns vector round-trip\n";
×
253
                }
254
        }
1✔
255

256
        // Test 8: integer vector round-trip
257
        {
258
                int start = nrOfFailedTestCases;
1✔
259
                using ClientTypes = type_list<float, integer<32, uint32_t, IntegerNumberType::IntegerNumber>>;
260

261
                vector<integer<32, uint32_t, IntegerNumberType::IntegerNumber>> v(4);
1✔
262
                v[0] = 1; v[1] = -2; v[2] = 100; v[3] = -999;
1✔
263

264
                typed_datafile<ClientTypes> saver;
1✔
265
                saver.add(v, "int_vec");
1✔
266
                std::stringstream ss;
1✔
267
                saver.save(ss);
1✔
268

269
                typed_datafile<ClientTypes> loader;
1✔
270
                if (!loader.restore(ss)) {
1✔
NEW
271
                        ++nrOfFailedTestCases;
×
NEW
272
                        if (reportTestCases) std::cerr << "FAIL: integer vector restore failed\n";
×
273
                }
274
                if (loader.size() != 1) {
1✔
NEW
275
                        ++nrOfFailedTestCases;
×
NEW
276
                        if (reportTestCases) std::cerr << "FAIL: expected 1 integer dataset\n";
×
277
                }
278
                if (nrOfFailedTestCases - start > 0) {
1✔
NEW
279
                        std::cout << "FAIL: integer vector round-trip\n";
×
280
                }
281
        }
1✔
282

283
#endif
284

285
        ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
1✔
286
        return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
1✔
287
#endif
288
}
1✔
289
catch (char const* msg) {
×
290
        std::cerr << "Caught ad-hoc exception: " << msg << std::endl;
×
291
        return EXIT_FAILURE;
×
292
}
×
293
catch (const std::runtime_error& err) {
×
294
        std::cerr << "Caught runtime exception: " << err.what() << std::endl;
×
295
        return EXIT_FAILURE;
×
296
}
×
297
catch (...) {
×
298
        std::cerr << "Caught unknown exception" << std::endl;
×
299
        return EXIT_FAILURE;
×
300
}
×
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