标签: thrust

在CUDA中按键排序3个数组(也许使用Thrust)

我有3相同大小的数组(超过300.000元素).一个浮点数和两个索引数组.所以,对于每个号码我都有2ID.

所有3阵列都已经在GPU全局内存中.我想相应地将所有数字与他们的ID排序.

有什么方法可以使用Thrust库来完成这项任务吗?有没有比推力图书馆更好的方法?

当然,我不喜欢将它们复制到主机内存中几次.顺便说一句,他们的数组不是向量.

感谢您的帮助.


暂时的解决方案,但这是非常缓慢的.它需要几4秒钟,我的数组大小按顺序排列300000

thrust::device_ptr<float> keys(afterSum);
thrust::device_ptr<int> vals0(d_index);
thrust::device_ptr<int> vals1(blockId); 

thrust::device_vector<int> sortedIndex(numElements);
thrust::device_vector<int> sortedBlockId(numElements);

thrust::counting_iterator<int> iter(0);
thrust::device_vector<int> indices(numElements);
thrust::copy(iter, iter + indices.size(), indices.begin()); 

thrust::sort_by_key(keys, keys + numElements , indices.begin());    

thrust::gather(indices.begin(), indices.end(), vals0, sortedIndex.begin());
thrust::gather(indices.begin(), indices.end(), vals1, sortedBlockId.begin());

thrust::host_vector<int> h_sortedIndex=sortedIndex;
thrust::host_vector<int> h_sortedBlockId=sortedBlockId;
Run Code Online (Sandbox Code Playgroud)

sorting cuda gpu thrust

7
推荐指数
1
解决办法
5558
查看次数

OpenCV GPU库对矩阵运算有多好?

我正在将OpenCV用于计算机视觉应用.我想在GPU上加速一些矩阵运算(矩阵相当大),并且如果可能的话,希望避免直接在CUDA C中进行编码.OpenCV 2.4.1具有许多GPU加速功能.他们的体验表现如何?我最好还是使用另一个库(例如Thrust)吗?

EDIT 示例应用:计算GPU上的平方欧几里德距离矩阵.目前,我在Matlab中使用并行计算工具箱(PCT)进行的GPU加速(和矢量化)实现比使用OpenCV的C++实现快5到10倍.

Matlab实现:

function K = sqEuclideanDist(P_cpu,Q_cpu)
% Vectorized method to compute pairwise squared Euclidean distance on GPU
% Returns K(i,j) = (P(i,:) - Q(j,:))'*(P(i,:) - Q(j,:))

P_gpu = gpuArray(P_cpu);
Q_gpu = gpuArray(Q_cpu);

[nP, d] = size(P_gpu);
[nQ, d] = size(Q_gpu);

pmag = sum(P_gpu .* P_gpu, 2);
qmag = sum(Q_gpu .* Q_gpu, 2);

% note that K is on GPU
K = ones(nP,1)*qmag' + pmag*ones(1,nQ) - 2*P_gpu*Q_gpu';

end
Run Code Online (Sandbox Code Playgroud)

更新这是另一个完成相同的Matlab实现(感谢/sf/answers/544202641/).但它仅在CPU上运行,因为bsxfunPCT不支持.仍然在寻找C++替代品.

function …
Run Code Online (Sandbox Code Playgroud)

c++ opencv cuda gpu thrust

7
推荐指数
1
解决办法
6072
查看次数

如何使CUDA中的矩阵列标准化并获得最大性能?

如何有效地规范化CUDA中的矩阵列?

我的矩阵存储在column-major中,典型大小为2000x200.

该操作可以用以下matlab代码表示.

A = rand(2000,200);

A = exp(A);
A = A./repmat(sum(A,1), [size(A,1) 1]);
Run Code Online (Sandbox Code Playgroud)

这可以通过Thrust,cuBLAS和/或cuNPP有效地完成吗?

包括4个内核的快速实现如下所示.

