Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion types/fundamental/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
* [`integer`](integer): `[U]Int{8,16,32,64}`, `Split[U]Int{16,32,64}`
* [`misc`](misc): `Bit`, `Byte`, `Char`
* [`real`](real): `Real{16,32,64}`, `SplitReal{32,64}`
* [`real32trunc`](real32trunc): `Real32Trunc`

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

__Missing:__
* `Real32Trunc`
* `Real32Quant`
21 changes: 21 additions & 0 deletions types/fundamental/real32trunc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Real Column Types with variable width and truncated mantissa

## Fields

* `FloatReal32Trunc10`
* `FloatReal32Trunc16`
* `FloatReal32Trunc31`
* `DoubleReal32Trunc10`
* `DoubleReal32Trunc16`
* `DoubleReal32Trunc31`
Comment thread
silverweed marked this conversation as resolved.

with the corresponding field, column types and bit width.

## Entries

1. Ascending values
2. All 1s in the mantissa
3. Lowest values with N bits
4. Smallest positive normal values with N bits
5. Smallest positive subnormal values with N bits
6. Maximum values with N bits
57 changes: 57 additions & 0 deletions types/fundamental/real32trunc/read.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <ROOT/REntry.hxx>
#include <ROOT/RNTupleReader.hxx>

using ROOT::Experimental::REntry;
using ROOT::Experimental::RNTupleReader;

#include <fstream>
#include <ios>
#include <ostream>
#include <string>
#include <string_view>

template <typename T>
static void PrintRealValue(const REntry &entry, std::string_view name,
std::ostream &os, bool last = false) {
T value = *entry.GetPtr<T>(name);
os << " \"" << name << "\": \"" << value << "\"";
if (!last) {
os << ",";
}
os << "\n";
}

void read(std::string_view input = "types.fundamental.real32trunc.root",
std::string_view output = "types.fundamental.real32trunc.json") {
std::ofstream os(std::string{output});
// Print floating-point numbers as hexadecimal literals.
os << std::hexfloat;
os << "[\n";

auto reader = RNTupleReader::Open("ntpl", input);
auto &entry = reader->GetModel().GetDefaultEntry();
bool first = true;
for (auto index : *reader) {
reader->LoadEntry(index);

if (first) {
first = false;
} else {
os << ",\n";
}
os << " {\n";

PrintRealValue<float>(entry, "FloatReal32Trunc10", os);
PrintRealValue<float>(entry, "FloatReal32Trunc16", os);
PrintRealValue<float>(entry, "FloatReal32Trunc31", os);
PrintRealValue<double>(entry, "DoubleReal32Trunc10", os);
PrintRealValue<double>(entry, "DoubleReal32Trunc16", os);
PrintRealValue<double>(entry, "DoubleReal32Trunc31", os, /*last=*/true);

os << " }";
// Newline is intentionally missing, may need to print a comma before the
// next entry.
}
os << "\n";
os << "]\n";
}
104 changes: 104 additions & 0 deletions types/fundamental/real32trunc/write.C
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include <ROOT/RField.hxx>
#include <ROOT/RNTupleModel.hxx>
#include <ROOT/RNTupleUtil.hxx>
#include <ROOT/RNTupleWriteOptions.hxx>
#include <ROOT/RNTupleWriter.hxx>

using ROOT::Experimental::EColumnType;
using ROOT::Experimental::RField;
using ROOT::Experimental::RNTupleModel;
using ROOT::Experimental::RNTupleWriteOptions;
using ROOT::Experimental::RNTupleWriter;

#include <limits>
#include <memory>
#include <string_view>

template <typename T>
static std::shared_ptr<T> MakeFieldReal32Trunc(RNTupleModel &model,
std::string_view name,
int nBits) {
assert(nBits >= 10 && nBits < 32);
auto field = std::make_unique<RField<T>>(name);
field->SetTruncated(nBits);
model.AddField(std::move(field));
return model.GetDefaultEntry().GetPtr<T>(name);
}

