我希望有人可以提供以下帮助,但我不知道出了什么问题。下面的函数用于使用3D拉普拉斯算子将3维矩阵和向量相乘,尽管这对于了解此问题不是必需的。我在函数的开头创建了两个宏,以从3D几何空间映射到线性存储空间。
使用宏从X(i,j-1,k)访问元素X(0,0,0)时出现分段错误,即当电流循环为i = 0,j = 1时对于具有n_x,n_y和n_z = 100(100x100x100)的系统,,k = 0,(0,1,0)。因此,宏会将3D几何形状(0,0,0)更改为线性索引0,可以通过打印确认。打印时访问x [0]很好。并且打印宏的结果也为零。
抱歉,我可能对宏的理解很简单?我正在使用动态内存分配数组。
void matvec_mul(int N,int n_x, int n_y, int n_z,double* restrict Ax,double* restrict x){
#define X(i,j,k) (x[(i*n_y*n_z)+(j*n_z)+k])
#define AX(i,j,k) (Ax[(i*n_y*n_z)+(j*n_z)+k])
int inv_h2 = (n_x-1)*(n_x-1);
for (int i = 0; i < n_x; ++i) {
for (int j = 0; j < n_y; ++j) {
for (int k = 0; k < n_z; ++k) {
printf("%i,%i,%i\n",i,j,k);
printf("%i\n",(i*n_y*n_z)+(j*n_z)+k);
double xx = X(i,j,k);
double xn = (i > 0) ? X(i-1,j,k) : 0;
double xs = (i < n_x-1) ? X(i+1,j,k) : 0;
printf("Seg faults on next line\n");
double xe = (j > 0) ? X(i,j-1,k) : 0;
double xw = (j < n_y-1) ? X(i,j+1,k) : 0;
double xu = (k > 0) ? X(i,j,k-1) : 0;
double xd = (k < n_z-1) ? X(i,j,k+1) : 0;
AX(i,j,k) = (6*xx - xn - xs - xe - xw - xu - xd)/inv_h2;
}
}
}
#undef AX
#undef X
}
答案 0 :(得分:1)
问题是由于宏替换文本中的宏参数周围没有括号。
将宏定义更改为以下内容:
#define X(i,j,k) (x[((i)*n_y*n_z)+((j)*n_z)+(k)])
#define AX(i,j,k) (Ax[((i)*n_y*n_z)+((j)*n_z)+(k)])
使用您的原始宏,X(i,j-1,k)
将扩展为(x[(i*n_y*n_z)+(j-1*n_z)+k])
,但您需要(x[(i*n_y*n_z)+((j-1)*n_z)+k])
。 (请注意(j-1*n_z)
和((j-1)*n_z)
之间的区别。)使用新的宏,替换为(x[((i)*n_y*n_z)+((j-1)*n_z)+(k)])
。