Мне нужно использовать MPI для вычисления значения концентрации из 3D-матрицы.
Я делю свою матрицу на кусочки в зависимости от того, какое количество процедур я буду использовать.
Я получаю меньшую трехмерную матрицу, которая работает независимо, но я хочу, чтобы вычисляемые ими значения концентрации записывались в один и тот же файл, например, строки от 0 до n-1 записывались процедурой от 0, от n до 2n-1 с помощью процедуры 1. .
Я знаю, что могу использовать смещение в функции mpi_file_write_at, чтобы выполнить такую вещь, но я не знаю, как это реализовать.
Я знаю, что простым решением было бы попросить proc 0 открыть файл, записать и закрыть его, после чего откроется процесс 1.
Не обращайте внимания на код сам по себе, поскольку он не закончен
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
char *name = argv[1];
double h, m, L, T_max, v_x, v_y, v_z, D, r_thresh;
unsigned int S;
FILE *file = fopen(name, "rb");
if (!file)
{
fprintf(stderr, "Not able to open the file %s\n", name);
}
else
printf("Able to open the file %s\n", name);
fscanf(file, "%lf", &h);
fscanf(file, "%lf", &m);
fscanf(file, "%lf", &L);
fscanf(file, "%lf", &T_max);
fscanf(file, "%lf", &v_x);
fscanf(file, "%lf", &v_y);
fscanf(file, "%lf", &v_z);
fscanf(file, "%lf", &D);
fscanf(file, "%u", &S);
fscanf(file, "%lf", &r_thresh);
fclose(file);
if (((L/h) % 2) != 0){
printf("Uncorrect parameters L and h ! \n");
return -1;
}
else{
unsigned int edge = (L/h);
unsigned int middle = edge/2;
unsigned int N = edge+1;
}
if (((T_max/m) % 1) != 0){
printf("Uncorrect parameters T_max and m ! \n");
return -1;
}
else{
unsigned int t_end = T_max/m;
}
unsigned int myrank, nbproc;
MPI_Init(&argc, &argv) ;
MPI_Comm_rank( MPI_COMM_WORLD , &myrank );
MPI_Comm_size( MPI_COMM_WORLD , &nbproc );
double w = N/nbproc;
unsigned int width = round(w);
unsigned int k_min, k_max;
k_min = myrank*width;
k_max = (myrank+1)*width-1;
width = width+2;
if (nbproc==1){
width = N;
}
else if (myrank==(nbproc-1)){
k_max = N-1;
width = k_max-k_min+1;
width = width+1;
}
else if (myrank==0){
width = width-1;
}
double ***C ;
C = malloc(width * sizeof(*C));
for(k=0 ; k < width ; k++){
C[k] = malloc(N * sizeof(**C));
}
for(k=0 ; k < width ; k++){
for(j=0 ; j < N ; j++){
C[k][j] = malloc(N * sizeof(***C));
}
}
unsigned int i,j,k,n;
for(k=0 ; k<width ; k++){
for(j=0 ; j<N ; j++){
for(i=0 ; i<N ; i++){
C[k][j][i]=0;
}
}
}
if (middle>=k_min && middle=<k_max){
C[middle-k_min][middle][middle] = 1;
}
if (myrank==0 || nbproc==1){
k_min = k_min +1 ;
}
if (myrank==(nbproc-1) || nbproc==1){
k_max = k_max -1 ;
}
for(n=1 ; n<T_max ; n++){
char *c = "c_";
char buffer[10];
itoa(n,buffer,2);
strcat(c,buffer);
// I want to write some value stored in a buffer now
// computed by different process in the same file
// MPI_File_write_at ???
}
for(k=0 ; k < width ; k++){
for(j=0 ; j < N ; j++){
free(C[k][j]);
}
free(C[k]);
}
free(C);
return 0;
}
все ли линии имеют одинаковую и фиксированную длину?
Обычно да, но в любом случае каждый процесс будет знать, сколько строк он должен написать. @GillesGouaillardet
важно то, сколько байтов должна знать каждая задача, если вы этого не знаете, это будет сложно.
каждая задача будет обрабатывать [sizeof (MPI_DOUBLE) * (L / h) * (L / h) * глубину среза]. Я не знаю, имеет ли это значение для вас, но все наши вычисления будут выполняться в кластере моего университета, поэтому я почти уверен, что у меня будет достаточно памяти.





Каждый процесс в программе MPI имеет локальное адресное пространство. Файловый ввод-вывод меняет это: файл - это глобально доступный линейный поток байтов. Вам нужно подумать о том, где в глобальном пространстве пишет каждый процесс. Пара способов сделать это:
иногда вы можете просто заставить каждый процесс писать в соответствующий фрагмент файла. нулевой ранг записывает в первый мегабайт, ранг 1 - во второй и так далее. Возможно, это будет слишком упрощенно для вашего трехмерного массива.
Для более сложной декомпозиции вы устанавливаете «файловое представление»: вы создаете тип данных MPI, описывающий структуру данных на диске. в вашем случае MPI_TYPE_CREATE_SUBARRAY, вероятно, то, что вы хотите: трехмерная глобальная матрица, и каждый процесс вносит свой вклад в глобальную картину.
минимальный воспроизводимый пример приветствуется! просто поставьте комментарий вместо записи в файл.