VXLIB User Guide
VXLIB_meanStdDev_ci.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * Neither the name of Texas Instruments Incorporated nor the names of
17  * its contributors may be used to endorse or promote products derived
18  * from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  ******************************************************************************/
33 
34 /**********************************************************************************************************************/
35 /* */
36 /* INCLUDES */
37 /* */
38 /**********************************************************************************************************************/
39 
40 #include "VXLIB_meanStdDev_priv.h"
41 
42 /**********************************************************************************************************************/
43 /* */
44 /* DEFINES */
45 /* */
46 /**********************************************************************************************************************/
47 
48 #define SE_PARAM_BASE (0x0000)
49 #define SE0_PARAM_OFFSET (SE_PARAM_BASE)
50 
51 // this method computes the square root of a scalar value
52 static inline double sqrtdp(double a)
53 {
54 
55  double half = 0.5;
56  double oneP5 = 1.5;
57 
58  double y, p0, p1, d0;
59  // double double_max = std::numeric_limits<double>::max();
60 
61  p0 = __recip_sqrt(a);
62  d0 = p0 * a;
63  p1 = oneP5 - d0 * p0 * half;
64  y = a * p0 * p1;
65 
66  return y;
67 }
68 
69 /**********************************************************************************************************************/
70 /* */
71 /* VXLIB_meanStdDev_init_ci */
72 /* */
73 /**********************************************************************************************************************/
74 
75 // this method initializes the kernel-specific parameters
76 // mainly, the streaming engine and streaming address generators
77 template <uint32_t dTypeIn, uint32_t dTypeOut>
79  const VXLIB_bufParams2D_t *bufParamsIn,
80  const VXLIB_meanStdDev_InitArgs *pKerInitArgs)
81 {
82  VXLIB_STATUS status = VXLIB_SUCCESS; // assign status to success by default
83 
84  // structs to hold SE and SA parameters
85  __SE_TEMPLATE_v1 se0Params = __gen_SE_TEMPLATE_v1();
86 
87  // typecast handle (void) to struct pointer type associated to kernel
88  VXLIB_meanStdDev_PrivArgs *pKerPrivArgs = (VXLIB_meanStdDev_PrivArgs *) handle;
89 
90  // obtain image size and compute number of blocks to process
91  size_t width = pKerPrivArgs->width;
92  size_t height = pKerPrivArgs->height;
93  size_t strideIn = pKerPrivArgs->strideInElements;
94 
95  size_t elemCount = 0;
96  if (dTypeIn == VXLIB_UINT8){
97  elemCount = c7x::element_count_of<c7x::uchar_qvec>::value;
98  }
99  else {
100  elemCount = c7x::element_count_of<c7x::ushort_qvec>::value;
101  }
102 
103  size_t wBlocks = VXLIB_ceilingDiv(width, elemCount);
104  size_t numBlocks = height * wBlocks;
105  pKerPrivArgs->numBlocks = numBlocks;
106 
107  uint8_t *pBlock = pKerPrivArgs->bufPblock; // address to retrieve to store SE/SA params
108 
109  if (strideIn == width) {
110 
111  se0Params.DIMFMT = __SE_DIMFMT_1D;
112  se0Params.ICNT0 = width * height;
113  }
114 
115  else {
116 
117  se0Params.DIMFMT = __SE_DIMFMT_3D;
118  se0Params.ICNT0 = elemCount;
119 
120  se0Params.DIM1 = strideIn;
121  se0Params.ICNT1 = height;
122 
123  se0Params.DIM2 = elemCount;
124  se0Params.ICNT2 = VXLIB_ceilingDiv(width, elemCount);
125 
126  se0Params.DECDIM1 = __SE_DECDIM_DIM2;
127  se0Params.DECDIM1_WIDTH = width;
128  se0Params.DECDIM1SD = __SE_DECDIMSD_DIM0;
129  }
130 
131  se0Params.PROMOTE = __SE_PROMOTE_4X_ZEROEXT;
132 
133  if (dTypeIn == VXLIB_UINT8) {
134  se0Params.ELETYPE = c7x::se_eletype<c7x::uchar_vec>::value;
135  se0Params.VECLEN = c7x::se_veclen<c7x::uchar_qvec>::value;
136  }
137 
138  else {
139  se0Params.ELETYPE = c7x::se_eletype<c7x::ushort_vec>::value;
140  se0Params.VECLEN = c7x::se_veclen<c7x::ushort_qvec>::value;
141  }
142 
143  /**************************/
144  /* Store SE and SA params */
145  /**************************/
146 
147  *(__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE0_PARAM_OFFSET) = se0Params;
148 
149  return status;
150 }
151 
152 /**********************************************************************************************************************/
153 /* */
154 /* Explicit instantiations for VXLIB_meanStdDev_init_ci */
155 /* */
156 /**********************************************************************************************************************/
157 
158 template VXLIB_STATUS
160  const VXLIB_bufParams2D_t *bufParamsIn,
161  const VXLIB_meanStdDev_InitArgs *pKerInitArgs);
162 
163 template VXLIB_STATUS
165  const VXLIB_bufParams2D_t *bufParamsIn,
166  const VXLIB_meanStdDev_InitArgs *pKerInitArgs);
167 
168 /**********************************************************************************************************************/
169 /* */
170 /* VXLIB_meanStdDev_exec_ci */
171 /* */
172 /**********************************************************************************************************************/
173 
174 // this method calculates the mean and standard deviation of an input image
175 template <typename dTypeIn, typename dTypeOut>
177  void *restrict pIn,
178  void *restrict pOut0,
179  void *restrict pOut1,
180  void *restrict pPixelsProcessed,
181  void *restrict pCurrentSum,
182  void *restrict pCurrentSqSum)
183 {
184 
185  // status
186  VXLIB_STATUS status = VXLIB_SUCCESS;
187 
188  // typecast handle (void) to struct pointer type associated to kernel
189  VXLIB_meanStdDev_PrivArgs *pKerPrivArgs = (VXLIB_meanStdDev_PrivArgs *) handle;
190 
191  // structs to retrieve SE and SA paramters
192  __SE_TEMPLATE_v1 se0Params;
193 
194  // vector typedefs
195  typedef typename std::conditional<std::is_same<dTypeIn, uint8_t>::value, uint32_t, uint64_t>::type dTypeAcc;
196 
197  typedef typename std::conditional<std::is_same<dTypeIn, uint8_t>::value, c7x::uint_vec, c7x::ulong_vec>::type
198  dTypeAccVec;
199 
200  // create local pointers
201  dTypeIn *restrict pInLocal = (dTypeIn *) pIn;
202  dTypeOut *restrict pOut0Local = (dTypeOut *) pOut0;
203  dTypeOut *restrict pOut1Local = (dTypeOut *) pOut1;
204 
205  uint32_t *restrict pPixelsProcessedLocal = (uint32_t *) pPixelsProcessed;
206  dTypeAcc *restrict pCurrentSumLocal = (dTypeAcc *) pCurrentSum;
207  dTypeAcc *restrict pCurrentSqSumLocal = (dTypeAcc *) pCurrentSqSum;
208 
209 #if VXLIB_DEBUGPRINT
210  printf("Enter VXLIB_meanStdDev_exec_ci\n");
211 #endif
212 
213  // address of SE and SA parameters
214  uint8_t *pBlock = pKerPrivArgs->bufPblock;
215  size_t numBlocks = pKerPrivArgs->numBlocks;
216  size_t elemCount = 0;
217 
218  if (VXLIB_MEANSTDDEV_I8U_O32F_TEMPLATE(dTypeIn)) {
219  elemCount = c7x::element_count_of<c7x::uchar_qvec>::value;
220  }
221  else {
222  elemCount = c7x::element_count_of<c7x::ushort_qvec>::value;
223  }
224 
225  size_t width = pKerPrivArgs->width;
226  size_t height = pKerPrivArgs->height;
227  size_t stride = pKerPrivArgs->strideInElements;
228 
229  if (stride == width){
230  numBlocks = VXLIB_ceilingDiv((height * width), elemCount);
231  }
232 
233  // retrieve SE and SA parameters
234  se0Params = *(__SE_TEMPLATE_v1 *) ((uint8_t *) pBlock + SE0_PARAM_OFFSET);
235 
236  // open SEs to fetch Input samples
237  __SE0_OPEN(pInLocal, se0Params);
238 
239  // declare variables and accumulators
240  dTypeAccVec a;
241  dTypeAccVec acc, acc_sq;
242 
243  acc = (dTypeAccVec) (0);
244  acc_sq = (dTypeAccVec) (0);
245 
246  uint32_t N = width * height;
247 
248  for (int32_t counter = 0; counter < (int32_t)numBlocks; counter++) {
249 
250  // fetch se0++
251  a = c7x::strm_eng<0, dTypeAccVec>::get_adv();
252 
253  // accumulate sum
254  acc += a;
255 
256  // accumulate square sum via dotprod or mult
257  acc_sq += (a * a);
258  }
259 
260  // horizontal add sum
261  dTypeAcc sum = __horizontal_add(acc);
262 
263  // horizontal add sq sum
264  dTypeAcc sum_sq = __horizontal_add(acc_sq);
265 
266  // update pixels processed
267  *pPixelsProcessedLocal += N;
268 
269  // update sum
270  *pCurrentSumLocal += sum;
271 
272  // update square sum
273  *pCurrentSqSumLocal += sum_sq;
274 
275  // calculate mean from sum
276 
277  double sum_f = (double) *pCurrentSumLocal;
278  double sum_sq_f = (double) *pCurrentSqSumLocal;
279 
280  *pOut0Local = (dTypeOut) (sum_f / (*pPixelsProcessedLocal));
281 
282  // calculate standard deviation from sum and square sum
283  double variance = (sum_sq_f - ((sum_f * sum_f) / (*pPixelsProcessedLocal))) / (*pPixelsProcessedLocal);
284 
285  *pOut1Local = (dTypeOut) sqrtdp(variance);
286 
287  // close SE/SA
288  __SE0_CLOSE();
289 
290  return status;
291 }
292 
293 /**********************************************************************************************************************/
294 /* */
295 /* Explicit instantiations for VXLIB_meanStdDev_exec_ci */
296 /* */
297 /**********************************************************************************************************************/
298 
300  void *restrict pIn,
301  void *restrict pOut0,
302  void *restrict pOut1,
303  void *restrict pPixelsProcessed,
304  void *restrict pCurrentSum,
305  void *restrict pCurrentSqSum);
306 
308  void *restrict pIn,
309  void *restrict pOut0,
310  void *restrict pOut1,
311  void *restrict pPixelsProcessed,
312  void *restrict pCurrentSum,
313  void *restrict pCurrentSqSum);
template VXLIB_STATUS VXLIB_meanStdDev_init_ci< VXLIB_MEANSTDDEV_DTYPE_I8U_O32F >(VXLIB_kernelHandle handle, const VXLIB_bufParams2D_t *bufParamsIn, const VXLIB_meanStdDev_InitArgs *pKerInitArgs)
#define SE0_PARAM_OFFSET
static double sqrtdp(double a)
template VXLIB_STATUS VXLIB_meanStdDev_exec_ci< VXLIB_MEANSTDDEV_TYPENAME_I8U_O32F >(VXLIB_kernelHandle handle, void *restrict pIn, void *restrict pOut0, void *restrict pOut1, void *restrict pPixelsProcessed, void *restrict pCurrentSum, void *restrict pCurrentSqSum)
VXLIB_STATUS VXLIB_meanStdDev_exec_ci(VXLIB_kernelHandle handle, void *restrict pIn, void *restrict pOut0, void *restrict pOut1, void *restrict pPixelsProcessed, void *restrict pCurrentSum, void *restrict pCurrentSqSum)
This function is the main execution function for the C7x implementation of the kernel....
template VXLIB_STATUS VXLIB_meanStdDev_exec_ci< VXLIB_MEANSTDDEV_TYPENAME_I16U_O32F >(VXLIB_kernelHandle handle, void *restrict pIn, void *restrict pOut0, void *restrict pOut1, void *restrict pPixelsProcessed, void *restrict pCurrentSum, void *restrict pCurrentSqSum)
VXLIB_STATUS VXLIB_meanStdDev_init_ci(VXLIB_kernelHandle handle, const VXLIB_bufParams2D_t *bufParamsIn, const VXLIB_meanStdDev_InitArgs *pKerInitArgs)
This function is the initialization function for the C7x implementation of the kernel....
template VXLIB_STATUS VXLIB_meanStdDev_init_ci< VXLIB_MEANSTDDEV_DTYPE_I16U_O32F >(VXLIB_kernelHandle handle, const VXLIB_bufParams2D_t *bufParamsIn, const VXLIB_meanStdDev_InitArgs *pKerInitArgs)
Header file for kernel's internal use. For the kernel's interface, please see VXLIB_meanStdDev.
#define VXLIB_MEANSTDDEV_I8U_O32F_TEMPLATE(dTypeIn)
void * VXLIB_kernelHandle
Handle type for VXLIB operations.
Definition: VXLIB_types.h:247
VXLIB_STATUS_NAME
The enumeration of all status codes.
Definition: VXLIB_types.h:220
@ VXLIB_SUCCESS
Definition: VXLIB_types.h:221
@ VXLIB_UINT8
A structure for a 2 dimensional buffer descriptor.
Structure containing the parameters to initialize the kernel.
Structure that is reserved for internal use by the kernel.
uint8_t bufPblock[VXLIB_MEANSTDDEV_IXX_IXX_OXX_PBLOCK_SIZE]
Array to hold SE/SA params.
size_t height
Height of image
size_t strideInElements
Stride of input in elements.
size_t numBlocks
Number of blocks to be processed after simidfication.