added README_changes.txt
[wrffire.git] / wrfv2_fire / external / RSL / RSL / rsl_mm_io.c
blobe6b5e56ef931de2c001022e81cb8546bea9cbd4d
1 /***********************************************************************
3 COPYRIGHT
5 The following is a notice of limited availability of the code and
6 Government license and disclaimer which must be included in the
7 prologue of the code and in all source listings of the code.
9 Copyright notice
10 (c) 1977 University of Chicago
12 Permission is hereby granted to use, reproduce, prepare
13 derivative works, and to redistribute to others at no charge. If
14 you distribute a copy or copies of the Software, or you modify a
15 copy or copies of the Software or any portion of it, thus forming
16 a work based on the Software and make and/or distribute copies of
17 such work, you must meet the following conditions:
19 a) If you make a copy of the Software (modified or verbatim)
20 it must include the copyright notice and Government
21 license and disclaimer.
23 b) You must cause the modified Software to carry prominent
24 notices stating that you changed specified portions of
25 the Software.
27 This software was authored by:
29 Argonne National Laboratory
30 J. Michalakes: (630) 252-6646; email: michalak@mcs.anl.gov
31 Mathematics and Computer Science Division
32 Argonne National Laboratory, Argonne, IL 60439
34 ARGONNE NATIONAL LABORATORY (ANL), WITH FACILITIES IN THE STATES
35 OF ILLINOIS AND IDAHO, IS OWNED BY THE UNITED STATES GOVERNMENT,
36 AND OPERATED BY THE UNIVERSITY OF CHICAGO UNDER PROVISION OF A
37 CONTRACT WITH THE DEPARTMENT OF ENERGY.
39 GOVERNMENT LICENSE AND DISCLAIMER
41 This computer code material was prepared, in part, as an account
42 of work sponsored by an agency of the United States Government.
43 The Government is granted for itself and others acting on its
44 behalf a paid-up, nonexclusive, irrevocable worldwide license in
45 this data to reproduce, prepare derivative works, distribute
46 copies to the public, perform publicly and display publicly, and
47 to permit others to do so. NEITHER THE UNITED STATES GOVERNMENT
48 NOR ANY AGENCY THEREOF, NOR THE UNIVERSITY OF CHICAGO, NOR ANY OF
49 THEIR EMPLOYEES, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR
50 ASSUMES ANY LEGAL LIABILITY OR RESPONSIBILITY FOR THE ACCURACY,
51 COMPLETENESS, OR USEFULNESS OF ANY INFORMATION, APPARATUS,
52 PRODUCT, OR PROCESS DISCLOSED, OR REPRESENTS THAT ITS USE WOULD
53 NOT INFRINGE PRIVATELY OWNED RIGHTS.
55 ***************************************************************************/
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include "rsl.h"
61 /* this module is specific to MM5 */
64 /*@
65 RSL_READ_REPL --- Fortran read of replicated, byte data into a buffer
67 Notes:
68 This does an unformatted (binary) Fortran read on a
69 file specified by Arg1. Data is read into the buffer specified
70 by Arg2. The length of the buffer, in bytes, is given by
71 Arg3. When the call returns, the data will be available on
72 all processors.
74 @*/
75 RSL_READ_REPL ( unit_p, base, nbytes_p )
76 int_p
77 unit_p ; /* (I) Fortran I/O unit number. */
78 void *
79 base ; /* (O) Buffer. */
80 int_p
81 nbytes_p ; /* (I) Buffer length in bytes. */
83 int unit, nbytes ;
84 rsl_read_req_t request ;
85 rsl_read_resp_t resp ;
86 rsl_processor_t P ;
87 int mlen, nlen, d ;
88 int mdest, mtag, msglen ;
89 int i_am_monitor ;
91 RSL_C_IAMMONITOR ( &i_am_monitor ) ;
93 #ifdef T3D
94 fprintf(stderr,"RSL_READ_REPL not implemented on T3D\n") ;
95 fprintf(stderr,"Use RSL_READ_REPLW instead\n") ;
96 RSL_TEST_ERR(1,"") ;
97 exit(2) ;
98 #else
100 unit = *unit_p ;
101 nbytes = *nbytes_p ;
102 request.request_type = RSL_READ_SPECIAL2 ;
103 request.speciala = nbytes ;
104 request.myproc = rsl_myproc ;
105 request.base = base ;
106 request.unit = *unit_p ;
107 request.sequence = io_seq_compute++ ;
109 if ( i_am_monitor )
111 FORT_CHARACTERREAD ( &unit, base, &nbytes ) ;
112 for ( P = 0 ; P < rsl_nproc_all ; P++ ) /* 95/02/22 */
114 mdest = rsl_c_comp2phys_proc(P) ;
115 if ( mdest != rsl_myproc )
117 mtag = MTYPE_FROMTO( MSG_SPECIAL2_RESPONSE, rsl_myproc, mdest ) ;
118 msglen = sizeof( resp ) ;
119 RSL_SEND( &resp, msglen, mtag, mdest ) ;
120 msglen = nbytes ;
121 RSL_SEND( base, msglen, mtag, mdest ) ;
125 else
127 mdest = RSL_C_MONITOR_PROC () ;
128 mtag = MTYPE_FROMTO( MSG_SPECIAL2_RESPONSE, mdest, rsl_myproc ) ;
129 msglen = sizeof(resp) ;
130 RSL_RECV( &resp, msglen, mtag ) ;
131 msglen = nbytes ;
132 RSL_RECV( base, msglen, mtag ) ;
134 #endif
138 RSL_READ_REPLW --- Fortran read of replicated, typed data into a buffer
140 Notes:
141 This does an unformatted (binary) Fortran read on a
142 file specified by Arg1. The element type of the data is
143 given as Arg2. It may be
144 Verbatim:
145 $ RSL_REAL
146 $ RSL_INTEGER
147 $ RSL_DOUBLE
148 $ RSL_COMPLEX
149 $ RSL_CHARACTER
150 BREAKTHEEXAMPLECODE
152 The buffer is provided as
153 Arg3. The length of the buffer, expressed as the number of
154 elements to be read, is given by
155 Arg4. When the call returns, the data will be available on
156 all processors.
160 RSL_READ_REPLW ( unit_p, type_p, base, nelems_p )
161 int_p
162 unit_p /* (I) Fortran I/O unit number. */
163 ,type_p ; /* (I) Element type of data. */
164 void *
165 base ; /* (O) Buffer. */
166 int_p
167 nelems_p ; /* (I) Number of elements to be read. */
169 int unit, nwords, type ;
170 rsl_read_req_t request ;
171 rsl_read_resp_t resp ;
172 rsl_processor_t P ;
174 int mdest, mtag, mlen ;
175 int i_am_monitor ;
177 RSL_C_IAMMONITOR ( &i_am_monitor ) ;
179 unit = *unit_p ;
180 nwords = *nelems_p ;
181 type = *type_p ;
182 request.request_type = RSL_READ_SPECIAL2 ;
183 request.speciala = nwords ;
184 request.myproc = rsl_myproc ;
185 request.base = base ;
186 request.unit = *unit_p ;
187 request.sequence = io_seq_compute++ ;
189 if ( i_am_monitor )
192 switch (type)
194 case RSL_REAL :
195 FORT_REALREAD ( &unit, base, &nwords ) ;
196 break ;
197 case RSL_INTEGER :
198 FORT_INTREAD ( &unit, base, &nwords ) ;
199 break ;
200 #ifndef T3D
201 case RSL_DOUBLE :
202 FORT_DOUBLEREAD ( &unit, base, &nwords ) ;
203 break ;
204 #endif
205 case RSL_COMPLEX :
206 FORT_COMPLEXREAD ( &unit, base, &nwords ) ;
207 break ;
208 case RSL_CHARACTER :
209 FORT_CHARACTERREAD ( &unit, base, &nwords ) ;
210 break ;
211 default:
212 RSL_TEST_ERR(1,"unsupported type argument") ;
214 for ( P = 0 ; P < rsl_nproc_all ; P++ ) /* 95/02/22 */
216 mdest = rsl_c_comp2phys_proc(P) ;
217 if ( mdest != rsl_myproc )
219 mtag = MTYPE_FROMTO( MSG_SPECIAL2_RESPONSE, rsl_myproc, mdest ) ;
220 mlen = sizeof( resp ) ;
221 RSL_SEND( &resp, mlen, mtag, mdest ) ;
222 mlen = elemsize(type)*nwords ;
223 RSL_SEND( base, mlen, mtag, mdest ) ;
227 else
229 mdest = RSL_C_MONITOR_PROC () ;
230 mtag = MTYPE_FROMTO( MSG_SPECIAL2_RESPONSE, mdest, rsl_myproc ) ;
231 mlen = sizeof(resp) ;
232 RSL_RECV( &resp, mlen, mtag ) ;
233 mlen = elemsize(type)*nwords ;
234 RSL_RECV( base, mlen, mtag ) ;
238 /* this module is specific to MM5 -- yes, it is a kludge to the max */
240 /* rev: 9/8/94 -- fixed problem wherein the monitor would attempt to
241 free buffers for boundaries it did not have (and so, had not been
242 allocated storage by the call to handle_spec1). The effect was
243 a segmentation error in the call to free. */
246 RSL_MM_BDY_IN ( unit_p, iotag_p,
247 ebase, wbase, nbase, sbase,
248 d_p, type_p,
249 bdy_wdth_p,
250 glen, llen )
251 int_p unit_p ;
252 int_p iotag_p ;
253 int_p type_p ;
254 int_p bdy_wdth_p ;
255 int_p d_p ;
256 char *ebase, *wbase, *nbase, *sbase ;
257 int glen[], llen[] ;
259 rsl_read_req_t request ;
260 rsl_read_resp_t resp ;
261 int cursor, mdest, mtag, msglen, dim ;
262 int bwdth ;
263 unsigned long ig, jg, min, maj, ioffset, joffset, tlen, k ;
264 void *dex ;
265 char *pbuf ;
266 char *buf_w, *buf_e, *buf_n, *buf_s ;
267 int wsz, esz, nsz, ssz ;
268 rsl_read_resp_t resp_w, resp_e, resp_n, resp_s ;
269 int P, mlen, nlen, d ;
270 int bdymark() ;
271 int i_am_monitor, got_bdy ;
272 rsl_point_t *domain ;
274 d = *d_p ;
275 RSL_TEST_ERR( d < 0 || d >= RSL_MAXDOMAINS,
276 "rsl_init_nextcell: bad domain") ;
277 RSL_TEST_ERR( domain_info[d].valid != RSL_VALID,
278 "rsl_init_nextcell: invalid domain") ;
279 if ( domain_info[d].decomposed != 1 )
281 default_decomposition( d_p,
282 &(domain_info[*d_p].loc_m),
283 &(domain_info[*d_p].loc_n) ) ;
285 mlen = domain_info[d].len_m ;
286 nlen = domain_info[d].len_n ;
287 domain = domain_info[d].domain ;
289 RSL_C_IAMMONITOR( &i_am_monitor ) ;
291 bwdth = *bdy_wdth_p ;
292 ioffset = domain_info[*d_p].ilocaloffset ;
293 joffset = domain_info[*d_p].jlocaloffset ;
294 tlen = elemsize( *type_p ) ;
296 request.request_type = RSL_READ_SPECIAL1 ;
297 request.speciala = bwdth ;
298 request.myproc = rsl_myproc ;
299 request.base = ebase ; /* not used anyway */
300 request.domain = *d_p ;
301 request.unit = *unit_p ;
302 request.type = *type_p ;
303 request.iotag = *iotag_p ;
304 request.sequence = io_seq_compute++ ;
306 P = rsl_c_phys2comp_proc( rsl_myproc ) ;
307 mlen = domain_info[*d_p].len_m ;
308 nlen = domain_info[*d_p].len_n ;
309 d = *d_p ;
311 switch( *iotag_p )
313 case IO2D :
314 case IO2D_IJ :
315 case IO2D_JI :
316 request.ndim = 2 ;
317 break ;
318 case IO3D :
319 case IO3D_IJK :
320 case IO3D_JIK :
321 request.ndim = 3 ;
322 break ;
323 default:
324 RSL_TEST_ERR(1,"rsl_mm_bdy_in: unknown data tag") ;
326 for ( dim = 0 ; dim < request.ndim ; dim++ )
328 request.glen[dim] = glen[dim] ;
329 request.llen[dim] = llen[dim] ;
332 buf_w = NULL ;
333 buf_e = NULL ;
334 buf_n = NULL ;
335 buf_s = NULL ;
336 got_bdy = handle_special1( &request, &buf_e, &esz,
337 &buf_w, &wsz,
338 &buf_n, &nsz,
339 &buf_s, &ssz ) ;
340 if ( got_bdy )
342 int i, j, k, by, b ;
343 int ix_g, jx_g, kx_g ;
344 int ix_l, jx_l, kx_l ;
345 ix_g = glen[0] ; jx_g = glen[1] ; kx_g = (request.ndim==3)?glen[2]:1 ;
346 ix_l = llen[0] ; jx_l = llen[1] ; kx_l = (request.ndim==3)?glen[2]:1 ;
348 /* west/east */
349 for ( b = 0 ; b < bwdth ; b++ )
350 for ( k = 0 ; k < kx_l ; k++ )
351 for ( i = 0 ; i < ix_l ; i++ )
353 if ( i+ioffset >= 0 )
355 for ( by = 0 ; by < tlen ; by++ )
357 wbase[by+tlen*(i+k*ix_l+b*ix_l*kx_l)]=buf_w[by+tlen*((i+ioffset)+k*ix_g+b*ix_g*kx_g)];
358 ebase[by+tlen*(i+k*ix_l+b*ix_l*kx_l)]=buf_e[by+tlen*((i+ioffset)+k*ix_g+b*ix_g*kx_g)];
363 /* north/south */
364 for ( b = 0 ; b < bwdth ; b++ )
365 for ( k = 0 ; k < kx_l ; k++ )
366 for ( j = 0 ; j < jx_l ; j++ )
368 if ( j+joffset >= 0 )
370 for ( by = 0 ; by < tlen ; by++ )
372 nbase[by+tlen*(j+k*jx_l+b*jx_l*kx_l)]=buf_n[by+tlen*((j+joffset)+k*jx_g+b*jx_g*kx_g)];
373 sbase[by+tlen*(j+k*jx_l+b*jx_l*kx_l)]=buf_s[by+tlen*((j+joffset)+k*jx_g+b*jx_g*kx_g)];
379 RSL_FREE( buf_e ) ;
382 #include "which_boundary.h"
384 RSL_MM_DIST_BDY ( unit_p, iotag_p, iorder_p, base, d_p,
385 type_p, bdy_wdth_p, bdy_height_p,
386 bdy_g_length_p, bdy_l_length_p )
387 int_p
388 unit_p
389 ,iotag_p
390 ,iorder_p ;
391 char *
392 base ;
393 int_p
395 ,type_p
396 ,bdy_wdth_p
397 ,bdy_height_p
398 ,bdy_g_length_p
399 ,bdy_l_length_p ;
402 rsl_read_req_t request ;
403 rsl_read_resp_t resp ;
404 int cursor, mdest, mtag, msglen, dim ;
405 int bwdth ;
406 unsigned long ig, jg, min, maj, ioffset, joffset, tlen, k ;
407 void *dex ;
408 char *buf ;
409 int P, mlen, nlen, d ;
410 int i_am_monitor, got_bdy, iorder, which_boundary ;
411 rsl_point_t *domain ;
413 d = *d_p ;
414 RSL_TEST_ERR( d < 0 || d >= RSL_MAXDOMAINS,
415 "rsl_init_nextcell: bad domain") ;
416 RSL_TEST_ERR( domain_info[d].valid != RSL_VALID,
417 "rsl_init_nextcell: invalid domain") ;
418 if ( domain_info[d].decomposed != 1 )
420 default_decomposition( d_p,
421 &(domain_info[*d_p].loc_m),
422 &(domain_info[*d_p].loc_n) ) ;
424 mlen = domain_info[d].len_m ;
425 nlen = domain_info[d].len_n ;
426 domain = domain_info[d].domain ;
428 RSL_C_IAMMONITOR( &i_am_monitor ) ;
430 iorder = *iorder_p ;
431 bwdth = *bdy_wdth_p ;
432 ioffset = domain_info[*d_p].ilocaloffset ;
433 joffset = domain_info[*d_p].jlocaloffset ;
434 tlen = elemsize( *type_p ) ;
436 request.request_type = RSL_READ_SPECIAL1 ;
437 request.speciala = bwdth ;
438 request.myproc = rsl_myproc ;
439 request.base = base ; /* not used anyway */
440 request.domain = *d_p ;
441 request.unit = *unit_p ;
442 request.type = *type_p ;
443 request.iotag = *iotag_p ;
444 request.sequence = io_seq_compute++ ;
446 P = rsl_c_phys2comp_proc( rsl_myproc ) ;
447 mlen = domain_info[*d_p].len_m ;
448 nlen = domain_info[*d_p].len_n ;
449 d = *d_p ;
451 switch( *iotag_p )
453 case IO2D :
454 case IO2D_IJ :
455 case IO2D_JI :
456 request.ndim = 2 ;
457 break ;
458 case IO3D :
459 case IO3D_IJK :
460 case IO3D_JIK :
461 request.ndim = 3 ;
462 break ;
463 default:
464 RSL_TEST_ERR(1,"rsl_mm_bdy_in: unknown data tag") ;
467 #if 0
468 /* east 2 */
469 /* west 1 */
470 /* north 8 */
471 /* south 4 */
472 #endif
474 /* set up some dimensioning for the call to handle_special3. For regularity with
475 other parts of the RSL code it uses the glen/llen construct for carrying this
476 information, although in the case of n/s boundaries the i info is not used and
477 in the case of the e/w boundaries the j info is not used. The boundary width
478 information is set above, in the assigment of request.speciala */
480 switch ( iorder )
482 case RSL_MLOW : /* south */
483 which_boundary = WHICH_BDY_SOUTH ;
484 case RSL_MHIGH : /* north */ /* FALL THROUGH */
485 which_boundary = WHICH_BDY_NORTH ;
486 request.glen[0] = 0 ; /* I dimension NOT USED for n/s boundaries */
487 request.glen[1] = *bdy_g_length_p ; /* Global length of boundary is global J */
488 request.glen[2] = *bdy_height_p ; /* number of levels */
489 request.llen[0] = 0 ; /* I dimension NOT USED for n/s boundaries */
490 request.llen[1] = *bdy_l_length_p ; /* Local length of boundary is local J */
491 request.llen[2] = *bdy_height_p ; /* number of levels */
492 break ;
493 case RSL_NLOW : /* west */
494 which_boundary = WHICH_BDY_WEST ;
495 case RSL_NHIGH : /* east */ /* FALL THROUGH */
496 which_boundary = WHICH_BDY_EAST ;
497 request.glen[0] = *bdy_g_length_p ; /* Global Length of boundary is global I */
498 request.glen[1] = 0 ; /* J dimension NOT USED for e/w boundaries */
499 request.glen[2] = *bdy_height_p ; /* number of levels */
500 request.llen[0] = *bdy_l_length_p ; /* Local length of boundary is local I */
501 request.llen[1] = 0 ; /* J dimension NOT USED for e/w boundaries */
502 request.llen[2] = *bdy_height_p ; /* number of levels */
503 break ;
504 default :
505 RSL_TEST_ERR(1,"Bad iorder spec for RSL_MM_DIST_BDY") ;
506 break ;
510 buf = NULL ;
511 got_bdy = handle_special3( &request, which_boundary, base, &buf ) ;
513 if ( got_bdy )
515 int i, j, k, by, b ;
516 int ix_g, jx_g, kx_g ;
517 int ix_l, jx_l, kx_l ;
518 ix_g = request.glen[0] ; jx_g = request.glen[1] ; kx_g = (request.ndim==3)?request.glen[2]:1 ;
519 ix_l = request.llen[0] ; jx_l = request.llen[1] ; kx_l = (request.ndim==3)?request.glen[2]:1 ;
521 switch ( iorder )
523 case RSL_NHIGH :
524 /* east */
525 for ( b = 0 ; b < bwdth ; b++ )
526 for ( k = 0 ; k < kx_l ; k++ )
527 for ( i = 0 ; i < ix_l ; i++ )
529 if ( i+ioffset >= 0 )
531 for ( by = 0 ; by < tlen ; by++ )
533 base[by+tlen*(i+k*ix_l+b*ix_l*kx_l)]=buf[by+tlen*((i+ioffset)+k*ix_g+b*ix_g*kx_g)];
537 break ;
539 case RSL_NLOW :
540 /* west */
541 for ( b = 0 ; b < bwdth ; b++ )
542 for ( k = 0 ; k < kx_l ; k++ )
543 for ( i = 0 ; i < ix_l ; i++ )
545 if ( i+ioffset >= 0 )
547 for ( by = 0 ; by < tlen ; by++ )
549 base[by+tlen*(i+k*ix_l+b*ix_l*kx_l)]=buf[by+tlen*((i+ioffset)+k*ix_g+b*ix_g*kx_g)];
553 break ;
555 case RSL_MHIGH :
556 /* north */
557 for ( b = 0 ; b < bwdth ; b++ )
558 for ( k = 0 ; k < kx_l ; k++ )
559 for ( j = 0 ; j < jx_l ; j++ )
561 if ( j+joffset >= 0 )
563 for ( by = 0 ; by < tlen ; by++ )
565 base[by+tlen*(j+k*jx_l+b*jx_l*kx_l)]=buf[by+tlen*((j+joffset)+k*jx_g+b*jx_g*kx_g)];
569 break ;
571 case RSL_MLOW :
572 /* south */
573 for ( b = 0 ; b < bwdth ; b++ )
574 for ( k = 0 ; k < kx_l ; k++ )
575 for ( j = 0 ; j < jx_l ; j++ )
577 if ( j+joffset >= 0 )
579 for ( by = 0 ; by < tlen ; by++ )
581 base[by+tlen*(j+k*jx_l+b*jx_l*kx_l)]=buf[by+tlen*((j+joffset)+k*jx_g+b*jx_g*kx_g)];
585 break ;
587 default:
588 RSL_TEST_ERR(1,"what boundary was that??") ;
589 break ;
593 RSL_FREE( buf ) ;