cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
ali_flt
Contributor
Contributor
563 Views
Registered: ‎08-10-2020

variable failed dataflow checking but it's only used in one proccess

Hi,

I want to make an IP core with stream interface using Vitis Vision 2020.1 library and I think I've understood the concept of working with xf::cv:: functions. 

my core gets 4 streams of RGBA video (which are the same stream, I'll explain later why 4) and performs xf::cv::erode on each color. I've implemented this function using xf::cv::extractChannel and xf::cv::merge functions. I want all 4 color processing to be done in parallel so I need to give 4 of the same video stream to my function, each of which go to one of the 4 parallel pipes.

my core code:

/* xfOpenCV kernels */
#include "imgproc/xf_erosion.hpp"
#include "common/xf_infra.hpp"
/* Project headers */
#include "wrapper.hpp"
#include "imgproc/xf_channel_combine.hpp"


void erosion_accel(stream_t& stream_in_1,stream_t& stream_in_2,stream_t& stream_in_3,stream_t& stream_in_4, stream_t& stream_out, int height,
                        int width) {
#pragma HLS INTERFACE axis register_mode=both register port=stream_in_1
#pragma HLS INTERFACE axis register_mode=both register port=stream_in_2
#pragma HLS INTERFACE axis register_mode=both register port=stream_in_3
#pragma HLS INTERFACE axis register_mode=both register port=stream_in_4
#pragma HLS INTERFACE axis register_mode=both register port=stream_out
#pragma HLS INTERFACE s_axilite port=height bundle=CRTL_BUS
#pragma HLS INTERFACE s_axilite port=width bundle=CRTL_BUS
#pragma HLS INTERFACE ap_ctrl_none port=return  // no handshakes

#pragma HLS dataflow
	xf::cv::Mat<RGBA_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> imgInput_1(height, width);
	#pragma HLS STREAM variable=imgInput_1.data depth=2 dim=3
	xf::cv::AXIvideo2xfMat<PIXEL_WIDTH,RGBA_TYPE,HEIGHT_MAX,WIDTH_MAX,NPC1>(stream_in_1, imgInput_1);
	xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> redMat_in(height, width);
	#pragma HLS STREAM variable=redMat_in.data depth=2 dim=1
    xf::cv::extractChannel<RGBA_TYPE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1>(imgInput_1, redMat_in, XF_EXTRACT_CH_R);
    xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> redMat_out(height, width);
    #pragma HLS STREAM variable=redMat_out.data depth=2 dim=1
	unsigned char EROSION_KERNEL_1[FILTER_WIDTH_EROSION * FILTER_WIDTH_EROSION] = {
			0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0};
    xf::cv::erode<XF_BORDER_REPLICATE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, XF_SHAPE_CROSS,
		FILTER_WIDTH_EROSION, FILTER_WIDTH_EROSION, EROSION_NITER, NPC1>(
				redMat_in,redMat_out , EROSION_KERNEL_1);

	xf::cv::Mat<RGBA_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> imgInput_2(height, width);
	#pragma HLS STREAM variable=imgInput_2.data depth=2 dim=3
	xf::cv::AXIvideo2xfMat<PIXEL_WIDTH,RGBA_TYPE,HEIGHT_MAX,WIDTH_MAX,NPC1>(stream_in_2, imgInput_2);
	xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> greenMat_in(height, width);
	#pragma HLS STREAM variable=greenMat_in.data depth=2 dim=1
    xf::cv::extractChannel<RGBA_TYPE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1>(imgInput_2, greenMat_in, XF_EXTRACT_CH_G);
    xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> greenMat_out(height, width);
    #pragma HLS STREAM variable=greenMat_out.data depth=2 dim=1
	unsigned char EROSION_KERNEL_2[FILTER_WIDTH_EROSION * FILTER_WIDTH_EROSION] = {
			0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0};
    xf::cv::erode<XF_BORDER_REPLICATE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, XF_SHAPE_CROSS,
		FILTER_WIDTH_EROSION, FILTER_WIDTH_EROSION, EROSION_NITER, NPC1>(
				greenMat_in,greenMat_out , EROSION_KERNEL_2);

	xf::cv::Mat<RGBA_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> imgInput_3(height, width);
	#pragma HLS STREAM variable=imgInput_3.data depth=2 dim=3
	xf::cv::AXIvideo2xfMat<PIXEL_WIDTH,RGBA_TYPE,HEIGHT_MAX,WIDTH_MAX,NPC1>(stream_in_3, imgInput_3);
	xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> blueMat_in(height, width);
	#pragma HLS STREAM variable=blueMat_in.data depth=2 dim=1
    xf::cv::extractChannel<RGBA_TYPE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1>(imgInput_3, blueMat_in, XF_EXTRACT_CH_B);
    xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> blueMat_out(height, width);
    #pragma HLS STREAM variable=blueMat_out.data depth=2 dim=1
	unsigned char EROSION_KERNEL_3[FILTER_WIDTH_EROSION * FILTER_WIDTH_EROSION] = {
			0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0};
    xf::cv::erode<XF_BORDER_REPLICATE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, XF_SHAPE_CROSS,
		FILTER_WIDTH_EROSION, FILTER_WIDTH_EROSION, EROSION_NITER, NPC1>(
				blueMat_in,blueMat_out , EROSION_KERNEL_3);

	xf::cv::Mat<RGBA_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> imgInput_4(height, width);
	#pragma HLS STREAM variable=imgInput_4.data depth=2 dim=3
	xf::cv::AXIvideo2xfMat<PIXEL_WIDTH,RGBA_TYPE,HEIGHT_MAX,WIDTH_MAX,NPC1>(stream_in_4, imgInput_4);
	xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> AMat_in(height, width);
	#pragma HLS STREAM variable=AMat_in.data depth=2 dim=1
    xf::cv::extractChannel<RGBA_TYPE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1>(imgInput_4, AMat_in, XF_EXTRACT_CH_A);
    xf::cv::Mat<SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> AMat_out(height, width);
    #pragma HLS STREAM variable=AMat_out.data depth=2 dim=1
	unsigned char EROSION_KERNEL_4[FILTER_WIDTH_EROSION * FILTER_WIDTH_EROSION] = {
			0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0};
    xf::cv::erode<XF_BORDER_REPLICATE, SINGLE_COLOR_TYPE, HEIGHT_MAX, WIDTH_MAX, XF_SHAPE_CROSS,
		FILTER_WIDTH_EROSION, FILTER_WIDTH_EROSION, EROSION_NITER, NPC1>(
				AMat_in,AMat_out , EROSION_KERNEL_4);


	xf::cv::Mat<RGBA_TYPE, HEIGHT_MAX, WIDTH_MAX, NPC1> imgOutput(height, width);
	#pragma HLS STREAM variable=imgOutput.data depth=2 dim=3
	xf::cv::merge(blueMat_out,greenMat_out,redMat_out,AMat_out,imgOutput);

  xf::cv::xfMat2AXIvideo<PIXEL_WIDTH,RGBA_TYPE,HEIGHT_MAX,WIDTH_MAX,NPC1>(imgOutput, stream_out);
}

wrapper.hpp:

#pragma once


#include "hls_stream.h"
#include "ap_int.h"
#include "common/xf_common.hpp"
#include "common/xf_utility.hpp"
#include "imgproc/xf_channel_extract.hpp"

#include "common/xf_common.hpp"
#include "common/xf_utility.hpp"

/* Define 8 pixel version */
#define NPC1 XF_NPPC1

/* Define image format */
#define RGBA_TYPE XF_8UC4
#define SINGLE_COLOR_TYPE XF_8UC1
const int WIDTH_MAX = 2048;
const int HEIGHT_MAX = 1536;

/* Define the AXI Stream type */
const int PPC = 1;
const int bytes_per_pixel = 4;
const int PIXEL_WIDTH = 8 * bytes_per_pixel * PPC;

typedef xf::cv::ap_axiu<PIXEL_WIDTH,1,1,1> package_t;
typedef hls::stream<package_t> stream_t;


/* Accelerator specific parameters */
const int FILTER_WIDTH_EROSION = 5;
const int EROSION_NITER = 1;


/* Declare the top function - This function needs redundant inputs */
void erosion_accel(stream_t& stream_in_1,stream_t& stream_in_2,stream_t& stream_in_3,stream_t& stream_in_4, stream_t& stream_out, int height,
                        int width);

but when I try to synthesis i get the following result:

ERROR: [HLS 200-977] Argument 'stream_in_1_V' failed dataflow checking: it can only be used in one process.
WARNING: [HLS 200-992] Argument 'stream_in_1_V' has read operations in process function 'Loop_loop_wait_for_start_proc26'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
WARNING: [HLS 200-992] Argument 'stream_in_1_V' has read operations in process function 'Loop_loop_height_proc'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
ERROR: [HLS 200-977] Argument 'stream_in_2_V' failed dataflow checking: it can only be used in one process.
WARNING: [HLS 200-992] Argument 'stream_in_2_V' has read operations in process function 'Loop_loop_wait_for_start_proc1529'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
WARNING: [HLS 200-992] Argument 'stream_in_2_V' has read operations in process function 'Loop_loop_height_proc16'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
ERROR: [HLS 200-977] Argument 'stream_in_3_V' failed dataflow checking: it can only be used in one process.
WARNING: [HLS 200-992] Argument 'stream_in_3_V' has read operations in process function 'Loop_loop_wait_for_start_proc1832'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
WARNING: [HLS 200-992] Argument 'stream_in_3_V' has read operations in process function 'Loop_loop_height_proc19'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
ERROR: [HLS 200-977] Argument 'stream_in_4_V' failed dataflow checking: it can only be used in one process.
WARNING: [HLS 200-992] Argument 'stream_in_4_V' has read operations in process function 'Loop_loop_wait_for_start_proc2135'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html
WARNING: [HLS 200-992] Argument 'stream_in_4_V' has read operations in process function 'Loop_loop_height_proc22'.
Resolution: For help on HLS 200-992 see www.xilinx.com/html_docs/xilinx2020_1/hls-guidance/200-992.html


As you can see in my DATAFLOW, each stream_in  (stream_in1 to stream_in4) has been used in only one xf::cv::AXIvideo2xfMat function and no other place.
Can someone please try to understand why i'm getting this error? 
Similar issue I found on forum: https://forums.xilinx.com/t5/High-Level-Synthesis-HLS/HLS-failed-dataflow-checking/td-p/1049741
Thanks in advance,

Ali

 

0 Kudos
3 Replies
ali_flt
Contributor
Contributor
462 Views
Registered: ‎08-10-2020

After waiting for the Xilinx Employees for a fix and not receiving even a comment, I've tried to fix the function myself. I tested it in Csim and in hardware implementation and it seems to be working. What I basically did was merging the loop_wait_for_start and loop_height in a single loop. I've attached the modified "xf_infra.hpp" file.

Note: Additionally I've noticed that the structs defined in "xf_axi_sdata.hpp" are not getting synthesized correctly either :))
so I included <ap_axi_sdata.h> library instead to get the ap_axiu struct working properly.

0 Kudos
scampbell
Moderator
Moderator
446 Views
Registered: ‎10-04-2011

Hello @ali_flt ,

We have identified an issue with the xf_infra.hpp file and are working on verifying that. The bug was related to a different issue, but may repair this as well. Can you attach a test project so that I make sure I have all of your settings / directives correct so I can verify this is working? I think this verified file is the best way forward but appreciate your creating a work around until we can release that to the community. If you could provide that project then I would appreciate it. 

Thank you,
Scott

0 Kudos
ali_flt
Contributor
Contributor
402 Views
Registered: ‎08-10-2020

Dear Scott,


Thank you very much for your response. I am looking forward to seeing the fix for this issue. 
Additionally I wanted to mention that in addition to xf_infra.hpp file, I believe the xf_axi.hpp has compilation issues too. I would be really glad if you could check that out too. 
The post related to this problem: https://forums.xilinx.com/t5/High-Level-Synthesis-HLS/Vitis-Vision-library-xf-cv-cvMat2AXIvideoxf-problem/td-p/1043645 
Sincerely,
Ali

0 Kudos