void write(std::string_view filename = "types.fundamental.real32trunc.root") {
auto model = RNTupleModel::Create();

auto FloatReal32Trunc10 =
MakeFieldReal32Trunc<float>(*model, "FloatReal32Trunc10", 10);
auto FloatReal32Trunc16 =
MakeFieldReal32Trunc<float>(*model, "FloatReal32Trunc16", 16);
auto FloatReal32Trunc31 =
MakeFieldReal32Trunc<float>(*model, "FloatReal32Trunc31", 31);
auto DoubleReal32Trunc10 =
MakeFieldReal32Trunc<double>(*model, "DoubleReal32Trunc10", 10);
auto DoubleReal32Trunc16 =
MakeFieldReal32Trunc<double>(*model, "DoubleReal32Trunc16", 16);
auto DoubleReal32Trunc31 =
MakeFieldReal32Trunc<double>(*model, "DoubleReal32Trunc31", 31);

RNTupleWriteOptions options;
options.SetCompression(0);
auto writer =
RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options);

// First entry: ascending values
*FloatReal32Trunc10 = 1.0f;
*FloatReal32Trunc16 = 2.0f;
*FloatReal32Trunc31 = 3.0f;
*DoubleReal32Trunc10 = 4.0f;
*DoubleReal32Trunc16 = 5.0f;
*DoubleReal32Trunc31 = 6.0f;
writer->Fill();

// Second entry: a value containing all 1s in the mantissa
static constexpr float Value32 = 3.9999997f;
*FloatReal32Trunc10 = Value32;
*FloatReal32Trunc16 = Value32;
*FloatReal32Trunc31 = Value32;
*DoubleReal32Trunc10 = Value32;
*DoubleReal32Trunc16 = Value32;
*DoubleReal32Trunc31 = Value32;
writer->Fill();

// Third entry: lowest values with N bits
*FloatReal32Trunc10 = -0x1.8p127f;
*FloatReal32Trunc16 = -0x1.FEp127f;
*FloatReal32Trunc31 = std::numeric_limits<float>::lowest() + 0x1p-149f;
*DoubleReal32Trunc10 = -0x1.8p127f;
*DoubleReal32Trunc16 = -0x1.FEp127;
*DoubleReal32Trunc31 = std::numeric_limits<float>::lowest() + 0x1p-149f;
writer->Fill();

// Fourth entry: min = smallest positive normal values
*FloatReal32Trunc10 = std::numeric_limits<float>::min();
*FloatReal32Trunc16 = std::numeric_limits<float>::min();
*FloatReal32Trunc31 = std::numeric_limits<float>::min();
*DoubleReal32Trunc10 = std::numeric_limits<float>::min();
*DoubleReal32Trunc16 = std::numeric_limits<float>::min();
*DoubleReal32Trunc31 = std::numeric_limits<float>::min();
writer->Fill();

// Fifth entry: smallest positive subnormal values with N bits
// (e.g. FloatReal32Trunc10 has a value with all 0s except a 1 in the 10th bit)
*FloatReal32Trunc10 = 0x1p-127f;
*FloatReal32Trunc16 = 0x1p-133f;
*FloatReal32Trunc31 = 0x1p-148f;
*DoubleReal32Trunc10 = 0x1p-127f;
*DoubleReal32Trunc16 = 0x1p-133f;
*DoubleReal32Trunc31 = 0x1p-148f;
writer->Fill();

// Sixth entry: maximum values
*FloatReal32Trunc10 = 0x1.8p127f;
*FloatReal32Trunc16 = 0x1.FEp127f;
*FloatReal32Trunc31 = std::numeric_limits<float>::max() - 0x1p-149f;
*DoubleReal32Trunc10 = 0x1.8p127f;
*DoubleReal32Trunc16 = 0x1.FEp127;
*DoubleReal32Trunc31 = std::numeric_limits<float>::max() - 0x1p-149f;
writer->Fill();
}