Beispiel #1
0
static void init_matrices(group_t *grp)
{
	int size = grp->matrix_size;
	int index = grp->group_id;
	int credit = grp->credit_value;

	matrices_A[index] = (matrix_t*)MALLOCZ_SAFE(sizeof(matrix_t));
	matrices_B[index] = (matrix_t*)MALLOCZ_SAFE(sizeof(matrix_t));
	matrices_C[index] = (matrix_t*)MALLOCZ_SAFE(sizeof(matrix_t));
	
	matrices_A[index]->m = (int *)MALLOCZ_SAFE((sizeof(int))*size*size); 
	matrices_B[index]->m = (int *)MALLOCZ_SAFE((sizeof(int))*size*size);
	matrices_C[index]->m = (int *)MALLOCZ_SAFE((sizeof(int))*size*size);

	group_t *grp_A = (group_t *)MALLOCZ_SAFE(sizeof(group_t));	
	group_t *grp_B = (group_t *)MALLOCZ_SAFE(sizeof(group_t));	
	group_t *grp_C = (group_t *)MALLOCZ_SAFE(sizeof(group_t));
	
	grp_A->matrix_size = grp_B->matrix_size = grp_C->matrix_size = size;
	grp_A->credit_value = grp_B->credit_value = grp_C->credit_value = credit;
	grp_A->group_id = grp_B->group_id = grp_C->group_id = index;

	matrices_A[index]->matrix_group = grp_A;
	matrices_B[index]->matrix_group = grp_B;
	matrices_C[index]->matrix_group = grp_C;
	
	generate_matrix(matrices_A[index], 1, size);
	generate_matrix(matrices_B[index], 1, size);
	generate_matrix(matrices_C[index], 0, size);

	return;
}
Beispiel #2
0
static void init_matrices() {
  int i = 0;
  for (i=0; i<4; ++i) {
	generate_matrix(&A[i], 1, sizes[i]);
	generate_matrix(&B[i], 1, sizes[i]);
	generate_matrix(&C[i], 0, sizes[i]);
  }
	return;
}
Beispiel #3
0
int main(int argc, char **argv)
{
   int size;
   int sparsity;
   int diagonality = 10;
 
   char* matrix_file = "/tmp/matrix.txt";
   char* vector_file = "/tmp/vector.txt";

   if (argc == 3 || argc == 4)
   { 
      size  = atoi(argv[1]); 
      sparsity = atoi(argv[2]);
    //  if (argc >= 5)
    //  {
    //     matrix_file = argv[3];
    //     vector_file = argv[4];
    //  }
      if (argc == 4)
      {
         diagonality = atoi(argv[3]);
      }
   } 
   else
   {
      printf("Usage: generate_matrix size sparsity diagonality filename\n  size - number of rows/columns\n");
      printf("  sparsity - integer > 0, higher sparsity indices result in sparser matrices\n");
      printf("  diagonality - 0 for uniform distribution, 1 for diagonal\n");
      printf("  filename - optional filename, 'matrix.txt' is default\n");
      exit(-1);
   }
   generate_matrix(size, sparsity, diagonality, matrix_file);
   generate_vector(size, vector_file);
   return 0;
}
Beispiel #4
0
int main() {
	int num;

    printf("How many digits? : ");
	scanf("%d",&num);
	generate_matrix(num);
	return 0;
}
double soft_cos_similarity(char *x_matrix_str, char *y_matrix_str)
{
    Matrix x_matrix = generate_matrix(x_matrix_str);
    Matrix y_matrix = generate_matrix(y_matrix_str);
    double similarity = 0.0;

    for (int i = 0; i < x_matrix.len; i++) {
        for (int j = 0; j < y_matrix.len; j++) {
            double word_sim = white_similarity(x_matrix.words[i], y_matrix.words[j]);
            similarity += (word_sim * x_matrix.values[i] * y_matrix.values[j]);
        }
    }

    free_matrix(x_matrix);
    free_matrix(y_matrix);

    return similarity;
}
Beispiel #6
0
static void * kadane_alg_threaded (void * pa)
{
  ARGS *pargs = (ARGS*) pa;
  cpu_set_t CPU_ID;
  int i;
  int *pps;

  CPU_ZERO(&CPU_ID);
  CPU_SET(pargs->CPU_ID, &CPU_ID);
  sched_setaffinity(0, sizeof(cpu_set_t), &CPU_ID);

  generate_matrix(pargs->n, pargs->m,
                  pargs->thread_number, pargs->total_threads, 
                  pargs->ps, pargs->len, pargs->prelen,
                  pargs->cycle, pargs->precycle, pargs->sync);  

  kadane_thread(pargs->n, pargs->m, pargs->MAX_ROW,
                pargs->total_threads, pargs->thread_number,
                pargs->ps, pargs->workspace, &(pargs->result));
                  
  return 0;
}
Beispiel #7
0
int llc_test_driver (const char *parm, const int *list, 
		     DATASET *dset, gretlopt opt, PRN *prn)
{
    gretl_matrix *m = NULL;
    int *plist = NULL;
    int p0 = -1;
    int err = 0;

    if (*parm == '{') {
	m = generate_matrix(parm, dset, &err);
	if (!err) {
	    plist = gretl_list_from_vector(m, &err);
	}
	gretl_matrix_free(m);
    } else if (gretl_is_matrix(parm)) {
	m = get_matrix_by_name(parm);
	plist = gretl_list_from_vector(m, &err);
    } else if (integer_string(parm)) {
	p0 = atoi(parm);
    } else if (gretl_is_scalar(parm)) {
	p0 = gretl_scalar_get_value(parm, NULL);
    } else {
	err = E_DATA;
    }

    if (!err) {
	if (plist != NULL) {
	    err = levin_lin_test(list[1], plist, dset, opt, prn);
	    free(plist);
	} else {
	    int tmplist[2] = {1, p0};

	    err = levin_lin_test(list[1], tmplist, dset, opt, prn);
	}
    }

    return err;
}
Beispiel #8
0
MODEL quantreg_driver (const char *parm, const int *list, 
		       DATASET *dset, gretlopt opt, PRN *prn)
{
    gretl_vector *tau;
    MODEL mod;
    int err = 0;

    tau = generate_matrix(parm, dset, &err);

    if (!err && gretl_vector_get_length(tau) == 0) {
	err = E_DATA;
    }

    if (err) {
	gretl_model_init(&mod, dset);
	mod.errcode = err;
    } else {
	mod = quantreg(tau, list, dset, opt, prn);
    }

    gretl_matrix_free(tau);

    return mod;
}
Beispiel #9
0
int readphase (Ctrl_str * cp, BB_struct * bp)
{
  char line[MAX_STRING_LEN];
  char *token;
  int i, j, itmp, n, npaded;
  int nx, ny, nz, nc;
  int rflag = 0;
  int index = 0;
  int error = FALSE;
  Mat_str *mp;
  Nuc_str *np;
  P_str *pp;
  MultiS_struct *ms;
  int ele_num, ele_1;
  CA_FLOAT *Cinit_multi_ptr;
  CA_FLOAT **Clim_multi_ptr;
  FILE *fileout;

  ms = &(bp->MultiSvals);       /* local variable for the multi diff values */
  pp = &(bp->pprops);
  mp = &(bp->mprops);
  np = &(bp->nprops);

  nx = bp->nc[0];
  ny = bp->nc[1];
  nz = bp->nc[2];
  nc = bp->ncsb;
  npaded = (nx + 2) * (ny + 2) * (nz + 2);
  bp->ntsb = bp->nsb[0] * bp->nsb[1] * bp->nsb[2];

  /*from read_ctrl.h */
  ele_num = D_NUM_COMP;
   /*******/
  ele_num = cp->NUM_COMP;       /*number of components in the alloy */
  ele_1 = ele_num - 1;

  fileout = fopen ("phase_out", "a+");

/*******************read liquidus temperature and solute concentration****/
/*******************from the input file provided by thermocalc************/

   /*********************************************************/
  /* Open the file                                         */
   /*********************************************************/
  if ((cp->fd_phadia = fopen (cp->fn_phadia, "r")) == NULL) {
    fprintf (stderr, "Error: can't open input file [%s]\n", cp->fn_phadia);
    exit (0);
  }

  while (fgets (line, MAX_STRING_LEN, cp->fd_phadia) != NULL) {
    /* ignore comment and blank lines */
    if (line[0] == '%' || line[0] == '#' || line[0] == '\n' || (token = strtok (line, " ,;\t")) == NULL) {
      continue;

      /*********************************************************/
      /* values for liquidus and solute concentration in liquid */
      /*********************************************************/
      /* number of tie-triangles produced by thermocalc */
    } else if (strcasecmp (token, "NumTieTri") == 0) {
      if ((token = strtok (NULL, " ,;\t")) != NULL) {
        ms->numtietri = atoi (token);
      } else {
        ms->numtietri = D_NUMTIETRI;
      }
    } else {
            /*****assign the first token for each loop****/
      ms->phaval[index][0] = atof (token);
      for (i = 1; i <= 3; i++) {
        if ((token = strtok (NULL, " ,;\t")) != NULL) {
          ms->phaval[index][i] = atof (token);
        }
      }
      index++;
    }
  }                             /* end of while routine */

/******************call generate_matrix routine********************/

  generate_matrix (cp, bp);

/*******************print test for the phase diagram routine******/

  for (i = 0; i < ms->numtietri; i++) {
    fprintf (fileout, "%d \t %f \t %f \t %f \t %f \n", i, ms->phaval[i][0], ms->phaval[i][1], ms->phaval[i][2], ms->phaval[i][3]);
  }
  for (i = 1; i <= 4; i++) {
    fprintf (fileout, "row number %d with %d elements is printed below \n \n", i, ms->counter[i]);
    for (j = 1; j <= ms->counter[i]; j++) {
      fprintf (fileout, "%d \t %f \n", j, ms->xxa[i][j]);
    }
  }
  for (i = 1; i <= ms->counter[3]; i++) {
    for (j = 1; j <= ms->counter[4]; j++) {
      fprintf (fileout, "liquidus function, index %d and %d = %f for %f and %f  \n", i, j, ms->ya1[i][j], ms->xxa[3][i],
               ms->xxa[4][j]);
    }
  }
  fclose (fileout);
  return (1);

}
Beispiel #10
0
int main(int argc, char * argv[])
{
	parse_args(argc, argv);
	const int size = n * n;
	int data_size_bytes = size * sizeof(float);

	float *mat_a = malloc(data_size_bytes);
	float *mat_b = malloc(data_size_bytes);
	float *vector;
	float *output = malloc(data_size_bytes);

	float *expected = malloc(data_size_bytes);

	generate_matrix(n, mat_a, range);
	generate_matrix(n, mat_b, range);

	timing_t timer;
	timer_start(&timer);

	float *mat_b_trans = malloc(data_size_bytes);
	transpose(n, mat_b, mat_b_trans);

	for (int i=0; i<n; ++i) {
		vector = &mat_b_trans[n*i];
		MatMatMultiply(n, mat_a, vector, &output[n*i]);
	}
	float *output_trans = malloc(data_size_bytes);
	transpose(n, output, output_trans);

	timer_stop(&timer);
	float sum = sum_mat(size, output_trans);
	printf("%d %f %ld %ld\n", n, sum, timer.realtime, timer.cputime);

	int status = 0;

	if (trace == 1) {

		printf("\nMatrix A\n");
		for (int i=0; i<n; i++){
			for (int j=0; j<n; j++){
				printf("%f " , mat_a[i*n+j]);
			}
			printf("\n");
		}

		printf("\nMatrix B \n");
		for (int i=0; i<n; i++){
			for (int j=0; j<n; j++){
				printf("%f " , mat_b[i*n+j]);
			}
			printf("\n");
		}

		printf("\n\nResult\n");
		for (int i=0; i<n; i++){
			for (int j=0; j<n; j++){
				printf("%f " , output[i*n+j]);
			}
			printf("\n");
		}
	}

	else if (trace == 2) {
		multiply_CPU_matrix(n, mat_a, mat_b, expected);

		int status = check(size, output_trans, expected);
		if (status) {
			printf("Test failed.\n");
			status = 1;
		}
		else
			printf("Test passed OK!\n");

	}


	free(mat_a);
	free(mat_b);
	free(mat_b_trans);
	free(output);
	free(expected);
	free(output_trans);

	return status;
}
Beispiel #11
0
int main(int argc, char *argv[]) {
  int node_index, node_count;
  int size;
  int block_size;
  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &node_index);
  MPI_Comm_size(MPI_COMM_WORLD, &node_count);

  if (node_index == 0) {
    sprintf(buf, "result%d.txt", node_count);
    freopen(buf, "w", stdout);
  }

  // Timer started
  MPI_Barrier(MPI_COMM_WORLD);
  if (node_index == 0)
    timer_start();
  

  if (argc != 3 && argc != 4) {
    if (node_index == 0)
      printf("Usage: %s matrix_size block_size [input_file]\n", argv[0]);
    MPI_Finalize();
    return -1;
  } else {
    size = atoi(argv[1]);
    block_size = atoi(argv[2]);
    if ((size < 2) || (block_size < 1) || (block_size > size)) {
      if (node_index == 0) {
        printf("Wrong format matrix_size > 1, matrix_size >= block_size > 0\n");
        printf("Usage: %s matrix_size block_size [input_file]\n", argv[0]);
      }
      MPI_Finalize();
      return -2;
    }
  }
  int memlen = size + node_count * block_size - 1;
  memlen /= node_count * block_size;
  memlen *= block_size * size;
  
  double *data = new double [memlen];
  memset(data, 0, memlen * sizeof(double));
  if (argc == 3) {
    generate_matrix(MATRIX_INDEX, size, block_size, node_index, node_count, data);
  } else {
    if (read_matrix_file(argv[3], size, block_size, node_index, node_count, data)) {
      if (node_index == 0)
        printf("Cannot open(read from) file: %s\n", argv[3]);
      delete[] data;
      MPI_Finalize();
      return -3;
    }
  }
  print_matrix(size, block_size, node_index, node_count, data);
  // Initialization done!
  MPI_Barrier(MPI_COMM_WORLD);
  if (node_index == 0)
    print_full_time("on init");

  if (spd_inverse(size, block_size, node_index, node_count, data)) {
    if (node_index == 0)
      printf("Method cannot be applied!\n");
    delete[] data;
    MPI_Finalize();
    return -4;
  }
  
  // Algorithm done!
  MPI_Barrier(MPI_COMM_WORLD);
  if (node_index == 0)
    print_full_time("on algorithm");
  
  // Printing result on console (and in file)
  downtr_to_symm(size, block_size, node_index, node_count, data);
  print_matrix(size, block_size, node_index, node_count, data);
  
  double *workspace = new double[memlen];
  memset(workspace, 0, memlen * sizeof(double));
  // For this two matrices inverse is known
  if (MATRIX_INDEX == 1 || MATRIX_INDEX == 2) {
    if (MATRIX_INDEX == 1)
      generate_matrix(2, size, block_size, node_index, node_count, workspace);
    else
      generate_matrix(1, size, block_size, node_index, node_count, workspace);
    sub_array(memlen, data, workspace);
    double err_norm = inf_norm_matrix(size, block_size, 
                                      node_index, node_count, workspace);
    err_norm = 0;
    // if (node_index == 0)
    //   printf("Error = %11.5le\n", err_norm);
  }
  // Restore input matrix to calculate residual  
  if (argc == 3) {
    generate_matrix(MATRIX_INDEX, size, block_size, node_index, node_count, workspace);
  } else {
    if (read_matrix_file(argv[3], size, block_size, node_index, node_count, workspace)) {
      if (node_index == 0)
        printf("Cannot open(read from) file: %s\n", argv[3]);
      delete[] data;
      delete[] workspace;
      MPI_Finalize();
      return -5;
    }
  }

#ifdef PRINT_RESULT_TO_FILE  
  if (print_matrix_file(output, size, block_size, node_index, node_count, data)) {
    if (node_index == 0)
      printf("Cannot open(print to) file: %s\n", output);
    delete[] data;
    delete[] workspace;
    MPI_Finalize();
    return -6;
  }
#endif

  double *residual = new double[memlen];
  tmatrix_mul(size, block_size, node_index, node_count, workspace, data, residual);
  generate_matrix(-2, size, block_size, node_index, node_count, residual);
  generate_matrix(0, size, block_size, node_index, node_count, workspace);
  sub_array(memlen, workspace, residual);
  downtr_to_symm(size, block_size, node_index, node_count, residual);

  double res_norm = inf_norm_matrix(size, block_size, node_index, node_count, residual);
  if (node_index == 0)
    printf("Residual = %11.5le\n", res_norm);

  delete[] data;
  delete[] workspace;
  delete[] residual;
  MPI_Finalize();
  return 0;
}
Beispiel #12
0
void test_tensor_crs_matrix( const size_t M , const size_t N , const bool print = false )
{
  const size_t length = N * N * N ;

  typedef IntType value_type ; // to avoid comparison round-off differences
  typedef KokkosArray::View<value_type**,KokkosArray::LayoutLeft,Device>
    block_vector_type ;

  typedef KokkosArray::SparseProductTensor< 3 , IntType , Device > block_spec ;
  typedef KokkosArray::BlockCrsMatrix< block_spec , value_type , Device > matrix_type ;

  typedef typename matrix_type::graph_type      graph_type ;
  typedef KokkosArray::ProductTensorIndex<3,Device>  index_type ;

  matrix_type matrix ;

  generate_matrix( M , N , matrix );

  block_vector_type x = block_vector_type( "x" , M , length );
  block_vector_type y = block_vector_type( "y" , M , length );

  typename block_vector_type::HostMirror hx = KokkosArray::create_mirror( x );
  typename block_vector_type::HostMirror hy = KokkosArray::create_mirror( y );

  for ( size_t i = 0 ; i < length ; ++i ) {
    for ( size_t j = 0 ; j < M ; ++j ) {
      hx(j,i) = 1 + j + 10 * i ;
    }
  }

  KokkosArray::deep_copy( x , hx );

  KokkosArray::multiply( matrix , x , y );

  KokkosArray::deep_copy( hy , y );

  // Check answer:

  typename graph_type::HostMirror h_graph =
    KokkosArray::create_mirror( matrix.graph );

  std::map< index_type , IntType > tensor_input ;

  generate_tensor( M , tensor_input );

  for ( size_t outer_row = 0 ; outer_row < length ; ++outer_row ) {
    const size_t outer_entry_begin = h_graph.row_map[outer_row];
    const size_t outer_entry_end   = h_graph.row_map[outer_row+1];

    for ( size_t inner_row = 0 ; inner_row < M ; ++inner_row ) {

      value_type value = 0 ;

      for ( size_t outer_entry = outer_entry_begin ;
                   outer_entry < outer_entry_end ; ++outer_entry ) {

        const size_t outer_column = h_graph.entries( outer_entry );

        for ( typename std::map< index_type , IntType >::iterator
              iter =  tensor_input.begin() ;
              iter != tensor_input.end() ; ++iter ) {

          const index_type index = (*iter).first ;
          const IntType    coeff = (*iter).second ;

          size_t i , j ;

          if ( inner_row == index.coord(2) ) {
            i = index.coord(0);
            j = index.coord(1);
          }
          else if ( inner_row == index.coord(1) ) {
            i = index.coord(0);
            j = index.coord(2);
          }
          else if ( inner_row == index.coord(0) ) {
            i = index.coord(1);
            j = index.coord(2);
          }
          else {
            continue ;
          }

          const IntType ai = generate_matrix_value( i , outer_row , outer_column );
          const IntType aj = generate_matrix_value( j , outer_row , outer_column );

          value += coeff * ( i == j ? ( ai * hx( i , outer_column ) )
                                    : ( ai * hx( j , outer_column ) +
                                        aj * hx( i , outer_column ) ) );
        }
      }

      if ( value != hy(inner_row,outer_row) ) {
        std::ostringstream msg ;
        msg << "correctness test failed "
            << value << " != " << hy(inner_row,outer_row)
            << " = hy( " << inner_row << "," << outer_row << ")" ;
        throw std::runtime_error(msg.str());
      }
      else if ( print ) {
        std::cout << " = hy( " << inner_row << "," << outer_row << ") = "
                  << hy( inner_row , outer_row ) << std::endl ;
      }
    }
  }
}
int main(int argc, char **argv) {
	//int dims[3] = {5,10,15};
	//int dim = 4;
	//int block_dim = 2;
  double time,avg;
  MPI_Init(&argc, &argv);
	int procs;
	int rank;
	MPI_Comm_size(MPI_COMM_WORLD, &procs);
	MPI_Comm_rank(MPI_COMM_WORLD, &rank);

#if doPAPI==1
	data = 0;
	papi_setup();
#endif

	//Check if number of processes is a perfect square
	if (sqrt(procs) != floor(sqrt(procs))) {
		printf("Number of processes is not a perfect square!\n");
		return -1;
	}

	//Read input arguements
	if(argc < 2) {
		if(rank == 0)
			fprintf(stderr,"Wrong # of arguments.\nUsage: mpirun -n procs %s $dim $numThreads $rank2print $doSerial(Only dim and numThreads are required; other 2 are optional)\n",argv[0]);
		return -1;
	}
	int dim = atoi(argv[1]);
  int numThreads = atoi(argv[2]);
	int block_dim = dim/(sqrt(procs));
	int rank2print = -1;
	int doSerial = 0;
	if(argc == 4) {
		rank2print = atoi(argv[3]);
	}
	if(argc == 5) {
		rank2print = atoi(argv[3]); 
		doSerial = atoi(argv[4]);
	}

	//Run code
	if(rank==0)
		printf("Running code on %i procs with dim = %i; numThreads = %i; block_dim = %i; printing on rank %i; doSerial = %i \n",procs, dim, numThreads, block_dim, rank2print, doSerial);
	if(doSerial==1) 
		serial_lu(generate_matrix(dim),dim);
#if doPAPI==1
	papi_start();
	parallel_lu(argc, argv, generate_matrix(dim), dim, block_dim, rank2print, doSerial, numThreads);
	papi_report();
#else
  time = MPI_Wtime();
  parallel_lu(argc, argv, generate_matrix(dim), dim, block_dim, rank2print, doSerial, numThreads);
  time = MPI_Wtime() - time;
  MPI_Reduce(&time, &avg, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
  if(rank == 0) {
    printf("Dim = %i, Procs = %i, Threads = %i, Average time: %e\n", dim, procs, numThreads, avg/procs);
  }
#endif
  MPI_Finalize();
	return 0;
}
int main(int argc, char * argv[])
{
	if (argc > 1){
		parse_args(argc, argv);
	}

	const int size = n * n;

	float *mat = malloc(size * sizeof(float));
	float *vec = malloc(n * sizeof(float));
	float *output = malloc(n * sizeof(float));
	float *expected = malloc(n * sizeof(float));
	float *mat_transposed = malloc(n * n * sizeof(float));

	generate_matrix(n, mat, range);
	generate_vector(n, vec, range);

	timing_t timer1;
	timer_start(&timer1);

	transpose(n, mat, mat_transposed);
	MatVecMultiply(size, n, mat_transposed, vec, output);

	timer_stop(&timer1);
	float sum = sum_vec(n, output);


	printf("%d %f %ld %ld\n", n, sum, timer1.realtime, timer1.cputime);


	if (trace == 1) {

		printf("\nInput matrix\n");

		for (int i=0; i<n; i++){
			for (int j=0; j<n; j++){
				printf("%f " , mat[i*n+j]);
			}
			printf("\n");
		}
		printf("\nInput vector \n");

		for (int i=0; i<n; i++){
			printf("%f " , vec[i]);
		}

		printf("\n\nResult\n");
		for (int i=0; i<n; i++){
			printf("%f " , output[i]);
		}
		printf("\n");
	}
	else if (trace == 2) {
		multiply_CPU(n, mat, vec, expected);
		int status = check(n, output, expected);
		if (status)
			printf("Test failed.\n");
		else
			printf("Test passed OK!\n");
		return status;
	}


	free(mat);
	free(vec);
	free(output);
	free(expected);
	free(mat_transposed);

	return 0;
}
int
main (int argc, char **argv)
{
  int mpi_rank, mpi_size;

  int n, ln;
  double *A, *b, *xA, *xB, *xC, *r, *X, *x;
  double lmax, max;
  struct timeval before, after;

  MPI_Init (&argc, &argv);
  MPI_Comm_size (MPI_COMM_WORLD, &mpi_size);
  MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank);
  
  /* Get the argument that indicates the problem size */
  n = JACOBI_DEF_SIZE;
  if (argc == 2)
    n = atoi (argv[1]);
  if (mpi_rank == ROOT_NODE)
    fprintf (stdout, "n = %d\n", n);
  ln = n / mpi_size;
  
  /* Initialize the random seed */
  /*srandom((unsigned int) getpid ());*/

  /* Allocate memory */
  A = (double *) calloc (ln * n, sizeof(double));
  if (A == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }

  b = (double *) calloc (ln, sizeof(double));
  if (b == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }
  
  xA = (double *) calloc (ln, sizeof(double));
  if (xA == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }

  xB = (double *) calloc (ln, sizeof(double));
  if (xB == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }

  xC = (double *) calloc (ln, sizeof(double));
  if (xC == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }

  X = (double *) calloc (n, sizeof(double));
  if (X == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }

  r = (double *) calloc (ln, sizeof(double));
  if (r == NULL)
    {
      perror ("calloc");
      MPI_Finalize ();
      return EXIT_FAILURE;
    }

  generate_matrix (A, ln, n, mpi_rank);
  generate_vector (b, ln);
  
  gettimeofday(&before, NULL);
  x = jacobi (xA, xB, xC, A, b, ln, n, mpi_rank, mpi_size);
  gettimeofday(&after, NULL);

  MPI_Allgather (x, ln, MPI_DOUBLE,
		 X, ln, MPI_DOUBLE, MPI_COMM_WORLD);

  /* Compute the residual */
  compute_residual (r, A, X, b, ln, n);

  /* Compute the maximum absolute value of the residual */
  lmax = find_max_abs (r, ln);
  MPI_Reduce (&lmax, &max, 1, MPI_DOUBLE, MPI_MAX, ROOT_NODE, MPI_COMM_WORLD);
  
  if (mpi_rank == ROOT_NODE)
    display_info (A, x, b, r, n, max, &before, &after);

  /* Free the memory */
  free (A);
  free (b);
  free (xA);
  free (xB);
  free (xC);
  free (X);
  free (r);

  /* Return success */
  MPI_Finalize ();
  return 0;
}
void rm_test_0(ull r, ull m, int k, int max_iter, FILE *fout) {
	ull wordsize = 0, dim = 0, gen_size = 0;
	unsigned char *G = NULL, *D = NULL, *DD = NULL, *C = NULL, *NC = NULL;
	unsigned short *masks = NULL, width = 0;
	ull accumulator = 0, n = 0;

	ull data_block_size_bytes = 0;
	ull code_block_size_bytes = 0;

	dim = rm_dim(r, m);
	wordsize = rm_wordsize(r, m);
	width = rm_codeword_size_in_bytes(r, m);

	gen_size = gen_matrix_mem_size(m, m);
	G = (unsigned char *) malloc(gen_size);
	generate_matrix(m, m, G);
	
	//print(dim, 8 * width, G);printf("\n");

	masks = (unsigned short *) malloc(wordsize * sizeof(unsigned short));
	generate_masks(m, masks);

	data_block_size_bytes = rm_dataword_size_in_bytes(r, m);
	code_block_size_bytes = rm_codeword_size_in_bytes(r, m);

	D =	(unsigned char *) malloc(data_block_size_bytes);
	DD = (unsigned char *) malloc(data_block_size_bytes);

	for (int i = 0; i < data_block_size_bytes; ++i)
		D[i] = (unsigned char) rand();

	C = (unsigned char *) malloc(code_block_size_bytes);
	NC = (unsigned char *) malloc(code_block_size_bytes);

	encode_block(r, m, dim, wordsize, C, D, masks, G);
	//printf("Data:\n");print(1, dim, D);printf("\n");
	
	memcpy(NC, C, width);
	// print(1, wordsize, C);printf("\n");
	// decode_block(r, m, dim, wordsize, NC, DD, masks, G, width);
	// print(1, dim, DD);
	srand (time(NULL));
	
	n = 2 * k / 3 + 1;
	fprintf(fout, "%lld\n", n);
	for (ull i = 0; i < n; i++) {
		accumulator = 0;
		fprintf(fout, "%1.9lf ", (double) i / (double) k);

		for (ull j = 0; j < max_iter; ++j) {
			memcpy(NC, C, code_block_size_bytes);
	
			add_noise(NC, code_block_size_bytes, (double) i / (double) k);				
			decode_block(r, m, dim, wordsize, NC, DD, masks, G, width);
			accumulator += match(data_block_size_bytes, 0, dim, D, DD);
		}

		fprintf(fout, "%1.9lf\n", (double) accumulator / (double) max_iter);
	}
	FREE_IF_ALLOCATED(C);
	FREE_IF_ALLOCATED(NC);
	FREE_IF_ALLOCATED(D);
	FREE_IF_ALLOCATED(DD);
	FREE_IF_ALLOCATED(masks);
	FREE_IF_ALLOCATED(G);
}