


bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



NAME
     bsp_put, bsp_hpput - deposit data into  a  remote  processes
     memory


C SYNOPSIS
     #include "bsp.h"

     void bsp_put(int _p_i_d,const void *_s_r_c,void *_d_s_t,int _o_f_f_s_e_t,int _n_b_y_t_e_s);

     void bsp_hpput(int _p_i_d,const void *_s_r_c,void *_d_s_t,int _o_f_f_s_e_t,int _n_b_y_t_e_s);

FORTRAN SYNOPSIS
     SUBROUTINE  bspput(_p_i_d,_s_r_c,_d_s_t,_o_f_f_s_e_t,_n_b_y_t_e_s)
       INTEGER, intent(IN)  :: _p_i_d,_o_f_f_s_e_t,_n_b_y_t_e_s
       <TYPE>,  intent(IN)  :: _s_r_c
       <TYPE>,  intent(OUT) :: _d_s_t

     SUBROUTINE  bsphpput(_p_i_d,_s_r_c,_d_s_t,_o_f_f_s_e_t,_n_b_y_t_e_s)
       INTEGER, intent(IN)  :: _p_i_d,_o_f_f_s_e_t,_n_b_y_t_e_s
       <TYPE>,  intent(IN)  :: _s_r_c
       <TYPE>,  intent(OUT) :: _d_s_t

DESCRIPTION
     The aim of bsp_put(3) and  bsp_hpput(3)  is  to  provide  an
     operation  akin  memcpy(3C) available in the Unix <_s_t_r_i_n_g._h>
     library.  Both operations copy a specified number of  bytes,
     from  a byte addressed data structure in the local memory of
     one process into contiguous memory locations  in  the  local
     memory of another process. The distinguishing factor between
     these operations is provided by the buffering choice.

     The semantics _b_u_f_f_e_r_e_d _o_n _s_o_u_r_c_e,  _b_u_f_f_e_r_e_d  _o_n  _d_e_s_t_i_n_a_t_i_o_n
     (see  drma(3))  is used for bsp_put(3) communications. While
     the semantics is clean and safety  is  maximised,  puts  may
     unduly  tax  the memory resources of a system. Consequently,
     bsplib(3) also provides a  _h_i_g_h  _p_e_r_f_o_r_m_a_n_c_e  _p_u_t  operation
     bsp_hpput(3)  whose  semantics  is  {_u_n_b_u_f_f_e_r_e_d  _o_n  _s_o_u_r_c_e,
     _u_n_b_u_f_f_e_r_e_d _o_n  _d_e_s_t_i_n_a_t_i_o_n  .  The  use  of  this  operation
     requires  care  as  correct data delivery is only guaranteed
     if: (1) no communications alter the source area; (2) no sub-
     sequent  local  computations  alter  the source area; (3) no
     other communications alter the destination area; and (4)  no
     computation  on  the  remote  process alters the destination
     area during the entire superstep. The main advantage of this
     operation  is  its economical use of memory. It is therefore
     particularly  useful  for  applications   which   repeatedly
     transfer large data sets.


EXAMPLES
     1)   The  _r_e_v_e_r_s_e  function  shown  below   highlights   the



Oxford BSP Toolset  Last change: 1.4 25/9/98                    1






bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



          interaction  between  registration  and  put communica-
          tions. This example defines a simple collective commun-
          ication  operation, in which all processes have to call
          the function within the same superstep. The  result  of
          the  function  on  process  _i  will be the value of the
          parameter _x from process _b_s_p__n_p_r_o_c_s()-_i-_1.

          int reverse(int x) {
            bsp_push_reg(&x,sizeof(int));
            bsp_sync();

            bsp_put(bsp_nprocs()-bsp_pid()-1,&x,&x,0,sizeof(int));
            bsp_sync();
            bsp_pop_reg(&x);
            return x;
          }

          The function would be defined in Fortran as:

                  INTEGER FUNCTION reverse(x)
                    INCLUDE 'fbsp.h'
                    INTEGER x

                    CALL bsppushreg(x,BSPINT)
                    CALL bspsync()

                    CALL bspput(bspnprocs()-bsppid()-1,x,x,0,BSPINT)
                    CALL bspsync()
                    CALL bsppopreg(x)
                    reverse=x
                  END

          By the end of the first superstep,  identified  by  the
          first   bsp_sync(3),   all   the  processes  will  have
          registered the  parameter  _x  as  being  available  for
          remote access by any subsequent drma(3) operation. Dur-
          ing the second superstep, each  process  transfers  its
          local copy of the variable _x into a remote copy on pro-
          cess _b_s_p__n_p_r_o_c_s()-_b_s_p__p_i_d()-_1 . Although communications
          occur  to  and  from  the same variable within the same
          superstep, the algorithm does not suffer from  problems
          of  concurrent  assignment  because  of the buffered on
          source,   buffered   on   destination   semantics    of
          bsp_put(3).  This  buffering ensures conflict-free com-
          munication between the outgoing communication  from  _x,
          and  any incoming transfers from remote processes.  The
          popregister at the end of the function  reinstates  the
          registration  properties  that  were active on entry to
          the function _a_t _t_h_e _n_e_x_t bsp_sync(3) _e_n_c_o_u_n_t_e_r_e_d _d_u_r_i_n_g
          _e_x_e_c_u_t_i_o_n.

          As can be seen from the Fortran code  above,  bsplib(3)



