标题 cuda学算法 1
cuda-algorithm
主要目的是学习算法和cuda。源码地址
- 本文实现了基本的cuda数组
写了一个类似于c++ vector的简单类实现cuda内存管理,重载运算符号[] 使之能便捷访问二维数组
template <class T>
struct cuBase
{
T *devPtr;
uint64_t cap;
uint64_t size;
//拷贝构造函数
cuBase(const cuBase <h) : devPtr(lth.devPtr), cap(lth.cap), size(lth.size){};
// struct cuBase copy()
// {
// cuBase b;
// // : devPtr(lth.devPtr), cap(lth.cap), size(lth.size)
// return cuBase;
// }
};
template <class T>
struct cuVector
{
public:
cuBase<T> *cb;
__host__ cuVector(int cap)
{
CK(cudaMallocManaged((void **)&cb, sizeof(cuBase<T>)));
cb->cap = cap;
cb->size = 0;
CK(cudaMallocManaged((void **)&(cb->devPtr), sizeof(T) * cb->cap));
CK(cudaMemset(cb->devPtr, 0, sizeof(T) * cb->cap));
}
__host__ cuVector(int cap, T val)
{
CK(cudaMallocManaged((void **)&cb, sizeof(cuBase<T>)));
cb->cap = cap;
cb->size = cap;
CK(cudaMallocManaged((void **)&(cb->devPtr), sizeof(T) * cb->cap));
CK(cudaMemset(cb->devPtr, val, sizeof(T) * cb->cap));
}
//拷贝构造函数
__host__ __device__ cuVector(const cuVector <h)
{
// cb->devPtr = lth.cb->devPtr;
// cb->size = lth.cb->size;
// cb->cap = lth.cb->cap;
cb = lth.cb;
}
__host__ void release()
{
cudaFree(cb);
}
~cuVector()
{
cudaFree(cb->devPtr);
// cudaFree(cb);
}
__host__ __device__ void push_back(T val)
{
cb->devPtr[cb->size++] = val;
}
__host__ __device__ inline T &operator[](size_t x)
{
return *(cb->devPtr + x);
}
__host__ __device__ inline size_t size()
{
return cb->size;
}
__host__ __device__ inline size_t cap()
{
return cb->cap;
}
// T begin(){};
// T end(){};
};
2. 凸包算法 Jarvis
```cpp
__device__ int cross(caltype p, caltype q, caltype r)
{
return (q.x - p.x) * (r.y - q.y) - (q.y - p.y) * (r.x - q.x);
}
__global__ void kernel(cuVector<caltype> trees, cuVector<bool> visit, cuVector<caltype> out)
{
int leftMost = 0;
//最坐边
auto n = trees.cap();
for (int i = 0; i < n; i++)
{
if (trees[i].x < trees[leftMost].x ||
(trees[i].x == trees[leftMost].x &&
trees[i].y < trees[leftMost].y))
{
leftMost = i;
}
}
int p = leftMost;
do
{
int q = (p + 1) % n; // p的下一个点
for (int r = 0; r < n; r++)
{
/* 如果 r 在 pq 的右侧,则 q = r */
if (cross(trees[p], trees[q], trees[r]) < 0)
{
q = r;
}
}
/* 是否存在点 i, 使得 p 、q 、i 在同一条直线上 */
for (int i = 0; i < n; i++)
{
if (visit[i] || i == p || i == q)
{
continue;
}
if (cross(trees[p], trees[q], trees[i]) == 0)
{
out.push_back(trees[i]);
visit[i] = true;
}
}
if (!visit[q])
{
out.push_back(trees[q]);
visit[q] = true;
}
p = q;
} while (p != leftMost);
}