void calc_block(
    hpxla::local_matrix_view<boost::int64_t>& H 
  , hpxla::local_matrix_view<hpx::future<void> >& C // Control matrix.
  , coords start   // The start of our cell block. 
  , coords end     // The end of our cell block.
  , coords control // Our location in the control matrix.
  , std::string const& a
  , std::string const& b
    )
{
    // TODO: Handle this with hpx::wait_all?
    C(control.i,   control.j-1).get(); 
    C(control.i-1, control.j-1).get(); 
    C(control.i-1, control.j  ).get(); 

    winner local_best = H_best.load();

    // Generate scores.
    for (boost::uint32_t i = start.i; i < end.i; ++i)
    {
        for (boost::uint32_t j = start.j; j < end.j; ++j)
        {
            H(i, j) = calc_cell(i, j, a[i-1], b[j-1]
              , H(i,   j-1) // left
              , H(i-1, j-1) // diagonal 
              , H(i-1, j  ) // up
            ); 

            if (H(i, j) > local_best.value)
            {
                local_best.value = H(i, j);
                local_best.i = i;
                local_best.j = j;
            } 
        }
    }

    winner H_best_old = H_best.load(); 

    while (true)
    {
        if (local_best.value > H_best_old.value)
        {
            if (H_best.compare_exchange_weak(H_best_old, local_best))
                break;
        }
        else
            break;
    }
}
示例#2
0
文件: classic.c 项目: dburger/archive
/*
 main entry point to program.  Determines number of tasks, the 0 task becomes
 the head, reading the data and broadcasting it to all other tasks which act
 as workers.  The 0 task then computes its portion of the result and then
 receives the results from all workers.  The result is then printed.
 */
