Example #1
0
TEST(ValueTest, ValueMap)
{
  boost::shared_ptr<Scalar> s(new Scalar(NTA_BasicType_Int32));
  s->value.int32 = 10;
  boost::shared_ptr<Array> a(new Array(NTA_BasicType_Real32));
  boost::shared_ptr<std::string> str(new std::string("hello world"));
  
  ValueMap vm;
  vm.add("scalar", s);
  vm.add("array", a);
  vm.add("string", str);
  ASSERT_ANY_THROW(vm.add("scalar", s));

  ASSERT_TRUE(vm.contains("scalar"));
  ASSERT_TRUE(vm.contains("array"));
  ASSERT_TRUE(vm.contains("string"));
  ASSERT_TRUE(!vm.contains("foo"));
  ASSERT_TRUE(!vm.contains("scalar2"));
  ASSERT_TRUE(!vm.contains("xscalar"));
  
  boost::shared_ptr<Scalar> s1 = vm.getScalar("scalar");
  ASSERT_TRUE(s1 == s);
  
  boost::shared_ptr<Array> a1 = vm.getArray("array");
  ASSERT_TRUE(a1 == a);
  
  boost::shared_ptr<Scalar> def(new Scalar(NTA_BasicType_Int32));
  Int32 x = vm.getScalarT("scalar", (Int32)20);
  ASSERT_EQ((Int32)10, x);
  
  x = vm.getScalarT("scalar2", (Int32)20);
  ASSERT_EQ((Int32)20, x);

  Value v = vm.getValue("array");
  ASSERT_EQ(Value::arrayCategory, v.getCategory());
  ASSERT_TRUE(v.getArray() == a);
}
Example #2
0
/*
 * For converting param specs for Regions and LinkPolicies
 */
ValueMap toValueMap(const char* yamlstring,
                    Collection<ParameterSpec>& parameters,
                    const std::string & nodeType,
                    const std::string & regionName)
{

    ValueMap vm;

    // yaml-cpp bug: append a space if it is only one character
    // This is very inefficient, but should be ok since it is
    // just used at construction time for short strings
    std::string paddedstring(yamlstring);
    // TODO: strip white space to determine if empty
    bool empty = (paddedstring.size() == 0);

    if (paddedstring.size() < 2)
        paddedstring = paddedstring + " ";
    std::stringstream s(paddedstring);
    // IMemStream s(yamlstring, ::strlen(yamlstring));

    // TODO: utf-8 compatible?
    YAML::Node doc;
    if (!empty)
    {
        YAML::Parser parser(s);
        bool success = parser.GetNextDocument(doc);

        if (!success)
            NTA_THROW << "Unable to find document in YAML string";

        // A ValueMap is specified as a dictionary
        if (doc.Type() != YAML::NodeType::Map)
        {
            std::string ys(yamlstring);
            if (ys.size() > 30)
            {
                ys = ys.substr(0, 30) + "...";
            }
            NTA_THROW << "YAML string '" << ys
                      << "' does not not specify a dictionary of key-value pairs. "
                      << "Region and Link parameters must be specified at a dictionary";
        }
    }

    // Grab each value out of the YAML dictionary and put into the ValueMap
    // if it is allowed by the nodespec.
    YAML::Iterator i;
    for (i = doc.begin(); i != doc.end(); i++)
    {
        const std::string key = i.first().to<std::string>();
        if (!parameters.contains(key))
        {
            std::stringstream ss;
            for (UInt j = 0; j < parameters.getCount(); j++)
            {
                ss << "   " << parameters.getByIndex(j).first << "\n";
            }

            if (nodeType == std::string(""))
            {
                NTA_THROW << "Unknown parameter '" << key << "'\n"
                          << "Valid parameters are:\n" << ss.str();
            }
            else
            {
                NTA_CHECK(regionName != std::string(""));
                NTA_THROW << "Unknown parameter '" << key << "' for region '"
                          << regionName << "' of type '" << nodeType << "'\n"
                          << "Valid parameters are:\n" << ss.str();
            }
        }
        if (vm.contains(key))
            NTA_THROW << "Parameter '" << key << "' specified more than once in YAML document";
        ParameterSpec spec = parameters.getByName(key);
        try
        {
            Value v = toValue(i.second(), spec.dataType);
            if (v.isScalar() && spec.count != 1)
            {
                throw std::runtime_error("Expected array value but got scalar value");
            }
            if (!v.isScalar() && spec.count == 1)
            {
                throw std::runtime_error("Expected scalar value but got array value");
            }
            vm.add(key, v);
        } catch (std::runtime_error& e) {
            NTA_THROW << "Unable to set parameter '" << key << "'. " << e.what();
        }
    }

    // Populate ValueMap with default values if they were not specified in the YAML dictionary.
    for (size_t i = 0; i < parameters.getCount(); i++)
    {
        std::pair<std::string, ParameterSpec>& item = parameters.getByIndex(i);
        if (!vm.contains(item.first))
        {
            ParameterSpec & ps = item.second;
            if (ps.defaultValue != "")
            {
                // TODO: This check should be uncommented after dropping NuPIC 1.x nodes (which don't comply)
                // if (ps.accessMode != ParameterSpec::CreateAccess)
                // {
                //   NTA_THROW << "Default value for non-create parameter: " << item.first;
                // }

                try {
#ifdef YAMLDEBUG
                    NTA_DEBUG << "Adding default value '" << ps.defaultValue
                              << "' to parameter " << item.first
                              << " of type " << BasicType::getName(ps.dataType)
                              << " count " << ps.count;
#endif
                    Value v = toValue(ps.defaultValue, ps.dataType);
                    vm.add(item.first, v);
                } catch (...) {
                    NTA_THROW << "Unable to set default value for item '"
                              << item.first << "' of datatype "
                              << BasicType::getName(ps.dataType)
                              <<" with value '" << ps.defaultValue << "'";
                }
            }
        }
    }

    return vm;
}
Example #3
0
/*
 * For converting param specs for Regions and LinkPolicies
 */
