1 #include "BSprivate.h"
2 
3 /*@ BScopy_par_mat - Create of copy of a matrix
4 
5     Input Parameters:
6 .   A - The sparse matrix
7 
8     Returns:
9     the copy of A
10 
11     Notes:
12 $   In the ICC case, we reuse the block matrices
13 $     in the cliques (we use the unused portion).
14 $   We reuse the permutations.
15 $   We reuse the map color_2_cl.
16 $   We reuse the diagonal.
17 $   We reuse the global numbering.
18 $   We reuse the reperm structure.
19 $   As in the original matrix, we only have a pointer
20 $     to the map.  IMPORTANT: this reuse must be
21 $     accounted for when freeing things.
22  @*/
BScopy_par_mat(BSpar_mat * A)23 BSpar_mat *BScopy_par_mat(BSpar_mat *A)
24 {
25 	BSpar_mat *newA;
26 	int	i, j, size;
27 	BScl_2_inode *cl2i, *newcl2i;
28 	BSinode_list *inodes, *new_inodes;
29 
30 	MY_MALLOCN(newA,(BSpar_mat *),sizeof(BSpar_mat),1);
31 	newA->num_rows = A->num_rows;
32 	newA->global_num_rows = A->global_num_rows;
33 	newA->local_nnz = A->local_nnz;
34 	newA->local_num_inodes = A->local_num_inodes;
35 	newA->global_num_inodes = A->global_num_inodes;
36 	newA->local_num_cliques = A->local_num_cliques;
37 	newA->global_num_cliques = A->global_num_cliques;
38 	newA->num_colors = A->num_colors;
39 	newA->max_local_row_length = A->max_local_row_length;
40 	newA->symmetric = A->symmetric;
41 	newA->icc_storage = A->icc_storage;
42 
43 	newA->perm = A->perm;
44 	newA->inv_perm = A->inv_perm;
45 	newA->global_row_num = A->global_row_num;
46 	newA->color2clique = A->color2clique;
47 	newA->diag = A->diag;
48 	newA->save_diag = A->save_diag;
49 	newA->scale_diag = A->scale_diag;
50 
51 	newA->map = A->map;
52 	newA->reperm = A->reperm;
53 
54 	/* make a copy of the "clique to inode" structure */
55 	cl2i = A->clique2inode;
56 	MY_MALLOCN(newcl2i,(BScl_2_inode *),sizeof(BScl_2_inode),2);
57 	newA->clique2inode = newcl2i;
58 	newcl2i->num_cols = cl2i->num_cols;
59 	MY_MALLOCN(newcl2i->g_offset,(int *),sizeof(int)*(cl2i->num_cols+1),3);
60 	MY_MALLOCN(newcl2i->proc,(int *),sizeof(int)*(cl2i->num_cols+1),4);
61 	MY_MALLOCN(newcl2i->inode_index,(int *),sizeof(int)*(cl2i->num_cols+1),5);
62 	MY_MALLOCN(newcl2i->d_mats,(BSdense *),sizeof(BSdense)*(cl2i->num_cols+1),6);
63 	for (i=0;i<cl2i->num_cols+1;i++) {
64 		newcl2i->g_offset[i] = cl2i->g_offset[i];
65 		newcl2i->proc[i] = cl2i->proc[i];
66 		newcl2i->inode_index[i] = cl2i->inode_index[i];
67 		newcl2i->d_mats[i].size = cl2i->d_mats[i].size;
68 		newcl2i->d_mats[i].local_ind = cl2i->d_mats[i].local_ind;
69 		if(A->icc_storage) {
70 			newcl2i->d_mats[i].matrix = cl2i->d_mats[i].matrix;
71 		} else {
72 			/* We do not reuse the clique matrices (ILU) */
73 			size = cl2i->d_mats[i].size;
74 			if ((i < cl2i->num_cols) && (size > 0)) {
75 				MY_MALLOCN(newcl2i->d_mats[i].matrix,(FLOAT *),
76 					size*size*sizeof(FLOAT)+size*sizeof(int),7);
77 			} else {
78 				newcl2i->d_mats[i].matrix = NULL;
79 			}
80 		}
81 	}
82 
83 	/* make a copy of the "inode" structure */
84 	inodes = A->inodes;
85 	MY_MALLOCN(new_inodes,(BSinode_list *),sizeof(BSinode_list),7);
86 	newA->inodes = new_inodes;
87 	new_inodes->length = inodes->length;
88 	MY_MALLOCN(new_inodes->list,(BSinode *),
89 		sizeof(BSinode)*(inodes->length+1),8);
90 	new_inodes->list[inodes->length].gcol_num = INT_MAX;
91 	MY_MALLOCN(new_inodes->list[inodes->length].o_gcol_num,(int *),
92 		sizeof(int),21);
93 	new_inodes->list[inodes->length].o_gcol_num[0] = INT_MAX;
94 	for (i=0;i<inodes->length;i++) {
95 		new_inodes->list[i].num_cols = inodes->list[i].num_cols;
96 		new_inodes->list[i].gcol_num = inodes->list[i].gcol_num;
97 		MY_MALLOCN(new_inodes->list[i].o_gcol_num,(int *),
98 			sizeof(int)*new_inodes->list[i].num_cols,20);
99 		for (j=0;j<new_inodes->list[i].num_cols;j++) {
100 			new_inodes->list[i].o_gcol_num[j] = inodes->list[i].o_gcol_num[j];
101 		}
102 		new_inodes->list[i].length = inodes->list[i].length;
103 		new_inodes->list[i].below_diag = inodes->list[i].below_diag;
104 		MY_MALLOCN(new_inodes->list[i].row_num,(int *),
105 			sizeof(int)*new_inodes->list[i].length,10);
106 		for (j=0;j<new_inodes->list[i].length;j++) {
107 			new_inodes->list[i].row_num[j] = inodes->list[i].row_num[j];
108 		}
109 		MY_MALLOCN(new_inodes->list[i].nz,(FLOAT *),sizeof(FLOAT)*
110 			new_inodes->list[i].length*new_inodes->list[i].num_cols,11);
111 	}
112 
113 	/* now, fill in the nonzero values */
114 	BScopy_nz(A,newA); CHKERRN(0);
115 
116 	return(newA);
117 }
118