Skip to content

Commit 9b982c3

Browse files
committed
[REFACTOR] copy DMLC headers, move operator to example (apache#20)
1 parent 2f837ab commit 9b982c3

File tree

19 files changed

+3527
-126
lines changed

19 files changed

+3527
-126
lines changed

nnvm/Makefile

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
export LDFLAGS = -pthread -lm
22
export CFLAGS = -std=c++11 -Wall -O2 -msse2 -Wno-unknown-pragmas -funroll-loops\
3-
-Iinclude -Idmlc-core/include -fPIC
3+
-Iinclude -fPIC
44

55
# specify tensor path
66
.PHONY: clean all test lint doc cython cython3 cyclean
77

8-
all: lib/libnnvm.so lib/libnnvm.a cli_test
8+
all: lib/libnnvm.a lib/libnnvm_example.so
99

10-
SRC = $(wildcard src/*.cc src/*/*.cc example/*.cc)
10+
SRC = $(wildcard src/*.cc src/*/*.cc)
1111
ALL_OBJ = $(patsubst src/%.cc, build/%.o, $(SRC))
12-
ALL_DEP = $(filter-out build/test_main.o, $(ALL_OBJ))
12+
ALL_DEP = $(ALL_OBJ)
1313

1414
include tests/cpp/unittest.mk
1515

@@ -20,16 +20,14 @@ build/%.o: src/%.cc
2020
$(CXX) $(CFLAGS) -MM -MT build/$*.o $< >build/$*.d
2121
$(CXX) -c $(CFLAGS) -c $< -o $@
2222

23-
lib/libnnvm.so: $(ALL_DEP)
24-
@mkdir -p $(@D)
25-
$(CXX) $(CFLAGS) -shared -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
2623

2724
lib/libnnvm.a: $(ALL_DEP)
2825
@mkdir -p $(@D)
2926
ar crv $@ $(filter %.o, $?)
3027

31-
cli_test: $(ALL_DEP) build/test_main.o
32-
$(CXX) $(CFLAGS) -o $@ $(filter %.o %.a, $^) $(LDFLAGS)
28+
lib/libnnvm_example.so: example/src/operator.cc lib/libnnvm.a
29+
@mkdir -p $(@D)
30+
$(CXX) $(CFLAGS) -shared -o $@ $(filter %.cc, $^) $(LDFLAGS) -Wl,--whole-archive lib/libnnvm.a -Wl,--no-whole-archive
3331

3432
cython:
3533
cd python; python setup.py build_ext --inplace

nnvm/src/example/operator.cc renamed to nnvm/example/src/operator.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ NNVM_REGISTER_OP(__add_symbol__)
9696
.set_num_inputs(2);
9797

9898
NNVM_REGISTER_OP(exp)
99-
.describe("take exponmential")
99+
.describe("take exponential")
100100
.set_num_inputs(1)
101101
.attr("inplace_pair", std::make_pair(0, 0))
102102
.attr<FInferShape>("FInferShape", SameShape);

nnvm/include/dmlc/README

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This folder is synced from dmlc-core/include/dmlc
2+
Contains useful utility headers for the project.

nnvm/include/dmlc/any.h

Lines changed: 345 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,345 @@
1+
/*!
2+
* Copyright (c) 2016 by Contributors
3+
* \file any.h
4+
* \brief Container to hold any data type.
5+
*/
6+
#ifndef DMLC_ANY_H_
7+
#define DMLC_ANY_H_
8+
9+
// This code need c++11 to compile
10+
#include <typeinfo>
11+
#include <type_traits>
12+
#include <utility>
13+
#include <algorithm>
14+
15+
#include "./base.h"
16+
#include "./logging.h"
17+
18+
namespace dmlc {
19+
// forward declare any;
20+
class any;
21+
22+
/*!
23+
* Get a reference to content stored in the any as type T.
24+
* This will cause an error if
25+
* T does not match the type stored.
26+
* This function is not part of std::any standard.
27+
*
28+
* \param src The source source any container.
29+
* \return The reference of content
30+
* \tparam T The type of the value to be fetched.
31+
*/
32+
template<typename T>
33+
inline T& get(any& src); // NOLINT(*)
34+
35+
/*!
36+
* Get the const reference content stored in the any as type T.
37+
* This will cause an error if
38+
* T does not match the type stored.
39+
* This function is not part of std::any standard.
40+
*
41+
* \param src The source source any container.
42+
* \return The reference of content
43+
* \tparam T The type of the value to be fetched.
44+
*/
45+
template<typename T>
46+
inline const T& get(const any& src);
47+
48+
/*!
49+
* \brief An any class that is compatible to std::any in c++17.
50+
*
51+
* \code
52+
* dmlc::any a = std::string("mydear"), b = 1;
53+
* // get reference out and add it
54+
* dmlc::get<int>(b) += 1;
55+
* // a is now string
56+
* LOG(INFO) << dmlc::get<std::string>(a);
57+
* // a is now 2, the string stored will be properly destructed
58+
* a = std::move(b);
59+
* LOG(INFO) << dmlc::get<int>(a);
60+
* \endcode
61+
* \sa get
62+
*/
63+
class any {
64+
public:
65+
/*! \brief default constructor */
66+
inline any() = default;
67+
/*!
68+
* \brief move constructor from another any
69+
* \param other The other any to be moved
70+
*/
71+
inline any(any&& other); // NOLINT(*)
72+
/*!
73+
* \brief copy constructor
74+
* \param other The other any to be copied
75+
*/
76+
inline any(const any& other); // NOLINT(*)
77+
/*!
78+
* \brief constructor from any types
79+
* \param other The other types to be constructed into any.
80+
* \tparam T The value type of other.
81+
*/
82+
template<typename T>
83+
inline any(T&& other); // NOLINT(*)
84+
/*! \brief destructor */
85+
inline ~any();
86+
/*!
87+
* \brief assign operator from other
88+
* \param other The other any to be copy or moved.
89+
* \return self
90+
*/
91+
inline any& operator=(any&& other);
92+
/*!
93+
* \brief assign operator from other
94+
* \param other The other any to be copy or moved.
95+
* \return self
96+
*/
97+
inline any& operator=(const any& other);
98+
/*!
99+
* \brief assign operator from any type.
100+
* \param other The other any to be copy or moved.
101+
* \tparam T The value type of other.
102+
* \return self
103+
*/
104+
template<typename T>
105+
inline any& operator=(T&& other);
106+
/*!
107+
* \return whether the container is empty.
108+
*/
109+
inline bool empty() const;
110+
/*!
111+
* \return clear the content of container
112+
*/
113+
inline void clear();
114+
/*!
115+
* swap current content with other
116+
* \param other The other data to be swapped.
117+
*/
118+
inline void swap(any& other); // NOLINT(*)
119+
/*!
120+
* \return The type_info about the stored type.
121+
*/
122+
inline const std::type_info& type() const;
123+
124+
private:
125+
//! \cond Doxygen_Suppress
126+
// declare of helper class
127+
template<typename T>
128+
class TypeOnHeap;
129+
template<typename T>
130+
class TypeOnStack;
131+
template<typename T>
132+
class TypeInfo;
133+
// size of stack space, it takes 32 bytes for one any type.
134+
static const size_t kStack = sizeof(void*) * 3;
135+
static const size_t kAlign = sizeof(void*);
136+
// container use dynamic storage only when space runs lager
137+
union Data {
138+
// stack space
139+
std::aligned_storage<kStack, kAlign>::type stack;
140+
// pointer to heap space
141+
void* pheap;
142+
};
143+
// type specific information
144+
struct Type {
145+
// destructor function
146+
void (*destroy)(Data* data);
147+
// copy constructor
148+
void (*create_from_data)(Data* dst, const Data& src);
149+
// the type info function
150+
const std::type_info* ptype_info;
151+
};
152+
// constant to check if data can be stored on heap.
153+
template<typename T>
154+
struct data_on_stack {
155+
static const bool value = alignof(T) <= kAlign && sizeof(T) <= kStack;
156+
};
157+
// declare friend with
158+
template<typename T>
159+
friend T& get(any& src); // NOLINT(*)
160+
template<typename T>
161+
friend const T& get(const any& src);
162+
// internal construct function
163+
inline void construct(any&& other);
164+
// internal construct function
165+
inline void construct(const any& other);
166+
// internal function to check if type is correct.
167+
template<typename T>
168+
inline void check_type() const;
169+
// internal type specific information
170+
const Type* type_{nullptr};
171+
// internal data
172+
Data data_;
173+
};
174+
175+
template<typename T>
176+
inline any::any(T&& other) {
177+
typedef typename std::decay<T>::type DT;
178+
if (std::is_same<DT, any>::value) {
179+
this->construct(std::forward<T>(other));
180+
} else {
181+
static_assert(std::is_copy_constructible<DT>::value,
182+
"Any can only hold value that is copy constructable");
183+
type_ = TypeInfo<DT>::get_type();
184+
if (data_on_stack<DT>::value) {
185+
new (&(data_.stack)) DT(std::forward<T>(other));
186+
} else {
187+
data_.pheap = new DT(std::forward<T>(other));
188+
}
189+
}
190+
}
191+
192+
inline any::any(any&& other) {
193+
this->construct(std::move(other));
194+
}
195+
196+
inline any::any(const any& other) {
197+
this->construct(other);
198+
}
199+
200+
inline void any::construct(any&& other) {
201+
type_ = other.type_;
202+
data_ = other.data_;
203+
other.type_ = nullptr;
204+
}
205+
206+
inline void any::construct(const any& other) {
207+
type_ = other.type_;
208+
if (type_ != nullptr) {
209+
type_->create_from_data(&data_, other.data_);
210+
}
211+
}
212+
213+
inline any::~any() {
214+
this->clear();
215+
}
216+
217+
inline any& any::operator=(any&& other) {
218+
any(std::move(other)).swap(*this);
219+
return *this;
220+
}
221+
222+
inline any& any::operator=(const any& other) {
223+
any(other).swap(*this);
224+
return *this;
225+
}
226+
227+
template<typename T>
228+
inline any& any::operator=(T&& other) {
229+
any(std::forward<T>(other)).swap(*this);
230+
return *this;
231+
}
232+
233+
inline void any::swap(any& other) { // NOLINT(*)
234+
std::swap(type_, other.type_);
235+
std::swap(data_, other.data_);
236+
}
237+
238+
inline void any::clear() {
239+
if (type_ != nullptr) {
240+
if (type_->destroy != nullptr) {
241+
type_->destroy(&data_);
242+
}
243+
type_ = nullptr;
244+
}
245+
}
246+
247+
inline bool any::empty() const {
248+
return type_ == nullptr;
249+
}
250+
251+
inline const std::type_info& any::type() const {
252+
if (type_ != nullptr) {
253+
return *(type_->ptype_info);
254+
} else {
255+
return typeid(void);
256+
}
257+
}
258+
259+
template<typename T>
260+
inline void any::check_type() const {
261+
CHECK(type_ != nullptr)
262+
<< "The any container is empty";
263+
CHECK(type_->ptype_info == &typeid(T))
264+
<< "The stored type mismatch"
265+
<< " stored=" << type_->ptype_info->name()
266+
<< " requested=" << typeid(T).name();
267+
}
268+
269+
template<typename T>
270+
inline const T& get(const any& src) {
271+
src.check_type<T>();
272+
return *any::TypeInfo<T>::get_ptr(&(src.data_));
273+
}
274+
275+
template<typename T>
276+
inline T& get(any& src) { // NOLINT(*)
277+
src.check_type<T>();
278+
return *any::TypeInfo<T>::get_ptr(&(src.data_));
279+
}
280+
281+
template<typename T>
282+
class any::TypeOnHeap {
283+
public:
284+
inline static T* get_ptr(any::Data* data) {
285+
return static_cast<T*>(data->pheap);
286+
}
287+
inline static const T* get_ptr(const any::Data* data) {
288+
return static_cast<const T*>(data->pheap);
289+
}
290+
inline static void create_from_data(any::Data* dst, const any::Data& data) {
291+
dst->pheap = new T(*get_ptr(&data));
292+
}
293+
inline static void destroy(Data* data) {
294+
delete static_cast<T*>(data->pheap);
295+
}
296+
};
297+
298+
template<typename T>
299+
class any::TypeOnStack {
300+
public:
301+
inline static T* get_ptr(any::Data* data) {
302+
return reinterpret_cast<T*>(&(data->stack));
303+
}
304+
inline static const T* get_ptr(const any::Data* data) {
305+
return reinterpret_cast<const T*>(&(data->stack));
306+
}
307+
inline static void create_from_data(any::Data* dst, const any::Data& data) {
308+
new (&(dst->stack)) T(*get_ptr(&data));
309+
}
310+
inline static void destroy(Data* data) {
311+
T* dptr = reinterpret_cast<T*>(&(data->stack));
312+
dptr->~T();
313+
}
314+
};
315+
316+
template<typename T>
317+
class any::TypeInfo
318+
: public std::conditional<any::data_on_stack<T>::value,
319+
any::TypeOnStack<T>,
320+
any::TypeOnHeap<T> >::type {
321+
public:
322+
inline static const Type* get_type() {
323+
static TypeInfo<T> tp;
324+
return &(tp.type_);
325+
}
326+
327+
private:
328+
// local type
329+
Type type_;
330+
// constructor
331+
TypeInfo() {
332+
if (std::is_pod<T>::value) {
333+
type_.destroy = nullptr;
334+
} else {
335+
type_.destroy = TypeInfo<T>::destroy;
336+
}
337+
type_.create_from_data = TypeInfo<T>::create_from_data;
338+
type_.ptype_info = &typeid(T);
339+
}
340+
};
341+
//! \endcond
342+
343+
} // namespace dmlc
344+
345+
#endif // DMLC_ANY_H_

0 commit comments

Comments
 (0)