如何在Vitis HLS中平坦的非完美循环

发布于 2025-01-21 15:16:55 字数 1950 浏览 1 评论 0原文

我的项目是将输入字符串编码为整数向量。我已经有一个编码方法。我创建了一个查找表并开始流入输入字符串。将输入字符串的每个字符的每个字符比较到查找表的char键,获取向量值并将它们添加。这是一个示例:

lookup table
$       {1, -1, -1, 1, -1, ...., 1}
c       {1, -1, 1, 1, 1, ...., 1}
C       {1, 1, -1, 1, -1, ...., 1}
....
*       {-1, 1, -1, 1, -1, ...., 1}
&       {1, 1, -1, 1, 1, ...., 1}

input[in_len] = {'*','C','(','=','O',')','[','C','@','H',']','(','C','C','C','C','N','C','(','=','O',')','O','C','C','O','C',')','N','C','(','=','O',')','O','C','C','O','C'};
""

这是我的代码:

void ENCODING_HV(FPGA_DATA input[in_len], 
                 FPGA_DATA lookup_key[NUM_TOKEN], 
                 LOOKUP_DATA lookup_HV[NUM_TOKEN],
                 int result_HV[CHUNK_NUM][CHUNK_SIZE]){
    
    for(int i = 0; i < in_len; i++){
        for(int j = 0; j < NUM_TOKEN; j++){
            if(input[i] == lookup_key[j]){
                for(int k = 0; k < CHUNK_NUM; k++){
    //#pragma HLS PIPELINE II=1
                    for(int l = 0; l < CHUNK_SIZE; l++){
    #pragma HLS ARRAY_RESHAPE variable=lookup_HV complete dim=3
    #pragma HLS ARRAY_RESHAPE variable=result complete dim=2
                        if(lookup_HV[j].map[k][l] == -1)
                            result_HV[k][l] = result_HV[k][l] + 1;
                        else
                            result_HV[k][l] = result_HV[k][l] - 1;
                    }
                }
            }
        }
    }
}

在第二个循环中,我有一个if语句将输入字符与查找表的关键char进行比较。 Vitis HLS说,“不能扁平循环'vitis_​​loop_60_2'”,并且需要很长时间才能合成。谁能给我一个想法怎么做? 谢谢

WARNING: [HLS 200-960] Cannot flatten loop 'VITIS_LOOP_60_2' (Stream_Interface/HLS_scholarly/data_tokenize_2.cpp:60:28) in function 'create_sample_HV' the outer loop is not a perfect loop because there is nontrivial logic before entering the inner loop.
Resolution: For help on HLS 200-960 see www.xilinx.com/cgi-bin/docs/rdoc?v=2021.1;t=hls+guidance;d=200-960.html

My project is to encode an input string into an integer vector. I already have an encoding method. I create a lookup table and begin to stream the input string in. Compare each char of the input string to the char key of the lookup table, get the vector value and add them up. Here is an example:

lookup table
$       {1, -1, -1, 1, -1, ...., 1}
c       {1, -1, 1, 1, 1, ...., 1}
C       {1, 1, -1, 1, -1, ...., 1}
....
*       {-1, 1, -1, 1, -1, ...., 1}
&       {1, 1, -1, 1, 1, ...., 1}

input[in_len] = {'*','C','(','=','O',')','[','C','@','H',']','(','C','C','C','C','N','C','(','=','O',')','O','C','C','O','C',')','N','C','(','=','O',')','O','C','C','O','C'};
""

Here is my code:

void ENCODING_HV(FPGA_DATA input[in_len], 
                 FPGA_DATA lookup_key[NUM_TOKEN], 
                 LOOKUP_DATA lookup_HV[NUM_TOKEN],
                 int result_HV[CHUNK_NUM][CHUNK_SIZE]){
    
    for(int i = 0; i < in_len; i++){
        for(int j = 0; j < NUM_TOKEN; j++){
            if(input[i] == lookup_key[j]){
                for(int k = 0; k < CHUNK_NUM; k++){
    //#pragma HLS PIPELINE II=1
                    for(int l = 0; l < CHUNK_SIZE; l++){
    #pragma HLS ARRAY_RESHAPE variable=lookup_HV complete dim=3
    #pragma HLS ARRAY_RESHAPE variable=result complete dim=2
                        if(lookup_HV[j].map[k][l] == -1)
                            result_HV[k][l] = result_HV[k][l] + 1;
                        else
                            result_HV[k][l] = result_HV[k][l] - 1;
                    }
                }
            }
        }
    }
}

