From: 박종현/동작제어Lab(SR)/Senior Engineer/삼성전자 Date: Thu, 5 Apr 2018 01:53:39 +0000 (+0900) Subject: Introduce 'nnfw::util::tensor' namespace (#440) X-Git-Tag: 0.1~431 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8c1f357193279b515b087d8740943ad942cfc9b1;p=platform%2Fcore%2Fml%2Fnnfw.git Introduce 'nnfw::util::tensor' namespace (#440) This commit introduces 'nnfw::util::tensor' namespace which will include various helpers for tensor (ND-array) object. Currently, 'nnfw::util::tensor' namespace includes the following classes and funtiont: - class Index - class Shape - class IndexIterator - method iterate Signed-off-by: Jonghyun Park --- diff --git a/include/util/tensor/Index.h b/include/util/tensor/Index.h new file mode 100644 index 0000000..d620483 --- /dev/null +++ b/include/util/tensor/Index.h @@ -0,0 +1,46 @@ +#ifndef __NNFW_UTIL_TENSOR_INDEX_H__ +#define __NNFW_UTIL_TENSOR_INDEX_H__ + +#include +#include + +#include +#include + +namespace nnfw +{ +namespace util +{ +namespace tensor +{ + +struct Index +{ +public: + Index(size_t rank) + { + _offsets.resize(rank); + } + +public: + Index(std::initializer_list offsets) : _offsets{offsets} + { + // DO NOTHING + } + +public: + size_t rank(void) const { return _offsets.size(); } + +public: + int32_t at(size_t n) const { return _offsets.at(n); } + int32_t &at(size_t n) { return _offsets.at(n); } + +private: + std::vector _offsets; +}; + +} // namespace tensor +} // namespace util +} // namespace nnfw + +#endif // __NNFW_UTIL_TENSOR_INDEX_H__ diff --git a/include/util/tensor/IndexIterator.h b/include/util/tensor/IndexIterator.h new file mode 100644 index 0000000..61c23cb --- /dev/null +++ b/include/util/tensor/IndexIterator.h @@ -0,0 +1,88 @@ +#ifndef __NNFW_UTIL_TENSOR_INDEX_ITERATOR_H__ +#define __NNFW_UTIL_TENSOR_INDEX_ITERATOR_H__ + +#include "util/tensor/Shape.h" +#include "util/tensor/Index.h" + +namespace nnfw +{ +namespace util +{ +namespace tensor +{ + +class IndexIterator +{ +public: + IndexIterator(const Shape &shape) : _shape(shape) + { + // DO NOTHING + } + +public: + // Allow move, but disallow copy + IndexIterator(IndexIterator &&) = default; + IndexIterator(const IndexIterator &) = delete; + +public: + template IndexIterator &iter(Callable fn) + { + Index index(_shape.rank()); + + for (size_t d = 0; d < _shape.rank(); ++d) + { + index.at(d) = 0; + } + + size_t cursor = 0; + + while (cursor < _shape.rank()) + { + fn(index); + + if (index.at(cursor) + 1 < _shape.dim(cursor)) + { + index.at(cursor) += 1; + } + else + { + while ((cursor < _shape.rank()) && (index.at(cursor) + 1 == _shape.dim(cursor))) + { + ++cursor; + } + + if (cursor == _shape.rank()) + { + break; + } + + index.at(cursor) += 1; + + for (size_t d = 0; d < cursor; ++d) + { + index.at(d) = 0; + } + + cursor = 0; + } + } + + return (*this); + } + +private: + const Shape &_shape; +}; + +IndexIterator iterate(const Shape &shape) { return IndexIterator{shape}; } + +template IndexIterator &operator<<(IndexIterator &&it, Callable cb) +{ + return it.iter(cb); +} + +} // namespace tensor +} // namespace util +} // namespace nnfw + +#endif // __NNFW_UTIL_TENSOR_INDEX_ITERATOR_H__ diff --git a/include/util/tensor/Shape.h b/include/util/tensor/Shape.h new file mode 100644 index 0000000..3211952 --- /dev/null +++ b/include/util/tensor/Shape.h @@ -0,0 +1,45 @@ +#ifndef __NNFW_UTIL_TENSOR_SHAPE_H__ +#define __NNFW_UTIL_TENSOR_SHAPE_H__ + +#include +#include +#include +#include + +namespace nnfw +{ +namespace util +{ +namespace tensor +{ + +class Shape +{ +public: + Shape(size_t rank) + { + _dimensions.resize(rank); + } + +public: + Shape(const std::initializer_list &dimensions) : _dimensions{dimensions} + { + // DO NOTHING + } + +public: + size_t rank(void) const { return _dimensions.size(); } + +public: + int32_t dim(size_t n) const { return _dimensions.at(n); } + int32_t &dim(size_t n) { return _dimensions.at(n); } + +private: + std::vector _dimensions; +}; + +} // namespace tensor +} // namespace util +} // namespace nnfw + +#endif // __NNFW_UTIL_TENSOR_SHAPE_H__ diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 2427766..3725781 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -9,3 +9,6 @@ target_include_directories(nnfw_util PUBLIC ${NNFW_INCLUDE_DIR}) install(TARGETS nnfw_util RUNTIME DESTINATION bin COMPONENT libraries LIBRARY DESTINATION lib COMPONENT libraries) + +add_executable(nnfw_util_tensor_index_iterator "examples/tensor_index_iterator.cpp") +target_link_libraries(nnfw_util_tensor_index_iterator nnfw_util) diff --git a/src/util/examples/tensor_index_iterator.cpp b/src/util/examples/tensor_index_iterator.cpp new file mode 100644 index 0000000..b5358e3 --- /dev/null +++ b/src/util/examples/tensor_index_iterator.cpp @@ -0,0 +1,22 @@ +#include "util/tensor/IndexIterator.h" + +#include + +int main(int argc, char **argv) +{ + nnfw::util::tensor::Shape shape{3, 4, 3, 4}; + + std::cout << "Iterate over tensor{3, 4, 3, 4}" << std::endl; + + nnfw::util::tensor::iterate(shape) << [] (const nnfw::util::tensor::Index &index) + { + std::cout << "rank: " << index.rank() << std::endl; + + for (size_t d = 0; d < index.rank(); ++d) + { + std::cout << " offset(" << d << ") = " << index.at(d) << std::endl; + } + }; + + return 0; +}