2012-12-13 20 views
25

Şimdiye kadar, başvurum tamsayılar listesini içeren bir txt dosyasında okuyor. Bu tamsayılar, bir dizide ana işlemle yani işlemcinin sıra 0 ile saklanması gerekir. Bu iyi çalışıyor.MPI_Scatter ve MPI_Gather C'den nasıl kullanılır?

Şimdi, programı çalıştırdığımda, ana işlem olup olmadığını kontrol edersem bir if deyim var ve varsa MPI_Scatter komutunu çalıştırıyorum. Bu sayılarla diziyi bölmek ve rütbe> 0 ile yani bütün köle süreçlerine dışarı geçecek anladığım

. Ancak, MPI_Scatter'un nasıl işleneceğinden emin değilim. Alt-dizi almak için köle süreci nasıl "abone" olur? Ana olmayan süreçlere alt diziyle bir şeyler yapmasını nasıl söyleyebilirim?

Birisi, ana işlemin diziden öğeleri nasıl gönderdiklerini ve daha sonra kölenin toplamı nasıl eklediğini ve bunu tüm toplamları bir araya getiren ve basan master'a vermesini göstermek için basit bir örnek sağlayabilir mi? Bugüne kadar

Kodum:

#include <stdio.h> 
#include <mpi.h> 

//A pointer to the file to read in. 
FILE *fr; 

int main(int argc, char *argv[]) { 

int rank,size,n,number_read; 
char line[80]; 
int numbers[30]; 
int buffer[30]; 

MPI_Init(&argc, &argv); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank); 
MPI_Comm_size(MPI_COMM_WORLD, &size); 

fr = fopen ("int_data.txt","rt"); //We open the file to be read. 

if(rank ==0){ 
printf("my rank = %d\n",rank); 

//Reads in the flat file of integers and stores it in the array 'numbers' of type int. 
n=0; 
while(fgets(line,80,fr) != NULL) { 
    sscanf(line, "%d", &number_read); 
    numbers[n] = number_read; 
    printf("I am processor no. %d --> At element %d we have number: %d\n",rank,n,numbers[n]); 
    n++; 
} 

fclose(fr); 

MPI_Scatter(&numbers,2,MPI_INT,&buffer,2,MPI_INT,rank,MPI_COMM_WORLD); 

} 
else { 
MPI_Gather (&buffer, 2, MPI_INT, &numbers, 2, MPI_INT, 0, MPI_COMM_WORLD); 
printf("%d",buffer[0]); 
} 
MPI_Finalize(); 
return 0; 
} 

cevap

56

Bu operasyonlar buna yeni insanlarla MPI nasıl çalıştığını ortak bir yanlış anlama; Özellikle, insanların sırayla 0'dan başlayarak (MPI_Bcast) yayınlamayı denediği toplu işlemlerde, bir şekilde çağrıyı bir şekilde diğer işlemcilere "ittirmek" için beklemek. Ama bu MPI rutinlerinin işleyişi değil; Çoğu MPI iletişimi hem gönderen hem de alıcı için MPI aramaları gerektirir.

Özellikle

, MPI_Scatter() ve MPI_Gather() (ve MPI_Bcast, ve diğerleri) toplu işlemlerdir; onlar Communicator'daki görevlerin tüm tarafından yapılmak zorunda. Communicator'daki tüm işlemciler aynı çağrıyı yapar ve işlem gerçekleştirilir. (Bu nedenle, dağınıklık ve toplanmanın her ikisi de, tüm verilerin nereye gittiği/geldiği "kök" işleminin parametrelerden biri olmasını gerektirir). Bu şekilde, MPI uygulamasının iletişim kalıplarını optimize etmek için pek çok alanı vardır.

#include <mpi.h> 
#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) { 
    int size, rank; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    int *globaldata=NULL; 
    int localdata; 

    if (rank == 0) { 
     globaldata = malloc(size * sizeof(int)); 
     for (int i=0; i<size; i++) 
      globaldata[i] = 2*i+1; 

     printf("Processor %d has data: ", rank); 
     for (int i=0; i<size; i++) 
      printf("%d ", globaldata[i]); 
     printf("\n"); 
    } 

    MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD); 

    printf("Processor %d has data %d\n", rank, localdata); 
    localdata *= 2; 
    printf("Processor %d doubling the data, now has %d\n", rank, localdata); 

    MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD); 

    if (rank == 0) { 
     printf("Processor %d has data: ", rank); 
     for (int i=0; i<size; i++) 
      printf("%d ", globaldata[i]); 
     printf("\n"); 
    } 

    if (rank == 0) 
     free(globaldata); 

    MPI_Finalize(); 
    return 0; 
} 

o verir Koşu:

gpc-f103n084-$ mpicc -o scatter-gather scatter-gather.c -std=c99 
gpc-f103n084-$ mpirun -np 4 ./scatter-gather 
Processor 0 has data: 1 3 5 7 
Processor 0 has data 1 
Processor 0 doubling the data, now has 2 
Processor 3 has data 7 
Processor 3 doubling the data, now has 14 
Processor 2 has data 5 
Processor 2 doubling the data, now has 10 
Processor 1 has data 3 
Processor 1 doubling the data, now has 6 
Processor 0 has data: 2 6 10 14 
+2

Ne mükemmel cevap

Yani burada (toplamak dahil etmek Güncelleme ) basit bir örnek. Çok ileriye doğru yaptı ve şimdi nasıl çalıştığını görüyorum. Bunu kolektif operasyonlar olarak düşünmeme hatasını yaptım. Çok teşekkürler! – DSF

+2

Vay! Günümü kurtardın Cheers. Teşekkürler – irobo

+0

Çoğu MPI girişinden çoğundan daha yararlıdır – WakaChewbacca

İlgili konular