1 #include "BSprivate.h"
2
3 /*+ BSperm_rows - Permute the nonzeros in A in preparation for
4 creating the efficient parallel execution structure
5
6 Input Parameters:
7 . A - the sparse matrix
8 . gnum - the new global numbering of the rows
9 . perm - the inode permutation
10 . distr - the inode distribution
11 . procinfo - the usual processor stuff
12 . keep - Indicates if certain structures should be kept for future
13 permuting of this structure
14 . max_row_len - the maximum length of any row in A
15
16 Output Parameters:
17 . A - the sparse matrix with permuted rows
18
19 Returns:
20 a structure used to perform the permutation quickly in the future
21
22 +*/
BSperm_rows(BSspmat * A,BSnumbering * gnum,BSpermutation * perm,BSdistribution * distr,BSprocinfo * procinfo,int keep,int * max_row_len)23 BSkey_arr *BSperm_rows(BSspmat *A, BSnumbering *gnum, BSpermutation *perm,
24 BSdistribution *distr, BSprocinfo *procinfo, int keep, int *max_row_len)
25 {
26 int num_nz;
27 int count, ind;
28 int i, j, k;
29 BSpermutation *iperm;
30 BSpermutation *tperm;
31 int *key;
32 BSkey_arr *key_arr;
33 FLOAT *dwork;
34 int *iwork;
35 BSbb *trans_bb;
36 int query_len, *addrs, *answs;
37 void (*map)(int,int *,int *,BSprocinfo *,BSmapping *);
38 BSsprow *row;
39 int *colptr;
40 FLOAT *nzptr;
41 int *map_work;
42
43
44 /* create inverse permutation */
45 iperm = BSalloc_permutation(A->num_rows); CHKERRN(0);
46 BSperm2iperm(perm,iperm); CHKERRN(0);
47
48 /* find the number of nonlocal nonzeros */
49 num_nz = BSnonlocalnz(A,max_row_len,procinfo); CHKERRN(0);
50 MY_MALLOCN(map_work,(int *),sizeof(int)*(*max_row_len),0);
51
52 /* set up query */
53 map = A->map->fglobal2proc;
54 MY_MALLOCN(addrs,(int *),sizeof(int)*num_nz,3);
55 query_len = 0;
56 count = 0;
57 for (i=0;i<distr->max+1;i++) {
58 ind = iperm->perm[count];
59 count += distr->distribution[i];
60 row = A->rows[ind];
61 colptr = row->col;
62 (*map)(row->length,colptr,map_work,procinfo,A->map); CHKERRN(0);
63 for (j=0;j<row->length;j++) {
64 if (map_work[j] != procinfo->my_id) {
65 addrs[query_len] = colptr[j];
66 query_len++;
67 }
68 }
69 }
70
71 /* set up and query bulletin board */
72 trans_bb = BSinit_bb(A->num_rows,A->map);CHKERRN(0);
73 BSpost_noaddr_bb(trans_bb,A->num_rows,gnum->numbers); CHKERRN(0);
74 MY_MALLOCN(answs,(int *),sizeof(int)*num_nz,4);
75 BSquery_match_bb(trans_bb,query_len,addrs,answs,procinfo); CHKERRN(0);
76 MY_FREEN(addrs);
77 BSfree_bb(trans_bb); CHKERRN(0);
78
79 /* now, do the sorting */
80 MY_MALLOCN(dwork,(FLOAT *),sizeof(FLOAT)*(*max_row_len),1);
81 MY_MALLOCN(iwork,(int *),sizeof(int)*(*max_row_len),2);
82 /* if keep is true, then allocate array of keys */
83 if (keep) {
84 key_arr = BSalloc_key_arr(distr->max+1); CHKERRN(0);
85 } else {
86 key_arr = NULL;
87 MY_MALLOCN(key,(int *),sizeof(int)*(*max_row_len),5);
88 }
89 query_len = 0;
90 count = 0;
91 map = A->map->fglobal2local;
92 tperm = BSalloc_permutation((*max_row_len)); CHKERRN(0);
93 for (i=0;i<distr->max+1;i++) {
94 ind = iperm->perm[count];
95 row = A->rows[ind];
96 colptr = row->col;
97 if (keep) {
98 MY_MALLOCN(key,(int *),sizeof(int)*row->length,5);
99 key_arr->array[i] = key;
100 }
101 (*map)(row->length,colptr,map_work,procinfo,A->map); CHKERRN(0);
102 for (j=0;j<row->length;j++) {
103 if (map_work[j] < 0) {
104 key[j] = answs[query_len];
105 query_len++;
106 } else {
107 key[j] = gnum->numbers[map_work[j]];
108 }
109 }
110 BSreset_permutation(row->length,tperm); CHKERRN(0);
111 for (j=0;j<row->length;j++) tperm->perm[j] = j;
112
113 /* now find the inverse permutation according to the new numbers */
114 BSheap_sort1(row->length,key,tperm->perm); CHKERRN(0);
115
116 /* permute the column values into iwork and then copy them */
117 /* into the correct places */
118 /* also create a floating point work vector */
119 BSiperm_ivec(colptr,iwork,tperm); CHKERRN(0);
120 for (k=0;k<row->length;k++) {
121 colptr[k] = iwork[k];
122 }
123 for (j=0;j<distr->distribution[i];j++) {
124 ind = iperm->perm[count];
125 row = A->rows[ind];
126 nzptr = row->nz;
127 BSiperm_dvec(nzptr,dwork,tperm); CHKERRN(0);
128 for (k=0;k<row->length;k++) {
129 nzptr[k] = dwork[k];
130 }
131 count++;
132 }
133 }
134 BSfree_permutation(tperm); CHKERRN(0);
135
136 if (!keep) {
137 MY_FREE(key);
138 }
139 MY_FREEN(map_work);
140 MY_FREEN(dwork);
141 MY_FREEN(iwork);
142 MY_FREEN(answs);
143 BSfree_permutation(iperm); CHKERRN(0);
144
145 return(key_arr);
146 }
147