2016-10-24 3 views
-1

Есть ли простой способ объединить несколько текстовых файлов, поступающих из нескольких ядер на одном ядре.Объединение текстовых файлов с MPI

Ядро 0

1 4 6 4 2 6 
4 5 4 2 4 7 
3 5 6 7 8 5 

Ядро 1

5 6 7 5 3 6 
5 6 7 8 5 4 
6 4 3 5 6 7 

Ядро 2

6 7 8 5 3 6 
4 5 7 3 4 5 
8 7 6 5 2 3 
6 7 8 6 5 4 
8 9 0 3 2 1 

Я хочу, чтобы добавить текстовые файлы на ядре 0 с текстовыми файлами из ядра 1 и ядра 2. Я знаю, что это что-то вроде ...

int textSize = ...; // size of text file on each core 
     if (rank == 0) { 
      int size = malloc(sizeof(float) * textSize); 
     } 
     MPI_Gather(&name_of_text_file, textSize, MPI_FLOAT, *size, textSize, MPI_FLOAT, 0, MPI_COMM_WORLD); 

Любая помощь будет оценена по достоинству.

+1

Я понимаю, что вы не хотите конкатенировать файлы (например, писать на диске), а собирать все локальные массивы в один. Я также предполагаю, что вы хотите использовать числа (какой?), А не текст. Правильно ли это? – MakisH

+0

Да, все они плавают. – brad

ответ

0

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

В этом случае, возможно, вы ищете функцию MPI_Gatherv. Он работает почти так же, как функция MPI_Gather, но вы можете определить для каждого процесса, сколько данных будет отправлено (массив recvcounts, указанный в принимающем ранге), и были ли они помещены в целевое местоположение (массив displs).

Вот два примера из документации MPI Forum:

Простой MPI_Gather, в котором только мастер ранга выделяет память для полного массива данных:

MPI_Comm comm; 
int gsize,sendarray[100]; 
int root, myrank, *rbuf; 
... 
MPI_Comm_rank(comm, myrank); 
if (myrank == root) { 
    MPI_Comm_size(comm, &gsize); 
    rbuf = (int *)malloc(gsize*100*sizeof(int)); 
    } 
MPI_Gather(sendarray, 100, MPI_INT, rbuf, 100, MPI_INT, root, comm); 

Example of MPI_Gather (from MPI Forum)

В этом примере все процессы имеют фрагменты из 100 целых чисел. В вашем случае вы можете изменить int на float.

MPI_Gatherv:

MPI_Comm comm; 
    int gsize,sendarray[100]; 
    int root, *rbuf, stride; 
    int *displs,i,*rcounts; 
...  
MPI_Comm_size(comm, &gsize); 
    rbuf = (int *)malloc(gsize*stride*sizeof(int)); 
    displs = (int *)malloc(gsize*sizeof(int)); 
    rcounts = (int *)malloc(gsize*sizeof(int)); 
    for (i=0; i<gsize; ++i) { 
     displs[i] = i*stride; 
     rcounts[i] = 100; 
    } 
    MPI_Gatherv(sendarray, 100, MPI_INT, rbuf, rcounts, displs, MPI_INT, 
                   root, comm); 

Example of MPI_Gatherv (from MPI Forum)

В этом примере, такое же количество элементов, полученных (100 целые числа) и регулярно положить в области памяти, которые отделены друг от друга целыми числами stride. Целевой массив (rbuf) может хранить (number_of_ranks * stride) целые числа.

Вы можете совершенно игнорировать фиксированного размера походку и установить displs и rcounts индивидуально для каждого процесса, если вы их знаете. Если вы их не знаете, посмотрите последний пример на странице форума MPI.

В любом случае, я предполагаю, что вы используете одиночные указатели для ваших данных (например, array [i]), а не double (например, array [i] [j]). Это требует дополнительных усилий для установки правильных индексов, но их проще использовать в MPI, а в некоторых случаях и быстрее.

Смежные вопросы