HYPRE_Int hypre_ParaSailsBuildIJMatrix(hypre_ParaSails obj, HYPRE_IJMatrix *pij_A) { hypre_ParaSails_struct *internal = (hypre_ParaSails_struct *) obj; ParaSails *ps = internal->ps; Matrix *mat = internal->ps->M; HYPRE_Int *diag_sizes, *offdiag_sizes, local_row, i, j; HYPRE_Int size; HYPRE_Int *col_inds; HYPRE_Real *values; HYPRE_IJMatrixCreate( ps->comm, ps->beg_row, ps->end_row, ps->beg_row, ps->end_row, pij_A ); HYPRE_IJMatrixSetObjectType( *pij_A, HYPRE_PARCSR ); diag_sizes = hypre_CTAlloc(HYPRE_Int, ps->end_row - ps->beg_row + 1); offdiag_sizes = hypre_CTAlloc(HYPRE_Int, ps->end_row - ps->beg_row + 1); local_row = 0; for (i=ps->beg_row; i<= ps->end_row; i++) { MatrixGetRow(mat, local_row, &size, &col_inds, &values); NumberingLocalToGlobal(ps->numb, size, col_inds, col_inds); for (j=0; j < size; j++) { if (col_inds[j] < ps->beg_row || col_inds[j] > ps->end_row) offdiag_sizes[local_row]++; else diag_sizes[local_row]++; } local_row++; } HYPRE_IJMatrixSetDiagOffdSizes( *pij_A, (const HYPRE_Int *) diag_sizes, (const HYPRE_Int *) offdiag_sizes ); hypre_TFree(diag_sizes); hypre_TFree(offdiag_sizes); HYPRE_IJMatrixInitialize( *pij_A ); local_row = 0; for (i=ps->beg_row; i<= ps->end_row; i++) { MatrixGetRow(mat, local_row, &size, &col_inds, &values); HYPRE_IJMatrixSetValues( *pij_A, 1, &size, &i, (const HYPRE_Int *) col_inds, (const HYPRE_Real *) values ); NumberingGlobalToLocal(ps->numb, size, col_inds, col_inds); local_row++; } HYPRE_IJMatrixAssemble( *pij_A ); return hypre_error_flag; }
void LoadBalDonorSend(MPI_Comm comm, Matrix *mat, Numbering *numb, int num_given, const int *donor_data_pe, const double *donor_data_cost, DonorData *donor_data, int *local_beg_row, MPI_Request *request) { int send_beg_row, send_end_row; int i, row; double accum; int buflen; int *bufferp; int len, *ind; double *val; send_end_row = mat->beg_row - 1; /* imaginary end of previous block */ for (i=0; i<num_given; i++) { send_beg_row = send_end_row + 1; send_end_row = send_beg_row - 1; /* Portion out rows that add up to the workload to be sent out */ /* and determine the size of the buffer needed */ accum = 0.0; /* amount of work portioned out so far */ buflen = 2; /* front of buffer will contain beg_row, end_row */ do { send_end_row++; assert(send_end_row <= mat->end_row); MatrixGetRow(mat, send_end_row - mat->beg_row, &len, &ind, &val); accum += (double) len*len*len; buflen += (len+1); /* additional one for row length */ } while (accum < donor_data_cost[i]); /* Create entry in donor_data structure */ donor_data[i].pe = donor_data_pe[i]; donor_data[i].beg_row = send_beg_row; donor_data[i].end_row = send_end_row; donor_data[i].buffer = (int *) malloc((buflen) * sizeof(int)); /* Construct send buffer */ bufferp = donor_data[i].buffer; *bufferp++ = send_beg_row; *bufferp++ = send_end_row; for (row=send_beg_row; row<=send_end_row; row++) { MatrixGetRow(mat, row - mat->beg_row, &len, &ind, &val); *bufferp++ = len; /* memcpy(bufferp, ind, len*sizeof(int)); */ /* copy into buffer */ NumberingLocalToGlobal(numb, len, ind, bufferp); bufferp += len; } MPI_Isend(donor_data[i].buffer, buflen, MPI_INT, donor_data[i].pe, LOADBAL_REQ_TAG, comm, &request[i]); } *local_beg_row = send_end_row + 1; }