【问题标题】:Template class with template method id具有模板方法 ID 的模板类
【发布时间】:2021-10-22 08:32:02
【问题描述】:

我正在尝试为我的方法创建一个标识符。这个标识符对我的工作很重要,因为它实际上是硬件综合。

我有以下模板类:

        template <int FF_COUNT, int FB_COUNT, int NEXT_COUNT>
        class Core{
        public:
        ...
            template<int id> void consume_fb_events (hls::stream<event>  feedback_stream [FB_COUNT] [FB_COUNT], weight w_mem [128*128]);
        }
    


template <int FF_COUNT, int FB_COUNT, int NEXT_COUNT>
    template <int id>
    void Core<FF_COUNT, FB_COUNT, NEXT_COUNT>::consume_fb_events (hls::stream<event> feedback_stream [FB_COUNT] [FB_COUNT], weight w_mem [128*128]){
    #pragma HLS INLINE off
    event e;   
            for(int i = 0 ; i < FB_COUNT ; i++) {
                while (!feedback_stream[id][i].empty()) {
                    feedback_stream[id][i].read(e);
                    ap_uint<16> mem_offset = e << size_exp;
                    consume_event (e, mem_offset, w_mem);    
            }
    }
    }

这是我的函数调用

    #define sth 8
for int i = 0 ; i < sth; i++
    core[i].consume_fb_events<i>(....);

我得到编译错误:

ERROR: [HLS 200-70] Compilation errors found: In file included from c1/srnn.cpp:1:
c1/srnn.cpp:197:14: error: no matching member function for call to 'consume_fb_events'
   core_1[i].consume_fb_events<i>(buffer_layer1_1, w1[i]);
   ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~
c1/core.h:52:24: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'id'
 template<int id> void consume_fb_events (hls::stream<event> feedback_stream [FB_COUNT] [FB_COUNT], weight w_mem [128*128]);
                   ^

【问题讨论】:

  • 你不能使用i 作为模板参数,因为它在编译时是未知的。为什么不把它变成一个普通参数呢?
  • 使其成为普通参数意味着它在编译时是未知的。我需要它以我的硬件合成而闻名。
  • sth 在编译时是否已知?如果是这样,您需要一个 constexpr 类型的循环 - 如果它不知道,i 也不能。
  • 是的,某事确实是一个常数值。你能告诉我如何指定吗?
  • 定义如下:#define C1_UNROLL 8 for (int i = 0 ; i (...)

标签: c++ templates vivado-hls


【解决方案1】:

您正在寻找的是编译时的 for 循环。因为模板参数必须是一个constexpr。我通常这样做,因为你不能在 constexpr 函数中有 for 循环:

template<int i>
struct MyFunc
{
    MyFunc()
    {
        // do something with i
        core[i].consume_fb_events<i>(....);
    }
};

template<int end, template <int I> class func, int i = 0>
struct ForLoop
{
    ForLoop()
    {
        func<i>{};
        ForLoop<end, func, i+1>{};
    }
};

template<int end, template <int I> class func>
struct ForLoop<end, func, end>
{
    ForLoop()
    {
    }
};

你可以在MyFunc的构造函数中运行任何代码。

然后你可以这样执行它:

ForLoop<8, MyFunc>{};

其中 8 是您通常使用的数字,但位于 for 循环的 i &lt; ... 部分

您必须小心这一点,因为这仅适用于 end 最多约 900(取决于最大模板递归深度)。否则你会得到一个编译时错误。

live example with std::cout

编辑:


由于@SherifBadawy 在评论中询问,您不必声明结构/类MyFunc 来执行此操作,但我采用了这种方法,因为它使ForLoop 更具动态性,您可以多次重复使用它次。

但是,如果您愿意,这也可以:

template<int i>
void foo()
{
    // code here
}

template<int end, int i = 0>
struct ForLoop
{
    ForLoop()
    {
        core[i].consume_fb_events<i>(....);
        // more code

        // or ...

        foo<i>();

        ForLoop<end, func, i+1>{};
    }
};

template<int end>
struct ForLoop<end, end>
{
    ForLoop()
    {
    }
};

要运行ForLoop,你会再次这样做:

ForLoop<8>{}; // without passing a class or function

【讨论】:

  • 感谢您的回答能否请您重新检查是否有错别字?什么是 func{};?你是说 MyFunc 吗?
  • 模板 class Core{ public: template struct consume_function { void consume_ff_events (hls::stream input_stream [FB_COUNT] [ FF_COUNT] , 权重 w_mem [128 * 128]); void consume_fb_events (hls::stream feedback_stream [FB_COUNT] [FB_COUNT], weight w_mem [128*128]){ };到目前为止,这就是我实现它的方式......对吗?
  • @SherifBadawy 不,func 是模板参数,它的使用有点像 lambda,但如果您愿意,也可以直接调用 MyFunc。使用模板参数,它变得更加动态和可重用。
  • @SherifBadawy 应该是,当然你也可以在ForLoop的构造函数中使用模板化函数代替类构造函数
  • 所以我不需要 struct "consume function"?我可以只使用普通的模板函数声明,而是在 ForLoop 的构造函数中调用函数?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 2011-10-24
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多