ソースを参照

add apply and reduce

JasonWang 7 年 前
コミット
73af5ff112

+ 25 - 16
traph/include/traph/core/tensor.h

@@ -2,6 +2,7 @@
 #define TRAPH_CORE_TENSOR_H_
 
 #include <algorithm>
+#include <functional>
 
 #include <traph/core/type.h>
 #include <traph/core/index.h>
@@ -10,37 +11,45 @@
 namespace traph
 {
     template<class T>
-    class ContiguousStorageBase
+    class StorageBase
     {
     public:
-        virtual idx_type size() const = 0;
         virtual size_type element_size() const = 0;
+        virtual void fill_(T v) = 0;
+        virtual void resize_(idx_type size) = 0;
+        virtual idx_type size() const = 0;
+
+    };
 
+    template<class T>
+    class ContiguousStorageBase: public StorageBase<T>
+    {
+    public:
+        virtual size_type element_size() const = 0;
+        virtual void fill_(T v) = 0;
         virtual void resize_(idx_type size) = 0;
+        virtual idx_type size() const = 0;
     };
 
     template<class T>
     class TensorBase
     {
     public:
-        virtual platform_type platform() = 0;
-
+        virtual void apply_(std::function<T(T)> f) = 0;
+        virtual void cos_() = 0;
         virtual device_id device() = 0;
-
+        virtual void fill_(T value) = 0;
+        virtual idx_type offset() const = 0;
+		virtual layout_type order() const = 0;
+        virtual platform_type platform() = 0;
+        virtual T reduce_(std::function<T(T,T)> f) const = 0;
         virtual void reshape(const DimVector& dims) = 0;
-
         virtual void resize(const DimVector& dims) = 0;
-
-		virtual idx_type offset() const = 0;
-
-		virtual layout_type layout() const = 0;
-
+        virtual void sin_() = 0;
 		virtual DimVector size() const = 0;
-
-		virtual const T* data() const = 0;
-		virtual T* data() = 0;
-
-		virtual DimVector strides() const = 0;
+        virtual StorageBase<T>& storage() const = 0;
+		virtual DimVector stride() const = 0;
+        virtual T sum() const = 0;
     };
 
     template<class T>

+ 7 - 1
traph/include/traph/core/variable.h

@@ -1,6 +1,8 @@
 #ifndef TRAPH_CORE_VARIABLE_H_
 #define TRAPH_CORE_VARIABLE_H_
 
+#include <traph/core/type.h>
+#include <traph/core/tensor.h>
 
 namespace traph
 {
@@ -11,7 +13,11 @@ namespace traph
         virtual platform_type platform() = 0;
 
         virtual device_id device() = 0;
-        
+
+        virtual TensorBase<T> * tensor_data() = 0;
+
+        virtual TensorBase<T> * tensor_grad() = 0;
+
         virtual void reshape(const DimVector& dims) = 0;
 
         virtual void resize(const DimVector& dims) = 0;

+ 16 - 0
traph/include/traph/nn/arithmetic.h

@@ -7,11 +7,27 @@
 #include <traph/core/type.h>
 #include <traph/core/index.h>
 #include <traph/core/utils.h>
+#include <traph/core/variable.h>
 #include <traph/tensor/tensor.h>
+#include <traph/nn/variable.h>
 
 namespace traph
 {
+    template<class T>
+	Variable<T> abs(const Variable<T> &t)
+    {
+        Variable<T> result;
+        // operator
+        TensorBase<T> * base = t.tensor_data();
+        if(t.platform() == platform_type::none)
+        {
+            Tensor<T> * down = dynamic_cast<Tensor<T> *>(base);
+            abs(*down);
+        }
+        
+        // record
 
+    }
 
 }
 

+ 46 - 0
traph/include/traph/nn/operation.h

@@ -0,0 +1,46 @@
+#ifndef TRAPH_NN_OPERATION_H_
+#define TRAPH_NN_OPERATION_H_
+
+#include <utility>
+#include <cmath>
+#include <string>
+
+#include <traph/core/type.h>
+#include <traph/core/index.h>
+#include <traph/core/utils.h>
+#include <traph/core/variable.h>
+#include <traph/tensor/tensor.h>
+#include <traph/nn/variable.h>
+
+namespace traph
+{
+    template<class T>
+    class OperationBase
+    {
+    public:
+        virtual name() = 0;
+    };
+
+    template<class T>
+    class OperationOneParam
+    {
+    public:
+        virtual name() = 0;
+    };
+
+    template<class T>
+    class OperationTwoParam
+    {
+    public:
+        virtual name() = 0;
+    };
+
+    template<class T>
+    class OperationThreeParam
+    {
+    public:
+        virtual name() = 0;
+    };
+}
+
+#endif

+ 23 - 2
traph/include/traph/nn/variable.h

@@ -20,17 +20,18 @@ namespace traph
         bool _requires_grad;
     public:
         Variable()
+            :_data(new Tensor<T>), _grad(nullptr), _requires_grad(false)
         {
 
         }
 
         Variable(const DimVector& dim)
-            :_data(new Tensor<T>(dim)), _grad(new Tensor<T>(dim)), _requires_grad(false)
+            :_data(new Tensor<T>(dim)), _grad(nullptr), _requires_grad(false)
         {
         }
 
         Variable(std::initializer_list<idx_type> l)
-            :_data(new Tensor<T>()), _grad(new Tensor<T>()), _requires_grad(false)
+            :_data(new Tensor<T>()), _grad(nullptr), _requires_grad(false)
         {
             DimVector dim;
             for (auto i : l)
@@ -45,6 +46,26 @@ namespace traph
 
         }
 
+        virtual platform_type platform() override
+        {
+            return _data->platform();
+        }
+
+        virtual device_id device() override
+        {
+            return _data->device();
+        }
+
+        virtual TensorBase<T> * tensor_data() override
+        {
+            return _data.get();
+        }
+
+        virtual TensorBase<T> * tensor_grad() override
+        {
+            return _grad.get();
+        }
+
         virtual void reshape(const DimVector& dims) override
         {
 

+ 74 - 160
traph/include/traph/tensor/tensor.h

@@ -3,6 +3,7 @@
 
 #include <initializer_list>
 #include <cmath>
+#include <functional>
 
 
 #include<traph/core/type.h>
@@ -24,7 +25,6 @@ namespace traph
         using ShortStorage = TensorStorage<i16>;
         using CharStorage = TensorStorage<i8>;
         using ByteStorage = TensorStorage<u8>;
-        // using HalfStorage = TensorStorage<f16>;
     public:
         std::unique_ptr<T[]> data;
         idx_type len;
@@ -62,10 +62,10 @@ namespace traph
         }
 
         // size
-        idx_type size() const {return len;}
-        size_type element_size() const {return sizeof(T);}
+        virtual idx_type size() const override {return len;}
+        virtual size_type element_size() const override {return sizeof(T);}
 
-        void resize_(idx_type size)
+        virtual void resize_(idx_type size) override
         {
             if(size < 0 || size == len)
                 return;
@@ -77,56 +77,14 @@ namespace traph
             len = size;
         }
 
-        // type cast
-        FloatStorage to_float() const
-        {
-            FloatStorage result;
-            result.resize_(size());
-            for(idx_type i = 0; i < size(); ++i)
-            {
-                result.data[i] = static_cast<f32>(data[i]);
-            }
-            return result;
-        }
-
-        DoubleStorage to_double() const
-        {
-            DoubleStorage result;
-            result.resize_(size());
-            for(idx_type i = 0; i < size(); ++i)
-            {
-                result.data[i] = static_cast<f64>(data[i]);
-            }
-            return result;
-        }
-
         // fill
-        void fill_(T v)
+        virtual void fill_(T v) override
         {
             for(idx_type i = 0; i < size(); ++i)
             {
                 data[i] = v;
             }
         }
-        /*
-        void resize(const DimVector& dimensions)
-        {
-            idx_type size = 1;
-            for(idx_type i = 0; i < dimensions.size(); ++i)
-            {
-                size *= dimensions[i];
-            }
-
-            if(size < 0 || size == len)
-                return;
-            idx_type move_size = (size > len ? len: size);
-            std::unique_ptr<T[]> temp(new idx_type[size]);
-            std::memcpy(temp.get(), data.get(), move_size * sizeof(idx_type));
-            data = std::move(temp);
-
-            len = size;
-        }
-        */
     };
 
     // ndarray
@@ -134,19 +92,27 @@ namespace traph
     class Tensor: public TensorBase<T>
     {
     private:
-        std::unique_ptr<TensorStorage<T>> _rep;
+        std::shared_ptr<TensorStorage<T>> _rep;
         DimVector _dimensions;
         idx_type _offset;
 		DimVector _strides;
         layout_type _order;
 
         bool _requires_grad;
+    public:
+        using DoubleTensor = Tensor<f64>;
+        using FloatTensor = Tensor<f32>;
+        using LongTensor = Tensor<i64>;
+        using IntTensor = Tensor<i32>;
+        using ShortTensor = Tensor<i16>;
+        using CharTensor = Tensor<i8>;
+        using ByteTensor = Tensor<u8>;
     private:
         void auto_strides()
         {
             idx_type dim_num = _dimensions.size();
             _strides.resize(dim_num);
-            size_type stride = 1;
+			idx_type stride = 1;
             if(_order == layout_type::column_major)
             {
 				for (idx_type i = dim_num - 1; i >= 0; --i)
@@ -164,14 +130,40 @@ namespace traph
 				}
             }
         }
-    public:
-        using DoubleTensor = Tensor<f64>;
-        using FloatTensor = Tensor<f32>;
-        using LongTensor = Tensor<i64>;
-        using IntTensor = Tensor<i32>;
-        using ShortTensor = Tensor<i16>;
-        using CharTensor = Tensor<i8>;
-        using ByteTensor = Tensor<u8>;
+
+        void apply_dim(idx_type dim, idx_type idx, std::function<T(T)> f)
+        {
+            idx_type dim_size = _dimensions.size();
+
+            idx_type step_len = _strides[dim];
+            idx_type step_num = _dimensions[dim];
+            
+            for(idx_type i = 0; i < step_num; ++i)
+            {
+                if(dim == dim_size - 1)
+                    _rep->data[idx] = f(_rep->data[idx]);
+                else
+                    apply_dim(dim + 1, idx, f);
+                idx += step_len;
+            }
+        }
+
+        void reduce_dim(T& result, idx_type dim, idx_type idx, std::function<T(T,T)> f) const
+        {
+            idx_type dim_size = _dimensions.size();
+
+            idx_type step_len = _strides[dim];
+            idx_type step_num = _dimensions[dim];
+
+            for(idx_type i = 0; i < step_num; ++i)
+            {
+                if(dim == dim_size - 1)
+                    result = f(result, _rep->data[idx]);
+                else
+                    reduce_dim(result, dim + 1, idx, f);
+                idx += step_len;
+            }
+        }
     public:
         Tensor()
             :_rep(new TensorStorage<T>),
@@ -243,126 +235,48 @@ namespace traph
         {
         }
 
-        virtual platform_type platform() override
+        virtual void apply_(std::function<T(T)> f) override
         {
-            return platform_type::none;
+            apply_dim(0, _offset, f);
         }
-
-        virtual device_id device() override
+        virtual void cos_() override
         {
-            return 0;
+			apply_([](T a)->T {return std::cos(a); });
         }
-
-        virtual void reshape(const DimVector& dims) override
+        virtual device_id device() override { return 0; }
+        virtual void fill_(T value) override
         {
-
+			apply_([&value](T a)->T {return value; });
         }
-
-        virtual void resize(const DimVector& dims) override
+		virtual idx_type offset() const override { return _offset; }
+		virtual layout_type order() const override { return _order; }
+        virtual platform_type platform() override { return platform_type::none; }
+        virtual T reduce_(std::function<T(T,T)> f) const override
         {
-            _dimensions = dims;
-            _rep->resize_(dims.flat_size());
-            auto_strides();
-        }
-
-		// info
-		idx_type offset() const
-		{
-			return _offset;
-		}
-
-		layout_type layout() const
-		{
-			return _order;
-		}
-
-		DimVector size() const
-		{
-			return _dimensions;
-		}
-
-		const T* data() const
-		{
-			return _rep->data.get();
-		}
-
-		T* data()
-		{
-			return _rep->data.get();
-		}
-
-		DimVector strides() const
-		{
-			return _strides;
-		}
-
-        // type cast
-        DoubleTensor to_double() const
-        {
-            DoubleTensor result(*this);
-            result._rep = result._rep.to_double();
+            T result{0.f};
+            reduce_dim(result, 0, _offset, f);
             return result;
         }
-        // op
-        void add_(T value)
+        virtual void reshape(const DimVector& dims) override
         {
-            idx_type i = _offset;
-            for(idx_type dim = 0;dim < _dimensions.size();++dim)
-            {
-                for(idx_type step = 0; step < dimension[dim];++step)
-                {
-                    _rep->data[i] = _rep->data[i] + value;
-                    i += _strides[dim];
-                }
-            }
-        }
 
-        void fill_(T value)
-        {
-			for (idx_type i = _offset; i < _rep->size(); ++i)
-			{
-				_rep->data[i] = value;
-			}
         }
-
-        void abs_()
+        virtual void resize(const DimVector& dims) override
         {
-            idx_type i = _offset;
-            for(idx_type dim = 0;dim < _dimensions.size();++dim)
-            {
-                for(idx_type step = 0; step < dimension[dim];++step)
-                {
-                    _rep->data[i] = std::abs(_rep->data[i]);
-                    i += _strides[dim];
-                }
-            }
+            _dimensions = dims;
+            _rep->resize_(dims.flat_size());
+            auto_strides();
         }
-        // index
-        T& item()
+        virtual void sin_() override
         {
-            if(_rep->size() > 0)
-            {
-                return _rep->data[0]; 
-            }
-            else
-            {
-                // error
-            }
-            
+			apply_([](T a)->T {return std::sin(a); });
         }
-
-        T& index(const DimVector& dims)
+		virtual DimVector size() const override { return _dimensions;}
+        virtual StorageBase<T>& storage() const override { return *(_rep.get()); }
+		virtual DimVector stride() const override { return _strides; }
+        virtual T sum() const override
         {
-            idx_type pos = 0;
-
-            for(idx_type i = 0; i < _dimensions.size(); ++i)
-            {
-                pos += _dimensions[i] * _strides[i];
-            }
-
-            pos += _offset;
-
-            return _rep->data[pos];
+			return reduce_([](T a, T b)->T {return a + b; });
         }
     };
 