Oxford BSP Toolset  Last change: 1.4 25/9/98                    2






bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



          defines   a  collection  of  constant  parameters  that
          specify the size, _i_n  _b_y_t_e_s,  of  the  various  Fortran
          data-types.   _B_S_P_W_O_R_D,   _B_S_P_I_N_T,  _B_S_P_L_O_G_I_C_A_L,  _B_S_P_R_E_A_L,
          _B_S_P_D_O_U_B_L_E, and _B_S_P_C_O_M_P_L_E_X can be used by including  the
          file _f_b_s_p._h within a compilation unit. The relationship
          between the sizes of each of these types  follows  that
          of Fortran 77. i.e.,

          BSPWORD   = BSPINT    = BSPLOGICAL = BSPREAL
          2*BSPWORD = BSPDOUBLE = BSPCOMPLEX


     2)   The procedure _p_u_t__a_r_r_a_y _s_h_o_w_n  _b_e_l_o_w  _h_a_s  _a  _s_e_m_a_n_t_i_c_s
          assignment:

          forall i in {0,..n-1} xs[xs[i]] := xs[i]

          Conceptually, the algorithm manipulates a global  array
          _x_s  of  _n  elements  that  are  distributed  among  the
          processes.  The role of bsplib(3)  is  to  provide  the
          infrastructure  for  the  user to take care of the data
          distribution, and any implied  communication  necessary
          to manipulate parts of the data structure that are on a
          remote process. Therefore, if the user distributes  the
          global array in a block-wise manner (i.e., process zero
          gets elements 0 to _n/(_p-_1), process  one  gets  _n/_p  to
          (_2_n)/(_p-_1), etc.) with each process owning an _n/_p chunk
          of elements, then the bsplib(3)  communications  neces-
          sary  to  perform  the  concurrent assignment are shown
          below.

          void put_array(int *xs, int n) {
            int i,pid,local_idx,n_over_p= n/bsp_nprocs();
            if ((n % bsp_nprocs()) != 0)
              bsp_abort("{put_array} n=%d not divisible by p=%d",
                        n,bsp_nprocs());
            bsp_push_reg(xs,n_over_p*sizeof(int));
            bsp_sync();

            for(i=0;i<n_over_p;i++) {
              pid       = xs[i]/n_over_p;
              local_idx = xs[i]%n_over_p;
              bsp_put(pid,&xs[i],xs,local_idx*sizeof(int),sizeof(int));
            }
            bsp_sync();
            bsp_pop_reg(xs);
          }

          Similarly, the function can be defined in Fortran as:

                  SUBROUTINE putarray(xs,n)
                    INCLUDE 'fbsp.h'



Oxford BSP Toolset  Last change: 1.4 25/9/98                    3






bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



                    INTEGER xs(*),n
                    INTEGER i,pid,localidx,noverp

                    noverp=n/bspnprocs()
                    IF (MOD(n,bspnprocs()) .NE. 0) THEN
                      CALL bspabort('N not divisible by p')
                    END IF
                    CALL bsppushreg(xs,noverp*BSPINT)
                    CALL bspsync()

                    DO i=1,noverp
                      pid      = xs(i)/noverp
                      localidx = MOD(xs(i),noverp)
                      CALL bspput(pid,xs(i),xs,localidx*BSPINT,BSPINT)
                    END DO
                    CALL bspsync()
                    CALL bsppopreg(xs)
                  END

          The procedure highlights the use  of  bsp_abort(3)  and
          the  offset  parameter  in  bsp_put(3).  Each process's
          local section of the array  _x_s  is  registered  in  the
          first superstep. Next, _n/_p puts are performed, in which
          the global numbering  used  in  the  distributed  array
          (i.e., indices in the range 0 through to _n-_1), are con-
          verted into  pairs  of  process  identifier  and  local
          numbering  in  the range 0 to _n/(_p-_1). Once the conver-
          sion from the global scheme to  process-id/local  index
          has  been  performed,  elements  of  the  array  can be
          transferred into the correct index on a remote process.
          It  should  be  noted that if the value of the variable
          _p_i_d is the same as bsp_pid(3), then a local  assignment
          (i.e., memory copy) will occur _a_t _t_h_e _e_n_d _o_f _t_h_e _s_u_p_e_r_-
          _s_t_e_p.


     3)   Consider a function _c_y_c_l_i_c__s_h_i_f_t executed on each  pro-
          cess,  that  takes  an  integer  _x as its argument, and
          returns the value of _x on its  left  neighbouring  pro-
          cess.

          int cyclic_shift(int x) {
            bsp_push_reg(&x,sizeof(int));
            bsp_sync();
            bsp_put( (bsp_pid() + 1) % bsp_nprocs(),
                     &x,
                     &x,0,
                     sizeof(int));
            bsp_sync();
            bsp_pop_reg(&x);
            return x;
          }



