Skip to content

Commit

Permalink
Teuchos: YAML parse support for TwoDArray
Browse files Browse the repository at this point in the history
This enhancement supports gahansen/Albany#74.
Albany uses TwoDArray type ParameterLists,
and getting these supported in the YAML parser
would streamline our migration from XML to YAML.
There should be no compatibility issue, as I
don't think the current parser can handle nested
Sequences.
A unit test is included.
  • Loading branch information
ibaned committed Mar 7, 2017
1 parent c0d0d38 commit 2f3f1a6
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 13 deletions.
86 changes: 73 additions & 13 deletions packages/teuchos/parameterlist/src/Teuchos_YamlParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@

#include "Teuchos_YamlParser_decl.hpp"
#include "Teuchos_XMLParameterListCoreHelpers.hpp"
#include "Teuchos_TwoDArray.hpp"

namespace Teuchos
{
Expand All @@ -63,6 +64,36 @@ template<typename T> Teuchos::Array<T> getYamlArray(const YAML::Node& node)
return arr;
}

void checkYamlTwoDArray(const YAML::Node& node, const std::string& key)
{
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");
}
}
}

template<typename T> Teuchos::TwoDArray<T> getYamlTwoDArray(const YAML::Node& node)
{
Teuchos::TwoDArray<T> arr;
typename Teuchos::TwoDArray<T>::size_type i, j;
arr.resizeRows(node.size());
arr.resizeCols(node.begin()->size());
i = 0;
for (YAML::const_iterator rit = node.begin(); rit != node.end(); ++rit)
{
j = 0;
for (YAML::const_iterator cit = rit->begin(); cit != rit->end(); ++cit)
{
arr(i, j) = cit->as<T>();
++j;
}
++i;
}
return arr;
}

/* Helper functions */

Expand Down Expand Up @@ -327,29 +358,58 @@ void processKeyValueNode(const std::string& key, const YAML::Node& node, Teuchos
}
else if(node.Type() == YAML::NodeType::Sequence)
{
//typeString is used to provide a useful error message if types inconsistent
try
{
node.begin()->as<int>();
parent.set(key, getYamlArray<int>(node));
}
catch(...)
{
if (node.begin()->Type() == YAML::NodeType::Sequence) {
checkYamlTwoDArray(node, key);
try
{
node.begin()->begin()->as<int>();
parent.set(key, getYamlTwoDArray<int>(node));
}
catch(...)
{
try
{
node.begin()->begin()->as<double>();
parent.set(key, getYamlTwoDArray<double>(node));
}
catch(...)
{
try
{
node.begin()->begin()->as<std::string>();
parent.set(key, getYamlTwoDArray<std::string>(node));
}
catch(...)
{
throw YamlSequenceError(std::string("TwoDArray \"") + key + "\" must contain int, double, bool or string");
}
}
}
} else {
//typeString is used to provide a useful error message if types inconsistent
try
{
node.begin()->as<double>();
parent.set(key, getYamlArray<double>(node));
node.begin()->as<int>();
parent.set(key, getYamlArray<int>(node));
}
catch(...)
{
try
{
node.begin()->as<std::string>();
parent.set(key, getYamlArray<std::string>(node));
node.begin()->as<double>();
parent.set(key, getYamlArray<double>(node));
}
catch(...)
{
throw YamlSequenceError(std::string("Array \"") + key + "\" must contain int, double, bool or string");
try
{
node.begin()->as<std::string>();
parent.set(key, getYamlArray<std::string>(node));
}
catch(...)
{
throw YamlSequenceError(std::string("Array \"") + key + "\" must contain int, double, bool or string");
}
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions packages/teuchos/parameterlist/test/yaml/TwoDArray.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
%YAML 1.1
---
Albany:
str2d: [[R, G, B], ['1', '2', '3']]
...
17 changes: 17 additions & 0 deletions packages/teuchos/parameterlist/test/yaml/YamlParameterList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include <Teuchos_YamlParameterListCoreHelpers.hpp>
#include <Teuchos_RCP.hpp>
#include <Teuchos_Exceptions.hpp>
#include <Teuchos_TwoDArray.hpp>



Expand Down Expand Up @@ -129,5 +130,21 @@ namespace TeuchosTests
}
});
}
TEUCHOS_UNIT_TEST(YAML, ReadTwoDArray)
{
std::string correctStrings[2][3] = {{"R", "G", "B"}, {"1", "2", "3"}};
TEST_NOTHROW({
RCP<ParameterList> plist = Teuchos::getParametersFromYamlFile("TwoDArray.yaml");
const Teuchos::TwoDArray<std::string>& str2d = plist->get<Teuchos::TwoDArray<std::string> >("str2d");
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 3; ++j) {
if (str2d[i][j] != correctStrings[i][j]) {
throw std::runtime_error(std::string("str2d[") + std::to_string(i) + "]["
+ std::to_string(j) + "] is incorrect.");
}
}
}
});
}

} //namespace TeuchosTests

0 comments on commit 2f3f1a6

Please sign in to comment.