C MPI管道使用插入排序

发布于 2025-02-01 11:29:22 字数 4487 浏览 3 评论 0 原文

我正在尝试使用此技术来实现:

因此,该程序在arraysize = numberfprocessors时可以工作并分类元素。问题在于我需要实现一种算法,该算法将数组分为冠军,主人将能够将Sublist发送到从属上进行整理。

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include <time.h>    // time()
#define WORKTAG 1  /* WORKTAG for sending a number */

void Compare_And_Swap(int duomenuBlokas[], int proc_Nr, int step, int *maxValue, int *gottenValue, int sizeOfSublist);
void Collect_And_Sort (int proc_Nr, int sizeOfArray, int maxValue, int *sortedArray);

int main ( int argc, char *argv[] )
{
   int processNumber; // current process number : 0 - Master
   int * sortingArray; // Our sorting array
   int * subList; // sublist
   int tempValue;
   int maxValue;
   int numberOfProcessors; // On how many processors we run our program
   MPI_Status status;
   MPI_Init(&argc,&argv);
   int arraySize = atoi(argv[1]); // Aray size input through the console
   int sizeOfSublist;
   subList = (int*)calloc(arraySize,sizeof(int));
   MPI_Comm_size(MPI_COMM_WORLD,&numberOfProcessors);
   MPI_Comm_rank(MPI_COMM_WORLD,&processNumber);
   if(processNumber==0) /* Master generates p random numbers */
   {
      sortingArray = (int*)calloc(arraySize,sizeof(int));
      srand(time(NULL));
      for(int i = 0; i < arraySize; i++)
      {
          sortingArray[i] = rand() % 100;
      }
      printf("The %d numbers to sort : ",arraySize);
      for(int i =0; i<arraySize; i++)
      {
          printf(" %d", sortingArray[i]);
      }
      printf("\n");
      fflush(stdout);
   }
       sizeOfSublist = arraySize / numberOfProcessors; // Get the size of each subList
       subList = (int*)calloc(sizeOfSublist,sizeof(int));
       MPI_Scatter(sortingArray, sizeOfSublist, MPI_INT, subList, // Get sublists
        sizeOfSublist, MPI_INT, 0, MPI_COMM_WORLD);

   for(int i=0; i<numberOfProcessors-processNumber; i++)
   {
      if(processNumber==0) // Master gets the value
      {
         tempValue = sortingArray[i]; // Send subLists here [21,32] for example
         printf("Master gets %d.\n",sortingArray[i]);
         fflush(stdout);

         Compare_And_Swap(subList,processNumber,i,&maxValue,&tempValue, sizeOfSublist); // Masteris siunc
      }
      else // Slave receives the value
      {
         MPI_Recv(&tempValue,1,MPI_INT,processNumber-1,WORKTAG,MPI_COMM_WORLD,&status);
         printf("Slave %d receives %d.\n",processNumber,tempValue);
         fflush(stdout);
         Compare_And_Swap(subList,processNumber,i,&maxValue,&tempValue, sizeOfSublist);
      }
   }
   Collect_And_Sort(processNumber,arraySize,maxValue,subList); // Collect values


    printf("Exit. \n");
    MPI_Finalize();
    return 0;
}

void Compare_And_Swap(int duomenuBlokas[], int proc_Nr, int step, int *maxValue, int *gottenValue, int sizeOfSublist) // Parallel pipe-sort function
{

   if(step==0) // assign maxValue
   {
       *maxValue = *gottenValue;
   }

   else
      if(*gottenValue > *maxValue)  // Send maxValue
      {
         MPI_Send(maxValue,1,MPI_INT ,proc_Nr+1,WORKTAG,MPI_COMM_WORLD);
         printf("Slave %d sends %d to %d.\n",proc_Nr,*maxValue,proc_Nr+1);
         fflush(stdout);
         *maxValue = *gottenValue;

      }
      else // Send gotten value
      {
         MPI_Send(gottenValue,1,MPI_INT,proc_Nr+1,WORKTAG,MPI_COMM_WORLD);
         printf("Slave %d sends %d to %d.\n",proc_Nr,*gottenValue,proc_Nr+1);
         fflush(stdout);
      }
}

 void Collect_And_Sort(int proc_Nr, int sizeOfArray, int maxValue, int *sortedArray)
{
   MPI_Status status;

   if(proc_Nr==0)
   {
      sortedArray[0] = maxValue;
      for(int i=1; i<sizeOfArray; i++)
      {
         MPI_Recv(&sortedArray[i],1,MPI_INT,i,WORKTAG,MPI_COMM_WORLD,&status);
      }
      printf("Sorted array: ");
      for(int i=0; i<sizeOfArray; i++)
      {
        printf(" %d",sortedArray[i]);
      }
      printf("\n");
   }
   else
   {
        MPI_Send(&maxValue,1,MPI_INT,0,WORKTAG,MPI_COMM_WORLD);
   }

}

我使用mpi_ -scatter获取了订书机,我认为我应该将它们发送到这个地方:tempvalue = sortingArray [i]替换为tmparray = sublist; sublist;我遇到的问题是所有值都是相同的,因为“ Master” ProcessID -0仅包含第一个sublist。例如,数组[2,3,4,5,6,7,8],在MPI_Scatter“ Master”之后,每次仅发送[2,3]。非常感谢。

如果需要,我还可以附加结果图片,以使其更加清晰。让我知道!

I am trying to implement using this technique: http://homepages.math.uic.edu/~jan/mcs572/pipelinedsort.pdf

Therefore, the program works and sorts elements when arraySize = numberOfProcessors. The problem is that I need to implement an algorithm, which would divide the array into subLists and the master would be able to send subList to the slave to sort it out.