Oxford BSP Toolset  Last change: 1.4 25/9/98                    4






bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



     4)   An alternative definition of _c_y_c_l_i_c _s_h_i_f_t that  uses  a
          high performance put.

          int cyclic_shift(int x) {
            int result;
            bsp_push_reg(&result,sizeof(int));
            bsp_sync();
            bsp_hpput( (bsp_pid() + 1) % bsp_nprocs(),
                       &x,
                       &result,0,
                       sizeof(int));
            bsp_sync();
            bsp_pop_reg(&result);
            return result;
          }


     5)   Consider a function  _b_s_p__a_l_l_s_u_m_s  that  calculates  the
          running  sums of _p values stored on _p processors. i.e.,
          if _x__i is stored on process _i, then the result on  each
          processor is _x__0 + .. _x__i.

          #include "bsp.h"
          #include <stdio.h>

          int bsp_allsums(int x) {
            int i, left, right;

            bsp_push_reg(&left,sizeof(int));
            bsp_sync();

            right=x;
            for(i=1;i<bsp_nprocs();i*=2) {
              if (bsp_pid()+i < bsp_nprocs())
                bsp_put(bsp_pid()+i,&right,&left,0,sizeof(int));
              bsp_sync();
              if (bsp_pid()>=i) right=left+right;
            }
            bsp_pop_reg(&left);
            return right;
          }

          void main() {
            int y;
            bsp_begin(bsp_nprocs());
            y = bsp_pid()+1;
            printf("y=%d sums=%d\n",y,bsp_allsums(y));
            bsp_end();
          }

          A compilation, and an example run on four processors is
          shown below:



Oxford BSP Toolset  Last change: 1.4 25/9/98                    5






bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



          pippin> bspcc allsums.c
          pippin> ./a.out
          y=4 sums=10
          y=2 sums=3
          y=1 sums=1
          y=3 sums=6


SEE ALSO
     drma(3),   bsp_push_reg(3),   bsp_pop_reg(3),    bsp_get(3),
     bsp_hpget(3)

     ``_B_S_P_l_i_b: _T_h_e _B_S_P _P_r_o_g_r_a_m_m_i_n_g _L_i_b_r_a_r_y'' Jonathan M. D. Hill,
     Bill  McColl,  Dan  C.  Stefanescu,  Mark W. Goudreau, Kevin
     Lang, Satish B. Rao, , Torsten Suel, Thanasis Tsantilas, and
     Rob  Bisseling.  Parallel  Computing,  to  appear  1998. See
     _h_t_t_p://_w_w_w._b_s_p-_w_o_r_l_d_w_i_d_e._o_r_g for more details.


NOTES
     i    The destination memory area used in a  put  has  to  be
          registered.  It  is an error to communicate into a data
          structure that has not been registered.


     ii   The source of a put does _n_o_t _h_a_v_e _t_o _b_e _r_e_g_i_s_t_e_r_e_d.


     iii  If the destination memory area _d_s_t is  registered  with
          size  _x,  then it is a bounds error to perform the com-
          munication _b_s_p__p_u_t(_p_i_d,_s_r_c,_d_s_t},_o,_n) if _o+_n>_x.


     iv   A communication of zero bytes does nothing.


     v    A process can communicate into its own memory if _p_i_d  =
          _b_s_p__p_i_d(). However, for bsp_put(3), due to the _b_u_f_f_e_r_e_d
          _a_t _d_e_s_t_i_n_a_t_i_o_n semantics, the memory  copy  only  takes
          effect _a_t _t_h_e _e_n_d _o_f _t_h_e _s_u_p_e_r_s_t_e_p.


     vi   The process numbering and offset parameter  start  from
          zero, even for the FORTRAN bindings of the operations.


BUGS
     Problems  and  bug  reports  should  be  mailed  to  _b_s_p_l_i_b-
     _b_u_g_s@_c_o_m_l_a_b._o_x._a_c._u_k






Oxford BSP Toolset  Last change: 1.4 25/9/98                    6






bsp_put(3)              BSPlib FUNCTIONS               bsp_put(3)



AUTHORS
     The Oxford BSP Toolset implementation of BSPlib was  written
     by Jonathan.Hill@comlab.ox.ac.uk
     http://www.comlab.ox.ac.uk/oucl/people/jonathan.hill.html



















































Oxford BSP Toolset  Last change: 1.4 25/9/98                    7



