file(GLOB_RECURSE SOFT_BACKEND_SOURCES src/*.cpp)
file(GLOB_RECURSE HEADERS "include/*.h")
+set(DEF_CONV src/def2src.cpp)
+
file(GLOB_RECURSE TESTS "src/*.test.cpp")
-list(REMOVE_ITEM SOFT_BACKEND_SOURCES ${TESTS})
+file(GLOB_RECURSE SOFT_DEF_SOURCES include/*.def)
+list(REMOVE_ITEM SOFT_BACKEND_SOURCES ${TESTS} ${DEF_CONV})
+
+# TODO move this macro to common make file
+macro(replace_ext ext dest_list src_list)
+ SET(${dest_list} "")
+ FOREACH(file IN LISTS ${src_list})
+ GET_FILENAME_COMPONENT(file_path ${file} PATH)
+ GET_FILENAME_COMPONENT(file_name ${file} NAME_WE)
+ list(APPEND ${dest_list} "${file_path}/${file_name}/${ext}")
+ ENDFOREACH()
+endmacro()
+
+replace_ext(".h" SOFT_GENERATED_SOURCES SOFT_DEF_SOURCES)
-add_library(soft_backend SHARED ${SOFT_BACKEND_SOURCES})
+add_library(soft_backend SHARED ${SOFT_BACKEND_SOURCES} ${SOFT_GENERATED_SOURCES})
add_nncc_test(nnc_soft_backend_test ${TESTS})
nncc_target_link_libraries(nnc_soft_backend_test nncc_core nnc_core nnc_plugin_core nncc_foundation soft_backend)
target_include_directories(nnc_soft_backend_test PUBLIC include)
+target_include_directories(nnc_soft_backend_test PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+add_executable(def2src ${DEF_CONV})
+
+add_custom_command(
+ OUTPUT ${SOFT_GENERATED_SOURCES}
+ COMMAND def2src ${CMAKE_CURRENT_BINARY_DIR} ${SOFT_DEF_SOURCES}
+ DEPENDS def2src ${SOFT_DEF_SOURCES}
+)
target_link_libraries(soft_backend PRIVATE nncc_core)
target_include_directories(soft_backend PUBLIC include)
+target_include_directories(soft_backend PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(soft_backend PRIVATE nnc_plugin_core)
target_link_libraries(soft_backend PRIVATE nncc_foundation)
-S(const int MAX_DIMS = 8;)
-S()
-S(template<int maxDims>)
-S(class BaseVector)
-S({)
-S(public:)
-S()
-S( BaseVector())
-S( {)
-S( _dims = 0;)
-S( _volume = 0;)
-S( })
-S()
-S( template <class T>)
-S( BaseVector(std::initializer_list<T> data): _dims(data.size()))
-S( {)
-S( assert(_dims <= maxDims);)
-S( size_t *dataPtr = _data;)
-S( for (T value: data))
-S( {)
-S( *dataPtr++ = static_cast<size_t>(value);)
-S( _volume *= static_cast<size_t>(value);)
-S( })
-S( })
-S()
-S( BaseVector(const BaseVector &orig): _dims(orig._dims), _volume(orig._volume))
-S( {)
-S( for (int i = 0; i < _dims; ++i))
-S( _data[i] = orig._data[i];)
-S( })
-S()
-S( BaseVector &operator=(const BaseVector &orig))
-S( {)
-S( _dims = orig._dims;)
-S( _volume = orig._volume;)
-S( for (int i = 0; i < _dims; ++i))
-S( _data[i] = orig._data[i];)
-S( return *this;)
-S( })
-S()
-S( void change(std::initializer_list<size_t> data))
-S( {)
-S( _dims = data.size();)
-S( assert(_dims <= maxDims);)
-S( _volume = 1;)
-S( size_t *dataPtr = _data;)
-S( for (size_t value: data))
-S( {)
-S( *dataPtr++ = value;)
-S( _volume *= value;)
-S( })
-S( })
-S()
-S( int dims() const)
-S( {)
-S( return _dims;)
-S( })
-S()
-S( size_t operator[](int dim) const)
-S( {)
-S( assert(dim < _dims);)
-S( return _data[dim];)
-S( })
-S()
-S( size_t getVolume() const)
-S( {)
-S( return _volume;)
-S( })
-S()
-S(private:)
-S( size_t _data[maxDims];)
-S( int _dims;)
-S( size_t _volume = 1;)
-S(};)
-S()
-S(using Shape = BaseVector<MAX_DIMS>;)
-S()
-S(using Index = BaseVector<MAX_DIMS>;)
-S()
-S(class Tensor)
-S({)
-S(public:)
-S( Tensor(): _shape(), _data(nullptr), _managed(true){})
-S()
-S( Tensor(const Shape& shape, float *data): _shape(shape), _data(data){})
-S()
-S( Tensor(const Shape& shape): _shape(shape), _data(new float[shape.getVolume()]), _managed(true) {})
-S()
-S( ~Tensor())
-S( {)
-S( if (_managed))
-S( delete [] _data;)
-S( })
-S()
-S( void fillData(const float *data))
-S( {)
-S( assert(_managed);)
-S( for (int i = 0; i < _shape.getVolume(); ++i))
-S( _data[i] = data[i];)
-S( })
-S()
-S( Tensor &operator=(const Tensor &t))
-S( {)
-S( assert(_managed);)
-S( if (this != &t))
-S( {)
-S( reShape(t.getShape());)
-S( fillData(t._data);)
-S( })
-S( return *this;)
-S( })
-S()
-S( float &at(const Index &idx))
-S( {)
-S( return *(_data + getOffset(idx));)
-S( })
-S()
-S( float at(const Index &idx) const)
-S( {)
-S( return *(_data + getOffset(idx));)
-S( })
-S()
-S( void reShape(const Shape &shape))
-S( {)
-S( size_t oldVolume = _shape.getVolume();)
-S( _shape = shape;)
-S( if (_managed && oldVolume != shape.getVolume()))
-S( {)
-S( delete [] _data;)
-S( _data = new float[shape.getVolume()];)
-S( })
-S( })
-S()
-S( const Shape &getShape() const)
-S( {)
-S( return _shape;)
-S( })
-S()
-S(private:)
-S( size_t getOffset(const Index &idx) const)
-S( {)
-S( assert(idx.dims() == _shape.dims());)
-S( size_t offset = 0;)
-S( size_t stride = 1;)
-S( for (int i = _shape.dims() - 1; i >= 0; --i))
-S( {)
-S( assert(idx[i] < _shape[i]);)
-S( offset += stride * idx[i];)
-S( stride *= _shape[i];)
-S( })
-S( return offset;)
-S( })
-S()
-S( Shape _shape;)
-S( float *_data;)
-S( bool _managed = false;)
-S(};)
+const int MAX_DIMS = 8;
+
+template<int maxDims>
+class BaseVector
+{
+public:
+
+ BaseVector()
+ {
+ _dims = 0;
+ _volume = 0;
+ }
+
+ template <class T>
+ BaseVector(std::initializer_list<T> data): _dims(data.size())
+ {
+ assert(_dims <= maxDims);
+ size_t *dataPtr = _data;
+ for (T value: data)
+ {
+ *dataPtr++ = static_cast<size_t>(value);
+ _volume *= static_cast<size_t>(value);
+ }
+ }
+
+ BaseVector(const BaseVector &orig): _dims(orig._dims), _volume(orig._volume)
+ {
+ for (int i = 0; i < _dims; ++i)
+ _data[i] = orig._data[i];
+ }
+
+ BaseVector &operator=(const BaseVector &orig)
+ {
+ _dims = orig._dims;
+ _volume = orig._volume;
+ for (int i = 0; i < _dims; ++i)
+ _data[i] = orig._data[i];
+ return *this;
+ }
+
+ void change(std::initializer_list<size_t> data)
+ {
+ _dims = data.size();
+ assert(_dims <= maxDims);
+ _volume = 1;
+ size_t *dataPtr = _data;
+ for (size_t value: data)
+ {
+ *dataPtr++ = value;
+ _volume *= value;
+ }
+ }
+
+ int dims() const
+ {
+ return _dims;
+ }
+
+ size_t operator[](int dim) const
+ {
+ assert(dim < _dims);
+ return _data[dim];
+ }
+
+ size_t getVolume() const
+ {
+ return _volume;
+ }
+
+private:
+ size_t _data[maxDims];
+ int _dims;
+ size_t _volume = 1;
+};
+
+using Shape = BaseVector<MAX_DIMS>;
+
+using Index = BaseVector<MAX_DIMS>;
+
+class Tensor
+{
+public:
+ Tensor(): _shape(), _data(nullptr), _managed(true){}
+
+ Tensor(const Shape& shape, float *data): _shape(shape), _data(data){}
+
+ Tensor(const Shape& shape): _shape(shape), _data(new float[shape.getVolume()]), _managed(true) {}
+
+ ~Tensor()
+ {
+ if (_managed)
+ delete [] _data;
+ }
+
+ void fillData(const float *data)
+ {
+ assert(_managed);
+ for (int i = 0; i < _shape.getVolume(); ++i)
+ _data[i] = data[i];
+ }
+
+ Tensor &operator=(const Tensor &t)
+ {
+ assert(_managed);
+ if (this != &t)
+ {
+ reShape(t.getShape());
+ fillData(t._data);
+ }
+ return *this;
+ }
+
+ float &at(const Index &idx)
+ {
+ return *(_data + getOffset(idx));
+ }
+
+ float at(const Index &idx) const
+ {
+ return *(_data + getOffset(idx));
+ }
+
+ void reShape(const Shape &shape)
+ {
+ size_t oldVolume = _shape.getVolume();
+ _shape = shape;
+ if (_managed && oldVolume != shape.getVolume())
+ {
+ delete [] _data;
+ _data = new float[shape.getVolume()];
+ }
+ }
+
+ const Shape &getShape() const
+ {
+ return _shape;
+ }
+
+private:
+ size_t getOffset(const Index &idx) const
+ {
+ assert(idx.dims() == _shape.dims());
+ size_t offset = 0;
+ size_t stride = 1;
+ for (int i = _shape.dims() - 1; i >= 0; --i)
+ {
+ assert(idx[i] < _shape[i]);
+ offset += stride * idx[i];
+ stride *= _shape[i];
+ }
+ return offset;
+ }
+
+ Shape _shape;
+ float *_data;
+ bool _managed = false;
+};
--- /dev/null
+#include <iostream>
+#include <fstream>
+
+int fileToArray(std::string &source, std::string &dest, std::string arrName) {
+ FILE *fs = fopen(source.c_str(), "rb");
+ if (!fs) {
+ std::cerr << "source file not found: <" << source << ">" << std::endl;
+ return -1;
+ }
+
+ std::ofstream fo(dest.c_str());
+ if (fo.fail()) {
+ std::cerr << "cannot generate file: <" << dest << ">" << std::endl;
+ fclose(fs);
+ return -1;
+ }
+
+ std::cout << "generating <" << dest << ">" << std::endl;
+
+ fo << "const char " << arrName << "[] = {" << std::endl;
+
+ fseek(fs, 0, SEEK_SET);
+ size_t bytes;
+ do {
+ char buf[1024];
+ bytes = fread(buf, 1, sizeof(buf), fs);
+
+ // convert line
+ for (size_t i = 0; i < bytes; i++) {
+ fo << "0x" << std::hex << (int)buf[i] << ", ";
+ }
+ } while (bytes != 0);
+
+ fo << "};" << std::endl;
+ fo.flush();
+ fclose(fs);
+
+ return 0;
+}
+
+std::string extractFileName(std::string path)
+{
+ auto pos = path.find_last_of('/');
+ if (pos != std::string::npos)
+ path = path.substr(pos + 1);
+
+ pos = path.find_first_of('.');
+ if (pos != std::string::npos)
+ path = path.substr(0, pos);
+
+ return path;
+}
+
+int main(int argc, char *argv[]) {
+ if (argc < 3)
+ return -1;
+
+ std::string OutPutDir = argv[1];
+
+ for (int i = 2; i < argc; i++) {
+ std::string sourceFullFileName = argv[i];
+ std::string filename = extractFileName(sourceFullFileName);
+ std::string outputFileName = OutPutDir + "/" + filename + ".h";
+
+ if (fileToArray(sourceFullFileName, outputFileName, filename) != 0)
+ return -1;
+ }
+
+ return 0;
+}