home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Professional
/
OS2PRO194.ISO
/
os2
/
prgramer
/
adaptor
/
dalib
/
pvm3
/
cshift0.c
< prev
next >
Wrap
Text File
|
1993-11-30
|
12KB
|
377 lines
/**************************************************************************
* *
* Author : Dr. Thomas Brandes, GMD, I1.HR *
* Copyright : GMD St. Augustin, Germany *
* Date : Apr 93 *
* Last Update : Apr 93 *
* *
* This Module is part of the DALIB, UNILIB, HOSTLIB *
* *
* Module : cshift0.c *
* *
* Function : local circular shifting of full arrays *
* (no communication required for local arrays) *
* *
* Export : FORTRAN Interface *
* *
**************************************************************************/
/*******************************************************************
* *
* update position that -n/2 <= pos <= n/2 *
* *
*******************************************************************/
void update_pos (pos, n)
int *pos, n;
{ int n2;
n2 = (n+1) / 2;
while (*pos > n2) *pos -= n;
while (*pos < -n2) *pos += n;
}
/*******************************************************************
* *
* SHIFT UP (local operation, no communication) *
* *
* NAME (j,i) = NAME (j+pos,i) *
* *
* ----------------------------------------------------- *
* low1 | | | | *
* | /\ | | | *
* | || | | | *
* | || | | | *
* | || | | | *
* up1 | | | | *
* ----------------------------------------------------- *
* *
* low2 up2 *
* *
* esize: bytes of one element *
* nrow : (up1 - low1 + 1) *
* ncol : (up2 - low2 + 1) *
* *
*******************************************************************/
void dalib_make_shift_up (dest, source, esize, nrow, pos, ncol)
unsigned char *dest, *source;
int esize, nrow, pos, ncol;
{ unsigned char *save, *source_ptr, *dest_ptr;
int pos_size, col_size, local_size, j;
#ifdef DEBUG
printf ("Proc %d calls make_shift_up, esize = %d, pos/rows = %d/%d\n",
pcb.i, esize, pos, nrow);
#endif
pos_size = pos * esize;
col_size = nrow * esize;
local_size = col_size - pos_size;
/* save (1:pos) = source (low1:low1+pos-1) */
source_ptr = source;
dest_ptr = dest;
save = (unsigned char*) (malloc (pos_size));
for (j=1; j<=ncol; j++)
{ /* do it for every column */
dalib_memcpy (save, source_ptr, pos_size);
/* save the first pos elements of the column to prevent overwrite */
dalib_memcpy (dest_ptr, source_ptr + pos_size, local_size);
dalib_memcpy (dest_ptr + local_size, save, pos_size);
source_ptr += col_size;
dest_ptr += col_size;
}
free (save);
}
/*******************************************************************
* *
* SHIFT DOWN (local operation, no communication) *
* *
* NAME (j,i) = NAME (j-pos,i) *
* *
* ----------------------------------------------------- *
* low1 | | | | *
* | || | | | *
* | || | | | *
* | || | | | *
* | \/ | | | *
* up1 | | | | *
* ----------------------------------------------------- *
* *
* low2 up2 *
* *
* esize: bytes of one element *
* nrow : (up1 - low1 + 1) *
* ncol : (up2 - low2 + 1) *
* *
*******************************************************************/
void dalib_make_shift_down (dest, source, esize, nrow, pos, ncol)
unsigned char *dest, *source;
int esize, nrow, pos, ncol;
{ unsigned char *save, *source_ptr, *dest_ptr;
int pos_size, col_size, local_size, j;
#ifdef DEBUG
printf ("Proc %d calls make_shift_down, esize = %d, pos/rows = %d/%d\n",
pcb.i, esize, pos, nrow);
#endif
pos_size = pos * esize;
col_size = nrow * esize;
local_size = col_size - pos_size;
/* save (1:pos) = source (low1:low1+pos-1) */
source_ptr = source;
dest_ptr = dest;
save = (unsigned char*) (malloc (pos_size));
for (j=1; j<=ncol; j++)
{ /* do it for every column */
dalib_memcpy (save, source_ptr + local_size, pos_size);
dalib_rmemcpy (dest_ptr + pos_size, source_ptr, local_size);
dalib_memcpy (dest_ptr, save, pos_size);
source_ptr += col_size;
dest_ptr += col_size;
}
free (save);
}
/*******************************************************************
* *
* ONE DIMENSIONAL ARRAYS *
* *
*******************************************************************/
void dalib_lcshift1__ (dest, source, size, N1, dim, pos)
unsigned char *dest, *source;
int *size, *N1, *dim, *pos;
{ int hpos, nrow, ncol;
int msize;
hpos = *pos;
switch (*dim) {
case 1 :
update_pos (&hpos, *N1);
msize = *size;
nrow = *N1;
ncol = 1;
break;
default :
printf ("DALIB: illegal dim (%d) in local cshift1\n", *dim);
exit (-1);
} /* end switch */
if (hpos > 0)
dalib_make_shift_up (dest, source, msize, nrow, hpos, ncol);
else if (hpos < 0)
dalib_make_shift_down (dest, source, msize, nrow, -hpos, ncol);
else if (dest != source)
dalib_memcpy (dest, source, msize*nrow*ncol);
} /* dalib_lcshift1 */
/*******************************************************************
* *
* TWO DIMENSIONAL ARRAYS *
* *
*******************************************************************/
void dalib_lcshift2__ (dest, source, size, N1, N2, dim, pos)
unsigned char *dest, *source;
int *size, *N1, *N2, *dim, *pos;
{ int hpos, nrow, ncol;
int msize;
hpos = *pos;
switch (*dim) {
case 1 :
update_pos (&hpos, *N1);
msize = *size;
nrow = *N1;
ncol = *N2;
break;
case 2 :
update_pos (&hpos, *N2);
msize = *size * *N1;
nrow = *N2;
ncol = 1;
break;
default :
printf ("DALIB: illegal dim (%d) in local cshift3\n", *dim);
exit (-1);
} /* end switch */
if (hpos > 0)
dalib_make_shift_up (dest, source, msize, nrow, hpos, ncol);
else if (hpos < 0)
dalib_make_shift_down (dest, source, msize, nrow, -hpos, ncol);
else if (dest != source)
dalib_memcpy (dest, source, msize*nrow*ncol);
} /* dalib_lcshift2 */
/*******************************************************************
* *
* THREE DIMENSIONAL ARRAYS *
* *
*******************************************************************/
void dalib_lcshift3__ (dest, source, size, N1, N2, N3, dim, pos)
unsigned char *dest, *source;
int *size, *N1, *N2, *N3, *dim, *pos;
{ int hpos, nrow, ncol;
int msize;
hpos = *pos;
switch (*dim) {
case 1 :
update_pos (&hpos, *N1);
msize = *size;
nrow = *N1;
ncol = *N2 * *N3;
break;
case 2 :
update_pos (&hpos, *N2);
msize = *size * *N1;
nrow = *N2;
ncol = *N3;
break;
case 3 :
update_pos (&hpos, *N3);
msize = *size * *N1 * *N2;
nrow = *N3;
ncol = 1;
break;
default :
printf ("DALIB: illegal dim (%d) in local cshift3\n", *dim);
exit (-1);
} /* end switch */
if (hpos > 0)
dalib_make_shift_up (dest, source, msize, nrow, hpos, ncol);
else if (hpos < 0)
dalib_make_shift_down (dest, source, msize, nrow, -hpos, ncol);
else if (dest != source)
dalib_memcpy (dest, source, msize*nrow*ncol);
} /* dalib_lcshift3 */
/*******************************************************************
* *
* FOUR DIMENSIONAL ARRAYS *
* *
*******************************************************************/
void dalib_lcshift4__ (dest, source, size, N1, N2, N3, N4, dim, pos)
unsigned char *dest, *source;
int *size, *N1, *N2, *N3, *N4, *dim, *pos;
{ int hpos, nrow, ncol;
int msize;
hpos = *pos;
switch (*dim) {
case 1 :
update_pos (&hpos, *N1);
msize = *size;
nrow = *N1;
ncol = *N2 * *N3 * *N4;
break;
case 2 :
update_pos (&hpos, *N2);
msize = *size * *N1;
nrow = *N2;
ncol = *N3 * *N4;
break;
case 3 :
update_pos (&hpos, *N3);
msize = *size * *N1 * *N2;
nrow = *N3;
ncol = *N4;
break;
case 4 :
update_pos (&hpos, *N4);
msize = *size * *N1 * *N2 * *N3;
nrow = *N4;
ncol = 1;
break;
default :
printf ("DALIB: illegal dim (%d) in local cshift4\n", *dim);
exit (-1);
} /* end switch */
if (hpos > 0)
dalib_make_shift_up (dest, source, msize, nrow, hpos, ncol);
else if (hpos < 0)
dalib_make_shift_down (dest, source, msize, nrow, -hpos, ncol);
else if (dest != source)
dalib_memcpy (dest, source, msize*nrow*ncol);
} /* dalib_lcshift4 */