Первая настоящая ошибка, которую я обнаружил, была такая:
MPI_Scatterv(&vett,sendcounts,displs,MPI_LONG,&c,1,MPI_LONG,0,MPI_COMM_WORLD);
, который передает адрес ::std::vector<int>
в функцию, которая ожидает void*
в этом аргументе. Преобразование любого типа указателя (например, ::std::vector<int>*
) в void*
допускается как неявное преобразование, поэтому на этом этапе нет ошибок компиляции. Однако MPI_Scatterv ожидает, что его первый аргумент будет адресом буфера отправки, который MPI ожидает, чтобы быть нормальным массивом.
Я полагаю, что вы недавно изменили свой код из закомментированных разделов, где vett
- это массив, и попытались заставить ваш вызов работать, добавив оператор address-of в ваш вызов MPI_Scatterv
. Исходный массив, вероятно, вызвал segfaults в какой-то момент, так как он был выделен стеком, и вы исчерпали пространство стека с этими монстрами (размер стека по умолчанию в системах Linux составляет порядка мегабайт iirc, что в точности соответствует этому предположению - проверьте это с помощью ulimit -s ).
Изменение на ::std::vector<int>
привело к тому, что вместо этого фактические данные были помещены в кучу, которая имеет гораздо больший максимальный размер (и в 64-разрядных системах можно ожидать, что физической памяти будет не хватать раньше). Вы уже реализовали решение вашей конкретной проблемы несколькими строчками ранее:
MPI_Scatter(&vett[dim*myrank], dim, MPI_LONG, &parsum, dim, MPI_LONG, 0, MPI_COMM_WORLD);
Здесь вы получаете доступ к элементу и затем берете его адрес (обратите внимание, что []
связывает более жесткие , чем &
). Хорошо. до тех пор, пока вы не измените базовый vector
. Если вы просто примените это решение к предыдущему вызову, вы можете решить эту проблему довольно легко:
MPI_Scatterv(&vett[0],sendcounts,displs,MPI_LONG,&c,1,MPI_LONG,0,MPI_COMM_WORLD);
В любом случае, за исключением двух vector
объектов, ваш код выглядит так, как будто он был написан для старого стандарта C, а не для C ++ - например, вы можете рассмотреть такие вещи, как new
Семейство операторов вместо malloc.h
, вы можете поместить объявления переменных в соответствие с их определениями (даже внутри for
заголовков цикла !), упростив вашу жизнь с помощью ostream
cout вместо printf
...