想知道这些是否可以在1或2个内核中完成以提高性能,尤其是对于由cublasDgemv()实现的列求和步骤.

#include <cuda.h>
#include <curand.h>
#include <cublas_v2.h>
#include <thrust/device_vector.h>
#include <thrust/device_ptr.h>
#include <thrust/transform.h>
#include <thrust/iterator/constant_iterator.h>
#include <math.h>

struct Exp
{
    __host__ __device__ void operator()(double& x)
    {
        x = exp(x);
    }
};

struct Inv
{
    __host__ __device__ void operator()(double& x)
    {
        x = (double) 1.0 / x;
    }
};

int main()
{
    cudaDeviceSetCacheConfig(cudaFuncCachePreferShared);
    cublasHandle_t hd;
    curandGenerator_t rng;
    cublasCreate(&hd);
    curandCreateGenerator(&rng, CURAND_RNG_PSEUDO_DEFAULT);

    const size_t m = 2000, …
Run Code Online (Sandbox Code Playgroud)

performance cuda matrix thrust cublas

7
推荐指数
1
解决办法
4007
查看次数

给定元素数组,偏移量和子列表长度的有效部分约简

对于我的应用程序,我必须处理一堆对象(比如ints),这些对象随后被分割并分类成更小的桶.为此,我将元素存储在一个连续的数组中

arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14...}
Run Code Online (Sandbox Code Playgroud)

并且关于桶(子列表)的信息由相应桶中的第一个元素的偏移量和子列表的长度给出.

所以,例如,给定

offsets = {0,3,8,..}
sublist_lengths = {3,5,2,...}
Run Code Online (Sandbox Code Playgroud)

会导致以下分裂:

0 1 2 || 3 4 5 6 7 || 8 9 || ...
Run Code Online (Sandbox Code Playgroud)

我正在寻找的只是使用自定义内核或thrust库在桶上运行算法(如减少)的一种通用且有效的方法.总结水桶应该给:

3 || 25 || 17 || ...
Run Code Online (Sandbox Code Playgroud)

我想出了什么:

  • 选项1:自定义内核需要相当多的修补,复制到共享内存,正确选择块和网格大小以及自己的算法实现,如扫描,减少等.此外,每个操作都需要自己定制核心.总的来说,我很清楚如何做到这一点,但在thrust过去几天使用后,我的印象是可能有更聪明的方式

  • 选项2:从偏移量({0,0,0,1,1,1,1,1,2,2,3,...}在上面的例子中)生成一个键数组并使用thrust::reduce_by_key.不过,我不喜欢额外的列表生成.

  • 选项3:thrust::transform_iterator与...一起使用thrust::counting_iterator以生成上面给出的密钥列表.不幸的是,我无法想出一个实现,它不需要将索引增加到设备上的偏移列表,并且会破坏并行性.

实现这一目标最理智的方式是什么?

c++ cuda thrust

6
推荐指数
1
解决办法
333
查看次数

如何通过常量减少device_vector的每个元素?

我试图用来thrust::transform减少a的每个元素的常量值device_vector.如您所见,最后一行不完整.我试图从所有元素减去常数,fLowestVal但不知道究竟是多少.

thrust::device_ptr<float> pWrapper(p);
thrust::device_vector<float> dVector(pWrapper, pWrapper + MAXX * MAXY);
float fLowestVal = *thrust::min_element(dVector.begin(), dVector.end(),thrust::minimum<float>());

// XXX What goes here?
thrust::transform(...);
Run Code Online (Sandbox Code Playgroud)

另一个问题:一旦我对其进行了更改device_vector,更改是否也适用于p阵列?

谢谢!

cuda thrust

6
推荐指数
1
解决办法
862
查看次数

我可以使用thrust :: host_vector或者我必须使用cudaHostAlloc进行零重复吗?

