многомерный массив — чтение hdf5 в c ++ с проблемами памяти

Я переписываю код, который я разработал на python, в c ++, в основном для повышения скорости; в то же время надеясь получить больше опыта в этом языке. Я также планирую использовать openMP для распараллеливания этого кода на 48 ядрах, которые совместно используют 204 ГБ памяти.

Программа, которую я пишу, проста, я импортирую файл hdf5, который является 3D:
A [T] [X] [E], где T связан с каждым временным шагом моделирования, X представляет место измерения поля, а E (0: 2) представляет электрическое поле в x, y, z.
Каждый элемент в A является двойным, и размеры ячеек охватывают: A [15000] [80] [3].

Первый сбой, с которым я столкнулся, — это ввод этого «большого» файла h5 в массив, и мне хотелось бы получить профессиональное мнение, прежде чем я продолжу. Моя первая попытка:

...
#define RANK  3
#define DIM1  15001
#define DIM2  80
#define DIM3  3

using namespace std;
int main (void)
{
//  Define HDF5 variables for opening file.
hid_t   file1, dataset1;
double bufnew[DIM1][DIM2][DIM3];
herr_t ret;
uint  i, j, k;

file1 = H5Fopen (FILE1, H5F_ACC_RDWR, H5P_DEFAULT);
dataset1 = H5Dopen (file1, "EFieldOnLine", H5P_DEFAULT);
ret = H5Dread (dataset1, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL,
H5P_DEFAULT, bufnew);

cout << "Let's try dumping 0->100 elements" << endl;
for(i=1; i < 100; i++) cout << bufnew[i][20][2] << endl;
...

что приводит к ошибке сегментации из объявления массива. Моим следующим шагом было использование либо трехмерного массива (нового), либо трехмерного вектора. Тем не менее, я видел много споров против этих методов, и что более важно, мне нужен только ОДИН компонент E, т.е. я хотел бы изменить A [T] [X] [E] -> B [T] [X] для скажем, х-компонента Е.

Извините за длинный пост, но я хотел быть как можно более ясным и хотел бы еще раз подчеркнуть, что мне интересно узнать, как писать самый быстрый и эффективный код.
Я ценю все ваши предложения, время и мудрость.

0

Решение

Определение массива как локальной переменной означает его размещение в стеке. Размер стека обычно ограничен несколькими мегабайтами, и переполнение стека, безусловно, приводит к segfault. Большие структуры данных должны динамически размещаться в куче (используя new оператор) или статически (когда определены как глобальные переменные).

Я бы не советовал составлять вектор векторов для таких размерностей.

Вместо этого создаем одномерный массив для хранения всех значений

double *bufnew = new double[DIM1*DIM2*DIM3];

и доступ к нему по следующей формуле для расчета линейного положения данного трехмерного элемента

bufnew[(T*DIM2+X)*DIM3+E] = ... ; // bufnew[T][X][E]

должно работать нормально.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]