来自here。
假设dev_X是一个向量。
int * X = (int*) malloc( ThreadsPerBlockX * BlocksPerGridX * sizeof(*X) );
for ( int i = 0; i < ThreadsPerBlockX * BlocksPerGridX; i++ )
X[ i ] = i;
// create device vectors
thrust::device_vector<int> dev_X ( ThreadsPerBlockX * BlocksPerGridX );
//copy to device
thrust::copy( X , X + theThreadsPerBlockX * theBlocksPerGridX , dev_X.begin() );
以下是减法:
thrust::transform( dev_Kx.begin(), dev_Kx.end(), dev_X.begin() , distX.begin() , thrust::minus<float>() );
dev_Kx - dev_X.
我想使用整个dev_Kx
向量(因为它使用的是因为它从.begin到.end())和整个dev_X
向量。
以上代码使用dev_X.begin()
。
这是否意味着它将使用整个dev_X
向量?从头开始?
或者我必须使用另一个额外的参数来指向dev_X.end()
? (因为在上面的函数调用中我不能只使用这个额外的参数)
另外,例如:
如果我想使用
thrust::transform( dev_Kx, dev_Kx + i , dev_X.begin() ,distX.begin() , thrust::minus<int>() );
然后dev_Kx
会从0到i和dev_X.begin()
?它将使用相同的长度? (0到i?)或者它将使用dev_X
的长度?
答案 0 :(得分:7)
许多thrust
(和标准库)函数将范围作为第一个参数,然后假设所有其他迭代器都由相同大小的容器支持。范围是一对迭代器,表示序列的开头和 end 。
例如:
thrust::copy(
X.begin(), // begin input iterator
X.end(), // end input iterator
dev_X.begin() // begin output iterator
);
这会将X
的全部内容复制到dev_X
。为什么不需要dev_X.end()
?因为thrust
要求您(程序员)需要正确调整dev_X
的大小,以便能够包含至少与输入范围中一样多的元素。如果您不满足该保证,则行为未定义。
执行此操作时:
thrust::transform(
dev_Kx.begin(), // begin input (1) iterator
dev_Kx.end(), // end input (1) iterator
dev_X.begin(), // begin input (2) iterator
distX.begin(), // output iterator
thrust::minus<float>()
);
thrust
看到的输入范围是dev_Kx.begin()
到dev_Kx.end()
。它的显式大小为dev_Kx.end() - dev_Kx.begin()
。为什么不需要dev_X.end()
和distX.end()
?因为它们的隐式大小也是dev_Kx.end() - dev_Kx.begin()
。例如,如果dev_Kx
中有10个元素,则transform
将:
dev_Kx
dev_X
的10个元素(必须至少包含 10个元素)distX
中,该结果必须至少能够容纳 10个元素。也许看看实施会消除任何疑虑。这是一些伪代码:
void transform(InputIterator input1_begin, InputIterator input1_end,
InputIterator input2_begin, OutputIterator output,
BinaryFunction op) {
while (input1_begin != input1_end) {
*output++ = op(*input1_begin++, *input2_begin++);
}
}
注意如何只需要一个结束迭代器。
在不相关的说明中,以下内容:
int * X = (int*) malloc( ThreadsPerBlockX * BlocksPerGridX * sizeof(*X) );
for ( int i = 0; i < ThreadsPerBlockX * BlocksPerGridX; i++ )
X[ i ] = i;
可以用更惯用,更不容易出错的C ++重写为:
std::vector<int> X(ThreadsPerBlockX * BlocksPerGridX);
std::iota(X.begin(), X.end(), 0);