- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在编写一个程序来计算三角形网格数据的许多属性。其中一些属性,我想使用 thrust::方法计算,其他属性需要使用 CUDA 内核中的原始内存指针来计算。
为了将数据传输到 GPU,我在 transfer.cu 文件中获取了该数据,(因为在纯 C++ 代码中创建和操作 thrust::device_vector
不支持):
// thrust vectors (global)
thrust::host_vector<glm::vec3> trianglethrust_host;
thrust::device_vector<glm::vec3> trianglethrust_device;
extern "C" void trianglesToGPU_thrust(const trimesh::TriMesh *mesh, float** triangles) {
// fill host vector
for (size_t i = 0; i < mesh->faces.size(); i++) {
// PUSHING DATA INTO HOST_VECTOR HERE (OMITTED FOR CLARITY)
}
// copy to GPU by assigning host vector to device vector, like in the Thrust documentation
trianglethrust_device = trianglethrust_host;
// save raw pointer
*triangles = (float*)thrust::raw_pointer_cast(&(trianglethrust_device[0]));
}
此函数 trianglestoGPU_thrust
是从我的 C++ 程序的主要方法中调用的。一切正常,花花公子,直到程序退出,并且(全局定义的)triangethrust_device vector 超出范围。 Thrust 试图释放它,但 CUDA 上下文已经消失,导致 cudaErrorInvalidDevicePointer
对于我的问题,什么是最佳实践?
TL;DR:我想要一个 thrust::device_vector 在我的程序运行期间一直存在,因为我想向它添加 thrust::函数(如转换等),以及读取和操作它通过 CUDA 中的原始指针访问。
解决方案:就我而言,我显然是在过程中进一步使用原始数据指针进行释放。删除那个免费的,并结束我的主循环
trianglethrust_device.clear();
trianglethrust_device.shrink_to_fit();
trianglethrust_device.device_vector~;
在 CUDA 运行时被拆除之前强制清除该 vector 。这行得通,但可能仍然是一种非常丑陋的方法。
我在这个问题上推荐罗伯特的回答,并将其标记为有效。
最佳答案
正如您已经发现的,推力 vector 容器本身不能放置在文件范围内。
一个可能的解决方案是在 main
的开头简单地创建您需要的 vector ,然后将对这些 vector 的引用传递给需要它们的任何函数。
如果您真的想要“全局行为”,您可以在全局/文件范围内放置指向 vector 的指针,然后在 main 的开头初始化所需的 vector ,并将全局范围内的指针设置为指向在 main 中创建的 vector 。
根据评论中的问题,我认为主文件是使用主机编译器编译的 .cpp
文件是重要/可取的。因此,我们可以将前面提到的概念与堆上的 vector 分配结合使用,以避免在程序终止之前重新分配。这是一个完整的例子:
$ cat main.cpp
#include "transfer.h"
int main(){
float **triangles, *mesh;
triangles = new float *[1];
mesh = new float[4];
mesh[0] = 0.1f; mesh[1] = 0.2f; mesh[2] = 0.3f;
trianglesToGPU_thrust(mesh, triangles);
do_global_work(triangles);
finish();
}
$ cat transfer.h
void trianglesToGPU_thrust(const float *, float **);
void do_global_work(float **);
void finish();
$ cat transfer.cu
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include "transfer.h"
#include <iostream>
#include <cstdio>
#include <thrust/copy.h>
__global__ void k(float *data, size_t ds){
for (int i = 0; i < ds; i++) printf("%f,", data[i]);
}
// thrust vectors (global)
thrust::host_vector<float> *trianglethrust_host;
thrust::device_vector<float> *trianglethrust_device;
void trianglesToGPU_thrust(const float *mesh, float** triangles) {
//create vectors
trianglethrust_host = new thrust::host_vector<float>;
trianglethrust_device = new thrust::device_vector<float>;
// fill host vector
size_t i = 0;
while (mesh[i] != 0.0f) {
(*trianglethrust_host).push_back(mesh[i++]);
}
// copy to GPU by assigning host vector to device vector, like in the Thrust documentation
*trianglethrust_device = *trianglethrust_host;
// save raw pointer
*triangles = (float*)thrust::raw_pointer_cast(&((*trianglethrust_device)[0]));
}
void do_global_work(float** triangles){
std::cout << "from device vector:" << std::endl;
thrust::copy((*trianglethrust_device).begin(), (*trianglethrust_device).end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "from kernel:" << std::endl;
k<<<1,1>>>(*triangles, (*trianglethrust_device).size());
cudaDeviceSynchronize();
std::cout << std::endl;
}
void finish(){
if (trianglethrust_host) delete trianglethrust_host;
if (trianglethrust_device) delete trianglethrust_device;
}
$ nvcc -c transfer.cu
$ g++ -c main.cpp
$ g++ -o test main.o transfer.o -L/usr/local/cuda/lib64 -lcudart
$ ./test
from device vector:
0.1,0.2,0.3,
from kernel:
0.100000,0.200000,0.300000,
$
这是另一种方法,类似于之前的方法,在全局范围内使用推力容器的 std::vector
(只有 transfer.cu
文件不同于前面的例子,main.cpp
和 transfer.h
是一样的):
$ cat transfer.cu
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include "transfer.h"
#include <iostream>
#include <cstdio>
#include <thrust/copy.h>
#include <vector>
__global__ void k(float *data, size_t ds){
for (int i = 0; i < ds; i++) printf("%f,", data[i]);
}
// thrust vectors (global)
std::vector<thrust::host_vector<float> > trianglethrust_host;
std::vector<thrust::device_vector<float> > trianglethrust_device;
void trianglesToGPU_thrust(const float *mesh, float** triangles) {
//create vectors
trianglethrust_host.resize(1);
trianglethrust_device.resize(1);
// fill host vector
size_t i = 0;
while (mesh[i] != 0.0f) {
trianglethrust_host[0].push_back(mesh[i++]);
}
// copy to GPU by assigning host vector to device vector, like in the Thrust documentation
trianglethrust_device[0] = trianglethrust_host[0];
// save raw pointer
*triangles = (float*)thrust::raw_pointer_cast(trianglethrust_device[0].data());
}
void do_global_work(float** triangles){
std::cout << "from device vector:" << std::endl;
thrust::copy(trianglethrust_device[0].begin(), trianglethrust_device[0].end(), std::ostream_iterator<float>(std::cout, ","));
std::cout << std::endl << "from kernel:" << std::endl;
k<<<1,1>>>(*triangles, trianglethrust_device[0].size());
cudaDeviceSynchronize();
std::cout << std::endl;
}
void finish(){
trianglethrust_host.clear();
trianglethrust_device.clear();
}
$ nvcc -c transfer.cu
$ g++ -o test main.o transfer.o -L/usr/local/cuda/lib64 -lcudart
$ ./test
from device vector:
0.1,0.2,0.3,
from kernel:
0.100000,0.200000,0.300000,
$
关于c++ - 在全局范围内拥有 thrust::device_vector,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54742267/
我有三个 td,并且正在尝试将每个内部的函数限制为仅该 td。我该怎么做呢?使用此代码,它会获取所有 3 个图像并将它们全部插入到 h2 之前: jQuery("td.frontpage_news")
这是所需的通用公式:if((b2-b1)=c1,True,False但是,我需要 b2-b1约等于 c1 , 在 5 内大约单位(在本例中为秒)。有没有可以处理这个的函数? 最佳答案 你也可以试试这个
我有三个整数,作为命令行参数传入后赋值给变量。我想验证每个整数都在 1-5 范围内。有没有一种方法可以在不使用如下所示的 if 语句的情况下在 Java 中完成此操作?我想避免这样做(注意伪代码):
检查某个变量 X 是否在某个变量 Z 的 n 个数字之内的最简洁方法是什么。n 是任意定义的数字(即 3)。 所以我想要 if (z {something} x){ // run code i
我的顶级 build.gradle (Gradle 2.2) 中有类似的东西 ext.repo = "https://my-artifactory-repo" buildscript { re
我只是在我的 jsp 页面中进行随机技巧和测试。我想使用 Attributes 将 request 范围对象存储在 session 范围对象中。存储后,当尝试从请求属性中提取值(存储在 session
我正在使用 Spring 。我有一个外部化属性文件。我正在按如下方式加载它。 现在我如何将 session 中的属性作为键值对保存? 我尝试编写一个扩展 ServletContextListene
我有以下范围: scope :billable, -> (range_start = nil, range_end = nil) { joins(:bids) .where("au
请看我的示例代码: var testObject = new SomeClass(); using (testObject) { //At this point how can the te
我目前在保持在 vector 范围内时遇到一些问题。 在下面的代码中,我试图检查正在检查的数字是否小于或等于它后面的数字 #include #include #include bool fun(
有人可以帮我解决下面的(简化的)代码吗?我试图从幻灯片事件函数中调用 doTheSlide() 函数。我对 JS 范围的理解仍然有点可疑。 实现这一目标的正确方法是什么?我收到此错误: Uncaugh
如何在 Swift 中检查时间是否在下午 6 点到晚上 11 点之间?我在使用 NSDateFormatter 时遇到了困难,我觉得一定有更简单的方法。 最佳答案 使用NSCalendar: let
我目前正在尝试创建一个 2D 横向滚动条,并且我目前有我的“世界”绘图(暂时是一个大白框),但我无法弄清楚世界地图的边缘与边缘之间的任何关系确保视口(viewport)始终完全被 map 覆盖。 我的
我正在学习李普曼,而且我只是在学习。我在这里尝试编写一个代码,该代码将返回 vector 中的最小元素。当我在 Codeblocks 中编译我的代码时,它说:“模板声明不能出现在 block 范围内”
我有三个日期对象。我该如何比较它们才能确定它们之间的相对差异。 oldDate = newDate() - 5; midDate = newDate() - 2.5; newDate = newDat
我需要检查对象“objCR”是否存在于当前范围内。我尝试使用以下代码。 if(objCR == null) alert("object is not defined"); 让我知道哪里错了。 最佳答案
如何检查 IP 地址是否属于私有(private)类别? if(isPrivateIPAddress(ipAddress)) { //do something } 如有
我正在开发一个 Firefox 插件,它可以转换用户通过用户选择突出显示的屏幕温度。转换后,用户选择将替换为 ID 为 alreadyconverted 的 span HTML 元素,其中包含原始温度
我正在开发一个邮资应用程序,该应用程序需要根据多个邮政编码范围检查整数邮政编码,并根据邮政编码匹配的范围返回不同的代码。 每个代码都有多个邮政编码范围。例如,如果邮政编码在 1000-2429、254
我正在使用 excel 范围进行连接:Set rng = Range("A1:A8")如果范围内的单元格之一为空,则会添加一个空格。 你如何阻止这个空间被添加? 最佳答案 假设您在那些非空单元格中有常
我是一名优秀的程序员,十分优秀!