Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 带CUDPP/推力的分段分拣_Sorting_Cuda_Thrust_Cudpp - Fatal编程技术网

Sorting 带CUDPP/推力的分段分拣

Sorting 带CUDPP/推力的分段分拣,sorting,cuda,thrust,cudpp,Sorting,Cuda,Thrust,Cudpp,是否可以在CUDA中使用CUDPP进行分段排序?通过分段排序,我的意思是对数组中受如下标志保护的元素进行排序 A[10,9,8,7,6,5,4,3,2,1] Flag array[1,0,1,0,0,1,0,0,0,0] 对连续1之间的元素进行排序。 预期产量 [9,10,6,7,8,1,2,3,4,5] 您可以在单个排序过程中完成此操作:其思想是调整数组中的元素,以便排序仅在“段”内重新定位元素 例如: A[10,9,8,7,6,5,4,3,2,1] flag[0,0,1,0,0,1,0

是否可以在CUDA中使用CUDPP进行分段排序?通过分段排序,我的意思是对数组中受如下标志保护的元素进行排序

A[10,9,8,7,6,5,4,3,2,1]

Flag array[1,0,1,0,0,1,0,0,0,0]
对连续1之间的元素进行排序。
预期产量

[9,10,6,7,8,1,2,3,4,5]

您可以在单个排序过程中完成此操作:其思想是调整数组中的元素,以便排序仅在“段”内重新定位元素

例如:

A[10,9,8,7,6,5,4,3,2,1]
flag[0,0,1,0,0,1,0,0,0,0] 
(我删除了第一个1,因为它不需要)

首先扫描标志数组:

scanned_flag[0,0,1,1,1,2,2,2,2,2]
然后,根据数字类型,您有许多选项,例如,对于无符号整数,您可以设置最高位以区分“段”。 最简单的方法是将最大的元素乘以扫描的_标志:

A + scanned_flag*10 = [10,9,18,17,16,25,24,23,22,21]
剩下的很简单:对数组排序并反转转换。 以下是两个版本:使用Arrayfire和推力。看看你更喜欢哪个

阵列火灾:

void af_test() {
 int A[] = {10,9,8,7,6,5,4,3,2,1};  
 int S[] = {0, 0,1,0,0,1,0,0,0,0};  
 int n = sizeof(A) / sizeof(int);

 af::array devA(n, A, af::afHost);
 af::array devS(n, S, af::afHost);
 // obtain the max element
 int maxi = af::max< int >(devS);

 // scan the keys
 // keys = 0,0,1,1,1,2,2,2,2,2
 af::array keys = af::accum(devS);

 // compute: A = A + keys * maxi
 // A = 10,9,18,17,16,25,24,23,22,21
 devA = devA + keys * maxi;

 // sort the array
 // A = 9,10,16,17,18,21,22,23,24,25
 devA = af::sort(devA);

 // compute: A = A - keys * maxi
 // A = 9,10,6,7,8,1,2,3,4,5
 devA = devA - keys * maxi;
 // print the results
 print(devA);
}
void af_测试(){
int A[]={10,9,8,7,6,5,4,3,2,1};
int S[]={0,0,1,0,0,1,0,0,0,0};
int n=sizeof(A)/sizeof(int);
af::array devA(n,A,af::afHost);
af::阵列devS(n,S,af::afHost);
//获取最大元素
intmaxi=af::max(devS);
//扫描钥匙
//键=0,0,1,1,1,2,2,2,2,2
af::数组键=af::accum(devS);
//计算:A=A+keys*maxi
//A=10,9,18,17,16,25,24,23,22,21
德瓦=德瓦+钥匙*maxi;
//对数组进行排序
//A=9,10,16,17,18,21,22,23,24,25
devA=af::排序(devA);
//计算:A=A-键*maxi
//A=9,10,6,7,8,1,2,3,4,5
devA=devA-键*maxi;
//打印结果
印刷(德瓦);
}
推力:

template<typename T>
struct add_mul : public binary_function<T,T,T>
{
add_mul(const T& _factor) : factor(_factor) {
}
   __host__ __device__ T operator()(const T& a, const T& b) const 
{
    return (a + b * factor);
}
const T factor;
}; 

void thrust_test()
{
  int A[] = {10,9,8,7,6,5,4,3,2,1};  
  int S[] = {0, 0,1,0,0,1,0,0,0,0};  
  int n = sizeof(A) / sizeof(int);
  thrust::host_vector< int > hA(A, A + n), hS(S, S + n);

  thrust::device_vector< int > devA = hA, devS = hS, keys(n);
  // scan the keys 
  thrust::inclusive_scan(devS.begin(), devS.end(), keys.begin());
  // obtain the maximal element
  int maxi = *(thrust::max_element(devA.begin(), devA.end()));
  // compute: A = A + keys * maxi
  thrust::transform(devA.begin(), devA.end(), keys.begin(), devA.begin(), add_mul< int >(maxi)); 
  // sort the array
  thrust::sort(devA.begin(), devA.end());
  // compute: A = A - keys * maxi
  thrust::transform(devA.begin(), devA.end(), keys.begin(), devA.begin(), add_mul< int >(-maxi)); 
  // copy back to the host 
  hA = devA;
  std::cout << "\nSorted array\n";
  thrust::copy(hA.begin(), hA.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
模板
结构add_mul:公共二进制函数
{
加上系数(常数和系数):系数(系数){
}
__主机设备运算符()(常数T&a,常数T&b)常数
{
收益率(a+b*因子);
}
常数因子;
}; 
无效推力试验()
{
int A[]={10,9,8,7,6,5,4,3,2,1};
int S[]={0,0,1,0,0,1,0,0,0,0};
int n=sizeof(A)/sizeof(int);
推力:主向量hA(A,A+n),hS(S,S+n);
推力:设备向量devA=hA,devS=hS,键(n);
//扫描钥匙
inclusive_scan(devS.begin()、devS.end()、keys.begin());
//求最大元
int maxi=*(推力::max_元素(devA.begin(),devA.end());
//计算:A=A+keys*maxi
转换(devA.begin(),devA.end(),keys.begin(),devA.begin(),add_mul(maxi));
//对数组进行排序
推力::排序(devA.begin(),devA.end());
//计算:A=A-键*maxi
转换(devA.begin(),devA.end(),keys.begin(),devA.begin(),add_mul(-maxi));
//复制回主机
hA=德瓦;

std::cout您可以在一次排序过程中完成此操作:其思想是调整数组中的元素,以便排序仅在“段”中重新定位元素

例如:

A[10,9,8,7,6,5,4,3,2,1]
flag[0,0,1,0,0,1,0,0,0,0] 
(我删除了第一个1,因为它不需要)

首先扫描标志数组:

scanned_flag[0,0,1,1,1,2,2,2,2,2]
然后,根据数字类型,您有许多选项,例如,对于无符号整数,您可以设置最高位以区分“段”。 最简单的方法是将最大的元素乘以扫描的_标志:

A + scanned_flag*10 = [10,9,18,17,16,25,24,23,22,21]
剩下的很简单:对数组排序并反转转换。 以下是两个版本:使用Arrayfire和推力。选择你更喜欢的

阵列火灾:

void af_test() {
 int A[] = {10,9,8,7,6,5,4,3,2,1};  
 int S[] = {0, 0,1,0,0,1,0,0,0,0};  
 int n = sizeof(A) / sizeof(int);

 af::array devA(n, A, af::afHost);
 af::array devS(n, S, af::afHost);
 // obtain the max element
 int maxi = af::max< int >(devS);

 // scan the keys
 // keys = 0,0,1,1,1,2,2,2,2,2
 af::array keys = af::accum(devS);

 // compute: A = A + keys * maxi
 // A = 10,9,18,17,16,25,24,23,22,21
 devA = devA + keys * maxi;

 // sort the array
 // A = 9,10,16,17,18,21,22,23,24,25
 devA = af::sort(devA);

 // compute: A = A - keys * maxi
 // A = 9,10,6,7,8,1,2,3,4,5
 devA = devA - keys * maxi;
 // print the results
 print(devA);
}
void af_测试(){
int A[]={10,9,8,7,6,5,4,3,2,1};
int S[]={0,0,1,0,0,1,0,0,0,0};
int n=sizeof(A)/sizeof(int);
af::array devA(n,A,af::afHost);
af::阵列devS(n,S,af::afHost);
//获取最大元素
intmaxi=af::max(devS);
//扫描钥匙
//键=0,0,1,1,1,2,2,2,2,2
af::数组键=af::accum(devS);
//计算:A=A+keys*maxi
//A=10,9,18,17,16,25,24,23,22,21
德瓦=德瓦+钥匙*maxi;
//对数组进行排序
//A=9,10,16,17,18,21,22,23,24,25
devA=af::排序(devA);
//计算:A=A-键*maxi
//A=9,10,6,7,8,1,2,3,4,5
devA=devA-键*maxi;
//打印结果
印刷(德瓦);
}
推力:

template<typename T>
struct add_mul : public binary_function<T,T,T>
{
add_mul(const T& _factor) : factor(_factor) {
}
   __host__ __device__ T operator()(const T& a, const T& b) const 
{
    return (a + b * factor);
}
const T factor;
}; 

void thrust_test()
{
  int A[] = {10,9,8,7,6,5,4,3,2,1};  
  int S[] = {0, 0,1,0,0,1,0,0,0,0};  
  int n = sizeof(A) / sizeof(int);
  thrust::host_vector< int > hA(A, A + n), hS(S, S + n);

  thrust::device_vector< int > devA = hA, devS = hS, keys(n);
  // scan the keys 
  thrust::inclusive_scan(devS.begin(), devS.end(), keys.begin());
  // obtain the maximal element
  int maxi = *(thrust::max_element(devA.begin(), devA.end()));
  // compute: A = A + keys * maxi
  thrust::transform(devA.begin(), devA.end(), keys.begin(), devA.begin(), add_mul< int >(maxi)); 
  // sort the array
  thrust::sort(devA.begin(), devA.end());
  // compute: A = A - keys * maxi
  thrust::transform(devA.begin(), devA.end(), keys.begin(), devA.begin(), add_mul< int >(-maxi)); 
  // copy back to the host 
  hA = devA;
  std::cout << "\nSorted array\n";
  thrust::copy(hA.begin(), hA.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
模板
结构add_mul:公共二进制函数
{
加上系数(常数和系数):系数(系数){
}
__主机设备运算符()(常数T&a,常数T&b)常数
{
收益率(a+b*因子);
}
常数因子;
}; 
无效推力试验()
{
int A[]={10,9,8,7,6,5,4,3,2,1};
int S[]={0,0,1,0,0,1,0,0,0,0};
int n=sizeof(A)/sizeof(int);
推力:主向量hA(A,A+n),hS(S,S+n);
推力:设备向量devA=hA,devS=hS,键(n);
//扫描钥匙
inclusive_scan(devS.begin()、devS.end()、keys.begin());
//求最大元
int maxi=*(推力::max_元素(devA.begin(),devA.end());
//计算:A=A+keys*maxi
转换(devA.begin(),devA.end(),keys.begin(),devA.begin(),add_mul(maxi));
//对数组进行排序
推力::排序(devA.begin(),devA.end());
//计算:A=A-键*maxi
转换(devA.begin(),devA.end(),keys.begin(),devA.begin(),add_mul(-maxi));
//复制回主机
hA=德瓦;

std::cout如果您可以稍微不同地枚举范围,可能会感兴趣。这意味着在推力/CUDPP中没有可用的直接方法?如果您可以稍微不同地枚举范围,可能会感兴趣。这意味着在推力/CUDPP中没有可用的直接方法?此方法的问题可能是值的范围
A
中的s可能太大,无法与它们的段号相乘。另一方面,它很快。另一种可能的方法是按键进行稳定排序,然后按段号进行稳定排序。缺点是它涉及大量数据移动,而您的方法仅在单个段内局部移动项,这会导致如果段小于排序内核的工作组,那么在GPU上可能非常有用(然后排序在本地内存中有效地进行)