np.zeros与C误解中的数组分配



我需要在大型实对称2D矩阵上使用来自LAPACKdsyev函数。我可以从scipy.linalg.lapack使用它,但它没有在合理的时间内完成计算。

我可以从>以intel 2020套件为模块的HPC集群上的20个核心。由于原因,我不能在集群中使用与笔记本电脑中相同的python代码,并设置环境变量MKL_NUM_THREADS=32我唯一的前进之路是使用C和"英特尔MKL"作为C。

我研究了英特尔MKL关于如何在C.中使用dsyev函数的例子

我在python中的2D数组的形状是np.float64(20160, 20160)20160 = 252 * 80。我只写了T = np.zeros((20160, 20160), dtype=np.float64),然后根据我的任务进行填充。最后,我使用np.flatten(order='C')对其进行整形,然后以.npy.txt格式将其保存到磁盘中。

在这里我请求您的帮助:

我正试着用C。我的基本程序适用于较小的1D阵列大小,例如doubles的(20000,),但在实际尝试读取整个1D阵列时失败,然后与dsyev一起使用。例如,根据google:250 * 80 * 250 * (64 bytes) = 0.32 gigabytes,我不知道为什么我不能在C程序中使用那种大小的1D数组。

我在C:中的代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
double arrayy[252*80*250];
// double *arrayy = (double*) malloc(250*80*100*sizeof(double));
printf("Hehe");
FILE *fp;
fp = fopen("1D_array.txt", "rb");
for ( int i = 0; i < 250*80 ; i++) {
// fread(&(array[i]), sizeof(array[i]), 1, fp);
fscanf(fp, "%lf", &arrayy[i]);
}
// fread(&(arrayy[0]), sizeof(double), 252*80*3, fp);
fclose(fp);
for ( int i = 0 ; i < 252*80 ; i++ ) {
if (i % 1000 == 0)
printf("Value at index %d is %fn", i, arrayy[i]);
}
}

我在Windows 11的Linux 1(WSL1(的Windows子系统中使用gcc 9.3.0.17,该系统具有16GB的RAM。

谢谢!

更新

当使用$ gcc -Wall test.c$./a.out进行编译时,会返回$ Segmentation fault (core dumped),而不会打印其他内容!

在C中,数组与任何其他局部变量一样在堆栈上分配,与堆相比,这是内存中相对较小的区域。

该行double arrayy[252*80*250];可能导致堆栈溢出,该堆栈溢出表现为分段故障。为了与Python代码保持一致,您应该动态分配数组,如下所示:

double *arrayy = malloc(250*80*100*sizeof(*arrayy));

请注意,您不需要强制转换,您可以执行sizeof(*arrayy)而不是sizeof(double)

还要注意,在您的代码中,您似乎毫无理由地在252和250之间交替。您可能只需要将数组的大小命名为一个变量,如下所示:

const unsigned long arrayy_size = 252 * 80 * 252 * 80;
double *arrayy = malloc(arrayy_size * sizeof(*arrayy));
// [...]
for (unsigned long i = 0; i < arrayy_size; ++i) {
// use arrayy[i]
}

最新更新