source: codes/icosagcm/devel/src/unstructured/data_unstructured.F90 @ 663

Last change on this file since 663 was 663, checked in by dubos, 6 years ago

devel/Python : fix numpy messing up OpenMP

File size: 8.5 KB
Line 
1MODULE data_unstructured_mod
2  USE ISO_C_BINDING
3  USE OMP_LIB
4  IMPLICIT NONE
5  SAVE
6
7#define BINDC_(thename) BIND(C, name=#thename)
8#define BINDC(thename) BINDC_(dynamico_ ## thename)
9
10#define DBL REAL(C_DOUBLE)
11#define DOUBLE1(m) DBL, DIMENSION(m)
12#define DOUBLE2(m,n) DBL, DIMENSION(m,n)
13#define DOUBLE3(m,n,p) DBL, DIMENSION(m,n,p)
14#define DOUBLE4(m,n,p,q) DBL, DIMENSION(m,n,p,q)
15#define INDEX INTEGER(C_INT)
16
17  INTEGER, PARAMETER :: eta_mass=1, eta_lag=2, &
18       thermo_theta=1, thermo_entropy=2, thermo_moist=3, thermo_boussinesq=4, &
19       caldyn_vert_cons=1, max_nb_stage=5
20  INTEGER(C_INT),  BIND(C) :: caldyn_thermo=thermo_theta, caldyn_eta=eta_lag, &
21       caldyn_vert_variant=caldyn_vert_cons, nb_threads=0, nb_stage=0
22  LOGICAL(C_BOOL), BIND(C) :: hydrostatic=.TRUE., debug_hevi_solver=.TRUE.
23
24  INDEX, BIND(C) :: llm, nqdyn, edge_num, primal_num, dual_num, &
25       max_primal_deg, max_dual_deg, max_trisk_deg
26  INDEX, ALLOCATABLE :: & ! deg(ij) = nb of vertices = nb of edges of primal/dual cell ij
27       primal_deg(:), primal_edge(:,:), primal_vertex(:,:), primal_ne(:,:), & 
28       dual_deg(:), dual_edge(:,:), dual_vertex(:,:), dual_ne(:,:), &
29       trisk_deg(:), trisk(:,:), &
30       left(:), right(:), up(:), down(:)
31  ! left and right are adjacent primal cells
32  ! flux is positive when going from left to right
33  ! up and down are adjacent dual cells
34  ! circulation is positive when going from down to up
35
36  DBL, BIND(C) :: elapsed, g, ptop, cpp, cppv, Rd, Rv, preff, Treff, &
37       pbot, Phi_bot, rho_bot
38  DBL :: kappa
39  DOUBLE1(max_nb_stage), BIND(C)              :: tauj       ! diagonal of fast Butcher tableau
40  DOUBLE2(max_nb_stage,max_nb_stage), BIND(C) :: cslj, cflj ! slow and fast modified Butcher tableaus
41  DOUBLE1(:), ALLOCATABLE            :: le_de, fv, Av, Ai
42  DOUBLE2(:,:), ALLOCATABLE          :: Riv2, wee, ap,bp, mass_bl, mass_dak, mass_dbk
43
44  INTEGER(C_INT), BIND(C) :: comm_icosa
45
46  INTEGER, PARAMETER :: id_dev1=1, id_dev2=2, &
47       id_pvort_only=3, id_slow_hydro=4, id_fast=5, id_coriolis=6, id_theta=7, id_geopot=8, id_vert=9, &
48       id_solver=10, id_slow_NH=11, id_NH_geopot=12, id_vert_NH=13, id_update=14, nb_routines=14 
49  DBL, PRIVATE :: start_time, time_spent(nb_routines) ! time spent in each kernel
50  INTEGER, PRIVATE :: current_id, nb_calls(nb_routines), bytes(nb_routines) ! bytes read or written be each kernel
51  CHARACTER(len = 10) :: id_name(nb_routines) = &
52       (/'dev1      ', 'dev2      ', &
53       'pvort_only', 'slow_hydro', 'fast      ', 'coriolis  ', 'theta     ', 'geopot    ', 'vert      ', &
54       'solver    ', 'slow_NH   ', 'NH_geopot ', 'vert_NH   ',  'update    ' /)
55
56CONTAINS
57
58  !----------------------------      PROFILING      --------------------------
59 
60  SUBROUTINE init_trace()
61    time_spent(:)=0.
62    bytes(:)=0
63    nb_calls(:)=0
64  END SUBROUTINE init_trace
65
66  SUBROUTINE print_trace()
67    INTEGER :: id
68    DBL :: total_spent
69    total_spent=SUM(time_spent)
70    PRINT *, '========================= Performance metrics ========================='
71    PRINT *, 'Total time spent in instrumented code (seconds) :', total_spent
72    PRINT *, 'Name, #calls, %time, microsec/call, MB/sec'   
73    DO id=1,nb_routines
74       IF(nb_calls(id)>0) PRINT *, id_name(id), nb_calls(id), INT(100.*time_spent(id)/total_spent), &
75            INT(1e6*time_spent(id)/nb_calls(id)), INT(1e-6*bytes(id)/time_spent(id))
76    END DO
77    CALL init_trace()
78  END SUBROUTINE print_trace
79
80  SUBROUTINE enter_trace(id, nbytes)
81    INTEGER :: id, nbytes
82    current_id = id
83    bytes(id) = bytes(id) + nbytes
84    nb_calls(id)=nb_calls(id)+1
85    start_time = OMP_GET_WTIME()
86  END SUBROUTINE enter_trace
87
88  SUBROUTINE exit_trace()
89    DBL :: elapsed
90    elapsed = OMP_GET_WTIME()-start_time
91    IF(elapsed<0.) elapsed=0.
92    time_spent(current_id) = time_spent(current_id) + elapsed
93  END SUBROUTINE exit_trace
94
95  !---------------------------- CONTEXT INITIALIZATION --------------------------
96
97#define ALLOC1(v,n1) IF(ALLOCATED(v)) DEALLOCATE(v) ; ALLOCATE(v(n1))
98#define ALLOC2(v,n1,n2) IF(ALLOCATED(v)) DEALLOCATE(v) ; ALLOCATE(v(n1,n2))
99
100  SUBROUTINE init_mesh( & 
101       primal_deg_, primal_edge_, primal_ne_, &
102       dual_deg_, dual_edge_, dual_ne_, dual_vertex_, &
103       left_, right_, up_, down_ ,&
104       trisk_deg_, trisk_) BINDC(init_mesh)
105    INDEX :: primal_deg_(primal_num), primal_edge_(max_primal_deg,primal_num), &
106         primal_ne_(max_primal_deg,primal_num), &
107         dual_deg_(dual_num), dual_edge_(max_dual_deg,dual_num), &
108         dual_ne_(max_dual_deg,dual_num), &
109         dual_vertex_(max_dual_deg,dual_num), &
110         trisk_deg_(edge_num), trisk_(max_trisk_deg, edge_num)
111    INDEX, DIMENSION(edge_num) :: left_, right_, down_, up_
112
113    PRINT *, 'init_mesh ...'
114    PRINT *, 'Primal mesh : ', primal_num, max_primal_deg
115    PRINT *, 'Dual mesh   : ', dual_num, max_dual_deg
116    PRINT *, 'Edge mesh   : ', edge_num, max_trisk_deg
117    PRINT *, 'Vertical levels :', llm
118    ALLOC1(primal_deg, primal_num)
119    ALLOC2(primal_edge, max_primal_deg,primal_num)
120    ALLOC2(primal_ne, max_primal_deg,primal_num)
121    ALLOC1(dual_deg,dual_num)
122    ALLOC2(dual_edge, max_dual_deg,dual_num)
123    ALLOC2(dual_ne, max_dual_deg,dual_num)
124    ALLOC2(dual_vertex, max_dual_deg,dual_num)
125    ALLOC1(trisk_deg, edge_num)
126    ALLOC2(trisk, max_trisk_deg, edge_num)
127    PRINT *, SHAPE(trisk), edge_num
128    ALLOC1(left, edge_num)
129    ALLOC1(right, edge_num)
130    ALLOC1(up, edge_num)
131    ALLOC1(down, edge_num)
132    primal_deg(:) = primal_deg_(:)
133    primal_edge(:,:) = primal_edge_(:,:)
134    primal_ne(:,:) = primal_ne_(:,:)
135    dual_deg(:) = dual_deg_(:)
136    dual_edge(:,:) = dual_edge_(:,:)
137    dual_ne(:,:) = dual_ne_(:,:)
138    dual_vertex(:,:) = dual_vertex_(:,:)
139    IF(MINVAL(dual_deg)<3) THEN
140       STOP 'At least one dual cell has less than 3 vertices'
141    END IF
142    IF(MINVAL(primal_deg)<3) THEN
143       STOP 'At least one primal cell has less than 3 vertices'
144    END IF
145    left(:)=left_(:)
146    right(:)=right_(:)
147    down(:)=down_(:)
148    up=up_(:)
149    trisk_deg(:)=trisk_deg_(:)
150    trisk(:,:)=trisk_(:,:)
151    PRINT *, MAXVAL(primal_edge), edge_num
152    PRINT *, MAXVAL(dual_edge), edge_num
153    PRINT *, MAXVAL(dual_vertex), dual_num
154    PRINT *, MAXVAL(trisk), edge_num
155    PRINT *, MAX(MAXVAL(left),MAXVAL(right)), primal_num
156    PRINT *, MAX(MAXVAL(up),MAXVAL(down)), dual_num
157    PRINT *, SHAPE(trisk), edge_num
158    PRINT *,' ... Done.'
159  END SUBROUTINE init_mesh
160
161  SUBROUTINE init_metric(Ai_, Av_, fv_, le_de_, Riv2_, wee_) BINDC(init_metric)
162    DOUBLE1(primal_num) :: Ai_
163    DOUBLE1(dual_num)   :: Av_, fv_
164    DOUBLE1(edge_num)   :: le_de_
165    DOUBLE2(max_dual_deg,dual_num) :: Riv2_
166    DOUBLE2(max_trisk_deg,edge_num) :: wee_
167    PRINT *, 'init_metric ...'
168    ALLOC1(Ai,primal_num)
169    ALLOC1(Av,dual_num)
170    ALLOC1(fv,dual_num)
171    ALLOC1(le_de,edge_num)
172    ALLOC2(Riv2, max_dual_deg, dual_num)
173    ALLOC2(wee, max_trisk_deg, edge_num)
174    Ai(:) = Ai_(:)
175    Av(:) = Av_(:)
176    fv(:) = fv_(:)
177    le_de(:) = le_de_(:)
178    Riv2(:,:)=Riv2_(:,:)
179    wee(:,:) = wee_(:,:)
180    PRINT *, MAXVAL(ABS(Ai))
181    PRINT *, MAXVAL(ABS(Av))
182    PRINT *, MAXVAL(ABS(fv))
183    PRINT *, MAXVAL(ABS(le_de))
184    PRINT *, MAXVAL(ABS(Riv2))
185    PRINT *, MAXVAL(ABS(wee))
186    PRINT *, MINVAL(right), MAXVAL(right)
187    PRINT *, MINVAL(right), MAXVAL(left)
188    PRINT *,' ... Done.'
189    IF(nb_threads==0) nb_threads=OMP_GET_MAX_THREADS()
190    PRINT *,'OpenMP : max_threads, num_procs, nb_threads', OMP_GET_MAX_THREADS(), OMP_GET_NUM_PROCS(), nb_threads
191  END SUBROUTINE init_metric
192  !
193  SUBROUTINE show_openmp() BINDC(show_openmp)
194    PRINT *,'OpenMP : max_threads, num_procs', OMP_GET_MAX_THREADS(), OMP_GET_NUM_PROCS()
195  END SUBROUTINE show_openmp
196  !
197  SUBROUTINE init_params() BINDC(init_params)
198    PRINT *, 'Setting physical parameters ...'
199    IF(hydrostatic) THEN
200       PRINT *, 'Hydrostatic dynamics (HPE)'
201    ELSE
202       PRINT *, 'Non-hydrostatic dynamics (Euler)'
203    END IF
204    kappa = Rd/cpp
205    PRINT *, 'g = ',g
206    PRINT *, 'preff = ',preff
207    PRINT *, 'Treff = ',Treff
208    PRINT *, 'Rd = ',Rd
209    PRINT *, 'cpp = ',cpp
210    PRINT *, 'kappa = ',kappa
211    PRINT *, '... Done'
212  END SUBROUTINE init_params
213  !
214  SUBROUTINE init_hybrid(bl,dak,dbk) BINDC(init_hybrid)
215    DOUBLE2(llm+1, primal_num) :: bl
216    DOUBLE2(llm, primal_num) :: dak,dbk
217    PRINT *, 'Setting hybrid coefficients ...'
218    ALLOC2(mass_bl, llm+1, primal_num)
219    ALLOC2(mass_dak, llm, primal_num)
220    ALLOC2(mass_dbk, llm, primal_num)
221    mass_bl(:,:)  = bl(:,:)
222    mass_dak(:,:) = dak(:,:)
223    mass_dbk(:,:) = dbk(:,:)
224    PRINT *, '... Done, llm = ', llm
225  END SUBROUTINE Init_hybrid
226
227END MODULE data_unstructured_mod
Note: See TracBrowser for help on using the repository browser.