ValueMap toValueMap(const char *yamlstring,
                    Collection<ParameterSpec> &parameters,
                    const std::string &nodeType,
                    const std::string &regionName) {

  ValueMap vm;

  // special value that applies to all regions.
  ParameterSpec dim_spec("Buffer dimensions for region's global dimensions. "
                    "Syntax: {dim: [2,3]}",  // description
	                  NTA_BasicType_UInt32,
							      0,                         // elementCount (an array of unknown size)
							      "",                        // constraints
							      "",                        // defaultValue
							      ParameterSpec::ReadWriteAccess);


  std::string paddedstring(yamlstring);
  // TODO: strip white space to determine if empty
  bool empty = (paddedstring.size() == 0);

  // TODO: utf-8 compatible?
  const YAML::Node doc = YAML::Load(paddedstring);
  if(!empty) {
    // A ValueMap is specified as a dictionary
    if (doc.Type() != YAML::NodeType::Map) {
      std::string ys(yamlstring);
      if (ys.size() > 30) {
        ys = ys.substr(0, 30) + "...";
      }
      NTA_THROW
          << "YAML string '" << ys
          << "' does not not specify a dictionary of key-value pairs. "
          << "Region and Link parameters must be specified as a dictionary";
    }
  }
  // Grab each value out of the YAML dictionary and put into the ValueMap
  // if it is allowed by the nodespec.
  for (auto i = doc.begin(); i != doc.end(); i++)
  {
    ParameterSpec ps;

    const auto key = i->first.as<std::string>();
    if (key == "dim")
      ps = dim_spec;
    else {
      if (!parameters.contains(key))
      {
        std::stringstream ss;
        for (UInt j = 0; j < parameters.getCount(); j++){
          ss << "   " << parameters.getByIndex(j).first << "\n";
        }

        if (nodeType == std::string("")) {
          NTA_THROW << "Unknown parameter '" << key << "'\n"
                    << "Valid parameters are:\n" << ss.str();
        } else {
          NTA_CHECK(regionName != std::string(""));
          NTA_THROW << "Unknown parameter '" << key << "' for region '"
                    << regionName << "' of type '" << nodeType << "'\n"
                    << "Valid parameters are:\n"
                    << ss.str();
        }
      }
      ps = parameters.getByName(key); // makes a copy of ParameterSpec
    }
    if (vm.contains(key))
        NTA_THROW << "Parameter '" << key << "' specified more than once in YAML document";
    try
    {
      if (ps.accessMode == ParameterSpec::ReadOnlyAccess) {
        NTA_THROW << "Parameter '" << key << "'. This is ReadOnly access. Cannot be set.";
      }
      Value v = toValue(i->second, ps.dataType);
      if (v.isScalar() && ps.count != 1)
      {
        NTA_THROW << "Parameter '" << key << "'. Bad value in runtime parameters. Expected array value but got scalar value";
      }
      if (!v.isScalar() && ps.count == 1)
      {
        NTA_THROW << "Parameter '" << key << "'. Bad value in runtime parameters. Expected scalar value but got array value";
      }
      vm.add(key, v);
    } catch (std::runtime_error &e) {
      NTA_THROW << "Unable to set parameter '" << key << "'. " << e.what();
    }
  } //end for

  // Populate ValueMap with default values if they were not specified in the YAML dictionary.
  for (size_t i = 0; i < parameters.getCount(); i++)
  {
    const std::pair<std::string, ParameterSpec>& item = parameters.getByIndex(i);
    if (!vm.contains(item.first))
    {
      const ParameterSpec & ps = item.second;
      if (ps.defaultValue != "")
      {
        // TODO: This check should be uncommented after dropping NuPIC 1.x nodes (which don't comply) //FIXME try this
        // if (ps.accessMode != ParameterSpec::CreateAccess)
        // {
        //   NTA_THROW << "Default value for non-create parameter: " << item.first;
        // }

        try {
#ifdef YAMLDEBUG
          NTA_DEBUG << "Adding default value '" << ps.defaultValue
                    << "' to parameter " << item.first << " of type "
                    << BasicType::getName(ps.dataType) << " count " << ps.count;
#endif
          // NOTE: this can handle both scalers and arrays
          //       Arrays MUST be in Yaml sequence format even if one element.
          //       i.e.  [1,2,3]
          Value v = toValue(ps.defaultValue, ps.dataType);
          if (v.isScalar() && ps.count != 1)
          {
            NTA_THROW << "Parameter '" << item.first << "'. Bad default value in spec. Expected array value but got scalar value";
          }
          if (!v.isScalar() && ps.count == 1)
          {
            NTA_THROW << "Parameter '" << item.first << "'. Bad default value in spec. Expected scalar value but got array value";
          }
          vm.add(item.first, v);
        } catch (...) {
          NTA_THROW << "Unable to set default value for item '" << item.first
                    << "' of datatype " << BasicType::getName(ps.dataType)
                    << " with value '" << ps.defaultValue << "'";
        }
      }
    }
  }

  return vm;
}
Example #4
0
void ValueTest::RunTests()
{
  // scalar
  {
    boost::shared_ptr<Scalar>  s(new Scalar(NTA_BasicType_Int32));
    s->value.int32 = 10;
    Value v(s);
    TEST(v.isScalar());
    TEST(! v.isString());
    TEST(! v.isArray());
    TESTEQUAL(Value::scalarCategory, v.getCategory());
    TESTEQUAL(NTA_BasicType_Int32, v.getType());
      
    boost::shared_ptr<Scalar> s1 = v.getScalar();
    TEST(s1 == s);
      
    SHOULDFAIL(v.getArray());
    SHOULDFAIL(v.getString());
      
    TESTEQUAL("Scalar of type Int32", v.getDescription());
      
    
    Int32 x = v.getScalarT<Int32>();
    TESTEQUAL(10, x);
    
    SHOULDFAIL(v.getScalarT<UInt32>());

  }

  // array
  {
    boost::shared_ptr<Array>  s(new Array(NTA_BasicType_Int32));
    s->allocateBuffer(10);
    Value v(s);
    TEST(v.isArray());
    TEST(! v.isString());
    TEST(! v.isScalar());
    TESTEQUAL(Value::arrayCategory, v.getCategory());
    TESTEQUAL(NTA_BasicType_Int32, v.getType());
      
    boost::shared_ptr<Array> s1 = v.getArray();
    TEST(s1 == s);
      
    SHOULDFAIL(v.getScalar());
    SHOULDFAIL(v.getString());
    SHOULDFAIL(v.getScalarT<Int32>());

    TESTEQUAL("Array of type Int32", v.getDescription());
  }

  // string
  {
    boost::shared_ptr<std::string> s(new std::string("hello world"));
    Value v(s);
    TEST(! v.isArray());
    TEST(v.isString());
    TEST(! v.isScalar());
    TESTEQUAL(Value::stringCategory, v.getCategory());
    TESTEQUAL(NTA_BasicType_Byte, v.getType());
      
    boost::shared_ptr<std::string> s1 = v.getString();
    TESTEQUAL("hello world", s1->c_str());
      
    SHOULDFAIL(v.getScalar());
    SHOULDFAIL(v.getArray());
    SHOULDFAIL(v.getScalarT<Int32>());
      
    TESTEQUAL("string (hello world)", v.getDescription());
  }

  // ValueMap
  {
    boost::shared_ptr<Scalar> s(new Scalar(NTA_BasicType_Int32));
    s->value.int32 = 10;
    boost::shared_ptr<Array> a(new Array(NTA_BasicType_Real32));
    boost::shared_ptr<std::string> str(new std::string("hello world"));
    
    ValueMap vm;
    vm.add("scalar", s);
    vm.add("array", a);
    vm.add("string", str);
    SHOULDFAIL(vm.add("scalar", s));

    TEST(vm.contains("scalar"));
    TEST(vm.contains("array"));
    TEST(vm.contains("string"));
    TEST(!vm.contains("foo"));
    TEST(!vm.contains("scalar2"));
    TEST(!vm.contains("xscalar"));
    
    boost::shared_ptr<Scalar> s1 = vm.getScalar("scalar");
    TEST(s1 == s);
    
    boost::shared_ptr<Array> a1 = vm.getArray("array");
    TEST(a1 == a);
    
    boost::shared_ptr<Scalar> def(new Scalar(NTA_BasicType_Int32));
    Int32 x = vm.getScalarT("scalar", (Int32)20);
    TESTEQUAL((Int32)10, x);
    
    x = vm.getScalarT("scalar2", (Int32)20);
    TESTEQUAL((Int32)20, x);

    Value v = vm.getValue("array");
    TESTEQUAL(Value::arrayCategory, v.getCategory());
    TEST(v.getArray() == a);
  }
}