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 /* global program control variables - explicitly exported */ 19b1c944f5SJed Brown PetscMPIInt PCTFS_my_id = 0; 20b1c944f5SJed Brown PetscMPIInt PCTFS_num_nodes = 1; 21b1c944f5SJed Brown PetscMPIInt PCTFS_floor_num_nodes = 0; 22b1c944f5SJed Brown PetscMPIInt PCTFS_i_log2_num_nodes = 0; 23827bd09bSSatish Balay 24827bd09bSSatish Balay /* global program control variables */ 2552f87cdaSBarry Smith static PetscInt p_init = 0; 2652f87cdaSBarry Smith static PetscInt modfl_num_nodes; 2752f87cdaSBarry Smith static PetscInt edge_not_pow_2; 28827bd09bSSatish Balay 2952f87cdaSBarry Smith static PetscInt edge_node[sizeof(PetscInt)*32]; 30827bd09bSSatish Balay 317b1ae94cSBarry Smith /***********************************comm.c*************************************/ 32b1c944f5SJed Brown PetscErrorCode PCTFS_comm_init(void) 33827bd09bSSatish Balay { 34362febeeSStefano Zampini PetscFunctionBegin; 353fdc5746SBarry Smith if (p_init++) PetscFunctionReturn(0); 36827bd09bSSatish Balay 37b1c944f5SJed Brown MPI_Comm_size(MPI_COMM_WORLD,&PCTFS_num_nodes); 38b1c944f5SJed Brown MPI_Comm_rank(MPI_COMM_WORLD,&PCTFS_my_id); 39827bd09bSSatish Balay 40b1c944f5SJed Brown if (PCTFS_num_nodes> (INT_MAX >> 1)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Can't have more then MAX_INT/2 nodes!!!"); 41827bd09bSSatish Balay 42ca8e9878SJed Brown PCTFS_ivec_zero((PetscInt*)edge_node,sizeof(PetscInt)*32); 43827bd09bSSatish Balay 44b1c944f5SJed Brown PCTFS_floor_num_nodes = 1; 45b1c944f5SJed Brown PCTFS_i_log2_num_nodes = modfl_num_nodes = 0; 46db4deed7SKarl Rupp while (PCTFS_floor_num_nodes <= PCTFS_num_nodes) { 47b1c944f5SJed Brown edge_node[PCTFS_i_log2_num_nodes] = PCTFS_my_id ^ PCTFS_floor_num_nodes; 48b1c944f5SJed Brown PCTFS_floor_num_nodes <<= 1; 49b1c944f5SJed Brown PCTFS_i_log2_num_nodes++; 50827bd09bSSatish Balay } 51827bd09bSSatish Balay 52b1c944f5SJed Brown PCTFS_i_log2_num_nodes--; 53b1c944f5SJed Brown PCTFS_floor_num_nodes >>= 1; 54b1c944f5SJed Brown modfl_num_nodes = (PCTFS_num_nodes - PCTFS_floor_num_nodes); 55827bd09bSSatish Balay 562fa5cd67SKarl Rupp if ((PCTFS_my_id > 0) && (PCTFS_my_id <= modfl_num_nodes)) edge_not_pow_2=((PCTFS_my_id|PCTFS_floor_num_nodes)-1); 572fa5cd67SKarl Rupp else if (PCTFS_my_id >= PCTFS_floor_num_nodes) edge_not_pow_2=((PCTFS_my_id^PCTFS_floor_num_nodes)+1); 582fa5cd67SKarl Rupp else edge_not_pow_2 = 0; 593fdc5746SBarry Smith PetscFunctionReturn(0); 60827bd09bSSatish Balay } 61827bd09bSSatish Balay 627b1ae94cSBarry Smith /***********************************comm.c*************************************/ 63b1c944f5SJed Brown PetscErrorCode PCTFS_giop(PetscInt *vals, PetscInt *work, PetscInt n, PetscInt *oprs) 64827bd09bSSatish Balay { 653fdc5746SBarry Smith PetscInt mask, edge; 663fdc5746SBarry Smith PetscInt type, dest; 67827bd09bSSatish Balay vfp fp; 68827bd09bSSatish Balay MPI_Status status; 693fdc5746SBarry Smith PetscInt ierr; 70827bd09bSSatish Balay 713fdc5746SBarry Smith PetscFunctionBegin; 72827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 73b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 74827bd09bSSatish Balay 75827bd09bSSatish Balay /* non-uniform should have at least two entries */ 76b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: non_uniform and n=0,1?"); 77827bd09bSSatish Balay 78827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 792fa5cd67SKarl Rupp if (!p_init) PCTFS_comm_init(); 80827bd09bSSatish Balay 81827bd09bSSatish Balay /* if there's nothing to do return */ 822fa5cd67SKarl Rupp if ((PCTFS_num_nodes<2)||(!n)) PetscFunctionReturn(0); 8371a0148aSBarry Smith 84827bd09bSSatish Balay /* a negative number if items to send ==> fatal */ 85b1c944f5SJed Brown if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: n=%D<0?",n); 86827bd09bSSatish Balay 87827bd09bSSatish Balay /* advance to list of n operations for custom */ 882fa5cd67SKarl Rupp if ((type=oprs[0])==NON_UNIFORM) oprs++; 89827bd09bSSatish Balay 90827bd09bSSatish Balay /* major league hack */ 91546078acSJacob Faibussowitsch if (!(fp = (vfp) PCTFS_ivec_fct_addr(type))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop() :: Could not retrieve function pointer!"); 92827bd09bSSatish Balay 93827bd09bSSatish Balay /* all msgs will be of the same length */ 94827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 95db4deed7SKarl Rupp if (edge_not_pow_2) { 962fa5cd67SKarl Rupp if (PCTFS_my_id >= PCTFS_floor_num_nodes) { 97ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_INT,edge_not_pow_2,MSGTAG0+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 982fa5cd67SKarl Rupp } else { 99ffc4695bSBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 100827bd09bSSatish Balay (*fp)(vals,work,n,oprs); 101827bd09bSSatish Balay } 102827bd09bSSatish Balay } 103827bd09bSSatish Balay 104827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 105db4deed7SKarl Rupp if (PCTFS_my_id<PCTFS_floor_num_nodes) { 106db4deed7SKarl Rupp for (mask=1,edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask<<=1) { 107b1c944f5SJed Brown dest = PCTFS_my_id^mask; 1082fa5cd67SKarl Rupp if (PCTFS_my_id > dest) { 109ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 1102fa5cd67SKarl Rupp } else { 111ffc4695bSBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRMPI(ierr); 112827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 113827bd09bSSatish Balay } 114827bd09bSSatish Balay } 115827bd09bSSatish Balay 116b1c944f5SJed Brown mask=PCTFS_floor_num_nodes>>1; 117db4deed7SKarl Rupp for (edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask>>=1) { 1182fa5cd67SKarl Rupp if (PCTFS_my_id%mask) continue; 119827bd09bSSatish Balay 120b1c944f5SJed Brown dest = PCTFS_my_id^mask; 1212fa5cd67SKarl Rupp if (PCTFS_my_id < dest) { 122ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 1232fa5cd67SKarl Rupp } else { 124ffc4695bSBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRMPI(ierr); 125827bd09bSSatish Balay } 126827bd09bSSatish Balay } 127827bd09bSSatish Balay } 128827bd09bSSatish Balay 129827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 130db4deed7SKarl Rupp if (edge_not_pow_2) { 1312fa5cd67SKarl Rupp if (PCTFS_my_id >= PCTFS_floor_num_nodes) { 132ffc4695bSBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 1332fa5cd67SKarl Rupp } else { 134ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_INT,edge_not_pow_2,MSGTAG5+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 135827bd09bSSatish Balay } 136827bd09bSSatish Balay } 1373fdc5746SBarry Smith PetscFunctionReturn(0); 138827bd09bSSatish Balay } 139827bd09bSSatish Balay 1407b1ae94cSBarry Smith /***********************************comm.c*************************************/ 141b1c944f5SJed Brown PetscErrorCode PCTFS_grop(PetscScalar *vals, PetscScalar *work, PetscInt n, PetscInt *oprs) 142827bd09bSSatish Balay { 1433fdc5746SBarry Smith PetscInt mask, edge; 1443fdc5746SBarry Smith PetscInt type, dest; 145827bd09bSSatish Balay vfp fp; 146827bd09bSSatish Balay MPI_Status status; 1473fdc5746SBarry Smith PetscErrorCode ierr; 148827bd09bSSatish Balay 1493fdc5746SBarry Smith PetscFunctionBegin; 150827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 151b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 152827bd09bSSatish Balay 153827bd09bSSatish Balay /* non-uniform should have at least two entries */ 154b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop() :: non_uniform and n=0,1?"); 155827bd09bSSatish Balay 156827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 1572fa5cd67SKarl Rupp if (!p_init) PCTFS_comm_init(); 158827bd09bSSatish Balay 159827bd09bSSatish Balay /* if there's nothing to do return */ 1602fa5cd67SKarl Rupp if ((PCTFS_num_nodes<2)||(!n)) PetscFunctionReturn(0); 161827bd09bSSatish Balay 162827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 163c1235816SBarry Smith if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"gdop() :: n=%D<0?",n); 164827bd09bSSatish Balay 165827bd09bSSatish Balay /* advance to list of n operations for custom */ 1662fa5cd67SKarl Rupp if ((type=oprs[0])==NON_UNIFORM) oprs++; 167827bd09bSSatish Balay 168546078acSJacob Faibussowitsch if (!(fp = (vfp) PCTFS_rvec_fct_addr(type))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop() :: Could not retrieve function pointer!"); 169827bd09bSSatish Balay 170827bd09bSSatish Balay /* all msgs will be of the same length */ 171827bd09bSSatish Balay /* if not a hypercube must colapse partial dim */ 1722fa5cd67SKarl Rupp if (edge_not_pow_2) { 1732fa5cd67SKarl Rupp if (PCTFS_my_id >= PCTFS_floor_num_nodes) { 174ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_SCALAR,edge_not_pow_2,MSGTAG0+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 1752fa5cd67SKarl Rupp } else { 176ffc4695bSBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG0+edge_not_pow_2,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 177827bd09bSSatish Balay (*fp)(vals,work,n,oprs); 178827bd09bSSatish Balay } 179827bd09bSSatish Balay } 180827bd09bSSatish Balay 181827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 182db4deed7SKarl Rupp if (PCTFS_my_id<PCTFS_floor_num_nodes) { 183db4deed7SKarl Rupp for (mask=1,edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask<<=1) { 184b1c944f5SJed Brown dest = PCTFS_my_id^mask; 1852fa5cd67SKarl Rupp if (PCTFS_my_id > dest) { 186ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 1872fa5cd67SKarl Rupp } else { 188ffc4695bSBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRMPI(ierr); 189827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 190827bd09bSSatish Balay } 191827bd09bSSatish Balay } 192827bd09bSSatish Balay 193b1c944f5SJed Brown mask=PCTFS_floor_num_nodes>>1; 194db4deed7SKarl Rupp for (edge=0; edge<PCTFS_i_log2_num_nodes; edge++,mask>>=1) { 1952fa5cd67SKarl Rupp if (PCTFS_my_id%mask) continue; 196827bd09bSSatish Balay 197b1c944f5SJed Brown dest = PCTFS_my_id^mask; 1982fa5cd67SKarl Rupp if (PCTFS_my_id < dest) { 199ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 2002fa5cd67SKarl Rupp } else { 201ffc4695bSBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD, &status);CHKERRMPI(ierr); 202827bd09bSSatish Balay } 203827bd09bSSatish Balay } 204827bd09bSSatish Balay } 205827bd09bSSatish Balay 206827bd09bSSatish Balay /* if not a hypercube must expand to partial dim */ 207db4deed7SKarl Rupp if (edge_not_pow_2) { 208db4deed7SKarl Rupp if (PCTFS_my_id >= PCTFS_floor_num_nodes) { 209ffc4695bSBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG5+edge_not_pow_2, MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 210db4deed7SKarl Rupp } else { 211ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_SCALAR,edge_not_pow_2,MSGTAG5+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 212827bd09bSSatish Balay } 213827bd09bSSatish Balay } 2143fdc5746SBarry Smith PetscFunctionReturn(0); 215827bd09bSSatish Balay } 216827bd09bSSatish Balay 2177b1ae94cSBarry Smith /***********************************comm.c*************************************/ 218b1c944f5SJed Brown PetscErrorCode PCTFS_grop_hc(PetscScalar *vals, PetscScalar *work, PetscInt n, PetscInt *oprs, PetscInt dim) 219827bd09bSSatish Balay { 2203fdc5746SBarry Smith PetscInt mask, edge; 2213fdc5746SBarry Smith PetscInt type, dest; 222827bd09bSSatish Balay vfp fp; 223827bd09bSSatish Balay MPI_Status status; 2243fdc5746SBarry Smith PetscErrorCode ierr; 225827bd09bSSatish Balay 2263fdc5746SBarry Smith PetscFunctionBegin; 227827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 228b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 229827bd09bSSatish Balay 230827bd09bSSatish Balay /* non-uniform should have at least two entries */ 231b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: non_uniform and n=0,1?"); 232827bd09bSSatish Balay 233827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 2342fa5cd67SKarl Rupp if (!p_init) PCTFS_comm_init(); 235827bd09bSSatish Balay 236827bd09bSSatish Balay /* if there's nothing to do return */ 2372fa5cd67SKarl Rupp if ((PCTFS_num_nodes<2)||(!n)||(dim<=0)) PetscFunctionReturn(0); 238827bd09bSSatish Balay 239827bd09bSSatish Balay /* the error msg says it all!!! */ 240b1c944f5SJed Brown if (modfl_num_nodes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: PCTFS_num_nodes not a power of 2!?!"); 241827bd09bSSatish Balay 242827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 243b1c944f5SJed Brown if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: n=%D<0?",n); 244827bd09bSSatish Balay 245827bd09bSSatish Balay /* can't do more dimensions then exist */ 246b1c944f5SJed Brown dim = PetscMin(dim,PCTFS_i_log2_num_nodes); 247827bd09bSSatish Balay 248827bd09bSSatish Balay /* advance to list of n operations for custom */ 2492fa5cd67SKarl Rupp if ((type=oprs[0])==NON_UNIFORM) oprs++; 250827bd09bSSatish Balay 251546078acSJacob Faibussowitsch if (!(fp = (vfp) PCTFS_rvec_fct_addr(type))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_grop_hc() :: Could not retrieve function pointer!"); 252827bd09bSSatish Balay 253db4deed7SKarl Rupp for (mask=1,edge=0; edge<dim; edge++,mask<<=1) { 254b1c944f5SJed Brown dest = PCTFS_my_id^mask; 2552fa5cd67SKarl Rupp if (PCTFS_my_id > dest) { 256ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 2572fa5cd67SKarl Rupp } else { 258ffc4695bSBarry Smith ierr = MPI_Recv(work,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 259827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 260827bd09bSSatish Balay } 261827bd09bSSatish Balay } 262827bd09bSSatish Balay 2632fa5cd67SKarl Rupp if (edge==dim) mask>>=1; 264db4deed7SKarl Rupp else { 2652fa5cd67SKarl Rupp while (++edge<dim) mask<<=1; 266db4deed7SKarl Rupp } 267827bd09bSSatish Balay 268db4deed7SKarl Rupp for (edge=0; edge<dim; edge++,mask>>=1) { 2692fa5cd67SKarl Rupp if (PCTFS_my_id%mask) continue; 270827bd09bSSatish Balay 271b1c944f5SJed Brown dest = PCTFS_my_id^mask; 2722fa5cd67SKarl Rupp if (PCTFS_my_id < dest) { 273ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_SCALAR,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 2742fa5cd67SKarl Rupp } else { 275ffc4695bSBarry Smith ierr = MPI_Recv(vals,n,MPIU_SCALAR,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 276827bd09bSSatish Balay } 277827bd09bSSatish Balay } 2783fdc5746SBarry Smith PetscFunctionReturn(0); 279827bd09bSSatish Balay } 280827bd09bSSatish Balay 2817b1ae94cSBarry Smith /******************************************************************************/ 282b1c944f5SJed Brown PetscErrorCode PCTFS_ssgl_radd(PetscScalar *vals, PetscScalar *work, PetscInt level, PetscInt *segs) 283827bd09bSSatish Balay { 2843fdc5746SBarry Smith PetscInt edge, type, dest, mask; 2853fdc5746SBarry Smith PetscInt stage_n; 286827bd09bSSatish Balay MPI_Status status; 2873fdc5746SBarry Smith PetscErrorCode ierr; 288*0912c85aSBarry Smith PetscMPIInt *maxval,flg; 289827bd09bSSatish Balay 2903fdc5746SBarry Smith PetscFunctionBegin; 291827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 2922fa5cd67SKarl Rupp if (!p_init) PCTFS_comm_init(); 293827bd09bSSatish Balay 294827bd09bSSatish Balay /* all msgs are *NOT* the same length */ 295827bd09bSSatish Balay /* implement the mesh fan in/out exchange algorithm */ 296db4deed7SKarl Rupp for (mask=0, edge=0; edge<level; edge++, mask++) { 297827bd09bSSatish Balay stage_n = (segs[level] - segs[edge]); 298db4deed7SKarl Rupp if (stage_n && !(PCTFS_my_id & mask)) { 299827bd09bSSatish Balay dest = edge_node[edge]; 300b1c944f5SJed Brown type = MSGTAG3 + PCTFS_my_id + (PCTFS_num_nodes*edge); 3012fa5cd67SKarl Rupp if (PCTFS_my_id>dest) { 302ffc4695bSBarry Smith ierr = MPI_Send(vals+segs[edge],stage_n,MPIU_SCALAR,dest,type, MPI_COMM_WORLD);CHKERRMPI(ierr); 3032fa5cd67SKarl Rupp } else { 304b1c944f5SJed Brown type = type - PCTFS_my_id + dest; 305ffc4695bSBarry Smith ierr = MPI_Recv(work,stage_n,MPIU_SCALAR,MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 306ca8e9878SJed Brown PCTFS_rvec_add(vals+segs[edge], work, stage_n); 307827bd09bSSatish Balay } 308827bd09bSSatish Balay } 309827bd09bSSatish Balay mask <<= 1; 310827bd09bSSatish Balay } 311827bd09bSSatish Balay mask>>=1; 312db4deed7SKarl Rupp for (edge=0; edge<level; edge++) { 313827bd09bSSatish Balay stage_n = (segs[level] - segs[level-1-edge]); 314db4deed7SKarl Rupp if (stage_n && !(PCTFS_my_id & mask)) { 315827bd09bSSatish Balay dest = edge_node[level-edge-1]; 316b1c944f5SJed Brown type = MSGTAG6 + PCTFS_my_id + (PCTFS_num_nodes*edge); 317*0912c85aSBarry Smith ierr = MPI_Comm_get_attr(MPI_COMM_WORLD,MPI_TAG_UB,&maxval,&flg);CHKERRMPI(ierr); 318*0912c85aSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"MPI error: MPI_Comm_get_attr() is not returning a MPI_TAG_UB"); 319*0912c85aSBarry Smith if (*maxval <= type) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MPI_TAG_UB for your current MPI implementation is not large enough to use PCTFS"); 3202fa5cd67SKarl Rupp if (PCTFS_my_id<dest) { 321ffc4695bSBarry Smith ierr = MPI_Send(vals+segs[level-1-edge],stage_n,MPIU_SCALAR,dest,type,MPI_COMM_WORLD);CHKERRMPI(ierr); 3222fa5cd67SKarl Rupp } else { 323b1c944f5SJed Brown type = type - PCTFS_my_id + dest; 324ffc4695bSBarry Smith ierr = MPI_Recv(vals+segs[level-1-edge],stage_n,MPIU_SCALAR, MPI_ANY_SOURCE,type,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 325827bd09bSSatish Balay } 326827bd09bSSatish Balay } 327827bd09bSSatish Balay mask >>= 1; 328827bd09bSSatish Balay } 3293fdc5746SBarry Smith PetscFunctionReturn(0); 330827bd09bSSatish Balay } 331827bd09bSSatish Balay 3327b1ae94cSBarry Smith /***********************************comm.c*************************************/ 333b1c944f5SJed Brown PetscErrorCode PCTFS_giop_hc(PetscInt *vals, PetscInt *work, PetscInt n, PetscInt *oprs, PetscInt dim) 334827bd09bSSatish Balay { 33552f87cdaSBarry Smith PetscInt mask, edge; 33652f87cdaSBarry Smith PetscInt type, dest; 337827bd09bSSatish Balay vfp fp; 338827bd09bSSatish Balay MPI_Status status; 3393fdc5746SBarry Smith PetscErrorCode ierr; 340827bd09bSSatish Balay 3413fdc5746SBarry Smith PetscFunctionBegin; 342827bd09bSSatish Balay /* ok ... should have some data, work, and operator(s) */ 343b1c944f5SJed Brown if (!vals||!work||!oprs) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: vals=%D, work=%D, oprs=%D",vals,work,oprs); 344827bd09bSSatish Balay 345827bd09bSSatish Balay /* non-uniform should have at least two entries */ 346b1c944f5SJed Brown if ((oprs[0] == NON_UNIFORM)&&(n<2)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: non_uniform and n=0,1?"); 347827bd09bSSatish Balay 348827bd09bSSatish Balay /* check to make sure comm package has been initialized */ 3492fa5cd67SKarl Rupp if (!p_init) PCTFS_comm_init(); 350827bd09bSSatish Balay 351827bd09bSSatish Balay /* if there's nothing to do return */ 3522fa5cd67SKarl Rupp if ((PCTFS_num_nodes<2)||(!n)||(dim<=0)) PetscFunctionReturn(0); 353827bd09bSSatish Balay 354827bd09bSSatish Balay /* the error msg says it all!!! */ 355b1c944f5SJed Brown if (modfl_num_nodes) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: PCTFS_num_nodes not a power of 2!?!"); 356827bd09bSSatish Balay 357827bd09bSSatish Balay /* a negative number of items to send ==> fatal */ 358b1c944f5SJed Brown if (n<0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: n=%D<0?",n); 359827bd09bSSatish Balay 360827bd09bSSatish Balay /* can't do more dimensions then exist */ 361b1c944f5SJed Brown dim = PetscMin(dim,PCTFS_i_log2_num_nodes); 362827bd09bSSatish Balay 363827bd09bSSatish Balay /* advance to list of n operations for custom */ 3642fa5cd67SKarl Rupp if ((type=oprs[0])==NON_UNIFORM) oprs++; 365827bd09bSSatish Balay 366546078acSJacob Faibussowitsch if (!(fp = (vfp) PCTFS_ivec_fct_addr(type))) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"PCTFS_giop_hc() :: Could not retrieve function pointer!"); 367827bd09bSSatish Balay 368db4deed7SKarl Rupp for (mask=1,edge=0; edge<dim; edge++,mask<<=1) { 369b1c944f5SJed Brown dest = PCTFS_my_id^mask; 3702fa5cd67SKarl Rupp if (PCTFS_my_id > dest) { 371ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG2+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 3722fa5cd67SKarl Rupp } else { 373ffc4695bSBarry Smith ierr = MPI_Recv(work,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG2+dest,MPI_COMM_WORLD, &status);CHKERRMPI(ierr); 374827bd09bSSatish Balay (*fp)(vals, work, n, oprs); 375827bd09bSSatish Balay } 376827bd09bSSatish Balay } 377827bd09bSSatish Balay 3782fa5cd67SKarl Rupp if (edge==dim) mask>>=1; 3792fa5cd67SKarl Rupp else { 3802fa5cd67SKarl Rupp while (++edge<dim) mask<<=1; 3812fa5cd67SKarl Rupp } 382827bd09bSSatish Balay 383db4deed7SKarl Rupp for (edge=0; edge<dim; edge++,mask>>=1) { 3842fa5cd67SKarl Rupp if (PCTFS_my_id%mask) continue; 385827bd09bSSatish Balay 386b1c944f5SJed Brown dest = PCTFS_my_id^mask; 3872fa5cd67SKarl Rupp if (PCTFS_my_id < dest) { 388ffc4695bSBarry Smith ierr = MPI_Send(vals,n,MPIU_INT,dest,MSGTAG4+PCTFS_my_id,MPI_COMM_WORLD);CHKERRMPI(ierr); 3892fa5cd67SKarl Rupp } else { 390ffc4695bSBarry Smith ierr = MPI_Recv(vals,n,MPIU_INT,MPI_ANY_SOURCE,MSGTAG4+dest,MPI_COMM_WORLD,&status);CHKERRMPI(ierr); 391827bd09bSSatish Balay } 392827bd09bSSatish Balay } 3933fdc5746SBarry Smith PetscFunctionReturn(0); 394827bd09bSSatish Balay } 395