We consider a matrix of natural numbers, A, of size NxN. Each value in the matrix, A[i,j], is substituted by the sum of the values in the same row i (without considering A[i,j]) which are multiples or divisors of A minus the sum of the values in the same column j which are multiples or divisors of A.
A number of problems is solved. For each problem the function to parallelize has:
Input parameters:
-int N: for the size of the matrix
-int *A: matrix NxN of natural numbers
3
3 1 1 5 1
800 4 1 20 72
750 3 2 30 67
/* CPP_CONTEST=2018Qual CPP_PROBLEM=A CPP_LANG=CPP+OPENMP CPP_PROCESSES_PER_NODE=1 CPP_NUM_NODES=1 */ #include < stdlib.h > #include < stdio.h > #include < omp.h > #include < iostream > #include < iomanip > #include < math.h > using namespace std; void copy(int n,int *vd,int *vo) { for(int i=0;i < n;i++) vd[i]=vo[i]; } void update(int n,int *a,int *b,int row,int column) { int element=a[row*n+column]; int *da=&a[row*n+column]; int *db=&b[row*n+column]; for(int i=1;i < n-column;i++) //the previous elements in the same row have been compared in previous calls to the routine { if(element%da[i]==0 || da[i]%element==0) { db[0]+=da[i]; db[i]+=da[0]; } } for(int i=1;i < n-row;i++) //the previous elements in the same column have been compared in previous calls to the routine { if(element%da[i*n]==0 || da[i*n]%element==0) { db[0]-=da[i*n]; db[i*n]-=da[0]; } } } void sec(int n,int *a) { int *b=(int *) calloc(sizeof(int),n*n); //to store the updated values for(int i=0;i < n;i++) { for(int j=0;j < n;j++) update(n,a,b,i,j); } copy(n*n,a,b); free(b); }
esquema-openmp.cpp (non modifiable, used by mooshak for in/out and evaluation, provided for local experimentation)
#include < stdlib.h > #include < stdio.h > #include < sys/time.h > #include < omp.h > #include < signal.h > #include < unistd.h > #include < iostream > #include < iomanip > #include < math.h > using namespace std; // Scheme for the problem of Multiples and divisors - OpenMP version // Qualification contest for the Spanish Parallel Programming Contest 2018, problem A //initialize a vector void inicialize(int n,int *m,int lv,int uv) { for(int i=0;i < n;i++) m[i]=int(((1.*rand())/RAND_MAX)*(uv-lv)+lv); } //write a matrix, only for debug void escribir(int n,int m,int *a){ for (int i = 0; i < n; i++) { for(int j=0;j < m;j++) cout << a[i*m+j]<<" "; cout <> num_problems; // 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 < num_problems;i++) { // if(nodo==0) // { cin >>N; // The first argument is the size of the vector cin >>seed; //seed for the random generation of data to generate cin >>lower_value; //lower bound for the values in the vector cin >>upper_value; //upper bound for the values in the vector cin >>gap; //gap between values to write in the output // Space for the data A = new int[N*N]; srand(seed); inicialize(N*N,A,lower_value,upper_value); #ifdef DEBUG // While debugging the vector written escribir(N,N,A); #endif // } // MPI_Barrier(MPI_COMM_WORLD); ti=mseconds(); sec(N,A); // MPI_Barrier(MPI_COMM_WORLD); tf=mseconds(); // if(nodo==0) // { // The time of the first input is not considered if(i!=0) tt+=tf-ti; #ifdef DEBUG // While debugging the time of each execution is written fprintf(stats_file, "%Ld\n", tf-ti); escribir(N,N,A); #endif // The results of each problem are written, // even for the first problem escribirresult(N*N,A,gap); delete[] A; // } */ } // if(nodo==0) // { fprintf(stats_file, "%Ld\n", tt); fclose(stats_file); // } // MPI_Finalize(); return 0; }