{"id":924,"date":"2022-12-09T12:14:52","date_gmt":"2022-12-09T05:14:52","guid":{"rendered":"https:\/\/dgway.com\/blog_E\/?p=924"},"modified":"2022-12-09T12:50:06","modified_gmt":"2022-12-09T05:50:06","slug":"moving-average-accelerator-real-time-data-stream-processing","status":"publish","type":"post","link":"https:\/\/dgway.com\/blog_E\/2022\/12\/09\/moving-average-accelerator-real-time-data-stream-processing\/","title":{"rendered":"Moving Average Accelerator (Real-time data stream processing)"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/dgway.com\/blog_E\/wp-content\/uploads\/2022\/12\/\u0e2a\u0e44\u0e25\u0e14\u0e4c3-1-1024x576.png\" alt=\"\" class=\"wp-image-942\" srcset=\"https:\/\/dgway.com\/blog_E\/wp-content\/uploads\/2022\/12\/\u0e2a\u0e44\u0e25\u0e14\u0e4c3-1-1024x576.png 1024w, https:\/\/dgway.com\/blog_E\/wp-content\/uploads\/2022\/12\/\u0e2a\u0e44\u0e25\u0e14\u0e4c3-1-300x169.png 300w, https:\/\/dgway.com\/blog_E\/wp-content\/uploads\/2022\/12\/\u0e2a\u0e44\u0e25\u0e14\u0e4c3-1-768x432.png 768w, https:\/\/dgway.com\/blog_E\/wp-content\/uploads\/2022\/12\/\u0e2a\u0e44\u0e25\u0e14\u0e4c3-1.png 1280w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Moving Average Accelerator (Real-time data stream processing) <br><a href=\"https:\/\/github.com\/dg-hpcdev\/alveo-simple-examples\/tree\/main\/03_moving_average\" data-type=\"URL\" data-id=\"https:\/\/github.com\/dg-hpcdev\/alveo-simple-examples\/tree\/main\/03_moving_average\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/dg-hpcdev\/alveo-simple-examples\/tree\/main\/03_moving_average<\/a><\/figcaption><\/figure>\n<\/div>\n\n\n<p>This example demonstrate a free-running kernel. Free-running kernel is a kernel which always repeatedly execute on its own whearas normal kernel requires user command (such as&nbsp;<code>q.enqueueTask(krnl)<\/code>). One scenario one might use a free-running kernel is processing a data stream from other kernel (both RTL\/HLS) without any CPU involvement.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>The&nbsp;<code>write_stream<\/code>&nbsp;kernel read from a buffer of floats then write them to stream one by one. In real projects, this could be replaced by other data producing kernel such as streaming data from TCP<\/li>\n\n\n\n<li>The&nbsp;<code>simple_moving_average<\/code>&nbsp;kernel read the data stream from&nbsp;<code>write_stream<\/code>&nbsp;and calculate simple moving average with window size = 20 and write the result to another stream. For the sake of simplicity, the edge cases(the beginning and the end of data stream) are ignored: the sum are always divided by 20.<\/li>\n\n\n\n<li>The&nbsp;<code>read_stream<\/code>&nbsp;kernel read from&nbsp;<code>simple_moving_average<\/code>&nbsp;kernel&#8217;s output stream and write them to FPGA&#8217;s global memory waiting for user command to migrate them to host PC. If you want the kernel to directly write to host memory, see Host Memory.<\/li>\n\n\n\n<li>The&nbsp;<code>exponential_moving_average<\/code>&nbsp;kernel is similar to&nbsp;<code>simple_moving_average<\/code>&nbsp;kernel but calculates exponential moving average instead and could be interchanged. This is provided for demonstrating how to modify configuration file.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration File<\/h2>\n\n\n\n<p>These lines specify which kernels are instantiated and how many. The basic syntax is&nbsp;<code>nk=kernel_name:number_of_kernel:name_1,name_2<\/code>&nbsp;(name is optional)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>nk=simple_moving_average:1\nnk=write_stream:1\nnk=read_stream:1<\/code><\/pre>\n\n\n\n<p>These lines maps kernel port to memory.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>sp=write_stream_1.buf:DDR[0]\nsp=read_stream_1.out:DDR[0]<\/code><\/pre>\n\n\n\n<p>These lines specify stream connections between kernels<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>stream_connect=write_stream_1.data_stream:simple_moving_average_1.in\nstream_connect=simple_moving_average_1.out:read_stream_1.data_stream<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Swapping Kernel<\/h2>\n\n\n\n<p>Suppose you want to change from&nbsp;<code>simple_moving_average<\/code>&nbsp;to&nbsp;<code>exponential_moving_average<\/code><\/p>\n\n\n\n<p>First, Instantiate&nbsp;<code>exponential_moving_average<\/code>&nbsp;instead of&nbsp;<code>simple_moving_average<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>[connectivity]\nnk=exponential_moving_average:1\nnk=write_stream:1\nnk=read_stream:1<\/code><\/pre>\n\n\n\n<p>Then, correctly change the stream connections.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>stream_connect=write_stream_1.data_stream:exponential_moving_average_1.in\nstream_connect=exponential_moving_average_1.out:read_stream_1.data_stream<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Setup<\/h2>\n\n\n\n<p>This must be done everytime a new terminal is opened<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>source \/opt\/xilinx\/xrt\/setup.sh\n# Replace &lt;Vitis install path&gt; and &lt;vesion&gt;\nsource &lt;Vitis install path&gt;\/Vitis\/&lt;version&gt;\/settings64.sh\nexport PLATFORM_REPO_PATHS=\/opt\/xilinx\/platforms\n# Change to appropiate platform\nexport PLATFORM=xilinx_u250_gen3x16_xdma_4_1_202210_1<\/code><\/pre>\n\n\n\n<p>For software emulation:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>export XCL_EMULATION_MODE=sw_emu\ncd sw_emu<\/code><\/pre>\n\n\n\n<p>For hardware emulation:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">export XCL_EMULATION_MODE=hw_emu\ncd hw_emu<\/pre>\n\n\n\n<p>For hardware:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>cd hw<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Build Host Software<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>g++ -Wall -g -std=c++11 ..\/src\/host.cpp -o moving_average -I${XILINX_XRT}\/include\/ -L${XILINX_XRT}\/lib\/ -lOpenCL -pthread -lrt -lstdc++<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Build And Link Kenel<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\"><code># Replace ${TARGET} with \/ Set TARGET to:\n#  sw_emu if targeting software emulation\n#  hw_emu if targeting hardware emulation\n#  hw if targeting hardware\nv++ -c -t ${TARGET} --platform ${PLATFORM} -k exponential_moving_average -I..\/src ..\/src\/exponential_moving_average.cpp -o exponential_moving_average.xo \nv++ -c -t ${TARGET} --platform ${PLATFORM} -k simple_moving_average -I..\/src ..\/src\/simple_moving_average.cpp -o simple_moving_average.xo \nv++ -c -t ${TARGET} --platform ${PLATFORM} -k write_stream -I..\/src ..\/src\/write_stream.cpp -o write_stream.xo \nv++ -c -t ${TARGET} --platform ${PLATFORM} -k read_stream -I..\/src ..\/src\/read_stream.cpp -o read_stream.xo \nv++ -l -t ${TARGET} --platform ${PLATFORM} --config ..\/src\/moving_average.cfg .\/simple_moving_average.xo .\/read_stream.xo .\/write_stream.xo -o moving_average.xclbin<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Configure Emulator<\/h2>\n\n\n\n<p>Only when targeting software\/hardware emulation<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>emconfigutil --platform ${PLATFORM} --nd 1<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Run the host software<\/h2>\n\n\n\n<pre class=\"wp-block-preformatted\"><code>.\/moving_average moving_average.xclbin<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>This example demonstrate a free-running kernel. Free-running kernel is a kernel which always repeatedly execute on its own whearas normal kernel requires user command (such as&nbsp;q.enqueueTask(krnl)). One scenario one might use a free-running kernel is processing a data stream from other kernel (both RTL\/HLS) without any CPU involvement. Configuration File These lines specify which kernels are instantiated and how many.&#46;&#46;&#46;<\/p>\n","protected":false},"author":1,"featured_media":943,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[18],"tags":[],"class_list":["post-924","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hls-development-series"],"_links":{"self":[{"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/posts\/924","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/comments?post=924"}],"version-history":[{"count":5,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/posts\/924\/revisions"}],"predecessor-version":[{"id":948,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/posts\/924\/revisions\/948"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/media\/943"}],"wp:attachment":[{"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/media?parent=924"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/categories?post=924"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dgway.com\/blog_E\/wp-json\/wp\/v2\/tags?post=924"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}