int main(int argc, char *argv[]) {
  int i, head, lo, hi, me, tasks;
  int a_rows, a_cols, a_cells, b_rows, b_cols, b_cells;
  int *recv_cnts, *disps;
  int *datapack, *temp;
  FILE *fp;

  MPI_Status status;

  /* init MPI, retrieve number of tasks, retrieve my index in tasks */
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &tasks);
  MPI_Comm_rank(MPI_COMM_WORLD, &me);

  /* first task is head, collecting results */
  head = 0;

  /* check for input file parameter */
  if (argc < 2) {
    if (me == head)
      BAIL_ALL("Please provide an input parameter");
  }

  if (me == head ) {

    /* create arrays for receive counts and displacements for MPI_Gatherv */
    if ((recv_cnts = (int *)malloc(tasks*sizeof(int))) == NULL)
      BAIL_ALL("Unable to allocate receive counts array");
    if ((disps = (int *)malloc(tasks*sizeof(int))) == NULL)
      BAIL_ALL("Unable to allocate displacements arrary");

    /* attempt to open the input file */
    if ((fp = fopen(argv[1], "r")) == NULL)
      BAIL_ALL("Unable to open the input file");

    while (!feof(fp)) {

      /* read the dimensions of matrix A */
      if (!read_dims(fp, &a_rows, &a_cols))
        BAIL_ALL("Unable to read the dimensions of matrix A");

      a_cells = a_rows * a_cols;

      /* allocate the space for the dimensions and matrix A */
      if ((datapack = (int *)malloc((2+a_cells)*sizeof(int))) == NULL)
        BAIL_ALL("Unable to allocate space for matrix A");

      /* put row and column data in the datapack */
      datapack[0] = a_rows;
      datapack[1] = a_cols;

      /* attempt to read in the matrix A values */
      if (read_matrix(fp, datapack+2, a_cells) < a_cells)
        BAIL_ALL("Unable to read the contents of matrix A");

      /* read the dimensions of matrix B */
      if (!read_dims(fp, &b_rows, &b_cols))
        BAIL_ALL("Unable to read the dimensions of matrix B");

      b_cells = b_rows * b_cols;

      /* allocate the extra space for dimensions and matrix B */
      if ((datapack = (int *)realloc(datapack,
                                     (4+a_cells+b_cells)*sizeof(int))) == NULL)
        BAIL_ALL("Unable to allocate space for matrix B");

      /* put row and column data in the datapack */
      datapack[2 + a_cells] = b_rows;
      datapack[3 + a_cells] = b_cols;

      /* attempt to read in the matrix B values */
      if (read_matrix(fp, datapack+4+a_cells, b_cells) < b_cells)
        BAIL_ALL("Unable to read the contents of matrix B");

      /* check for multiplication compatibility */
      if (a_cols != b_rows ||
          a_rows < 1 || a_cols < 1 ||
          b_rows < 1 || b_cols < 1) {
        printf("Matrix A and B are not multiplicative compatible\n");
      } else {
        /* calc the range of cells I am responsible for */
        calc_range(a_rows*b_cols, me, tasks, &lo, &hi);

        /* allocate an array for the portion I will compute */
        if ((temp = (int *)malloc((hi-lo+1)*sizeof(int))) == NULL)
          BAIL_ALL("Unable to allocate space for the temp array");

        /* tell the workers the size of the datapack coming in */
        i = 4 + a_cells + b_cells;
        MPI_Bcast(&i, 1, MPI_INT, me, MPI_COMM_WORLD);

        /* send the datapack to the workers */
        MPI_Bcast(datapack, 4+a_cells+b_cells, MPI_INT, me, MPI_COMM_WORLD);

        /* calculate my portion of the results */
        for (i=lo; i<=hi; i++) {
          temp[i-lo] = calc_cell(datapack+2, datapack+4+a_cells, a_cols,
                                 a_rows, b_cols, i);
        }

        /* calculate the proper displacements and sizes for returned results */
        for (i=0; i<tasks; i++) {
          int worker_hi;
          calc_range(a_rows*b_cols, i, tasks, disps+i, &worker_hi);
          recv_cnts[i] = worker_hi - disps[i] + 1;
        }

        /* print out the matrices */
        printf("MATRIX A\n");
        print_matrix(datapack+2, a_rows, a_cols);
        printf("MATRIX B\n");
        print_matrix(datapack+4+a_cells, b_rows, b_cols);

        /* gatherv the results */
        MPI_Gatherv(temp, hi-lo+1, MPI_INT, datapack, recv_cnts, disps,
                    MPI_INT, me, MPI_COMM_WORLD);

        /* print out the result */
        printf("RESULT\n");
        print_matrix(datapack, a_rows, b_cols);

        free(temp);

      }

      free(datapack);

    }

  } else { /* not the head task */

    for (;;) {

      /* check if more results are coming */
      MPI_Bcast(&i, 1, MPI_INT, head, MPI_COMM_WORLD);
      if (!i) break;

      /* allocate space for the data pack */
      datapack = (int *)malloc(i*sizeof(int));

      /* receive the datapack */
      MPI_Bcast(datapack, i, MPI_INT, head, MPI_COMM_WORLD);

      /* get values from the data pack */
      a_rows = datapack[0];
      a_cols = datapack[1];
      a_cells = a_rows*a_cols;
      b_rows = datapack[2 + a_cells];
      b_cols = datapack[3 + a_cells];
      b_cells = b_rows*b_cols;

      /* calculate the range of cells that I am responsible for */
      calc_range(a_rows*b_cols, me, tasks, &lo, &hi);

      /* allocate an array for the results I will send back */
      temp = (int *)malloc((hi-lo+1)*sizeof(int));

      /* and calculate my set of results */
      for (i=lo; i<=hi; i++) {
        temp[i-lo] = calc_cell(datapack+2, datapack+4+a_cells, a_cols, a_rows,
                               b_cols, i);
      }

      /* return the values to the head task */
      MPI_Gatherv(temp, hi-lo+1, MPI_INT, NULL, NULL, NULL, MPI_INT, head,
                  MPI_COMM_WORLD);

      free(datapack);
      free(temp);

    }

  }

  if (me == head) {
    fclose(fp);
    BAIL_ALL("Job complete!");
  }

  /* shut down */
  MPI_Finalize();
  exit(0);

}