+ 2 - 4
traph/source/tensor/CMakeLists.txt

@@ -4,14 +4,12 @@ SET(LIB_OUTNAME traph-${LIB_NAME})
 SET(HEADER_PATH ${TRAPH_PATH_HEADER}/${LIB_NAME})
 SET(SOURCE_PATH ${TRAPH_PATH_SOURCE}/${LIB_NAME})
 
-SET(CORE_LIST
-	${HEADER_PATH}/arithmetic.h
-	${SOURCE_PATH}/arithmetic.cpp
+SET(TENSOR_LIST
 	${HEADER_PATH}/tensor.h
 	${SOURCE_PATH}/tensor.cpp
 )
 
-ADD_LIBRARY(${LIB_OUTNAME} ${CORE_LIST})
+ADD_LIBRARY(${LIB_OUTNAME} ${TENSOR_LIST})
 
 IF(Boost_FOUND)
 	target_link_libraries(${LIB_OUTNAME} ${Boost_LIBRARIES})

+ 9 - 1
traph/source/test/main.cpp

@@ -3,6 +3,8 @@
 #include <traph/tensor/arithmetic.h>
 #include <traph/nn/variable.h>
 
+#include <iostream>
+
 int main()
 {
 	/*
@@ -17,10 +19,16 @@ int main()
 	traph::Tensor<traph::f32> c = traph::matmul(a, b);
 	*/
 
+	/*
 	auto a = traph::Variable<traph::f32>({2, 3});
 	auto c = traph::mul(traph::mul(a, a), 3);
 	auto out = traph::mean(c);
 	out.backward();
-		
+	*/
+
+	traph::Tensor<float> a = traph::ones<float>({ 10000, 10000 });
+
+	auto b = a.sum();
+	std::cout << b;
     return 0;
 }