*IF DEF,C96_1B GATFML1B.2
*IF DEF,T3E,AND,DEF,MPP GATFML1B.3
C *****************************COPYRIGHT****************************** GATFML1B.4
C (c) CROWN COPYRIGHT 1998, METEOROLOGICAL OFFICE, All Rights Reserved. GATFML1B.5
C GATFML1B.6
C Use, duplication or disclosure of this code is subject to the GATFML1B.7
C restrictions as set forth in the contract. GATFML1B.8
C GATFML1B.9
C Meteorological Office GATFML1B.10
C London Road GATFML1B.11
C BRACKNELL GATFML1B.12
C Berkshire UK GATFML1B.13
C RG12 2SZ GATFML1B.14
C GATFML1B.15
C If no contract has been raised with this copy of the code, the use, GATFML1B.16
C duplication or disclosure of it is strictly prohibited. Permission GATFML1B.17
C to do so must first be obtained in writing from the Head of Numerical GATFML1B.18
C Modelling at the above address. GATFML1B.19
C ******************************COPYRIGHT****************************** GATFML1B.20
! GATFML1B.21
! Description: GATFML1B.22
! Takes 1 or more levels of a model field that have been decomposed GATFML1B.23
! over a group of processors, and gathers the data together so that GATFML1B.24
! one complete global level is contained on one processor. Processors GATFML1B.25
! can hold one or more such levels, as determined by the 'LOCAL_LEVEL' GATFML1B.26
! array, which gives the index for each level on the processor to GATFML1B.27
! which it is sent. For one level per PE, the setting of the values GATFML1B.28
! LOCAL_LEVEL(1...GLOBAL_LEVELS) should all be one. Successive ones GATFML1B.29
! obviously range from 1 upwards. GATFML1B.30
! GATFML1B.31
! Method: GATFML1B.32
! This routine uses SHMEM_PUT directly for each row, and staggers the GATFML1B.33
! target PE's, based on the identity of the sending PE. GATFML1B.34
! GATFML1B.35
! Current Code Owner: Paul Burton GATFML1B.36
! GATFML1B.37
! History: GATFML1B.38
! Model Date Modification history: GATFML1B.39
! version GATFML1B.40
! 4.5 18/09/97 New code optimised for the T3E GATFML1B.41
! Author: P.Burton GATFML1B.42
! GATFML1B.43
! Subroutine Interface: GATFML1B.44
SUBROUTINE GATHER_FIELD_ML(LOCAL_FIELD,GLOBAL_FIELD, 5GATFML1B.45
& LOCAL_ROW_LEN,LOCAL_ROWS,LOCAL_LEVS, GATFML1B.46
& GLOBAL_ROW_LEN,GLOBAL_ROWS,GLOBAL_LEVS, GATFML1B.47
& PE_FOR_LEVEL,LOCAL_LEVEL,PROC_GROUP, GATFML1B.48
& INFO) GATFML1B.49
GATFML1B.50
IMPLICIT NONE GATFML1B.51
! GATFML1B.52
! Subroutine Arguments: GATFML1B.53
GATFML1B.54
INTEGER GATFML1B.55
& LOCAL_ROW_LEN ! IN length of rows in local part of field GATFML1B.56
&, LOCAL_ROWS ! IN number of rows in local part of field GATFML1B.57
&, LOCAL_LEVS ! IN number of levels in local field GATFML1B.58
&, GLOBAL_ROW_LEN ! IN length of rows in global field GATFML1B.59
&, GLOBAL_ROWS ! IN number of rows in global field GATFML1B.60
&, GLOBAL_LEVS ! IN number of levels in global field GATFML1B.61
&, PE_FOR_LEVEL(LOCAL_LEVS) GATFML1B.62
! IN PE to gather each level to GATFML1B.63
&, LOCAL_LEVEL(LOCAL_LEVS) GATFML1B.64
! IN level index of level on gather pe GATFML1B.65
&, PROC_GROUP ! IN group ID of processors involved here GATFML1B.66
&, INFO ! OUT return code from comms GATFML1B.67
GATFML1B.68
REAL GATFML1B.69
& LOCAL_FIELD(LOCAL_ROW_LEN,LOCAL_ROWS,LOCAL_LEVS) GATFML1B.70
! ! IN local part of field GATFML1B.71
&, GLOBAL_FIELD(GLOBAL_ROW_LEN,GLOBAL_ROWS,GLOBAL_LEVS) GATFML1B.72
! ! OUT (on PE GATHER_PE) global field GATFML1B.73
GATFML1B.74
! Parameters and Common blocks GATFML1B.75
GATFML1B.76
*CALL PARVARS
GATFML1B.77
*CALL GCCOM
GATFML1B.78
GATFML1B.79
! Local variables GATFML1B.80
GATFML1B.81
INTEGER GATFML1B.82
& fld_type ! Field type - P or U only GATFML1B.83
&, level ! loop index for levels GATFML1B.84
GATFML1B.85
INTEGER GATFML1B.86
& n_rows_to_put ! Number of rows to send GATFML1B.87
& ,j ! loop index for rows GATFML1B.88
& ,real_level ! The actual level to send - PE's GATFML1B.89
! traverse the levels using their GATFML1B.90
! PE numbers as an offset to reduce GATFML1B.91
! network contention GATFML1B.92
GATFML1B.93
c--array to hold the address of the global fields on each PE GATFML1B.94
INTEGER GATFML1B.95
& address_global_field(0:MAXPROC) GATFML1B.96
GATFML1B.97
COMMON /shmem_align_address/ GATFML1B.98
& address_global_field GATFML1B.99
GATFML1B.100
c--remote global field on other PE's, whose address is set up GATFML1B.101
c by a CRAY type pointer, after exchanging remote addresses GATFML1B.102
REAL GATFML1B.103
& remote_GLOBAL_FIELD(GLOBAL_ROW_LEN, GLOBAL_ROWS, GLOBAL_LEVS) GATFML1B.104
GATFML1B.105
POINTER (PTR_remote_GLOBAL_FIELD, remote_GLOBAL_FIELD) GATFML1B.106
GATFML1B.107
GATFML1B.108
!------------------------------------------------------- GATFML1B.109
GATFML1B.110
GATFML1B.111
c--determine what type of field we are gathering GATFML1B.112
IF (GLOBAL_ROWS .EQ. glsize(2)) THEN GATFML1B.113
fld_type=fld_type_p GATFML1B.114
ELSEIF (GLOBAL_ROWS .EQ. glsize(2)-1) THEN GATFML1B.115
fld_type=fld_type_u GATFML1B.116
c--not a P or U field - return an error code GATFML1B.117
ELSE GATFML1B.118
WRITE(6,*) 'Bad field type in GATHER_FIELD_ML' GATFML1B.119
info=-1 GATFML1B.120
GOTO 9999 GATFML1B.121
ENDIF GATFML1B.122
GATFML1B.123
c--based on the field type, determine the number of rows GATFML1B.124
c to send to the gathering PE. The only case that needs GATFML1B.125
c consideration is a U field for a PE along the bolltom GATFML1B.126
c of the grid. GATFML1B.127
IF (atbase .AND. (fld_type .EQ. fld_type_u)) THEN GATFML1B.128
n_rows_to_put=LOCAL_ROWS-2*Offy-1 GATFML1B.129
ELSE GATFML1B.130
n_rows_to_put=LOCAL_ROWS-2*Offy GATFML1B.131
ENDIF GATFML1B.132
GATFML1B.133
c--store the address of the global field I am collecting GATFML1B.134
c (sending PE's must get this before they send data) GATFML1B.135
address_global_field(mype)=LOC(GLOBAL_FIELD) GATFML1B.136
GATFML1B.137
c--ensure everyone has set the address of their global fields GATFML1B.138
CALL barrier(
) GATFML1B.139
GATFML1B.140
c--loop over the number of rows to put GATFML1B.141
DO j=Offy+1,Offy+n_rows_to_put GATFML1B.142
GATFML1B.143
c--loop over the levels to send, using our PE number as an GATFML1B.144
c offset to reduce network contention and spread the work GATFML1B.145
c out of different PE's GATFML1B.146
DO level=1+mype,LOCAL_LEVS+mype GATFML1B.147
GATFML1B.148
c--compute the real level to send GATFML1B.149
real_level=MOD(level-1,LOCAL_LEVS)+1 GATFML1B.150
GATFML1B.151
c--first row for this level? If so, we must find the remote GATFML1B.152
c address of the global field into which the data is to be sent GATFML1B.153
IF (j .eq. Offy+1) THEN GATFML1B.154
GATFML1B.155
CALL shmem_get(
GATFML1B.156
& address_GLOBAL_FIELD(PE_FOR_LEVEL(real_level)), GATFML1B.157
& address_GLOBAL_FIELD(PE_FOR_LEVEL(real_level)), GATFML1B.158
& 1,PE_FOR_LEVEL(real_level)) GATFML1B.159
GATFML1B.160
ENDIF GATFML1B.161
GATFML1B.162
c--set up the remote address of the global field GATFML1B.163
PTR_remote_GLOBAL_FIELD= GATFML1B.164
& address_GLOBAL_FIELD(PE_FOR_LEVEL(real_level)) GATFML1B.165
GATFML1B.166
c--send the data off to the collecting PE for this level GATFML1B.167
CALL shmem_put(
GATFML1B.168
& remote_GLOBAL_FIELD(datastart(1),datastart(2)+j-Offy-1, GATFML1B.169
& LOCAL_LEVEL(real_level)), GATFML1B.170
& LOCAL_FIELD(Offx+1,j,real_level), GATFML1B.171
& LOCAL_ROW_LEN-2*Offx,PE_FOR_LEVEL(real_level)) GATFML1B.172
GATFML1B.173
ENDDO ! level GATFML1B.174
ENDDO ! j GATFML1B.175
GATFML1B.176
c--wait for everyone to finish sending their data GATFML1B.177
CALL barrier(
) GATFML1B.178
GATFML1B.179
9999 continue GATFML1B.180
GATFML1B.181
GATFML1B.182
RETURN GATFML1B.183
END GATFML1B.184
*ENDIF GATFML1B.185
*ENDIF GATFML1B.186