#include "BSprivate.h" /*@ BScopy_par_mat - Create of copy of a matrix Input Parameters: . A - The sparse matrix Returns: the copy of A Notes: $ In the ICC case, we reuse the block matrices $ in the cliques (we use the unused portion). $ We reuse the permutations. $ We reuse the map color_2_cl. $ We reuse the diagonal. $ We reuse the global numbering. $ We reuse the reperm structure. $ As in the original matrix, we only have a pointer $ to the map. IMPORTANT: this reuse must be $ accounted for when freeing things. @*/ BSpar_mat *BScopy_par_mat(BSpar_mat *A) { BSpar_mat *newA; int i, j, size; BScl_2_inode *cl2i, *newcl2i; BSinode_list *inodes, *new_inodes; MY_MALLOCN(newA,(BSpar_mat *),sizeof(BSpar_mat),1); newA->num_rows = A->num_rows; newA->global_num_rows = A->global_num_rows; newA->local_nnz = A->local_nnz; newA->local_num_inodes = A->local_num_inodes; newA->global_num_inodes = A->global_num_inodes; newA->local_num_cliques = A->local_num_cliques; newA->global_num_cliques = A->global_num_cliques; newA->num_colors = A->num_colors; newA->max_local_row_length = A->max_local_row_length; newA->symmetric = A->symmetric; newA->icc_storage = A->icc_storage; newA->perm = A->perm; newA->inv_perm = A->inv_perm; newA->global_row_num = A->global_row_num; newA->color2clique = A->color2clique; newA->diag = A->diag; newA->save_diag = A->save_diag; newA->scale_diag = A->scale_diag; newA->map = A->map; newA->reperm = A->reperm; /* make a copy of the "clique to inode" structure */ cl2i = A->clique2inode; MY_MALLOCN(newcl2i,(BScl_2_inode *),sizeof(BScl_2_inode),2); newA->clique2inode = newcl2i; newcl2i->num_cols = cl2i->num_cols; MY_MALLOCN(newcl2i->g_offset,(int *),sizeof(int)*(cl2i->num_cols+1),3); MY_MALLOCN(newcl2i->proc,(int *),sizeof(int)*(cl2i->num_cols+1),4); MY_MALLOCN(newcl2i->inode_index,(int *),sizeof(int)*(cl2i->num_cols+1),5); MY_MALLOCN(newcl2i->d_mats,(BSdense *),sizeof(BSdense)*(cl2i->num_cols+1),6); for (i=0;inum_cols+1;i++) { newcl2i->g_offset[i] = cl2i->g_offset[i]; newcl2i->proc[i] = cl2i->proc[i]; newcl2i->inode_index[i] = cl2i->inode_index[i]; newcl2i->d_mats[i].size = cl2i->d_mats[i].size; newcl2i->d_mats[i].local_ind = cl2i->d_mats[i].local_ind; if(A->icc_storage) { newcl2i->d_mats[i].matrix = cl2i->d_mats[i].matrix; } else { /* We do not reuse the clique matrices (ILU) */ size = cl2i->d_mats[i].size; if ((i < cl2i->num_cols) && (size > 0)) { MY_MALLOCN(newcl2i->d_mats[i].matrix,(FLOAT *), size*size*sizeof(FLOAT)+size*sizeof(int),7); } else { newcl2i->d_mats[i].matrix = NULL; } } } /* make a copy of the "inode" structure */ inodes = A->inodes; MY_MALLOCN(new_inodes,(BSinode_list *),sizeof(BSinode_list),7); newA->inodes = new_inodes; new_inodes->length = inodes->length; MY_MALLOCN(new_inodes->list,(BSinode *), sizeof(BSinode)*(inodes->length+1),8); new_inodes->list[inodes->length].gcol_num = INT_MAX; MY_MALLOCN(new_inodes->list[inodes->length].o_gcol_num,(int *), sizeof(int),21); new_inodes->list[inodes->length].o_gcol_num[0] = INT_MAX; for (i=0;ilength;i++) { new_inodes->list[i].num_cols = inodes->list[i].num_cols; new_inodes->list[i].gcol_num = inodes->list[i].gcol_num; MY_MALLOCN(new_inodes->list[i].o_gcol_num,(int *), sizeof(int)*new_inodes->list[i].num_cols,20); for (j=0;jlist[i].num_cols;j++) { new_inodes->list[i].o_gcol_num[j] = inodes->list[i].o_gcol_num[j]; } new_inodes->list[i].length = inodes->list[i].length; new_inodes->list[i].below_diag = inodes->list[i].below_diag; MY_MALLOCN(new_inodes->list[i].row_num,(int *), sizeof(int)*new_inodes->list[i].length,10); for (j=0;jlist[i].length;j++) { new_inodes->list[i].row_num[j] = inodes->list[i].row_num[j]; } MY_MALLOCN(new_inodes->list[i].nz,(FLOAT *),sizeof(FLOAT)* new_inodes->list[i].length*new_inodes->list[i].num_cols,11); } /* now, fill in the nonzero values */ BScopy_nz(A,newA); CHKERRN(0); return(newA); }