1dba47a55SKris Buschelman #define PETSCKSP_DLL 2827bd09bSSatish Balay 3827bd09bSSatish Balay /***********************************comm.c************************************* 4827bd09bSSatish Balay 5827bd09bSSatish Balay Author: Henry M. Tufo III 6827bd09bSSatish Balay 7827bd09bSSatish Balay e-mail: hmt@cs.brown.edu 8827bd09bSSatish Balay 9827bd09bSSatish Balay snail-mail: 10827bd09bSSatish Balay Division of Applied Mathematics 11827bd09bSSatish Balay Brown University 12827bd09bSSatish Balay Providence, RI 02912 13827bd09bSSatish Balay 14827bd09bSSatish Balay Last Modification: 15827bd09bSSatish Balay 11.21.97 16827bd09bSSatish Balay ***********************************comm.c*************************************/ 17827bd09bSSatish Balay 18827bd09bSSatish Balay /***********************************comm.c************************************* 19827bd09bSSatish Balay File Description: 20827bd09bSSatish Balay ----------------- 21827bd09bSSatish Balay 22827bd09bSSatish Balay ***********************************comm.c*************************************/ 237758a8cdSBarry Smith #include "src/ksp/pc/impls/tfs/tfs.h" 24827bd09bSSatish Balay 25827bd09bSSatish Balay 26827bd09bSSatish Balay /* global program control variables - explicitly exported */ 27827bd09bSSatish Balay int my_id = 0; 28827bd09bSSatish Balay int num_nodes = 1; 29827bd09bSSatish Balay int floor_num_nodes = 0; 30827bd09bSSatish Balay int i_log2_num_nodes = 0; 31827bd09bSSatish Balay 32827bd09bSSatish Balay /* global program control variables */ 33827bd09bSSatish Balay static int p_init = 0; 34827bd09bSSatish Balay static int modfl_num_nodes; 35827bd09bSSatish Balay static int edge_not_pow_2; 36827bd09bSSatish Balay 37a501084fSBarry Smith static unsigned int edge_node[sizeof(PetscInt)*32]; 38827bd09bSSatish Balay 39827bd09bSSatish Balay /***********************************comm.c************************************* 40827bd09bSSatish Balay Function: giop() 41827bd09bSSatish Balay 42827bd09bSSatish Balay Input : 43827bd09bSSatish Balay Output: 44827bd09bSSatish Balay Return: 45827bd09bSSatish Balay Description: 46827bd09bSSatish Balay ***********************************comm.c*************************************/ 47*0924e98cSBarry Smith PetscErrorCode comm_init (void) 48827bd09bSSatish Balay { 49827bd09bSSatish Balay 503fdc5746SBarry Smith if (p_init++) PetscFunctionReturn(0); 51827bd09bSSatish Balay 52827bd09bSSatish Balay MPI_Comm_size(MPI_COMM_WORLD,&num_nodes); 53827bd09bSSatish Balay MPI_Comm_rank(MPI_COMM_WORLD,&my_id); 54827bd09bSSatish Balay 55827bd09bSSatish Balay if (num_nodes> (INT_MAX >> 1)) 56827bd09bSSatish Balay {error_msg_fatal("Can't have more then MAX_INT/2 nodes!!!");} 57827bd09bSSatish Balay 583fdc5746SBarry Smith ivec_zero((PetscInt*)edge_node,sizeof(PetscInt)*32); 59827bd09bSSatish Balay 60827bd09bSSatish Balay floor_num_nodes = 1; 61827bd09bSSatish Balay i_log2_num_nodes = modfl_num_nodes = 0; 62827bd09bSSatish Balay while (floor_num_nodes <= num_nodes) 63827bd09bSSatish Balay { 64827bd09bSSatish Balay edge_node[i_log2_num_nodes] = my_id ^ floor_num_nodes; 65827bd09bSSatish Balay floor_num_nodes <<= 1; 66827bd09bSSatish Balay i_log2_num_nodes++; 67827bd09bSSatish Balay } 68827bd09bSSatish Balay 69827bd09bSSatish Balay i_log2_num_nodes--; 70827bd09bSSatish Balay floor_num_nodes >>= 1; 71827bd09bSSatish Balay modfl_num_nodes = (num_nodes - floor_num_nodes); 72827bd09bSSatish Balay 73827bd09bSSatish Balay if ((my_id > 0) && (my_id <= modfl_num_nodes)) 74827bd09bSSatish Balay {edge_not_pow_2=((my_id|floor_num_nodes)-1);} 75827bd09bSSatish Balay else if (my_id >= floor_num_nodes) 76827bd09bSSatish Balay {edge_not_pow_2=((my_id^floor_num_nodes)+1); 77827bd09bSSatish Balay } 78827bd09bSSatish Balay else 79827bd09bSSatish Balay {edge_not_pow_2 = 0;} 803fdc5746SBarry Smith PetscFunctionReturn(0); 81827bd09bSSatish Balay } 82827bd09bSSatish Balay 83827bd09bSSatish Balay 84827bd09bSSatish Balay 85827bd09bSSatish Balay /***********************************comm.c************************************* 86827bd09bSSatish Balay Function: giop() 87827bd09bSSatish Balay 88827bd09bSSatish Balay Input : 89827bd09bSSatish Balay Output: 90827bd09bSSatish Balay Return: 91827bd09bSSatish Balay Description: fan-in/out version 92827bd09bSSatish Balay ***********************************comm.c*************************************/ 93*0924e98cSBarry Smith PetscErrorCode giop(PetscInt *vals, PetscInt *work, PetscInt n, PetscInt *oprs) 94827bd09bSSatish Balay { 953fdc5746SBarry Smith PetscInt mask, edge; 963fdc5746SBarry Smith PetscInt type, dest; 97827bd09bSSatish Balay vfp fp; 98827bd09bSSatish Balay MPI_Status status; 993fdc5746SBarry Smith PetscInt ierr; 100827bd09bSSatish Balay 1013fdc5746SBarry Smith PetscFunctionBegin; 102827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 103827bd09bSSatish Balay if (!vals||!work||!oprs) 10477431f27SBarry Smith {error_msg_fatal("giop() :: vals=%D, work=%D, oprs=%D",vals,work,oprs);} 105827bd09bSSatish Balay 106827bd09bSSatish Balay /* non-uniform should have at least two entries */ 107827bd09bSSatish Balay if ((oprs[0] == NON_UNIFORM)&&(n<2)) 108827bd09bSSatish Balay {error_msg_fatal("giop() :: non_uniform and n=0,1?");} 109827bd09bSSatish Balay 110827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 111827bd09bSSatish Balay if (!p_init) 112827bd09bSSatish Balay {comm_init();} 113827bd09bSSatish Balay 114827bd09bSSatish Balay /* if there's nothing to do return */ 115827bd09bSSatish Balay if ((num_nodes<2)||(!n)) 116827bd09bSSatish Balay { 1173fdc5746SBarry Smith PetscFunctionReturn(0); 118827bd09bSSatish Balay } 119827bd09bSSatish Balay 120827bd09bSSatish Balay /* a negative number if items to send ==> fatal */ 121827bd09bSSatish Balay if (n<0) 12277431f27SBarry Smith {error_msg_fatal("giop() :: n=%D<0?",n);} 123827bd09bSSatish Balay 124827bd09bSSatish Balay /* advance to list of n operations for custom */ 125827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 126827bd09bSSatish Balay {oprs++;} 127827bd09bSSatish Balay 128827bd09bSSatish Balay /* major league hack */ 129d890fc11SSatish Balay if (!(fp = (vfp) ivec_fct_addr(type))) { 130827bd09bSSatish Balay error_msg_warning("giop() :: hope you passed in a rbfp!\n"); 131827bd09bSSatish Balay fp = (vfp) oprs; 132827bd09bSSatish Balay } 133827bd09bSSatish Balay 134827bd09bSSatish Balay /* all msgs will be of the same length */ 135827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 136827bd09bSSatish Balay if (edge_not_pow_2) 137827bd09bSSatish Balay { 138827bd09bSSatish Balay if (my_id >= floor_num_nodes) 1393fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_INT,edge_not_pow_2,MSGTAG0+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 140827bd09bSSatish Balay else 141827bd09bSSatish Balay { 1423fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRQ(ierr); 143827bd09bSSatish Balay (*fp)(vals,work,n,oprs); 144827bd09bSSatish Balay } 145827bd09bSSatish Balay } 146827bd09bSSatish Balay 147827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 148827bd09bSSatish Balay if (my_id<floor_num_nodes) 149827bd09bSSatish Balay { 150827bd09bSSatish Balay for (mask=1,edge=0; edge<i_log2_num_nodes; edge++,mask<<=1) 151827bd09bSSatish Balay { 152827bd09bSSatish Balay dest = my_id^mask; 153827bd09bSSatish Balay if (my_id > dest) 1543fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG2+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 155827bd09bSSatish Balay else 156827bd09bSSatish Balay { 1573fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 158827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 159827bd09bSSatish Balay } 160827bd09bSSatish Balay } 161827bd09bSSatish Balay 162827bd09bSSatish Balay mask=floor_num_nodes>>1; 163827bd09bSSatish Balay for (edge=0; edge<i_log2_num_nodes; edge++,mask>>=1) 164827bd09bSSatish Balay { 165827bd09bSSatish Balay if (my_id%mask) 166827bd09bSSatish Balay {continue;} 167827bd09bSSatish Balay 168827bd09bSSatish Balay dest = my_id^mask; 169827bd09bSSatish Balay if (my_id < dest) 1703fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG4+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 171827bd09bSSatish Balay else 172827bd09bSSatish Balay { 1733fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 174827bd09bSSatish Balay } 175827bd09bSSatish Balay } 176827bd09bSSatish Balay } 177827bd09bSSatish Balay 178827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 179827bd09bSSatish Balay if (edge_not_pow_2) 180827bd09bSSatish Balay { 181827bd09bSSatish Balay if (my_id >= floor_num_nodes) 182827bd09bSSatish Balay { 1833fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 184827bd09bSSatish Balay } 185827bd09bSSatish Balay else 1863fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_INT,edge_not_pow_2,MSGTAG5+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 187827bd09bSSatish Balay } 1883fdc5746SBarry Smith PetscFunctionReturn(0); 189827bd09bSSatish Balay } 190827bd09bSSatish Balay 191827bd09bSSatish Balay /***********************************comm.c************************************* 192827bd09bSSatish Balay Function: grop() 193827bd09bSSatish Balay 194827bd09bSSatish Balay Input : 195827bd09bSSatish Balay Output: 196827bd09bSSatish Balay Return: 197827bd09bSSatish Balay Description: fan-in/out version 198827bd09bSSatish Balay ***********************************comm.c*************************************/ 199*0924e98cSBarry Smith PetscErrorCode grop(PetscScalar *vals, PetscScalar *work, PetscInt n, int *oprs) 200827bd09bSSatish Balay { 2013fdc5746SBarry Smith PetscInt mask, edge; 2023fdc5746SBarry Smith PetscInt type, dest; 203827bd09bSSatish Balay vfp fp; 204827bd09bSSatish Balay MPI_Status status; 2053fdc5746SBarry Smith PetscErrorCode ierr; 206827bd09bSSatish Balay 2073fdc5746SBarry Smith PetscFunctionBegin; 208827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 209827bd09bSSatish Balay if (!vals||!work||!oprs) 21077431f27SBarry Smith {error_msg_fatal("grop() :: vals=%D, work=%D, oprs=%D",vals,work,oprs);} 211827bd09bSSatish Balay 212827bd09bSSatish Balay /* non-uniform should have at least two entries */ 213827bd09bSSatish Balay if ((oprs[0] == NON_UNIFORM)&&(n<2)) 214827bd09bSSatish Balay {error_msg_fatal("grop() :: non_uniform and n=0,1?");} 215827bd09bSSatish Balay 216827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 217827bd09bSSatish Balay if (!p_init) 218827bd09bSSatish Balay {comm_init();} 219827bd09bSSatish Balay 220827bd09bSSatish Balay /* if there's nothing to do return */ 221827bd09bSSatish Balay if ((num_nodes<2)||(!n)) 2223fdc5746SBarry Smith { PetscFunctionReturn(0);} 223827bd09bSSatish Balay 224827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 225827bd09bSSatish Balay if (n<0) 22677431f27SBarry Smith {error_msg_fatal("gdop() :: n=%D<0?",n);} 227827bd09bSSatish Balay 228827bd09bSSatish Balay /* advance to list of n operations for custom */ 229827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 230827bd09bSSatish Balay {oprs++;} 231827bd09bSSatish Balay 232d890fc11SSatish Balay if (!(fp = (vfp) rvec_fct_addr(type))) { 233827bd09bSSatish Balay error_msg_warning("grop() :: hope you passed in a rbfp!\n"); 234827bd09bSSatish Balay fp = (vfp) oprs; 235827bd09bSSatish Balay } 236827bd09bSSatish Balay 237827bd09bSSatish Balay /* all msgs will be of the same length */ 238827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 239827bd09bSSatish Balay if (edge_not_pow_2) 240827bd09bSSatish Balay { 241827bd09bSSatish Balay if (my_id >= floor_num_nodes) 2423fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_SCALAR,edge_not_pow_2,MSGTAG0+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 243827bd09bSSatish Balay else 244827bd09bSSatish Balay { 2453fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 246827bd09bSSatish Balay (*fp)(vals,work,n,oprs); 247827bd09bSSatish Balay } 248827bd09bSSatish Balay } 249827bd09bSSatish Balay 250827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 251827bd09bSSatish Balay if (my_id<floor_num_nodes) 252827bd09bSSatish Balay { 253827bd09bSSatish Balay for (mask=1,edge=0; edge<i_log2_num_nodes; edge++,mask<<=1) 254827bd09bSSatish Balay { 255827bd09bSSatish Balay dest = my_id^mask; 256827bd09bSSatish Balay if (my_id > dest) 2573fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG2+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 258827bd09bSSatish Balay else 259827bd09bSSatish Balay { 2603fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 261827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 262827bd09bSSatish Balay } 263827bd09bSSatish Balay } 264827bd09bSSatish Balay 265827bd09bSSatish Balay mask=floor_num_nodes>>1; 266827bd09bSSatish Balay for (edge=0; edge<i_log2_num_nodes; edge++,mask>>=1) 267827bd09bSSatish Balay { 268827bd09bSSatish Balay if (my_id%mask) 269827bd09bSSatish Balay {continue;} 270827bd09bSSatish Balay 271827bd09bSSatish Balay dest = my_id^mask; 272827bd09bSSatish Balay if (my_id < dest) 2733fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG4+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 274827bd09bSSatish Balay else 275827bd09bSSatish Balay { 2763fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 277827bd09bSSatish Balay } 278827bd09bSSatish Balay } 279827bd09bSSatish Balay } 280827bd09bSSatish Balay 281827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 282827bd09bSSatish Balay if (edge_not_pow_2) 283827bd09bSSatish Balay { 284827bd09bSSatish Balay if (my_id >= floor_num_nodes) 285827bd09bSSatish Balay { 2863fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRQ(ierr); 287827bd09bSSatish Balay } 288827bd09bSSatish Balay else 2893fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_SCALAR,edge_not_pow_2,MSGTAG5+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 290827bd09bSSatish Balay } 2913fdc5746SBarry Smith PetscFunctionReturn(0); 292827bd09bSSatish Balay } 293827bd09bSSatish Balay 294827bd09bSSatish Balay 295827bd09bSSatish Balay /***********************************comm.c************************************* 296827bd09bSSatish Balay Function: grop() 297827bd09bSSatish Balay 298827bd09bSSatish Balay Input : 299827bd09bSSatish Balay Output: 300827bd09bSSatish Balay Return: 301827bd09bSSatish Balay Description: fan-in/out version 302827bd09bSSatish Balay 303827bd09bSSatish Balay note good only for num_nodes=2^k!!! 304827bd09bSSatish Balay 305827bd09bSSatish Balay ***********************************comm.c*************************************/ 306*0924e98cSBarry Smith PetscErrorCode grop_hc(PetscScalar *vals, PetscScalar *work, PetscInt n, int *oprs, PetscInt dim) 307827bd09bSSatish Balay { 3083fdc5746SBarry Smith PetscInt mask, edge; 3093fdc5746SBarry Smith PetscInt type, dest; 310827bd09bSSatish Balay vfp fp; 311827bd09bSSatish Balay MPI_Status status; 3123fdc5746SBarry Smith PetscErrorCode ierr; 313827bd09bSSatish Balay 3143fdc5746SBarry Smith PetscFunctionBegin; 315827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 316827bd09bSSatish Balay if (!vals||!work||!oprs) 31777431f27SBarry Smith {error_msg_fatal("grop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs);} 318827bd09bSSatish Balay 319827bd09bSSatish Balay /* non-uniform should have at least two entries */ 320827bd09bSSatish Balay if ((oprs[0] == NON_UNIFORM)&&(n<2)) 321827bd09bSSatish Balay {error_msg_fatal("grop_hc() :: non_uniform and n=0,1?");} 322827bd09bSSatish Balay 323827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 324827bd09bSSatish Balay if (!p_init) 325827bd09bSSatish Balay {comm_init();} 326827bd09bSSatish Balay 327827bd09bSSatish Balay /* if there's nothing to do return */ 328827bd09bSSatish Balay if ((num_nodes<2)||(!n)||(dim<=0)) 329*0924e98cSBarry Smith {PetscFunctionReturn(0);} 330827bd09bSSatish Balay 331827bd09bSSatish Balay /* the error msg says it all!!! */ 332827bd09bSSatish Balay if (modfl_num_nodes) 333827bd09bSSatish Balay {error_msg_fatal("grop_hc() :: num_nodes not a power of 2!?!");} 334827bd09bSSatish Balay 335827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 336827bd09bSSatish Balay if (n<0) 33777431f27SBarry Smith {error_msg_fatal("grop_hc() :: n=%D<0?",n);} 338827bd09bSSatish Balay 339827bd09bSSatish Balay /* can't do more dimensions then exist */ 34039945688SSatish Balay dim = PetscMin(dim,i_log2_num_nodes); 341827bd09bSSatish Balay 342827bd09bSSatish Balay /* advance to list of n operations for custom */ 343827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 344827bd09bSSatish Balay {oprs++;} 345827bd09bSSatish Balay 346d890fc11SSatish Balay if (!(fp = (vfp) rvec_fct_addr(type))) { 347827bd09bSSatish Balay error_msg_warning("grop_hc() :: hope you passed in a rbfp!\n"); 348827bd09bSSatish Balay fp = (vfp) oprs; 349827bd09bSSatish Balay } 350827bd09bSSatish Balay 351827bd09bSSatish Balay for (mask=1,edge=0; edge<dim; edge++,mask<<=1) 352827bd09bSSatish Balay { 353827bd09bSSatish Balay dest = my_id^mask; 354827bd09bSSatish Balay if (my_id > dest) 3553fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG2+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 356827bd09bSSatish Balay else 357827bd09bSSatish Balay { 3583fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 359827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 360827bd09bSSatish Balay } 361827bd09bSSatish Balay } 362827bd09bSSatish Balay 363827bd09bSSatish Balay if (edge==dim) 364827bd09bSSatish Balay {mask>>=1;} 365827bd09bSSatish Balay else 366827bd09bSSatish Balay {while (++edge<dim) {mask<<=1;}} 367827bd09bSSatish Balay 368827bd09bSSatish Balay for (edge=0; edge<dim; edge++,mask>>=1) 369827bd09bSSatish Balay { 370827bd09bSSatish Balay if (my_id%mask) 371827bd09bSSatish Balay {continue;} 372827bd09bSSatish Balay 373827bd09bSSatish Balay dest = my_id^mask; 374827bd09bSSatish Balay if (my_id < dest) 3753fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG4+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 376827bd09bSSatish Balay else 377827bd09bSSatish Balay { 3783fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 379827bd09bSSatish Balay } 380827bd09bSSatish Balay } 3813fdc5746SBarry Smith PetscFunctionReturn(0); 382827bd09bSSatish Balay } 383827bd09bSSatish Balay 384827bd09bSSatish Balay 385827bd09bSSatish Balay /***********************************comm.c************************************* 386827bd09bSSatish Balay Function: gop() 387827bd09bSSatish Balay 388827bd09bSSatish Balay Input : 389827bd09bSSatish Balay Output: 390827bd09bSSatish Balay Return: 391827bd09bSSatish Balay Description: fan-in/out version 392827bd09bSSatish Balay ***********************************comm.c*************************************/ 3933fdc5746SBarry Smith PetscErrorCode gfop(void *vals, void *work, PetscInt n, vbfp fp, MPI_Datatype dt, int comm_type) 394827bd09bSSatish Balay { 3953fdc5746SBarry Smith PetscInt mask, edge; 3963fdc5746SBarry Smith PetscInt dest; 397827bd09bSSatish Balay MPI_Status status; 398827bd09bSSatish Balay MPI_Op op; 3993fdc5746SBarry Smith PetscErrorCode ierr; 400827bd09bSSatish Balay 4013fdc5746SBarry Smith PetscFunctionBegin; 402827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 403827bd09bSSatish Balay if (!p_init) 404827bd09bSSatish Balay {comm_init();} 405827bd09bSSatish Balay 406827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 407827bd09bSSatish Balay if (!vals||!work||!fp) 40877431f27SBarry Smith {error_msg_fatal("gop() :: v=%D, w=%D, f=%D",vals,work,fp);} 409827bd09bSSatish Balay 410827bd09bSSatish Balay /* if there's nothing to do return */ 411827bd09bSSatish Balay if ((num_nodes<2)||(!n)) 4123fdc5746SBarry Smith {CHKERRQ(ierr);} 413827bd09bSSatish Balay 414827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 415827bd09bSSatish Balay if (n<0) 41677431f27SBarry Smith {error_msg_fatal("gop() :: n=%D<0?",n);} 417827bd09bSSatish Balay 418827bd09bSSatish Balay if (comm_type==MPI) 419827bd09bSSatish Balay { 4203fdc5746SBarry Smith ierr = MPI_Op_create(fp,TRUE,&op);CHKERRQ(ierr); 4213fdc5746SBarry Smith ierr = MPI_Allreduce (vals, work, n, dt, op, MPI_COMM_WORLD);CHKERRQ(ierr); 4223fdc5746SBarry Smith ierr = MPI_Op_free(&op);CHKERRQ(ierr); 4233fdc5746SBarry Smith CHKERRQ(ierr); 424827bd09bSSatish Balay } 425827bd09bSSatish Balay 426827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 427827bd09bSSatish Balay if (edge_not_pow_2) 428827bd09bSSatish Balay { 429827bd09bSSatish Balay if (my_id >= floor_num_nodes) 4303fdc5746SBarry Smith {ierr = MPI_Send(vals,n,dt,edge_not_pow_2,MSGTAG0+my_id, MPI_COMM_WORLD);CHKERRQ(ierr);} 431827bd09bSSatish Balay else 432827bd09bSSatish Balay { 4333fdc5746SBarry Smith ierr = MPI_Recv(work,n,dt,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 434827bd09bSSatish Balay (*fp)(vals,work,&n,&dt); 435827bd09bSSatish Balay } 436827bd09bSSatish Balay } 437827bd09bSSatish Balay 438827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 439827bd09bSSatish Balay if (my_id<floor_num_nodes) 440827bd09bSSatish Balay { 441827bd09bSSatish Balay for (mask=1,edge=0; edge<i_log2_num_nodes; edge++,mask<<=1) 442827bd09bSSatish Balay { 443827bd09bSSatish Balay dest = my_id^mask; 444827bd09bSSatish Balay if (my_id > dest) 4453fdc5746SBarry Smith {ierr = MPI_Send(vals,n,dt,dest,MSGTAG2+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 446827bd09bSSatish Balay else 447827bd09bSSatish Balay { 4483fdc5746SBarry Smith ierr = MPI_Recv(work,n,dt,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 449827bd09bSSatish Balay (*fp)(vals, work, &n, &dt); 450827bd09bSSatish Balay } 451827bd09bSSatish Balay } 452827bd09bSSatish Balay 453827bd09bSSatish Balay mask=floor_num_nodes>>1; 454827bd09bSSatish Balay for (edge=0; edge<i_log2_num_nodes; edge++,mask>>=1) 455827bd09bSSatish Balay { 456827bd09bSSatish Balay if (my_id%mask) 457827bd09bSSatish Balay {continue;} 458827bd09bSSatish Balay 459827bd09bSSatish Balay dest = my_id^mask; 460827bd09bSSatish Balay if (my_id < dest) 4613fdc5746SBarry Smith {ierr = MPI_Send(vals,n,dt,dest,MSGTAG4+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 462827bd09bSSatish Balay else 463827bd09bSSatish Balay { 4643fdc5746SBarry Smith ierr = MPI_Recv(vals,n,dt,MPI_ANY_SOURCE,MSGTAG4+dest, MPI_COMM_WORLD, &status);CHKERRQ(ierr); 465827bd09bSSatish Balay } 466827bd09bSSatish Balay } 467827bd09bSSatish Balay } 468827bd09bSSatish Balay 469827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 470827bd09bSSatish Balay if (edge_not_pow_2) 471827bd09bSSatish Balay { 472827bd09bSSatish Balay if (my_id >= floor_num_nodes) 473827bd09bSSatish Balay { 4743fdc5746SBarry Smith ierr = MPI_Recv(vals,n,dt,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRQ(ierr); 475827bd09bSSatish Balay } 476827bd09bSSatish Balay else 4773fdc5746SBarry Smith {ierr = MPI_Send(vals,n,dt,edge_not_pow_2,MSGTAG5+my_id, MPI_COMM_WORLD);CHKERRQ(ierr);} 478827bd09bSSatish Balay } 4793fdc5746SBarry Smith PetscFunctionReturn(0); 480827bd09bSSatish Balay } 481827bd09bSSatish Balay 482827bd09bSSatish Balay 483827bd09bSSatish Balay 484827bd09bSSatish Balay 485827bd09bSSatish Balay 486827bd09bSSatish Balay 487827bd09bSSatish Balay /****************************************************************************** 488827bd09bSSatish Balay Function: giop() 489827bd09bSSatish Balay 490827bd09bSSatish Balay Input : 491827bd09bSSatish Balay Output: 492827bd09bSSatish Balay Return: 493827bd09bSSatish Balay Description: 494827bd09bSSatish Balay 495827bd09bSSatish Balay ii+1 entries in seg :: 0 .. ii 496827bd09bSSatish Balay 497827bd09bSSatish Balay ******************************************************************************/ 498*0924e98cSBarry Smith PetscErrorCode ssgl_radd( PetscScalar *vals, PetscScalar *work, PetscInt level, PetscInt *segs) 499827bd09bSSatish Balay { 5003fdc5746SBarry Smith PetscInt edge, type, dest, mask; 5013fdc5746SBarry Smith PetscInt stage_n; 502827bd09bSSatish Balay MPI_Status status; 5033fdc5746SBarry Smith PetscErrorCode ierr; 504827bd09bSSatish Balay 5053fdc5746SBarry Smith PetscFunctionBegin; 506827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 507827bd09bSSatish Balay if (!p_init) 508827bd09bSSatish Balay {comm_init();} 509827bd09bSSatish Balay 510827bd09bSSatish Balay 511827bd09bSSatish Balay /* all msgs are *NOT* the same length */ 512827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 513827bd09bSSatish Balay for (mask=0, edge=0; edge<level; edge++, mask++) 514827bd09bSSatish Balay { 515827bd09bSSatish Balay stage_n = (segs[level] - segs[edge]); 516827bd09bSSatish Balay if (stage_n && !(my_id & mask)) 517827bd09bSSatish Balay { 518827bd09bSSatish Balay dest = edge_node[edge]; 519827bd09bSSatish Balay type = MSGTAG3 + my_id + (num_nodes*edge); 520827bd09bSSatish Balay if (my_id>dest) 5213fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[edge],stage_n,MPIU_SCALAR,dest,type, MPI_COMM_WORLD);CHKERRQ(ierr);} 522827bd09bSSatish Balay else 523827bd09bSSatish Balay { 524827bd09bSSatish Balay type = type - my_id + dest; 5253fdc5746SBarry Smith ierr = MPI_Recv(work,stage_n,MPIU_SCALAR,MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 526827bd09bSSatish Balay rvec_add(vals+segs[edge], work, stage_n); 527827bd09bSSatish Balay } 528827bd09bSSatish Balay } 529827bd09bSSatish Balay mask <<= 1; 530827bd09bSSatish Balay } 531827bd09bSSatish Balay mask>>=1; 532827bd09bSSatish Balay for (edge=0; edge<level; edge++) 533827bd09bSSatish Balay { 534827bd09bSSatish Balay stage_n = (segs[level] - segs[level-1-edge]); 535827bd09bSSatish Balay if (stage_n && !(my_id & mask)) 536827bd09bSSatish Balay { 537827bd09bSSatish Balay dest = edge_node[level-edge-1]; 538827bd09bSSatish Balay type = MSGTAG6 + my_id + (num_nodes*edge); 539827bd09bSSatish Balay if (my_id<dest) 5403fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[level-1-edge],stage_n,MPIU_SCALAR,dest,type,MPI_COMM_WORLD);CHKERRQ(ierr);} 541827bd09bSSatish Balay else 542827bd09bSSatish Balay { 543827bd09bSSatish Balay type = type - my_id + dest; 5443fdc5746SBarry Smith ierr = MPI_Recv(vals+segs[level-1-edge],stage_n,MPIU_SCALAR, MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 545827bd09bSSatish Balay } 546827bd09bSSatish Balay } 547827bd09bSSatish Balay mask >>= 1; 548827bd09bSSatish Balay } 5493fdc5746SBarry Smith PetscFunctionReturn(0); 550827bd09bSSatish Balay } 551827bd09bSSatish Balay 552827bd09bSSatish Balay 553827bd09bSSatish Balay 554827bd09bSSatish Balay /***********************************comm.c************************************* 555827bd09bSSatish Balay Function: grop_hc_vvl() 556827bd09bSSatish Balay 557827bd09bSSatish Balay Input : 558827bd09bSSatish Balay Output: 559827bd09bSSatish Balay Return: 560827bd09bSSatish Balay Description: fan-in/out version 561827bd09bSSatish Balay 562827bd09bSSatish Balay note good only for num_nodes=2^k!!! 563827bd09bSSatish Balay 564827bd09bSSatish Balay ***********************************comm.c*************************************/ 565*0924e98cSBarry Smith PetscErrorCode grop_hc_vvl(PetscScalar *vals, PetscScalar *work, PetscInt *segs, PetscInt *oprs, PetscInt dim) 566827bd09bSSatish Balay { 5673fdc5746SBarry Smith PetscInt mask, edge, n; 5683fdc5746SBarry Smith PetscInt type, dest; 569827bd09bSSatish Balay vfp fp; 570827bd09bSSatish Balay MPI_Status status; 5713fdc5746SBarry Smith PetscErrorCode ierr; 572827bd09bSSatish Balay 5733fdc5746SBarry Smith PetscFunctionBegin; 574827bd09bSSatish Balay error_msg_fatal("grop_hc_vvl() :: is not working!\n"); 575827bd09bSSatish Balay 576827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 577827bd09bSSatish Balay if (!vals||!work||!oprs||!segs) 57877431f27SBarry Smith {error_msg_fatal("grop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs);} 579827bd09bSSatish Balay 580827bd09bSSatish Balay /* non-uniform should have at least two entries */ 581827bd09bSSatish Balay 582827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 583827bd09bSSatish Balay if (!p_init) 584827bd09bSSatish Balay {comm_init();} 585827bd09bSSatish Balay 586827bd09bSSatish Balay /* if there's nothing to do return */ 587827bd09bSSatish Balay if ((num_nodes<2)||(dim<=0)) 5883fdc5746SBarry Smith {PetscFunctionReturn(0);} 589827bd09bSSatish Balay 590827bd09bSSatish Balay /* the error msg says it all!!! */ 591827bd09bSSatish Balay if (modfl_num_nodes) 592827bd09bSSatish Balay {error_msg_fatal("grop_hc() :: num_nodes not a power of 2!?!");} 593827bd09bSSatish Balay 594827bd09bSSatish Balay /* can't do more dimensions then exist */ 59539945688SSatish Balay dim = PetscMin(dim,i_log2_num_nodes); 596827bd09bSSatish Balay 597827bd09bSSatish Balay /* advance to list of n operations for custom */ 598827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 599827bd09bSSatish Balay {oprs++;} 600827bd09bSSatish Balay 601d890fc11SSatish Balay if (!(fp = (vfp) rvec_fct_addr(type))){ 602827bd09bSSatish Balay error_msg_warning("grop_hc() :: hope you passed in a rbfp!\n"); 603827bd09bSSatish Balay fp = (vfp) oprs; 604827bd09bSSatish Balay } 605827bd09bSSatish Balay 606827bd09bSSatish Balay for (mask=1,edge=0; edge<dim; edge++,mask<<=1) 607827bd09bSSatish Balay { 608827bd09bSSatish Balay n = segs[dim]-segs[edge]; 609827bd09bSSatish Balay dest = my_id^mask; 610827bd09bSSatish Balay if (my_id > dest) 6113fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[edge],n,MPIU_SCALAR,dest,MSGTAG2+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 612827bd09bSSatish Balay else 613827bd09bSSatish Balay { 6143fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 615827bd09bSSatish Balay (*fp)(vals+segs[edge], work, n, oprs); 616827bd09bSSatish Balay } 617827bd09bSSatish Balay } 618827bd09bSSatish Balay 619827bd09bSSatish Balay if (edge==dim) 620827bd09bSSatish Balay {mask>>=1;} 621827bd09bSSatish Balay else 622827bd09bSSatish Balay {while (++edge<dim) {mask<<=1;}} 623827bd09bSSatish Balay 624827bd09bSSatish Balay for (edge=0; edge<dim; edge++,mask>>=1) 625827bd09bSSatish Balay { 626827bd09bSSatish Balay if (my_id%mask) 627827bd09bSSatish Balay {continue;} 628827bd09bSSatish Balay 629827bd09bSSatish Balay n = (segs[dim]-segs[dim-1-edge]); 630827bd09bSSatish Balay 631827bd09bSSatish Balay dest = my_id^mask; 632827bd09bSSatish Balay if (my_id < dest) 6333fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[dim-1-edge],n,MPIU_SCALAR,dest,MSGTAG4+my_id, MPI_COMM_WORLD);CHKERRQ(ierr);} 634827bd09bSSatish Balay else 635827bd09bSSatish Balay { 6363fdc5746SBarry Smith ierr = MPI_Recv(vals+segs[dim-1-edge],n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 637827bd09bSSatish Balay } 638827bd09bSSatish Balay } 6393fdc5746SBarry Smith PetscFunctionReturn(0); 640827bd09bSSatish Balay } 641827bd09bSSatish Balay 642827bd09bSSatish Balay /****************************************************************************** 643827bd09bSSatish Balay Function: giop() 644827bd09bSSatish Balay 645827bd09bSSatish Balay Input : 646827bd09bSSatish Balay Output: 647827bd09bSSatish Balay Return: 648827bd09bSSatish Balay Description: 649827bd09bSSatish Balay 650827bd09bSSatish Balay ii+1 entries in seg :: 0 .. ii 651827bd09bSSatish Balay 652827bd09bSSatish Balay ******************************************************************************/ 6533fdc5746SBarry Smith PetscErrorCode new_ssgl_radd( PetscScalar *vals, PetscScalar *work, int level, int *segs) 654827bd09bSSatish Balay { 655a501084fSBarry Smith int edge, type, dest, mask; 656a501084fSBarry Smith int stage_n; 657827bd09bSSatish Balay MPI_Status status; 6583fdc5746SBarry Smith PetscErrorCode ierr; 659827bd09bSSatish Balay 6603fdc5746SBarry Smith PetscFunctionBegin; 661827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 662827bd09bSSatish Balay if (!p_init) 663827bd09bSSatish Balay {comm_init();} 664827bd09bSSatish Balay 665827bd09bSSatish Balay /* all msgs are *NOT* the same length */ 666827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 667827bd09bSSatish Balay for (mask=0, edge=0; edge<level; edge++, mask++) 668827bd09bSSatish Balay { 669827bd09bSSatish Balay stage_n = (segs[level] - segs[edge]); 670827bd09bSSatish Balay if (stage_n && !(my_id & mask)) 671827bd09bSSatish Balay { 672827bd09bSSatish Balay dest = edge_node[edge]; 673827bd09bSSatish Balay type = MSGTAG3 + my_id + (num_nodes*edge); 674827bd09bSSatish Balay if (my_id>dest) 6753fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[edge],stage_n,MPIU_SCALAR,dest,type, MPI_COMM_WORLD);CHKERRQ(ierr);} 676827bd09bSSatish Balay else 677827bd09bSSatish Balay { 678827bd09bSSatish Balay type = type - my_id + dest; 6793fdc5746SBarry Smith ierr = MPI_Recv(work,stage_n,MPIU_SCALAR,MPI_ANY_SOURCE,type, MPI_COMM_WORLD,&status);CHKERRQ(ierr); 680827bd09bSSatish Balay rvec_add(vals+segs[edge], work, stage_n); 681827bd09bSSatish Balay } 682827bd09bSSatish Balay } 683827bd09bSSatish Balay mask <<= 1; 684827bd09bSSatish Balay } 685827bd09bSSatish Balay mask>>=1; 686827bd09bSSatish Balay for (edge=0; edge<level; edge++) 687827bd09bSSatish Balay { 688827bd09bSSatish Balay stage_n = (segs[level] - segs[level-1-edge]); 689827bd09bSSatish Balay if (stage_n && !(my_id & mask)) 690827bd09bSSatish Balay { 691827bd09bSSatish Balay dest = edge_node[level-edge-1]; 692827bd09bSSatish Balay type = MSGTAG6 + my_id + (num_nodes*edge); 693827bd09bSSatish Balay if (my_id<dest) 6943fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[level-1-edge],stage_n,MPIU_SCALAR,dest,type,MPI_COMM_WORLD);CHKERRQ(ierr);} 695827bd09bSSatish Balay else 696827bd09bSSatish Balay { 697827bd09bSSatish Balay type = type - my_id + dest; 6983fdc5746SBarry Smith ierr = MPI_Recv(vals+segs[level-1-edge],stage_n,MPIU_SCALAR, MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 699827bd09bSSatish Balay } 700827bd09bSSatish Balay } 701827bd09bSSatish Balay mask >>= 1; 702827bd09bSSatish Balay } 7033fdc5746SBarry Smith PetscFunctionReturn(0); 704827bd09bSSatish Balay } 705827bd09bSSatish Balay 706827bd09bSSatish Balay 707827bd09bSSatish Balay 708827bd09bSSatish Balay /***********************************comm.c************************************* 709827bd09bSSatish Balay Function: giop() 710827bd09bSSatish Balay 711827bd09bSSatish Balay Input : 712827bd09bSSatish Balay Output: 713827bd09bSSatish Balay Return: 714827bd09bSSatish Balay Description: fan-in/out version 715827bd09bSSatish Balay 716827bd09bSSatish Balay note good only for num_nodes=2^k!!! 717827bd09bSSatish Balay 718827bd09bSSatish Balay ***********************************comm.c*************************************/ 7193fdc5746SBarry Smith PetscErrorCode giop_hc(int *vals, int *work, int n, int *oprs, int dim) 720827bd09bSSatish Balay { 721a501084fSBarry Smith int mask, edge; 722827bd09bSSatish Balay int type, dest; 723827bd09bSSatish Balay vfp fp; 724827bd09bSSatish Balay MPI_Status status; 7253fdc5746SBarry Smith PetscErrorCode ierr; 726827bd09bSSatish Balay 7273fdc5746SBarry Smith PetscFunctionBegin; 728827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 729827bd09bSSatish Balay if (!vals||!work||!oprs) 73077431f27SBarry Smith {error_msg_fatal("giop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs);} 731827bd09bSSatish Balay 732827bd09bSSatish Balay /* non-uniform should have at least two entries */ 733827bd09bSSatish Balay if ((oprs[0] == NON_UNIFORM)&&(n<2)) 734827bd09bSSatish Balay {error_msg_fatal("giop_hc() :: non_uniform and n=0,1?");} 735827bd09bSSatish Balay 736827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 737827bd09bSSatish Balay if (!p_init) 738827bd09bSSatish Balay {comm_init();} 739827bd09bSSatish Balay 740827bd09bSSatish Balay /* if there's nothing to do return */ 741827bd09bSSatish Balay if ((num_nodes<2)||(!n)||(dim<=0)) 7423fdc5746SBarry Smith { PetscFunctionReturn(0);} 743827bd09bSSatish Balay 744827bd09bSSatish Balay /* the error msg says it all!!! */ 745827bd09bSSatish Balay if (modfl_num_nodes) 746827bd09bSSatish Balay {error_msg_fatal("giop_hc() :: num_nodes not a power of 2!?!");} 747827bd09bSSatish Balay 748827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 749827bd09bSSatish Balay if (n<0) 75077431f27SBarry Smith {error_msg_fatal("giop_hc() :: n=%D<0?",n);} 751827bd09bSSatish Balay 752827bd09bSSatish Balay /* can't do more dimensions then exist */ 75339945688SSatish Balay dim = PetscMin(dim,i_log2_num_nodes); 754827bd09bSSatish Balay 755827bd09bSSatish Balay /* advance to list of n operations for custom */ 756827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 757827bd09bSSatish Balay {oprs++;} 758827bd09bSSatish Balay 759d890fc11SSatish Balay if (!(fp = (vfp) ivec_fct_addr(type))){ 760827bd09bSSatish Balay error_msg_warning("giop_hc() :: hope you passed in a rbfp!\n"); 761827bd09bSSatish Balay fp = (vfp) oprs; 762827bd09bSSatish Balay } 763827bd09bSSatish Balay 764827bd09bSSatish Balay for (mask=1,edge=0; edge<dim; edge++,mask<<=1) 765827bd09bSSatish Balay { 766827bd09bSSatish Balay dest = my_id^mask; 767827bd09bSSatish Balay if (my_id > dest) 7683fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG2+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 769827bd09bSSatish Balay else 770827bd09bSSatish Balay { 7713fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 772827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 773827bd09bSSatish Balay } 774827bd09bSSatish Balay } 775827bd09bSSatish Balay 776827bd09bSSatish Balay if (edge==dim) 777827bd09bSSatish Balay {mask>>=1;} 778827bd09bSSatish Balay else 779827bd09bSSatish Balay {while (++edge<dim) {mask<<=1;}} 780827bd09bSSatish Balay 781827bd09bSSatish Balay for (edge=0; edge<dim; edge++,mask>>=1) 782827bd09bSSatish Balay { 783827bd09bSSatish Balay if (my_id%mask) 784827bd09bSSatish Balay {continue;} 785827bd09bSSatish Balay 786827bd09bSSatish Balay dest = my_id^mask; 787827bd09bSSatish Balay if (my_id < dest) 7883fdc5746SBarry Smith {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG4+my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 789827bd09bSSatish Balay else 790827bd09bSSatish Balay { 7913fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 792827bd09bSSatish Balay } 793827bd09bSSatish Balay } 7943fdc5746SBarry Smith PetscFunctionReturn(0); 795827bd09bSSatish Balay } 796