我试图通过两个向量,计算坐标之间的差异,使用质量计算一些更大的力等,并在thrust :: for_each的每个循环上实现加速度值。但是,我无法跟踪加速度值。
使用Thrust和functor,我设法写了这个:
这是给我带来麻烦的仿函数:
struct ParticleGenerator::acc_func{
//stores the initial coordinates if i-th particle to use it for computation and the init. acc. that is 0.0f
acc_func(float Ax, float Bx, float Cx, int X, int Y, int Z) : ax(Ax), bx(Bx), cx(Cx), _x(X), _y(Y), _z(Z) {}
template <typename Tuple>
__device__ __host__
void operator()(Tuple t){
//thrust::get<0>(t) +=(int) 32;
// save some values
acc[0] = thrust::get<0>(t); //(#)
acc[1] = thrust::get<1>(t);
acc2[0] = acc[0];
acc2[1] = acc[1];
//retrieve them, OK
printf("%d_%d\n", acc[0], acc[1]); //works well
}
int getRes(){
//return saved values, not OK
printf("%d_%d_%d_%d\n", acc[0], acc[1], acc2[0], acc2[1]); //prints wrong values
return 0;
}
//this returns the correct value, though
int getRes2(){ return _x;}
int acc2[2];
private:
float ax, bx, cx;
int _x, _y, _z;
int temp;
int acc[2];
};
正如您所看到的,我已经尝试过公共和私有,也尝试使用简单的int( temp )来存储任何值,但函数 getRes()如下所示,永远不会返回正确的值。
我注意到部件 _x(X)(向右滚动以查看acc_func()的完整构造函数)正确存储值,我可以使用函数检索它 getRes()
问题:有没有办法如何复制这种行为?要在标有//(#)的行上使用该命令并成功保存,更新并稍后返回值?
这是我的推力循环:
for(unsigned int i = 0; i < vecPosX.size(); ++i){
acc_func AF(0.0f, 0.0f, 0.0f, vecPosX[i], vecPosY[i], vecPosZ[i]);
thrust::for_each(
thrust::make_zip_iterator(thrust::make_tuple(vecPosX.begin(), vecPosY.begin())),
thrust::make_zip_iterator(thrust::make_tuple(vecPosX.end(), vecPosY.end())),
AF
);
AF.getRes();
//use the AF.getRes() to save the values of the acceleration and
//update the vecPosX[i], vecPosY[i] etc accordingly
}
其中vecPosX,vecPosY是影响粒子X和Y位置的载体
整个想法是创建一个元组(posX,posY)并在每个 thrust :: for_each 循环上重新计算并实现加速,当计算完成时,只需返回加速x的结果和y,以便我可以更新第i个粒子的速度和位置
这里有两个不同的结果:
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
0_4_-588854768_32764
267_264_267_264
254_272_254_272
256_237_256_237
264_264_264_264
259_228_259_228
259_247_259_247
264_245_264_245
265_237_265_237
272_260_272_260
我希望你能帮助我,谢谢你:)。
编辑:请注意我已经使用SDL,Visual Studio和两个for循环一起成功编写了整个模拟应用程序,现在我正在尝试制作能够使用更多粒子的速度更快
编辑2:来复制问题,可以使用
thrust::device_vector<int> vecPosX(10, 10;
thrust::device_vector<int> vecPosY(10, 10);
thrust::device_vector<int> vecPosZ(10, 10);
创建向量和一些值
编辑3:
我为我的错误解释道歉,请耐心等待。 以下是预期和意外结果的完整,简单,可编辑和可运行的示例:
example.cu:
#include <thrust/device_vector.h>
#include <thrust/for_each.h>
#include <thrust/iterator/zip_iterator.h>
#include <iostream>
thrust::device_vector<int> vecPosX(5, 10);
thrust::device_vector<int> vecPosY(5, 10);
struct acc_func {
acc_func(int X, int Y) : _x(X), _y(Y) {}
template <typename Tuple>
__device__ __host__
void operator()(Tuple t){
acc2[0] = _x;
acc2[1] = _y;
acc[0] += 1;
acc[1] += 1;
}
void expected(){
printf("expected:\t%d:%d:and:%d:%d\n", 5, 5, _x, _y);
return;
}
void not_expected(){
printf("unexpected:\t%d:%d:nor:%d:%d\n\n", acc[0], acc[1], acc2[0], acc2[1]);
return;
}
public:
int acc2[2];
private:
int _x, _y;
int acc[2] = {0, 0};
};
int main(){
for(unsigned int i = 0; i < vecPosX.size(); ++i){
acc_func AF(vecPosX[i], vecPosY[i]);
thrust::for_each(
thrust::make_zip_iterator(thrust::make_tuple(vecPosX.begin(),vecPosY.begin())),
thrust::make_zip_iterator(thrust::make_tuple(vecPosX.end(), vecPosY.end())),
AF
);
AF.expected();
AF.not_expected();
}
return 0;
}
结果:
$ nvcc -std=c++11 example.cu -o example
$ ./example
expected: 5:5:and:10:10
unexpected: 0:0:nor:19:0
expected: 5:5:and:10:10
unexpected: 0:0:nor:19:0
expected: 5:5:and:10:10
unexpected: 0:0:nor:19:0
expected: 5:5:and:10:10
unexpected: 0:0:nor:19:0
expected: 5:5:and:10:10
unexpected: 0:0:nor:19:0
编辑4
我想要实现的是重写以下代码:
float ax, ay, az, dx, dy, dz;
float invr, invr3, f;
for(unsigned int i = 0; i < particles.size(); i++){
ax = 0.0;
ay = 0.0;
az = 0.0;
for(unsigned int j = 0; j < particles.size(); j++){
dx = (float) (particles[j]->mPosX - particles[i]->mPosX);
dy = (float) (particles[j]->mPosY - particles[i]->mPosY);
dz = (float) (particles[j]->mPosZ - particles[i]->mPosZ);
invr = (float) 1.0/sqrt(dx*dx + dy*dy + dz*dz + 100);
invr3 = invr*invr*invr;
f = particles[j]->mass * invr3;
ax += f*dx;
ay += f*dy;
az += f*dz;
}
particles[i]->mPosX = particles[i]->mPosX + (int) dt*particles[i]->xVel + (int) 0.5*dt*dt*ax;
particles[i]->mPosY = particles[i]->mPosY + (int) dt*particles[i]->yVel + (int) 0.5*dt*dt*ay;
particles[i]->mPosZ = particles[i]->mPosZ + (int) dt*particles[i]->zVel + (int) 0.5*dt*dt*az;
particles[i]->xVel += dt*ax;
particles[i]->yVel += dt*ay;
particles[i]->zVel += dt*az;
}
我的目的是保持外环非常实际,使用推力计算 ax , ay , az (因为它& #39; s遍历向量中的一堆元素)并使用结果 for_each 更新向量。
如何安全地计算 ax , ay 和 az 并将其返回?
你看到的粒子是
std::vector<Particle *> particles;
和 Particle 是一个具有成员变量的类
int mPosX, mPoY, mPosZ;
float xVel, yVel, zVel;
int mass;
和dt是:
const float dt = 0.1f;
因此,不是包含整数和浮点数的类,而是创建了整数和浮点数的向量,以便每个向量的第i个元素(质量,速度,位置的向量)对应于关于一个特定粒子的信息