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