Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catalyst: Add support for Exodus IOSS Properties in Conduit Representation #458

Merged
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
104 changes: 103 additions & 1 deletion packages/seacas/libraries/ioss/src/catalyst/Iocatalyst_DatabaseIO.C
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,104 @@ namespace Iocatalyst {
return true;
}

std::vector<std::string> getScalarNamesFromNonScalarField(const Ioss::Field &field) const
{
int ncomp = field.get_component_count(Ioss::Field::InOut::INPUT);
std::vector<std::string> fnames;
for(int i=1; i<=ncomp; i++){
fnames.push_back(field.get_component_name(i, Ioss::Field::InOut::INPUT));
}
return fnames;
}

template <typename T>
std::vector<T> getInterweavedScalarDataFromConduitNode(const std::vector<std::string> fnames, conduit_cpp::Node &node) const
{
int ncomp = fnames.size();
auto &&t_node = node[fnames[0] + detail::FS + detail::VALUE];
int num_get = t_node.number_of_elements();
std::vector<T> vals(ncomp*num_get);

for(int i=0; i<num_get; i++) {
for(int j=0; j<ncomp; j++){
std::string path_to_value = fnames[j] + detail::FS + detail::VALUE;
auto &&child_value = node[path_to_value];
vals[i*ncomp + j] =
reinterpret_cast<const T *>(child_value.element_ptr(0))[i];
}
}
return vals;
}

template <typename T>
void addFieldNodeAndDataToConduitNode(const Ioss::Field &field, void *data, conduit_cpp::Node &node) const
{
int ncomp = field.get_component_count(Ioss::Field::InOut::INPUT);
int num_get = field.raw_count();
node[field.get_name()] = conduit_cpp::Node();
auto &&f_node = node[field.get_name()];
f_node[detail::ROLE].set(static_cast<std::int8_t>(field.get_role()));
f_node[detail::TYPE].set(static_cast<std::int8_t>(field.get_type()));
f_node[detail::COUNT].set(static_cast<std::int64_t>(field.raw_count()));
f_node[detail::INDEX].set(static_cast<std::int64_t>(field.get_index()));
f_node[detail::COMPONENTCOUNT].set(static_cast<std::int64_t>(ncomp));
f_node[detail::STORAGE].set(field.raw_storage()->name());
f_node[detail::VALUE].set(static_cast< T *>(data), ncomp * num_get);
}

void combineScalarFieldsInConduitNodeToNonScalarField(
const Ioss::Field &field, conduit_cpp::Node &node) const
{
std::vector<std::string> fnames =
this->getScalarNamesFromNonScalarField(field);

switch (field.get_type()) {
case Ioss::Field::BasicType::DOUBLE:
this->addFieldNodeAndDataToConduitNode<double>(
field,
this->getInterweavedScalarDataFromConduitNode<double>(fnames, node).data(),
node
);
break;

case Ioss::Field::BasicType::INT32:
this->addFieldNodeAndDataToConduitNode<std::int32_t>(
field,
this->getInterweavedScalarDataFromConduitNode<std::int32_t>(fnames, node).data(),
node
);
break;

case Ioss::Field::BasicType::INT64:
this->addFieldNodeAndDataToConduitNode<std::int64_t>(
field,
this->getInterweavedScalarDataFromConduitNode<std::int64_t>(fnames, node).data(),
node
);
break;

case Ioss::Field::BasicType::CHARACTER:
this->addFieldNodeAndDataToConduitNode<std::int8_t>(
field,
this->getInterweavedScalarDataFromConduitNode<char>(fnames, node).data(),
node
);
break;
default:
std::ostringstream errmsg;
fmt::print(errmsg, "ERROR in {} on read: {}, unsupported field type: {}\n", __func__,
field.get_name(), field.type_string());
IOSS_ERROR(errmsg);
}

//Remove Related Scalars from Conduit Node
for(int i=0; i<fnames.size(); i++) {
node.remove(fnames[i]);
}
}

template <typename GroupingEntityT>
bool readFields(const conduit_cpp::Node &&parent, GroupingEntityT *block) const
bool readFields(conduit_cpp::Node &&parent, GroupingEntityT *block) const
{
// Assumption: count = entity_count (in block)
Ioss::DatabaseIO *dbase = block->get_database();
Expand Down Expand Up @@ -878,6 +974,12 @@ namespace Iocatalyst {
for (const auto &field : fields) {
block->field_add(field.set_zero_copy_enabled());
}

for (const auto &field : fields) {
if(field.raw_storage()->name() != IOSS_SCALAR()) {
this->combineScalarFieldsInConduitNodeToNonScalarField(field, parent);
}
}
}

return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ namespace Iocatalyst {
values.push_back(itr->second + j*0.1);
}
elemBlock->put_field_data(itr->first, values);
values.clear();
}
}

