home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
adaptor.zip
/
adapt.zip
/
adaptor
/
dalib
/
pvm3
/
manager1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-29
|
11KB
|
228 lines
/**************************************************************************
* *
* Author : Dr. Thomas Brandes, GMD, I1.HR *
* Copyright : GMD St. Augustin, Germany *
* Date : Jan 92 *
* Last Update : Aug 92 *
* *
* This Module is part of the DALIB *
* *
* Module : manager1.c *
* *
* Function: Operations for the process access of distributed arrays *
* distributed along one dimension *
* *
* Export : FORTRAN Interface *
* =========================== *
* *
* int dalib_have_i_ (int *N, int *index) *
* *
* void dalib_node_get_ (char *rep_data, char *node_data, *
* int *size, int *N, int *index) *
* *
* void dalib_array_pardim_ (int *N, int *lb, int *ub) *
* *
* void dalib_local_slice_ (int *N, *
* int *global_lb, int *global_ub, *
* int *local_lb, int *local_ub ) *
* *
* void dalib_local_range_ (int *N, *
* int *global_lb, int *global_ub, int *global_stride, *
* int *local_lb, int *local_ub, int *local_stride ) *
* *
* Export : local to DALIB *
* ======================== *
* *
* int dalib_where (int N, int index) *
* *
* void dalib_local_extensions (int i, int N, int *lb, int *ub) *
* *
* int dalib_local_size (int N) *
* *
**************************************************************************/
#include "system.h"
#undef DEBUG
/*******************************************************************
* *
* Error - Handling *
* *
*******************************************************************/
void manager_error (s)
char *s;
{ printf ("*** Internal Error in manager.c : %s\n", s);
exit (-1);
}
/*******************************************************************
* *
* Internal function *
* *
* void dalib_local_extensions (int i, int N, int *lb, int *ub) *
* *
*******************************************************************/
void dalib_local_extensions (i, N, lower_bound, upper_bound)
int i, N, *lower_bound, *upper_bound;
{ int P;
P = pcb.p;
*upper_bound = (i * N / P);
*lower_bound = ((i-1) * N / P) + 1;
}
/*********************************************************
* *
* compute the local size of a distributed array *
* *
*********************************************************/
int dalib_local_size (N)
int N;
{ int lower_bound, upper_bound;
dalib_local_extensions (pcb.i, N, &lower_bound, &upper_bound);
return (upper_bound - lower_bound + 1);
}
/*******************************************************************
* *
* int dalib_where (N, index) *
* *
* - let B (...,N) be a distributed array, function returns *
* owner process id of B (....,index) *
* *
*******************************************************************/
int dalib_where (N, index)
int N, index;
{ return ( (index * pcb.p -1) / N + 1);
} /* dalib_where is owner of index */
/*******************************************************************
* *
* dalib_array_pardim_ (int *N, int *lb, int *ub) *
* *
* - local extensions on this processor *
* *
*******************************************************************/
void dalib_array_pardim__ (N, lb, ub)
int *N, *lb, *ub;
{ if (*N < pcb.p)
{ printf ("Parallel Dimension : 1 - %d for %d processes\n", *N, pcb.p);
manager_error ("size must be >= number of node processes");
}
dalib_local_extensions (pcb.i, *N, lb, ub);
} /* dalib_array_pardim */
/*******************************************************************
* *
* dalib_have_i_ (N, index) *
* *
* - true if index is in my local range where the distributed *
* dimension has exactly elements from 1 to N *
* *
*******************************************************************/
int dalib_have_i__ (N, index)
int *N, *index;
{ if (dalib_where (*N, *index) == pcb.i)
return (1); /* true */
else
return (0); /* false */
}
/*******************************************************************
* *
* dalib_node_get_ (rep_data, node_data, N, index) *
* *
* S = A(I) -> call dalib_node_get_ (S, A(I), 4, N, I) *
* *
*******************************************************************/
void dalib_node_get__ (rep_data, node_data, size, N, index)
int *N;
int *index;
int *size;
unsigned char *rep_data, *node_data;
{ int proc;
proc = dalib_where (*N, *index);
if (pcb.i == proc) /* I am the owner of node_data */
dalib_memcpy (rep_data, node_data, *size);
process_broadcast (rep_data, *size, proc);
} /* dalib_node_get */
/*******************************************************************
* *
* Range slicing for the distributed dimension *
* *
* global range : global_lb : global_ub : global_stride *
* local range : local_lb : local_ub : local_stride *
* *
*******************************************************************/
void dalib_local_range__ (N, global_lb, global_ub, global_stride,
local_lb, local_ub, local_stride)
int * N;
int * global_lb, * global_ub, * global_stride;
int * local_lb, * local_ub, * local_stride;
/* make the global range to a local range, dependent on the distribution */
{ int hlb, hub; /* local lower and uppber bound */
#ifdef DEBUG
printf ("%d computes dalib_local_range for %d:%d:%d of %d\n",
pcb.i, *global_lb, *global_ub, *global_stride, *N);
#endif
dalib_local_extensions (pcb.i, *N, &hlb, &hub);
*local_lb = *global_lb;
if (*local_lb < hlb) /* find *global_lb + k * global_stride >= hlb */
*local_lb = *global_lb + ((( hlb - *global_lb - 1) / *global_stride)
+ 1) * *global_stride;
*local_ub = *global_ub;
if (hub < *local_ub) /* find *global_lb + k * global_stride <= hub */
*local_ub = *global_lb + ( (hub - *global_lb) / *global_stride)
* *global_stride;
if (*local_ub > hub) *local_ub -= *global_stride;
*local_stride = *global_stride;
#ifdef DEBUG
printf ("%d has local_range = %d:%d:%d\n",
pcb.i, *local_lb, *local_ub, *local_stride);
#endif
} /* dalib_local_range */
/****************************************************
* *
* Special Case : Stride is always 1 *
* *
****************************************************/
void dalib_local_slice__ (N, global_lb, global_ub, local_lb, local_ub)
int * N;
int * global_lb, * global_ub;
int * local_lb, * local_ub;
/* make the global range to a local range, dependent on the distribution */
{ int lb, ub; /* local lower and upper bound */
dalib_local_extensions (pcb.i, *N, &lb, &ub);
*local_lb = *global_lb;
if (*local_lb < lb) *local_lb = lb ;
*local_ub = *global_ub;
if (ub < *local_ub) *local_ub = ub;
} /* dalib_local_slice */