Skip to content

Commit ce8a39a

Browse files
committed
Add Real32Trunc
1 parent 077ae65 commit ce8a39a

File tree

4 files changed

+183
-1
lines changed

4 files changed

+183
-1
lines changed

types/fundamental/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
* [`integer`](integer): `[U]Int{8,16,32,64}`, `Split[U]Int{16,32,64}`
44
* [`misc`](misc): `Bit`, `Byte`, `Char`
55
* [`real`](real): `Real{16,32,64}`, `SplitReal{32,64}`
6+
* [`real32trunc`](real32trunc): `Real32Trunc`
67

78
__Covered under a different category:__
89
* `[Split]Index{32,64}`: with [`std::string`](../string) and [`std::vector`](../vector)
910
* `Switch`: with [`std::variant`](../variant)
1011

1112
__Missing:__
12-
* `Real32Trunc`
1313
* `Real32Quant`
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Real Column Types with variable width and truncated mantissa
2+
3+
## Fields
4+
5+
* `FloatReal32Trunc10`
6+
* `FloatReal32Trunc16`
7+
* `FloatReal32Trunc31`
8+
* `DoubleReal32Trunc10`
9+
* `DoubleReal32Trunc16`
10+
* `DoubleReal32Trunc31`
11+
12+
with the corresponding field, column types and bit width.
13+
14+
## Entries
15+
16+
1. Ascending values
17+
2. All 1s in the mantissa
18+
3. Lowest values with N bits
19+
4. Smallest positive normal values with N bits
20+
5. Smallest positive subnormal values with N bits
21+
6. Maximum values with N bits

types/fundamental/real32trunc/read.C

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
#include <ROOT/REntry.hxx>
2+
#include <ROOT/RNTupleReader.hxx>
3+
4+
using ROOT::Experimental::REntry;
5+
using ROOT::Experimental::RNTupleReader;
6+
7+
#include <fstream>
8+
#include <ios>
9+
#include <ostream>
10+
#include <string>
11+
#include <string_view>
12+
13+
template <typename T>
14+
static void PrintRealValue(const REntry &entry, std::string_view name,
15+
std::ostream &os, bool last = false) {
16+
T value = *entry.GetPtr<T>(name);
17+
os << " \"" << name << "\": \"" << value << "\"";
18+
if (!last) {
19+
os << ",";
20+
}
21+
os << "\n";
22+
}
23+
24+
void read(std::string_view input = "types.fundamental.real32trunc.root",
25+
std::string_view output = "types.fundamental.real32trunc.json") {
26+
std::ofstream os(std::string{output});
27+
// Print floating-point numbers as hexadecimal literals.
28+
os << std::hexfloat;
29+
os << "[\n";
30+
31+
auto reader = RNTupleReader::Open("ntpl", input);
32+
auto &entry = reader->GetModel().GetDefaultEntry();
33+
bool first = true;
34+
for (auto index : *reader) {
35+
reader->LoadEntry(index);
36+
37+
if (first) {
38+
first = false;
39+
} else {
40+
os << ",\n";
41+
}
42+
os << " {\n";
43+
44+
PrintRealValue<float>(entry, "FloatReal32Trunc10", os);
45+
PrintRealValue<float>(entry, "FloatReal32Trunc16", os);
46+
PrintRealValue<float>(entry, "FloatReal32Trunc31", os);
47+
PrintRealValue<double>(entry, "DoubleReal32Trunc10", os);
48+
PrintRealValue<double>(entry, "DoubleReal32Trunc16", os);
49+
PrintRealValue<double>(entry, "DoubleReal32Trunc31", os, /*last=*/true);
50+
51+
os << " }";
52+
// Newline is intentionally missing, may need to print a comma before the
53+
// next entry.
54+
}
55+
os << "\n";
56+
os << "]\n";
57+
}