我想在映射内存上使用零拷贝cudaHostGetDevicePointer.我可以使用thrust::host_vector或者必须使用cudaHostAlloc(...,cudaHostAllocMapped)? 或者它是否更容易使用Thrust?

cuda gpu zero-copy thrust

6
推荐指数
1
解决办法
1087
查看次数

在我的机器上操作大型矢量时,CUDA推力变慢

我是一名CUDA初学者并正在阅读一些推力教程.我写了一个简单但非常有组织的代码并试图找出推力的加速度.(这个想法是否正确?).我尝试通过在cpu上添加数组并在gpu上添加device_vector,将两个向量(10000000 int)添加到另一个向量.

这是事情:

#include <iostream>
#include "cuda.h"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>

#define N 10000000
int main(void)
{
    float time_cpu;
    float time_gpu;
    int *a = new int[N];
    int *b = new int[N];
    int *c = new int[N];
    for(int i=0;i<N;i++)
    {
        a[i]=i;
        b[i]=i*i;
    }
    clock_t start_cpu,stop_cpu;
    start_cpu=clock();
    for(int i=0;i<N;i++)
    {
        c[i]=a[i]+b[i];
    }
    stop_cpu=clock();   
    time_cpu=(double)(stop_cpu-start_cpu)/CLOCKS_PER_SEC*1000;
    std::cout<<"Time to generate (CPU):"<<time_cpu<<std::endl;
    thrust::device_vector<int> X(N);
    thrust::device_vector<int> Y(N);
    thrust::device_vector<int> Z(N);
    for(int i=0;i<N;i++)
    {
        X[i]=i;
        Y[i]=i*i;
    }
    cudaEvent_t start, stop;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);
    cudaEventRecord(start,0);       
    thrust::transform(X.begin(), X.end(), …
Run Code Online (Sandbox Code Playgroud)

c c++ cuda thrust

6
推荐指数
1
解决办法
4548
查看次数

使用CUDA Thrust确定每个矩阵列中的最小元素及其位置

我有一个相当简单的问题,但我无法找到一个优雅的解决方案.

我有一个Thrust代码,它生成c包含值的相同大小的向量.假设这些c向量中的每一个都有一个索引.我想为每个向量位置获取c值为最低的向量的索引:

例:

C0 =     (0,10,20,3,40)
C1 =     (1,2 ,3 ,5,10)
Run Code Online (Sandbox Code Playgroud)

我会得到一个包含C具有最低值的向量索引的向量:

result = (0,1 ,1 ,0,1)
Run Code Online (Sandbox Code Playgroud)

我已经考虑过使用推力zip迭代器来做这件事,但是已经遇到了问题:我可以压缩所有c向量并实现任意转换,它接受一个元组并返回其最低值的索引,但是:

  1. 如何迭代元组的内容?
  2. 据我所知,元组只能存储10元素,并且可以存在比10 c矢量更多的元素.

然后我考虑这样做:不是使用c单独的向量,而是将它们全部附加到单个向量中C,然后生成引用位置的键并按键执行稳定排序,这将从同一位置重新组合向量条目.在示例中,将给出:

C =      (0,10,20,3,40,1,2,3,5,10)
keys =   (0,1 ,2 ,3,4 ,0,1,2,3,4 )
after stable sort by key:
output = (0,1,10,2,20,3,3,5,40,10)
keys =   (0,0,1 ,1,2 ,2,3,3,4 ,4 )
Run Code Online (Sandbox Code Playgroud)

然后使用向量中的位置生成键,使用向量的索引压缩输出,c然后使用自定义函数执行按键缩减,对于每个缩减,输出具有最低值的索引.在示例中:

input =  (0,1,10,2,20,3,3,5,40,10)
indexes= (0,1,0 ,1,0 ,1,0,1,0 ,1)
keys =   (0,0,1 ,1,2 …
Run Code Online (Sandbox Code Playgroud)

c++ cuda thrust

6
推荐指数
1
解决办法
2373
查看次数

如何优化VBO/IBO以最大化GPU缓存使用率

我正在使用在CUDA上运行的Marching Cubes算法从体积数据生成网格.

我试过保存网格并以3种方式渲染它.

  1. 将一组原始三角形保存为连续的顶点数据数组.我估计第一遍的大小,创建一个OpenGL VBO,将其映射到CUDA并以下面的格式将顶点数据写入它

V0x, V0y, V0z, N0x, N0y, N0z, V1x, V1y, V1z, N1x, N1y, N1z, ...

并使用它绘制glDrawArrays().

VBO中的冗余顶点,每个多维数据集的冗余顶点,无索引.

  1. 从第1步获取网格,使用thrust::sort()thrust::unique()删除冗余顶点,使用计算索引thrust::lower_bound().将结果保存到映射到CUDA的OpenGL VBO/IBO.使用绘制模型glDrawElements().

VBO中没有冗余顶点,生成指数.

  1. 生成每个立方体的唯一顶点列表,将它们存储在VBO中,以及它们在IBO中形成三角形的索引.渲染使用glDrawElements().

VBO中的冗余顶点,每个多维数据集的唯一顶点,每个多维数据集的生成索引

现在我得到的相同数据集的FPS是相同的ISO-Value`

Method 1 : 92  FPS, 30,647,016 Verts,          0 Indices
Method 2 : 122 FPS,  6,578,066 Verts, 30,647,016 Indices
Method 3 : 140 FPS, 20,349,880 Verts, 30,647,016 Indices
Run Code Online (Sandbox Code Playgroud)

即使方法2产生最少数量的顶点,FPS也很低.我相信这是因为索引的顺序可以最大限度地减少GPU缓存的使用.方法3的索引顺序获得更高的GPU缓存使用率,因此FPS更高.

如何修改/修改方法2以获得更高的FPS?

c++ opengl cuda thrust

6
推荐指数
1
解决办法
562
查看次数

在 cpp 文件中使用时推力静态断言

我正在尝试编译并运行一个简单的 Cuda/thrust 程序,当扩展名是 时它可以工作,.cu但当源扩展名是.cpp. 我已经在 cmake 中应用了 cpp 文件所需的更改,但我得到了

错误:静态断言失败:此系统未实现 THRUST_STATIC_ASSERT_MSG

cmake_minimum_required(VERSION 3.12 FATAL_ERROR)

project(thrust_test LANGUAGES CXX CUDA)

find_package(CUDA 10.0 REQUIRED)
message(STATUS "CUDA ${CUDA_VERSION_STRING} at ${CUDA_TOOLKIT_ROOT_DIR}")
set(CUDA_LINK_LIBRARIES_KEYWORD PUBLIC)

include_directories(${CUDA_INCLUDE_DIRS})
link_directories(${CUDA_LIBRARY_DIRS})

set(CMAKE_CUDA_STANDARD 14)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
set(CUDA_SEPARABLE_COMPILATION ON)

set_source_files_properties(
        main.cpp
        PROPERTIES
        CUDA_SOURCE_PROPERTY_FORMAT
        OBJ)

add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} ${CUDA_LIBRARIES})
Run Code Online (Sandbox Code Playgroud)

和main.cpp:

__host__
__device__
int foo() {

    // generate random data serially
    thrust::host_vector<int> h_vec(100);
    std::generate(h_vec.begin(), h_vec.end(), rand);

    // transfer to device and compute sum
    thrust::device_vector<int> d_vec = h_vec;
    return thrust::reduce(d_vec.begin(), d_vec.end(), 0, …
Run Code Online (Sandbox Code Playgroud)

c++ cuda cmake thrust

6
推荐指数
1
解决办法
4050
查看次数

标签 统计

cuda ×10

thrust ×10

c++ ×6

gpu ×3

c ×1

cmake ×1

cublas ×1

matrix ×1

opencv ×1

opengl ×1

performance ×1

sorting ×1

zero-copy ×1