From c292175f00747d7c2a52373e8db70cca6448d8a5 Mon Sep 17 00:00:00 2001 From: Jan Vales Date: Mon, 30 Jan 2012 01:32:53 +0100 Subject: [PATCH] mpiscan: schoenere einruekung und getopt + fileread. --- scan/scan.c | 254 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 166 insertions(+), 88 deletions(-) diff --git a/scan/scan.c b/scan/scan.c index 4fe6578..256c95b 100755 --- a/scan/scan.c +++ b/scan/scan.c @@ -7,100 +7,178 @@ #include #include #include +#include #include #include "scan.h" // tag for control messages -#define KEY 1234 - -void array_contents ( unsigned long arr[], unsigned long size ) { - fprintf (stdout, "[%li", arr[0]); - for (unsigned long i = 1; i < size; i++) { - fprintf (stdout, ", %li", arr[i]); - } - fprintf (stdout, "]\n"); +#define KEY 1337 + +/* This one's binary name. */ +char* binname = "unset"; + +void usage () { + fprintf (stderr, "\nUsage: mpirun -node 1-32 -nnp 1 %s [-f ] [-n ]\n", binname); + fprintf (stderr, "\t -f: set the filename of the randfile. (defaults to \"numlist.bin\")\n"); + fprintf (stderr, "\t -n: set the number count to read from randfile. (defaults to -1 = read all)\n\n"); +} + + +void array_contents(unsigned long arr[], unsigned long size){ + fprintf(stdout, "[%li", arr[0]); + for(unsigned long i = 1; i < size; i++){ + fprintf(stdout, ", %li", arr[i]); + } + fprintf(stdout, "]\n"); } int main(int argc, char *argv[]){ - int tmp; - int tmp2; - - /* node info stuff*/ - int rank, nodes; - char name[MPI_MAX_PROCESSOR_NAME]; - MPI_Init(&argc,&argv); - MPI_Comm_size(MPI_COMM_WORLD,&nodes); - MPI_Comm_rank(MPI_COMM_WORLD,&rank); - MPI_Get_processor_name(name,&tmp); - fprintf(stdout, "[%d/%d:%s] openMPI initialised.\n",rank,nodes,name); - - /* data */ - unsigned long size = 18; - unsigned long blocksize = size/nodes; - if(blocksize*nodes < size){ - blocksize++; - fprintf(stdout, "[%d/%d:%s] perfect split impossible: n:%d, s:%li ==> bs:%li (off: %li)\n",rank,nodes,name,nodes,size,blocksize,(nodes*blocksize)-size); - } - - unsigned long databuf[size]; - - /* temp stuff */ - MPI_Status status; - MPI_Request request; - - /* stuff done by root */ - if (rank == 0) { - fprintf(stdout, "[%d/%d:%s] I am root. Size: %li nodes: %d blocksize: %li (n*b: %li) (n*b+1: %li)- reading data...\n",rank,nodes,name,size,nodes,blocksize,nodes*blocksize, nodes*(blocksize+1)); - for (unsigned long i = 0; i < size; i++) { - databuf[i]=10; - } - MPI_Isend(&databuf, size-1, MPI_LONG, 0, KEY, MPI_COMM_WORLD, &request); - } - - // MPI_Recv(&databuf,1,MPI_INT,nodes-1,KEY,MPI_COMM_WORLD,MPI_STATUS_IGNORE); - /* stuff done by all others */ - tmp = rank -1; - if (tmp < 0)tmp = 0; - MPI_Recv(&databuf, size, MPI_LONG, tmp, KEY, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - - /* propagate data, if not last node. */ - if(rank +1 < nodes) MPI_Send(&databuf, size, MPI_LONG, rank+1, KEY, MPI_COMM_WORLD); - - /* do processing here. */ - for (unsigned long i = (rank*blocksize+1); i < ((rank+1)*blocksize) && i < size; i++) { - databuf[i] = databuf[(i-1)] + databuf[i]; - } - fprintf(stdout, "[%d/%d:%s] proc array ",rank,nodes,name); - array_contents(databuf, size); - - - /* receive sums */ - if (rank != 0){ - MPI_Recv(&databuf, rank*blocksize, MPI_LONG, tmp, KEY, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - fprintf(stdout, "[%d/%d:%s] rcv array ",rank,nodes,name); - array_contents(databuf, size); - for (unsigned long i = rank*blocksize; i < ((rank+1)*blocksize); i++) { - databuf[i] += databuf[((rank*blocksize)-1)]; - } - fprintf(stdout, "[%d/%d:%s] added array ",rank,nodes,name); - array_contents(databuf, size); - } - - tmp = rank +1; - if (tmp >= nodes)tmp = 0; - tmp2 = ((rank+1)*blocksize); - if (tmp2 > size)tmp2 = size; - MPI_Send(&databuf, tmp2, MPI_LONG, tmp, KEY, MPI_COMM_WORLD); - - /* receive result by root */ - if (rank == 0) { - MPI_Recv(&databuf, size, MPI_LONG, nodes-1, KEY, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - fprintf(stdout, "[%d/%d:%s] I AM ROOT! got data from %d.\n",rank,nodes,name,nodes-1); - fprintf(stdout, "[%d/%d:%s] result array ",rank,nodes,name); - array_contents(databuf, size); - } - - MPI_Finalize(); - return 0; + int tmp; + int tmp2; + FILE *file = NULL; + MPI_Request request; + unsigned long blocksize; + unsigned long *databuf; + + /* options */ + unsigned long size = 0; + char *filename = "numlist.bin"; + + /* store out name for usage(); */ + binname = argv[0]; + + /* node info stuff*/ + int rank, nodes; + char name[MPI_MAX_PROCESSOR_NAME]; + MPI_Init(&argc,&argv); + MPI_Comm_size(MPI_COMM_WORLD,&nodes); + MPI_Comm_rank(MPI_COMM_WORLD,&rank); + MPI_Get_processor_name(name,&tmp); + //fprintf(stdout, "[%d/%d:%s] openMPI initialised.\n",rank,nodes,name); + + /* getopt stuff */ + int c; + opterr = 0; + while ((c = getopt (argc, argv, "n:f:")) != -1) switch (c){ + case 'n': + size = strtoul (optarg,NULL,0); + break; + case 'f': + filename = optarg; + break; + case '?': + if (optopt == 'f' || optopt == 'n') + fprintf (stderr, "Option -%c requires an argument.\n", optopt); + else if (isprint (optopt)) + fprintf (stderr, "Unknown option `-%c'.\n", optopt); + else + fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt); + if (rank == 0)usage(); + MPI_Finalize(); + exit(2); + + default: + if (rank == 0)usage(); + MPI_Finalize(); + exit(2); + } + + /* sanize size, calculate blocksize, init databuf. */ + if ((file = fopen(filename, "r"))) { + fclose(file); + file = NULL; + struct stat st; + stat(filename, &st); + if (size <= 0 || size > st.st_size){ + size = st.st_size; + } + }else{ + if(rank == 0){ + fprintf (stdout, "[%d/%d:%s] File %s does not exist.\n",rank,nodes,name,filename); + usage(); + } + MPI_Finalize(); + exit(3); + } + + databuf = malloc(size * sizeof(unsigned long)); + if(databuf == NULL) { + fprintf(stdout, "[%d/%d:%s] malloc for databuf failed.\n",rank,nodes,name); + MPI_Finalize(); + exit(2); + } + + blocksize = size/nodes; + if(blocksize*nodes < size){ + blocksize++; + if(rank == 0) + fprintf(stdout, "[%d/%d:%s] perfect split impossible: n:%d, s:%li -> bs:%li (off: %li)\n",rank,nodes,name,nodes,size,blocksize,(nodes*blocksize)-size); + } + + if(rank == 0){ + fprintf(stdout, "[%d/%d:%s] s: %li n: %d bs: %li n*b: %li n*(b+1): %li\n",rank,nodes,name,size,nodes,blocksize,nodes*blocksize, nodes*(blocksize+1)); + + /* read file. */ + if ((file = fopen(filename, "r"))) { + for (unsigned long i = 0; i < size; i++) { + databuf[i] = fgetc(file); + } + fclose(file); + }else{ + fprintf (stdout, "[%d/%d:%s] File %s could not be read.\n",rank,nodes,name,filename); + usage(); + MPI_Finalize(); + exit(3); + } + + fprintf(stdout, "[%d/%d:%s] file read - distributing work.\n",rank,nodes,name); + MPI_Isend(databuf, size-1, MPI_LONG, 0, KEY, MPI_COMM_WORLD, &request); + } + + /* stuff done by all others */ + tmp = rank -1; + if(tmp < 0) tmp = 0; + MPI_Recv(databuf, size, MPI_LONG, tmp, KEY, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + /* propagate data, if not last node. */ + if(rank +1 < nodes) MPI_Send(databuf, size, MPI_LONG, rank+1, KEY, MPI_COMM_WORLD); + + /* do processing here. */ + for(unsigned long i = (rank*blocksize+1); i < ((rank+1)*blocksize) && i < size; i++){ + databuf[i] = databuf[(i-1)] + databuf[i]; + } + //fprintf(stdout, "[%d/%d:%s] proc array ",rank,nodes,name); + //array_contents(databuf, size); + + + /* receive sums */ + if(rank != 0){ + MPI_Recv(databuf, rank*blocksize, MPI_LONG, tmp, KEY, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // fprintf(stdout, "[%d/%d:%s] rcv array ",rank,nodes,name); + // array_contents(databuf, size); + for(unsigned long i = rank*blocksize; i < ((rank+1)*blocksize) && i < size; i++){ + databuf[i] += databuf[((rank*blocksize)-1)]; + } + // fprintf(stdout, "[%d/%d:%s] added array ",rank,nodes,name); + // array_contents(databuf, size); + } + + tmp = rank +1; + if(tmp >= nodes) tmp = 0; + tmp2 = ((rank+1)*blocksize); + if(tmp2 > size) tmp2 = size; + MPI_Send(databuf, tmp2, MPI_LONG, tmp, KEY, MPI_COMM_WORLD); + + /* receive result by root */ + if(rank == 0){ + MPI_Recv(databuf, size, MPI_LONG, nodes-1, KEY, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + fprintf(stdout, "[%d/%d:%s] result: %li\n",rank,nodes,name,databuf[size-1]); +// fprintf(stdout, "[%d/%d:%s] res array ",rank,nodes,name); +// array_contents(databuf, size); + } + + MPI_Finalize(); + return 0; } + -- 2.43.0