我正在尝试在C语言上运行Runge-Kutta 4。代码如下:
__kernel void updade_state( __global float8 *q,__global float8 *qm, __global float8 *v){
const int gid = get_global_id(0);
float8 qs;
//k1
f( q, v);
qs = q[gid] + dt * v[gid]/6.0;
qm[gid] = q[gid] + 0.5 * dt * v[gid];
//k2
f(qm, v);
qs += dt * v[gid]/3.0;
qm[gid] = q[gid] + 0.5 * dt * v[gid];
//k3
f( qm, v);
qs += dt * v[gid]/3.0;
qm[gid] = q[gid] + dt * v[gid];
//k4
f( qm, v);
qs += dt * v[gid]/6.0;
//update particle
q[gid] = qs;
}
我正在使用pyopencl模块访问我的显卡(“ gid ”),以便更有效地运行多个粒子的模拟。
除了在内核中调用的函数 f 之外,内核的其余部分是在python程序中构建的,通过它添加常量值 dt < / strong>,出现在我的Runge-Kutta代码中。
但是,当我运行整个事情时,会显示以下错误消息:
<kernel>:52:22: error: can't convert between vector values of different size ('double' and 'float8')
qs = q[gid] + dt * v[gid]/6.0;
~~ ^ ~~~~~~
<kernel>:53:33: error: can't convert between vector values of different size ('double' and 'float8')
qm[gid] = q[gid] + 0.5 * dt * v[gid];
~~~~~~~~ ^ ~~~~~~
<kernel>:57:15: error: can't convert between vector values of different size ('double' and 'float8')
qs += dt * v[gid]/3.0;
~~ ^ ~~~~~~
<kernel>:58:33: error: can't convert between vector values of different size ('double' and 'float8')
qm[gid] = q[gid] + 0.5 * dt * v[gid];
~~~~~~~~ ^ ~~~~~~
<kernel>:62:15: error: can't convert between vector values of different size ('double' and 'float8')
qs += dt * v[gid]/3.0;
~~ ^ ~~~~~~
<kernel>:63:27: error: can't convert between vector values of different size ('double' and 'float8')
qm[gid] = q[gid] + dt * v[gid];
~~ ^ ~~~~~~
<kernel>:67:15: error: can't convert between vector values of different size ('double' and 'float8')
qs += dt * v[gid]/6.0;
干杯
答案 0 :(得分:1)
好吧,我解决了这个问题并通过在内核中转换值dt和其他常量来解决它,正如Jiminion所建议的那样。这不是最优雅的解决方案,但它有效。
__kernel void updade_state( __global float8 *q,__global float8 *qm, __global float8 *v){
const int gid = get_global_id(0);
float8 qs;
float dt, c1, c2, c3;
c1 = 6.0;
c2 = 3.0;
c3 = 0.5;
dt = 0.0001;
//k1
f( q, v);
qs = q[gid] + dt * v[gid]/c1;
qm[gid] = q[gid] + c3 * dt * v[gid];
//k2
f(qm, v);
qs += dt * v[gid]/c2;
qm[gid] = q[gid] + c3 * dt * v[gid];
//k3
f( qm, v);
qs += dt * v[gid]/c2;
qm[gid] = q[gid] + dt * v[gid];
//k4
f( qm, v);
qs += dt * v[gid]/c1;
//update photon
q[gid] = qs;
}