Multiples and divisors. OpenMP version

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

Files

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);
}
#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;
}