/*
 * shift function for multiple paths
 */
/*
 * "in"  is a list of "m" arrays of length "nx" packets to read
 * "out" is a list of "m" arrays of length "nx" packets to write
 * "inchan"  is a list of "m" input channels for the arrays
 * "outchan"  is a list of "m" output channels for the arrays
 */
#include "msgtyp.h"
#define MAXM 5
mshift(in,inchan,out,outchan,nx,m)
short **in, **out;
int *inchan, *outchan, nx,m;
{
 static int node,proc,host,dim;
 static int hpkt, hsrcp, hpktyp, hcfpkt;
 static int npkt, nsrcp, npktyp, ncfpkt;
 int srcpr,typepr,cflagr;
 int srcpw,typepw,cflagw;
 int rcw, rcr, i, ii, j, jj, nxm;
 extern int nwrite(), nread(), ntime(), nparity();
 int nb, ns; int endtime, oddpar;
 short *inptr[MAXM], *outptr[MAXM];
 short *outtop[MAXM];
 double inpkt, outpkt[MAXM];

 whoami(&node,&proc,&host,&dim);
 oddpar = nparity(node);
 nb = sizeof(double);
 ns = nb/sizeof(short);
 nxm = nx*m;
 for(i=0; i<m; i++) {
	inptr[i] = in[i];
	outptr[i] = out[i];
	outtop[i] = outptr[i]+nx*ns;
	}

 if(oddpar) { /* if my node parity is odd, read first and then write */

 for(i=0; i<nx; i++) {
     for(ii=0; ii<m; ii++) {
	 outpkt[ii] = *((double *)(outptr[ii]));
	 outptr[ii] += ns;
	 }

	 for(ii=0; ii<m; ii++) {
	     srcpr = -1; typepr = DATA; cflagr = 0;
	     rcr = nread (&inpkt,nb,&srcpr,&typepr,&cflagr);
	     if(rcr < 0) report_err(rcr);
	     for(jj=0; jj<m; jj++) if(srcpr == inchan[jj]) {
		 *((double *)(inptr[jj])) = inpkt;
		 inptr[jj] += ns;
		 break;
		 }
	     }

	 for(ii=0; ii<m; ii++) {
	     srcpw = outchan[ii];  typepw = DATA; cflagw = 0;
	     rcw = nwrite(&outpkt[ii],nb,srcpw,typepw,&cflagw);
	     if(rcw < 0) report_err(rcw);
	     }

     }

} else { /* if my node parity is even, write first and then read */

     for(i=0; i<nx; i++) { /* now do read/write scramble for the rest */

	 for(ii=0; ii<m; ii++) { /* write out first m packets */
	     srcpw = outchan[ii];  typepw = DATA; cflagw = 0;
	     rcw = nwrite(outptr[ii],nb,srcpw,typepw,&cflagw);
	     if(rcw < 0) report_err(rcw);
	     outptr[ii] += ns;
	     }

	 for(ii=0; ii<m; ii++) {
	     srcpr = -1; typepr = DATA; cflagr = 0;
	     rcr = nread (&inpkt,nb,&srcpr,&typepr,&cflagr);
	     if(rcr < 0) report_err(rcr);
	     for(jj=0; jj<m; jj++) if(srcpr == inchan[jj]) {
		    *((double *)(inptr[jj])) = inpkt;
		    inptr[jj] += ns;
		    break;
		    }
	    }
        }
    }
}