In the second for loop I have an if statement to compare the input char with key char of lookup table. And the Vitis HLS said that "Cannot flatten loop 'VITIS_LOOP_60_2'", and it take a long time to synthesis. Could anyone give me an idea how to do it?
Thank you

WARNING: [HLS 200-960] Cannot flatten loop 'VITIS_LOOP_60_2' (Stream_Interface/HLS_scholarly/data_tokenize_2.cpp:60:28) in function 'create_sample_HV' the outer loop is not a perfect loop because there is nontrivial logic before entering the inner loop.
Resolution: For help on HLS 200-960 see www.xilinx.com/cgi-bin/docs/rdoc?v=2021.1;t=hls+guidance;d=200-960.html

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我不会写诗 2025-01-28 15:16:55

免责声明:由于您没有提供完整的代码,因此我无法亲自测试我的解决方案。

在性能方面,按照经验,如果在硬件和HLS中陈述“廉价”,因为它们大部分时间都在Muxes中解决。在软件中,它们会导致不连续性。

在您的算法中,if-Statement守卫两个嵌套的前循环,最终不会执行它们。但是,在HLS中,for-loops不能只是“跳过”,因为它们最终会代表某些物理硬件组件。因此,通过查看您的代码,我会在嵌套的前面移动if-Statement ,因为它不会影响算法

因此,最终的解决方案可能是:

void ENCODING_HV(FPGA_DATA input[in_len], 
                 FPGA_DATA lookup_key[NUM_TOKEN], 
                 LOOKUP_DATA lookup_HV[NUM_TOKEN],
                 int result_HV[CHUNK_NUM][CHUNK_SIZE]){
#pragma HLS ARRAY_RESHAPE variable=lookup_HV complete dim=3
#pragma HLS ARRAY_RESHAPE variable=result complete dim=2
    for(int i = 0; i < in_len; i++){
        for(int j = 0; j < NUM_TOKEN; j++){
            for(int k = 0; k < CHUNK_NUM; k++){
#pragma HLS PIPELINE II=1
                for(int l = 0; l < CHUNK_SIZE; l++){
                    if(input[i] == lookup_key[j]){
                        if(lookup_HV[j].map[k][l] == -1)
                            result_HV[k][l] = result_HV[k][l] + 1;
                        else
                            result_HV[k][l] = result_HV[k][l] - 1;
                    }
                }
            }
        }
    }
}

旁注:通过将所有IF仪式保留在嵌套的前路内,您甚至可以将管道实用程序移动到上方,以完全展开最内部的前面循环。

Disclaimer: since you aren't providing a full code, I cannot test my solution myself.

Performance-wise, as a rule of thumb, if-statements are "cheap" in hardware and HLS, since they most of the time resolve in MUXes. That is not true in software, where they cause discontinuities.

In your algorithm, the if-statement guards two nested for-loops and eventually does not execute them. However, in HLS, for-loops cannot just be "skipped", because they will end up representing some physical hardware components. Hence, by looking at your code, I would move the if-statement inside the nested for-loops, since it doesn't affect the algorithm.

A final solution might therefore be:

void ENCODING_HV(FPGA_DATA input[in_len], 
                 FPGA_DATA lookup_key[NUM_TOKEN], 
                 LOOKUP_DATA lookup_HV[NUM_TOKEN],
                 int result_HV[CHUNK_NUM][CHUNK_SIZE]){
#pragma HLS ARRAY_RESHAPE variable=lookup_HV complete dim=3
#pragma HLS ARRAY_RESHAPE variable=result complete dim=2
    for(int i = 0; i < in_len; i++){
        for(int j = 0; j < NUM_TOKEN; j++){
            for(int k = 0; k < CHUNK_NUM; k++){
#pragma HLS PIPELINE II=1
                for(int l = 0; l < CHUNK_SIZE; l++){
                    if(input[i] == lookup_key[j]){
                        if(lookup_HV[j].map[k][l] == -1)
                            result_HV[k][l] = result_HV[k][l] + 1;
                        else
                            result_HV[k][l] = result_HV[k][l] - 1;
                    }
                }
            }
        }
    }
}

Side note: by keeping all the if-statements inside the nested for-loops, you can even move the PIPELINE pragma above to fully unroll the most inner for-loops.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文