Commit ef9bb4ae authored by Mark Olesen's avatar Mark Olesen Committed by Andrew Heather
Browse files

ENH: add low-level readRawLabels, readRawScalars (#1378)

- these use the additional byte-size checks in IOstream to handle
  native vs non-native sizes
parent b0ffdbcf
......@@ -30,6 +30,7 @@ Description
#include "int.H"
#include "uint.H"
#include "string.H"
#include "scalar.H"
#include "IOstreams.H"
using namespace Foam;
......@@ -40,32 +41,54 @@ using namespace Foam;
int main(int argc, char *argv[])
{
//NONE Info<<"int16:" << pTraits<int16_t>::max << nl;
Info<<"=max=" << nl;
Info<<"uint8:" << std::numeric_limits<uint8_t>::max() << nl;
Info<<"int16:" << std::numeric_limits<int16_t>::max() << nl;
Info<<"int32:" << pTraits<int32_t>::max << nl;
Info<<"uint32:" << pTraits<uint32_t>::max << nl;
Info<<"int64:" << pTraits<int64_t>::max << nl;
Info<<"uint64:" << pTraits<uint64_t>::max << nl;
Info<< "=max=" << nl;
Info<< "uint8:" << std::numeric_limits<uint8_t>::max() << nl;
Info<< "int16:" << std::numeric_limits<int16_t>::max() << nl;
Info<< "int32:" << pTraits<int32_t>::max << nl;
Info<< "uint32:" << pTraits<uint32_t>::max << nl;
Info<< "int64:" << pTraits<int64_t>::max << nl;
Info<< "uint64:" << pTraits<uint64_t>::max << nl;
Info<< nl;
cout<<"int16:" << std::numeric_limits<int16_t>::max() << nl;
cout<<"int32:" << pTraits<int32_t>::max << nl;
cout<<"uint32:" << pTraits<uint32_t>::max << nl;
cout<<"int64:" << pTraits<int64_t>::max << nl;
cout<<"uint64:" << pTraits<uint64_t>::max << nl;
cout<< "int16:" << std::numeric_limits<int16_t>::max() << nl;
cout<< "int32:" << pTraits<int32_t>::max << nl;
cout<< "uint32:" << pTraits<uint32_t>::max << nl;
cout<< "int64:" << pTraits<int64_t>::max << nl;
cout<< "uint64:" << pTraits<uint64_t>::max << nl;
Info<< nl << "=digits=" << nl;
cout<<"int16:" << std::numeric_limits<int16_t>::digits << nl;
cout<<"int32:" << std::numeric_limits<int32_t>::digits << nl;
cout<<"uint32:" << std::numeric_limits<uint32_t>::digits << nl;
cout<<"int64:" << std::numeric_limits<int64_t>::digits << nl;
cout<<"uint64:" << std::numeric_limits<uint64_t>::digits << nl;
cout<<"float:" << std::numeric_limits<float>::digits << nl;
cout<<"double:" << std::numeric_limits<double>::digits << nl;
cout<<"long double:" << std::numeric_limits<long double>::digits << nl;
cout<< "int16:" << std::numeric_limits<int16_t>::digits << nl;
cout<< "int32:" << std::numeric_limits<int32_t>::digits << nl;
cout<< "uint32:" << std::numeric_limits<uint32_t>::digits << nl;
cout<< "int64:" << std::numeric_limits<int64_t>::digits << nl;
cout<< "uint64:" << std::numeric_limits<uint64_t>::digits << nl;
cout<< "float:" << std::numeric_limits<float>::digits << nl;
cout<< "double:" << std::numeric_limits<double>::digits << nl;
cout<< "long double:" << std::numeric_limits<long double>::digits << nl;
Info<< nl << "=float=" << nl;
cout<< "max:" << std::numeric_limits<float>::max()
<< " VGREAT:" << floatScalarVGREAT << nl;
cout<< "min:" << std::numeric_limits<float>::min()
<< " VSMALL:" << floatScalarVSMALL << nl;
cout<< "epsilon:" << std::numeric_limits<float>::epsilon()
<< " SMALL:" << floatScalarSMALL << nl;
cout<< "1/epsilon:" << 1.0f/std::numeric_limits<float>::epsilon()
<< " GREAT:" << floatScalarGREAT << nl;
Info<< nl << "=double=" << nl;
cout<< "max:" << std::numeric_limits<double>::max()
<< " VGREAT:" << doubleScalarVGREAT << nl;
cout<< "min:" << std::numeric_limits<double>::min()
<< " VSMALL:" << doubleScalarVSMALL << nl;
cout<< "epsilon:" << std::numeric_limits<double>::epsilon()
<< " SMALL:" << doubleScalarSMALL << nl;
cout<< "1/epsilon:" << 1.0f/std::numeric_limits<double>::epsilon()
<< " GREAT:" << doubleScalarGREAT << nl;
Info << "---\nEnd\n" << endl;
......
......@@ -30,7 +30,8 @@ Description
\*---------------------------------------------------------------------------*/
#include "scalar.H"
#include "label.H"
#include "FlatOutput.H"
#include "ListStream.H"
#include "StringStream.H"
#include "NASCore.H"
#include "parsing.H"
......@@ -67,6 +68,19 @@ void printInfo(const Switch& sw)
}
Ostream& toString(Ostream& os, const UList<char>& list)
{
os << '"';
for (const char c : list)
{
os << c;
}
os << '"';
return os;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class T>
......@@ -280,6 +294,59 @@ int main(int argc, char *argv[])
);
}
if (true)
{
#ifdef WM_DP
typedef float otherType;
#else
typedef double otherType;
#endif
Info<< nl << "Test raw binary read of scalar list:"
<< " write " << sizeof(otherType)
<< " read " << sizeof(scalar) << nl;
List<otherType> srcList(15);
forAll(srcList, i)
{
srcList[i] = 1 + 10*i;
}
DynamicList<char> buf;
OListStream os(std::move(buf), IOstream::BINARY);
os << srcList;
os.swap(buf); // Recover buffer
// Read back
List<scalar> dstList;
UIListStream is(buf, IOstream::BINARY);
is.setScalarByteSize(sizeof(otherType));
Info<< "Stream scalar-size ("
<< is.scalarByteSize() << ") is native: "
<< Switch(is.checkScalarSize<otherType>()) << nl;
token firstToken(is);
Info<< "List has " << firstToken.info() << " scalar items" << nl;
dstList.resize(firstToken.labelToken(), 3.14159);
is.beginRawRead();
// for (scalar& val : dstList)
// {
// val = readRawScalar(is);
// }
readRawScalars(is, dstList.data(), dstList.size());
is.endRawRead();
Info<< "Wrote " << flatOutput(srcList) << nl
<< "Read " << flatOutput(dstList) << nl;
}
if (nFail)
{
Info<< nl << "failed " << nFail << " tests" << nl;
......
......@@ -249,7 +249,7 @@ public:
}
// Stream State Functions
// Element sizes (precision)
//- The label byte-size associated with the stream
unsigned labelByteSize() const
......@@ -275,6 +275,28 @@ public:
scalarByteSize_ = nbytes;
}
//- Check if the label byte-size associated with the stream
//- is the same as the given type
template<class T = label>
typename std::enable_if<std::is_integral<T>::value, bool>::type
checkLabelSize() const
{
return labelByteSize_ == sizeof(T);
}
//- Check if the scalar byte-size associated with the stream
//- is the same as the given type
template<class T = scalar>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
checkScalarSize() const
{
return scalarByteSize_ == sizeof(T);
}
// Stream State Functions
//- Const access to the current stream line number
label lineNumber() const
{
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2016-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -123,7 +123,7 @@ bool ScalarRead(const char* buf, Scalar& val)
Scalar ScalarRead(Istream& is)
{
Scalar val;
Scalar val(0);
is >> val;
return val;
......
......@@ -51,8 +51,7 @@ namespace Foam
typedef double doubleScalar;
// Largest and smallest scalar values allowed in certain parts of the code.
// (15 is the number of significant figures in an
// IEEE double precision number. See limits.h or float.h)
// See std::numeric_limits max(), min(), epsilon()
constexpr doubleScalar doubleScalarGREAT = 1.0e+15;
constexpr doubleScalar doubleScalarVGREAT = 1.0e+300;
constexpr doubleScalar doubleScalarROOTVGREAT = 1.0e+150;
......
......@@ -51,8 +51,7 @@ namespace Foam
typedef float floatScalar;
// Largest and smallest scalar values allowed in certain parts of the code.
// (6 is the number of significant figures in an
// IEEE single precision number. See limits.h or float.h)
// See std::numeric_limits max(), min(), epsilon()
constexpr floatScalar floatScalarGREAT = 1.0e+6;
constexpr floatScalar floatScalarVGREAT = 1.0e+37;
constexpr floatScalar floatScalarROOTVGREAT = 1.0e+18;
......
......@@ -2,10 +2,8 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2004-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
......@@ -32,11 +30,93 @@ License
Foam::scalar Foam::readScalar(Istream& is)
{
scalar val;
scalar val(0);
is >> val;
return val;
}
Foam::scalar Foam::readRawScalar(Istream& is)
{
scalar val(0);
readRawScalars(is, &val, 1);
return val;
}
void Foam::readRawScalars(Istream& is, scalar* data, size_t nElem)
{
// No check for binary vs ascii, the caller knows what they are doing
#if defined(WM_SP) || defined(WM_SPDP)
// Defined scalar as a float, non-native type is double
// Handle type narrowing limits
typedef double nonNative;
if (is.checkScalarSize<nonNative>())
{
nonNative other;
for (const scalar* endData = data + nElem; data != endData; ++data)
{
is.readRaw(reinterpret_cast<char*>(&other), sizeof(nonNative));
// Type narrowing
// Overflow: silently fix, or raise error?
if (other < -VGREAT)
{
*data = -VGREAT;
}
else if (other > VGREAT)
{
*data = VGREAT;
}
else if (other > -VSMALL && other < VSMALL)
{
// Underflow: round to zero
*data = 0;
}
else
{
*data = scalar(other);
}
}
}
else
{
// Read with native size
is.readRaw(reinterpret_cast<char*>(data), nElem*sizeof(scalar));
}
#elif defined(WM_DP)
// Defined scalar as a double, non-native type is float
typedef float nonNative;
if (is.checkScalarSize<nonNative>())
{
nonNative other;
for (const scalar* endData = data + nElem; data != endData; ++data)
{
is.readRaw(reinterpret_cast<char*>(&other), sizeof(nonNative));
*data = scalar(other);
}
}
else
{
// Read with native size
is.readRaw(reinterpret_cast<char*>(data), nElem*sizeof(scalar));
}
#endif
}
// ************************************************************************* //
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2017 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2017-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2016 OpenFOAM Foundation
......@@ -64,8 +64,6 @@ namespace Foam
constexpr scalar VSMALL = floatScalarVSMALL;
constexpr scalar ROOTVSMALL = floatScalarROOTVSMALL;
scalar readScalar(Istream& is);
inline scalar readScalar(const char* buf)
{
return readFloat(buf);
......@@ -85,6 +83,19 @@ namespace Foam
{
return readFloat(str, val);
}
//- Read scalar from stream.
scalar readScalar(Istream& is);
//- Read raw scalar from binary stream.
// \note No internal check for binary vs ascii,
// the caller knows what they are doing
scalar readRawScalar(Istream& is);
//- Read raw scalars from binary stream.
// \note No internal check for binary vs ascii,
// the caller knows what they are doing
void readRawScalars(Istream& is, scalar* data, size_t nElem);
}
#elif defined(WM_DP)
......@@ -104,8 +115,6 @@ namespace Foam
constexpr scalar VSMALL = doubleScalarVSMALL;
constexpr scalar ROOTVSMALL = doubleScalarROOTVSMALL;
scalar readScalar(Istream& is);
inline scalar readScalar(const char* buf)
{
return readDouble(buf);
......@@ -125,6 +134,20 @@ namespace Foam
{
return readDouble(str, val);
}
//- Read scalar from stream.
scalar readScalar(Istream& is);
//- Read raw scalar from binary stream.
// \note No internal check for binary vs ascii,
// the caller knows what they are doing
scalar readRawScalar(Istream& is);
//- Read raw scalars from binary stream.
// \note No internal check for binary vs ascii,
// the caller knows what they are doing
void readRawScalars(Istream& is, scalar* data, size_t nElem);
}
#endif
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd |
\\ / A nd | Copyright (C) 2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2015 OpenFOAM Foundation
......@@ -27,18 +27,97 @@ License
#include "error.H"
#include "label.H"
#include "Istream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
#if WM_LABEL_SIZE == 32
const char* const Foam::pTraits<int64_t>::typeName = "int64";
const char* const Foam::pTraits<int32_t>::typeName = "label";
const char* const Foam::pTraits<int64_t>::typeName = "int64";
#elif WM_LABEL_SIZE == 64
const char* const Foam::pTraits<int64_t>::typeName = "label";
const char* const Foam::pTraits<int32_t>::typeName = "int32";
const char* const Foam::pTraits<int64_t>::typeName = "label";
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::label Foam::readRawLabel(Istream& is)
{
label val(0);
readRawLabels(is, &val, 1);
return val;
}
void Foam::readRawLabels(Istream& is, label* data, size_t nElem)
{
// No check for binary vs ascii, the caller knows what they are doing
#if WM_LABEL_SIZE == 32
// Defined label as int32, non-native type is int64
// Handle type narrowing limits
typedef int64_t nonNative;
if (is.checkLabelSize<nonNative>())
{
nonNative parsed;
for (const label* endData = data + nElem; data != endData; ++data)
{
is.readRaw(reinterpret_cast<char*>(&parsed), sizeof(nonNative));
// Type narrowing
// Overflow: silently fix, or raise error?
if (parsed < labelMin)
{
*data = labelMin;
}
else if (parsed > labelMax)
{
*data = labelMax;
}
else
{
*data = label(parsed);
}
}
}
else
{
// Read with native size
is.readRaw(reinterpret_cast<char*>(data), nElem*sizeof(label));
}
#elif WM_LABEL_SIZE == 64
// Defined label as int64, non-native type is int32
typedef int32_t nonNative;
if (is.checkLabelSize<nonNative>())
{
nonNative parsed;
for (const label* endData = data + nElem; data != endData; ++data)
{
is.readRaw(reinterpret_cast<char*>(&parsed), sizeof(nonNative));
*data = label(parsed);
}
}
else
{
// Read with native size
is.readRaw(reinterpret_cast<char*>(data), nElem*sizeof(label));
}
#endif
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::label Foam::pow(label a, label b)
......
......@@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2018 OpenCFD Ltd.
\\ / A nd | Copyright (C) 2018-2019 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
| Copyright (C) 2011-2014 OpenFOAM Foundation
......@@ -63,13 +63,6 @@ typedef INT_SIZE(int, _t) label;
constexpr label labelMin = INT_SIZE(INT, _MIN);
constexpr label labelMax = INT_SIZE(INT, _MAX);
//- Read label from stream.
// Uses readInt32 or readInt64 according to WM_LABEL_SIZE
inline label readLabel(Istream& is)
{
return INT_SIZE(readInt,) (is);
}
//- Parse entire buffer as a label, skipping leading/trailing whitespace.
// Uses readInt32 or readInt64 according to WM_LABEL_SIZE
// \return Parsed value or FatalIOError on any problem
......@@ -103,6 +96,24 @@ inline bool readLabel(const std::string& str, label& val)
}
//- Read label from stream.
// Uses readInt32 or readInt64 according to WM_LABEL_SIZE
inline label readLabel(Istream& is)
{
return INT_SIZE(readInt,) (is);
}
//- Read raw label from binary stream.
// \note No internal check for binary vs ascii,
// the caller knows what they are doing
label readRawLabel(Istream& is);
//- Read raw labels from binary stream.
// \note No internal check for binary vs ascii,
// the caller knows what they are doing
void readRawLabels(Istream& is, label* data, size_t nElem);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
//- Raise one label to the power of another
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment