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 >
C/C++ Source or Header  |  1993-11-29  |  11KB  |  228 lines

  1. /**************************************************************************
  2. *                                                                         *
  3. *  Author      : Dr. Thomas Brandes, GMD, I1.HR                           *
  4. *  Copyright   : GMD St. Augustin, Germany                                *
  5. *  Date        : Jan 92                                                   *
  6. *  Last Update : Aug 92                                                   *
  7. *                                                                         *
  8. *  This Module is part of the DALIB                                       *
  9. *                                                                         *
  10. *  Module      : manager1.c                                               *
  11. *                                                                         *
  12. *  Function: Operations for the process access of distributed arrays      *
  13. *            distributed along one dimension                              *
  14. *                                                                         *
  15. *  Export :  FORTRAN Interface                                            *
  16. *  ===========================                                            *
  17. *                                                                         *
  18. *  int dalib_have_i_ (int *N, int *index)                                 *
  19. *                                                                         *
  20. *  void dalib_node_get_ (char *rep_data, char *node_data,                 *
  21. *                        int *size, int *N, int *index)                   *
  22. *                                                                         *
  23. *  void dalib_array_pardim_ (int *N, int *lb, int *ub)                    *
  24. *                                                                         *
  25. *  void dalib_local_slice_ (int *N,                                       *
  26. *                           int *global_lb, int *global_ub,               *
  27. *                           int *local_lb,  int *local_ub  )              *
  28. *                                                                         *
  29. *  void dalib_local_range_ (int *N,                                       *
  30. *              int *global_lb, int *global_ub, int *global_stride,        *
  31. *              int *local_lb,  int *local_ub,  int *local_stride  )       *
  32. *                                                                         *
  33. *  Export :  local to DALIB                                               *
  34. *  ========================                                               *
  35. *                                                                         *
  36. *  int dalib_where (int N, int index)                                     *
  37. *                                                                         *
  38. *  void dalib_local_extensions (int i, int N, int *lb, int *ub)           *
  39. *                                                                         *
  40. *  int dalib_local_size (int N)                                           *
  41. *                                                                         *
  42. **************************************************************************/
  43.  
  44. #include "system.h"
  45.  
  46. #undef  DEBUG
  47.  
  48. /*******************************************************************
  49. *                                                                  *
  50. *  Error - Handling                                                *
  51. *                                                                  *
  52. *******************************************************************/
  53.  
  54. void manager_error (s)
  55. char *s;
  56. { printf ("*** Internal Error in manager.c : %s\n", s); 
  57.   exit (-1);
  58. }
  59.  
  60. /*******************************************************************
  61. *                                                                  *
  62. *  Internal function                                               *
  63. *                                                                  *
  64. *   void dalib_local_extensions (int i, int N, int *lb, int *ub)   *
  65. *                                                                  *
  66. *******************************************************************/
  67.  
  68. void dalib_local_extensions (i, N, lower_bound, upper_bound)
  69. int i, N, *lower_bound, *upper_bound;
  70. { int P;
  71.   P = pcb.p;
  72.   *upper_bound = (i * N / P);
  73.   *lower_bound  = ((i-1) * N / P) + 1;
  74. }
  75.  
  76.      /*********************************************************
  77.      *                                                        *
  78.      *  compute the local size of a distributed array         *
  79.      *                                                        *
  80.      *********************************************************/
  81.  
  82. int dalib_local_size (N)
  83. int N;
  84. { int lower_bound, upper_bound;
  85.   dalib_local_extensions (pcb.i, N, &lower_bound, &upper_bound);
  86.   return (upper_bound - lower_bound + 1);
  87. }
  88.  
  89. /*******************************************************************
  90. *                                                                  *
  91. *  int dalib_where (N, index)                                      *
  92. *                                                                  *
  93. *    - let B (...,N) be a distributed array, function returns      *
  94. *      owner process id of B (....,index)                          *
  95. *                                                                  *
  96. *******************************************************************/
  97.  
  98. int dalib_where (N, index)
  99. int N, index;
  100. { return ( (index * pcb.p -1) / N + 1);
  101. } /* dalib_where is owner of index */
  102.  
  103. /*******************************************************************
  104. *                                                                  *
  105. *  dalib_array_pardim_ (int *N, int *lb, int *ub)                  *
  106. *                                                                  *
  107. *   - local extensions on this processor                           *
  108. *                                                                  *
  109. *******************************************************************/
  110.  
  111. void dalib_array_pardim__ (N, lb, ub)
  112. int *N, *lb, *ub;
  113.  
  114. {  if (*N < pcb.p)
  115.     { printf ("Parallel Dimension : 1 - %d for %d processes\n", *N, pcb.p);
  116.       manager_error ("size must be >= number of node processes");
  117.     }
  118.    dalib_local_extensions (pcb.i, *N, lb, ub);
  119. } /* dalib_array_pardim */
  120.  
  121. /*******************************************************************
  122. *                                                                  *
  123. *  dalib_have_i_  (N, index)                                       *
  124. *                                                                  *
  125. *   - true if index is in my local range where the distributed     *
  126. *     dimension has exactly elements from 1 to N                   *
  127. *                                                                  *
  128. *******************************************************************/
  129.  
  130. int dalib_have_i__ (N, index)
  131. int *N, *index;
  132. { if (dalib_where (*N, *index) == pcb.i)
  133.      return (1);  /* true */ 
  134.    else
  135.      return (0);  /* false */
  136. }
  137.  
  138. /*******************************************************************
  139. *                                                                  *
  140. * dalib_node_get_ (rep_data, node_data, N, index)                  *
  141. *                                                                  *
  142. *  S = A(I) -> call dalib_node_get_ (S, A(I), 4, N, I)             *
  143. *                                                                  *
  144. *******************************************************************/
  145.  
  146. void dalib_node_get__ (rep_data, node_data, size, N, index)
  147. int *N;
  148. int *index;
  149. int *size;
  150. unsigned char *rep_data, *node_data;
  151.  
  152. { int proc;
  153.   proc   = dalib_where (*N, *index);
  154.   if (pcb.i == proc)  /* I am the owner of node_data */
  155.     dalib_memcpy (rep_data, node_data, *size);
  156.   process_broadcast (rep_data, *size, proc);
  157. } /* dalib_node_get */
  158.  
  159. /*******************************************************************
  160. *                                                                  *
  161. *  Range slicing for the distributed dimension                     *
  162. *                                                                  *
  163. *    global range :  global_lb : global_ub : global_stride         *
  164. *    local  range :  local_lb  : local_ub  : local_stride          *
  165. *                                                                  *
  166. *******************************************************************/
  167.  
  168. void dalib_local_range__ (N, global_lb, global_ub, global_stride,
  169.                             local_lb, local_ub, local_stride)
  170.  
  171. int * N;
  172. int * global_lb, * global_ub, * global_stride;
  173. int * local_lb, * local_ub, * local_stride;
  174.  
  175. /* make the global range to a local range, dependent on the distribution */
  176.  
  177. { int hlb, hub; /* local lower and uppber bound */
  178.  
  179. #ifdef DEBUG
  180.   printf ("%d computes dalib_local_range for %d:%d:%d of %d\n", 
  181.            pcb.i, *global_lb, *global_ub, *global_stride, *N);
  182. #endif
  183.  
  184.   dalib_local_extensions (pcb.i, *N, &hlb, &hub);
  185.  
  186.   *local_lb = *global_lb;
  187.   if (*local_lb < hlb) /* find *global_lb + k * global_stride >= hlb */
  188.      *local_lb = *global_lb + ((( hlb - *global_lb - 1) / *global_stride) 
  189.                               + 1) * *global_stride;
  190.   *local_ub = *global_ub;
  191.   if (hub < *local_ub) /* find *global_lb + k * global_stride <= hub */
  192.      *local_ub = *global_lb + ( (hub - *global_lb) / *global_stride)
  193.                               * *global_stride;
  194.   if (*local_ub > hub) *local_ub -= *global_stride;
  195.   *local_stride = *global_stride;
  196.  
  197. #ifdef DEBUG
  198.   printf ("%d has local_range = %d:%d:%d\n", 
  199.            pcb.i, *local_lb, *local_ub, *local_stride);
  200. #endif
  201.  
  202. } /* dalib_local_range */
  203.  
  204.           /****************************************************
  205.           *                                                   *
  206.           *  Special Case : Stride is always 1                *
  207.           *                                                   *
  208.           ****************************************************/
  209.  
  210. void dalib_local_slice__ (N, global_lb, global_ub, local_lb, local_ub)
  211. int * N;
  212. int * global_lb, * global_ub;
  213. int * local_lb, * local_ub;
  214.  
  215. /* make the global range to a local range, dependent on the distribution */
  216.  
  217. { int lb, ub; /* local lower and upper bound */
  218.  
  219.   dalib_local_extensions (pcb.i, *N, &lb, &ub);
  220.  
  221.   *local_lb = *global_lb;
  222.   if (*local_lb < lb) *local_lb = lb ;
  223.  
  224.   *local_ub = *global_ub;
  225.   if (ub < *local_ub) *local_ub = ub;
  226.  
  227. } /* dalib_local_slice */
  228.