LCOV - code coverage report
Current view: top level - nntrainer/tensor - float_tensor.h (source / functions) Coverage Total Hit
Test: coverage_filtered.info Lines: 100.0 % 42 42
Test Date: 2025-12-14 20:38:17 Functions: 85.7 % 7 6

            Line data    Source code
       1              : // SPDX-License-Identifier: Apache-2.0
       2              : /**
       3              :  * @file        float_tensor.h
       4              :  * @date        01 December 2023
       5              :  * @brief       This is FloatTensor class for 32-bit floating point calculation
       6              :  * @see         https://github.com/nnstreamer/nntrainer
       7              :  * @author      Jijoong Moon <jijoong.moon@samsung.com>
       8              :  * @author      Donghyeon Jeong <dhyeon.jeong@samsung.com>
       9              :  * @bug         No known bugs except for NYI items
      10              :  */
      11              : 
      12              : #ifndef __FLOAT_TENSOR_H__
      13              : #define __FLOAT_TENSOR_H__
      14              : #ifdef __cplusplus
      15              : 
      16              : #include <tensor_base.h>
      17              : 
      18              : #ifdef DEBUG
      19              : #define EXCEPT_WHEN_DEBUG
      20              : #else
      21              : #define EXCEPT_WHEN_DEBUG noexcept
      22              : #endif
      23              : 
      24              : namespace nntrainer {
      25              : 
      26              : /**
      27              :  * @class FloatTensor class
      28              :  * @brief FloatTensor class for 32-bit floating point calculation
      29              :  */
      30              : class FloatTensor : public TensorBase {
      31              : public:
      32              :   /**
      33              :    * @brief     Basic Constructor of Tensor
      34              :    */
      35              :   FloatTensor(std::string name_ = "", Tformat fm = Tformat::NCHW);
      36              : 
      37              :   /**
      38              :    * @brief Construct a new FloatTensor object
      39              :    *
      40              :    * @param d Tensor dim for this float tensor
      41              :    * @param alloc_now Allocate memory to this tensor or not
      42              :    * @param init Initializer for the tensor
      43              :    * @param name Name of the tensor
      44              :    */
      45              :   FloatTensor(const TensorDim &d, bool alloc_now,
      46              :               Initializer init = Initializer::NONE, std::string name = "");
      47              : 
      48              :   /**
      49              :    * @brief Construct a new FloatTensor object
      50              :    *
      51              :    * @param d Tensor dim for this tensor
      52              :    * @param buf buffer
      53              :    */
      54              :   FloatTensor(const TensorDim &d, const void *buf = nullptr);
      55              : 
      56              :   /**
      57              :    * @brief Construct a new FloatTensor object
      58              :    *
      59              :    * @param d data for the Tensor
      60              :    * @param fm format for the Tensor
      61              :    */
      62           31 :   FloatTensor(
      63              :     std::vector<std::vector<std::vector<std::vector<float>>>> const &d,
      64           62 :     Tformat fm) {
      65           31 :     if (d.empty() || d[0].empty() || d[0][0].empty() || d[0][0][0].empty()) {
      66              :       throw std::out_of_range(
      67            1 :         "[Tensor] trying to initialize FloatTensor from empty vector");
      68              :     }
      69              : 
      70           30 :     dim.setTensorDim(0, d.size());
      71           30 :     if (fm == Tformat::NCHW) {
      72           28 :       dim.setTensorDim(1, d[0].size());
      73           28 :       dim.setTensorDim(2, d[0][0].size());
      74           28 :       dim.setTensorDim(3, d[0][0][0].size());
      75              :     } else {
      76            2 :       dim.setTensorDim(2, d[0].size());
      77            2 :       dim.setTensorDim(3, d[0][0].size());
      78            2 :       dim.setTensorDim(1, d[0][0][0].size());
      79              :     }
      80              : 
      81              :     dim.setTensorType({fm, Tdatatype::FP32});
      82              : 
      83           30 :     strides = dim.computeStrides();
      84           30 :     contiguous = true;
      85           30 :     initializer = Initializer::NONE;
      86              : 
      87              :     MemoryData *mem_data =
      88          833 :       new MemoryData((void *)(new float[dim.getDataLen()]()));
      89           31 :     data = std::shared_ptr<MemoryData>(mem_data, [](MemoryData *ptr) {
      90           30 :       delete[] ptr->getAddr<float>();
      91           30 :       delete ptr;
      92              :     });
      93              : 
      94           30 :     offset = 0;
      95              : 
      96              :     // if fm == Tformat::NCHW, then dim[0] == batch , dim[1] == channel, dim[2]
      97              :     // == height, dim[3] == width. and if fm == Tformat::NHWC, dim[0] == batch,
      98              :     // dim[1] == height, dim[2] == width, dim[3] == channel
      99           30 :     if (fm == Tformat::NCHW) {
     100           91 :       for (unsigned int i = 0; i < batch(); ++i)
     101          163 :         for (unsigned int j = 0; j < channel(); ++j)
     102          226 :           for (unsigned int k = 0; k < height(); ++k)
     103          923 :             for (unsigned int l = 0; l < width(); ++l)
     104          797 :               this->setValue(i, j, k, l, d[i][j][k][l]);
     105              :     } else {
     106            4 :       for (unsigned int i = 0; i < batch(); ++i)
     107            4 :         for (unsigned int j = 0; j < height(); ++j)
     108            8 :           for (unsigned int k = 0; k < width(); ++k)
     109           12 :             for (unsigned int l = 0; l < channel(); ++l)
     110            6 :               this->setValue(i, l, j, k, d[i][j][k][l]);
     111              :     }
     112           31 :   }
     113              : 
     114              :   /**
     115              :    * @brief Construct a new FloatTensor object
     116              :    * @param rhs TensorBase object to copy
     117              :    */
     118       540296 :   FloatTensor(TensorBase &rhs) : TensorBase(rhs) {}
     119              : 
     120              :   /**
     121              :    * @brief Basic Destructor
     122              :    */
     123      1198342 :   ~FloatTensor() {}
     124              : 
     125              :   /**
     126              :    * @brief     Comparison operator overload
     127              :    * @param[in] rhs Tensor to be compared with
     128              :    * @note      Only compares Tensor data
     129              :    */
     130              :   bool operator==(const FloatTensor &rhs) const;
     131              : 
     132              :   /**
     133              :    * @brief     Comparison operator overload
     134              :    * @param[in] rhs Tensor to be compared with
     135              :    * @note      Only compares Tensor data
     136              :    */
     137              :   bool operator!=(const FloatTensor &rhs) const { return !(*this == rhs); }
     138              : 
     139              :   /**
     140              :    * @copydoc Tensor::allocate()
     141              :    */
     142              :   void allocate() override;
     143              : 
     144              :   /**
     145              :    * @copydoc Tensor::deallocate()
     146              :    */
     147              :   void deallocate() override;
     148              : 
     149              :   /**
     150              :    * @copydoc Tensor::getData()
     151              :    */
     152              :   void *getData() const override;
     153              : 
     154              :   /**
     155              :    * @copydoc Tensor::getData(size_t idx)
     156              :    */
     157              :   void *getData(size_t idx) const override;
     158              : 
     159              :   /**
     160              :    * @brief     i data index
     161              :    * @retval    address of ith data
     162              :    */
     163              :   void *getAddress(unsigned int i) override;
     164              : 
     165              :   /**
     166              :    * @brief     i data index
     167              :    * @retval    address of ith data
     168              :    */
     169              :   const void *getAddress(unsigned int i) const override;
     170              : 
     171              :   /**
     172              :    * @brief     return value at specific location
     173              :    * @param[in] i index
     174              :    */
     175              :   const float &getValue(unsigned int i) const;
     176              : 
     177              :   /**
     178              :    * @brief     return value at specific location
     179              :    * @param[in] i index
     180              :    */
     181              :   float &getValue(unsigned int i);
     182              : 
     183              :   /**
     184              :    * @brief     return value at specific location
     185              :    * @param[in] b batch location
     186              :    * @param[in] c channel location
     187              :    * @param[in] h height location
     188              :    * @param[in] w width location
     189              :    */
     190              :   const float &getValue(unsigned int b, unsigned int c, unsigned int h,
     191              :                         unsigned int w) const;
     192              : 
     193              :   /**
     194              :    * @brief     return value at specific location
     195              :    * @param[in] b batch location
     196              :    * @param[in] c channel location
     197              :    * @param[in] h height location
     198              :    * @param[in] w width location
     199              :    */
     200              :   float &getValue(unsigned int b, unsigned int c, unsigned int h,
     201              :                   unsigned int w);
     202              : 
     203              :   /**
     204              :    * @copydoc Tensor::setValue(float value)
     205              :    */
     206              :   void setValue(float value) override;
     207              : 
     208              :   /**
     209              :    * @copydoc Tensor::setValue(b, c, h, w, value)
     210              :    */
     211              :   void setValue(unsigned int b, unsigned int c, unsigned int h, unsigned int w,
     212              :                 float value) override;
     213              : 
     214              :   /**
     215              :    * @copydoc Tensor::addValue(b, c, h, w, value, beta)
     216              :    */
     217              :   void addValue(unsigned int b, unsigned int c, unsigned int h, unsigned int w,
     218              :                 float value, float beta) override;
     219              : 
     220              :   /**
     221              :    * @copydoc Tensor::setZero()
     222              :    */
     223              :   void setZero() override;
     224              : 
     225              :   /**
     226              :    * @brief Set the Dist object
     227              :    * @param dist distribution engine
     228              :    */
     229        18214 :   template <typename Engine> void setDist(Engine dist) {
     230        18214 :     NNTR_THROW_IF(!contiguous, std::invalid_argument)
     231              :       // << getName() << " Tensor is not contiguous, cannot set distribution";
     232              :       << " Tensor is not contiguous, cannot set distribution";
     233              : 
     234        18214 :     float *data_ = (float *)getData();
     235        18214 :     unsigned int len = size();
     236     73266601 :     for (unsigned int i = 0; i < len; ++i) {
     237     73248387 :       data_[i] = (float)dist(rng);
     238              :     }
     239        18214 :   };
     240              : 
     241              :   /**
     242              :    * @copydoc Tensor::setRandNormal()
     243              :    */
     244              :   void setRandNormal(float mean = 0.0f, float stddev = 0.05f) override;
     245              : 
     246              :   /**
     247              :    * @copydoc Tensor::setRandUniform()
     248              :    */
     249              :   void setRandUniform(float min = -0.05f, float max = 0.05f) override;
     250              : 
     251              :   /**
     252              :    * @copydoc Tensor::setRandBernoulli()
     253              :    */
     254              :   void setRandBernoulli(float probability = 0.5f) override;
     255              : 
     256              :   /**
     257              :    * @copydoc Tensor::initialize()
     258              :    */
     259              :   void initialize() override;
     260              : 
     261              :   /**
     262              :    * @copydoc Tensor::initialize(Initializer init)
     263              :    */
     264              :   void initialize(Initializer init) override;
     265              : 
     266              :   /**
     267              :    * @copydoc Tensor::apply(std::function<T(T)> f, Tensor &output)
     268              :    */
     269              :   Tensor &apply(std::function<float(float)> f, Tensor &output) const override;
     270              : 
     271              :   /**
     272              :    * @copydoc Tensor::multiply_strided(Tensor const &m, Tensor &output,
     273              :    * const float beta)
     274              :    */
     275              :   Tensor multiply_strided(Tensor const &m, Tensor &output,
     276              :                           const float beta) const override;
     277              : 
     278              :   /**
     279              :    * @copydoc Tensor::multiply_i(float const &value)
     280              :    */
     281              :   int multiply_i(float const &value) override;
     282              : 
     283              :   /**
     284              :    * @copydoc Tensor::multiply(float const &value, Tensor &out)
     285              :    */
     286              :   Tensor &multiply(float const &value, Tensor &out) const override;
     287              : 
     288              :   /**
     289              :    * @copydoc Tensor::multiply(Tensor const &m, Tensor &output, const
     290              :    * float beta = 0.0)
     291              :    */
     292              :   Tensor &multiply(Tensor const &m, Tensor &output,
     293              :                    const float beta = 0.0) const override;
     294              : 
     295              :   /**
     296              :    * @copydoc Tensor::divide(float const &value, Tensor &output)
     297              :    */
     298              :   Tensor &divide(float const &value, Tensor &output) const override;
     299              : 
     300              :   /**
     301              :    * @copydoc Tensor::divide(Tensor const &m, Tensor &output)
     302              :    */
     303              :   Tensor &divide(Tensor const &m, Tensor &output) const override;
     304              : 
     305              :   /**
     306              :    * @copydoc Tensor::add_strided(Tensor const &input, Tensor &output,
     307              :    * const float beta)
     308              :    */
     309              :   Tensor &add_strided(Tensor const &input, Tensor &output,
     310              :                       const float beta) const override;
     311              : 
     312              :   /**
     313              :    * @copydoc Tensor::add_i_partial()
     314              :    */
     315              :   int add_i_partial(unsigned int len, unsigned int addr_idx, Tensor &m,
     316              :                     unsigned int incX, unsigned int incY, const Tensor alphas,
     317              :                     unsigned int alpha_idx) override;
     318              : 
     319              :   /**
     320              :    * @copydoc Tensor::add(float const &value, Tensor &output)
     321              :    */
     322              :   Tensor &add(float const &value, Tensor &output) const override;
     323              : 
     324              :   /**
     325              :    * @copydoc Tensor::add(Tensor const &m, Tensor &output, float const
     326              :    * alpha)
     327              :    */
     328              :   Tensor &add(Tensor const &m, Tensor &output,
     329              :               float const alpha) const override;
     330              : 
     331              :   /**
     332              :    *  @copydoc Tensor::subtract(float const &value, Tensor &output)
     333              :    */
     334              :   Tensor &subtract(float const &value, Tensor &output) const override;
     335              : 
     336              :   /**
     337              :    *  @copydoc TensorBase::sum_by_batch(Tensor &output)
     338              :    */
     339              :   void sum_by_batch(Tensor &output) const override;
     340              : 
     341              :   /**
     342              :    * @copydoc Tensor::sum(unsigned int axis, Tensor &output, float alpha,
     343              :    * float beta) const
     344              :    */
     345              :   Tensor &sum(unsigned int axis, Tensor &output, float alpha,
     346              :               float beta) const override;
     347              : 
     348              :   /**
     349              :    * @copydoc Tensor::abs()
     350              :    */
     351              :   Tensor &abs(Tensor &output) const override;
     352              : 
     353              :   /**
     354              :    * @copydoc Tensor::l2norm
     355              :    */
     356              :   float l2norm() const override;
     357              : 
     358              :   /**
     359              :    * @copydoc Tensor::pow(float exponent, Tensor &output)
     360              :    */
     361              :   Tensor &pow(float exponent, Tensor &output) const override;
     362              : 
     363              :   /**
     364              :    * @copydoc Tensor::sqrt(&output)
     365              :    */
     366              :   Tensor &sqrt(Tensor &output) const override;
     367              : 
     368              :   /**
     369              :    * @copydoc Tensor::erf(Tensor &output)
     370              :    */
     371              :   Tensor &erf(Tensor &output) const override;
     372              : 
     373              :   /**
     374              :    * @copydoc Tensor::sin(Tensor &out, float alpha)
     375              :    */
     376              :   void sin(Tensor &out, float alpha) override;
     377              : 
     378              :   /**
     379              :    * @copydoc Tensor::cos(Tensor &out, float alpha)
     380              :    */
     381              :   void cos(Tensor &out, float alpha) override;
     382              : 
     383              :   /**
     384              :    * @copydoc Tensor::tan(Tensor &output, float alpha)
     385              :    */
     386              :   void tan(Tensor &output, float alpha) override;
     387              : 
     388              :   /**
     389              :    * @copydoc TensorBase::inv_sqrt(Tensor &out)
     390              :    */
     391              :   void inv_sqrt(Tensor &out) override;
     392              : 
     393              :   /**
     394              :    *  @copydoc Tensor::dot(Tensor const &input, Tensor &output, bool
     395              :    * trans, bool trans_in, float beta)
     396              :    */
     397              :   Tensor &dot(Tensor const &input, Tensor &output, bool trans, bool trans_in,
     398              :               float beta) const override;
     399              : 
     400              :   void dot(std::vector<Tensor *> input, std::vector<Tensor *> output,
     401              :            bool trans, bool trans_in, float beta) const override;
     402              : 
     403              :   /**
     404              :    * @copydoc Tensor::dropout_mask(float dropout)
     405              :    */
     406              :   void dropout_mask(float dropout) override;
     407              : 
     408              :   /**
     409              :    * @copydoc Tensor::filter_mask(const Tensor &mask_len, bool reverse)
     410              :    */
     411              :   void filter_mask(const Tensor &mask_len, bool reverse) override;
     412              : 
     413              :   /**
     414              :    * @copydoc Tensor::zoneout_mask(Tensor &opposite, float zoneout)
     415              :    */
     416              :   void zoneout_mask(Tensor &opposite, float zoneout) override;
     417              : 
     418              :   /**
     419              :    * @copydoc Tensor::split(std::vector<size_t> sizes, int axis)
     420              :    */
     421              :   std::vector<Tensor> split(std::vector<size_t> sizes, int axis) override;
     422              : 
     423              :   /**
     424              :    * @copydoc Tensor::concat()
     425              :    */
     426              :   Tensor concat(const std::vector<Tensor> &tensors, int axis,
     427              :                 Tensor &output) override;
     428              : 
     429              :   /**
     430              :    * @copydoc Tensor::copy(const Tensor &from)
     431              :    */
     432              :   void copy(const Tensor &from) override;
     433              : 
     434              :   /**
     435              :    * @copydoc Tensor::copyData(const Tensor &from)
     436              :    */
     437              :   void copyData(const Tensor &from) override;
     438              : 
     439              :   /**
     440              :    * @brief      Copy the Tensor
     441              :    * @param[in]  input Tensor to be copied
     442              :    * @param[out] output output Tensor
     443              :    */
     444              :   void copy_with_stride(const Tensor &input, Tensor &output) override;
     445              : 
     446              :   /**
     447              :    * @copydoc Tensor::argmax()
     448              :    */
     449              :   std::vector<unsigned int> argmax() const override;
     450              : 
     451              :   /**
     452              :    * @copydoc Tensor::argmin()
     453              :    */
     454              :   std::vector<unsigned int> argmin() const override;
     455              : 
     456              :   /**
     457              :    * @copydoc TensorBase::top_k()
     458              :    */
     459              :   void topK(unsigned int k, void *output_data, uint32_t *indices) override;
     460              : 
     461              :   /**
     462              :    * @copydoc Tensor::max_abs()
     463              :    */
     464              :   float max_abs() const override;
     465              :   /**
     466              :    * @copydoc Tensor::maxValue()
     467              :    */
     468              :   float maxValue() const override;
     469              : 
     470              :   /**
     471              :    * @copydoc Tensor::minValue()
     472              :    */
     473              :   float minValue() const override;
     474              : 
     475              :   /**
     476              :    * @copydoc Tensor::transpose(const std::string &direction, Tensor &out)
     477              :    */
     478              :   Tensor &transpose(const std::string &direction,
     479              :                     Tensor &output) const override;
     480              : 
     481              :   /**
     482              :    * @copydoc Tensor::print(std::ostream &out)
     483              :    */
     484              :   void print(std::ostream &out) const override;
     485              : 
     486              : private:
     487              :   /**
     488              :    * @brief copy a buffer to @a this, the caller has to ensure that @a this is
     489              :    * initialized otherwise undefined behavior
     490              :    *
     491              :    * @param buf buffer to copy from
     492              :    */
     493              :   void copy(const void *buf);
     494              : 
     495              :   /**
     496              :    * @brief Applies the given operator to the tensor with the passed argument
     497              :    * @param[in] m Tensor
     498              :    * @param[in] v_func vectorized function to apply
     499              :    * @param e broadcast info.
     500              :    * @param cur_axis current axis. pass default when calling outside.
     501              :    * @param offset offset for this.  pass default when calling outside.
     502              :    * @param m_offset offset for m.  pass default when calling outside.
     503              :    * @retval #ML_ERROR_NONE Successful
     504              :    * @retval #ML_ERROR_INVALID_PARAMETER Invalid Parameter
     505              :    */
     506              :   void
     507              :   apply_broadcast_util(Tensor const &m,
     508              :                        std::function<void(const BroadcastInfo &e, const float *,
     509              :                                           const float *, float *)>
     510              :                          v_func,
     511              :                        Tensor &output, const BroadcastInfo &e,
     512              :                        int cur_axis = -1, size_t offset = 0,
     513              :                        size_t m_offset = 0) const;
     514              : 
     515              :   /**
     516              :    * @brief Applies the given operator to the tensor with the passed argument
     517              :    *
     518              :    * @param[in] m Tensor
     519              :    * @param[in] v_func vectorized function to apply
     520              :    * @retval #ML_ERROR_NONE Successful
     521              :    * @retval #ML_ERROR_INVALID_PARAMETER Invalid Parameter
     522              :    */
     523              :   void apply_broadcast(Tensor const &m,
     524              :                        std::function<void(const BroadcastInfo &e, const float *,
     525              :                                           const float *, float *)>
     526              :                          v_func,
     527              :                        Tensor &output) const;
     528              : 
     529              :   /**
     530              :    * @brief  Get the Data Type String object
     531              :    * @return std::string of tensor data type (FP32)
     532              :    */
     533            1 :   std::string getStringDataType() const override { return "FP32"; }
     534              : 
     535              :   /**
     536              :    * @copydoc Tensor::isValid()
     537              :    */
     538              :   bool isValid() const override;
     539              : 
     540              :   /**
     541              :    * @brief Float.dot(Float)
     542              :    * @return Tensor& reference to the output tensor
     543              :    */
     544              :   Tensor &dotFloat(Tensor const &input, Tensor &output, bool trans,
     545              :                    bool trans_in, float beta) const;
     546              : 
     547              :   /**
     548              :    * @brief Float32.dot(Float16)
     549              :    * @return Tensor& reference to the output tensor
     550              :    */
     551              :   Tensor &dotFloat32Float16(Tensor const &input, Tensor &output, bool trans,
     552              :                             bool trans_in, float beta) const;
     553              : 
     554              :   /**
     555              :    * @brief Float.dot(Q4K/Q6K)
     556              :    * @return Tensor& reference to the output tensor
     557              :    */
     558              :   Tensor &dotQnK(Tensor const &input, Tensor &output, bool trans, bool trans_in,
     559              :                  float beta, Tdatatype dtype) const;
     560              : 
     561              :   /**
     562              :    * @brief Float.dot(QINT4/QINT8/QINT16)
     563              :    * @return Tensor& reference to the output tensor
     564              :    */
     565              :   Tensor &dotQInteger(Tensor const &input, Tensor &output, bool trans,
     566              :                       bool trans_in, float beta, Tdatatype dtype) const;
     567              : };
     568              : 
     569              : } // namespace nntrainer
     570              : 
     571              : #endif /* __cplusplus */
     572              : #endif /* __FLOAT_TENSOR_H__ */
        

Generated by: LCOV version 2.0-1