#include "BSprivate.h"
/*@ BSsetup_forward - Set up the communication structure for triangular
matrix solution
Input Parameters:
. A - a sparse matrix
. procinfo - the usual processor stuff
Returns:
the communication structure for triangular matrix solution
@*/
BScomm *BSsetup_forward(BSpar_mat *A, BSprocinfo *procinfo)
{
BMcomp_msg *to_msg, *from_msg;
BMphase *phase_ptr;
BMmsg *msg;
int i, j, k;
int cl_ind, tcl_ind, cur_proc;
int count, size;
int *setup_data, *user_data;
BScl_2_inode *clique2inode;
BSnumbering *color2clique;
BSinode *inodes;
BScomm *comm_ptr;
int *data, data_len, ind, *perm;
void (*map)(int,int *,int *,BSprocinfo *,BSmapping *);
/* initialize communication structures */
to_msg = BMcomp_init(COMP_MSG_BASE); CHKERRN(0);
from_msg = BMcomp_init(COMP_MSG_BASE); CHKERRN(0);
/* now go through and figure out everyone that we need stuff from */
/* do it by color, where each color is a phase */
color2clique = A->color2clique;
clique2inode = A->clique2inode;
inodes = A->inodes->list;
for (i=0;i<color2clique->length-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,MY_MPI_FLT,cur_proc); CHKERRN(0);
BMadd_msg(from_msg,msg,procinfo); CHKERRN(0);
MY_MALLOCN(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); CHKERRN(0);
MY_MALLOCN(setup_data,(int *),sizeof(int)*size,1);
count = 0;
while (count < size) {
for (j=clique2inode->inode_index[cl_ind];
j<clique2inode->inode_index[cl_ind+1];j++) {
for (k=0;k<inodes[j].num_cols;k++) {
setup_data[count] = inodes[j].o_gcol_num[k];
count++;
}
}
cl_ind++;
}
BMset_setup_data(msg,setup_data,size,BSfree_comm_data);
CHKERRN(0);
BMset_msg_size(msg,size); CHKERRN(0);
}
cl_ind = tcl_ind;
}
/* now, let's work out what I need to send */
phase_ptr = BMget_phase(from_msg,i); CHKERRN(0);
count = BMfix_send(SETUP_FORWARD_MSG,COMP_MSG_BASE,MY_MPI_FLT,to_msg,
phase_ptr,BSfree_comm_data,procinfo); CHKERRN(0);
/* now free up the setup data */
msg = NULL;
while ((msg = BMnext_msg(phase_ptr,msg)) != NULL) {
CHKERRN(0);
BMfree_setup_data(msg);
CHKERRN(0);
}
CHKERRN(0);
}
/* now, go over the messages that I have to send and translate the */
/* user data */
map = A->map->fglobal2local;
perm = A->perm->perm;
for (i=0;i<color2clique->length-1;i++) {
phase_ptr = BMget_phase(to_msg,i); CHKERRN(0);
msg = NULL;
while ((msg = BMnext_msg(phase_ptr,msg)) != NULL) {
CHKERRN(0);
data = BMget_user(msg,&data_len); CHKERRN(0);
BMset_msg_size(msg,data_len); CHKERRN(0);
for (j=0;j<data_len;j++) {
(*map)(1,&(data[j]),&ind,procinfo,A->map); CHKERRN(0);
data[j] = perm[ind];
}
}
CHKERRN(0);
}
/* organize the messages */
BMalloc_msg(to_msg); CHKERRN(0);
BMalloc_msg(from_msg); CHKERRN(0);
MY_MALLOCN(comm_ptr,(BScomm *),sizeof(BScomm),1);
comm_ptr->num_rhs = 1;
comm_ptr->to_msg = to_msg;
comm_ptr->from_msg = from_msg;
return(comm_ptr);
}
syntax highlighted by Code2HTML, v. 0.9.1