openpilot is an open source driver assistance system. openpilot performs the functions of Automated Lane Centering and Adaptive Cruise Control for over 200 supported car makes and models.
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.

359 lines
10 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 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;
protected:
uint64_t m_StepExactly0;
float m_QuantizedStepSize;
};
class ZDL_EXPORT UserBufferEncodingTf8 : public UserBufferEncodingTfN {
public:
UserBufferEncodingTf8() = delete;
UserBufferEncodingTf8(unsigned char stepFor0, float stepSize) :
UserBufferEncodingTfN(stepFor0, stepSize) {};
UserBufferEncodingTf8(const zdl::DlSystem::UserBufferEncoding &ubEncoding) : UserBufferEncodingTfN(ubEncoding){}
/**
* @brief Sets the step value that represents 0
*
* @param[in] stepExactly0 The step value that represents 0
*
*/
void setStepExactly0(const unsigned char stepExactly0) {
UserBufferEncodingTfN::m_StepExactly0 = stepExactly0;
}
/**
* @brief Retrieves the step that represents 0.0
*
* @return Step value
*/
unsigned char getStepExactly0() const {
return UserBufferEncodingTfN::m_StepExactly0;
}
};
/**
* @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