home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / adaptor / dalib / pvm3 / replict1.c < prev    next >
Text File  |  1993-11-29  |  10KB  |  317 lines

  1. /**************************************************************************
  2. *                                                                         *
  3. *  Author      : Dr. Thomas Brandes, GMD, I1.HR                           *
  4. *  Copyright   : GMD St. Augustin, Germany                                *
  5. *  Date        : Feb 92                                                   *
  6. *  Last Update : Aug 92                                                   *
  7. *                                                                         *
  8. *  This Module is part of the DALIB                                       *
  9. *                                                                         *
  10. *  Module      : replicate1.c                                             *
  11. *                                                                         *
  12. *  Function    : Operations for replicating sections of distr. arrays     *
  13. *                                                                         *
  14. *  Export : FORTRAN Interface                                             *
  15. *                                                                         *
  16. **************************************************************************/
  17.  
  18. # undef DEBUG
  19.  
  20. # include "system.h"
  21.  
  22. void dalib_replicate1__ (ra, a, size, N1, x1, y1)
  23. unsigned char *a, *ra;
  24. int *size;
  25. int *N1, *x1, *y1;
  26.  
  27. {   /* replicate a(x1:y1) to ra */
  28.  
  29.     int pid_low, pid_up, send_pid;
  30.     int my_pid;
  31.  
  32.     int send_size;
  33.     int low, up;
  34.  
  35.     unsigned char *ra_ptr;
  36.  
  37.     my_pid = pcb.i;
  38.  
  39. #ifdef DEBUG
  40.     printf ("Process %d calls replicate1 %d : %d\n", my_pid, *x1, *y1);
  41. #endif
  42.  
  43.     /* pid_low : pid_up =  processors that own elements of this range */
  44.  
  45.     pid_low = dalib_where (*N1, *x1);
  46.     pid_up  = dalib_where (*N1, *y1);
  47.  
  48.     ra_ptr = ra;
  49.  
  50.     for (send_pid = pid_low; send_pid <= pid_up; send_pid++)
  51.  
  52.       { /* get local range of process i */
  53.  
  54.         dalib_local_extensions (send_pid, *N1, &low, &up);
  55.         if (low < *x1) low = *x1;
  56.         if (up  > *y1) up  = *y1;
  57.  
  58.         /* replicate a(low:up) from processor send_pid */
  59.  
  60.         send_size = (up - low + 1) * *size;
  61.  
  62.         /* if I am process send_pid,  set the elements in ra */
  63.  
  64.         if (send_pid == my_pid)
  65.           {  dalib_setup_section1 (*size, *N1, low, up);
  66.              dalib_copy_section1  (ra_ptr, a);
  67.           }
  68.  
  69.         /* broadcast of the section of ra   */
  70.  
  71.         process_broadcast (ra_ptr, send_size, send_pid);
  72.  
  73.         ra_ptr += send_size;
  74.       }
  75. } /* dalib_replicate1 */
  76.  
  77. void dalib_replicate2__ (ra, a, size, N1, x1, y1, N2, x2, y2)
  78. unsigned char *a, *ra;
  79. int *size;
  80. int *N1, *x1, *y1, *N2, *x2, *y2;
  81.  
  82. {   /* replicate a(x1:y1,x2:y2) to ra */
  83.  
  84.     int pid_low, pid_up, send_pid;
  85.     int my_pid;
  86.  
  87.     int send_size;
  88.     int low, up;
  89.  
  90.     unsigned char *ra_ptr;
  91.  
  92.     my_pid = pcb.i;
  93.  
  94. #ifdef DEBUG
  95.     printf ("Process %d calls replicate2 %d : %d\n",
  96.              my_pid, *x1, *y1, *x2, *y2);
  97. #endif
  98.  
  99.     /* pid_low : pid_up =  processors that own elements of this range */
  100.  
  101.     pid_low = dalib_where (*N2, *x2);
  102.     pid_up  = dalib_where (*N2, *y2);
  103.  
  104.     ra_ptr = ra;
  105.  
  106.     for (send_pid = pid_low; send_pid <= pid_up; send_pid++)
  107.  
  108.       { /* get local range of process i */
  109.  
  110.         dalib_local_extensions (send_pid, *N2, &low, &up);
  111.         if (low < *x2) low = *x2;
  112.         if (up  > *y2) up  = *y2;
  113.  
  114.         /* replicate a(low:up) from processor send_pid */
  115.  
  116.         send_size = (up - low + 1) * (*y1 - *x1 + 1) * *size;
  117.  
  118.         /* if I am process send_pid,  set the elements in ra */
  119.  
  120.         if (send_pid == my_pid)
  121.           {  dalib_setup_section2 (*size, *N1, *x1, *y1, *N2, low, up);
  122.              dalib_copy_section2  (ra_ptr, a);
  123.           }
  124.  
  125.         /* broadcast of the section of ra   */
  126.  
  127.         process_broadcast (ra_ptr, send_size, send_pid);
  128.  
  129.         ra_ptr += send_size;
  130.       }
  131. } /* dalib_replicate2 */
  132.  
  133. void dalib_replicate3__ (ra, a, size, N1, x1, y1, N2, x2, y2, N3, x3, y3)
  134. unsigned char *a, *ra;
  135. int *size;
  136. int *N1, *x1, *y1, *N2, *x2, *y2, *N3, *x3, *y3;
  137.  
  138. {   /* replicate a(x1:y1,x2:y2,x3:y3) to ra */
  139.  
  140.     int pid_low, pid_up, send_pid;
  141.     int my_pid;
  142.  
  143.     int send_size;
  144.     int low, up;
  145.  
  146.     unsigned char *ra_ptr;
  147.  
  148.     my_pid = pcb.i;
  149.  
  150. #ifdef DEBUG
  151.     printf ("Process %d calls replicate3 %d : %d, %d : %d, %d : %d\n",
  152.              my_pid, *x1, *y1, *x2, *y2, *x3, *y3);
  153. #endif
  154.  
  155.     /* pid_low : pid_up =  processors that own elements of this range */
  156.  
  157.     pid_low = dalib_where (*N3, *x3);
  158.     pid_up  = dalib_where (*N3, *y3);
  159.  
  160.     ra_ptr = ra;
  161.  
  162.     for (send_pid = pid_low; send_pid <= pid_up; send_pid++)
  163.  
  164.       { /* get local range of process i */
  165.  
  166.         dalib_local_extensions (send_pid, *N3, &low, &up);
  167.         if (low < *x3) low = *x3;
  168.         if (up  > *y3) up  = *y3;
  169.  
  170.         /* replicate a(low:up) from processor send_pid */
  171.  
  172.         send_size = (up - low + 1)  * (*y1 - *x1 + 1) * 
  173.                     (*y2 - *x2 + 1) * *size;
  174.  
  175.         /* if I am process send_pid,  set the elements in ra */
  176.  
  177.         if (send_pid == my_pid)
  178.           {  dalib_setup_section3 (*size, *N1, *x1, *y1, *N2, *x2, *y2,
  179.                                           *N3, low, up);
  180.              dalib_copy_section3  (ra_ptr, a);
  181.           }
  182.  
  183.         /* broadcast of the section of ra   */
  184.  
  185.         process_broadcast (ra_ptr, send_size, send_pid);
  186.  
  187.         ra_ptr += send_size;
  188.       }
  189. } /* dalib_replicate3 */
  190.  
  191. void dalib_replicate4__ (ra, a, size, N1, x1, y1, N2, x2, y2, 
  192.                                      N3, x3, y3, N4, x4, y4)
  193. unsigned char *a, *ra;
  194. int *size;
  195. int *N1, *x1, *y1, *N2, *x2, *y2, *N3, *x3, *y3, *N4, *x4, *y4;
  196.  
  197. {   /* replicate a(x1:y1,x2:y2,x3:y3,x4:y4) to ra */
  198.  
  199.     int pid_low, pid_up, send_pid;
  200.     int my_pid;
  201.  
  202.     int send_size;
  203.     int low, up;
  204.  
  205.     unsigned char *ra_ptr;
  206.  
  207.     my_pid = pcb.i;
  208.  
  209. #ifdef DEBUG
  210.     printf ("Process %d calls replicate4 %d : %d, %d : %d, %d : %d, %d : %d\n",
  211.              my_pid, *x1, *y1, *x2, *y2, *x3, *y3, *x4, *y4);
  212. #endif
  213.  
  214.     /* pid_low : pid_up =  processors that own elements of this range */
  215.  
  216.     pid_low = dalib_where (*N4, *x4);
  217.     pid_up  = dalib_where (*N4, *y4);
  218.  
  219.     ra_ptr = ra;
  220.  
  221.     for (send_pid = pid_low; send_pid <= pid_up; send_pid++)
  222.  
  223.       { /* get local range of process i */
  224.  
  225.         dalib_local_extensions (send_pid, *N4, &low, &up);
  226.         if (low < *x4) low = *x4;
  227.         if (up  > *y4) up  = *y4;
  228.  
  229.         /* replicate a(low:up) from processor send_pid */
  230.  
  231.         send_size = (up - low + 1)  * (*y1 - *x1 + 1) * 
  232.                     (*y2 - *x2 + 1) * (*y3 - *x3 + 1) *  *size;
  233.  
  234.         /* if I am process send_pid,  set the elements in ra */
  235.  
  236.         if (send_pid == my_pid)
  237.           {  dalib_setup_section4 (*size, *N1, *x1, *y1, *N2, *x2, *y2,
  238.                                           *N3, *x3, *y3, *N4, low, up);
  239.              dalib_copy_section4  (ra_ptr, a);
  240.           }
  241.  
  242.         /* broadcast of the section of ra   */
  243.  
  244.         process_broadcast (ra_ptr, send_size, send_pid);
  245.  
  246.         ra_ptr += send_size;
  247.       }
  248. } /* dalib_replicate4 */
  249.  
  250. /*    Idea of replication if most processors have elements 
  251.  
  252. C     ****************************************************************
  253. C     *                                                              *
  254. C     *  REPLICATE a full array NAME (only nodes)                    *
  255. C     *                                                              *
  256. C     ****************************************************************
  257.  
  258.       subroutine adp_full_replicate_NAME (NAME_dsp, NAME, ra)
  259.       integer NAME_dsp
  260.       TYPE NAME(*), ra(*)
  261.       integer tsize
  262.       parameter (tsize = TYPESIZE)
  263. c
  264. c        A of $1    A of $2        ....        A of $p
  265. c      -------------------------------------------------
  266. c      |         |          |     ......     |         |
  267. c      |         |          |     ......     |         |
  268. c      |         |          |     ......     |         |
  269. c      -------------------------------------------------
  270. c
  271. c         shifting $p times every part to the right processor
  272. c
  273.       integer p, sendp, recvp, pid
  274.       integer lb1, ub1, lb2, ub2, glb2, gub2
  275.       integer k, size, address, rows
  276.       integer dalib_nproc, dalib_pid 
  277.       integer i
  278. c
  279.       p = dalib_nproc ()
  280.       pid = dalib_pid()
  281.       sendp = pid + 1
  282.       if (sendp .gt. p) sendp = 1
  283.       recvp = pid - 1
  284.       if (recvp .eq. 0) recvp = p
  285. c
  286.       call dalib_array_dimensions2 (NAME_dsp, lb1, ub1, lb2, ub2)
  287. c
  288.       call dalib_pardim_dimensions (NAME_dsp, glb2, gub2)
  289. c
  290. c     address of ra (1, lb2) where ra (lb1:ub1,glb2:ub2)
  291.       rows    = ub1 - lb1 + 1
  292.       address = (lb2 - glb2) * rows + 1
  293.       k = dalib_pid()
  294.       size = (ub2 - lb2 + 1) * rows
  295. c     
  296. c     copy local part
  297.       do i = 1, size
  298.          ra (address + i - 1) = NAME (i)
  299.       end do
  300.       do i=1,p-1
  301. c        send right processor the last part
  302.          call dalib_array_size  (NAME_dsp, k, size)
  303.          call dalib_send (sendp, ra (address), size)
  304.          k = k - 1
  305.          if (k .eq. 0) then
  306.             k = p
  307.             address = (gub2 - glb2 + 1) * rows + 1
  308.          end if
  309. c        get part of original processor k
  310.          call dalib_array_size (NAME_dsp,k,size)
  311.          address = address - (size / tsize)
  312.          call dalib_receive (recvp, ra(address),size)
  313.       end do
  314.       end
  315.  
  316. */
  317.