types/fundamental/real32trunc/write.C

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
#include <ROOT/RField.hxx>
2+
#include <ROOT/RNTupleModel.hxx>
3+
#include <ROOT/RNTupleUtil.hxx>
4+
#include <ROOT/RNTupleWriteOptions.hxx>
5+
#include <ROOT/RNTupleWriter.hxx>
6+
7+
using ROOT::Experimental::EColumnType;
8+
using ROOT::Experimental::RField;
9+
using ROOT::Experimental::RNTupleModel;
10+
using ROOT::Experimental::RNTupleWriteOptions;
11+
using ROOT::Experimental::RNTupleWriter;
12+
13+
#include <limits>
14+
#include <memory>
15+
#include <string_view>
16+
17+
template <typename T>
18+
static std::shared_ptr<T> MakeFieldReal32Trunc(RNTupleModel &model,
19+
std::string_view name,
20+
int nBits) {
21+
assert(nBits >= 10 && nBits < 32);
22+
auto field = std::make_unique<RField<T>>(name);
23+
field->SetTruncated(nBits);
24+
model.AddField(std::move(field));
25+
return model.GetDefaultEntry().GetPtr<T>(name);
26+
}
27+
28+
void write(std::string_view filename = "types.fundamental.real32trunc.root") {
29+
auto model = RNTupleModel::Create();
30+
31+
auto FloatReal32Trunc10 =
32+
MakeFieldReal32Trunc<float>(*model, "FloatReal32Trunc10", 10);
33+
auto FloatReal32Trunc16 =
34+
MakeFieldReal32Trunc<float>(*model, "FloatReal32Trunc16", 16);
35+
auto FloatReal32Trunc31 =
36+
MakeFieldReal32Trunc<float>(*model, "FloatReal32Trunc31", 31);
37+
auto DoubleReal32Trunc10 =
38+
MakeFieldReal32Trunc<double>(*model, "DoubleReal32Trunc10", 10);
39+
auto DoubleReal32Trunc16 =
40+
MakeFieldReal32Trunc<double>(*model, "DoubleReal32Trunc16", 16);
41+
auto DoubleReal32Trunc31 =
42+
MakeFieldReal32Trunc<double>(*model, "DoubleReal32Trunc31", 31);
43+
44+
RNTupleWriteOptions options;
45+
options.SetCompression(0);
46+
auto writer =
47+
RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options);
48+
49+
// First entry: ascending values
50+
*FloatReal32Trunc10 = 1.0f;
51+
*FloatReal32Trunc16 = 2.0f;
52+
*FloatReal32Trunc31 = 3.0f;
53+
*DoubleReal32Trunc10 = 4.0f;
54+
*DoubleReal32Trunc16 = 5.0f;
55+
*DoubleReal32Trunc31 = 6.0f;
56+
writer->Fill();
57+
58+
// Second entry: a value containing all 1s in the mantissa
59+
static constexpr float Value32 = 3.9999997f;
60+
*FloatReal32Trunc10 = Value32;
61+
*FloatReal32Trunc16 = Value32;
62+
*FloatReal32Trunc31 = Value32;
63+
*DoubleReal32Trunc10 = Value32;
64+
*DoubleReal32Trunc16 = Value32;
65+
*DoubleReal32Trunc31 = Value32;
66+
writer->Fill();
67+
68+
// Third entry: lowest values with N bits
69+
*FloatReal32Trunc10 = -0x1.8p127f;
70+
*FloatReal32Trunc16 = -0x1.FEp127f;
71+
*FloatReal32Trunc31 = std::numeric_limits<float>::lowest() + 0x1p-149f;
72+
*DoubleReal32Trunc10 = -0x1.8p127f;
73+
*DoubleReal32Trunc16 = -0x1.FEp127;
74+
*DoubleReal32Trunc31 = std::numeric_limits<float>::lowest() + 0x1p-149f;
75+
writer->Fill();
76+
77+
// Fourth entry: min = smallest positive normal values
78+
*FloatReal32Trunc10 = std::numeric_limits<float>::min();
79+
*FloatReal32Trunc16 = std::numeric_limits<float>::min();
80+
*FloatReal32Trunc31 = std::numeric_limits<float>::min();
81+
*DoubleReal32Trunc10 = std::numeric_limits<float>::min();
82+
*DoubleReal32Trunc16 = std::numeric_limits<float>::min();
83+
*DoubleReal32Trunc31 = std::numeric_limits<float>::min();
84+
writer->Fill();
85+
86+
// Fifth entry: smallest positive subnormal values with N bits
87+
// (e.g. FloatReal32Trunc10 has a value with all 0s except a 1 in the 10th bit)
88+
*FloatReal32Trunc10 = 0x1p-127f;
89+
*FloatReal32Trunc16 = 0x1p-133f;
90+
*FloatReal32Trunc31 = 0x1p-148f;
91+
*DoubleReal32Trunc10 = 0x1p-127f;
92+
*DoubleReal32Trunc16 = 0x1p-133f;
93+
*DoubleReal32Trunc31 = 0x1p-148f;
94+
writer->Fill();
95+
96+
// Sixth entry: maximum values
97+
*FloatReal32Trunc10 = 0x1.8p127f;
98+
*FloatReal32Trunc16 = 0x1.FEp127f;
99+
*FloatReal32Trunc31 = std::numeric_limits<float>::max() - 0x1p-149f;
100+
*DoubleReal32Trunc10 = 0x1.8p127f;
101+
*DoubleReal32Trunc16 = 0x1.FEp127;
102+
*DoubleReal32Trunc31 = std::numeric_limits<float>::max() - 0x1p-149f;
103+
writer->Fill();
104+
}

0 commit comments

Comments
 (0)