void ML_getrow_matvec(ML_Operator *matrix, double *vec, int Nvec, double *ovec, int *Novec) { ML_Operator *temp, *temp2, *temp3, *temp4, *tptr; int *cols, i; int allocated, row_length; if (matrix->getrow->func_ptr == NULL) { printf("ML_getrow_matvec: empty object? \n"); exit(1); } temp = ML_Operator_Create(matrix->comm); ML_Operator_Set_1Levels(temp, matrix->from, matrix->from); ML_Operator_Set_ApplyFuncData(temp,1,Nvec,vec,Nvec,NULL,0); ML_Operator_Set_Getrow(temp,Nvec, VECTOR_getrows); temp->max_nz_per_row = 1; temp->N_nonzeros = Nvec; if (matrix->getrow->pre_comm != NULL) { ML_exchange_rows(temp, &temp2, matrix->getrow->pre_comm); } else temp2 = temp; ML_matmat_mult(matrix, temp2, &temp3); if (matrix->getrow->post_comm != NULL) ML_exchange_rows(temp3, &temp4, matrix->getrow->post_comm); else temp4 = temp3; allocated = temp4->getrow->Nrows + 1; cols = (int *) ML_allocate(allocated*sizeof(int)); if (cols == NULL) { printf("no space in ML_getrow_matvec()\n"); exit(1); } for (i = 0; i < temp4->getrow->Nrows; i++) { ML_get_matrix_row(temp4, 1, &i, &allocated , &cols, &ovec, &row_length, i); if (allocated != temp4->getrow->Nrows + 1) printf("memory problems ... we can't reallocate here\n"); } ML_free(cols); if ( *Novec != temp4->getrow->Nrows) { printf("Warning: The length of ML's output vector does not agree with\n"); printf(" the user's length for the output vector (%d vs. %d).\n", *Novec, temp4->getrow->Nrows); printf(" indicate a problem.\n"); } *Novec = temp4->getrow->Nrows; if (matrix->getrow->pre_comm != NULL) { tptr = temp2; while ( (tptr!= NULL) && (tptr->sub_matrix != temp)) tptr = tptr->sub_matrix; if (tptr != NULL) tptr->sub_matrix = NULL; ML_RECUR_CSR_MSRdata_Destroy(temp2); ML_Operator_Destroy(&temp2); } if (matrix->getrow->post_comm != NULL) { tptr = temp4; while ( (tptr!= NULL) && (tptr->sub_matrix != temp3)) tptr = tptr->sub_matrix; if (tptr != NULL) tptr->sub_matrix = NULL; ML_RECUR_CSR_MSRdata_Destroy(temp4); ML_Operator_Destroy(&temp4); } ML_Operator_Destroy(&temp); ML_RECUR_CSR_MSRdata_Destroy(temp3); ML_Operator_Destroy(&temp3); }
void ML_rap(ML_Operator *Rmat, ML_Operator *Amat, ML_Operator *Pmat, ML_Operator *Result, int matrix_type) { int max_per_proc, i, j, N_input_vector; ML_Operator *APmat, *RAPmat, *Pcomm, *RAPcomm, *APcomm, *AP2comm, *tptr; ML_CommInfoOP *getrow_comm; double *scales = NULL; # ifdef ML_TIMING double tpre,tmult,tpost,ttotal; # endif /* Check that N_input_vector is reasonable */ # ifdef ML_TIMING tpre = GetClock(); ttotal = GetClock(); # endif N_input_vector = Pmat->invec_leng; getrow_comm = Pmat->getrow->pre_comm; if ( getrow_comm != NULL) { for (i = 0; i < getrow_comm->N_neighbors; i++) { for (j = 0; j < getrow_comm->neighbors[i].N_send; j++) { if (getrow_comm->neighbors[i].send_list[j] >= N_input_vector) { printf("(%d) Error: N_input_vector (%d) argument to rap() is not \n", Amat->comm->ML_mypid,N_input_vector); printf("(%d) Error: larger than %dth element (%d) sent to node %d\n", Amat->comm->ML_mypid,j+1, getrow_comm->neighbors[i].send_list[j], getrow_comm->neighbors[i].ML_id); printf("(%d) Error: Amat(%d,%d) Rmat(%d,%d) Pmat(%d,%d)\n", Amat->comm->ML_mypid, Amat->outvec_leng,Amat->invec_leng, Rmat->outvec_leng,Rmat->invec_leng, Pmat->outvec_leng,Pmat->invec_leng); fflush(stdout); exit(1); } } } } ML_create_unique_col_id(N_input_vector, &(Pmat->getrow->loc_glob_map), getrow_comm, &max_per_proc, Pmat->comm); Pmat->getrow->use_loc_glob_map = ML_YES; if (Amat->getrow->pre_comm != NULL) ML_exchange_rows( Pmat, &Pcomm, Amat->getrow->pre_comm); else Pcomm = Pmat; #ifdef DEBUG if ( Pmat->comm->ML_mypid == 0 ) printf("ML_rap : A * P begins...\n"); #endif # ifdef ML_TIMING tpre = GetClock() - tpre; tmult = GetClock(); # endif ML_matmat_mult(Amat, Pcomm , &APmat); # ifdef ML_TIMING tmult = GetClock() - tmult; tpost = GetClock(); # endif #ifdef DEBUG if ( Pmat->comm->ML_mypid == 0 ) printf("ML_rap : A * P ends.\n"); #endif ML_free(Pmat->getrow->loc_glob_map); Pmat->getrow->loc_glob_map = NULL; Pmat->getrow->use_loc_glob_map = ML_NO; if (Amat->getrow->pre_comm != NULL) { tptr = Pcomm; while ( (tptr!= NULL) && (tptr->sub_matrix != Pmat)) tptr = tptr->sub_matrix; if (tptr != NULL) tptr->sub_matrix = NULL; ML_RECUR_CSR_MSRdata_Destroy(Pcomm); ML_Operator_Destroy(&Pcomm); } if (Amat->getrow->post_comm != NULL) { ML_exchange_rows(APmat, &APcomm, Amat->getrow->post_comm); } else APcomm = APmat; /* Take into account any scaling in Amat */ if (Rmat->from != NULL) ML_DVector_GetDataPtr(Rmat->from->Amat_Normalization,&scales); if (scales != NULL) ML_Scale_CSR(APcomm, scales, 0); if (Rmat->getrow->pre_comm != NULL) ML_exchange_rows( APcomm, &AP2comm, Rmat->getrow->pre_comm); else AP2comm = APcomm; # ifdef ML_TIMING tpost = GetClock() - tpost; if ( Pmat->comm->ML_mypid == 0 && ML_Get_PrintLevel() > 5) { int level=-1; if (Amat->from != NULL) level = Amat->from->levelnum-1; printf("Timing summary (in seconds) for product RAP on level %d\n", level); printf(" (level %d) RAP right: pre-multiply communication time = %3.2e\n", level, tpre); printf(" (level %d) RAP right: multiply time = %3.2e\n", level, tmult); printf(" (level %d) RAP right: post-multiply communication time = %3.2e\n", level, tpost); } # endif #ifdef DEBUG if ( Pmat->comm->ML_mypid == 0 ) printf("ML_rap : R * AP begins...\n"); #endif # ifdef ML_TIMING tmult = GetClock(); # endif ML_matmat_mult(Rmat,AP2comm, &RAPmat); #ifdef DEBUG if ( Pmat->comm->ML_mypid == 0 ) printf("ML_rap : R * AP ends.\n"); #endif ML_RECUR_CSR_MSRdata_Destroy(AP2comm); ML_Operator_Destroy(&AP2comm); # ifdef ML_TIMING tmult = GetClock()-tmult; tpost = GetClock(); # endif if (Rmat->getrow->post_comm != NULL) ML_exchange_rows( RAPmat, &RAPcomm, Rmat->getrow->post_comm); else RAPcomm = RAPmat; scales = NULL; if (Rmat->to != NULL) ML_DVector_GetDataPtr(Rmat->to->Amat_Normalization,&scales); if (scales != NULL) ML_Scale_CSR(RAPcomm, scales, 1); RAPcomm->num_PDEs = Amat->num_PDEs; RAPcomm->num_rigid = Amat->num_rigid; if (matrix_type == ML_MSR_MATRIX) ML_back_to_local(RAPcomm, Result, max_per_proc); else if (matrix_type == ML_CSR_MATRIX) ML_back_to_csrlocal(RAPcomm, Result, max_per_proc); else if (matrix_type == ML_EpetraCRS_MATRIX) #ifdef ML_WITH_EPETRA ML_back_to_epetraCrs(RAPcomm, Result, Rmat, Pmat); #else pr_error("ML_RAP: ML_EpetraCRS_MATRIX requires epetra to be compiled in.\n"); #endif else pr_error("ML_RAP: Unknown matrix type\n");