Skip to content

Commit

Permalink
Merge branch 'xdmf_change_int_to_size_t' into 'master'
Browse files Browse the repository at this point in the history
Xdmf: Change index data type for topology from int to size_t

See merge request ogs/ogs!5125
  • Loading branch information
bilke committed Dec 9, 2024
2 parents 9a3b8f1 + e839e77 commit 99c196d
Show file tree
Hide file tree
Showing 61 changed files with 477 additions and 524 deletions.
42 changes: 21 additions & 21 deletions MeshLib/IO/XDMF/MeshPropertyDataType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,86 +11,86 @@
#include "MeshPropertyDataType.h"

// See https://www.xdmf.org/index.php/XDMF_Model_and_Format#Topology (Arbitrary)
std::string ParentDataType2String(ParentDataType p)
std::pair<std::string, std::size_t> ParentDataType2String(ParentDataType p)
{
// not used in OGS ParentDataType::POLYGON, ParentDataType::POLYHEDRON,
// ParentDataType::HEXAHEDRON_24
if (p == ParentDataType::MIXED)
{
return "Mixed";
return {"Mixed", 1};
}

if (p == ParentDataType::POLYVERTEX)
{
return "Polyvertex";
return {"Polyvertex", 1};
}
if (p == ParentDataType::POLYLINE)
{
return "Polyline";
return {"Polyline", 2};
}
if (p == ParentDataType::TRIANGLE)
{
return "Triangle";
return {"Triangle", 3};
}
if (p == ParentDataType::QUADRILATERAL)
{
return "Quadrilateral";
return {"Quadrilateral", 4};
}
if (p == ParentDataType::TETRAHEDRON)
{
return "Tetrahedron";
return {"Tetrahedron", 4};
}
if (p == ParentDataType::PYRAMID)
{
return "Pyramid";
return {"Pyramid", 5};
}
if (p == ParentDataType::WEDGE)
{
return "Wedge";
return {"Wedge", 6};
}
if (p == ParentDataType::HEXAHEDRON)
{
return "Hexahedron";
return {"Hexahedron", 8};
}
if (p == ParentDataType::EDGE_3)
{
return "Edge_3";
return {"Edge_3", 3};
}
if (p == ParentDataType::QUADRILATERAL_9)
{
return "Quadrilateral_9";
return {"Quadrilateral_9", 9};
}
if (p == ParentDataType::TRIANGLE_6)
{
return "Triangle_6";
return {"Triangle_6", 6};
}
if (p == ParentDataType::QUADRILATERAL_8)
{
return "Quadrilateral_8";
return {"Quadrilateral_8", 8};
}
if (p == ParentDataType::TETRAHEDRON_10)
{
return "Tetrahedron_10";
return {"Tetrahedron_10", 10};
}
if (p == ParentDataType::PYRAMID_13)
{
return "Pyramid_13";
return {"Pyramid_13", 13};
}
if (p == ParentDataType::WEDGE_15)
{
return "Wedge_15";
return {"Wedge_15", 15};
}
if (p == ParentDataType::WEDGE_18)
{
return "Wedge_18";
return {"Wedge_18", 18};
}
if (p == ParentDataType::HEXAHEDRON_20)
{
return "Hexahedron_20";
return {"Hexahedron_20", 20};
}
if (p == ParentDataType::HEXAHEDRON_27)
{
return "Hexahedron_27";
return {"Hexahedron_27", 27};
}
return "Mixed";
return {"Mixed", 1};
}
4 changes: 2 additions & 2 deletions MeshLib/IO/XDMF/MeshPropertyDataType.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ enum class ParentDataType
{
MIXED = 0,
POLYVERTEX = 1,
POLYLINE = 2,
POLYLINE = 2, // OGS polylines are supposed to contain exactly 2 nodes
// POLYGON = 3, // not used in OGS
TRIANGLE = 4,
QUADRILATERAL = 5,
Expand All @@ -60,4 +60,4 @@ enum class ParentDataType
HEXAHEDRON_27 = 50
};

