static double vec_r2[2*LOC]; static double vec_r4[4*LOC]; static double vec_s2[2*LOC]; static double vec_s4[4*LOC]; /************************************* * FUNCTION: pow2 -- computes 2^n * *************************************/ int pow2 (n) int n; { int p=1, i; for (i = 1; i <= n; i++) p *= 2; return(p); } /* end of function pow2 */ /***************************************************************** * FUNCTION: lvec -- determines how many powers of 2 divide a * * given integer * * e.g. lvec(40) = 3, since 40 = 2^3 * 5 * *****************************************************************/ int lvec (n) int n; { int ctr=0, num=n, done=0; do { if (num % 2 == 0) { num /= 2; ctr++; } else done = 1; } while (!done); return(pow2(ctr)); } /* end of function lvec */ /*************************************************************** * FUNCTION: getGray -- computes binary reflected Gray code * * for a d-dimensional hypercube * ***************************************************************/ void getGray (V, Vinv, d) int *V, *Vinv, d; { int i, j, a, b, c, ctr; V[0] = 0; V[1] = 1; Vinv[0] = 0; Vinv[1] = 1; ctr = 2; for (i = 2; i <= d; i++) { for (j = 0; j < ctr; j++) { a = ctr+j; b = ctr-1-j; c = ctr + V[b]; V[a] = c; Vinv[c] = a; } ctr *= 2; } } /* end of function getGray */ /******************************************************************* * FUNCTION: cshift_R4 -- receives a kvec4 for a circular shift * *******************************************************************/ void cshift_R4 (R, loc, tp1) struct kvec4 *R; int loc, tp1; { int i, j, k; pvm_recv(tp1, 2); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) pvm_upkdouble(&R->el[i].el[j].el[k], 1, 1); } /* end of function cshift_R4 */ /**************************************************************** * FUNCTION: cshift_S4 -- sends a kvec4 for a circular shift * ****************************************************************/ void cshift_S4 (S, loc, tm1) struct kvec4 *S; int loc, tm1; { int i, j, k; pvm_initsend(code); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) pvm_pkdouble(&S->el[i].el[j].el[k], 1, 1); pvm_send(tm1, 2); } /* end of function cshift_S4 */ /**************************************************************** * FUNCTION: cshift_S2 -- sends a kvec2 for a circular shift * ****************************************************************/ void cshift_S2 (S, loc, tm1) struct kvec2 *S; int loc, tm1; { int i, j; pvm_initsend(code); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) pvm_pkdouble(&S->el[i].el[j], 1, 1); pvm_send(tm1, 2); } /* end of function cshift_S2 */ /******************************************************************* * FUNCTION: cshift_R2 -- receives a kvec2 for a circular shift * *******************************************************************/ void cshift_R2 (R, loc, tp1) struct kvec2 *R; int loc, tp1; { int i, j; pvm_recv(tp1, 2); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) pvm_upkdouble(&R->el[i].el[j], 1, 1); } /* end of function cshift_R2 */ /***************************** * FUNCTION: cshift_S2_R4 * *****************************/ void cshift_S2_R4 (S, tm1, R, tp1, loc) struct kvec2 *S; struct kvec4 *R; int tm1, tp1, loc; { int i, j, k, ctr; /* pvm_initsend(code); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) pvm_pkdouble(&S->el[i].el[j], 1, 1); pvm_send(tm1, 2); pvm_recv(tp1, 2); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) pvm_upkdouble(&R->el[i].el[j].el[k], 1, 1); */ ctr = -1; for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) vec_s2[++ctr] = S->el[i].el[j]; barrier(); shmem_get(vec_r4, vec_s4, 4*loc, tp1); ctr = -1; for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) R->el[i].el[j].el[k] = vec_r4[++ctr]; } /* end of function cshift_S2_R4 */ /***************************** * FUNCTION: cshift_S4_R4 * *****************************/ void cshift_S4_R4 (S, tm1, R, tp1, loc) struct kvec4 *S, *R; int tm1, tp1, loc; { int i, j, k, ctr; /* pvm_initsend(code); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) pvm_pkdouble(&S->el[i].el[j].el[k], 1, 1); pvm_send(tm1, 2); pvm_recv(tp1, 2); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) pvm_upkdouble(&R->el[i].el[j].el[k], 1, 1); */ ctr = -1; for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) vec_s4[++ctr] = S->el[i].el[j].el[k]; barrier(); shmem_get(vec_r4, vec_s4, 4*loc, tp1); ctr = -1; for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) R->el[i].el[j].el[k] = vec_r4[++ctr]; } /* end of function cshift_S4_R4 */ /***************************** * FUNCTION: cshift_S4_R2 * *****************************/ void cshift_S4_R2 (S, tm1, R, tp1, loc) struct kvec4 *S; struct kvec2 *R; int tm1, tp1, loc; { int i, j, k, ctr; /* pvm_initsend(code); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) pvm_pkdouble(&S->el[i].el[j].el[k], 1, 1); pvm_send(tm1, 2); pvm_recv(tp1, 2); for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) pvm_upkdouble(&R->el[i].el[j], 1, 1); */ ctr = -1; for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) for (k = 0; k < 2; k++) vec_s4[++ctr] = S->el[i].el[j].el[k]; barrier(); shmem_get(vec_r2, vec_s2, 2*loc, tp1); ctr = -1; for (i = 0; i < loc; i++) for (j = 0; j < 2; j++) R->el[i].el[j] = vec_r2[++ctr]; } /* end of fucntion cshift_S4_R2 */