1827bd09bSSatish Balay 2827bd09bSSatish Balay /***********************************comm.c************************************* 3827bd09bSSatish Balay 4827bd09bSSatish Balay Author: Henry M. Tufo III 5827bd09bSSatish Balay 6827bd09bSSatish Balay e-mail: hmt@cs.brown.edu 7827bd09bSSatish Balay 8827bd09bSSatish Balay snail-mail: 9827bd09bSSatish Balay Division of Applied Mathematics 10827bd09bSSatish Balay Brown University 11827bd09bSSatish Balay Providence, RI 02912 12827bd09bSSatish Balay 13827bd09bSSatish Balay Last Modification: 14827bd09bSSatish Balay 11.21.97 15827bd09bSSatish Balay ***********************************comm.c*************************************/ 16c6db04a5SJed Brown #include <../src/ksp/pc/impls/tfs/tfs.h> 17827bd09bSSatish Balay 18827bd09bSSatish Balay 19827bd09bSSatish Balay /* global program control variables - explicitly exported */ 20b1c944f5SJed Brown PetscMPIInt PCTFS_my_id = 0; 21b1c944f5SJed Brown PetscMPIInt PCTFS_num_nodes = 1; 22b1c944f5SJed Brown PetscMPIInt PCTFS_floor_num_nodes = 0; 23b1c944f5SJed Brown PetscMPIInt PCTFS_i_log2_num_nodes = 0; 24827bd09bSSatish Balay 25827bd09bSSatish Balay /* global program control variables */ 2652f87cdaSBarry Smith static PetscInt p_init = 0; 2752f87cdaSBarry Smith static PetscInt modfl_num_nodes; 2852f87cdaSBarry Smith static PetscInt edge_not_pow_2; 29827bd09bSSatish Balay 3052f87cdaSBarry Smith static PetscInt edge_node[sizeof(PetscInt)*32]; 31827bd09bSSatish Balay 327b1ae94cSBarry Smith /***********************************comm.c*************************************/ 33b1c944f5SJed Brown PetscErrorCode PCTFS_comm_init (void) 34827bd09bSSatish Balay { 35827bd09bSSatish Balay 363fdc5746SBarry Smith if (p_init++) PetscFunctionReturn(0); 37827bd09bSSatish Balay 38b1c944f5SJed Brown MPI_Comm_size(MPI_COMM_WORLD,&PCTFS_num_nodes); 39b1c944f5SJed Brown MPI_Comm_rank(MPI_COMM_WORLD,&PCTFS_my_id); 40827bd09bSSatish Balay 41b1c944f5SJed Brown if (PCTFS_num_nodes> (INT_MAX >> 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Can't have more then MAX_INT/2 nodes!!!"); 42827bd09bSSatish Balay 43*ca8e9878SJed Brown PCTFS_ivec_zero((PetscInt*)edge_node,sizeof(PetscInt)*32); 44827bd09bSSatish Balay 45b1c944f5SJed Brown PCTFS_floor_num_nodes = 1; 46b1c944f5SJed Brown PCTFS_i_log2_num_nodes = modfl_num_nodes = 0; 47b1c944f5SJed Brown while (PCTFS_floor_num_nodes <= PCTFS_num_nodes) 48827bd09bSSatish Balay { 49b1c944f5SJed Brown edge_node[PCTFS_i_log2_num_nodes] = PCTFS_my_id ^ PCTFS_floor_num_nodes; 50b1c944f5SJed Brown PCTFS_floor_num_nodes <<= 1; 51b1c944f5SJed Brown PCTFS_i_log2_num_nodes++; 52827bd09bSSatish Balay } 53827bd09bSSatish Balay 54b1c944f5SJed Brown PCTFS_i_log2_num_nodes--; 55b1c944f5SJed Brown PCTFS_floor_num_nodes >>= 1; 56b1c944f5SJed Brown modfl_num_nodes = (PCTFS_num_nodes - PCTFS_floor_num_nodes); 57827bd09bSSatish Balay 58b1c944f5SJed Brown if ((PCTFS_my_id > 0) && (PCTFS_my_id <= modfl_num_nodes)) 59b1c944f5SJed Brown {edge_not_pow_2=((PCTFS_my_id|PCTFS_floor_num_nodes)-1);} 60b1c944f5SJed Brown else if (PCTFS_my_id >= PCTFS_floor_num_nodes) 61b1c944f5SJed Brown {edge_not_pow_2=((PCTFS_my_id^PCTFS_floor_num_nodes)+1); 62827bd09bSSatish Balay } 63827bd09bSSatish Balay else 64827bd09bSSatish Balay {edge_not_pow_2 = 0;} 653fdc5746SBarry Smith PetscFunctionReturn(0); 66827bd09bSSatish Balay } 67827bd09bSSatish Balay 687b1ae94cSBarry Smith /***********************************comm.c*************************************/ 69b1c944f5SJed Brown PetscErrorCode PCTFS_giop(PetscInt *vals, PetscInt *work, PetscInt n, PetscInt *oprs) 70827bd09bSSatish Balay { 713fdc5746SBarry Smith PetscInt mask, edge; 723fdc5746SBarry Smith PetscInt type, dest; 73827bd09bSSatish Balay vfp fp; 74827bd09bSSatish Balay MPI_Status status; 753fdc5746SBarry Smith PetscInt ierr; 76827bd09bSSatish Balay 773fdc5746SBarry Smith PetscFunctionBegin; 78827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 79b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 80827bd09bSSatish Balay 81827bd09bSSatish Balay /* non-uniform should have at least two entries */ 82b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: non_uniform and n=0,1?"); 83827bd09bSSatish Balay 84827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 85827bd09bSSatish Balay if (!p_init) 86b1c944f5SJed Brown {PCTFS_comm_init();} 87827bd09bSSatish Balay 88827bd09bSSatish Balay /* if there's nothing to do return */ 89b1c944f5SJed Brown if ((PCTFS_num_nodes<2)||(!n)) 90827bd09bSSatish Balay { 913fdc5746SBarry Smith PetscFunctionReturn(0); 92827bd09bSSatish Balay } 93827bd09bSSatish Balay 9471a0148aSBarry Smith 95827bd09bSSatish Balay /* a negative number if items to send ==> fatal */ 96b1c944f5SJed Brown if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: n=%D<0?",n); 97827bd09bSSatish Balay 98827bd09bSSatish Balay /* advance to list of n operations for custom */ 99827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 100827bd09bSSatish Balay {oprs++;} 101827bd09bSSatish Balay 102827bd09bSSatish Balay /* major league hack */ 103*ca8e9878SJed Brown if (!(fp = (vfp) PCTFS_ivec_fct_addr(type))) { 104b1c944f5SJed Brown ierr = PetscInfo(0,"PCTFS_giop() :: hope you passed in a rbfp!\n");CHKERRQ(ierr); 105827bd09bSSatish Balay fp = (vfp) oprs; 106827bd09bSSatish Balay } 107827bd09bSSatish Balay 108827bd09bSSatish Balay /* all msgs will be of the same length */ 109827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 110827bd09bSSatish Balay if (edge_not_pow_2) 111827bd09bSSatish Balay { 112b1c944f5SJed Brown if (PCTFS_my_id >= PCTFS_floor_num_nodes) 113b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_INT,edge_not_pow_2,MSGTAG0+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 114827bd09bSSatish Balay else 115827bd09bSSatish Balay { 1163fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRQ(ierr); 117827bd09bSSatish Balay (*fp)(vals,work,n,oprs); 118827bd09bSSatish Balay } 119827bd09bSSatish Balay } 120827bd09bSSatish Balay 121827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 122b1c944f5SJed Brown if (PCTFS_my_id<PCTFS_floor_num_nodes) 123827bd09bSSatish Balay { 124b1c944f5SJed Brown for (mask=1,edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask<<=1) 125827bd09bSSatish Balay { 126b1c944f5SJed Brown dest = PCTFS_my_id^mask; 127b1c944f5SJed Brown if (PCTFS_my_id > dest) 128b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 129827bd09bSSatish Balay else 130827bd09bSSatish Balay { 1313fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 132827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 133827bd09bSSatish Balay } 134827bd09bSSatish Balay } 135827bd09bSSatish Balay 136b1c944f5SJed Brown mask=PCTFS_floor_num_nodes>>1; 137b1c944f5SJed Brown for (edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask>>=1) 138827bd09bSSatish Balay { 139b1c944f5SJed Brown if (PCTFS_my_id%mask) 140827bd09bSSatish Balay {continue;} 141827bd09bSSatish Balay 142b1c944f5SJed Brown dest = PCTFS_my_id^mask; 143b1c944f5SJed Brown if (PCTFS_my_id < dest) 144b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 145827bd09bSSatish Balay else 146827bd09bSSatish Balay { 1473fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 148827bd09bSSatish Balay } 149827bd09bSSatish Balay } 150827bd09bSSatish Balay } 151827bd09bSSatish Balay 152827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 153827bd09bSSatish Balay if (edge_not_pow_2) 154827bd09bSSatish Balay { 155b1c944f5SJed Brown if (PCTFS_my_id >= PCTFS_floor_num_nodes) 156827bd09bSSatish Balay { 1573fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 158827bd09bSSatish Balay } 159827bd09bSSatish Balay else 160b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_INT,edge_not_pow_2,MSGTAG5+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 161827bd09bSSatish Balay } 1623fdc5746SBarry Smith PetscFunctionReturn(0); 163827bd09bSSatish Balay } 164827bd09bSSatish Balay 1657b1ae94cSBarry Smith /***********************************comm.c*************************************/ 166b1c944f5SJed Brown PetscErrorCode PCTFS_grop(PetscScalar *vals, PetscScalar *work, PetscInt n, PetscInt *oprs) 167827bd09bSSatish Balay { 1683fdc5746SBarry Smith PetscInt mask, edge; 1693fdc5746SBarry Smith PetscInt type, dest; 170827bd09bSSatish Balay vfp fp; 171827bd09bSSatish Balay MPI_Status status; 1723fdc5746SBarry Smith PetscErrorCode ierr; 173827bd09bSSatish Balay 1743fdc5746SBarry Smith PetscFunctionBegin; 175827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 176b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 177827bd09bSSatish Balay 178827bd09bSSatish Balay /* non-uniform should have at least two entries */ 179b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop() :: non_uniform and n=0,1?"); 180827bd09bSSatish Balay 181827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 182827bd09bSSatish Balay if (!p_init) 183b1c944f5SJed Brown {PCTFS_comm_init();} 184827bd09bSSatish Balay 185827bd09bSSatish Balay /* if there's nothing to do return */ 186b1c944f5SJed Brown if ((PCTFS_num_nodes<2)||(!n)) 1873fdc5746SBarry Smith { PetscFunctionReturn(0);} 188827bd09bSSatish Balay 189827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 190c1235816SBarry Smith if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"gdop() :: n=%D<0?",n); 191827bd09bSSatish Balay 192827bd09bSSatish Balay /* advance to list of n operations for custom */ 193827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 194827bd09bSSatish Balay {oprs++;} 195827bd09bSSatish Balay 196*ca8e9878SJed Brown if (!(fp = (vfp) PCTFS_rvec_fct_addr(type))) { 197b1c944f5SJed Brown ierr = PetscInfo(0,"PCTFS_grop() :: hope you passed in a rbfp!\n");CHKERRQ(ierr); 198827bd09bSSatish Balay fp = (vfp) oprs; 199827bd09bSSatish Balay } 200827bd09bSSatish Balay 201827bd09bSSatish Balay /* all msgs will be of the same length */ 202827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 203827bd09bSSatish Balay if (edge_not_pow_2) 204827bd09bSSatish Balay { 205b1c944f5SJed Brown if (PCTFS_my_id >= PCTFS_floor_num_nodes) 206b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_SCALAR,edge_not_pow_2,MSGTAG0+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 207827bd09bSSatish Balay else 208827bd09bSSatish Balay { 2093fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 210827bd09bSSatish Balay (*fp)(vals,work,n,oprs); 211827bd09bSSatish Balay } 212827bd09bSSatish Balay } 213827bd09bSSatish Balay 214827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 215b1c944f5SJed Brown if (PCTFS_my_id<PCTFS_floor_num_nodes) 216827bd09bSSatish Balay { 217b1c944f5SJed Brown for (mask=1,edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask<<=1) 218827bd09bSSatish Balay { 219b1c944f5SJed Brown dest = PCTFS_my_id^mask; 220b1c944f5SJed Brown if (PCTFS_my_id > dest) 221b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 222827bd09bSSatish Balay else 223827bd09bSSatish Balay { 2243fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 225827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 226827bd09bSSatish Balay } 227827bd09bSSatish Balay } 228827bd09bSSatish Balay 229b1c944f5SJed Brown mask=PCTFS_floor_num_nodes>>1; 230b1c944f5SJed Brown for (edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask>>=1) 231827bd09bSSatish Balay { 232b1c944f5SJed Brown if (PCTFS_my_id%mask) 233827bd09bSSatish Balay {continue;} 234827bd09bSSatish Balay 235b1c944f5SJed Brown dest = PCTFS_my_id^mask; 236b1c944f5SJed Brown if (PCTFS_my_id < dest) 237b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 238827bd09bSSatish Balay else 239827bd09bSSatish Balay { 2403fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 241827bd09bSSatish Balay } 242827bd09bSSatish Balay } 243827bd09bSSatish Balay } 244827bd09bSSatish Balay 245827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 246827bd09bSSatish Balay if (edge_not_pow_2) 247827bd09bSSatish Balay { 248b1c944f5SJed Brown if (PCTFS_my_id >= PCTFS_floor_num_nodes) 249827bd09bSSatish Balay { 2503fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRQ(ierr); 251827bd09bSSatish Balay } 252827bd09bSSatish Balay else 253b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_SCALAR,edge_not_pow_2,MSGTAG5+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 254827bd09bSSatish Balay } 2553fdc5746SBarry Smith PetscFunctionReturn(0); 256827bd09bSSatish Balay } 257827bd09bSSatish Balay 2587b1ae94cSBarry Smith /***********************************comm.c*************************************/ 259b1c944f5SJed Brown PetscErrorCode PCTFS_grop_hc(PetscScalar *vals, PetscScalar *work, PetscInt n, PetscInt *oprs, PetscInt dim) 260827bd09bSSatish Balay { 2613fdc5746SBarry Smith PetscInt mask, edge; 2623fdc5746SBarry Smith PetscInt type, dest; 263827bd09bSSatish Balay vfp fp; 264827bd09bSSatish Balay MPI_Status status; 2653fdc5746SBarry Smith PetscErrorCode ierr; 266827bd09bSSatish Balay 2673fdc5746SBarry Smith PetscFunctionBegin; 268827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 269b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 270827bd09bSSatish Balay 271827bd09bSSatish Balay /* non-uniform should have at least two entries */ 272b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: non_uniform and n=0,1?"); 273827bd09bSSatish Balay 274827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 275827bd09bSSatish Balay if (!p_init) 276b1c944f5SJed Brown {PCTFS_comm_init();} 277827bd09bSSatish Balay 278827bd09bSSatish Balay /* if there's nothing to do return */ 279b1c944f5SJed Brown if ((PCTFS_num_nodes<2)||(!n)||(dim<=0)) 2800924e98cSBarry Smith {PetscFunctionReturn(0);} 281827bd09bSSatish Balay 282827bd09bSSatish Balay /* the error msg says it all!!! */ 283b1c944f5SJed Brown if (modfl_num_nodes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: PCTFS_num_nodes not a power of 2!?!"); 284827bd09bSSatish Balay 285827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 286b1c944f5SJed Brown if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: n=%D<0?",n); 287827bd09bSSatish Balay 288827bd09bSSatish Balay /* can't do more dimensions then exist */ 289b1c944f5SJed Brown dim = PetscMin(dim,PCTFS_i_log2_num_nodes); 290827bd09bSSatish Balay 291827bd09bSSatish Balay /* advance to list of n operations for custom */ 292827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 293827bd09bSSatish Balay {oprs++;} 294827bd09bSSatish Balay 295*ca8e9878SJed Brown if (!(fp = (vfp) PCTFS_rvec_fct_addr(type))) { 296b1c944f5SJed Brown ierr = PetscInfo(0,"PCTFS_grop_hc() :: hope you passed in a rbfp!\n");CHKERRQ(ierr); 297827bd09bSSatish Balay fp = (vfp) oprs; 298827bd09bSSatish Balay } 299827bd09bSSatish Balay 300827bd09bSSatish Balay for (mask=1,edge=0; edge<dim; edge++,mask<<=1) 301827bd09bSSatish Balay { 302b1c944f5SJed Brown dest = PCTFS_my_id^mask; 303b1c944f5SJed Brown if (PCTFS_my_id > dest) 304b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 305827bd09bSSatish Balay else 306827bd09bSSatish Balay { 3073fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 308827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 309827bd09bSSatish Balay } 310827bd09bSSatish Balay } 311827bd09bSSatish Balay 312827bd09bSSatish Balay if (edge==dim) 313827bd09bSSatish Balay {mask>>=1;} 314827bd09bSSatish Balay else 315827bd09bSSatish Balay {while (++edge<dim) {mask<<=1;}} 316827bd09bSSatish Balay 317827bd09bSSatish Balay for (edge=0; edge<dim; edge++,mask>>=1) 318827bd09bSSatish Balay { 319b1c944f5SJed Brown if (PCTFS_my_id%mask) 320827bd09bSSatish Balay {continue;} 321827bd09bSSatish Balay 322b1c944f5SJed Brown dest = PCTFS_my_id^mask; 323b1c944f5SJed Brown if (PCTFS_my_id < dest) 324b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 325827bd09bSSatish Balay else 326827bd09bSSatish Balay { 3273fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 328827bd09bSSatish Balay } 329827bd09bSSatish Balay } 3303fdc5746SBarry Smith PetscFunctionReturn(0); 331827bd09bSSatish Balay } 332827bd09bSSatish Balay 3337b1ae94cSBarry Smith /******************************************************************************/ 334b1c944f5SJed Brown PetscErrorCode PCTFS_ssgl_radd( PetscScalar *vals, PetscScalar *work, PetscInt level, PetscInt *segs) 335827bd09bSSatish Balay { 3363fdc5746SBarry Smith PetscInt edge, type, dest, mask; 3373fdc5746SBarry Smith PetscInt stage_n; 338827bd09bSSatish Balay MPI_Status status; 3393fdc5746SBarry Smith PetscErrorCode ierr; 340827bd09bSSatish Balay 3413fdc5746SBarry Smith PetscFunctionBegin; 342827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 343827bd09bSSatish Balay if (!p_init) 344b1c944f5SJed Brown {PCTFS_comm_init();} 345827bd09bSSatish Balay 346827bd09bSSatish Balay 347827bd09bSSatish Balay /* all msgs are *NOT* the same length */ 348827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 349827bd09bSSatish Balay for (mask=0, edge=0; edge<level; edge++, mask++) 350827bd09bSSatish Balay { 351827bd09bSSatish Balay stage_n = (segs[level] - segs[edge]); 352b1c944f5SJed Brown if (stage_n && !(PCTFS_my_id & mask)) 353827bd09bSSatish Balay { 354827bd09bSSatish Balay dest = edge_node[edge]; 355b1c944f5SJed Brown type = MSGTAG3 + PCTFS_my_id + (PCTFS_num_nodes*edge); 356b1c944f5SJed Brown if (PCTFS_my_id>dest) 3573fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[edge],stage_n,MPIU_SCALAR,dest,type, MPI_COMM_WORLD);CHKERRQ(ierr);} 358827bd09bSSatish Balay else 359827bd09bSSatish Balay { 360b1c944f5SJed Brown type = type - PCTFS_my_id + dest; 3613fdc5746SBarry Smith ierr = MPI_Recv(work,stage_n,MPIU_SCALAR,MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 362*ca8e9878SJed Brown PCTFS_rvec_add(vals+segs[edge], work, stage_n); 363827bd09bSSatish Balay } 364827bd09bSSatish Balay } 365827bd09bSSatish Balay mask <<= 1; 366827bd09bSSatish Balay } 367827bd09bSSatish Balay mask>>=1; 368827bd09bSSatish Balay for (edge=0; edge<level; edge++) 369827bd09bSSatish Balay { 370827bd09bSSatish Balay stage_n = (segs[level] - segs[level-1-edge]); 371b1c944f5SJed Brown if (stage_n && !(PCTFS_my_id & mask)) 372827bd09bSSatish Balay { 373827bd09bSSatish Balay dest = edge_node[level-edge-1]; 374b1c944f5SJed Brown type = MSGTAG6 + PCTFS_my_id + (PCTFS_num_nodes*edge); 375b1c944f5SJed Brown if (PCTFS_my_id<dest) 3763fdc5746SBarry Smith {ierr = MPI_Send(vals+segs[level-1-edge],stage_n,MPIU_SCALAR,dest,type,MPI_COMM_WORLD);CHKERRQ(ierr);} 377827bd09bSSatish Balay else 378827bd09bSSatish Balay { 379b1c944f5SJed Brown type = type - PCTFS_my_id + dest; 3803fdc5746SBarry Smith ierr = MPI_Recv(vals+segs[level-1-edge],stage_n,MPIU_SCALAR, MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 381827bd09bSSatish Balay } 382827bd09bSSatish Balay } 383827bd09bSSatish Balay mask >>= 1; 384827bd09bSSatish Balay } 3853fdc5746SBarry Smith PetscFunctionReturn(0); 386827bd09bSSatish Balay } 387827bd09bSSatish Balay 3887b1ae94cSBarry Smith /***********************************comm.c*************************************/ 389b1c944f5SJed Brown PetscErrorCode PCTFS_giop_hc(PetscInt *vals, PetscInt *work, PetscInt n, PetscInt *oprs, PetscInt dim) 390827bd09bSSatish Balay { 39152f87cdaSBarry Smith PetscInt mask, edge; 39252f87cdaSBarry Smith PetscInt type, dest; 393827bd09bSSatish Balay vfp fp; 394827bd09bSSatish Balay MPI_Status status; 3953fdc5746SBarry Smith PetscErrorCode ierr; 396827bd09bSSatish Balay 3973fdc5746SBarry Smith PetscFunctionBegin; 398827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 399b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 400827bd09bSSatish Balay 401827bd09bSSatish Balay /* non-uniform should have at least two entries */ 402b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: non_uniform and n=0,1?"); 403827bd09bSSatish Balay 404827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 405827bd09bSSatish Balay if (!p_init) 406b1c944f5SJed Brown {PCTFS_comm_init();} 407827bd09bSSatish Balay 408827bd09bSSatish Balay /* if there's nothing to do return */ 409b1c944f5SJed Brown if ((PCTFS_num_nodes<2)||(!n)||(dim<=0)) 4103fdc5746SBarry Smith { PetscFunctionReturn(0);} 411827bd09bSSatish Balay 412827bd09bSSatish Balay /* the error msg says it all!!! */ 413b1c944f5SJed Brown if (modfl_num_nodes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: PCTFS_num_nodes not a power of 2!?!"); 414827bd09bSSatish Balay 415827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 416b1c944f5SJed Brown if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: n=%D<0?",n); 417827bd09bSSatish Balay 418827bd09bSSatish Balay /* can't do more dimensions then exist */ 419b1c944f5SJed Brown dim = PetscMin(dim,PCTFS_i_log2_num_nodes); 420827bd09bSSatish Balay 421827bd09bSSatish Balay /* advance to list of n operations for custom */ 422827bd09bSSatish Balay if ((type=oprs[0])==NON_UNIFORM) 423827bd09bSSatish Balay {oprs++;} 424827bd09bSSatish Balay 425*ca8e9878SJed Brown if (!(fp = (vfp) PCTFS_ivec_fct_addr(type))){ 426b1c944f5SJed Brown ierr = PetscInfo(0,"PCTFS_giop_hc() :: hope you passed in a rbfp!\n");CHKERRQ(ierr); 427827bd09bSSatish Balay fp = (vfp) oprs; 428827bd09bSSatish Balay } 429827bd09bSSatish Balay 430827bd09bSSatish Balay for (mask=1,edge=0; edge<dim; edge++,mask<<=1) 431827bd09bSSatish Balay { 432b1c944f5SJed Brown dest = PCTFS_my_id^mask; 433b1c944f5SJed Brown if (PCTFS_my_id > dest) 434b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 435827bd09bSSatish Balay else 436827bd09bSSatish Balay { 4373fdc5746SBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRQ(ierr); 438827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 439827bd09bSSatish Balay } 440827bd09bSSatish Balay } 441827bd09bSSatish Balay 442827bd09bSSatish Balay if (edge==dim) 443827bd09bSSatish Balay {mask>>=1;} 444827bd09bSSatish Balay else 445827bd09bSSatish Balay {while (++edge<dim) {mask<<=1;}} 446827bd09bSSatish Balay 447827bd09bSSatish Balay for (edge=0; edge<dim; edge++,mask>>=1) 448827bd09bSSatish Balay { 449b1c944f5SJed Brown if (PCTFS_my_id%mask) 450827bd09bSSatish Balay {continue;} 451827bd09bSSatish Balay 452b1c944f5SJed Brown dest = PCTFS_my_id^mask; 453b1c944f5SJed Brown if (PCTFS_my_id < dest) 454b1c944f5SJed Brown {ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRQ(ierr);} 455827bd09bSSatish Balay else 456827bd09bSSatish Balay { 4573fdc5746SBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD,&status);CHKERRQ(ierr); 458827bd09bSSatish Balay } 459827bd09bSSatish Balay } 4603fdc5746SBarry Smith PetscFunctionReturn(0); 461827bd09bSSatish Balay } 462