#include "BSprivate.h"
/*+ BStrans_perm_in - Get the complete mapping from i-node to rows
Input Parameters:
. A - a sparse matrix
. gnum - the global permuted numbering
. onum - the original global numbering
. inode_distr - the distribution of the inode numbering
. procinfo - the usual processor stuff
Returns:
the mapping from i-nodes to rows
+*/
#define __TREE_RETURN
#include "BStree.h"
typedef struct __this_data {
int data1;
int data2;
} this_data;
BSinode_list *BStrans_perm_in(BSspmat *A, BSnumbering *gnum,
BSnumbering *onum, BSdistribution *inode_distr, BSprocinfo *procinfo)
{
BStree tree;
BStree_ptr node_ptr;
this_data *data_ptr;
BSbb *row_bb;
int i, j;
int count;
BSsprow *row;
int *colptr;
int *addrs, *answs, *answs2, *answs3;
void (*map)(int,int *,int *,BSprocinfo *,BSmapping *);
void (*glmap)(int,int *,int *,BSprocinfo *,BSmapping *);
int num_cols;
int num_nz;
int cval, oval, lval, row_gval, ival;
int found;
BSinode_list *trans;
int max_row_len;
int *map_work;
/* set up requests */
num_nz = BSnonlocalnz(A,&max_row_len,procinfo); CHKERRN(0);
MY_MALLOCN(addrs,(int *),sizeof(int)*num_nz,1);
MY_MALLOCN(map_work,(int *),sizeof(int)*max_row_len,2);
count = 0;
map = A->map->fglobal2proc;
for (i=0;i<A->num_rows;i++) {
row = A->rows[i];
colptr = row->col;
(*map)(row->length,colptr,map_work,procinfo,A->map); CHKERRN(0);
for (j=0;j<row->length;j++) {
if (map_work[j] != procinfo->my_id) {
addrs[count] = colptr[j];
count++;
}
}
}
/* initialize BB */
row_bb = BSinit_bb(A->num_rows,A->map); CHKERRN(0);
/* query BB for inode numbers */
BSpost_noaddr_bb(row_bb,A->num_rows,gnum->numbers); CHKERRN(0);
MY_MALLOCN(answs,(int *),sizeof(int)*num_nz,2);
BSquery_match_bb(row_bb,count,addrs,answs,procinfo); CHKERRN(0);
/* query BB for inode lengths */
BSpost_noaddr_bb(row_bb,A->num_rows,inode_distr->distribution);
CHKERRN(0);
MY_MALLOCN(answs2,(int *),sizeof(int)*num_nz,2);
BSquery_match_bb(row_bb,count,addrs,answs2,procinfo); CHKERRN(0);
/* query BB for original inode numbers */
BSpost_noaddr_bb(row_bb,A->num_rows,onum->numbers); CHKERRN(0);
MY_MALLOCN(answs3,(int *),sizeof(int)*num_nz,3);
BSquery_match_bb(row_bb,count,addrs,answs3,procinfo); CHKERRN(0);
/* free up BB */
MY_FREEN(addrs);
BSfree_bb(row_bb); CHKERRN(0);
/* set up a dummy head pointer */
MY_INIT_TREE(tree,(2*sizeof(int)));
count = 0;
map = A->map->fglobal2proc;
glmap = A->map->fglobal2local;
num_cols = 0;
for (i=0;i<A->num_rows;i++) {
row = A->rows[i];
colptr = row->col;
row_gval = gnum->numbers[i];
(*map)(row->length,colptr,map_work,procinfo,A->map); CHKERRN(0);
for (j=0;j<row->length;j++) {
if (map_work[j] != procinfo->my_id) {
cval = answs[count];
ival = answs2[count];
oval = answs3[count];
count++;
} else {
(*glmap)(1,&(colptr[j]),&lval,procinfo,A->map); CHKERRN(0);
cval = gnum->numbers[lval];
ival = inode_distr->distribution[lval];
oval = onum->numbers[lval];
}
if(A->icc_storage) {
if (row_gval >= cval) {
/* check to see if the column is already there */
MY_INSERT_TREE_NODE(tree,cval,found,node_ptr,num_cols);
if (!found) {
data_ptr = (this_data *) MY_GET_TREE_DATA(node_ptr);
data_ptr->data1 = oval;
data_ptr->data2 = ival;
}
}
} else {
/* Do not need row_gval >= cval check for nonsymmetric case */
/* check to see if the column is already there */
MY_INSERT_TREE_NODE(tree,cval,found,node_ptr,num_cols);
if (!found) {
data_ptr = (this_data *) MY_GET_TREE_DATA(node_ptr);
data_ptr->data1 = oval;
data_ptr->data2 = ival;
}
}
}
}
MY_FREEN(map_work);
MY_FREEN(answs);
MY_FREEN(answs2);
MY_FREEN(answs3);
/* copy the linked list into the array structure */
MY_MALLOCN(trans,(BSinode_list *),sizeof(BSinode_list),5);
trans->length = num_cols;
MY_MALLOCN(trans->list,(BSinode *),sizeof(BSinode)*(num_cols+1),5);
trans->list[num_cols].gcol_num = INT_MAX;
MY_MALLOCN(trans->list[num_cols].o_gcol_num,(int *),sizeof(int),6);
trans->list[num_cols].o_gcol_num[0] = INT_MAX;
count = 0;
MY_FIRST_IN_TREE(tree,node_ptr);
while (! IS_TREE_PTR_NULL(node_ptr)) {
trans->list[count].gcol_num = MY_GET_TREE_KEY(node_ptr);
data_ptr = (this_data *) MY_GET_TREE_DATA(node_ptr);
trans->list[count].num_cols = data_ptr->data2;
MY_MALLOCN(trans->list[count].o_gcol_num,(int *),sizeof(int)*
data_ptr->data2,1);
trans->list[count].o_gcol_num[0] = data_ptr->data1;
count++;
MY_NEXT_IN_TREE(node_ptr);
}
MY_FREE_TREE(tree);
return(trans);
}
syntax highlighted by Code2HTML, v. 0.9.1