#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;inum_rows;i++) { row = A->rows[i]; colptr = row->col; (*map)(row->length,colptr,map_work,procinfo,A->map); CHKERRN(0); for (j=0;jlength;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;inum_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;jlength;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); }