Связь с древовидной структурой MPI - PullRequest
0 голосов
/ 28 мая 2020

Я написал этот код, чтобы отслеживать и проверять обмен данными в модели MPI. идея здесь в том, что, если есть, например, 8 процессоров, узел-0- будет связываться с самим собой и с узлом-4-. также узел-4- обменивается данными с узлом-6- и узел-2- на другой стороне дерева обменивается данными с узлом-3-. вот изображение этой схемы. enter image description here

поэтому я написал приведенный ниже код, чтобы увидеть, как узлы передают массив элементов друг другу. строки 31-33 вычисляют параметры каждого узла. точно так же, как двоичное дерево, но немного отличается. вот проблема: когда я выполняю Код, каждый дочерний узел возвращает своему родителю некоторый мусор рядом с элементами массива. Я не могу понять, в чем проблема. может ли кто-нибудь помочь мне?

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

void print_array(int arr[], int size)
{
    for (int i = 0; i < size; i++)
        printf("%d ", arr[i]);
    printf("\n");
}
/***********************************************************************/
void copyarray(int a[] ,int start_a , int end_a, int* b, int size_b)
{
    int i = 0;
    for (i = 0; i < size_b;i++)
    {
        b[i] = a[start_a];
        start_a++;
        if (start_a > end_a)
            break;
    }
}
/***************************************************/
void tree (int arr[],int size,int level)
{
    int rank;
    int numOfcores;
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&numOfcores);
    int parent = rank & ~(1 << level);
    int next = level - 1;
    int rightChild = rank | (1 << (level - 1));

         if(level>0)
         {
                printf("\n enterig the divid process\n");
                printf("\n i am the node %d with te Rank of %d and height of %d \n",rank,rank,level);
                 int mid = (int)(size/2);///////////////////////////////////////////////////
                 print_array(arr,size);
                 tree(arr,mid,next);
                 int rightsize=size-mid;////////////////////////////////////////////////////////
                 int* rightArray =(int*)calloc(rightsize,sizeof(int));
                 if(rightArray==NULL)
                 return;
                 copyarray(arr,mid,size,rightArray,rightsize);////////////////////////////////////////
                 int massage[2];
                 massage[0]=next;
                 massage[1]=rightsize;
                 MPI_Send(massage,2,MPI_INT,rightChild,0,MPI_COMM_WORLD);
                 MPI_Send(rightArray,rightsize,MPI_INT,rightChild,1,MPI_COMM_WORLD);   

                 int* recvArray = (int*)calloc(rightsize,sizeof(int));

                 if(parent!=rank)
                 {
                  printf("\n i am the node %d withe height of  %d and i send my array to parent %d ",rank,level,parent);
                  MPI_Send(arr,size,MPI_INT,parent,2,MPI_COMM_WORLD);
                 }
                 MPI_Recv(recvArray,size,MPI_INT,rightChild,2,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
                 printf("\n i am the parent node %d with the height of %d and i recieved form %d the array :\n ",rank,level,rightChild);
                 print_array(recvArray,size);
                 free(rightArray);
                 free(recvArray);
         } 

         else 
         {
            printf("\n i am the node %d with the height of %d and i have the array of : \n ",rank,level);
            print_array(arr,size);
            if(parent!=rank)
             {
                 printf("\n i am the node %d withe height of  %d and i send my array to parent %d ",rank,level,parent);
                  MPI_Send(arr,size,MPI_INT,parent,2,MPI_COMM_WORLD);
             }
            printf("\n");
         }     
}

/*************************************/
int main()
{
    int arr[10]={1,2,3,4,5,6,7,8,9,10};
    int rank;
    int comm_size;
    MPI_Init(NULL,NULL);
    MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    MPI_Comm_size(MPI_COMM_WORLD,&comm_size);

    if(rank==0)
    {
        int rootHeight=0;
        int nodeCount=1;
        while (nodeCount<comm_size)
        {
            nodeCount++;
        }
        rootHeight=(int)log2(nodeCount);
        printf("i am the root with the rank of %d and height of %d\n",rank,rootHeight);
        tree(arr,10,rootHeight);
    }
    else 
    {
        int height;
        int massage[2];
        int newSize;
        MPI_Recv(massage,2,MPI_INT,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
        height=massage[0];
        newSize=massage[1];
        int* newArray = (int*)calloc(newSize,sizeof(int));
        MPI_Recv(newArray,newSize,MPI_INT,MPI_ANY_SOURCE,1,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
        tree(newArray,newSize,height);
        free(newArray);
    }
    MPI_Finalize();
    return 0;

}

когда я запускаю код для 4 процессоров, результат будет:

i am the root with the rank of 0 and height of 2

 enterig the divid process

 i am the node 0 with te Rank of 0 and height of 2 

1 2 3 4 5 6 7 8 9 10 

 enterig the divid process

 i am the node 0 with te Rank of 0 and height of 1 

1 2 3 4 5 

 i am the node 0 with the height of 0 and i have the array of : 

 1 2 


 i am the node 1 with the height of 0 and i have the array of : 

 3 4 5 

 i am the node 1 withe height of  0 and i send my array to parent 0 

 i am the parent node 0 with the height of 1 and i recieved form 1 the array :

 3 4 5 0 0 

 enterig the divid process

 i am the node 2 with te Rank of 2 and height of 1 

6 7 8 9 10 

 i am the node 2 with the height of 0 and i have the array of :

 6 7 



 i am the parent node 0 with the height of 2 and i recieved form 2 the array :

 6 7 8 9 10 0 104993 0 0 0 

 i am the node 3 with the height of 0 and i have the array of : 

 8 9 10 

 i am the node 3 withe height of  0 and i send my array to parent 2 

 i am the node 2 withe height of  1 and i send my array to parent 0 

 i am the parent node 2 with the height of 1 and i recieved form 3 the array :

 8 9 10 0 0
...