35 void hypre_CSRMatrixEliminateAXB( hypre_CSRMatrix* A,
36 HYPRE_Int nrows_to_eliminate,
37 HYPRE_Int* rows_to_eliminate,
42 HYPRE_Int irow, jcol, ibeg, iend, pos;
45 HYPRE_Int* Ai = hypre_CSRMatrixI( A );
46 HYPRE_Int* Aj = hypre_CSRMatrixJ( A );
47 HYPRE_Real* Adata = hypre_CSRMatrixData( A );
48 HYPRE_Int nrows = hypre_CSRMatrixNumRows( A );
50 HYPRE_Real* Xdata = hypre_VectorData( X );
51 HYPRE_Real* Bdata = hypre_VectorData( B );
54 for( i = 0; i < nrows; i++ )
58 for( j = ibeg; j < iend; j++ )
61 pos = hypre_BinarySearch( rows_to_eliminate, jcol, nrows_to_eliminate );
66 Bdata[i] -= a * Xdata[jcol];
72 for( i = 0; i < nrows_to_eliminate; i++ )
74 irow = rows_to_eliminate[i];
77 for( j = ibeg; j < iend; j++ )
96 void hypre_CSRMatrixEliminateOffdColsAXB( hypre_CSRMatrix* A,
97 HYPRE_Int ncols_to_eliminate,
98 HYPRE_Int* eliminate_cols,
99 HYPRE_Real* eliminate_coefs,
103 HYPRE_Int ibeg, iend, pos;
106 HYPRE_Int* Ai = hypre_CSRMatrixI( A );
107 HYPRE_Int* Aj = hypre_CSRMatrixJ( A );
108 HYPRE_Real* Adata = hypre_CSRMatrixData( A );
109 HYPRE_Int nrows = hypre_CSRMatrixNumRows( A );
111 HYPRE_Real* Bdata = hypre_VectorData( B );
113 for( i = 0; i < nrows; i++ )
117 for( j = ibeg; j < iend; j++ )
119 pos = hypre_BinarySearch( eliminate_cols, Aj[j], ncols_to_eliminate );
124 Bdata[i] -= a * eliminate_coefs[pos];
135 void hypre_CSRMatrixEliminateOffdRowsAXB( hypre_CSRMatrix* A,
136 HYPRE_Int nrows_to_eliminate,
137 HYPRE_Int* rows_to_eliminate )
139 HYPRE_Int* Ai = hypre_CSRMatrixI( A );
140 HYPRE_Real* Adata = hypre_CSRMatrixData( A );
143 HYPRE_Int irow, ibeg, iend;
145 for( i = 0; i < nrows_to_eliminate; i++ )
147 irow = rows_to_eliminate[i];
150 for( j = ibeg; j < iend; j++ )
181 void hypre_ParCSRMatrixEliminateAXB( hypre_ParCSRMatrix* A,
182 HYPRE_Int num_rowscols_to_elim,
183 HYPRE_Int* rowscols_to_elim,
187 hypre_CSRMatrix* diag = hypre_ParCSRMatrixDiag( A );
188 hypre_CSRMatrix* offd = hypre_ParCSRMatrixOffd( A );
189 HYPRE_Int diag_nrows = hypre_CSRMatrixNumRows( diag );
190 HYPRE_Int offd_ncols = hypre_CSRMatrixNumCols( offd );
192 hypre_Vector* Xlocal = hypre_ParVectorLocalVector( X );
193 hypre_Vector* Blocal = hypre_ParVectorLocalVector( B );
195 HYPRE_Real* Bdata = hypre_VectorData( Blocal );
196 HYPRE_Real* Xdata = hypre_VectorData( Xlocal );
198 HYPRE_Int num_offd_cols_to_elim;
199 HYPRE_Int* offd_cols_to_elim;
200 HYPRE_Real* eliminate_coefs;
203 hypre_ParCSRCommHandle* comm_handle;
204 hypre_ParCSRCommPkg* comm_pkg;
206 HYPRE_Int index, start;
207 HYPRE_Int i, j, k, irow;
209 HYPRE_Real* eliminate_row = hypre_CTAlloc( HYPRE_Real, diag_nrows );
210 HYPRE_Real* eliminate_col = hypre_CTAlloc( HYPRE_Real, offd_ncols );
211 HYPRE_Real *buf_data, coef;
214 comm_pkg = hypre_ParCSRMatrixCommPkg( A );
217 hypre_MatvecCommPkgCreate( A );
218 comm_pkg = hypre_ParCSRMatrixCommPkg( A );
224 for( i = 0; i < diag_nrows; i++ )
226 eliminate_row[i] = std::numeric_limits< HYPRE_Real >::quiet_NaN();
228 for( i = 0; i < num_rowscols_to_elim; i++ )
230 irow = rowscols_to_elim[i];
231 eliminate_row[irow] = Xdata[irow];
236 num_sends = hypre_ParCSRCommPkgNumSends( comm_pkg );
237 buf_data = hypre_CTAlloc( HYPRE_Real, hypre_ParCSRCommPkgSendMapStart( comm_pkg, num_sends ) );
239 for( i = 0; i < num_sends; i++ )
241 start = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i );
242 for( j = start; j < hypre_ParCSRCommPkgSendMapStart( comm_pkg, i + 1 ); j++ )
244 k = hypre_ParCSRCommPkgSendMapElmt( comm_pkg, j );
245 buf_data[index++] = eliminate_row[k];
248 comm_handle = hypre_ParCSRCommHandleCreate( 1, comm_pkg, buf_data, eliminate_col );
251 hypre_CSRMatrixEliminateAXB( diag, num_rowscols_to_elim, rowscols_to_elim, Xlocal, Blocal );
254 hypre_ParCSRCommHandleDestroy( comm_handle );
257 num_offd_cols_to_elim = 0;
258 for( i = 0; i < offd_ncols; i++ )
260 coef = eliminate_col[i];
263 num_offd_cols_to_elim++;
267 offd_cols_to_elim = hypre_CTAlloc( HYPRE_Int, num_offd_cols_to_elim );
268 eliminate_coefs = hypre_CTAlloc( HYPRE_Real, num_offd_cols_to_elim );
271 num_offd_cols_to_elim = 0;
272 for( i = 0; i < offd_ncols; i++ )
274 coef = eliminate_col[i];
277 offd_cols_to_elim[num_offd_cols_to_elim] = i;
278 eliminate_coefs[num_offd_cols_to_elim] = coef;
279 num_offd_cols_to_elim++;
283 hypre_TFree( buf_data );
284 hypre_TFree( eliminate_row );
285 hypre_TFree( eliminate_col );
288 hypre_CSRMatrixEliminateOffdColsAXB( offd, num_offd_cols_to_elim, offd_cols_to_elim, eliminate_coefs, Blocal );
290 hypre_CSRMatrixEliminateOffdRowsAXB( offd, num_rowscols_to_elim, rowscols_to_elim );
293 for(
int m = 0; m < num_rowscols_to_elim; m++ )
295 irow = rowscols_to_elim[m];
296 Bdata[irow] = Xdata[irow];
299 hypre_TFree( offd_cols_to_elim );
300 hypre_TFree( eliminate_coefs );
312 void hypre_CSRMatrixElimCreate( hypre_CSRMatrix* A,
318 HYPRE_Int* col_mark )
321 HYPRE_Int A_beg, A_end;
323 HYPRE_Int* A_i = hypre_CSRMatrixI( A );
324 HYPRE_Int* A_j = hypre_CSRMatrixJ( A );
325 HYPRE_Int A_rows = hypre_CSRMatrixNumRows( A );
327 hypre_CSRMatrixI( Ae ) = hypre_TAlloc( HYPRE_Int, A_rows + 1 );
329 HYPRE_Int* Ae_i = hypre_CSRMatrixI( Ae );
332 for( i = 0; i < A_rows; i++ )
339 if( hypre_BinarySearch( rows, i, nrows ) >= 0 )
342 nnz += A_end - A_beg;
346 for( j = A_beg; j < A_end; j++ )
348 col_mark[A_j[j]] = 1;
355 for( j = A_beg; j < A_end; j++ )
358 if( hypre_BinarySearch( cols, col, ncols ) >= 0 )
371 hypre_CSRMatrixJ( Ae ) = hypre_TAlloc( HYPRE_Int, nnz );
372 hypre_CSRMatrixData( Ae ) = hypre_TAlloc( HYPRE_Real, nnz );
373 hypre_CSRMatrixNumNonzeros( Ae ) = nnz;
383 void hypre_CSRMatrixEliminateRowsCols( hypre_CSRMatrix* A,
390 HYPRE_Int* col_remap )
392 HYPRE_Int i, j, k, col;
393 HYPRE_Int A_beg, Ae_beg, A_end;
396 HYPRE_Int* A_i = hypre_CSRMatrixI( A );
397 HYPRE_Int* A_j = hypre_CSRMatrixJ( A );
398 HYPRE_Real* A_data = hypre_CSRMatrixData( A );
399 HYPRE_Int A_rows = hypre_CSRMatrixNumRows( A );
401 HYPRE_Int* Ae_i = hypre_CSRMatrixI( Ae );
402 HYPRE_Int* Ae_j = hypre_CSRMatrixJ( Ae );
403 HYPRE_Real* Ae_data = hypre_CSRMatrixData( Ae );
405 for( i = 0; i < A_rows; i++ )
411 if( hypre_BinarySearch( rows, i, nrows ) >= 0 )
414 for( j = A_beg, k = Ae_beg; j < A_end; j++, k++ )
417 Ae_j[k] = col_remap ? col_remap[col] : col;
418 a = ( diag && col == i ) ? 1.0 : 0.0;
419 Ae_data[k] = A_data[j] - a;
426 for( j = A_beg, k = Ae_beg; j < A_end; j++ )
429 if( hypre_BinarySearch( cols, col, ncols ) >= 0 )
431 Ae_j[k] = col_remap ? col_remap[col] : col;
432 Ae_data[k] = A_data[j];
455 void hypre_ParCSRMatrixEliminateAAe( hypre_ParCSRMatrix* A,
456 hypre_ParCSRMatrix** Ae,
457 HYPRE_Int num_rowscols_to_elim,
458 HYPRE_Int* rowscols_to_elim )
462 hypre_CSRMatrix* A_diag = hypre_ParCSRMatrixDiag( A );
463 hypre_CSRMatrix* A_offd = hypre_ParCSRMatrixOffd( A );
464 HYPRE_Int A_diag_nrows = hypre_CSRMatrixNumRows( A_diag );
465 HYPRE_Int A_offd_ncols = hypre_CSRMatrixNumCols( A_offd );
467 *Ae = hypre_ParCSRMatrixCreate( hypre_ParCSRMatrixComm( A ), hypre_ParCSRMatrixGlobalNumRows( A ),
468 hypre_ParCSRMatrixGlobalNumCols( A ), hypre_ParCSRMatrixRowStarts( A ),
469 hypre_ParCSRMatrixColStarts( A ), 0, 0, 0 );
471 hypre_ParCSRMatrixSetRowStartsOwner( *Ae, 0 );
472 hypre_ParCSRMatrixSetColStartsOwner( *Ae, 0 );
474 hypre_CSRMatrix* Ae_diag = hypre_ParCSRMatrixDiag( *Ae );
475 hypre_CSRMatrix* Ae_offd = hypre_ParCSRMatrixOffd( *Ae );
476 HYPRE_Int Ae_offd_ncols;
478 HYPRE_Int num_offd_cols_to_elim;
479 HYPRE_Int* offd_cols_to_elim;
481 HYPRE_Int* A_col_map_offd = hypre_ParCSRMatrixColMapOffd( A );
482 HYPRE_Int* Ae_col_map_offd;
485 HYPRE_Int* col_remap;
489 hypre_ParCSRCommHandle* comm_handle;
490 hypre_ParCSRCommPkg* comm_pkg;
491 HYPRE_Int num_sends, *int_buf_data;
492 HYPRE_Int index, start;
494 HYPRE_Int* eliminate_row = hypre_CTAlloc( HYPRE_Int, A_diag_nrows );
495 HYPRE_Int* eliminate_col = hypre_CTAlloc( HYPRE_Int, A_offd_ncols );
498 comm_pkg = hypre_ParCSRMatrixCommPkg( A );
501 hypre_MatvecCommPkgCreate( A );
502 comm_pkg = hypre_ParCSRMatrixCommPkg( A );
506 for( i = 0; i < A_diag_nrows; i++ )
508 eliminate_row[i] = 0;
510 for( i = 0; i < num_rowscols_to_elim; i++ )
512 eliminate_row[rowscols_to_elim[i]] = 1;
517 num_sends = hypre_ParCSRCommPkgNumSends( comm_pkg );
518 int_buf_data = hypre_CTAlloc( HYPRE_Int, hypre_ParCSRCommPkgSendMapStart( comm_pkg, num_sends ) );
520 for( i = 0; i < num_sends; i++ )
522 start = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i );
523 for( j = start; j < hypre_ParCSRCommPkgSendMapStart( comm_pkg, i + 1 ); j++ )
525 k = hypre_ParCSRCommPkgSendMapElmt( comm_pkg, j );
526 int_buf_data[index++] = eliminate_row[k];
529 comm_handle = hypre_ParCSRCommHandleCreate( 11, comm_pkg, int_buf_data, eliminate_col );
532 hypre_CSRMatrixElimCreate( A_diag, Ae_diag, num_rowscols_to_elim, rowscols_to_elim, num_rowscols_to_elim,
533 rowscols_to_elim, NULL );
535 hypre_CSRMatrixEliminateRowsCols( A_diag, Ae_diag, num_rowscols_to_elim, rowscols_to_elim,
536 num_rowscols_to_elim, rowscols_to_elim, 1, NULL );
537 hypre_CSRMatrixReorder( Ae_diag );
540 hypre_ParCSRCommHandleDestroy( comm_handle );
543 num_offd_cols_to_elim = 0;
544 for( i = 0; i < A_offd_ncols; i++ )
546 if( eliminate_col[i] )
548 num_offd_cols_to_elim++;
552 offd_cols_to_elim = hypre_CTAlloc( HYPRE_Int, num_offd_cols_to_elim );
555 num_offd_cols_to_elim = 0;
556 for( i = 0; i < A_offd_ncols; i++ )
558 if( eliminate_col[i] )
560 offd_cols_to_elim[num_offd_cols_to_elim++] = i;
564 hypre_TFree( int_buf_data );
565 hypre_TFree( eliminate_row );
566 hypre_TFree( eliminate_col );
570 col_mark = hypre_CTAlloc( HYPRE_Int, A_offd_ncols );
571 col_remap = hypre_CTAlloc( HYPRE_Int, A_offd_ncols );
573 hypre_CSRMatrixElimCreate( A_offd, Ae_offd, num_rowscols_to_elim, rowscols_to_elim, num_offd_cols_to_elim,
574 offd_cols_to_elim, col_mark );
576 for( i = k = 0; i < A_offd_ncols; i++ )
584 hypre_CSRMatrixEliminateRowsCols( A_offd, Ae_offd, num_rowscols_to_elim, rowscols_to_elim,
585 num_offd_cols_to_elim, offd_cols_to_elim, 0, col_remap );
589 for( i = 0; i < A_offd_ncols; i++ )
597 Ae_col_map_offd = hypre_CTAlloc( HYPRE_Int, Ae_offd_ncols );
600 for( i = 0; i < A_offd_ncols; i++ )
604 Ae_col_map_offd[Ae_offd_ncols++] = A_col_map_offd[i];
608 hypre_ParCSRMatrixColMapOffd( *Ae ) = Ae_col_map_offd;
609 hypre_CSRMatrixNumCols( Ae_offd ) = Ae_offd_ncols;
611 hypre_TFree( col_remap );
612 hypre_TFree( col_mark );
613 hypre_TFree( offd_cols_to_elim );
615 hypre_ParCSRMatrixSetNumNonzeros( *Ae );
616 hypre_MatvecCommPkgCreate( *Ae );
623 void hypre_CSRMatrixSplit( hypre_CSRMatrix* A,
626 HYPRE_Int* row_block_num,
627 HYPRE_Int* col_block_num,
628 hypre_CSRMatrix** blocks )
630 HYPRE_Int i, j, k, bi, bj;
632 HYPRE_Int* A_i = hypre_CSRMatrixI( A );
633 HYPRE_Int* A_j = hypre_CSRMatrixJ( A );
634 HYPRE_Complex* A_data = hypre_CSRMatrixData( A );
636 HYPRE_Int A_rows = hypre_CSRMatrixNumRows( A );
637 HYPRE_Int A_cols = hypre_CSRMatrixNumCols( A );
639 HYPRE_Int* num_rows = hypre_CTAlloc( HYPRE_Int,
nr );
640 HYPRE_Int* num_cols = hypre_CTAlloc( HYPRE_Int, nc );
642 HYPRE_Int* block_row = hypre_TAlloc( HYPRE_Int, A_rows );
643 HYPRE_Int* block_col = hypre_TAlloc( HYPRE_Int, A_cols );
645 for( i = 0; i < A_rows; i++ )
647 block_row[i] = num_rows[row_block_num[i]]++;
649 for( j = 0; j < A_cols; j++ )
651 block_col[j] = num_cols[col_block_num[j]]++;
655 for( i = 0; i <
nr; i++ )
657 for( j = 0; j < nc; j++ )
659 hypre_CSRMatrix* B = hypre_CSRMatrixCreate( num_rows[i], num_cols[j], 0 );
660 hypre_CSRMatrixI( B ) = hypre_CTAlloc( HYPRE_Int, num_rows[i] + 1 );
661 blocks[i * nc + j] = B;
666 for( i = 0; i < A_rows; i++ )
668 bi = row_block_num[i];
669 for( j = A_i[i]; j < A_i[i + 1]; j++ )
671 bj = col_block_num[A_j[j]];
672 hypre_CSRMatrix* B = blocks[bi * nc + bj];
673 hypre_CSRMatrixI( B )[block_row[i] + 1]++;
678 for( k = 0; k <
nr * nc; k++ )
680 hypre_CSRMatrix* B = blocks[k];
681 HYPRE_Int* B_i = hypre_CSRMatrixI( B );
683 HYPRE_Int nnz = 0, rs;
684 for(
int m = 1; m <= hypre_CSRMatrixNumRows( B ); m++ )
686 rs = B_i[m], B_i[m] = nnz, nnz += rs;
689 hypre_CSRMatrixJ( B ) = hypre_TAlloc( HYPRE_Int, nnz );
690 hypre_CSRMatrixData( B ) = hypre_TAlloc( HYPRE_Complex, nnz );
691 hypre_CSRMatrixNumNonzeros( B ) = nnz;
695 for( i = 0; i < A_rows; i++ )
697 bi = row_block_num[i];
698 for( j = A_i[i]; j < A_i[i + 1]; j++ )
701 bj = col_block_num[k];
702 hypre_CSRMatrix* B = blocks[bi * nc + bj];
703 HYPRE_Int* bii = hypre_CSRMatrixI( B ) + block_row[i] + 1;
704 hypre_CSRMatrixJ( B )[*bii] = block_col[k];
705 hypre_CSRMatrixData( B )[*bii] = A_data[j];
710 hypre_TFree( block_col );
711 hypre_TFree( block_row );
713 hypre_TFree( num_cols );
714 hypre_TFree( num_rows );
717 void hypre_ParCSRMatrixSplit( hypre_ParCSRMatrix* A,
720 hypre_ParCSRMatrix** blocks,
721 int interleaved_rows,
722 int interleaved_cols )
726 MPI_Comm comm = hypre_ParCSRMatrixComm( A );
728 hypre_CSRMatrix* Adiag = hypre_ParCSRMatrixDiag( A );
729 hypre_CSRMatrix* Aoffd = hypre_ParCSRMatrixOffd( A );
731 HYPRE_Int global_rows = hypre_ParCSRMatrixGlobalNumRows( A );
732 HYPRE_Int global_cols = hypre_ParCSRMatrixGlobalNumCols( A );
734 HYPRE_Int local_rows = hypre_CSRMatrixNumRows( Adiag );
735 HYPRE_Int local_cols = hypre_CSRMatrixNumCols( Adiag );
736 HYPRE_Int offd_cols = hypre_CSRMatrixNumCols( Aoffd );
738 hypre_assert( local_rows %
nr == 0 && local_cols % nc == 0 );
739 hypre_assert( global_rows %
nr == 0 && global_cols % nc == 0 );
741 HYPRE_Int block_rows = local_rows /
nr;
742 HYPRE_Int block_cols = local_cols / nc;
743 HYPRE_Int num_blocks =
nr * nc;
746 HYPRE_Int* row_block_num = hypre_TAlloc( HYPRE_Int, local_rows );
747 HYPRE_Int* col_block_num = hypre_TAlloc( HYPRE_Int, local_cols );
749 for( i = 0; i < local_rows; i++ )
751 row_block_num[i] = interleaved_rows ? ( i %
nr ) : ( i / block_rows );
753 for( i = 0; i < local_cols; i++ )
755 col_block_num[i] = interleaved_cols ? ( i % nc ) : ( i / block_cols );
759 HYPRE_Int* offd_col_block_num = hypre_TAlloc( HYPRE_Int, offd_cols );
760 hypre_ParCSRCommHandle* comm_handle;
761 HYPRE_Int* int_buf_data;
764 hypre_ParCSRCommPkg* comm_pkg = hypre_ParCSRMatrixCommPkg( A );
767 hypre_MatvecCommPkgCreate( A );
768 comm_pkg = hypre_ParCSRMatrixCommPkg( A );
772 HYPRE_Int* count = hypre_CTAlloc( HYPRE_Int, nc );
773 HYPRE_Int* block_global_col = hypre_TAlloc( HYPRE_Int, local_cols );
774 HYPRE_Int first_col = hypre_ParCSRMatrixFirstColDiag( A ) / nc;
775 for( i = 0; i < local_cols; i++ )
777 block_global_col[i] = first_col + count[col_block_num[i]]++;
779 hypre_TFree( count );
782 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends( comm_pkg );
783 int_buf_data = hypre_CTAlloc( HYPRE_Int, hypre_ParCSRCommPkgSendMapStart( comm_pkg, num_sends ) );
784 HYPRE_Int start, index = 0;
785 for( i = 0; i < num_sends; i++ )
787 start = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i );
788 for( j = start; j < hypre_ParCSRCommPkgSendMapStart( comm_pkg, i + 1 ); j++ )
790 k = hypre_ParCSRCommPkgSendMapElmt( comm_pkg, j );
791 int_buf_data[index++] = col_block_num[k] + nc * block_global_col[k];
794 hypre_TFree( block_global_col );
796 comm_handle = hypre_ParCSRCommHandleCreate( 11, comm_pkg, int_buf_data, offd_col_block_num );
800 HYPRE_Int num_procs = 1;
801 if( !hypre_ParCSRMatrixAssumedPartition( A ) )
803 hypre_MPI_Comm_size( comm, &num_procs );
806 HYPRE_Int* row_starts = hypre_TAlloc( HYPRE_Int, num_procs + 1 );
807 HYPRE_Int* col_starts = hypre_TAlloc( HYPRE_Int, num_procs + 1 );
808 for( i = 0; i <= num_procs; i++ )
810 row_starts[i] = hypre_ParCSRMatrixRowStarts( A )[i] /
nr;
811 col_starts[i] = hypre_ParCSRMatrixColStarts( A )[i] / nc;
814 for( i = 0; i < num_blocks; i++ )
817 hypre_ParCSRMatrixCreate( comm, global_rows /
nr, global_cols / nc, row_starts, col_starts, 0, 0, 0 );
821 hypre_CSRMatrix** csr_blocks = hypre_TAlloc( hypre_CSRMatrix*,
nr * nc );
822 hypre_CSRMatrixSplit( Adiag,
nr, nc, row_block_num, col_block_num, csr_blocks );
824 for( i = 0; i < num_blocks; i++ )
826 hypre_TFree( hypre_ParCSRMatrixDiag( blocks[i] ) );
827 hypre_ParCSRMatrixDiag( blocks[i] ) = csr_blocks[i];
831 hypre_ParCSRCommHandleDestroy( comm_handle );
832 hypre_TFree( int_buf_data );
835 HYPRE_Int* offd_global_col = hypre_TAlloc( HYPRE_Int, offd_cols );
836 for( i = 0; i < offd_cols; i++ )
838 offd_global_col[i] = offd_col_block_num[i] / nc;
839 offd_col_block_num[i] %= nc;
843 hypre_CSRMatrixSplit( Aoffd,
nr, nc, row_block_num, offd_col_block_num, csr_blocks );
845 for( i = 0; i < num_blocks; i++ )
847 hypre_TFree( hypre_ParCSRMatrixOffd( blocks[i] ) );
848 hypre_ParCSRMatrixOffd( blocks[i] ) = csr_blocks[i];
851 hypre_TFree( csr_blocks );
852 hypre_TFree( col_block_num );
853 hypre_TFree( row_block_num );
856 for(
int bi = 0; bi <
nr; bi++ )
858 for(
int bj = 0; bj < nc; bj++ )
860 hypre_ParCSRMatrix* block = blocks[bi * nc + bj];
861 hypre_CSRMatrix* block_offd = hypre_ParCSRMatrixOffd( block );
862 HYPRE_Int block_offd_cols = hypre_CSRMatrixNumCols( block_offd );
864 HYPRE_Int* block_col_map = hypre_TAlloc( HYPRE_Int, block_offd_cols );
865 for( i = j = 0; i < offd_cols; i++ )
867 HYPRE_Int bn = offd_col_block_num[i];
870 block_col_map[j++] = offd_global_col[i];
873 hypre_assert( j == block_offd_cols );
875 hypre_ParCSRMatrixColMapOffd( block ) = block_col_map;
879 hypre_TFree( offd_global_col );
880 hypre_TFree( offd_col_block_num );
883 for( i = 0; i < num_blocks; i++ )
885 hypre_ParCSRMatrixSetNumNonzeros( blocks[i] );
886 hypre_MatvecCommPkgCreate( blocks[i] );
888 hypre_ParCSRMatrixOwnsData( blocks[i] ) = 1;
891 hypre_ParCSRMatrixOwnsRowStarts( blocks[i] ) = !i;
892 hypre_ParCSRMatrixOwnsColStarts( blocks[i] ) = !i;
897 void hypre_CSRMatrixBooleanMatvec( hypre_CSRMatrix* A,
904 HYPRE_Int* A_i = hypre_CSRMatrixI( A );
905 HYPRE_Int* A_j = hypre_CSRMatrixJ( A );
906 HYPRE_Int num_rows = hypre_CSRMatrixNumRows( A );
908 HYPRE_Int* A_rownnz = hypre_CSRMatrixRownnz( A );
909 HYPRE_Int num_rownnz = hypre_CSRMatrixNumRownnz( A );
911 HYPRE_Bool* x_data = x;
912 HYPRE_Bool* y_data = y;
914 HYPRE_Bool temp, tempx;
920 HYPRE_Real xpar = 0.7;
928 #ifdef HYPRE_USING_OPENMP
929 #pragma omp parallel for private( i ) HYPRE_SMP_SCHEDULE
931 for( i = 0; i < num_rows; i++ )
933 y_data[i] = y_data[i] && beta;
944 #ifdef HYPRE_USING_OPENMP
945 #pragma omp parallel for private( i ) HYPRE_SMP_SCHEDULE
947 for( i = 0; i < num_rows; i++ )
964 if( num_rownnz < xpar * ( num_rows ) )
966 #ifdef HYPRE_USING_OPENMP
967 #pragma omp parallel for private( i, jj, m, tempx ) HYPRE_SMP_SCHEDULE
969 for( i = 0; i < num_rownnz; i++ )
974 for( jj = A_i[m]; jj < A_i[m + 1]; jj++ )
977 tempx = tempx || x_data[A_j[jj]];
979 y_data[m] = y_data[m] || tempx;
984 #ifdef HYPRE_USING_OPENMP
985 #pragma omp parallel for private( i, jj, temp ) HYPRE_SMP_SCHEDULE
987 for( i = 0; i < num_rows; i++ )
990 for( jj = A_i[i]; jj < A_i[i + 1]; jj++ )
993 temp = temp || x_data[A_j[jj]];
995 y_data[i] = y_data[i] || temp;
1007 hypre_ParCSRCommHandle* hypre_ParCSRCommHandleCreate_bool( HYPRE_Int job,
1008 hypre_ParCSRCommPkg* comm_pkg,
1009 HYPRE_Bool* send_data,
1010 HYPRE_Bool* recv_data )
1012 HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends( comm_pkg );
1013 HYPRE_Int num_recvs = hypre_ParCSRCommPkgNumRecvs( comm_pkg );
1014 MPI_Comm comm = hypre_ParCSRCommPkgComm( comm_pkg );
1016 hypre_ParCSRCommHandle* comm_handle;
1017 HYPRE_Int num_requests;
1018 hypre_MPI_Request* requests;
1021 HYPRE_Int my_id, num_procs;
1022 HYPRE_Int ip, vec_start, vec_len;
1024 num_requests = num_sends + num_recvs;
1025 requests = hypre_CTAlloc( hypre_MPI_Request, num_requests );
1027 hypre_MPI_Comm_size( comm, &num_procs );
1028 hypre_MPI_Comm_rank( comm, &my_id );
1034 HYPRE_Bool* d_send_data = (HYPRE_Bool*)send_data;
1035 HYPRE_Bool* d_recv_data = (HYPRE_Bool*)recv_data;
1036 for( i = 0; i < num_recvs; i++ )
1038 ip = hypre_ParCSRCommPkgRecvProc( comm_pkg, i );
1039 vec_start = hypre_ParCSRCommPkgRecvVecStart( comm_pkg, i );
1040 vec_len = hypre_ParCSRCommPkgRecvVecStart( comm_pkg, i + 1 ) - vec_start;
1041 hypre_MPI_Irecv( &d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL, ip, 0, comm, &requests[j++] );
1043 for( i = 0; i < num_sends; i++ )
1045 vec_start = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i );
1046 vec_len = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i + 1 ) - vec_start;
1047 ip = hypre_ParCSRCommPkgSendProc( comm_pkg, i );
1048 hypre_MPI_Isend( &d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL, ip, 0, comm, &requests[j++] );
1053 HYPRE_Bool* d_send_data = (HYPRE_Bool*)send_data;
1054 HYPRE_Bool* d_recv_data = (HYPRE_Bool*)recv_data;
1055 for( i = 0; i < num_sends; i++ )
1057 vec_start = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i );
1058 vec_len = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i + 1 ) - vec_start;
1059 ip = hypre_ParCSRCommPkgSendProc( comm_pkg, i );
1060 hypre_MPI_Irecv( &d_recv_data[vec_start], vec_len, HYPRE_MPI_BOOL, ip, 0, comm, &requests[j++] );
1062 for( i = 0; i < num_recvs; i++ )
1064 ip = hypre_ParCSRCommPkgRecvProc( comm_pkg, i );
1065 vec_start = hypre_ParCSRCommPkgRecvVecStart( comm_pkg, i );
1066 vec_len = hypre_ParCSRCommPkgRecvVecStart( comm_pkg, i + 1 ) - vec_start;
1067 hypre_MPI_Isend( &d_send_data[vec_start], vec_len, HYPRE_MPI_BOOL, ip, 0, comm, &requests[j++] );
1076 comm_handle = hypre_CTAlloc( hypre_ParCSRCommHandle, 1 );
1078 hypre_ParCSRCommHandleCommPkg( comm_handle ) = comm_pkg;
1079 hypre_ParCSRCommHandleSendData( comm_handle ) = send_data;
1080 hypre_ParCSRCommHandleRecvData( comm_handle ) = recv_data;
1081 hypre_ParCSRCommHandleNumRequests( comm_handle ) = num_requests;
1082 hypre_ParCSRCommHandleRequests( comm_handle ) = requests;
1088 void hypre_ParCSRMatrixBooleanMatvec( hypre_ParCSRMatrix* A,
1094 hypre_ParCSRCommHandle* comm_handle;
1095 hypre_ParCSRCommPkg* comm_pkg = hypre_ParCSRMatrixCommPkg( A );
1096 hypre_CSRMatrix* diag = hypre_ParCSRMatrixDiag( A );
1097 hypre_CSRMatrix* offd = hypre_ParCSRMatrixOffd( A );
1099 HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols( offd );
1100 HYPRE_Int num_sends, i, j, index;
1102 HYPRE_Bool *x_tmp, *x_buf;
1104 x_tmp = hypre_CTAlloc( HYPRE_Bool, num_cols_offd );
1112 hypre_MatvecCommPkgCreate( A );
1113 comm_pkg = hypre_ParCSRMatrixCommPkg( A );
1116 num_sends = hypre_ParCSRCommPkgNumSends( comm_pkg );
1117 x_buf = hypre_CTAlloc( HYPRE_Bool, hypre_ParCSRCommPkgSendMapStart( comm_pkg, num_sends ) );
1120 for( i = 0; i < num_sends; i++ )
1122 j = hypre_ParCSRCommPkgSendMapStart( comm_pkg, i );
1123 for( ; j < hypre_ParCSRCommPkgSendMapStart( comm_pkg, i + 1 ); j++ )
1125 x_buf[index++] = x[hypre_ParCSRCommPkgSendMapElmt( comm_pkg, j )];
1129 comm_handle = hypre_ParCSRCommHandleCreate_bool( 1, comm_pkg, x_buf, x_tmp );
1131 hypre_CSRMatrixBooleanMatvec( diag, alpha, x, beta, y );
1133 hypre_ParCSRCommHandleDestroy( comm_handle );
1137 hypre_CSRMatrixBooleanMatvec( offd, alpha, x_tmp, 1, y );
1140 hypre_TFree( x_buf );
1141 hypre_TFree( x_tmp );
1144 HYPRE_Int hypre_CSRMatrixSum( hypre_CSRMatrix* A, HYPRE_Complex beta, hypre_CSRMatrix* B )
1146 HYPRE_Complex* A_data = hypre_CSRMatrixData( A );
1147 HYPRE_Int* A_i = hypre_CSRMatrixI( A );
1148 HYPRE_Int* A_j = hypre_CSRMatrixJ( A );
1149 HYPRE_Int nrows_A = hypre_CSRMatrixNumRows( A );
1150 HYPRE_Int ncols_A = hypre_CSRMatrixNumCols( A );
1151 HYPRE_Complex* B_data = hypre_CSRMatrixData( B );
1152 HYPRE_Int* B_i = hypre_CSRMatrixI( B );
1153 HYPRE_Int* B_j = hypre_CSRMatrixJ( B );
1154 HYPRE_Int nrows_B = hypre_CSRMatrixNumRows( B );
1155 HYPRE_Int ncols_B = hypre_CSRMatrixNumCols( B );
1157 HYPRE_Int ia, j, pos;
1160 if( nrows_A != nrows_B || ncols_A != ncols_B )
1165 marker = hypre_CTAlloc( HYPRE_Int, ncols_A );
1166 for( ia = 0; ia < ncols_A; ia++ )
1171 for( ia = 0; ia < nrows_A; ia++ )
1173 for( j = A_i[ia]; j < A_i[ia + 1]; j++ )
1178 for( j = B_i[ia]; j < B_i[ia + 1]; j++ )
1180 pos = marker[B_j[j]];
1185 A_data[pos] += beta * B_data[j];
1189 hypre_TFree( marker );
1193 hypre_ParCSRMatrix* hypre_ParCSRMatrixAdd( hypre_ParCSRMatrix* A, hypre_ParCSRMatrix* B )
1195 MPI_Comm comm = hypre_ParCSRMatrixComm( A );
1196 hypre_CSRMatrix* A_diag = hypre_ParCSRMatrixDiag( A );
1197 hypre_CSRMatrix* A_offd = hypre_ParCSRMatrixOffd( A );
1198 HYPRE_Int* A_cmap = hypre_ParCSRMatrixColMapOffd( A );
1199 HYPRE_Int A_cmap_size = hypre_CSRMatrixNumCols( A_offd );
1200 hypre_CSRMatrix* B_diag = hypre_ParCSRMatrixDiag( B );
1201 hypre_CSRMatrix* B_offd = hypre_ParCSRMatrixOffd( B );
1202 HYPRE_Int* B_cmap = hypre_ParCSRMatrixColMapOffd( B );
1203 HYPRE_Int B_cmap_size = hypre_CSRMatrixNumCols( B_offd );
1204 hypre_ParCSRMatrix* C;
1205 hypre_CSRMatrix* C_diag;
1206 hypre_CSRMatrix* C_offd;
1209 HYPRE_Int cmap_differ;
1213 if( A_cmap_size != B_cmap_size )
1219 for( im = 0; im < A_cmap_size; im++ )
1221 if( A_cmap[im] != B_cmap[im] )
1229 if( cmap_differ == 0 )
1236 C_diag = hypre_CSRMatrixAdd( A_diag, B_diag );
1241 C_offd = hypre_CSRMatrixAdd( A_offd, B_offd );
1244 hypre_CSRMatrixDestroy( C_diag );
1248 C_cmap = hypre_TAlloc( HYPRE_Int, A_cmap_size );
1249 for( im = 0; im < A_cmap_size; im++ )
1251 C_cmap[im] = A_cmap[im];
1254 C = hypre_ParCSRMatrixCreate( comm, hypre_ParCSRMatrixGlobalNumRows( A ),
1255 hypre_ParCSRMatrixGlobalNumCols( A ), hypre_ParCSRMatrixRowStarts( A ),
1256 hypre_ParCSRMatrixColStarts( A ), hypre_CSRMatrixNumCols( C_offd ),
1257 hypre_CSRMatrixNumNonzeros( C_diag ), hypre_CSRMatrixNumNonzeros( C_offd ) );
1261 hypre_CSRMatrixDestroy( hypre_ParCSRMatrixDiag( C ) );
1262 hypre_CSRMatrixDestroy( hypre_ParCSRMatrixOffd( C ) );
1263 hypre_ParCSRMatrixDiag( C ) = C_diag;
1264 hypre_ParCSRMatrixOffd( C ) = C_offd;
1266 hypre_ParCSRMatrixColMapOffd( C ) = C_cmap;
1274 hypre_CSRMatrix* csr_A;
1275 hypre_CSRMatrix* csr_B;
1276 hypre_CSRMatrix* csr_C_temp;
1279 csr_A = hypre_MergeDiagAndOffd( A );
1282 csr_B = hypre_MergeDiagAndOffd( B );
1285 csr_C_temp = hypre_CSRMatrixAdd( csr_A, csr_B );
1288 ierr += hypre_CSRMatrixDestroy( csr_A );
1289 ierr += hypre_CSRMatrixDestroy( csr_B );
1292 C = hypre_ParCSRMatrixCreate( hypre_ParCSRMatrixComm( A ), hypre_ParCSRMatrixGlobalNumRows( A ),
1293 hypre_ParCSRMatrixGlobalNumCols( A ), hypre_ParCSRMatrixRowStarts( A ),
1294 hypre_ParCSRMatrixColStarts( A ), 0, 0, 0 );
1300 ierr += GenerateDiagAndOffd( csr_C_temp, C, hypre_ParCSRMatrixFirstColDiag( A ),
1301 hypre_ParCSRMatrixLastColDiag( A ) );
1304 ierr += hypre_CSRMatrixDestroy( csr_C_temp );
1310 hypre_CSRMatrixReorder( hypre_ParCSRMatrixDiag( C ) );
1313 hypre_ParCSRMatrixSetDataOwner( C, 1 );
1315 hypre_ParCSRMatrixSetRowStartsOwner( C, 0 );
1316 hypre_ParCSRMatrixSetColStartsOwner( C, 0 );
1321 HYPRE_Int hypre_ParCSRMatrixSum( hypre_ParCSRMatrix* A, HYPRE_Complex beta, hypre_ParCSRMatrix* B )
1323 hypre_CSRMatrix* A_diag = hypre_ParCSRMatrixDiag( A );
1324 hypre_CSRMatrix* A_offd = hypre_ParCSRMatrixOffd( A );
1325 hypre_CSRMatrix* B_diag = hypre_ParCSRMatrixDiag( B );
1326 hypre_CSRMatrix* B_offd = hypre_ParCSRMatrixOffd( B );
1329 error = hypre_CSRMatrixSum( A_diag, beta, B_diag );
1335 HYPRE_Int hypre_CSRMatrixSetConstantValues( hypre_CSRMatrix* A, HYPRE_Complex value )
1337 HYPRE_Complex* A_data = hypre_CSRMatrixData( A );
1338 HYPRE_Int A_nnz = hypre_CSRMatrixNumNonzeros( A );
1341 for( ia = 0; ia < A_nnz; ia++ )
1349 HYPRE_Int hypre_ParCSRMatrixSetConstantValues( hypre_ParCSRMatrix* A, HYPRE_Complex value )
1351 hypre_CSRMatrixSetConstantValues( hypre_ParCSRMatrixDiag( A ), value );
1352 hypre_CSRMatrixSetConstantValues( hypre_ParCSRMatrixOffd( A ), value );