mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
- now distinguish between basic MPI types and user-defined types.
The new front-facing trait UPstream_basic_dataType unwinds components
and other types, but only for MPI fundamental types
(including any aliases)
- additional helper to combine a test for binary operator validity and
basic data type validity, which better expresses intent:
template<class BinaryOp, class T>
UPstream_data_opType;
- relax bit-wise operators to also accept signed integrals
and 'void' generic
270 lines
7.6 KiB
C++
270 lines
7.6 KiB
C++
/*---------------------------------------------------------------------------*\
|
|
========= |
|
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
|
\\ / O peration |
|
|
\\ / A nd | www.openfoam.com
|
|
\\/ M anipulation |
|
|
-------------------------------------------------------------------------------
|
|
Copyright (C) 2018-2025 OpenCFD Ltd.
|
|
-------------------------------------------------------------------------------
|
|
License
|
|
This file is part of OpenFOAM.
|
|
|
|
OpenFOAM is free software: you can redistribute it and/or modify it
|
|
under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
Description
|
|
Test the sizeof for basic types.
|
|
Also tests how the data mapping of OpenFOAM types to UPstream (MPI)
|
|
type ids are handled.
|
|
|
|
Can be compiled and run without any OpenFOAM libraries.
|
|
|
|
g++ -std=c++17 -oTest-machine-sizes Test-machine-sizes.cpp
|
|
|
|
\*---------------------------------------------------------------------------*/
|
|
|
|
#include <climits>
|
|
#include <cstdint>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <limits>
|
|
#include <typeinfo>
|
|
#include <type_traits>
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
// Partial copy from UPstream.H
|
|
|
|
//- Some MPI data types
|
|
//
|
|
//- Mapping of some fundamental and aggregate types to MPI data types
|
|
enum class dataTypes : int
|
|
{
|
|
// Fundamental Types [10]:
|
|
Basic_begin,
|
|
type_byte = Basic_begin,
|
|
type_int16,
|
|
type_int32,
|
|
type_int64,
|
|
type_uint16,
|
|
type_uint32,
|
|
type_uint64,
|
|
type_float,
|
|
type_double,
|
|
type_long_double,
|
|
invalid,
|
|
Basic_end = invalid
|
|
};
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
// Partial copy from UPstreamTraits.H
|
|
|
|
//- UPstream data type corresponding to an intrinsic (MPI) type
|
|
template<class T>
|
|
struct UPstream_mpi_dataType : std::false_type
|
|
{
|
|
static constexpr auto datatype_id = dataTypes::invalid;
|
|
};
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
// Specializations to match elements of UPstream::dataTypes
|
|
#undef defineUPstreamDataTraits
|
|
#define defineUPstreamDataTraits(TypeId, Type) \
|
|
template<> struct UPstream_mpi_dataType<Type> : std::true_type \
|
|
{ \
|
|
static constexpr auto datatype_id = dataTypes::TypeId; \
|
|
};
|
|
|
|
|
|
defineUPstreamDataTraits(type_byte, char);
|
|
defineUPstreamDataTraits(type_byte, unsigned char);
|
|
defineUPstreamDataTraits(type_int16, int16_t);
|
|
defineUPstreamDataTraits(type_int32, int32_t);
|
|
defineUPstreamDataTraits(type_int64, int64_t);
|
|
defineUPstreamDataTraits(type_uint16, uint16_t);
|
|
defineUPstreamDataTraits(type_uint32, uint32_t);
|
|
defineUPstreamDataTraits(type_uint64, uint64_t);
|
|
defineUPstreamDataTraits(type_float, float);
|
|
defineUPstreamDataTraits(type_double, double);
|
|
defineUPstreamDataTraits(type_long_double, long double);
|
|
|
|
#undef defineUPstreamDataTraits
|
|
|
|
|
|
//- Explicit handling of data type aliases. This is necessary since
|
|
//- different systems map things like 'unsigned long' differently but we
|
|
//- restrict ourselves to int32/int64 types
|
|
template<class T>
|
|
struct UPstream_alias_dataType
|
|
:
|
|
std::bool_constant
|
|
<
|
|
// Basic MPI type
|
|
UPstream_mpi_dataType<std::remove_cv_t<T>>::value ||
|
|
(
|
|
// Or some int 32/64 type to re-map
|
|
std::is_integral_v<T>
|
|
&& (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))
|
|
)
|
|
>
|
|
{
|
|
using base = std::conditional_t
|
|
<
|
|
UPstream_mpi_dataType<std::remove_cv_t<T>>::value,
|
|
std::remove_cv_t<T>, // <- using mpi type (no alias)
|
|
std::conditional_t // <- using alias
|
|
<
|
|
(
|
|
std::is_integral_v<T>
|
|
&& (sizeof(T) == sizeof(int32_t) || sizeof(T) == sizeof(int64_t))
|
|
),
|
|
std::conditional_t
|
|
<
|
|
(sizeof(T) == sizeof(int32_t)),
|
|
std::conditional_t<std::is_signed_v<T>, int32_t, uint32_t>,
|
|
std::conditional_t<std::is_signed_v<T>, int64_t, uint64_t>
|
|
>,
|
|
char // Fallback is a byte (eg, arbitrary contiguous data)
|
|
>
|
|
>;
|
|
|
|
static constexpr auto datatype_id =
|
|
UPstream_mpi_dataType<base>::datatype_id;
|
|
};
|
|
|
|
|
|
// Handle int8_t/uint8_t as aliases since 'signed char' etc may be
|
|
// ambiguous
|
|
|
|
//- Map \c int8_t to UPstream::dataTypes::type_byte
|
|
template<>
|
|
struct UPstream_alias_dataType<int8_t> : std::true_type
|
|
{
|
|
using base = char;
|
|
static constexpr auto datatype_id = dataTypes::type_byte;
|
|
};
|
|
|
|
//- Map \c uint8_t to UPstream::dataTypes::type_byte
|
|
template<>
|
|
struct UPstream_alias_dataType<uint8_t> : std::true_type
|
|
{
|
|
using base = unsigned char;
|
|
static constexpr auto datatype_id = dataTypes::type_byte;
|
|
};
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
|
|
template<class T>
|
|
void print(const char* name, bool showLimits = true)
|
|
{
|
|
std::cout
|
|
<< "name=\"" << name << "\" sizeof=" << sizeof(T);
|
|
|
|
if (showLimits)
|
|
{
|
|
std::cout
|
|
<< " max=<";
|
|
|
|
if constexpr (sizeof(T) == 1)
|
|
{
|
|
std::cout << int(std::numeric_limits<T>::max());
|
|
}
|
|
else
|
|
{
|
|
std::cout << std::numeric_limits<T>::max();
|
|
}
|
|
std::cout << '>';
|
|
}
|
|
|
|
// A declared or deduced MPI type, or aliased
|
|
if constexpr (UPstream_mpi_dataType<T>::value)
|
|
{
|
|
std::cout
|
|
<< " is_mpi=("
|
|
<< int(UPstream_mpi_dataType<T>::datatype_id) << ')';
|
|
}
|
|
else
|
|
{
|
|
std::cout << " is_mpi=(null)";
|
|
}
|
|
|
|
// Any aliases?
|
|
if constexpr (UPstream_alias_dataType<T>::value)
|
|
{
|
|
if constexpr (UPstream_mpi_dataType<T>::value)
|
|
{
|
|
std::cout << " alias=base";
|
|
}
|
|
else
|
|
{
|
|
std::cout
|
|
<< " alias=("
|
|
<< int(UPstream_alias_dataType<T>::datatype_id) << ')';
|
|
}
|
|
}
|
|
|
|
std::cout<< '\n';
|
|
}
|
|
|
|
|
|
|
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
// Main program:
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
std::cout<< "c++ = " << __cplusplus << '\n';
|
|
std::cout<< "machine sizes (and some MPI traits)\n---\n\n";
|
|
|
|
print<int8_t>("int8_t");
|
|
print<uint8_t>("uint8_t");
|
|
print<int16_t>("int16_t");
|
|
print<uint16_t>("uint16_t");
|
|
print<int32_t>("int32_t");
|
|
print<uint32_t>("uint32_t");
|
|
print<int64_t>("int64_t");
|
|
print<uint64_t>("uint64_t");
|
|
|
|
std::cout << '\n';
|
|
print<char>("char");
|
|
print<signed char>("signed char");
|
|
print<unsigned char>("unsigned char");
|
|
print<short>("short");
|
|
print<int>("int");
|
|
print<unsigned>("unsigned");
|
|
print<long>("long");
|
|
print<unsigned long>("unsigned long");
|
|
print<long long>("long long");
|
|
|
|
std::cout << '\n';
|
|
print<std::size_t>("std::size_t");
|
|
print<std::streamsize>("std::streamsize");
|
|
|
|
std::cout << '\n';
|
|
print<float>("float");
|
|
print<double>("double");
|
|
print<long double>("long double");
|
|
|
|
std::cout << "\n---\nEnd\n\n";
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
// ************************************************************************* //
|