#include "BSprivate.h" /*+ BSorig_inode - Change the inode structure to include the original, unpermuted i-node numbers Input Parameters: . A - the sparse matrix . procinfo - the usual processor stuff Output Parameters: . A - the sparse matrix changed to include the original i-node numbers Returns: void +*/ void BSorig_inode(BSpar_mat *A, BSprocinfo *procinfo) { BMcomp_msg *to_msg, *from_msg; BMphase *phase_ptr, *to_phase, *from_phase; BMmsg *msg; int i, j, k; int cl_ind, tcl_ind, cur_proc, in_ind; int count, size; int last; int *setup_data, *user_data; BScl_2_inode *clique2inode; BSnumbering *color2clique; BSinode *inodes; int local_num; int *msg_buf, *data_ptr, msg_len; int *data, data_len, ind, *perm, *iperm; void (*map)(int,int *,int *,BSprocinfo *,BSmapping *); void (*lmap)(int,int *,int *,BSprocinfo *,BSmapping *); /* initialize communication structures */ to_msg = BMcomp_init(COMP_MSG_BASE); CHKERR(0); from_msg = BMcomp_init(COMP_MSG_BASE); CHKERR(0); /* initialize variables for ease of use */ map = A->map->fglobal2local; lmap = A->map->flocal2global; perm = A->perm->perm; iperm = A->inv_perm->perm; color2clique = A->color2clique; clique2inode = A->clique2inode; inodes = A->inodes->list; /* now go through and figure out everyone that we need stuff from */ /* do it by color, where each color is a phase */ for (i=0;ilength-1;i++) { cl_ind = color2clique->numbers[i]; while (cl_ind < color2clique->numbers[i+1]) { /* figure out the message size and destination */ cur_proc = clique2inode->proc[cl_ind]; tcl_ind = cl_ind; size = 0; while ((tcl_ind < color2clique->numbers[i+1]) && (cur_proc == clique2inode->proc[tcl_ind])) { /* add in the lengths, nonlocals are negative */ size += abs(clique2inode->d_mats[tcl_ind].size); tcl_ind++; } if (cur_proc != procinfo->my_id) { /* now we know the message size, allocate the message, etc */ msg = BMcreate_msg(i,-1,MPI_INT,cur_proc); CHKERR(0); BMadd_msg(from_msg,msg,procinfo); CHKERR(0); MY_MALLOC(user_data,(int *),sizeof(int)*2,1); user_data[0] = cl_ind; user_data[1] = tcl_ind-1; BMset_user_data(msg,user_data,2,BSfree_comm_data); CHKERR(0); MY_MALLOC(setup_data,(int *),sizeof(int)*size,1); count = 0; while (count < size) { for (j=clique2inode->inode_index[cl_ind]; jinode_index[cl_ind+1];j++) { setup_data[count] = inodes[j].o_gcol_num[0]; count++; for (k=1;kinode_index[cl_ind]; jinode_index[cl_ind+1];j++) { (*map)(1,&(inodes[j].o_gcol_num[0]),&ind,procinfo, A->map); CHKERR(0); last = perm[ind]+1; for (k=1;kmap); CHKERR(0); inodes[j].o_gcol_num[k] = ind; last++; } } } } } /* now, let's work out what I need to send */ phase_ptr = BMget_phase(from_msg,i); CHKERR(0); count = BMfix_send(SETUP_ORIGINAL_MSG,COMP_MSG_BASE,MPI_INT,to_msg, phase_ptr,BSfree_comm_data,procinfo); CHKERR(0); /* now free up the setup data */ msg = NULL; while ((msg = BMnext_msg(phase_ptr,msg)) != NULL) { CHKERR(0); BMfree_setup_data(msg); CHKERR(0); } CHKERR(0); } /* now, go over the messages that I have to send and translate the */ /* user data */ for (i=0;ilength-1;i++) { phase_ptr = BMget_phase(to_msg,i); CHKERR(0); msg = NULL; while ((msg = BMnext_msg(phase_ptr,msg)) != NULL) { CHKERR(0); data = BMget_user(msg,&data_len); BMset_msg_size(msg,data_len); CHKERR(0); last = -1; for (j=0;jmap); CHKERR(0); data[j] = ind; last++; } else { (*map)(1,&(data[j]),&ind,procinfo,A->map); CHKERR(0); last = perm[ind]+1; } } } CHKERR(0); } /* organize the messages */ BMalloc_msg(to_msg); CHKERR(0); BMalloc_msg(from_msg); CHKERR(0); /* now send and receive the true info */ BMinit_comp_msg(from_msg,procinfo); CHKERR(0); for (i=0;ilength-1;i++) { /* send messages */ to_phase = BMget_phase(to_msg,i); CHKERR(0); msg = NULL; while ((msg = BMnext_msg(to_phase,msg)) != NULL) { CHKERR(0); msg_buf = (int *) BMget_msg_ptr(msg); CHKERR(0); data_ptr = BMget_user(msg,&msg_len); CHKERR(0); for (j=0;jinode_index[cl_ind]; in_indinode_index[cl_ind+1];in_ind++) { for (j=0;j