home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / adaptor / dalib / pvm3 / movemnt1.c < prev    next >
C/C++ Source or Header  |  1993-11-30  |  30KB  |  833 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      : movement1.c                                              *
  11. *                                                                         *
  12. *  Function    : Operations for moving array sections of distr. arrays    *
  13. *                                                                         *
  14. *              T[...,t_low:t_up]  =  S[...,s_low:s_up]                    *
  15. *                                                                         *
  16. *  Export : FORTRAN Interface                                             *
  17. *                                                                         *
  18. *  void dalib_move_define__ (t_N, t_low, t_up, s_N, s_low, s_up)           *
  19. *  int *t_N, *t_low, *t_up;                                               *
  20. *  int *s_N, *s_low, *s_up;                                               *
  21. *                                                                         *
  22. *  void dalib_move_source1__ (a, size, N1, x1, y1)                         *
  23. *  unsigned char *a;                                                      *
  24. *  int *size;                                                             *
  25. *  int *N1, *x1, *y1;                                                     *
  26. *                                                                         *
  27. *  void dalib_move_source2__ (a_dsp, a, x1, y1, x2, y2)                    *
  28. *  int *a_dsp;                                                            *
  29. *  unsigned char *a;                                                      *
  30. *  int *x1, *y1, *x2, *y2;                                                *
  31. *                                                                         *
  32. *   .......                                                               *
  33. *                                                                         *
  34. *  void dalib_move_source4__ (a_dsp, a, x1, y1, x2, y2, x3, y3, x4, y4)    *
  35. *  int *a_dsp;                                                            *
  36. *  unsigned char *a;                                                      *
  37. *  int *x1, *y1, *x2, *y2, *x3, *y3, *x4, *y4;                            *
  38. *                                                                         *
  39. *  void dalib_move_target1__ (a_dsp, a, x1, y1)                            *
  40. *  int *a_dsp;                                                            *
  41. *  unsigned char *a;                                                      *
  42. *  int *x1, *y1;                                                          *
  43. *                                                                         *
  44. *  void dalib_move_target2__ (a_dsp, a, x1, y1, x2, y2)                    *
  45. *  int *a_dsp;                                                            *
  46. *  unsigned char *a;                                                      *
  47. *  int *x1, *y1, *x2, *y2;                                                *
  48. *                                                                         *
  49. *   .......                                                               *
  50. *                                                                         *
  51. *  void dalib_move_target4__ (a_dsp, a, x1, y1, x2, y2, x3, y3, x4, y4)    *
  52. *  int *a_dsp;                                                            *
  53. *  unsigned char *a;                                                      *
  54. *  int *x1, *y1, *x2, *y2, *x3, *y3, *x4, *y4;                            *
  55. *                                                                         *
  56. **************************************************************************/
  57.  
  58. #include "system.h"
  59.  
  60. #undef DEBUG
  61.  
  62.   /*********************************************************
  63.   *                                                        *
  64.   *  Global data for a movement                            *
  65.   *                                                        *
  66.   *    - size of source and target                         *
  67.   *    - global range of source and target                 *
  68.   *    - local range of source and target                  *
  69.   *    - kind of movement:                                 *
  70.   *                                                        *
  71.   *        a(1:5) = b(7:11)   many <-- many    KIND = 0    *
  72.   *      a(1:5,4) = b(7:11)   one  <-- many    KIND = 1    *
  73.   *        a(1:5) = b(7:11,3) many <-- one     KIND = 2    *
  74.   *      a(1:5,4) = b(7:11,3) one  <-- one     KIND = 3    *
  75.   *                                                        *
  76.   *********************************************************/
  77.  
  78. int target_size, source_size;
  79.  
  80. int target_low, target_up;
  81. int source_low, source_up;
  82. int local_source_low, local_source_up; /* range of source that will be send  */
  83. int local_target_low, local_target_up; /* range of target that will be recvd */
  84.  
  85. int move_kind, move_constant;
  86.  
  87.      /*********************************************************
  88.      *                                                        *
  89.      *  Definition of a movement                              *
  90.      *                                                        *
  91.      *********************************************************/
  92.  
  93. void dalib_move_define__ (t_N, t_low, t_up, s_N, s_low, s_up)
  94. int *t_N, *t_low, *t_up;
  95. int *s_N, *s_low, *s_up;
  96.  
  97. { /* maps [s_low:s_up] of source to [t_low:t_up] of target */
  98.   
  99. #ifdef DEBUG
  100.   printf ("Process %d calls move_define (%d:%d)/%d <- (%d:%d)/%d\n", 
  101.            pcb.i, *t_low, *t_up, *t_N, *s_low, *s_up, *s_N          ); 
  102. #endif
  103.  
  104.   target_size       = *t_N;
  105.   target_low        = *t_low;
  106.   target_up         = *t_up;
  107.   source_size       = *s_N;
  108.   source_low        = *s_low;
  109.   source_up         = *s_up;
  110.  
  111.   move_kind = 0;
  112.   if (source_low == source_up) move_kind += 2;
  113.   if (target_low == target_up) move_kind += 1;
  114.  
  115.   move_constant = target_low - source_low;
  116.  
  117.   /* set local_source : elements to send */
  118.  
  119.   dalib_local_slice__ (&source_size, &source_low, &source_up,
  120.                                     &local_source_low, &local_source_up);
  121.         
  122.   /* set local_target : elements to recv */
  123.  
  124.   dalib_local_slice__ (&target_size, &target_low, &target_up,
  125.                                     &local_target_low, &local_target_up);
  126. }
  127.  
  128.      /*********************************************************
  129.      *                                                        *
  130.      *  pid_low - pid_up : Processes that will get elements   *
  131.      *                     from the source array              *
  132.      *                                                        *
  133.      *********************************************************/
  134.  
  135. void dalib_move_source_pids (pid_low, pid_up)
  136. int *pid_low, *pid_up;
  137.  
  138. { /* find pids where source has to send elements to */
  139.  
  140.   int def_target_low, def_target_up;
  141.  
  142.   if (local_source_low > local_source_up)
  143.     { /* this process has no elements for other processes */
  144.       *pid_low = 2;
  145.       *pid_up  = 1;
  146.     }
  147.    else if (move_kind == 0) 
  148.     { /* many <-> many */
  149.  
  150.       /* get the range of target that is defined by my local source */
  151.       def_target_low = local_source_low + move_constant;
  152.       def_target_up  = local_source_up + move_constant;
  153.       *pid_low = dalib_where (target_size, def_target_low);
  154.       *pid_up = dalib_where (target_size, def_target_up);
  155.     }
  156.    else if (move_kind == 2)
  157.     { /* one -> many, my elements are for all other */
  158.       *pid_low = dalib_where (target_size, target_low);
  159.       *pid_up  = dalib_where (target_size, target_up);
  160.     }
  161.    else 
  162.     { /* my element(s) are only for one processor , target_low == target_up */
  163.       *pid_low = dalib_where (target_size, target_low);
  164.       *pid_up  = *pid_low;
  165.     }
  166.  
  167.   /* 
  168.   printf ("Process %d will send processes %d - %d\n",
  169.           pcb.i, *pid_low, *pid_up);
  170.   */
  171. }
  172.  
  173.      /*********************************************************
  174.      *                                                        *
  175.      *  t_pid : Process that gets elements from my source     *
  176.      *                                                        *
  177.      *  low : up : Interval of my source that has to be sent  *
  178.      *                                                        *
  179.      *********************************************************/
  180.  
  181. void dalib_move_source_range (t_pid, low, up)
  182. int t_pid, *low, *up;
  183.  
  184. { /* finds source range that has to be sent to t_pid */
  185.   int n;
  186.   int a_low, a_up;
  187.   int s_low, s_up;
  188.  
  189.   n = pcb.p;
  190.  
  191.   dalib_local_extensions (t_pid, target_size, &a_low, &a_up);
  192.  
  193.   /* a_low:a_up is local range of target of t_pid */
  194.  
  195.   if (move_kind == 0)
  196.      { /* many <- many, b(7:11) = a(8:12) */
  197.        s_low = a_low - move_constant;
  198.        s_up  = a_up  - move_constant;
  199.        /* s_low .. s_up is range of source for t_pid, give it if I have */
  200.        if (s_low < local_source_low) s_low = local_source_low;
  201.        if (s_up  > local_source_up)  s_up  = local_source_up;
  202.      }
  203.    else if (move_kind == 2)
  204.      { /* many <- one,  b(7:11) = a(8:12,4) */
  205.        /* restrict full range of a to the slice */
  206.        if (a_low < target_low) a_low = target_low;
  207.        if (a_up  > target_up)  a_up  = target_up;
  208.        /* normalize it for splitting up other dimension */
  209.        s_low = a_low - target_low;
  210.        s_up  = a_up  - target_low;
  211.      }
  212.    else 
  213.      { /* all my elements are for one processor */
  214.        s_low = local_source_low;
  215.        s_up  = local_source_up;
  216.      }
  217.   *low = s_low;
  218.   *up  = s_up;
  219. }
  220.  
  221.      /*********************************************************
  222.      *                                                        *
  223.      *  pid_low - pid_up : Processes that have sent elements  *
  224.      *                     from the source array              *
  225.      *                                                        *
  226.      *********************************************************/
  227.  
  228. void dalib_move_target_pids (pid_low, pid_up)
  229. int *pid_low, *pid_up;
  230.  
  231. { /* find pids where target will receive elements from */
  232.  
  233.   int def_source_low, def_source_up;
  234.  
  235.   if (local_target_low > local_target_up)
  236.     { /* this process needs no elements from other processes */
  237.       *pid_low = 2;
  238.       *pid_up  = 1;
  239.     }
  240.    else if (move_kind == 0)
  241.     { /* many <-> many */
  242.       /* get the range of source that is needed for my local target */
  243.       def_source_low = local_target_low - move_constant;
  244.       def_source_up  = local_target_up  - move_constant;
  245.       *pid_low = dalib_where (source_size, def_source_low);
  246.       *pid_up = dalib_where (source_size, def_source_up);
  247.     }
  248.    else if (move_kind == 1)
  249.     { /* many -> one, I get elements from all other */
  250.       *pid_low = dalib_where (source_size, source_low);
  251.       *pid_up  = dalib_where (source_size, source_up);
  252.     }
  253.    else
  254.     { /* get elements only from one processor, source_low == source_up */
  255.       *pid_low = dalib_where (source_size, source_low);
  256.       *pid_up  = *pid_low;
  257.     }
  258.  
  259.   /*
  260.   printf ("Process %d will receive from processes %d - %d\n",
  261.           pcb.i, *pid_low, *pid_up);
  262.   */
  263. }
  264.  
  265.      /*********************************************************
  266.      *                                                        *
  267.      *  t_pid : Process that has elements for my target       *
  268.      *                                                        *
  269.      *  low : up : Interval of my target that has to be recvd *
  270.      *                                                        *
  271.      *********************************************************/
  272.  
  273. void dalib_move_target_range (t_pid, low, up)
  274. int t_pid, *low, *up;
  275.  
  276. { /* finds target range that I will get from t_pid */
  277.   int n;
  278.   int a_low, a_up;
  279.   int t_low, t_up;
  280.  
  281.   n = pcb.p;
  282.   dalib_local_extensions (t_pid, source_size, &a_low, &a_up);
  283.  
  284.   /* a_low .. a_up is local range of source of t_pid */
  285.  
  286.   if (move_kind == 0)
  287.     { /* many <- many, e.g. b(7:11) = a(8:12) */
  288.       t_low = a_low + move_constant;
  289.       t_up  = a_up  + move_constant;
  290.       if (t_low < local_target_low) t_low = local_target_low;
  291.       if (t_up  > local_target_up ) t_up  = local_target_up ;
  292.     }
  293.    else if (move_kind == 1)
  294.     { /* one <- many, e.g. b(8:12,4) = a(7:11) */
  295.       /* restrict full range of a to the range */
  296.       if (a_low < source_low) a_low = source_low;
  297.       if (a_up  > source_up ) a_up  = source_up;
  298.       /* normalize it to have later access */
  299.       t_low = a_low - source_low;
  300.       t_up  = a_up  - source_low;
  301.     }
  302.    else 
  303.     { /* many <- one, one <- one , I get all elements from one processor */
  304.       t_low = local_target_low;
  305.       t_up  = local_target_up;
  306.     }
  307.  
  308.   *low = t_low;
  309.   *up  = t_up;
  310. }
  311.  
  312.      /*********************************************************
  313.      *                                                        *
  314.      *  Global sending of A[x1:y1]                            *
  315.      *                                                        *
  316.      *********************************************************/
  317.  
  318. void dalib_move_source1__ (a, size, N1, x1, y1)
  319. unsigned char *a;
  320. int *size;
  321. int *N1, *x1, *y1;
  322.  
  323. { int low_pid, up_pid, pid;
  324.   int hx1, hy1;
  325.   int from;
  326.  
  327.   from = dalib_pid_ ();
  328.  
  329.   if (*y1 < *x1) goto End;
  330.  
  331.   dalib_move_source_pids (&low_pid, &up_pid);
  332.  
  333.   /* I have to send local sections to low_pid .. up_pid */
  334.  
  335.   for (pid = low_pid; pid <= up_pid; pid++)
  336.     { dalib_move_source_range (pid, &hx1, &hy1);
  337. #ifdef DEBUG
  338.       printf ("%d sends range1 %d - %d to %d\n", from, hx1, hy1, pid);
  339. #endif 
  340.       dalib_setup_section1 (*size, *N1, hx1, hy1);
  341.       dalib_send_section1 (pid, a);
  342.     }
  343.    End: ;
  344. }
  345.  
  346.      /*********************************************************
  347.      *                                                        *
  348.      *  Global sending of A[x1:y1,x2:y2]                      *
  349.      *                                                        *
  350.      *********************************************************/
  351.  
  352. void dalib_move_source2__ (a, size, N1, x1, y1, N2, x2, y2)
  353. unsigned char *a;
  354. int *size;
  355. int *N1, *x1, *y1, *N2, *x2, *y2;
  356.  
  357. { int low_pid, up_pid, pid;
  358.   int hx2, hy2;
  359.   int from;
  360.   int dim;
  361.  
  362.   if (*y1 < *x1) goto End;
  363.   if (*y2 < *x2) goto End;
  364.  
  365.   from = dalib_pid_ ();
  366.  
  367.   dalib_move_source_pids (&low_pid, &up_pid);
  368.  
  369.   /* I have to send local sections to low_pid .. up_pid */
  370.  
  371.   if (move_kind == 2)
  372.      { /* many <- one, b(7:11) = a(8:12,4) so the problem is to
  373.           find the dimension of a for which sections are splitted */
  374.        dim = 1;
  375.      }
  376.     else
  377.      dim = 2;
  378.  
  379.   for (pid = low_pid; pid <= up_pid; pid++)
  380.     { dalib_move_source_range (pid, &hx2, &hy2);
  381.       if (dim == 2)
  382.         {
  383. #ifdef DEBUG
  384.           printf ("%d sends range2 %d - %d, %d - %d to %d\n",
  385.                    from, *x1, *y1, hx2, hy2, pid);
  386. #endif
  387.           dalib_setup_section2 (*size, *N1, *x1, *y1, 
  388.                                        *N2, hx2, hy2);
  389.         }
  390.        else
  391.         {
  392. #ifdef DEBUG
  393.           printf ("%d sends 1->n range2 %d - %d, %d - %d to %d\n",
  394.                    from, *x1+hx2, *x1+hy2, *x2, *y2, pid);
  395. #endif
  396.           dalib_setup_section2 (*size, *N1, *x1 + hx2, *x1 + hy2, 
  397.                                        *N2, *x2, *y2);
  398.         }
  399.       dalib_send_section2 (pid, a);
  400.     }
  401.   End:;
  402. }
  403.  
  404.      /*********************************************************
  405.      *                                                        *
  406.      *  Global sending of A[x1:y1,x2:y2,x3:y3]                *
  407.      *                                                        *
  408.      *********************************************************/
  409.  
  410. void dalib_move_source3__ (a, size, N1, x1, y1, N2, x2, y2, N3, x3, y3)
  411. unsigned char *a;
  412. int *size;
  413. int *N1, *x1, *y1, *N2, *x2, *y2, *N3, *x3, *y3;
  414.  
  415. { int low_pid, up_pid, pid;
  416.   int hx3, hy3;
  417.   int from;
  418.   int dim;
  419.  
  420.   if (*y1 < *x1) goto End;
  421.   if (*y2 < *x2) goto End;
  422.   if (*y3 < *x3) goto End;
  423.  
  424.   from = dalib_pid_ ();
  425.  
  426.   dalib_move_source_pids (&low_pid, &up_pid);
  427.  
  428.   if (move_kind == 2)
  429.      { /* many <- one, b(7:11) = a(8:12,..,4) so the problem is to
  430.           find the dimension of a for which sections are splitted */
  431.        if (*x2 != *y2)
  432.           dim = 2;
  433.         else
  434.           dim = 1;
  435.      }
  436.     else
  437.      dim = 3;
  438.  
  439.   /* I have to send local sections to low_pid .. up_pid */
  440.  
  441.   for (pid = low_pid; pid <= up_pid; pid++)
  442.   /* I have to send local sections to low_pid .. up_pid */
  443.  
  444.   for (pid = low_pid; pid <= up_pid; pid++)
  445.     { dalib_move_source_range (pid, &hx3, &hy3);
  446.       if (dim == 3)
  447.         {
  448. #ifdef DEBUG
  449.           printf ("%d sends range3 %d - %d, %d - %d, %d - %d to %d\n",
  450.                    from, *x1, *y1, *x2, *y2, hx3, hy3, pid);
  451. #endif
  452.           dalib_setup_section3 (*size, *N1, *x1, *y1, 
  453.                                        *N2, *x2, *y2, 
  454.                                        *N3, hx3, hy3);
  455.         }
  456.        else if (dim == 2)
  457.         {
  458. #ifdef DEBUG
  459.           printf ("%d sends 1->n range3 %d - %d, %d - %d, %d - %d to %d\n",
  460.                    from, *x1, *y1, *x2+hx3, *x2+hy3, *x3, *y3, pid);
  461. #endif
  462.           dalib_setup_section3 (*size, *N1, *x1,*y1,
  463.                                        *N2, *x2+hx3,*x2+hy3,
  464.                                        *N3, *x3,*y3);
  465.         }
  466.        else 
  467.         {
  468. #ifdef DEBUG
  469.           printf ("%d sends 1->n range3 %d - %d, %d - %d, %d - %d to %d\n",
  470.                    from, *x1+hx3,*x1+hy3, *x2, *y2, *x3, *y3, pid);
  471. #endif
  472.           dalib_setup_section3 (*size, *N1, *x1+hx3, *x1+hy3,
  473.                                        *N2, *x2,     *y2,
  474.                                        *N3, *x3,     *y3);
  475.         }
  476.       dalib_send_section3 (pid, a);
  477.     }
  478.   End:;
  479. }
  480.  
  481.      /*********************************************************
  482.      *                                                        *
  483.      *  Global sending of A[x1:y1,x2:y2,x3:y3,x4:y4]          *
  484.      *                                                        *
  485.      *********************************************************/
  486.  
  487. void dalib_move_source4__ (a, size, N1, x1, y1, N2, x2, y2, 
  488.                                    N3, x3, y3, N4, x4, y4)
  489. unsigned char *a;
  490. int *size;
  491. int *N1, *x1, *y1, *N2, *x2, *y2, *N3, *x3, *y3, *N4, *x4, *y4;
  492.  
  493. { int low_pid, up_pid, pid;
  494.   int hx4, hy4;
  495.   int from;
  496.   int dim;
  497.  
  498.   if (*y1 < *x1) goto End;
  499.   if (*y2 < *x2) goto End;
  500.   if (*y3 < *x3) goto End;
  501.   if (*y4 < *x4) goto End;
  502.  
  503.   from = dalib_pid_ ();
  504.  
  505.   dalib_move_source_pids (&low_pid, &up_pid);
  506.  
  507.   if (move_kind == 2)
  508.      { /* many <- one, b(7:11) = a(8:12,..,4) so the problem is to
  509.           find the dimension of a for which sections are splitted */
  510.        if (*x3 != *y3)
  511.           dim = 3;
  512.         else if (*x2 != *y2)
  513.           dim = 2;
  514.         else
  515.           dim = 1;
  516.      }
  517.     else
  518.      dim = 4;
  519.  
  520.   /* I have to send local sections to low_pid .. up_pid */
  521.  
  522.   for (pid = low_pid; pid <= up_pid; pid++)
  523.     { dalib_move_source_range (pid, &hx4, &hy4);
  524.       if (dim == 4)
  525.         { /* usual case */
  526. #ifdef DEBUG
  527.           printf ("%d sends range4 %d - %d, %d - %d, %d - %d, %d - %d to %d\n",
  528.                    from, *x1, *y1, *x2, *y2, *x3, *y3, hx4, hy4, pid);
  529. #endif
  530.           dalib_setup_section4 (*size, *N1, *x1, *y1, 
  531.                                        *N2, *x2, *y2, 
  532.                                        *N3, *x3, *y3, 
  533.                                        *N4, hx4, hy4);
  534.         }
  535.        else if (dim == 3)
  536.         {
  537. #ifdef DEBUG
  538.           printf ("%d sends 1->n range4 %d-%d,%d-%d,%d-%d,%d-%d to %d\n",
  539.                    from, *x1,*y1,*x2,*y2,*x3+hx4,*x4+hy4,*x4,*y4, pid);
  540. #endif
  541.           dalib_setup_section4 (*size, *N1, *x1,*y1,
  542.                                        *N2, *x2,*y2,
  543.                                        *N3, *x3+hx4,*x3+hy4,
  544.                                        *N4, *x4,*y4);
  545.         }
  546.        else if (dim == 2)
  547.         {
  548. #ifdef DEBUG
  549.           printf ("%d sends 1->n range4 %d-%d,%d-%d,%d-%d,%d-%d to %d\n",
  550.                    from, *x1,*y2,*x2+hx4,*x2+hy4,*x3,*y3,*x4,*y4, pid);
  551. #endif
  552.           dalib_setup_section4 (*size, *N1, *x1,*y1,
  553.                                        *N2, *x2+hx4,*x2+hy4,
  554.                                        *N3, *x3,*y3,
  555.                                        *N4, *x4,*y4);
  556.         }
  557.        else 
  558.         {
  559. #ifdef DEBUG
  560.           printf ("%d sends 1->n range4 %d-%d,%d-%d,%d-%d,%d-%d to %d\n",
  561.                    from, *x1+hx4,*x1+hy4,*x2,*y2,*x3,*y3,*x4,*y4, pid);
  562. #endif
  563.           dalib_setup_section4 (*size, *N1, *x1+hx4,*x1+hy4,
  564.                                        *N2, *x2,*y2,
  565.                                        *N3, *x3,*y3,
  566.                                        *N4, *x4,*y4);
  567.         }
  568. #ifdef DEBUG
  569.       printf ("%d sends range4 %d - %d to %d\n", from, hx4, hy4, pid);
  570. #endif
  571.       dalib_send_section4 (pid, a);
  572.     }
  573.   End:;
  574. }
  575.  
  576.      /*********************************************************
  577.      *                                                        *
  578.      *  Global receiving of A[x1:y1]                          *
  579.      *                                                        *
  580.      *********************************************************/
  581.  
  582. void dalib_move_target1__ (a, size, N1, x1, y1)
  583. unsigned char *a;
  584. int *size;
  585. int *N1, *x1, *y1;
  586.  
  587. { int low_pid, up_pid, pid;
  588.   int hx1, hy1;
  589.   int to;
  590.  
  591.   if (*y1 < *x1) goto End;
  592.  
  593.   dalib_move_target_pids (&low_pid, &up_pid);
  594.  
  595.   to = dalib_pid_();
  596.  
  597.   /* I have to receive local section from low_pid .. up_pid */
  598.  
  599.   for (pid = low_pid; pid <= up_pid; pid++)
  600.     { dalib_move_target_range (pid, &hx1, &hy1);
  601. #ifdef DEBUG
  602.       printf ("%d recvs range1 %d - %d from %d\n", to, hx1, hy1, pid);
  603. #endif
  604.       dalib_setup_section1   (*size, *N1, hx1, hy1);
  605.       dalib_recv_section1   (pid, a);
  606.     }
  607.   End:;
  608. }
  609.  
  610.      /*********************************************************
  611.      *                                                        *
  612.      *  Global receiving of A[x1:y1,x2:y2]                    *
  613.      *                                                        *
  614.      *********************************************************/
  615.  
  616. void dalib_move_target2__ (a, size, N1, x1, y1, N2, x2, y2)
  617. unsigned char *a;
  618. int *size;
  619. int *N1, *x1, *y1, *N2, *x2, *y2;
  620.  
  621. { int low_pid, up_pid, pid;
  622.   int hx2, hy2;
  623.   int to;
  624.   int dim;
  625.  
  626.   if (*y1 < *x1) goto End;
  627.   if (*y2 < *x2) goto End;
  628.  
  629.   dalib_move_target_pids (&low_pid, &up_pid);
  630.  
  631.   to = dalib_pid_();
  632.  
  633.   /* I have to receive local section from low_pid .. up_pid */
  634.  
  635.   if (move_kind == 1)
  636.      { /* one <- many, b(7:11,4) = a(8:12) so the problem is to
  637.           find the dimension of b for which sections are splitted */
  638.        dim = 1;
  639.      }
  640.    else
  641.      dim = 2;
  642.  
  643.   for (pid = low_pid; pid <= up_pid; pid++)
  644.     { dalib_move_target_range (pid, &hx2, &hy2);
  645.       if (dim == 2)
  646.         {
  647. #ifdef DEBUG
  648.           printf ("%d recvs range2 %d - %d, %d - %d from %d\n",
  649.                    to, *x1, *y1, hx2, hy2, pid);
  650. #endif
  651.           dalib_setup_section2  (*size, *N1, *x1, *y1, 
  652.                                         *N2, hx2, hy2);
  653.         }
  654.         else
  655.         {
  656. #ifdef DEBUG
  657.           printf ("%d recvs n->1 range2 %d - %d, %d - %d from %d\n",
  658.                    to, *x1+hx2, *x1+hy2, *x2, *y2, pid);
  659. #endif
  660.           dalib_setup_section2  (*size, *N1, *x1+hx2, *x1+hy2, 
  661.                                         *N2, *x2, *y2);
  662.         }
  663.       dalib_recv_section2   (pid, a);
  664.     }
  665.   End:;
  666. }
  667.  
  668.      /*********************************************************
  669.      *                                                        *
  670.      *  Global receiving of A[x1:y1,x2:y2,x3:y3]              *
  671.      *                                                        *
  672.      *********************************************************/
  673.  
  674. void dalib_move_target3__ (a, size, N1, x1, y1, N2, x2, y2, N3, x3, y3)
  675. unsigned char *a;
  676. int *size;
  677. int *N1, *x1, *y1, *N2, *x2, *y2, *N3, *x3, *y3;
  678.  
  679. { int low_pid, up_pid, pid;
  680.   int hx3, hy3;
  681.   int to;
  682.   int dim;
  683.  
  684.   if (*y1 < *x1) goto End;
  685.   if (*y2 < *x2) goto End;
  686.   if (*y3 < *x3) goto End;
  687.  
  688.   dalib_move_target_pids (&low_pid, &up_pid);
  689.  
  690.   to = dalib_pid_();
  691.  
  692.   if (move_kind == 1)
  693.      { /* one <- many, b(7:11,...,4) = a(8:12) so the problem is to
  694.           find the dimension of b for which sections are splitted */
  695.        if (*x2 != *y2)
  696.           dim = 2;
  697.        else
  698.           dim = 1;
  699.      }
  700.    else
  701.      dim = 3;
  702.  
  703.   /* I have to receive local section from low_pid .. up_pid */
  704.  
  705.   for (pid = low_pid; pid <= up_pid; pid++)
  706.     { dalib_move_target_range (pid, &hx3, &hy3);
  707.       if (dim == 3)
  708.         { /* usual case */
  709. #ifdef DEBUG
  710.           printf ("%d recvs range3 %d - %d, %d - %d, %d - %d from %d\n",
  711.                    to, *x1, *y1, *x2, *y2, hx3, hy3, pid);
  712. #endif
  713.           dalib_setup_section3  (*size, *N1, *x1, *y1, 
  714.                                         *N2, *x2, *y2, 
  715.                                         *N3, hx3, hy3);
  716.         }
  717.         else if (dim == 2)
  718.         {
  719. #ifdef DEBUG
  720.           printf ("%d recvs n->1 range3 %d-%d,%d-%d,%d-%d from %d\n",
  721.                    to, *x1,*y1,*x2+hx3,*x2+hy3,*x3,*y3, pid);
  722. #endif
  723.           dalib_setup_section3  (*size, *N1, *x1,*y1,
  724.                                         *N2, *x2+hx3,*x2+hy3,
  725.                                         *N3, *x3,*y3);
  726.         }
  727.         else
  728.         {
  729. #ifdef DEBUG
  730.           printf ("%d recvs n->1 range3 %d-%d,%d-%d,%d-%d from %d\n",
  731.                    to, *x1,*y1,*x2,*y2,*x3,*y3, pid);
  732. #endif
  733.           dalib_setup_section3  (*size, *N1, *x1,*y1,
  734.                                         *N2, *x2,*y2,
  735.                                         *N3, *x3,*y3);
  736.         }
  737.       dalib_recv_section3   (pid, a);
  738.     }
  739.   End:;
  740. }
  741.  
  742.      /*********************************************************
  743.      *                                                        *
  744.      *  Global receiving of A[x1:y1,x2:y2,x3:y3,x4:y4]        *
  745.      *                                                        *
  746.      *********************************************************/
  747.  
  748. void dalib_move_target4__ (a, size, N1, x1, y1, N2, x2, y2, 
  749.                                    N3, x3, y3, N4, x4, y4)
  750. unsigned char *a;
  751. int *size;
  752. int *N1, *x1, *y1, *N2, *x2, *y2, *N3, *x3, *y3, *N4, *x4, *y4;
  753.  
  754. { int low_pid, up_pid, pid;
  755.   int hx4, hy4;
  756.   int to;
  757.   int dim;
  758.  
  759.   if (*y1 < *x1) goto End;
  760.   if (*y2 < *x2) goto End;
  761.   if (*y3 < *x3) goto End;
  762.   if (*y4 < *x4) goto End;
  763.  
  764.   dalib_move_target_pids (&low_pid, &up_pid);
  765.  
  766.   to = dalib_pid_();
  767.  
  768.   if (move_kind == 1)
  769.      { /* one <- many, b(7:11,...,4) = a(8:12) so the problem is to
  770.           find the dimension of b for which sections are splitted */
  771.        if (*x3 != *y3)
  772.           dim = 3;
  773.        else if (*x2 != *y2)
  774.           dim = 2;
  775.        else
  776.           dim = 1;
  777.      }
  778.    else
  779.      dim = 4;
  780.  
  781.   /* I have to receive local section from low_pid .. up_pid */
  782.  
  783.   for (pid = low_pid; pid <= up_pid; pid++)
  784.     { dalib_move_target_range (pid, &hx4, &hy4);
  785.       if (dim == 4)
  786.         { /* usual case */
  787. #ifdef DEBUG
  788.           printf ("%d recvs range4 %d-%d, %d-%d, %d-%d, %d-%d from %d\n",
  789.                    to, *x1, *y1, *x2, *y2, *x3, *y3, hx4, hy4, pid);
  790. #endif
  791.           dalib_setup_section4  (*size, *N1, *x1, *y1, 
  792.                                         *N2, *x2, *y2, 
  793.                                         *N3, *x3, *y3, 
  794.                                         *N4, hx4, hy4);
  795.         }
  796.         else if (dim == 3)
  797.         {
  798. #ifdef DEBUG
  799.           printf ("%d recvs n->1 range4 %d-%d,%d-%d,%d-%d,%d-%d from %d\n",
  800.                    to, *x1,*y1,*x2,*y2,*x3+hx4,*x3+hy4,*x4,*y4, pid);
  801. #endif
  802.           dalib_setup_section4  (*size, *N1, *x1,*y1,
  803.                                         *N2, *x2,*y2,
  804.                                         *N3, *x3+hx4,*x3+hy4,
  805.                                         *N4, *x4,*y4);
  806.         }
  807.         else if (dim == 2)
  808.         {
  809. #ifdef DEBUG
  810.           printf ("%d recvs n->1 range4 %d-%d,%d-%d,%d-%d,%d-%d from %d\n",
  811.                    to, *x1,*y1,*x2+hx4,*x2+hy4,*x3,*y3,*x4,*y4, pid);
  812. #endif
  813.           dalib_setup_section4  (*size, *N1, *x1,*y1,
  814.                                         *N2, *x2+hx4,*x2+hy4,
  815.                                         *N3, *x3,*y3,
  816.                                         *N4, *x4,*y4);
  817.         }
  818.         else 
  819.         {
  820. #ifdef DEBUG
  821.           printf ("%d recvs n->1 range4 %d-%d,%d-%d,%d-%d,%d-%d from %d\n",
  822.                    to, *x1+hx4,*x1+hy4,*x2,*y2,*x3,*y3,*x4,*y4, pid);
  823. #endif
  824.           dalib_setup_section4  (*size, *N1, *x1+hx4,*x1+hy4,
  825.                                         *N2, *x2,*y2,
  826.                                         *N3, *x3,*y3,
  827.                                         *N4, *x4,*y4);
  828.         }
  829.       dalib_recv_section4   (pid, a);
  830.     }
  831.   End:;
  832. }
  833.