重复的可变参数模板参数
Duplicate variadic template parameter
上下文:
我是一名Jr.软件工程师,希望我不是在重新发明轮子,请告诉我。 我想创建一个模板函数,它包装并调用另一个函数元素。例如:
// returns a*x + y
__device__ float saxpy(float a, float x, float y) {
return a*x + y;
}
int main() {
int A[4] = { 1,2,3,4 };
int X[4] = { 1,2,3,4 };
int Y[4] = { 1,1,1,1 };
// A*X = 1,4,9,16
// A*X+Y = 2,5,10,17
float *C = cudaReduce(saxpy, A, X, Y);
for (int i = 0; i < 4; i++)
printf("%d, ", C[i]); // should print "2, 5, 10, 17, "
std::cin.ignore();
return 0;
}
重要的是,我想创建这个包装器,以便在我执行元素级操作时很好地包装 cuda 调用。虽然非常不完整,但这是我对函数包装器的伪代码尝试。
我想提供一个最小的例子;但是,我对C++的某些方面知之甚少,所以请原谅大量注释的伪代码:
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <iostream>
// returns a*x + y
__device__ float saxpy(float a, float x, float y) {
return a*x + y;
}
// finds return type of function pointer
template<typename R, typename... A>
R ret(R(*)(A...));
template<typename C, typename R, typename... A>
R ret(R(C::*)(A...));
template<typename F, size_t N, typename... Args>
auto cudaReduce(F &f, Args(&...argsarray)[N]) {
cudaSetDevice(0);
// ret is function f's return type
typedef decltype(ret(f)) ret;
ret d_out[N], h_out[N];
// cudaMalloc((void**)&d_out, sizeof(d_out));
sendToCuda(argsarray...); // allocates and copies all contents of argsarray to cuda
// reduceKernel<<<1, N>>>(f, d_out, dev_argsarray...);
// cudaDeviceSynchronize();
// cudaMemcpy(h_out, d_out, sizeof(h_out), cudaMemcpyDeviceToHost);
// cudaFree(d_out);
// for d_args in d_argsarray
// cudaFree(d_args);
return h_out;
}
template<typename F, size_t N, typename Out, typename... Args>
__global__ void cudaReduceKernel(F &f, Out(&out)[N], Args(&...argsarray)[N]) {
int tid = threadIdx.x;
int i = tid + blockIdx.x * blockDim.x;
// Below is invalid syntax; however, the 'pseudo-code' is what I'd like to achieve.
// out[i] = f(argsarray[i]...);
}
// cuda malloc and memcpy
template<typename Arg, size_t N>
void sendToCuda(Arg(&args)[N]) {
size_t buffer = sizeof(args);
//cudaMalloc((void**)&dev_arg[ ??? ], buffer);
//cudaMemcpy((void**)&dev_arg[ ??? ], args, buffer, cudaMemcpyHostToDevice);
}
template<typename Arg, size_t N, typename... Args>
void sendToCuda(Arg(&args)[N], Args(&...argsarray)[N]) {
sendToCuda(args);
sendToCuda(argsarray...);
}
int main() {
int A[4] = { 1,2,3,4 };
int X[4] = { 1,2,3,4 };
int Y[4] = { 1,1,1,1 };
// A*X = 1,4,9,16
// A*X+Y = 2,5,10,17
float *C = cudaReduce(saxpy, A, X, Y);
for (int i = 0; i < 4; i++)
printf("%d, ", C[i]); // should print "2, 5, 10, 17, ", currently prints undefined behaviour
std::cin.ignore();
return 0;
}
我意识到不是每个人都有时间完全审查代码,所以我将关键问题归结为几点:
1. 是否可以复制可变参数模板输入,如果是,如何复制? EX(非真实代码(:
template<typename... Args>
void foo(Args... args) {
Args... args2;
}
这是必需的,以便我可以将我的输入参数复制到我的 cudamalloc()
和memcpy()
的输入参数。
阿拉伯数字。 我将如何处理可变参数数组参数的第 i 个元组,例如在 python 中压缩。 EX(非真实代码(:
template<typename... Args, size_t N>
void bar(Args(&...argsarray)[N]) {
// (python) ithvariadic = zip(*argsarray)[i]
auto ithvariadic = argsarray[i]...;
}
- 是否可以复制可变参数模板输入,如果是,如何复制?EX(非真实代码(:
template <typename... Args>
void foo(Args... args) {
Args2... args;
}
不是那样的。
Args...
个类型名称是args...
参数的免赔额。
但是大约Args2...
?你怎么能推断出它们?你想解释它们吗?
但是您确定需要不同的类型吗?
如果你不需要不同的类型列表,正如Jarod42所建议的那样,我能想象到的最好的就是使用元组
。如下内容
template <typename ... Args>
void foo (Args ... args)
{
std::tuple<Args...> tpl { args... };
// do something with tpl`
}
或者,如果您想启用完美转发,
template <typename ... Args>
void foo (Args && ... args)
{
std::tuple<Args...> tpl { std::forward<Args>(args)... };
// do something with tpl`
}
- 我将如何处理可变参数数组参数的第 i 个元组,就像在 python 中压缩一样。EX(非真实代码(:
template<typename... Args, size_t N>
void bar(Args(&...argsarray)[N]) {
// (python) ithvariadic = zip(*argsarray)[i]
auto ithvariadic = argsarray[i]...;
}
怎么样
template <typename ... Args, std::size_t N>
void bar (Args (&...argsarray)[N])
{
for ( auto ui = 0u ; ui < N ; ++ui )
{
std::tuple<Args...> ithvariadic { argsarray[ui]... };
// do something with ithvariadic
}
}
?
相关文章:
- 在不传递参数数量且只有3个点的情况下,如何使用变差函数
- 如何使用可变参数模板强制转换每个变体类型
- 关于如何在具有单个参数的变体构造中选择替代方案?
- 调用参数排列不变函数 f(i++, i++)
- 参数归纳与标准::变体
- 模板化回调参数的逆变,如 C# 中的逆变
- 如何在没有参数包的情况下编写变差函数
- 通过具有嵌套类的工厂类获取多个变异类模板参数包
- 获取模板参数的成员变量值列表
- 保留短 lambda 用作函数的中间参数,使用 clang 格式保持不变
- 如何定义变体<x,y,z>提取模板参数的子类型
- 正确对齐内存模板,参数顺序不变
- 递归中不同参数类型的变元模板函数
- 通过函数指针传递给变差函数的参数会更改其值
- 提升预定义为带有参数的全局 lambda 的变体访问者
- 使用可变参数模板参数提升变体访问者
- boost ::变体 - 为什么模板参数比const字符串参数具有更高的优先级
- 将变参数包中的值加载到临时数组中
- 使用额外参数提升变体访客
- 正在将动态数组元素解析为参数?(变音符)