Program Listing for File xf_reduce.hpp
↰ Return to documentation for file (/tmp/ws/src/vitis_common/include/imgproc/xf_reduce.hpp
)
/*
* Copyright 2019 Xilinx, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _XF_REDUCE_HPP_
#define _XF_REDUCE_HPP_
#ifndef __cplusplus
#error C++ is needed to include this header
#endif
typedef unsigned short uint16_t;
typedef unsigned char uchar;
#include "hls_stream.h"
#include "../common/xf_common.hpp"
#include "../common/xf_utility.hpp"
namespace xf {
namespace cv {
template <int SRC_T,
int DST_T,
int ROWS,
int COLS,
int ONE_D_HEIGHT,
int ONE_D_WIDTH,
int DEPTH,
int NPC,
int WORDWIDTH_SRC,
int WORDWIDTH_DST,
int COLS_TRIP,
int REDUCE_OP>
void xFreduceKernel(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& _src_mat,
xf::cv::Mat<DST_T, ONE_D_HEIGHT, ONE_D_WIDTH, 1>& _dst_mat,
unsigned char dim,
unsigned short height,
unsigned short width) {
XF_SNAME(WORDWIDTH_SRC) val_src;
XF_SNAME(WORDWIDTH_DST) val_dst;
unsigned long long int p = 0, q = 0;
unsigned char max = 0;
short int depth = XF_DTPIXELDEPTH(SRC_T, NPC) / XF_CHANNELS(SRC_T, NPC);
XF_SNAME(WORDWIDTH_DST) internal_res;
XF_SNAME(WORDWIDTH_DST) line_buf[(COLS >> XF_BITSHIFT(NPC))];
// clang-format off
#pragma HLS RESOURCE variable=line_buf core=RAM_S2P_BRAM
// clang-format on
if (dim == 0) {
for (int i = 0; i < (width >> XF_BITSHIFT(NPC)); i++) {
// clang-format off
#pragma HLS pipeline
// clang-format on
line_buf[i] = _src_mat.read(i);
}
}
ap_uint<13> i, j, k, planes;
unsigned int var;
if (dim == 0) {
var = 1;
} else {
var = 0;
}
rowLoop:
for (i = var; i < height; i++) {
// clang-format off
#pragma HLS LOOP_TRIPCOUNT min=ROWS max=ROWS
#pragma HLS LOOP_FLATTEN off
// clang-format on
if (REDUCE_OP == REDUCE_MIN) {
internal_res = -1;
max = 255;
} else {
internal_res = 0;
max = 0;
}
colLoop:
for (j = 0; j < width; j++) {
// clang-format off
#pragma HLS LOOP_TRIPCOUNT min=COLS_TRIP max=COLS_TRIP
#pragma HLS pipeline
// clang-format on
val_src =
(XF_SNAME(WORDWIDTH_SRC))(_src_mat.read(i * width + j)); // reading the source stream _src into val_src
if (dim == 0) {
internal_res = line_buf[j];
}
switch (REDUCE_OP) {
case REDUCE_SUM:
internal_res = internal_res + val_src;
break;
case REDUCE_AVG:
internal_res = internal_res + val_src;
break;
case REDUCE_MAX:
internal_res =
((XF_SNAME(WORDWIDTH_SRC))internal_res > val_src ? (XF_SNAME(WORDWIDTH_SRC))internal_res
: val_src);
break;
case REDUCE_MIN:
internal_res =
((XF_SNAME(WORDWIDTH_SRC))internal_res < val_src ? (XF_SNAME(WORDWIDTH_SRC))internal_res
: val_src);
break;
}
if (dim == 1 && j == width - 1) {
if (REDUCE_OP == REDUCE_AVG) {
val_dst = internal_res / width;
} else {
val_dst = internal_res;
}
}
if (dim == 0) {
val_dst = internal_res;
line_buf[j] = val_dst;
}
}
if (dim == 1) {
_dst_mat.write(q, val_dst);
q++;
}
}
if (dim == 0) {
for (unsigned int out = 0; out < ((width >> XF_BITSHIFT(NPC))); out++) {
if ((REDUCE_OP == REDUCE_SUM)) {
_dst_mat.write(q, line_buf[out]);
q++;
} else if (REDUCE_OP == REDUCE_AVG) {
_dst_mat.write(q, line_buf[out] / height);
q++;
} else {
_dst_mat.write(q, line_buf[out]);
q = q + 1;
}
}
}
}
template <int REDUCE_OP, int SRC_T, int DST_T, int ROWS, int COLS, int ONE_D_HEIGHT, int ONE_D_WIDTH, int NPC = 1>
void reduce(xf::cv::Mat<SRC_T, ROWS, COLS, NPC>& _src_mat,
xf::cv::Mat<DST_T, ONE_D_HEIGHT, ONE_D_WIDTH, 1>& _dst_mat,
unsigned char dim) {
unsigned short width = _src_mat.cols >> XF_BITSHIFT(NPC);
unsigned short height = _src_mat.rows;
#ifndef __SYNTHESIS__
assert(((NPC == XF_NPPC1) || (NPC == XF_NPPC8)) && "NPC must be XF_NPPC1, XF_NPPC8");
assert(((height <= ROWS) && (width <= COLS)) && "ROWS and COLS should be greater than input image");
#endif
// clang-format off
#pragma HLS INLINE OFF
// clang-format on
xFreduceKernel<SRC_T, DST_T, ROWS, COLS, ONE_D_HEIGHT, ONE_D_WIDTH, XF_DEPTH(SRC_T, NPC), NPC,
XF_WORDWIDTH(SRC_T, NPC), XF_WORDWIDTH(DST_T, NPC), (COLS >> XF_BITSHIFT(NPC)), REDUCE_OP>(
_src_mat, _dst_mat, dim, height, width);
}
} // namespace cv
} // namespace xf
#endif