From 391d96794ace3bf4b0859a9a66eb903b98dcf39c Mon Sep 17 00:00:00 2001 From: Caleb Schilly Date: Fri, 8 Dec 2023 16:51:51 -0500 Subject: [PATCH] support ragged arrays, lists of lists of lists --- nga-ci/build-yamlcpp-off.sh | 10 +- nga-ci/build-yamlcpp-on.sh | 10 +- .../BlockPrec/maxwell-pthOrder-newyaml.yaml | 2 +- .../parameterlist/src/Teuchos_YamlParser.cpp | 146 ++++++++++++++++-- 4 files changed, 136 insertions(+), 32 deletions(-) diff --git a/nga-ci/build-yamlcpp-off.sh b/nga-ci/build-yamlcpp-off.sh index c35da379e675..baf99fbfdab9 100644 --- a/nga-ci/build-yamlcpp-off.sh +++ b/nga-ci/build-yamlcpp-off.sh @@ -36,6 +36,7 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -D Trilinos_ENABLE_ALL_FORWARD_DEP_PACKAGES=ON \ -D Trilinos_VERBOSE_CONFIGURE=OFF \ -D BUILD_SHARED_LIBS:BOOL=ON \ + -D Tpetra_ENABLE_DEPRECATED_CODE=ON \ \ -D Trilinos_ENABLE_Panzer=ON \ -D Trilinos_ENABLE_PanzerMiniEM=ON \ @@ -88,14 +89,5 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -D MPI_EXEC_MAX_NUMPROCS=4 \ \ \ - -D Trilinos_ENABLE_Rythmos=OFF \ - -D Trilinos_ENABLE_STK=OFF \ - -D Trilinos_ENABLE_Pike=OFF \ - -D Trilinos_ENABLE_Komplex=OFF \ - -D Trilinos_ENABLE_TriKota=OFF \ - -D Trilinos_ENABLE_Moertel=OFF \ - -D Trilinos_ENABLE_Domi=OFF \ - -D Trilinos_ENABLE_FEI=OFF \ - -D Trilinos_ENABLE_PyTrilinos=OFF \ -S /opt/src/Trilinos -B /opt/build/Trilinos ninja -j 12 diff --git a/nga-ci/build-yamlcpp-on.sh b/nga-ci/build-yamlcpp-on.sh index ac1130536cf5..bc07bcfa5720 100644 --- a/nga-ci/build-yamlcpp-on.sh +++ b/nga-ci/build-yamlcpp-on.sh @@ -36,6 +36,7 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -D Trilinos_ENABLE_ALL_FORWARD_DEP_PACKAGES=ON \ -D Trilinos_VERBOSE_CONFIGURE=OFF \ -D BUILD_SHARED_LIBS:BOOL=ON \ + -D Tpetra_ENABLE_DEPRECATED_CODE=ON \ \ -D Trilinos_ENABLE_Panzer=ON \ -D Trilinos_ENABLE_PanzerMiniEM=ON \ @@ -89,14 +90,5 @@ cmake -G "${CMAKE_GENERATOR:-Ninja}" \ -D MPI_EXEC_MAX_NUMPROCS=4 \ \ \ - -D Trilinos_ENABLE_Rythmos=OFF \ - -D Trilinos_ENABLE_STK=OFF \ - -D Trilinos_ENABLE_Pike=OFF \ - -D Trilinos_ENABLE_Komplex=OFF \ - -D Trilinos_ENABLE_TriKota=OFF \ - -D Trilinos_ENABLE_Moertel=OFF \ - -D Trilinos_ENABLE_Domi=OFF \ - -D Trilinos_ENABLE_FEI=OFF \ - -D Trilinos_ENABLE_PyTrilinos=OFF \ -S /opt/src/Trilinos -B /opt/build/Trilinos ninja -j 12 diff --git a/packages/panzer/mini-em/example/BlockPrec/maxwell-pthOrder-newyaml.yaml b/packages/panzer/mini-em/example/BlockPrec/maxwell-pthOrder-newyaml.yaml index 896b8275314c..e95fa236fa4a 100644 --- a/packages/panzer/mini-em/example/BlockPrec/maxwell-pthOrder-newyaml.yaml +++ b/packages/panzer/mini-em/example/BlockPrec/maxwell-pthOrder-newyaml.yaml @@ -82,7 +82,7 @@ User_App Parameters: - e - f List of lists: - - [1, 2, 3, 4] + - [1, 2, 3] - [1, 2, 3, 4] List of lists of lists: - [[1,2,3], [4,5,6], [7,8,9]] diff --git a/packages/teuchos/parameterlist/src/Teuchos_YamlParser.cpp b/packages/teuchos/parameterlist/src/Teuchos_YamlParser.cpp index 3f131c75a259..19fa168b46d8 100644 --- a/packages/teuchos/parameterlist/src/Teuchos_YamlParser.cpp +++ b/packages/teuchos/parameterlist/src/Teuchos_YamlParser.cpp @@ -108,15 +108,17 @@ Teuchos::Array getYamlArray(const ::YAML::Node& node) return arr; } -void checkYamlTwoDArray(const ::YAML::Node& node, const std::string& key) +bool checkYamlTwoDArrayIsRagged(const ::YAML::Node& node) { + bool ragged = false; for (::YAML::const_iterator it = node.begin(); it != node.end(); ++it) { if (it->size() != node.begin()->size()) { - throw YamlSequenceError(std::string("TwoDArray \"") + key + "\" has irregular sizes"); + ragged=true; } } + return ragged; } template Teuchos::TwoDArray getYamlTwoDArray(const ::YAML::Node& node) @@ -139,6 +141,71 @@ template Teuchos::TwoDArray getYamlTwoDArray(const ::YAML::Node& return arr; } +int getYamlArrayDim(const ::YAML::Node& node) +{ + int ndim = 0; + + if (node.Type() == ::YAML::NodeType::Sequence) + { + ++ndim; + + if (node.begin()->Type() == ::YAML::NodeType::Sequence) + { + ++ndim; + + if (node.begin()->begin()->Type() == ::YAML::NodeType::Sequence) + { + ++ndim; + } + } + } + + return ndim; +} + + + +template +tarray_t getYaml2DRaggedArray(::YAML::Node node, int ndim, std::string key) +{ + tarray_t base_arr; + if (ndim == 2) { + Teuchos::Array sub_arr; + for (::YAML::const_iterator it1 = node.begin(); it1 != node.end(); ++it1) { + for (::YAML::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) { + sub_arr.push_back(quoted_as(*it2)); + } base_arr.push_back(sub_arr); + } + } + else + { + throw YamlSequenceError(std::string("MDArray \"" + key + "\" must have dim 2.")); + } + return base_arr; +} + +template +tarray_t getYaml3DArray(::YAML::Node node, int ndim, std::string key) +{ + tarray_t base_arr; + if (ndim == 3) { + Teuchos::Array> sub_arr; + Teuchos::Array sub_sub_arr; + for (::YAML::const_iterator it1 = node.begin(); it1 != node.end(); ++it1) { + for (::YAML::const_iterator it2 = it1->begin(); it2 != it1->end(); ++it2) { + for (::YAML::const_iterator it3 = it2->begin(); it3 != it2->end(); ++it3) { + sub_sub_arr.push_back(quoted_as(*it3)); + } sub_arr.push_back(sub_sub_arr); + } base_arr.push_back(sub_arr); + } + } + else + { + throw YamlSequenceError(std::string("MDArray \"" + key + "\" must have dim 3.")); + } + return base_arr; +} + #endif std::string remove_trailing_whitespace(std::string const& in) { @@ -1298,27 +1365,73 @@ void processKeyValueNode(const std::string& key, const ::YAML::Node& node, Teuch } else if(node.Type() == ::YAML::NodeType::Sequence) { - if (node.begin()->Type() == ::YAML::NodeType::Sequence) { - checkYamlTwoDArray(node, key); + int ndim = getYamlArrayDim(node); + if (ndim == 1) + { + ::YAML::Node const& first_value = *(node.begin()); + try + { + quoted_as(first_value); + parent.set(key, getYamlArray(node)); + } + catch(...) + { + try + { + quoted_as(first_value); + parent.set(key, getYamlArray(node)); + } + catch(...) + { + try + { + quoted_as(first_value); + parent.set(key, getYamlArray(node)); + } + catch(...) + { + throw YamlSequenceError(std::string("Array \"") + key + "\" must contain int, double, bool or string"); + } + } + } + } + else if (ndim == 2) + { + bool is_ragged = checkYamlTwoDArrayIsRagged(node); ::YAML::Node const& first_value = *(node.begin()->begin()); try { quoted_as(first_value); - parent.set(key, getYamlTwoDArray(node)); + using arr_t = Teuchos::Array>; + if (is_ragged) { + parent.set(key, getYaml2DRaggedArray(node, ndim, key)); + } else { + parent.set(key, getYamlTwoDArray(node)); + } } catch(...) { try { quoted_as(first_value); - parent.set(key, getYamlTwoDArray(node)); + using arr_t = Teuchos::Array>; + if (is_ragged) { + parent.set(key, getYaml2DRaggedArray(node, ndim, key)); + } else { + parent.set(key, getYamlTwoDArray(node)); + } } catch(...) { try { quoted_as(first_value); - parent.set(key, getYamlTwoDArray(node)); + using arr_t = Teuchos::Array>; + if (is_ragged) { + parent.set(key, getYaml2DRaggedArray(node, ndim, key)); + } else { + parent.set(key, getYamlTwoDArray(node)); + } } catch(...) { @@ -1326,30 +1439,37 @@ void processKeyValueNode(const std::string& key, const ::YAML::Node& node, Teuch } } } - } else { - ::YAML::Node const& first_value = *(node.begin()); + } + else if (ndim == 3) + { + ::YAML::Node const& first_value = *(node.begin()->begin()->begin()); try { quoted_as(first_value); - parent.set(key, getYamlArray(node)); + using arr_t = Teuchos::Array>>; + parent.set(key, getYaml3DArray(node, ndim, key)); } catch(...) { try { quoted_as(first_value); - parent.set(key, getYamlArray(node)); + using arr_t = Teuchos::Array>>; + parent.set(key, getYaml3DArray(node, ndim, key)); + } catch(...) { try { quoted_as(first_value); - parent.set(key, getYamlArray(node)); + using arr_t = Teuchos::Array>>; + parent.set(key, getYaml3DArray(node, ndim, key)); + } catch(...) { - throw YamlSequenceError(std::string("Array \"") + key + "\" must contain int, double, bool or string"); + throw YamlSequenceError(std::string("3DArray \"") + key + "\" must contain int, double, bool or string"); } } }