⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 collapse.c

📁 c语言应用MPI并行计算程序实例.可将一个大数字(大于百万位)并行collapse,成为一个digit.例如11->2,179->17->8
💻 C
字号:
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h> 

int ItoOneDigit(int);

int	chunk_size = 99;

int main(int argc, char *argv[])
{
    int 		myid, numprocs;
    FILE*       fp;
    char        ch[chunk_size];
    
    MPI_Init (&argc, &argv);
	MPI_Comm_size (MPI_COMM_WORLD, &numprocs);
	MPI_Comm_rank (MPI_COMM_WORLD, &myid);
	
	if(myid == 0){
            int* 			lSum = (int*)calloc(numprocs - 1, sizeof(int)); 
	        MPI_Request* 	reqs = (MPI_Request*)calloc(numprocs - 1, sizeof(MPI_Request));
	        int* 			indices = (int *)malloc((numprocs-1)*sizeof(int)); 
	        MPI_Status * 	stat=(MPI_Status*)malloc(sizeof(MPI_Status)*(numprocs - 1));
	        int 			i, count, numRunningProcs, lastlocation, tmp;
	        int             result;

	        count = numprocs - 1;
		    for (i = 0; i < count; i++)
			    indices[i] = i;
            for (i = 0; i < chunk_size; i++)
                ch[i] = '0';              
		    numRunningProcs = 0;
		    result = 0;

		    if((fp=fopen(argv[1],"r"))==NULL)
            {    printf("cannot open file\n");
                 exit(1);
            }

            fseek(fp,0,2);
            lastlocation = ftell(fp);
            
            fseek(fp,0,0);
            while (numRunningProcs || (lastlocation - ftell(fp)) > chunk_size){
                  for(i = 0; i < count && ((lastlocation - ftell(fp)) > chunk_size); i++){
                        fread(ch,1,chunk_size,fp);
                        MPI_Send(&ch,chunk_size,MPI_CHAR,indices[i]+1,1,MPI_COMM_WORLD);
                        numRunningProcs++;
                        MPI_Irecv((lSum + indices[i]), 1, MPI_INT, indices[i] + 1, 1, MPI_COMM_WORLD, reqs + indices[i]); 
                  }
                  MPI_Testsome(numprocs-1,reqs ,&count,indices ,stat);
			      numRunningProcs -= count;      
			      for (i = 0; i < count; i++){
                      result += *(lSum + indices[i]);
                  }
            }
            
             for (i = 0; i < chunk_size; i++)
                      ch[i] = '0';
             tmp = lastlocation - ftell(fp);
             fread(ch,1,(lastlocation - ftell(fp)),fp);

             for (i = 0; i < tmp; i++){
                 if ((int)(ch[i] - '0')>=0 && (int)(ch[i] - '0')<=9){
                       result += (int)(ch[i] - '0');
                 }
           }         
                      
             result = ItoOneDigit(result);  
            
            
            for (i = 0; i < chunk_size; i++)
                      ch[i] = '0';
            ch[0] = '$';
	    	for(i = 0; i < numprocs - 1; i++)
		          MPI_Send(&ch,1,MPI_CHAR,i+1,1,MPI_COMM_WORLD);
			      
            printf("%d\n", result);
		    free(lSum);
		    free(reqs);
		    free(indices);
		    free(stat); 
		    fclose(fp);            
    }    
    else{
         MPI_Status stat;
	     MPI_Request req;
	     
	     while (1){
               int i, result = 0, sum = 0;
               
               MPI_Recv(&ch,chunk_size,MPI_CHAR,0,1,MPI_COMM_WORLD, &stat);
               
               if (ch[0] == '$')
	              break;
	              
                for (i = 0; i < chunk_size; i++){
                    if ((int)(ch[i] - '0')>=0 && (int)(ch[i] - '0')<=9){
                       sum += (int)(ch[i] - '0');
                    }
                }
               
               result = ItoOneDigit(sum);
               
               MPI_Isend(&result, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &req);
			   MPI_Wait(&req,&stat);
         }
    }
         
    MPI_Finalize();
	return 0;
}

int ItoOneDigit(int input){
       int x = input;
       int sum = 0;
       
       while (x >= 10){
             sum += x%10;
             x /= 10;
       }
       sum += x; 
       if (sum <10 )
          return sum;
       else
           return ItoOneDigit(sum);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -