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
C++ 用推力排序压缩顶点_C++_Sorting_Cuda_Thrust - Fatal编程技术网

C++ 用推力排序压缩顶点

C++ 用推力排序压缩顶点,c++,sorting,cuda,thrust,C++,Sorting,Cuda,Thrust,所以我有一个PackedVertex结构的设备阵列: struct PackedVertex{ glm::vec3顶点; glm::vec2紫外线; glm::vec3正常; } 我试图对它们进行排序,以便重复项在数组中聚集在一起;我一点也不关心整体秩序 我尝试通过比较运行的向量的长度对它们进行排序,但没有正确排序,所以现在我尝试使用3个稳定的\u排序和二进制\u运算符对每个变量进行排序: \u推力\u高清\u警告\u禁用__ 结构排序按顶点压缩顶点:公共推力::二进制函数 { __主机设备布

所以我有一个PackedVertex结构的设备阵列:

struct PackedVertex{
glm::vec3顶点;
glm::vec2紫外线;
glm::vec3正常;
}
我试图对它们进行排序,以便重复项在数组中聚集在一起;我一点也不关心整体秩序

我尝试通过比较运行的向量的长度对它们进行排序,但没有正确排序,所以现在我尝试使用3个稳定的\u排序和二进制\u运算符对每个变量进行排序:

\u推力\u高清\u警告\u禁用__
结构排序按顶点压缩顶点:公共推力::二进制函数
{
__主机设备布尔运算符()
{
返回lhs.Vertex.x
{
__主机设备布尔运算符()
{
返回lhs.UV.x
{
__主机设备布尔运算符()
{
返回lhs.Normal.x
问题是我现在得到了一个推力错误:“启动\关闭\按\值”,这意味着我的排序由于我的运算符而不收敛


话虽如此,我也非常确定这不是我进行此类排序的最佳方式,因此非常感谢您的反馈。

我不相信您的排序函子是正确的

排序函子必须给出一致的顺序。让我们来考虑一下这个:

    return lhs.UV.x < rhs.UV.x || lhs.UV.y < rhs.UV.y;
无论我呈现的是
UV1
UV2
的顺序,该函子都将返回
true
。你的其他函子也有类似的缺陷

在中,这些是无效的函子。如果我们希望订购
UV1
UV2
,我们必须提供一个函子,该函子(一致地)为一个演示顺序返回
true
,为另一个演示顺序返回
false
。(唯一的例外是,如果呈现的两个量真的相等,则函子应始终只返回一个答案,无论呈现顺序如何,一致地返回
true
false
。但是此处呈现的
UV1
UV2
并不“相等”用于您所需的排序,即相同结构的分组。)

以下简单测试似乎对我有效:

$ cat t717.cu
#include <thrust/sort.h>
#include <thrust/device_ptr.h>
#include <iostream>
#include <stdlib.h>

#define DSIZE 64
#define RNG 10

struct PackedVertex {
  float3 Vertex;
  float2 UV;
  float3 Normal;
};

struct my_PV_grouper {

  template <typename T>
  __host__ __device__
  bool operator()(const T &lhs, const T &rhs) const {

    if      (lhs.Vertex.x > rhs.Vertex.x) return true;
    else if (lhs.Vertex.x < rhs.Vertex.x) return false;
    else if (lhs.Vertex.y > rhs.Vertex.y) return true;
    else if (lhs.Vertex.y < rhs.Vertex.y) return false;
    else if (lhs.Vertex.z > rhs.Vertex.z) return true;
    else if (lhs.Vertex.z < rhs.Vertex.z) return false;
    else if (lhs.UV.x > rhs.UV.x) return true;
    else if (lhs.UV.x < rhs.UV.x) return false;
    else if (lhs.UV.y > rhs.UV.y) return true;
    else if (lhs.UV.y < rhs.UV.y) return false;
    else if (lhs.Normal.x > rhs.Normal.x) return true;
    else if (lhs.Normal.x < rhs.Normal.x) return false;
    else if (lhs.Normal.y > rhs.Normal.y) return true;
    else if (lhs.Normal.y < rhs.Normal.y) return false;
    else if (lhs.Normal.z > rhs.Normal.z) return true;
    else return false;
    }
};

int main(){

  PackedVertex h_data[DSIZE];
  PackedVertex *d_data;

  for (int i =0; i < DSIZE; i++)
    h_data[i].Vertex.x = h_data[i].Vertex.y = h_data[i].Vertex.z = h_data[i].UV.x = h_data[i].UV.y = h_data[i].Normal.x = h_data[i].Normal.y = h_data[i].Normal.z = rand()%RNG;
  cudaMalloc(&d_data, DSIZE*sizeof(PackedVertex));
  cudaMemcpy(d_data, h_data, DSIZE*sizeof(PackedVertex), cudaMemcpyHostToDevice);
  thrust::device_ptr<PackedVertex> d_ptr(d_data);
  thrust::sort(d_ptr, d_ptr+DSIZE, my_PV_grouper());
  cudaMemcpy(h_data, d_data, DSIZE*sizeof(PackedVertex), cudaMemcpyDeviceToHost);
  for (int i =0; i < DSIZE; i++)
    std::cout << h_data[i].Vertex.x << " ";
  std::cout << std::endl;
}
$ nvcc -o t717 t717.cu
$ ./t717
9 9 9 9 9 9 9 8 8 8 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0
$
$cat t717.cu
#包括
#包括
#包括
#包括
#定义DSIZE64
#定义RNG 10
结构PackedVertex{
3个顶点;
2紫外线;
正常3例;
};
构造我的石斑鱼{
样板
__主机设备__
布尔运算符()(常数T&lhs、常数T&rhs)常数{
如果(lhs.Vertex.x>rhs.Vertex.x)返回true;
else if(lhs.Vertex.xrhs.Vertex.y)返回true;
else if(lhs.Vertex.yrhs.Vertex.z)返回true;
else if(lhs.Vertex.zrhs.UV.x)返回true;
否则如果(lhs.UV.xrhs.UV.y)返回true;
否则如果(lhs.UV.yrhs.Normal.x)返回true;
否则如果(lhs.Normal.xrhs.Normal.y)返回true;
否则如果(lhs.Normal.yrhs.Normal.z)返回true;
否则返回false;
}
};
int main(){
PackedVertex h_数据[DSIZE];
PackedVertex*d_数据;
对于(int i=0;istd::与您之前的问题一样:如果您想得到答案,请提供完整的复制案例、准确的错误消息和编译命令。否则您将浪费所有人的时间。谢谢,我认为其中存在逻辑错误,代码将再次运行:)
$ cat t717.cu
#include <thrust/sort.h>
#include <thrust/device_ptr.h>
#include <iostream>
#include <stdlib.h>

#define DSIZE 64
#define RNG 10

struct PackedVertex {
  float3 Vertex;
  float2 UV;
  float3 Normal;
};

struct my_PV_grouper {

  template <typename T>
  __host__ __device__
  bool operator()(const T &lhs, const T &rhs) const {

    if      (lhs.Vertex.x > rhs.Vertex.x) return true;
    else if (lhs.Vertex.x < rhs.Vertex.x) return false;
    else if (lhs.Vertex.y > rhs.Vertex.y) return true;
    else if (lhs.Vertex.y < rhs.Vertex.y) return false;
    else if (lhs.Vertex.z > rhs.Vertex.z) return true;
    else if (lhs.Vertex.z < rhs.Vertex.z) return false;
    else if (lhs.UV.x > rhs.UV.x) return true;
    else if (lhs.UV.x < rhs.UV.x) return false;
    else if (lhs.UV.y > rhs.UV.y) return true;
    else if (lhs.UV.y < rhs.UV.y) return false;
    else if (lhs.Normal.x > rhs.Normal.x) return true;
    else if (lhs.Normal.x < rhs.Normal.x) return false;
    else if (lhs.Normal.y > rhs.Normal.y) return true;
    else if (lhs.Normal.y < rhs.Normal.y) return false;
    else if (lhs.Normal.z > rhs.Normal.z) return true;
    else return false;
    }
};

int main(){

  PackedVertex h_data[DSIZE];
  PackedVertex *d_data;

  for (int i =0; i < DSIZE; i++)
    h_data[i].Vertex.x = h_data[i].Vertex.y = h_data[i].Vertex.z = h_data[i].UV.x = h_data[i].UV.y = h_data[i].Normal.x = h_data[i].Normal.y = h_data[i].Normal.z = rand()%RNG;
  cudaMalloc(&d_data, DSIZE*sizeof(PackedVertex));
  cudaMemcpy(d_data, h_data, DSIZE*sizeof(PackedVertex), cudaMemcpyHostToDevice);
  thrust::device_ptr<PackedVertex> d_ptr(d_data);
  thrust::sort(d_ptr, d_ptr+DSIZE, my_PV_grouper());
  cudaMemcpy(h_data, d_data, DSIZE*sizeof(PackedVertex), cudaMemcpyDeviceToHost);
  for (int i =0; i < DSIZE; i++)
    std::cout << h_data[i].Vertex.x << " ";
  std::cout << std::endl;
}
$ nvcc -o t717 t717.cu
$ ./t717
9 9 9 9 9 9 9 8 8 8 7 7 7 7 7 7 7 6 6 6 6 6 6 6 6 6 5 5 5 5 5 5 4 4 4 3 3 3 3 3 3 3 3 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 0 0 0 0 0 0
$