You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							421 lines
						
					
					
						
							12 KiB
						
					
					
				
			
		
		
	
	
							421 lines
						
					
					
						
							12 KiB
						
					
					
				| //==============================================================================
 | |
| //
 | |
| // Copyright (c) 2017-2020 Qualcomm Technologies, Inc.
 | |
| // All Rights Reserved.
 | |
| // Confidential and Proprietary - Qualcomm Technologies, Inc.
 | |
| //
 | |
| //==============================================================================
 | |
| 
 | |
| #ifndef _IUSER_BUFFER_HPP
 | |
| #define _IUSER_BUFFER_HPP
 | |
| 
 | |
| #include "TensorShape.hpp"
 | |
| #include "ZdlExportDefine.hpp"
 | |
| #include <math.h>
 | |
| 
 | |
| namespace zdl {
 | |
| namespace DlSystem {
 | |
| 
 | |
| /** @addtogroup c_plus_plus_apis C++
 | |
| @{ */
 | |
| 
 | |
| 
 | |
| /**
 | |
|   * @brief .
 | |
|   *
 | |
|   * A base class buffer encoding type
 | |
|   */
 | |
| class ZDL_EXPORT UserBufferEncoding {
 | |
| public:
 | |
| 
 | |
|     /**
 | |
|       * @brief .
 | |
|       *
 | |
|       * An enum class of all supported element types in a IUserBuffer
 | |
|       */
 | |
|     enum class ElementType_t
 | |
|     {
 | |
|         /// Unknown element type.
 | |
|         UNKNOWN         = 0,
 | |
| 
 | |
|         /// Each element is presented by float.
 | |
|         FLOAT           = 1,
 | |
| 
 | |
|         /// Each element is presented by an unsigned int.
 | |
|         UNSIGNED8BIT    = 2,
 | |
| 
 | |
|         /// Each element is presented by an 8-bit quantized value.
 | |
|         TF8             = 10,
 | |
| 
 | |
|         /// Each element is presented by an 16-bit quantized value.
 | |
|         TF16            = 11
 | |
|     };
 | |
| 
 | |
|     /**
 | |
|       * @brief Retrieves the size of the element, in bytes.
 | |
|       *
 | |
|       * @return Size of the element, in bytes.
 | |
|      */
 | |
|     virtual size_t getElementSize() const noexcept = 0;
 | |
| 
 | |
|     /**
 | |
|       * @brief Retrieves the element type
 | |
|       *
 | |
|       * @return Element type
 | |
|      */
 | |
|     ElementType_t getElementType() const noexcept {return m_ElementType;};
 | |
| 
 | |
|     virtual ~UserBufferEncoding() {}
 | |
| 
 | |
| protected:
 | |
|     UserBufferEncoding(ElementType_t  elementType) : m_ElementType(elementType) {};
 | |
| private:
 | |
|     const ElementType_t  m_ElementType;
 | |
| };
 | |
| 
 | |
| /**
 | |
|   * @brief .
 | |
|   *
 | |
|   * A base class buffer source type
 | |
|   *
 | |
|   * @note User buffer from CPU support all kinds of runtimes;
 | |
|   *       User buffer from GLBUFFER support only GPU runtime.
 | |
|   */
 | |
| class ZDL_EXPORT UserBufferSource {
 | |
| public:
 | |
|    enum class SourceType_t
 | |
|    {
 | |
|       /// Unknown buffer source type.
 | |
|       UNKNOWN = 0,
 | |
| 
 | |
|       /// The network inputs are from CPU buffer.
 | |
|       CPU = 1,
 | |
| 
 | |
|       /// The network inputs are from OpenGL buffer.
 | |
|       GLBUFFER = 2
 | |
|    };
 | |
| 
 | |
|    /**
 | |
|      * @brief Retrieves the source type
 | |
|      *
 | |
|      * @return Source type
 | |
|     */
 | |
|    SourceType_t getSourceType() const noexcept {return m_SourceType;};
 | |
| 
 | |
| protected:
 | |
|    UserBufferSource(SourceType_t sourceType): m_SourceType(sourceType) {};
 | |
| private:
 | |
|    const SourceType_t m_SourceType;
 | |
| };
 | |
| 
 | |
| /**
 | |
|   * @brief .
 | |
|   *
 | |
|   * An source type where input data is delivered from OpenGL buffer
 | |
|   */
 | |
| class ZDL_EXPORT UserBufferSourceGLBuffer : public UserBufferSource{
 | |
| public:
 | |
|    UserBufferSourceGLBuffer() : UserBufferSource(SourceType_t::GLBUFFER) {};
 | |
| };
 | |
| 
 | |
| /**
 | |
|   * @brief .
 | |
|   *
 | |
|   * An encoding type where each element is represented by an unsigned int
 | |
|   */
 | |
| class ZDL_EXPORT UserBufferEncodingUnsigned8Bit : public UserBufferEncoding {
 | |
| public:
 | |
|     UserBufferEncodingUnsigned8Bit() : UserBufferEncoding(ElementType_t::UNSIGNED8BIT) {};
 | |
|     size_t getElementSize() const noexcept override;
 | |
| 
 | |
| protected:
 | |
|     UserBufferEncodingUnsigned8Bit(ElementType_t  elementType) : UserBufferEncoding(elementType) {};
 | |
| 
 | |
| };
 | |
| 
 | |
| /**
 | |
|   * @brief .
 | |
|   *
 | |
|   * An encoding type where each element is represented by a float
 | |
|   */
 | |
| class ZDL_EXPORT UserBufferEncodingFloat : public UserBufferEncoding {
 | |
| public:
 | |
|     UserBufferEncodingFloat() : UserBufferEncoding(ElementType_t::FLOAT) {};
 | |
|     size_t getElementSize() const noexcept override;
 | |
| 
 | |
| };
 | |
| 
 | |
| /**
 | |
|   * @brief .
 | |
|   *
 | |
|   * An encoding type where each element is represented by tf8, which is an
 | |
|   * 8-bit quantizd value, which has an exact representation of 0.0
 | |
|   */
 | |
| 
 | |
| class ZDL_EXPORT UserBufferEncodingTf8 : public UserBufferEncodingUnsigned8Bit {
 | |
| public:
 | |
|     UserBufferEncodingTf8() = delete;
 | |
|     UserBufferEncodingTf8(unsigned char stepFor0, float stepSize) :
 | |
|             UserBufferEncodingUnsigned8Bit(ElementType_t::TF8),
 | |
|             m_StepExactly0(stepFor0),
 | |
|             m_QuantizedStepSize(stepSize) {};
 | |
| 
 | |
|     UserBufferEncodingTf8(const zdl::DlSystem::UserBufferEncoding &ubEncoding) : UserBufferEncodingUnsigned8Bit(ubEncoding.getElementType()){
 | |
|             const zdl::DlSystem::UserBufferEncodingTf8* ubEncodingTf8
 | |
|                             = dynamic_cast <const zdl::DlSystem::UserBufferEncodingTf8*> (&ubEncoding);
 | |
|             if (ubEncodingTf8) {
 | |
|                 m_StepExactly0 = ubEncodingTf8->getStepExactly0();
 | |
|                 m_QuantizedStepSize = ubEncodingTf8->getQuantizedStepSize();
 | |
|             }
 | |
|     }
 | |
| 
 | |
| /**
 | |
|       * @brief Sets the step value that represents 0
 | |
|       *
 | |
|       * @param[in] stepExactly0 The step value that represents 0
 | |
|       *
 | |
|      */
 | |
| 
 | |
|     void setStepExactly0(const unsigned char stepExactly0) {
 | |
|         m_StepExactly0 = stepExactly0;
 | |
|     }
 | |
| 
 | |
| 
 | |
| /**
 | |
|       * @brief Sets the float value that each step represents
 | |
|       *
 | |
|       * @param[in] quantizedStepSize The float value of each step size
 | |
|       *
 | |
|      */
 | |
| 
 | |
|     void setQuantizedStepSize(const float quantizedStepSize) {
 | |
|         m_QuantizedStepSize = quantizedStepSize;
 | |
|     }
 | |
| 
 | |
| 
 | |
| /**
 | |
|       * @brief Retrieves the step that represents 0.0
 | |
|       *
 | |
|       * @return Step value
 | |
|      */
 | |
| 
 | |
|     unsigned char getStepExactly0() const {
 | |
|         return m_StepExactly0;
 | |
|     }
 | |
| 
 | |
| 
 | |
| /**
 | |
|      * Calculates the minimum floating point value that
 | |
|      * can be represented with this encoding.
 | |
|      *
 | |
|      * @return Minimum representable floating point value
 | |
|      */
 | |
| 
 | |
|     float getMin() const {
 | |
|         return m_QuantizedStepSize * (0 - m_StepExactly0);
 | |
|     }
 | |
| 
 | |
| 
 | |
| /**
 | |
|      * Calculates the maximum floating point value that
 | |
|      * can be represented with this encoding.
 | |
|      *
 | |
|      * @return Maximum representable floating point value
 | |
|      */
 | |
| 
 | |
|     float getMax() const {
 | |
|         return m_QuantizedStepSize * (255 - m_StepExactly0);
 | |
|     }
 | |
| 
 | |
| 
 | |
| /**
 | |
|       * @brief Retrieves the step size
 | |
|       *
 | |
|       * @return Step size
 | |
|      */
 | |
| 
 | |
|     float getQuantizedStepSize() const {
 | |
|         return m_QuantizedStepSize;
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     unsigned char m_StepExactly0;
 | |
| 
 | |
|     float m_QuantizedStepSize;
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| class ZDL_EXPORT UserBufferEncodingTfN : public UserBufferEncoding {
 | |
| public:
 | |
|    UserBufferEncodingTfN() = delete;
 | |
|    UserBufferEncodingTfN(uint64_t stepFor0, float stepSize, uint8_t bWidth=8):
 | |
|                                            UserBufferEncoding(getTypeFromWidth(bWidth)),
 | |
|                                            bitWidth(bWidth),
 | |
|                                            m_StepExactly0(stepFor0),
 | |
|                                            m_QuantizedStepSize(stepSize){};
 | |
| 
 | |
|    UserBufferEncodingTfN(const zdl::DlSystem::UserBufferEncoding &ubEncoding) : UserBufferEncoding(ubEncoding.getElementType()){
 | |
|             const zdl::DlSystem::UserBufferEncodingTfN* ubEncodingTfN
 | |
|                             = dynamic_cast <const zdl::DlSystem::UserBufferEncodingTfN*> (&ubEncoding);
 | |
|             if (ubEncodingTfN) {
 | |
|                 m_StepExactly0 = ubEncodingTfN->getStepExactly0();
 | |
|                 m_QuantizedStepSize = ubEncodingTfN->getQuantizedStepSize();
 | |
|                 bitWidth = ubEncodingTfN->bitWidth;
 | |
|             }
 | |
|    }
 | |
| 
 | |
|    size_t getElementSize() const noexcept override;
 | |
|    /**
 | |
|       * @brief Sets the step value that represents 0
 | |
|       *
 | |
|       * @param[in] stepExactly0 The step value that represents 0
 | |
|       *
 | |
|      */
 | |
|    void setStepExactly0(uint64_t stepExactly0) {
 | |
|       m_StepExactly0 = stepExactly0;
 | |
|    }
 | |
| 
 | |
|    /**
 | |
|      * @brief Sets the float value that each step represents
 | |
|      *
 | |
|      * @param[in] quantizedStepSize The float value of each step size
 | |
|      *
 | |
|     */
 | |
|    void setQuantizedStepSize(const float quantizedStepSize) {
 | |
|       m_QuantizedStepSize = quantizedStepSize;
 | |
|    }
 | |
| 
 | |
|    /**
 | |
|      * @brief Retrieves the step that represents 0.0
 | |
|      *
 | |
|      * @return Step value
 | |
|     */
 | |
|    uint64_t getStepExactly0() const {
 | |
|       return m_StepExactly0;
 | |
|    }
 | |
| 
 | |
|    /**
 | |
|     * Calculates the minimum floating point value that
 | |
|     * can be represented with this encoding.
 | |
|     *
 | |
|     * @return Minimum representable floating point value
 | |
|     */
 | |
|    float getMin() const {
 | |
|       return static_cast<float>(m_QuantizedStepSize * (0 - (double)m_StepExactly0));
 | |
|    }
 | |
| 
 | |
|    /**
 | |
|     * Calculates the maximum floating point value that
 | |
|     * can be represented with this encoding.
 | |
|     *
 | |
|     * @return Maximum representable floating point value
 | |
|     */
 | |
|    float getMax() const{
 | |
|        return static_cast<float>(m_QuantizedStepSize * (pow(2,bitWidth)-1 - (double)m_StepExactly0));
 | |
|    };
 | |
| 
 | |
|    /**
 | |
|      * @brief Retrieves the step size
 | |
|      *
 | |
|      * @return Step size
 | |
|     */
 | |
|    float getQuantizedStepSize() const {
 | |
|       return m_QuantizedStepSize;
 | |
|    }
 | |
| 
 | |
|    ElementType_t getTypeFromWidth(uint8_t width);
 | |
| 
 | |
|    uint8_t bitWidth;
 | |
| private:
 | |
|    uint64_t m_StepExactly0;
 | |
|    float m_QuantizedStepSize;
 | |
| };
 | |
| 
 | |
| 
 | |
| /**
 | |
|  * @brief UserBuffer contains a pointer and info on how to walk it and interpret its content.
 | |
|  */
 | |
| class ZDL_EXPORT IUserBuffer {
 | |
| public:
 | |
|     virtual ~IUserBuffer() = default;
 | |
|     
 | |
|     /**
 | |
|       * @brief Retrieves the total number of bytes between elements in each dimension if
 | |
|       * the buffer were to be interpreted as a multi-dimensional array.
 | |
|       *
 | |
|       * @return Number of bytes between elements in each dimension.
 | |
|       * e.g. A tightly packed tensor of floats with dimensions [4, 3, 2] would
 | |
|       * return strides of [24, 8, 4].
 | |
|      */
 | |
|     virtual const TensorShape& getStrides() const = 0;
 | |
| 
 | |
|     /**
 | |
|       * @brief Retrieves the size of the buffer, in bytes.
 | |
|       *
 | |
|       * @return Size of the underlying buffer, in bytes.
 | |
|      */
 | |
|     virtual size_t getSize() const = 0;
 | |
| 
 | |
|     /**
 | |
|       * @brief Retrieves the size of the inference data in the buffer, in bytes.
 | |
|       *
 | |
|       * The inference results from a dynamic-sized model may not be exactly the same size
 | |
|       * as the UserBuffer provided to SNPE. This function can be used to get the amount
 | |
|       * of output inference data, which may be less or greater than the size of the UserBuffer.
 | |
|       *
 | |
|       * If the inference results fit in the UserBuffer, getOutputSize() would be less than
 | |
|       * or equal to getSize(). But if the inference results were more than the capacity of
 | |
|       * the provided UserBuffer, the results would be truncated to fit the UserBuffer. But,
 | |
|       * getOutputSize() would be greater than getSize(), which indicates a bigger buffer
 | |
|       * needs to be provided to SNPE to hold all of the inference results.
 | |
|       *
 | |
|       * @return Size required for the buffer to hold all inference results, which can be less
 | |
|       * or more than the size of the buffer, in bytes.
 | |
|     */
 | |
|     virtual size_t getOutputSize() const = 0;
 | |
| 
 | |
|     /**
 | |
|       * @brief Changes the underlying memory that backs the UserBuffer.
 | |
|       *
 | |
|       * This can be used to avoid creating multiple UserBuffer objects
 | |
|       * when the only thing that differs is the memory location.
 | |
|       *
 | |
|       * @param[in] buffer Pointer to the memory location
 | |
|       *
 | |
|       * @return Whether the set succeeds.
 | |
|      */
 | |
|     virtual bool setBufferAddress(void *buffer) noexcept = 0;
 | |
| 
 | |
|     /**
 | |
|       * @brief Gets a const reference to the data encoding object of
 | |
|       *        the underlying buffer
 | |
|       *
 | |
|       * This is necessary when the UserBuffer is filled by SNPE with
 | |
|       * data types such as TF8, where the caller needs to know the quantization
 | |
|       * parameters in order to interpret the data properly
 | |
|       *
 | |
|       * @return A read-only encoding object
 | |
|      */
 | |
|     virtual const UserBufferEncoding& getEncoding() const noexcept = 0;
 | |
| 
 | |
|     /**
 | |
|       * @brief Gets a reference to the data encoding object of
 | |
|       *        the underlying buffer
 | |
|       *
 | |
|       * This is necessary when the UserBuffer is re-used, and the encoding
 | |
|       * parameters can change.  For example, each input can be quantized with
 | |
|       * different step sizes.
 | |
|       *
 | |
|       * @return Data encoding meta-data
 | |
|      */
 | |
|     virtual UserBufferEncoding& getEncoding() noexcept = 0;
 | |
| 
 | |
| };
 | |
| 
 | |
| /** @} */ /* end_addtogroup c_plus_plus_apis C++ */
 | |
| 
 | |
| }
 | |
| }
 | |
| 
 | |
| #endif
 | |
| 
 |