std::string ParentDataType2String(ParentDataType p);
std::pair<std::string, std::size_t> ParentDataType2String(ParentDataType p);
2 changes: 1 addition & 1 deletion MeshLib/IO/XDMF/XdmfData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ XdmfData::XdmfData(std::size_t const size_partitioned_dim,
}
}()),
data_type(mesh_property_data_type),
size_partitioned_dim(size_partitioned_dim),
name(name),
attribute_center(attribute_center),
index(index),
parent_data_type(parent_data_type)
{
auto partition_info = getPartitionInfo(size_partitioned_dim, n_files);
// TODO (tm) XdmfLib does not support 64 bit data types so far
assert(partition_info.local_length <
std::numeric_limits<unsigned int>::max());
auto const ui_global_components =
Expand Down
1 change: 1 addition & 0 deletions MeshLib/IO/XDMF/XdmfData.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct XdmfData final
std::vector<XdmfDimType> strides;
std::vector<XdmfDimType> global_block_dims;
MeshPropertyDataType data_type;
std::size_t size_partitioned_dim;
std::string name;
std::optional<MeshLib::MeshItemType> attribute_center;
unsigned int index;
Expand Down
2 changes: 1 addition & 1 deletion MeshLib/IO/XDMF/XdmfHdfWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace MeshLib::IO
struct TransformedMeshData final
{
std::vector<double> flattened_geometry_values;
std::vector<int> flattened_topology_values;
std::vector<std::size_t> flattened_topology_values;
ParentDataType parent_data_type;
};
struct XdmfHdfMesh final
Expand Down
108 changes: 67 additions & 41 deletions MeshLib/IO/XDMF/transformData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
* http://www.opengeosys.org/project/license
*/

// \TODO (tm) Extend xdmf lib with 64bit data types

#include "transformData.h"

#include <algorithm>
Expand Down Expand Up @@ -97,7 +95,7 @@ std::optional<XdmfHdfData> transformAttribute(
std::size_t num_of_tuples = 0;
void const* data_ptr = 0;

// lambda f : Collects properties from the propertyVectorBase. It captures
// lambda f : Collects properties from the PropertyVectorBase. It captures
// (and overwrites) data that can only be collected via the typed property.
// It has boolean return type to allow kind of pipe using || operator.
auto f = [&data_type, &num_of_tuples, &data_ptr,
Expand Down Expand Up @@ -133,39 +131,30 @@ std::optional<XdmfHdfData> transformAttribute(
"Float has 23 bits fractional part");
data_type = MeshPropertyDataType::float32;
}
else if constexpr (std::is_same_v<int, decltype(basic_type)>)
else if constexpr (std::is_same_v<int32_t, decltype(basic_type)>)
{
static_assert((std::numeric_limits<int>::digits == 31),
"Signed int has 32-1 bits");
data_type = MeshPropertyDataType::int32;
}
// ToDo (tm) These tests are platform specific and currently fail on
// Windows else if constexpr (std::is_same_v<long,
// decltype(basic_type)>)
//{
// static_assert((std::numeric_limits<long>::digits == 63),
// "Signed int has 64-1 bits");
// data_type = MeshPropertyDataType::int64;
//}
// else if constexpr (std::is_same_v<unsigned long,
// decltype(basic_type)>)
//{
// static_assert((std::numeric_limits<unsigned long>::digits == 64),
// "Unsigned long has 64 bits");
// data_type = MeshPropertyDataType::uint64;
//}
else if constexpr (std::is_same_v<unsigned int, decltype(basic_type)>)
else if constexpr (std::is_same_v<uint32_t, decltype(basic_type)>)
{
static_assert((std::numeric_limits<unsigned int>::digits == 32),
"Unsigned int has 32 bits");
data_type = MeshPropertyDataType::uint32;
}
else if constexpr (std::is_same_v<std::size_t, decltype(basic_type)>)
else if constexpr (std::is_same_v<int64_t, decltype(basic_type)>)
{
data_type = MeshPropertyDataType::int64;
}
else if constexpr (std::is_same_v<uint64_t, decltype(basic_type)>)
{
static_assert((std::numeric_limits<std::size_t>::digits == 64),
"size_t has 64 bits");
data_type = MeshPropertyDataType::uint64;
}
else if constexpr (std::is_same_v<int8_t, decltype(basic_type)>)
{
data_type = MeshPropertyDataType::int8;
}
else if constexpr (std::is_same_v<uint8_t, decltype(basic_type)>)
{
data_type = MeshPropertyDataType::uint8;
}
else if constexpr (std::is_same_v<char, decltype(basic_type)>)
{
data_type = MeshPropertyDataType::char_native;
Expand All @@ -176,6 +165,40 @@ std::optional<XdmfHdfData> transformAttribute(
"Unsigned char has 8 bits");
data_type = MeshPropertyDataType::uchar;
}
else if constexpr (std::is_same_v<unsigned long, decltype(basic_type)>)
{
if (sizeof(unsigned long) == 8 &&
std::numeric_limits<unsigned long>::digits == 64)
{
data_type = MeshPropertyDataType::uint64;
}
else if (sizeof(unsigned long) == 4 &&
std::numeric_limits<unsigned long>::digits == 32)
{
data_type = MeshPropertyDataType::uint32;
}
else
{
return false;
}
}
else if constexpr (std::is_same_v<std::size_t, decltype(basic_type)>)
{
if (sizeof(std::size_t) == 8 &&
std::numeric_limits<std::size_t>::digits == 64)
{
data_type = MeshPropertyDataType::uint64;
}
else if (sizeof(std::size_t) == 4 &&
std::numeric_limits<std::size_t>::digits == 32)
{
data_type = MeshPropertyDataType::uint32;
}
else
{
return false;
}
}
else
{
return false;
Expand Down Expand Up @@ -316,18 +339,18 @@ ParentDataType getTopologyType(MeshLib::Mesh const& mesh)
return cellTypeOGS2XDMF(ogs_cell_type).id;
}

std::pair<std::vector<int>, ParentDataType> transformToXDMFTopology(
std::pair<std::vector<std::size_t>, ParentDataType> transformToXDMFTopology(
MeshLib::Mesh const& mesh, std::size_t const offset)
{
std::vector<MeshLib::Element*> const& elements = mesh.getElements();
std::vector<int> values;
std::vector<std::size_t> values;

auto const push_cellnode_ids_to_vector =
[&values, &offset](auto const& cell)
{
values |= ranges::actions::push_back(
cell->nodes() | MeshLib::views::ids |
ranges::views::transform([&offset](auto const node_id) -> int
ranges::views::transform([&offset](auto const node_id)
{ return node_id + offset; }));
};

Expand All @@ -344,14 +367,12 @@ std::pair<std::vector<int>, ParentDataType> transformToXDMFTopology(
push_cellnode_ids_to_vector(cell);
}
}
else if (topology_type == ParentDataType::POLYVERTEX ||
topology_type == ParentDataType::POLYLINE)
else if (topology_type == ParentDataType::POLYLINE)
{
// '+ 1' for number of nodes of the cell
values.reserve(elements.size() * (elements[0]->getNumberOfNodes() + 1));
values.reserve(elements.size() * elements[0]->getNumberOfNodes());
for (auto const& cell : elements)
{
values.push_back(cell->getNumberOfNodes());
push_cellnode_ids_to_vector(cell);
}
}
Expand All @@ -367,18 +388,23 @@ std::pair<std::vector<int>, ParentDataType> transformToXDMFTopology(
return {values, topology_type};
}

XdmfHdfData transformTopology(std::vector<int> const& values,
XdmfHdfData transformTopology(std::vector<std::size_t> const& values,
ParentDataType const parent_data_type,
unsigned int const n_files,
unsigned int const chunk_size_bytes)
{
std::string const name = "topology";
HdfData const hdf = {
values.data(), values.size(), 1, name, MeshPropertyDataType::int32,
n_files, chunk_size_bytes};
XdmfData const xdmf{values.size(),
1,
MeshPropertyDataType::int32,
auto const tuple_size = ParentDataType2String(parent_data_type).second;
HdfData const hdf = {values.data(),
values.size() / tuple_size,
tuple_size,
name,
MeshPropertyDataType::uint64,
n_files,
chunk_size_bytes};
XdmfData const xdmf{values.size() / tuple_size,
tuple_size,
MeshPropertyDataType::uint64,
name,
std::nullopt,
3,
Expand Down
4 changes: 2 additions & 2 deletions MeshLib/IO/XDMF/transformData.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ XdmfHdfData transformGeometry(MeshLib::Mesh const& mesh, double const* data_ptr,
* Data will be split into chunks. The parameter specifies the size (in bytes)
* of the largest chunk. \return Topology meta data
*/
XdmfHdfData transformTopology(std::vector<int> const& values,
XdmfHdfData transformTopology(std::vector<std::size_t> const& values,
ParentDataType const parent_data_type,
unsigned int n_files,
unsigned int chunk_size_bytes);
Expand All @@ -79,6 +79,6 @@ std::vector<double> transformToXDMFGeometry(MeshLib::Mesh const& mesh);
* be zero in serial and must be defined for each process in parallel execution.
* \return vector containing a copy of the data and the computed ParentDataType
*/
std::pair<std::vector<int>, ParentDataType> transformToXDMFTopology(
std::pair<std::vector<std::size_t>, ParentDataType> transformToXDMFTopology(
MeshLib::Mesh const& mesh, std::size_t const offset);
} // namespace MeshLib::IO
20 changes: 9 additions & 11 deletions MeshLib/IO/XDMF/writeXdmf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,15 +203,15 @@ std::function<std::string(std::vector<double>)> write_xdmf(
auto const& dataitem_transform)
{
return fmt::format(
fmt::runtime("\n\t<Topology Dimensions=\"{dimensions}\" "
"Type=\"{topology_type}\" "
"NodesPerElement=\"{nodes_per_element}\">{dataitem}"
fmt::runtime("\n\t<Topology Type=\"{topology_type}\" "
"NodesPerElement=\"{nodes_per_element}\" "
"NumberOfElements=\"{number_of_elements}\">{dataitem}"
"\n\t</Topology>"),
"topology_type"_a =
ParentDataType2String(*topology.parent_data_type),
ParentDataType2String(*topology.parent_data_type).first,
"dataitem"_a = dataitem_transform(topology),
"dimensions"_a = fmt::join(topology.global_block_dims, " "),
"nodes_per_element"_a = nodes_per_element);
"nodes_per_element"_a = nodes_per_element,
"number_of_elements"_a = topology.size_partitioned_dim);
};

// Define content of <Topology> in XDMF, same as attribute_transform
Expand Down Expand Up @@ -243,13 +243,11 @@ std::function<std::string(std::vector<double>)> write_xdmf(
case ParentDataType::PYRAMID_13:
return fmt::format(
fmt::runtime(
"\n\t<Topology Dimensions=\"{dimensions}\" "
"\n\t<Topology "
"Type=\"{topology_type}\">{dataitem}\n\t</Topology>"),
"topology_type"_a =
ParentDataType2String(*topology.parent_data_type),
"dataitem"_a = dataitem_transform(topology),
"dimensions"_a =
fmt::join(topology.global_block_dims, " "));
ParentDataType2String(*topology.parent_data_type).first,
"dataitem"_a = dataitem_transform(topology));
}
OGS_FATAL("Could not transform unknown XDMF topology type");
return std::string{};
Expand Down
Loading

0 comments on commit 99c196d

Please sign in to comment.