#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include <time.h>    // time()
#define WORKTAG 1  /* WORKTAG for sending a number */

void Compare_And_Swap(int duomenuBlokas[], int proc_Nr, int step, int *maxValue, int *gottenValue, int sizeOfSublist);
void Collect_And_Sort (int proc_Nr, int sizeOfArray, int maxValue, int *sortedArray);

int main ( int argc, char *argv[] )
{
   int processNumber; // current process number : 0 - Master
   int * sortingArray; // Our sorting array
   int * subList; // sublist
   int tempValue;
   int maxValue;
   int numberOfProcessors; // On how many processors we run our program
   MPI_Status status;
   MPI_Init(&argc,&argv);
   int arraySize = atoi(argv[1]); // Aray size input through the console
   int sizeOfSublist;
   subList = (int*)calloc(arraySize,sizeof(int));
   MPI_Comm_size(MPI_COMM_WORLD,&numberOfProcessors);
   MPI_Comm_rank(MPI_COMM_WORLD,&processNumber);
   if(processNumber==0) /* Master generates p random numbers */
   {
      sortingArray = (int*)calloc(arraySize,sizeof(int));
      srand(time(NULL));
      for(int i = 0; i < arraySize; i++)
      {
          sortingArray[i] = rand() % 100;
      }
      printf("The %d numbers to sort : ",arraySize);
      for(int i =0; i<arraySize; i++)
      {
          printf(" %d", sortingArray[i]);
      }
      printf("\n");
      fflush(stdout);
   }
       sizeOfSublist = arraySize / numberOfProcessors; // Get the size of each subList
       subList = (int*)calloc(sizeOfSublist,sizeof(int));
       MPI_Scatter(sortingArray, sizeOfSublist, MPI_INT, subList, // Get sublists
        sizeOfSublist, MPI_INT, 0, MPI_COMM_WORLD);

   for(int i=0; i<numberOfProcessors-processNumber; i++)
   {
      if(processNumber==0) // Master gets the value
      {
         tempValue = sortingArray[i]; // Send subLists here [21,32] for example
         printf("Master gets %d.\n",sortingArray[i]);
         fflush(stdout);

         Compare_And_Swap(subList,processNumber,i,&maxValue,&tempValue, sizeOfSublist); // Masteris siunc
      }
      else // Slave receives the value
      {
         MPI_Recv(&tempValue,1,MPI_INT,processNumber-1,WORKTAG,MPI_COMM_WORLD,&status);
         printf("Slave %d receives %d.\n",processNumber,tempValue);
         fflush(stdout);
         Compare_And_Swap(subList,processNumber,i,&maxValue,&tempValue, sizeOfSublist);
      }
   }
   Collect_And_Sort(processNumber,arraySize,maxValue,subList); // Collect values


    printf("Exit. \n");
    MPI_Finalize();
    return 0;
}

void Compare_And_Swap(int duomenuBlokas[], int proc_Nr, int step, int *maxValue, int *gottenValue, int sizeOfSublist) // Parallel pipe-sort function
{

   if(step==0) // assign maxValue
   {
       *maxValue = *gottenValue;
   }

   else
      if(*gottenValue > *maxValue)  // Send maxValue
      {
         MPI_Send(maxValue,1,MPI_INT ,proc_Nr+1,WORKTAG,MPI_COMM_WORLD);
         printf("Slave %d sends %d to %d.\n",proc_Nr,*maxValue,proc_Nr+1);
         fflush(stdout);
         *maxValue = *gottenValue;

      }
      else // Send gotten value
      {
         MPI_Send(gottenValue,1,MPI_INT,proc_Nr+1,WORKTAG,MPI_COMM_WORLD);
         printf("Slave %d sends %d to %d.\n",proc_Nr,*gottenValue,proc_Nr+1);
         fflush(stdout);
      }
}

 void Collect_And_Sort(int proc_Nr, int sizeOfArray, int maxValue, int *sortedArray)
{
   MPI_Status status;

   if(proc_Nr==0)
   {
      sortedArray[0] = maxValue;
      for(int i=1; i<sizeOfArray; i++)
      {
         MPI_Recv(&sortedArray[i],1,MPI_INT,i,WORKTAG,MPI_COMM_WORLD,&status);
      }
      printf("Sorted array: ");
      for(int i=0; i<sizeOfArray; i++)
      {
        printf(" %d",sortedArray[i]);
      }
      printf("\n");
   }
   else
   {
        MPI_Send(&maxValue,1,MPI_INT,0,WORKTAG,MPI_COMM_WORLD);
   }

}

I used MPI_Scatter to get the sublists and I am thinking that I should send them in this place: tempValue = sortingArray[i] replace with something tmpArray = subList; The problem I encountered is that all the values are the same because "MASTER" processID - 0 contains only the first subList. For example array[2,3,4,5,6,7,8] and after MPI_Scatter "MASTER" sends only [2,3] everytime. Thank you a lot.

If needed, I can also attach the result pictures to make it more clear. Let me know!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

紫罗兰の梦幻 2025-02-08 11:29:22

通常,您需要使用 MPI_Scatterv 一般。如果所有标准师的长度相同,则您的方法将起作用。

更大的问题是您的测试如果( *GottenValue&gt; *MaxValue)需要变得更加复杂,因为您的 GottenValue 将是一个数组,因此您需要比较每个数组成分。例如,您可以在每个通信对中:让两个进程都从另一个接收,并且仅保留最低/最高的elemts。

You need to use MPI_Scatterv in general. Your approach will work if all the sublists have the same length.

The bigger problem is that your test if(*gottenValue > *maxValue) needs to become much more complicated because your gottenValue will be an array, so you need to compare each component. You could for instance in each communicating pair: let both processes receive from the other and keep only the lowest/highest set of elememts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文