Skip to content

Commit

Permalink
Fix warnings from Logging, enable Plan memory to take external memory (
Browse files Browse the repository at this point in the history
…apache#93)

* Fix warnings from Logging, enable Plan memory to take external memory

* fix external memory id

* fix graph
  • Loading branch information
tqchen committed Jan 6, 2017
1 parent 4d6d320 commit d6a6e0e
Show file tree
Hide file tree
Showing 11 changed files with 325 additions and 24 deletions.
12 changes: 6 additions & 6 deletions include/dmlc/json.h
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,8 @@ inline void JSONWriter::BeginArray(bool multi_line) {
}

inline void JSONWriter::EndArray() {
CHECK_NE(scope_multi_line_.size(), 0);
CHECK_NE(scope_counter_.size(), 0);
CHECK_NE(scope_multi_line_.size(), 0U);
CHECK_NE(scope_counter_.size(), 0U);
bool newline = scope_multi_line_.back();
size_t nelem = scope_counter_.back();
scope_multi_line_.pop_back();
Expand All @@ -764,8 +764,8 @@ inline void JSONWriter::BeginObject(bool multi_line) {
}

inline void JSONWriter::EndObject() {
CHECK_NE(scope_multi_line_.size(), 0);
CHECK_NE(scope_counter_.size(), 0);
CHECK_NE(scope_multi_line_.size(), 0U);
CHECK_NE(scope_counter_.size(), 0U);
bool newline = scope_multi_line_.back();
size_t nelem = scope_counter_.back();
scope_multi_line_.pop_back();
Expand Down Expand Up @@ -842,7 +842,7 @@ inline void JSONObjectReadHelper::ReadAllFields(JSONReader *reader) {
for (std::map<std::string, Entry>::iterator
it = map_.begin(); it != map_.end(); ++it) {
if (it->second.optional) continue;
CHECK_NE(visited.count(it->first), 0)
CHECK_NE(visited.count(it->first), 0U)
<< "JSONReader: Missing field \"" << it->first << "\"\n At "
<< reader->line_info();
}
Expand All @@ -857,7 +857,7 @@ inline void JSONObjectReadHelper::ReaderFunction(JSONReader *reader, void *addr)
template<typename T>
inline void JSONObjectReadHelper::
DeclareFieldInternal(const std::string &key, T *addr, bool optional) {
CHECK_EQ(map_.count(key), 0)
CHECK_EQ(map_.count(key), 0U)
<< "Adding duplicate field " << key;
Entry e;
e.func = ReaderFunction<T>;
Expand Down
181 changes: 181 additions & 0 deletions include/dmlc/optional.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*!
* Copyright (c) 2016 by Contributors
* \file optional.h
* \brief Container to hold optional data.
*/
#ifndef DMLC_OPTIONAL_H_
#define DMLC_OPTIONAL_H_

#include <iostream>
#include <utility>
#include <algorithm>

#include "./base.h"
#include "./logging.h"
#include "./type_traits.h"

namespace dmlc {

/*! \brief dummy type for assign null to optional */
struct nullopt_t {
#if defined(_MSC_VER) && _MSC_VER < 1900
/*! \brief dummy constructor */
explicit nullopt_t(int) {}
#else
/*! \brief dummy constructor */
constexpr nullopt_t(int) {}
#endif
};

/*! Assign null to optional: optional<T> x = nullopt; */
constexpr const nullopt_t nullopt = nullopt_t(0);

/*!
* \brief c++17 compatible optional class.
*
* At any time an optional<T> instance either
* hold no value (string representation "None")
* or hold a value of type T.
*/
template<typename T>
class optional {
public:
/*! \brief construct an optional object that contains no value */
optional() : is_none(true) {}
/*! \brief construct an optional object with value */
explicit optional(const T& value) {
is_none = false;
new (&val) T(value);
}
/*! \brief construct an optional object with another optional object */
optional(const optional<T>& other) {
is_none = other.is_none;
if (!is_none) {
new (&val) T(other.value());
}
}
/*! \brief deconstructor */
~optional() {
if (!is_none) {
reinterpret_cast<T*>(&val)->~T();
}
}
/*! \brief swap two optional */
void swap(optional<T>& other) {
std::swap(val, other.val);
std::swap(is_none, other.is_none);
}
/*! \brief set this object to hold value
* \param value the value to hold
* \return return self to support chain assignment
*/
optional<T>& operator=(const T& value) {
(optional<T>(value)).swap(*this);
return *this;
}
/*! \brief set this object to hold the same value with other
* \param other the other object
* \return return self to support chain assignment
*/
optional<T>& operator=(const optional<T> &other) {
(optional<T>(other)).swap(*this);
return *this;
}
/*! \brief clear the value this object is holding.
* optional<T> x = nullopt;
*/
optional<T>& operator=(nullopt_t) {
(optional<T>()).swap(*this);
return *this;
}
/*! \brief non-const dereference operator */
T& operator*() { // NOLINT(*)
return *reinterpret_cast<T*>(&val);
}
/*! \brief const dereference operator */
const T& operator*() const {
return *reinterpret_cast<const T*>(&val);
}
/*! \brief return the holded value.
* throws std::logic_error if holding no value
*/
const T& value() const {
if (is_none) {
throw std::logic_error("bad optional access");
}
return *reinterpret_cast<const T*>(&val);
}
/*! \brief whether this object is holding a value */
explicit operator bool() const { return !is_none; }

private:
// whether this is none
bool is_none;
// on stack storage of value
typename std::aligned_storage<sizeof(T), alignof(T)>::type val;
};

/*! \brief serialize an optional object to string.
*
* \code
* dmlc::optional<int> x;
* std::cout << x; // None
* x = 0;
* std::cout << x; // 0
* \endcode
*
* \param os output stream
* \param t source optional<T> object
* \return output stream
*/
template<typename T>
std::ostream &operator<<(std::ostream &os, const optional<T> &t) {
if (t) {
os << *t;
} else {
os << "None";
}
return os;
}

/*! \brief parse a string object into optional<T>
*
* \code
* dmlc::optional<int> x;
* std::string s1 = "1";
* std::istringstream is1(s1);
* s1 >> x; // x == optional<int>(1)
*
* std::string s2 = "None";
* std::istringstream is2(s2);
* s2 >> x; // x == optional<int>()
* \endcode
*
* \param is input stream
* \param t target optional<T> object
* \return input stream
*/
template<typename T>
std::istream &operator>>(std::istream &is, optional<T> &t) {
char buf[4];
std::streampos origin = is.tellg();
is.read(buf, 4);
if (is.fail() || buf[0] != 'N' || buf[1] != 'o' ||
buf[2] != 'n' || buf[3] != 'e') {
is.clear();
is.seekg(origin);
T x;
is >> x;
t = x;
} else {
t = nullopt;
}
return is;
}

/*! \brief description for optional int */
DMLC_DECLARE_TYPE_NAME(optional<int>, "int or None");

} // namespace dmlc

#endif // DMLC_OPTIONAL_H_
112 changes: 111 additions & 1 deletion include/dmlc/parameter.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "./json.h"
#include "./logging.h"
#include "./type_traits.h"
#include "./optional.h"

namespace dmlc {
// this file is backward compatible with non-c++11
Expand Down Expand Up @@ -758,7 +759,7 @@ class FieldEntry<int>
// override print default
virtual void PrintValue(std::ostream &os, int value) const { // NOLINT(*)
if (is_enum_) {
CHECK_NE(enum_back_map_.count(value), 0)
CHECK_NE(enum_back_map_.count(value), 0U)
<< "Value not found in enum declared";
os << enum_back_map_.at(value);
} else {
Expand All @@ -781,6 +782,115 @@ class FieldEntry<int>
}
};


// specialize define for optional<int>(enum)
template<>
class FieldEntry<optional<int> >
: public FieldEntryBase<FieldEntry<optional<int> >, optional<int> > {
public:
// construct
FieldEntry<optional<int> >() : is_enum_(false) {}
// parent
typedef FieldEntryBase<FieldEntry<optional<int> >, optional<int> > Parent;
// override set
virtual void Set(void *head, const std::string &value) const {
if (is_enum_ && value != "None") {
std::map<std::string, int>::const_iterator it = enum_map_.find(value);
std::ostringstream os;
if (it == enum_map_.end()) {
os << "Invalid Input: \'" << value;
os << "\', valid values are: ";
PrintEnums(os);
throw dmlc::ParamError(os.str());
} else {
os << it->second;
Parent::Set(head, os.str());
}
} else {
Parent::Set(head, value);
}
}
virtual ParamFieldInfo GetFieldInfo() const {
if (is_enum_) {
ParamFieldInfo info;
std::ostringstream os;
info.name = key_;
info.type = type_;
PrintEnums(os);
if (has_default_) {
os << ',' << "optional, default=";
PrintDefaultValueString(os);
} else {
os << ", required";
}
info.type_info_str = os.str();
info.description = description_;
return info;
} else {
return Parent::GetFieldInfo();
}
}
// add enum
inline FieldEntry<optional<int> > &add_enum(const std::string &key, int value) {
CHECK_NE(key, "None") << "None is reserved for empty optional<int>";
if ((enum_map_.size() != 0 && enum_map_.count(key) != 0) || \
enum_back_map_.count(value) != 0) {
std::ostringstream os;
os << "Enum " << "(" << key << ": " << value << " exisit!" << ")\n";
os << "Enums: ";
for (std::map<std::string, int>::const_iterator it = enum_map_.begin();
it != enum_map_.end(); ++it) {
os << "(" << it->first << ": " << it->second << "), ";
}
throw dmlc::ParamError(os.str());
}
enum_map_[key] = value;
enum_back_map_[value] = key;
is_enum_ = true;
return this->self();
}

protected:
// enum flag
bool is_enum_;
// enum map
std::map<std::string, int> enum_map_;
// enum map
std::map<int, std::string> enum_back_map_;
// override print behavior
virtual void PrintDefaultValueString(std::ostream &os) const { // NOLINT(*)
os << '\'';
PrintValue(os, default_value_);
os << '\'';
}
// override print default
virtual void PrintValue(std::ostream &os, optional<int> value) const { // NOLINT(*)
if (is_enum_) {
if (!value) {
os << "None";
} else {
CHECK_NE(enum_back_map_.count(value.value()), 0U)
<< "Value not found in enum declared";
os << enum_back_map_.at(value.value());
}
} else {
os << value;
}
}


private:
inline void PrintEnums(std::ostream &os) const { // NOLINT(*)
os << "{None";
for (std::map<std::string, int>::const_iterator
it = enum_map_.begin(); it != enum_map_.end(); ++it) {
os << ", ";
os << "\'" << it->first << '\'';
}
os << '}';
}
};

// specialize define for string
template<>
class FieldEntry<std::string>
Expand Down
2 changes: 1 addition & 1 deletion include/dmlc/registry.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class Registry {
* \return ref to the registered entry, used to set properties
*/
inline EntryType &__REGISTER__(const std::string& name) {
CHECK_EQ(fmap_.count(name), 0)
CHECK_EQ(fmap_.count(name), 0U)
<< name << " already registered";
EntryType *e = new EntryType();
e->name = name;
Expand Down
Loading

0 comments on commit d6a6e0e

Please sign in to comment.