Expand All @@ -449,6 +450,7 @@ namespace Iocatalyst {
values.push_back(itr->second + j*0.1);
}
nodeBlock->put_field_data(itr->first, values);
values.clear();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class IOCATALYST_EXPORT Iocatalyst_DatabaseIOTest : public ::testing::Test
void *data;
size_t dataSize;
g->get_field_data(name, &data, &dataSize);
ASSERT_GT(dataSize, 0) << "DataSize is not greater than 0 for field "<<name<<std::endl;
std::byte *b = static_cast<std::byte *>(data);
std::vector<std::byte> zcBuffer(b, b + field.get_size());
EXPECT_EQ(dcBuffer, zcBuffer);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,18 @@
//
// See packages/seacas/LICENSE for details

#include <catalyst_tests/Iocatalyst_DatabaseIOTest.h>
#include <Ioss_Compare.h>
#include <Ioss_CopyDatabase.h>
#include <Ioss_DatabaseIO.h>
#include <Ioss_ElementBlock.h>
#include <Ioss_IOFactory.h>
#include <Ioss_MeshCopyOptions.h>
#include <Ioss_NodeBlock.h>
#include <Ioss_StructuredBlock.h>
#include <catalyst/Iocatalyst_DatabaseIO.h>
#include <catalyst_tests/Iocatalyst_DatabaseIOTest.h>
#include <catalyst/Iocatalyst_CatalystManager.h>

#include <Ioss_ElementBlock.h>


TEST_F(Iocatalyst_DatabaseIOTest, WriteThreeElementBlocksWith24Cells)
Expand Down Expand Up @@ -92,13 +100,26 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_ENABLE_FIELD_RECOGNITION_ON)
auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));
auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));

checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks());

bool exo_foo_exists = exo_elemBlock->field_exists("foo");
bool cat_foo_exists = cat_elemBlock->field_exists("foo");
EXPECT_TRUE(exo_foo_exists);
EXPECT_TRUE(cat_foo_exists);
if(exo_foo_exists && cat_foo_exists)
EXPECT_TRUE(exo_elemBlock->get_field("foo") == cat_elemBlock->get_field("foo"));

//Check field data for equality
auto cat_field = cat_elemBlock->get_fieldref("foo");
std::vector<std::byte> dcBuffer(cat_field.get_size());
cat_elemBlock->get_field_data("foo", Data(dcBuffer), dcBuffer.size());

exo_reg.begin_state(1);
auto exo_field = exo_elemBlock->get_fieldref("foo");
std::vector<std::byte> deBuffer(exo_field.get_size());
exo_elemBlock->get_field_data("foo", Data(deBuffer), deBuffer.size());
EXPECT_EQ(dcBuffer, deBuffer);

//Check foo_x doesn't exist
bool exo_foo_x_exists = exo_elemBlock->field_exists("foo_x");
bool cat_foo_x_exists = cat_elemBlock->field_exists("foo_x");
Expand Down Expand Up @@ -135,6 +156,8 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_ENABLE_FIELD_RECOGNITION_OFF)
auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));
auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));

checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks());

bool exo_foo_x_exists = exo_elemBlock->field_exists("foo_x");
bool cat_foo_x_exists = cat_elemBlock->field_exists("foo_x");
EXPECT_TRUE(exo_foo_x_exists);
Expand Down Expand Up @@ -173,21 +196,24 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_ON)
auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));
auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));

checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks());

bool exo_foo_1_exists = exo_elemBlock->field_exists("foo_1");
bool cat_foo_1_exists = cat_elemBlock->field_exists("foo_1");
EXPECT_TRUE(exo_foo_1_exists);
EXPECT_TRUE(cat_foo_1_exists);
if(exo_foo_1_exists && cat_foo_1_exists)
EXPECT_TRUE(exo_elemBlock->get_field("foo_1") == cat_elemBlock->get_field("foo_1"));

}

TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_OFF)
{
Iocatalyst::BlockMesh bm;
setBlockMeshSize(2, 2, 2);

bm.addTransientCellField("foo_1", 2);
bm.addTransientCellField("foo_2", 3);
bm.addTransientCellField("foo_1", 3);
bm.addTransientCellField("foo_2", 2);
bm.addTransientCellField("foo_3", 4);


Expand All @@ -209,12 +235,26 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_IGNORE_REALN_FIELDS_OFF)
auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));
auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));

checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks());

bool exo_foo_exists = exo_elemBlock->field_exists("foo");
bool cat_foo_exists = cat_elemBlock->field_exists("foo");
EXPECT_TRUE(exo_foo_exists);
EXPECT_TRUE(cat_foo_exists);
if(exo_foo_exists && cat_foo_exists)
EXPECT_TRUE(exo_elemBlock->get_field("foo") == cat_elemBlock->get_field("foo"));

//Check field data for equality
auto cat_field = cat_elemBlock->get_fieldref("foo");
std::vector<std::byte> dcBuffer(cat_field.get_size());
cat_elemBlock->get_field_data("foo", Data(dcBuffer), dcBuffer.size());

exo_reg.begin_state(1);
auto exo_field = exo_elemBlock->get_fieldref("foo");
std::vector<std::byte> deBuffer(exo_field.get_size());
exo_elemBlock->get_field_data("foo", Data(deBuffer), deBuffer.size());
EXPECT_EQ(dcBuffer, deBuffer);

}

TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_SUFFIX_SEPARATOR)
Expand Down Expand Up @@ -249,6 +289,8 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_SUFFIX_SEPARATOR)
auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));
auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));

checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks());

bool exo_foo_x_exists = exo_elemBlock->field_exists("foo_x");
bool cat_foo_x_exists = cat_elemBlock->field_exists("foo_x");
EXPECT_TRUE(exo_foo_x_exists);
Expand All @@ -262,6 +304,17 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_SUFFIX_SEPARATOR)
EXPECT_TRUE(cat_bar_exists);
if(exo_bar_exists && cat_bar_exists)
EXPECT_TRUE(exo_elemBlock->get_field("bar") == cat_elemBlock->get_field("bar"));

//Check bar field data for equality
auto cat_field = cat_elemBlock->get_fieldref("bar");
std::vector<std::byte> dcBuffer(cat_field.get_size());
cat_elemBlock->get_field_data("bar", Data(dcBuffer), dcBuffer.size());

exo_reg.begin_state(1);
auto exo_field = exo_elemBlock->get_fieldref("bar");
std::vector<std::byte> deBuffer(exo_field.get_size());
exo_elemBlock->get_field_data("bar", Data(deBuffer), deBuffer.size());
EXPECT_EQ(dcBuffer, deBuffer);

}

Expand Down Expand Up @@ -294,12 +347,25 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_FIELD_STRIP_TRAILING_UNDERSCORE)
auto cat_elemBlock = cat_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));
auto exo_elemBlock = exo_reg.get_element_block(bmSet.getUnstructuredBlockName(bm.getID()));

checkEntityContainerZeroCopyFields(cat_reg.get_element_blocks());

bool exo_foo_exists = exo_elemBlock->field_exists("foo");
bool cat_foo_exists = cat_elemBlock->field_exists("foo");
EXPECT_TRUE(exo_foo_exists);
EXPECT_TRUE(cat_foo_exists);
if(exo_foo_exists && cat_foo_exists)
EXPECT_TRUE(exo_elemBlock->get_field("foo") == cat_elemBlock->get_field("foo"));

//Check field data for equality
auto cat_field = cat_elemBlock->get_fieldref("foo");
std::vector<std::byte> dcBuffer(cat_field.get_size());
cat_elemBlock->get_field_data("foo", Data(dcBuffer), dcBuffer.size());

exo_reg.begin_state(1);
auto exo_field = exo_elemBlock->get_fieldref("foo");
std::vector<std::byte> deBuffer(exo_field.get_size());
exo_elemBlock->get_field_data("foo", Data(deBuffer), deBuffer.size());
EXPECT_EQ(dcBuffer, deBuffer);

}

Expand All @@ -325,6 +391,7 @@ TEST_F(Iocatalyst_DatabaseIOTest, Exodus_Prop_SURFACE_SPLIT_TYPE)
Ioss::Region cat_reg(cat_d);

Ioss::SideSetContainer cat_sideSets = cat_reg.get_sidesets();
checkEntityContainerZeroCopyFields(cat_sideSets);

EXPECT_TRUE(cat_sideSets.empty())<<"Cat sidesets not empty when different SURFACE_SPLIT_TYPE";

Expand Down
Loading