1 /* #define LEARN_BCAST */
2 /***********************************************************************
6 The following is a notice of limited availability of the code and
7 Government license and disclaimer which must be included in the
8 prologue of the code and in all source listings of the code.
11 (c) 1977 University of Chicago
13 Permission is hereby granted to use, reproduce, prepare
14 derivative works, and to redistribute to others at no charge. If
15 you distribute a copy or copies of the Software, or you modify a
16 copy or copies of the Software or any portion of it, thus forming
17 a work based on the Software and make and/or distribute copies of
18 such work, you must meet the following conditions:
20 a) If you make a copy of the Software (modified or verbatim)
21 it must include the copyright notice and Government
22 license and disclaimer.
24 b) You must cause the modified Software to carry prominent
25 notices stating that you changed specified portions of
28 This software was authored by:
30 Argonne National Laboratory
31 J. Michalakes: (630) 252-6646; email: michalak@mcs.anl.gov
32 Mathematics and Computer Science Division
33 Argonne National Laboratory, Argonne, IL 60439
35 ARGONNE NATIONAL LABORATORY (ANL), WITH FACILITIES IN THE STATES
36 OF ILLINOIS AND IDAHO, IS OWNED BY THE UNITED STATES GOVERNMENT,
37 AND OPERATED BY THE UNIVERSITY OF CHICAGO UNDER PROVISION OF A
38 CONTRACT WITH THE DEPARTMENT OF ENERGY.
40 GOVERNMENT LICENSE AND DISCLAIMER
42 This computer code material was prepared, in part, as an account
43 of work sponsored by an agency of the United States Government.
44 The Government is granted for itself and others acting on its
45 behalf a paid-up, nonexclusive, irrevocable worldwide license in
46 this data to reproduce, prepare derivative works, distribute
47 copies to the public, perform publicly and display publicly, and
48 to permit others to do so. NEITHER THE UNITED STATES GOVERNMENT
49 NOR ANY AGENCY THEREOF, NOR THE UNIVERSITY OF CHICAGO, NOR ANY OF
50 THEIR EMPLOYEES, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
51 ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY,
52 COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS,
53 PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD
54 NOT INFRINGE PRIVATELY OWNED RIGHTS.
56 ***************************************************************************/
58 #define MAX(a,b) (((a)>(b))?a:b)
71 typedef struct bcast_point_desc
{
74 } bcast_point_desc_t
;
77 static destroy_par_info ( p
)
80 if ( p
!= NULL
) RSL_FREE( p
) ;
83 static destroy_list( list
, dfcn
)
84 rsl_list_t
** list
; /* pointer to pointer to list */
85 int (*dfcn
)() ; /* pointer to function for destroying
86 the data field of the list */
88 rsl_list_t
*p
, *trash
;
89 if ( list
== NULL
) return(0) ;
90 if ( *list
== NULL
) return(0) ;
91 for ( p
= *list
; p
!= NULL
; )
93 if ( dfcn
!= NULL
) (*dfcn
)( p
->data
) ;
103 static rsl_list_t
*Xlist
, *Xp
, *Xprev
;
104 static rsl_list_t
*stage
;
105 static int stage_len
= 0 ; /* 96/3/15 */
107 static int Sendbufsize
;
108 static int Sendbufcurs
;
109 static char *Sendbuf
;
110 static int Sdisplacements
[RSL_MAXPROC
] ;
111 static int Ssizes
[RSL_MAXPROC
] ;
113 static int Recsizeindex
;
115 static int Rbufsize
;
116 static int Rbufcurs
;
117 static int Rpointcurs
;
118 static char *Recvbuf
;
119 static int Rdisplacements
[RSL_MAXPROC
+1] ;
120 static int Rsizes
[RSL_MAXPROC
] ;
128 static int s_idim_nst
;
129 static int s_jdim_nst
;
130 static int s_irax_n
;
131 static int s_irax_m
;
132 static int s_ntasks_nest_x
;
133 static int s_ntasks_nest_y
;
134 static int s_ntasks_par_x
;
135 static int s_ntasks_par_y
;
136 static rsl_list_t
**Plist
;
137 static int Plist_length
= 0 ;
138 static int Psize
[RSL_MAXPROC
] ;
139 static char *s_parent_msgs
;
140 static int s_parent_msgs_curs
;
141 static int s_remaining
; /* number of bytes left in a parent message before
142 the next point descriptor */
143 static int alltasks
, offset
;
145 /* add a field to a message outgoing for the specified child domain cell */
146 /* relies on rsl_ready_bcast having been called already */
147 /* sends are specified in terms of coarse domain */
149 static int s_i
, s_j
, s_ig
, s_jg
, s_cm
, s_cn
,
153 static rsl_list_t
*Pptr
;
156 static int s_putmsg
= 0 ;
159 // NOTES for PARALLELNESTING
160 // This routine is building a list of destination processes to send to on a communicator that .
161 // It needs the minor number of tasks on the nest's MPI mesh (just pass that in)
162 // Otherwise it doesn't need a communicator
164 RSL_LITE_NESTING_RESET (
169 for ( j
= 0 ; j
< RSL_MAXPROC
; j
++ ) {
171 Sdisplacements
[j
] = 0 ;
173 Rdisplacements
[j
] = 0 ;
175 Rdisplacements
[RSL_MAXPROC
] = 0 ;
176 if ( Plist
!= NULL
) {
177 for ( j
= 0 ; j
< Plist_length
; j
++ ) {
178 destroy_list ( &(Plist
[j
]), NULL
) ;
186 void RSL_LITE_TO_CHILD_INFO ( msize_p
, /* number of tasks in minor dim of nest's mesh */
187 cips_p
, cipe_p
, cjps_p
, cjpe_p
, /* patch dims of SOURCE DOMAIN */
188 iids_p
, iide_p
, ijds_p
, ijde_p
, /* domain dims of INTERMEDIATE DOMAIN */
189 nids_p
, nide_p
, njds_p
, njde_p
, /* domain dims of CHILD DOMAIN */
190 pgr_p
, shw_p
, /* nest ratio and stencil half width */
191 offset_p
, /* first task of the nest in me_and_mom communicator */
192 ntasks_par_x_p
, ntasks_par_y_p
, /* proc counts in x and y */
193 ntasks_nest_x_p
, ntasks_nest_y_p
, /* proc counts in x and y */
194 min_subdomain
, /* minimum width allowed for a subdomain in a dim ON PARENT */
196 idim_cd_p
, jdim_cd_p
,
201 cips_p
, cipe_p
, cjps_p
, cjpe_p
/* (i) c.d. patch dims */
202 ,iids_p
, iide_p
, ijds_p
, ijde_p
/* (i) n.n. global dims -- in WRF this will be intermediate domain */
203 ,nids_p
, nide_p
, njds_p
, njde_p
/* (i) n.n. global dims */
204 ,pgr_p
/* nesting ratio */
205 ,offset_p
/* first task of the nest in me_and_mom communicator */
206 ,ntasks_nest_x_p
, ntasks_nest_y_p
/* proc counts in x and y */
207 ,ntasks_par_x_p
, ntasks_par_y_p
/* proc counts in x and y */
209 ,icoord_p
/* i coordinate of nest in cd */
210 ,jcoord_p
/* j coordinate of nest in cd */
211 ,shw_p
/* stencil half width */
212 ,idim_cd_p
/* i width of nest in cd */
213 ,jdim_cd_p
/* j width of nest in cd */
214 ,msize_p
/* (I) Message size in bytes. */
215 ,ig_p
/* (O) Global N index of parent domain point. */
216 ,jg_p
/* (O) Global N index of parent domain point. */
217 ,retval_p
; /* (O) =1 if a valid point returned; =0 (zero) otherwise. */
227 if ( Plist
== NULL
) {
228 s_ntasks_par_x
= *ntasks_par_x_p
;
229 s_ntasks_par_y
= *ntasks_par_y_p
;
230 s_ntasks_nest_x
= *ntasks_nest_x_p
;
231 s_ntasks_nest_y
= *ntasks_nest_y_p
;
233 alltasks
= MAX( s_ntasks_nest_x
*s_ntasks_nest_y
+ offset
, s_ntasks_par_x
*s_ntasks_par_y
) ;
236 fprintf(stderr
,"s_ntasks_par_x %d\n",s_ntasks_par_x
) ;
237 fprintf(stderr
,"s_ntasks_par_y %d\n",s_ntasks_par_y
) ;
238 fprintf(stderr
,"s_ntasks_nest_x %d\n",s_ntasks_nest_x
) ;
239 fprintf(stderr
,"s_ntasks_nest_y %d\n",s_ntasks_nest_y
) ;
240 fprintf(stderr
,"%s %d offset %d\n",__FILE__
,__LINE__
,offset
) ;
241 fprintf(stderr
,"%s %d alltasks %d\n",__FILE__
,__LINE__
,alltasks
) ;
242 fprintf(stderr
,"%s %d a %d b %d\n",__FILE__
,__LINE__
,s_ntasks_nest_x
*s_ntasks_nest_y
+offset
,s_ntasks_par_x
*s_ntasks_par_y
) ;
245 /* construct Plist */
247 Plist
= RSL_MALLOC( rsl_list_t
* , alltasks
) ; /* big enough for nest points */
248 Plist_length
= alltasks
;
249 /* big enough for the mom and me communicator, which includes tasks for the parent and the nest */
250 for ( j
= 0 ; j
< alltasks
; j
++ ) {
252 Sdisplacements
[j
] = 0 ;
256 for ( j
= *cjps_p
; j
<= *cjpe_p
; j
++ )
258 for ( i
= *cips_p
; i
<= *cipe_p
; i
++ )
260 if ( ( *jcoord_p
<= j
&& j
<= *jcoord_p
+*jdim_cd_p
-1 ) && ( *icoord_p
<= i
&& i
<= *icoord_p
+*idim_cd_p
-1 ) ) {
261 ni
= ( i
- (*icoord_p
+ *shw_p
) ) * *pgr_p
+ 1 + 1 ; /* add 1 to give center point */
262 nj
= ( j
- (*jcoord_p
+ *shw_p
) ) * *pgr_p
+ 1 + 1 ;
265 TASK_FOR_POINT ( &ni
, &nj
, nids_p
, nide_p
, njds_p
, njde_p
, &s_ntasks_nest_x
, &s_ntasks_nest_y
, &Px
, &Py
,
266 min_subdomain
, min_subdomain
, &ierr
) ;
267 P
= Px
+ Py
* *ntasks_nest_x_p
+ offset
;
268 // coords[1] = Px ; coords[0] = Py ;
269 // MPI_Cart_rank( *comm, coords, &P ) ;
271 // adjust P so that is the rank in the intercomm_to_kid communicator for this parent/nest pair
272 //fprintf(stderr,"after tfp ni %d nj %d Px %d Py %d P %d ntx %d nty %d\n",ni,nj,Px,Py,P,*ntasks_nest_x_p,*ntasks_nest_y_p) ;
277 q
= RSL_MALLOC( rsl_list_t
, 1 ) ;
282 Sendbufsize
+= *msize_p
+ 3 * sizeof( int ) ; /* point data plus 3 ints for i, j, and size */
287 fprintf(stderr
,"rsl_to_child_info: ") ;
288 TASK_FOR_POINT_MESSAGE () ;
290 Sendbuf
= RSL_MALLOC( char , Sendbufsize
) ;
297 if ( Pptr
!= NULL
) {
301 if ( Recsizeindex
>= 0 ) {
302 r
= (int *) &(Sendbuf
[Recsizeindex
]) ;
303 *r
= Sendbufcurs
- Recsizeindex
+ 2 * sizeof(int) ;
304 Ssizes
[Pcurs
] += *r
;
307 while ( Pptr
== NULL
) {
309 while ( Pcurs
< alltasks
&& Plist
[Pcurs
] == NULL
) Pcurs
++ ;
310 if ( Pcurs
< alltasks
) {
311 Sdisplacements
[Pcurs
] = Sendbufcurs
;
313 Pptr
= Plist
[Pcurs
] ;
320 *ig_p
= Pptr
->info1
;
321 *jg_p
= Pptr
->info2
;
323 r
= (int *) &(Sendbuf
[Sendbufcurs
]) ;
324 *r
++ = Pptr
->info1
; Sendbufcurs
+= sizeof(int) ; /* ig to buffer */
325 *r
++ = Pptr
->info2
; Sendbufcurs
+= sizeof(int) ; /* jg to buffer */
326 Recsizeindex
= Sendbufcurs
;
327 *r
++ = 0 ; Sendbufcurs
+= sizeof(int) ; /* store start for size */
333 /********************************************/
336 void RSL_LITE_TO_PARENT_INFO ( msize_p
,
337 nips_p
, nipe_p
, njps_p
, njpe_p
, /* patch dims of SOURCE DOMAIN (CHILD) */
338 cids_p
, cide_p
, cjds_p
, cjde_p
, /* domain dims of TARGET DOMAIN (PARENT) */
340 ntasks_par_x_p
, ntasks_par_y_p
, /* proc counts in x and y */
341 ntasks_nest_x_p
, ntasks_nest_y_p
, /* proc counts in x and y */
344 idim_cd_p
, jdim_cd_p
,
348 nips_p
, nipe_p
, njps_p
, njpe_p
/* (i) n.d. patch dims */
349 ,cids_p
, cide_p
, cjds_p
, cjde_p
/* (i) n.n. global dims */
351 ,ntasks_nest_x_p
, ntasks_nest_y_p
/* proc counts in x and y */
352 ,ntasks_par_x_p
, ntasks_par_y_p
/* proc counts in x and y */
354 ,icoord_p
/* i coordinate of nest in cd */
355 ,jcoord_p
/* j coordinate of nest in cd */
356 ,idim_cd_p
/* i width of nest in cd */
357 ,jdim_cd_p
/* j width of nest in cd */
358 ,msize_p
/* (I) Message size in bytes. */
359 ,ig_p
/* (O) Global N index of parent domain point. */
360 ,jg_p
/* (O) Global N index of parent domain point. */
361 ,retval_p
; /* (O) =1 if a valid point returned; =0 (zero) otherwise. */
370 if ( Plist
== NULL
) {
371 s_ntasks_nest_x
= *ntasks_nest_x_p
;
372 s_ntasks_nest_y
= *ntasks_nest_y_p
;
373 s_ntasks_par_x
= *ntasks_par_x_p
;
374 s_ntasks_par_y
= *ntasks_par_y_p
;
376 alltasks
= MAX( s_ntasks_nest_x
*s_ntasks_nest_y
+ offset
, s_ntasks_par_x
*s_ntasks_par_y
) ;
378 /* construct Plist */
380 Plist
= RSL_MALLOC( rsl_list_t
* , alltasks
) ;
381 Plist_length
= alltasks
;
382 for ( j
= 0 ; j
< alltasks
; j
++ ) {
384 Sdisplacements
[j
] = 0 ;
388 for ( j
= *njps_p
; j
<= *njpe_p
; j
++ )
390 for ( i
= *nips_p
; i
<= *nipe_p
; i
++ )
392 if ( ( *jcoord_p
<= j
&& j
<= *jcoord_p
+*jdim_cd_p
-1 ) && ( *icoord_p
<= i
&& i
<= *icoord_p
+*idim_cd_p
-1 ) ) {
394 TASK_FOR_POINT ( &i
, &j
, cids_p
, cide_p
, cjds_p
, cjde_p
, &s_ntasks_par_x
, &s_ntasks_par_y
, &Px
, &Py
,
395 min_subdomain
, min_subdomain
, &ierr
) ;
396 P
= Px
+ Py
* *ntasks_par_x_p
; // we are computing parent task numbers, so no offset
400 q
= RSL_MALLOC( rsl_list_t
, 1 ) ;
405 Sendbufsize
+= *msize_p
+ 3 * sizeof( int ) ; /* point data plus 3 ints for i, j, and size */
410 fprintf(stderr
,"rsl_to_parent_info: ") ;
411 TASK_FOR_POINT_MESSAGE () ;
413 Sendbuf
= RSL_MALLOC( char , Sendbufsize
) ;
419 if ( Pptr
!= NULL
) {
423 if ( Recsizeindex
>= 0 ) {
424 r
= (int *) &(Sendbuf
[Recsizeindex
]) ;
425 *r
= Sendbufcurs
- Recsizeindex
+ 2 * sizeof(int) ;
426 Ssizes
[Pcurs
] += *r
;
429 while ( Pptr
== NULL
) {
431 while ( Pcurs
< alltasks
&& Plist
[Pcurs
] == NULL
) Pcurs
++ ;
432 if ( Pcurs
< alltasks
) {
433 Sdisplacements
[Pcurs
] = Sendbufcurs
;
435 Pptr
= Plist
[Pcurs
] ;
442 *ig_p
= Pptr
->info1
;
443 *jg_p
= Pptr
->info2
;
445 r
= (int *) &(Sendbuf
[Sendbufcurs
]) ;
446 *r
++ = Pptr
->info1
; Sendbufcurs
+= sizeof(int) ; /* ig to buffer */
447 *r
++ = Pptr
->info2
; Sendbufcurs
+= sizeof(int) ; /* jg to buffer */
448 Recsizeindex
= Sendbufcurs
;
449 *r
++ = 0 ; Sendbufcurs
+= sizeof(int) ; /* store start for size */
456 /********************************************/
459 RSL_TO_CHILD_MSG -- Pack force data into a message for a nest point.
464 RSL_LITE_TO_CHILD_MSG ( nbuf_p
, buf
)
466 nbuf_p
; /* (I) Number of bytes to be packed. */
468 buf
; /* (I) Buffer containing the data to be packed. */
470 rsl_lite_to_peerpoint_msg ( nbuf_p
, buf
) ;
474 RSL_LITE_TO_PARENT_MSG ( nbuf_p
, buf
)
476 nbuf_p
; /* (I) Number of bytes to be packed. */
478 buf
; /* (I) Buffer containing the data to be packed. */
480 rsl_lite_to_peerpoint_msg ( nbuf_p
, buf
) ;
484 rsl_lite_to_peerpoint_msg ( nbuf_p
, buf
)
486 nbuf_p
; /* (I) Number of bytes to be packed. */
488 buf
; /* (I) Buffer containing the data to be packed. */
496 RSL_TEST_ERR(buf
==NULL
,"2nd argument is NULL. Field allocated?") ;
500 if ( Sendbufcurs
+ nbuf
>= Sendbufsize
) {
501 sprintf(mess
,"rsl_lite_to_peerpoint_msg: Sendbufcurs + nbuf (%d) would exceed Sendbufsize (%d)\n",
502 Sendbufcurs
+ nbuf
, Sendbufsize
) ;
503 RSL_TEST_ERR(1,mess
) ;
506 if ( nbuf
% sizeof(int) == 0 ) {
507 for ( p
= (int *)buf
, q
= (int *) &(Sendbuf
[Sendbufcurs
]), i
= 0 ; i
< nbuf
; i
+= sizeof(int) )
514 for ( c
= buf
, d
= &(Sendbuf
[Sendbufcurs
]), i
= 0 ; i
< nbuf
; i
++ )
520 Sendbufcurs
+= nbuf
;
524 /********************************************/
526 // PARALLELNESTING NOTES
527 // what communicator should be passed and what are mytask and ntasks?
528 // I think it should be the mom_and_me communicator and the mytask and ntasks from
531 // nest if it's parent->nest and the parent if it's nest->parent (we'll see)
534 RSL_LITE_BCAST_MSGS ( mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, Fcomm
)
535 int_p mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, Fcomm
; /* offset is the id of the first task in the nest set */
540 comm
= MPI_Comm_f2c( *Fcomm
) ;
544 rsl_lite_allgather_msgs ( mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, comm
, 0 ) ;
548 RSL_LITE_MERGE_MSGS ( mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, Fcomm
)
549 int_p mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, Fcomm
; /* offset is the id of the first task in the nest set */
554 comm
= MPI_Comm_f2c( *Fcomm
) ;
558 rsl_lite_allgather_msgs ( mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, comm
, 1 ) ;
562 rsl_lite_allgather_msgs ( mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
, comm
, dir
)
563 int_p mytask_p
, ntasks_par_p
, ntasks_nest_p
, offset_p
;
564 int dir
; /* 0 = parent to nest, otherwist nest to parent */
574 bcast_point_desc_t pdesc
;
576 int msglen
, mdest
, mtag
;
577 int ntasks_par
, ntasks_nest
, ntasks
, mytask
;
585 ntasks_par
= *ntasks_par_p
;
586 ntasks_nest
= *ntasks_nest_p
;
588 MPI_Comm_rank( comm
, &mytask_on_comm
) ;
595 if ( ( mytask_on_comm
< ntasks_par
&& dir
== 0 ) /* parent in parent->child */
596 || ( mytask_on_comm
>= *offset_p
&&
597 mytask_on_comm
< *offset_p
+ ntasks_nest
&& dir
== 1 )) { /* child in child->parent */
598 RSL_TEST_ERR( Plist
== NULL
,
599 "rsl_lite_allgather_msgs: rsl_to_child_info or rsl_to_parent_info not called first" ) ;
603 ntasks
= MAX(ntasks_par
,ntasks_nest
+*offset_p
) ;
606 RSL_TEST_ERR( ntasks
>= RSL_MAXPROC
,
607 "rsl_lite_allgather_msgs: raise the compile time value of MAXPROC" ) ;
610 MPI_Alltoall(Ssizes
,1,MPI_INT
, Rsizes
,1,MPI_INT
,comm
);
612 Rsizes
[0] = Ssizes
[0];
615 for ( Rbufsize
= 0, P
= 0, Rdisplacements
[0] = 0 ; P
< ntasks
; P
++ )
617 Rdisplacements
[P
+1] = Rsizes
[P
] + Rdisplacements
[P
] ;
619 Rbufsize
+= Rsizes
[P
] ;
622 /* this will be freed later */
624 Recvbuf
= RSL_MALLOC( char , Rbufsize
+ 3 * sizeof(int) ) ; /* for sentinal record */
629 rc
= MPI_Alltoallv ( Sendbuf
, Ssizes
, Sdisplacements
, MPI_BYTE
,
630 Recvbuf
, Rsizes
, Rdisplacements
, MPI_BYTE
, comm
) ;
637 /* add sentinel to the end of Recvbuf */
639 r
= (int *)&(Recvbuf
[Rbufsize
+ 2 * sizeof(int)]) ;
642 if ( Sendbuf
!= NULL
) RSL_FREE( Sendbuf
) ;
643 if ( Plist
!= NULL
) {
644 for ( j
= 0 ; j
< Plist_length
; j
++ ) {
645 destroy_list ( &(Plist
[j
]), NULL
) ;
654 /********************************************/
657 RSL_LITE_FROM_PARENT_INFO ( ig_p
, jg_p
, retval_p
)
659 ig_p
/* (O) Global index in M dimension of nest. */
660 ,jg_p
/* (O) Global index in N dimension of nest. */
661 ,retval_p
; /* (O) Return value; =1 valid point, =0 done. */
663 rsl_lite_from_peerpoint_info ( ig_p
, jg_p
, retval_p
) ;
667 RSL_LITE_FROM_CHILD_INFO ( ig_p
, jg_p
, retval_p
)
669 ig_p
/* (O) Global index in M dimension of nest. */
670 ,jg_p
/* (O) Global index in N dimension of nest. */
671 ,retval_p
; /* (O) Return value; =1 valid point, =0 done. */
673 rsl_lite_from_peerpoint_info ( ig_p
, jg_p
, retval_p
) ;
677 rsl_lite_from_peerpoint_info ( ig_p
, jg_p
, retval_p
)
679 ig_p
/* (O) Global index in M dimension of nest. */
680 ,jg_p
/* (O) Global index in N dimension of nest. */
681 ,retval_p
; /* (O) Return value; =1 valid point, =0 done. */
685 Rbufcurs
= Rbufcurs
+ Rreclen
;
687 *ig_p
= *(int *)&( Recvbuf
[Rbufcurs
+ Rpointcurs
] ) ; Rpointcurs
+= sizeof(int) ;
688 *jg_p
= *(int *)&( Recvbuf
[Rbufcurs
+ Rpointcurs
] ) ; Rpointcurs
+= sizeof(int) ;
690 Rreclen
= *(int *)&( Recvbuf
[Rbufcurs
+ Rpointcurs
] ) ; Rpointcurs
+= sizeof(int) ;
692 if ( Rreclen
== RSL_INVALID
) {
694 RSL_FREE( Recvbuf
) ;
699 /********************************************/
702 RSL_LITE_FROM_PARENT_MSG ( len_p
, buf
)
704 len_p
; /* (I) Number of bytes to unpack. */
706 buf
; /* (O) Destination buffer. */
708 rsl_lite_from_peerpoint_msg ( len_p
, buf
) ;
712 RSL_LITE_FROM_CHILD_MSG ( len_p
, buf
)
714 len_p
; /* (I) Number of bytes to unpack. */
716 buf
; /* (O) Destination buffer. */
718 rsl_lite_from_peerpoint_msg ( len_p
, buf
) ;
722 rsl_lite_from_peerpoint_msg ( len_p
, buf
)
724 len_p
; /* (I) Number of bytes to unpack. */
726 buf
; /* (O) Destination buffer. */
732 if ( *len_p
% sizeof(int) == 0 ) {
733 for ( p
= (int *)&(Recvbuf
[Rbufcurs
+Rpointcurs
]), q
= buf
, i
= 0 ; i
< *len_p
; i
+= sizeof(int) )
738 for ( c
= &(Recvbuf
[Rbufcurs
+Rpointcurs
]), d
= (char *) buf
, i
= 0 ; i
< *len_p
; i
++ )
744 Rpointcurs
+= *len_p
;
747 /********************************************/