Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
tic
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wenyuanbo
tic
Commits
cf0ef48b
Commit
cf0ef48b
authored
Jul 04, 2016
by
tqchen
Committed by
Tianqi Chen
May 29, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add TShape and Tuple to nngraph
parent
66b9ef23
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
395 additions
and
19 deletions
+395
-19
nnvm/include/nngraph/graph.h
+6
-17
nnvm/include/nngraph/node.h
+20
-1
nnvm/include/nngraph/tuple.h
+334
-0
nnvm/src/core/node.cc
+7
-0
nnvm/src/test_main.cc
+28
-1
No files found.
nnvm/include/nngraph/graph.h
View file @
cf0ef48b
...
...
@@ -7,6 +7,8 @@
#define NNGRAPH_GRAPH_H_
#include <vector>
#include <string>
#include <unordered_map>
#include "./node.h"
namespace
nngraph
{
...
...
@@ -16,23 +18,10 @@ namespace nngraph {
*/
class
Graph
{
public
:
/*!
* \brief get the index th element from the returned tuple.
* \param index index of multi output
* \return the symbol corresponds to the indexed element.
*/
Graph
operator
[]
(
size_t
index
)
const
;
/*!
* \brief get number of outputs of this symbol
* \return number of outputs
*/
inline
size_t
outputs_size
()
const
{
return
outputs_
.
size
();
}
private
:
/*! \brief outputs of the graph. */
std
::
vector
<
NodeEntry
>
outputs_
;
/*! \brief outputs of the computation graph. */
std
::
vector
<
NodeEntry
>
outputs
;
/*! \brief attributes of a graph */
std
::
unordered_map
<
std
::
string
,
any
>
attrs
;
};
}
// namespace nngraph
...
...
nnvm/include/nngraph/node.h
View file @
cf0ef48b
...
...
@@ -47,21 +47,40 @@ class Node {
public
:
/*! \brief name of the node */
std
::
string
name
;
/*! \brief the operator this node is pointing at */
/*!
* \brief The operator this node uses.
* For place holder variable, op == nullptr.
*/
const
Op
*
op
;
/*! \brief inputs to this node */
std
::
vector
<
NodeEntry
>
inputs
;
/*!
* \brief Optional control flow dependencies
* Gives operation must be performed before this operation.
*/
std
::
vector
<
std
::
shared_ptr
<
Node
>
>
control_deps
;
/*! \brief The attributes in the node. */
NodeAttrs
attrs
;
/*! \brief destructor of node */
~
Node
();
/*!
* \brief return whether node is placeholder variable.
* This is equivalent to op == nullptr
* \return whether node is placeholder input variable
*/
inline
bool
is_variable
()
const
;
/*!
* \brief create a new empty shared_ptr of Node.
* \return a created empty node.
*/
static
std
::
shared_ptr
<
Node
>
Create
();
};
// implementation of functions.
inline
bool
Node
::
is_variable
()
const
{
return
this
->
op
==
nullptr
;
}
}
// namespace nngraph
#endif // NNGRAPH_NODE_H_
nnvm/include/nngraph/tuple.h
0 → 100644
View file @
cf0ef48b
/*!
* Copyright (c) 2016 by Contributors
* \file tuple.h
* \brief Data structure Tuple and TShape to store dynamic sized shapes.
*/
#ifndef NNGRAPH_TUPLE_H_
#define NNGRAPH_TUPLE_H_
#include <vector>
#include <type_traits>
#include <algorithm>
#include <iostream>
namespace
nngraph
{
/*! \brief data type to store array index */
typedef
uint32_t
index_t
;
/*!
* \brief A dynamic sized array data strcuture
* that is optimized for storing small number of elements with same type.
* Data will be stored in stack when number of elements is small.
*
* It is suitable to hold Shape of Tensor.
*
* \tparam ValueType The type of data stored inside tuple.
* \sa TShape
*/
template
<
typename
ValueType
>
class
Tuple
{
public
:
// Tuple requires the content to be simple data type.
static_assert
(
std
::
is_pod
<
ValueType
>::
value
,
"Tuple only support simple data type like int"
);
/*! \brief default constructor */
Tuple
()
=
default
;
/*! \brief destructor */
inline
~
Tuple
()
{
delete
[]
data_heap_
;
}
/*!
* \brief copy constructor from another tuple
* \param s the source tuple
*/
inline
Tuple
(
const
Tuple
<
ValueType
>&
s
)
{
this
->
assign
(
s
.
begin
(),
s
.
end
());
}
/*!
* \brief constructor from initializer list
* \param init the initializer_list
*/
inline
Tuple
(
std
::
initializer_list
<
ValueType
>
init
)
{
this
->
assign
(
init
.
begin
(),
init
.
end
());
}
/*!
* \brief move constructor from Tuple
* \param src the source shape
*/
inline
Tuple
(
Tuple
<
ValueType
>&&
src
)
{
this
->
swap
(
src
);
}
/*!
* \brief construct an Tuple to fill the value with v.
* \param ndim the number of dimension of the Tuple
* \param v The value to fill.
*/
inline
Tuple
(
index_t
ndim
,
ValueType
v
)
{
this
->
SetDim
(
ndim
);
std
::
fill_n
(
begin
(),
ndim
,
v
);
}
/*!
* \brief construct the Tuple from content of iterator
* \param begin the beginning of iterator
* \param end end the end of the iterator
* \tparam RandomAccessIterator iterator type
*/
template
<
typename
RandomAccessIterator
>
inline
Tuple
(
RandomAccessIterator
begin
,
RandomAccessIterator
end
)
{
this
->
assign
(
begin
,
end
);
}
/*!
* \brief Assign content to tuple from iterator.
* \param begin the beginning of iteratro
* \param end end the end of the iterator
* \tparam RandomAccessIterator iterator type
*/
template
<
typename
RandomAccessIterator
>
inline
void
assign
(
RandomAccessIterator
begin
,
RandomAccessIterator
end
)
{
this
->
SetDim
(
end
-
begin
);
std
::
copy
(
begin
,
end
,
this
->
begin
());
}
/*!
* \brief Swap current object with other
* \param other another object to be swapped.
*/
inline
void
swap
(
Tuple
<
ValueType
>&
other
)
noexcept
{
// NOLINT(*)
std
::
swap
(
ndim_
,
other
.
ndim_
);
std
::
swap
(
num_heap_allocated_
,
other
.
num_heap_allocated_
);
std
::
swap
(
data_stack_
,
other
.
data_stack_
);
std
::
swap
(
data_heap_
,
other
.
data_heap_
);
}
/*!
* \brief assignment from another tuple.
* \param src source tuple
* \return reference of self
*/
inline
Tuple
<
ValueType
>&
operator
=
(
const
Tuple
<
ValueType
>&
src
)
{
this
->
assign
(
src
.
begin
(),
src
.
end
());
return
*
this
;
}
/*!
* \brief assignment from rvalue of another tuple.
* \param src source tuple
* \return reference of self
*/
inline
Tuple
<
ValueType
>&
operator
=
(
Tuple
<
ValueType
>&&
src
)
{
Tuple
<
ValueType
>
(
std
::
move
(
src
)).
swap
(
*
this
);
return
*
this
;
}
/*!
* \brief assignment from initializer list
* \param init the source initializer list
* \return reference of self
*/
inline
Tuple
<
ValueType
>
&
operator
=
(
std
::
initializer_list
<
ValueType
>
init
)
{
this
->
assign
(
init
.
begin
(),
init
.
end
());
return
*
this
;
}
/*!
* \return whether two tuple equals
* \param s the tuple to compare against
*/
inline
bool
operator
==
(
const
Tuple
<
ValueType
>
&
s
)
const
{
if
(
ndim_
!=
s
.
ndim_
)
return
false
;
return
std
::
equal
(
begin
(),
end
(),
s
.
begin
());
}
/*!
* \return whether two tuple not equal
* \param s the tuple to compare against
*/
inline
bool
operator
!=
(
const
Tuple
<
ValueType
>
&
s
)
const
{
return
!
(
*
this
==
s
);
}
/*! \return the begin data pointer to content of the tuple */
inline
const
ValueType
*
begin
()
const
{
return
ndim_
<=
kStackCache
?
data_stack_
:
data_heap_
;
}
/*! \return the begin data pointer to content of the tuple */
inline
ValueType
*
begin
()
{
return
ndim_
<=
kStackCache
?
data_stack_
:
data_heap_
;
}
/*! \return the data pointer to end of the tuple */
inline
const
ValueType
*
end
()
const
{
return
ndim_
<=
kStackCache
?
(
data_stack_
+
ndim_
)
:
(
data_heap_
+
ndim_
);
}
/*! \return the data pointer to end the tuple */
inline
ValueType
*
end
()
{
return
ndim_
<=
kStackCache
?
(
data_stack_
+
ndim_
)
:
(
data_heap_
+
ndim_
);
}
/*! \return number of dimension of the tuple */
inline
index_t
ndim
()
const
{
return
ndim_
;
}
/*!
* \brief get corresponding index
* \param i dimension index
* \return the corresponding dimension size
*/
inline
ValueType
&
operator
[](
index_t
i
)
{
return
begin
()[
i
];
}
/*!
* \brief get corresponding index
* \param i dimension index
* \return the corresponding dimension size
*/
inline
const
ValueType
&
operator
[](
index_t
i
)
const
{
return
begin
()[
i
];
}
/*!
* \brief allow output string of tuple to ostream
* \param os the output stream
* \param t the tuple
* \return the ostream
*/
friend
std
::
ostream
&
operator
<<
(
std
::
ostream
&
os
,
const
Tuple
<
ValueType
>
&
t
)
{
os
<<
'('
;
const
ValueType
*
begin
=
t
.
begin
();
const
ValueType
*
end
=
t
.
end
();
for
(
const
ValueType
*
it
=
begin
;
it
!=
end
;
++
it
)
{
if
(
it
!=
begin
)
os
<<
','
;
os
<<
*
it
;
}
// python style tuple
if
(
t
.
ndim
()
==
1
)
os
<<
','
;
os
<<
')'
;
return
os
;
}
/*!
* \brief read tuple from the istream
* \param is the input stream
* \param t The tuple
* \return the istream
*/
friend
std
::
istream
&
operator
>>
(
std
::
istream
&
is
,
Tuple
<
ValueType
>
&
t
)
{
// get (
while
(
true
)
{
char
ch
=
is
.
peek
();
if
(
isdigit
(
ch
))
{
ValueType
idx
;
if
(
is
>>
idx
)
{
t
.
assign
(
&
idx
,
&
idx
+
1
);
}
return
is
;
}
is
.
get
();
if
(
ch
==
'('
)
break
;
if
(
!
isspace
(
ch
))
{
is
.
setstate
(
std
::
ios
::
failbit
);
return
is
;
}
}
index_t
idx
;
std
::
vector
<
ValueType
>
tmp
;
while
(
is
>>
idx
)
{
tmp
.
push_back
(
idx
);
char
ch
;
do
{
ch
=
is
.
get
();
}
while
(
isspace
(
ch
));
if
(
std
::
is_integral
<
ValueType
>::
value
&&
ch
==
'L'
)
{
ch
=
is
.
get
();
}
if
(
ch
==
','
)
{
while
(
true
)
{
ch
=
is
.
peek
();
if
(
isspace
(
ch
))
{
is
.
get
();
continue
;
}
if
(
ch
==
')'
)
{
is
.
get
();
break
;
}
break
;
}
if
(
ch
==
')'
)
break
;
}
else
if
(
ch
==
')'
)
{
break
;
}
else
{
is
.
setstate
(
std
::
ios
::
failbit
);
return
is
;
}
}
t
.
assign
(
tmp
.
begin
(),
tmp
.
end
());
return
is
;
}
private
:
// stack cache size
static
const
uint32_t
kStackCache
=
4
;
/*! \brief number of dimension of the tuple */
index_t
ndim_
{
0
};
/*! \brief number of cells allocated in data_heap_ */
index_t
num_heap_allocated_
{
0
};
/*! \brief in stack space used to store shape when it is small */
ValueType
data_stack_
[
kStackCache
];
/*! \brief space to store shape when dimension is big*/
ValueType
*
data_heap_
{
nullptr
};
// internal function to change the dimension
inline
void
SetDim
(
index_t
dim
)
{
if
(
dim
>
kStackCache
&&
dim
>
num_heap_allocated_
)
{
delete
[]
data_heap_
;
data_heap_
=
new
ValueType
[
dim
];
num_heap_allocated_
=
dim
;
}
ndim_
=
dim
;
}
};
/*!
* \brief A Shape class that is used to represent shape of each tensor.
*/
class
TShape
:
public
Tuple
<
index_t
>
{
public
:
// inheritate other constructors from Tuple
using
Tuple
<
index_t
>::
Tuple
;
/*!
* \brief copy constructor of TShape
* \param s source shape.
*/
inline
TShape
(
const
Tuple
<
index_t
>&
s
)
// NOLINT(*)
:
Tuple
<
index_t
>
(
s
)
{}
/*!
* \brief move constructor.
* \param s source shape.
*/
inline
TShape
(
Tuple
<
index_t
>&&
s
)
{
// NOLINT(*)
this
->
swap
(
s
);
}
/*!
* \brief assignment function from tshape
* \param src source shape.
* \return self.
*/
inline
TShape
&
operator
=
(
const
Tuple
<
index_t
>&
src
)
{
this
->
assign
(
src
.
begin
(),
src
.
end
());
return
*
this
;
}
/*!
* \brief move assignment function from tshape
* \param src source shape.
* \return self.
*/
inline
TShape
&
operator
=
(
Tuple
<
index_t
>&&
src
)
{
// NOLINT(*)
TShape
(
std
::
move
(
src
)).
swap
(
*
this
);
// NOLINT(*)
return
*
this
;
}
/*! \return total number of elements in the shape */
inline
size_t
Size
()
const
{
size_t
size
=
1
;
const
index_t
*
start
=
begin
(),
*
fin
=
end
();
for
(
const
index_t
*
it
=
start
;
it
!=
fin
;
++
it
)
{
size
*=
*
it
;
}
return
size
;
}
};
}
// namespace nngraph
#endif // NNGRAPH_TUPLE_H_
nnvm/src/core/node.cc
View file @
cf0ef48b
...
...
@@ -24,6 +24,13 @@ Node::~Node() {
e
.
node
.
reset
();
}
}
for
(
std
::
shared_ptr
<
Node
>&
sp
:
n
->
control_deps
)
{
if
(
sp
.
unique
())
{
stack
.
push_back
(
sp
.
get
());
}
else
{
sp
.
reset
();
}
}
n
->
inputs
.
clear
();
}
}
...
...
nnvm/src/test_main.cc
View file @
cf0ef48b
// Copyright (c) 2016 by Contributors
#include <nngraph/op.h>
#include <nngraph/graph.h>
#include <nngraph/tuple.h>
#include <string>
int
main
()
{
void
test_op
()
{
using
namespace
nngraph
;
auto
add
=
Op
::
Get
(
"add"
);
auto
nick
=
Op
::
GetAttr
<
std
::
string
>
(
"nick_name"
);
LOG
(
INFO
)
<<
"nick="
<<
nick
[
add
];
}
void
test_tuple
()
{
using
nngraph
::
Tuple
;
using
nngraph
::
TShape
;
Tuple
<
int
>
x
{
1
,
2
,
3
};
Tuple
<
int
>
y
{
1
,
2
,
3
,
5
,
6
};
x
=
std
::
move
(
y
);
CHECK_EQ
(
x
.
ndim
(),
5
);
Tuple
<
int
>
z
{
1
,
2
,
3
,
5
,
6
};
std
::
ostringstream
os
;
os
<<
z
;
CHECK_EQ
(
os
.
str
(),
"(1,2,3,5,6)"
);
std
::
istringstream
is
(
os
.
str
());
is
>>
y
;
CHECK_EQ
(
x
,
y
);
Tuple
<
nngraph
::
index_t
>
ss
{
1
,
2
,
3
};
TShape
s
=
ss
;
s
=
std
::
move
(
ss
);
CHECK
((
s
==
TShape
{
1
,
2
,
3
}));
}
int
main
()
{
test_tuple
();
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment