In a bidimensional array of characters A of size NxN, we want to find the maximum number of coincidences with a bidimensional mask B of size MxM.
A number of problems is solved. For each problem the function to parallelize has:
Input parameters:
-int N: for the size of the array
-char *A: the array where to search for the maximum
-int M: for the size of the mask
-char *B: the mask
-int node: node identifier
int np: number of MPI processes
return an integer with the maximum number of coincidences
3 13 4 2 3 1800 48 6 5 1950 41 9 7
/* CPP_CONTEST=2017 CPP_PROBLEM=F CPP_LANG=CPP+MPI CPP_PROCESSES_PER_NODE=1 CPP_NUM_NODES=1 */ #include <stdlib.h> #include <mpi.h> int count(int ld,int n,char *a,char *b) { int i,j; int value=0; for(i=0;i < n;i++) for(j=0;j < n;j++) if(a[i*ld+j]==b[i*n+j]) value++; return value; } int sec(int n,char *a,int m,char *b,int node,int np) { int i, j; int maximum=0,value; for (i = 0; i <= n-m; i++) { for (j = 0; j <= n-m; j++) { value=count(n,m,&a[i*n+j],b); if(value>maximum) maximum=value; } } return maximum; }
esquema-mpi.cpp (non modifiable, used by mooshak for in/out and evaluation, provided for local experiments)
#include <stdlib.h> #include <stdio.h> #include <sys/time.h> #include <mpi.h> #include <signal.h> #include <unistd.h> //Spanish Parallel programming Contest 2017. Problem F - CESGA //Maximum coincidence with a mask in 2D. MPI version. //Schema for In/Out, validation and execution time void generar(char *m, int t,int sup) { int i; for (i = 0; i < t; i++) { m[i] = (char) (((1. * rand()) / RAND_MAX)*sup)+'a'; } } void escribir(char *m, int t) { int i; for (i = 0; i < t; i++) { printf("%c ", m[i]); } printf("\n"); } /* c c mseconds - returns elapsed milliseconds since Jan 1st, 1970. c */ long long mseconds(){ struct timeval t; gettimeofday(&t, NULL); return t.tv_sec*1000 + t.tv_usec/1000; } static void alarm_handler(int sig) { fprintf(stderr, "Time Limit Exceeded\n"); abort(); } extern int sec(int,char *,int,char *,int ,int); int main(int argc,char *argv[]) { int N,M,cuantos,result; bool correcto=true; int semilla,upper; char *A,*B; long long ti,tf,tt=0; int nodo,np; FILE *stats_file = fopen("stats", "w"); struct sigaction sact; sigemptyset(&sact.sa_mask); sact.sa_flags = 0; sact.sa_handler = alarm_handler; sigaction(SIGALRM, &sact, NULL); alarm(40); /* time limit */ MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&np); MPI_Comm_rank(MPI_COMM_WORLD,&nodo); // The number of test cases is read // and sent to all the processes if(nodo==0) { scanf("%d",&cuantos); MPI_Bcast(&cuantos,1,MPI_INT,0,MPI_COMM_WORLD); } else { MPI_Bcast(&cuantos,1,MPI_INT,0,MPI_COMM_WORLD); } for(int i=0;i<cuantos;i++) { if(nodo==0) { scanf("%d",&N); // Matrices size scanf("%d",&M); // mask size scanf("%d",&semilla); // seed for random generation scanf("%d",&upper); // upper value for random generation // Space for the matrix, the values, rows and columns A = (char *) malloc(sizeof(double)*N*N); B = (char *) malloc(sizeof(double)*M*M); srand(semilla); generar(A,N*N,upper); generar(B,M*M,upper); /*#ifdef DEBUG escribir(A,N*N); escribir(B,M*M); #endif*/ } MPI_Barrier(MPI_COMM_WORLD); ti=mseconds(); result=sec(N,A,M,B,nodo,np); MPI_Barrier(MPI_COMM_WORLD); tf=mseconds(); if(nodo==0) { if(i!=0) tt+=tf-ti; printf("%d\n",result); free(A); free(B); } } if(nodo==0) { fprintf(stats_file, "%Ld\n", tt); fclose(stats_file); } MPI_Finalize(); return 0; }