简体   繁体   English

CUDA内核“只允许单个包参数”解决方法?

[英]CUDA kernel “Only a single pack parameter is allowed” workaround?

The CUDA 7 standard regarding variadic global function templates states "only a single pack parameter is allowed." 关于可变参数全局函数模板的CUDA 7标准规定“只允许单个包参数”。 Is there an elegant workaround for this? 这有一个优雅的解决方法吗? I want to be able to do something like: 我希望能够做到这样的事情:

template<int... vals>
void RecursiveFunct() {

}

template<int... vals, typename T, typename... Args>
void RecursiveFunct(T t, Args... args) {
  t.template call<vals...>();
  RecursiveFunct<vals...>(args...);
}

I'm thinking I could wrap my pack of integers into something before passing them along but is it possible to do that in a way that is transparent to the caller of this code? 我想我可以在传递它们之前将我的整数包装成一些东西但是有可能以对这段代码的调用者透明的方式这样做吗?

Not sure to understand your exactly limits but... I suppose that std::integer_sequence and a wrapper function to call call() can help you. 不确定理解你的确切限制但是...我想std::integer_sequence和一个调用call()的包装函数可以帮到你。

The following is a toy, but compilable, example that show what I mean. 以下是一个玩具,但可编辑,显示我的意思的例子。

struct foo
 {
   template <int ... vals>
   void call () const
    { std::cout << "- call " << sizeof...(vals) << std::endl; }
 };

template <typename IS>
void RecursiveFunct (IS const &)
 { }

template <typename T, int ... vals>
void wrapCall (T const & t, std::integer_sequence<int, vals...> const &)
 { t.template call<vals...>(); }


template<typename IS,  typename T, typename ... Args>
void RecursiveFunct (IS const & is, T t, Args... args)
 {
   wrapCall(t, is);
   RecursiveFunct(is, args...);
 }

int main ()
 {
   // print 5 times "- call 4"
   RecursiveFunct(std::integer_sequence<int, 2, 3, 5, 7>{},
                  foo{}, foo{}, foo{}, foo{}, foo{});
 }

Take in count that std::integer_sequence is a C++14 feature, so the preceding code needs (at least) a C++14 compiler. 接受std::integer_sequence是C ++ 14特性的计数,因此前面的代码需要(至少)一个C ++ 14编译器。

But if you need to work with C++11, it's trivial to create a std::integer_sequence substitute. 但是如果你需要使用C ++ 11,那么创建一个std::integer_sequence替换是微不足道的。

By example 以身作则

template <typename T, T ... ts>
struct myIntegerSequence
 { };

-- EDIT -- - 编辑 -

The OP ask OP问

can this work without creating an instance of integer_sequence? 这可以在不创建integer_sequence实例的情况下工作吗?

In normal C++14, yes. 在普通的C ++ 14中,是的。 Works this with Cuda? 和Cuda合作吗? I don't know. 我不知道。

I've obtained this changing the wrapCall() func with a wrapCall struct and a func() static method. 我已经使用wrapCall结构和func()静态方法更改了wrapCall()函数。 This because I've used the partial specialization that can't be used with funcs. 这是因为我使用了不能与funcs一起使用的部分特化。

The folling is the toy example 愚蠢是玩具的例子

#include <utility>
#include <iostream>

struct foo
 {
   template <int ... vals>
   void call () const
    { std::cout << "- call " << sizeof...(vals) << std::endl; }
 };

template <typename>
void RecursiveFunct ()
 { }

template <typename>
struct wrapCall;

template <int ... vals>
struct wrapCall<std::integer_sequence<int, vals...>>
 {
   template <typename T>
   static constexpr void func (T const & t)
    { t.template call<vals...>(); }
 };

template<typename IS,  typename T, typename ... Args>
void RecursiveFunct (T t, Args... args)
 {
   wrapCall<IS>::func(t);
   RecursiveFunct<IS>(args...);
 }

int main ()
 {
   // print 5 times "- call 4"
   RecursiveFunct<std::integer_sequence<int, 2, 3, 5, 7>>
                  (foo{}, foo{}, foo{}, foo{}, foo{});
 }

But are you sure that is a problem the istantiation of a std::integer_sequence ? 但是你确定这是std::integer_sequence一个问题吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM