Millepede-II V04-13-05
mpskyl.f90
Go to the documentation of this file.
1
24
26MODULE mpskyl
27 USE mpdef
28 IMPLICIT NONE
29
30 INTEGER(mpi) :: npar
31 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: lastrowincol
32 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: pargroupstoregions
33 INTEGER(mpi), DIMENSION(:), ALLOCATABLE :: regionoffsets
34 INTEGER(mpi) :: nthrd
35
36END MODULE mpskyl
37
45SUBROUTINE mpslan(n,lrows,npgrp,nsparr)
46 USE mpskyl
47 USE mpdalc
48
49 IMPLICIT NONE
50 LOGICAL :: lfirst
51 INTEGER(mpi) :: i
52 INTEGER(mpi) :: ichunk
53 INTEGER(mpi) :: j
54 INTEGER(mpi) :: ncol
55 INTEGER(mpi) :: nrgn
56 INTEGER(mpl) :: length
57
58 INTEGER(mpi), INTENT(IN) :: n
59 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: lrows
60 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
61 INTEGER(mpl), DIMENSION(:,:), INTENT(OUT) :: nsparr
62 !$ INTEGER(mpi) :: OMP_GET_MAX_THREADS
63
64 npar=n
65 print *, ' MPSLAN ', npar
66 nthrd=1
67 !$ NTHRD=OMP_GET_MAX_THREADS()
68
69 length=n
70 CALL mpalloc(lastrowincol,length,'last (non-zero) row in column')
71 lastrowincol=lrows(:n)
72 CALL mpalloc(pargroupstoregions,length,'mapping of parameter groups to regions (in row)')
73 length=n+1
74 CALL mpalloc(regionoffsets,length,'offsets for parameter group regions (in row)')
75
76 ichunk=min((npar+nthrd-1)/nthrd/32+1,256)
77 ! analyse sparsity
78 ! parallelize row loop
79 !$OMP PARALLEL DO &
80 !$OMP PRIVATE(I,J,NCOL,NRGN,LFIRST) &
81 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
82 DO i=1,npar !row
83 ncol=0 ! number of columns
84 nrgn=0 ! number of regions
85 lfirst=.true.
86 DO j=1,i ! loop until diagonal element
87 ! inside skyline?
88 IF (i <= lastrowincol(j)) THEN
89 IF (lfirst) THEN
90 nrgn=nrgn+1
91 lfirst=.false.
92 END IF
93 ncol=ncol+npgrp(j+1)-npgrp(j)
94 ELSE
95 lfirst=.true.
96 END IF
97 END DO
98 nsparr(1,i+1)=2*(nrgn+1)
99 nsparr(2,i+1)=ncol*(npgrp(i+1)-npgrp(i))
100 END DO
101 !$OMP END PARALLEL DO
102
103 !sum up
104 nsparr(1,1)=0
105 nsparr(2,1)=npgrp(npar+1)-npgrp(1) ! number of diagonal elements
106 DO i=1,npar
107 nsparr(:,i+1)=nsparr(:,i+1)+nsparr(:,i)
108 !print *, ' row ', i, nsparr(:,i+1)
109 !print *, ' skyline ', i, lastRowInCol(i), npgrp(i), npgrp(i+1)
110 END DO
111
112END SUBROUTINE mpslan
113
120SUBROUTINE mpslsp(npgrp,nsparr,nsparc)
121 USE mpskyl
122
123 IMPLICIT NONE
124 LOGICAL :: lfirst
125 INTEGER(mpi) :: i
126 INTEGER(mpi) :: ichunk
127 INTEGER(mpi) :: j
128 INTEGER(mpl) :: kl
129 INTEGER(mpl) :: ll
130 INTEGER(mpl) :: l1
131
132 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
133 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
134 INTEGER(mpi), DIMENSION(:), INTENT(OUT) :: nsparc
135
136 ichunk=min((npar+nthrd-1)/nthrd/32+1,256)
137 ! analyse sparsity
138 ! parallelize row loop
139 !$OMP PARALLEL DO &
140 !$OMP PRIVATE(I,J,KL,LL,L1,LFIRST) &
141 !$OMP SCHEDULE(DYNAMIC,ICHUNK)
142 DO i=1,npar !row
143 kl=nsparr(1,i) ! pointer to row in NSPARC
144 l1=nsparr(2,i) ! pointer to row in sparse matrix
145 ll=l1
146 lfirst=.true.
147 DO j=1,i ! loop until diagonal element
148 ! inside skyline?
149 IF (i <= lastrowincol(j)) THEN
150 IF (lfirst) THEN
151 kl=kl+1
152 nsparc(kl)=int(ll-l1,mpi)
153 kl=kl+1
154 nsparc(kl)=j
155 lfirst=.false.
156 END IF
157 ll=ll+npgrp(j+1)-npgrp(j)
158 ELSE
159 lfirst=.true.
160 END IF
161 END DO
162 ! next offset, end marker
163 kl=kl+1
164 nsparc(kl)=int(ll-l1,mpi)
165 kl=kl+1
166 nsparc(kl)=npar+1
167 END DO
168 !$OMP END PARALLEL DO
169
170 WRITE(*,*) ' '
171 WRITE(*,*) 'MPSLSP: skyline structure constructed ',nsparr(1,npar+1), ' words'
172 WRITE(*,*) 'MPSLSP: dimension parameter of matrix',nsparr(2,1)
173 WRITE(*,*) 'MPSLSP: index of last used location',nsparr(2,npar+1)
174
175END SUBROUTINE mpslsp
176
187SUBROUTINE mpsldc(npgrp,nsparr,nsparc,gmat,nsize,nrank,mon)
188 USE mpskyl
189 USE mpdalc
190
191 IMPLICIT NONE
192 INTEGER(mpi) :: i
193 INTEGER(mpi) :: ia
194 INTEGER(mpi) :: ib
195 INTEGER(mpi) :: ik
196 INTEGER(mpi) :: ikj
197 INTEGER(mpi) :: in
198 INTEGER(mpi) :: in1
199 INTEGER(mpi) :: ipg
200 INTEGER(mpi) :: ir
201 INTEGER(mpi) :: j
202 INTEGER(mpi) :: jpg
203 INTEGER(mpi) :: ja
204 INTEGER(mpi) :: jai
205 INTEGER(mpi) :: jaj
206 INTEGER(mpi) :: jb
207 INTEGER(mpi) :: jbi
208 INTEGER(mpi) :: jbj
209 INTEGER(mpi) :: jk
210 INTEGER(mpi) :: jn
211 INTEGER(mpi) :: jn1
212 INTEGER(mpi) :: jni
213 INTEGER(mpi) :: jnj
214 INTEGER(mpi) :: jr
215 INTEGER(mpi) :: lj
216 INTEGER(mpi) :: nrgn
217 INTEGER(mpi) :: mpg
218 INTEGER(mpl) :: ii
219 INTEGER(mpl) :: iij
220 INTEGER(mpl) :: is1
221 INTEGER(mpl) :: is2
222 INTEGER(mpl) :: ki
223 INTEGER(mpl) :: kj
224 INTEGER(mpl) :: jj
225 INTEGER(mpl) :: js1
226 INTEGER(mpl) :: js2
227 REAL(mpd) :: ratio
228
229 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
230 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
231 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: nsparc
232 REAL(mpd), DIMENSION(:), INTENT(INOUT) :: gmat
233 INTEGER(mpi), INTENT(IN) :: nsize
234 INTEGER(mpi), INTENT(OUT) :: nrank
235 INTEGER(mpi), INTENT(IN) :: mon
236
237 !$POMP INST BEGIN(mpsldc)
238 ! max. used par. group
239 mpg=npar
240 DO WHILE (npgrp(mpg) > nsize)
241 mpg=mpg-1
242 END DO
243 !print *, ' MPSLDC ', npar, npgrp(npar+1), npgrp(1), nsize, mpg
244 !DO ipg=1,npar
245 ! print *, ' group ', ipg, npgrp(ipg), npgrp(ipg+1)-npgrp(ipg)
246 !END DO
247
248 ! parameter groups
249 DO ipg=mpg,1,-1
250 ! monitoring ?
251 IF(mon>0) CALL monpgs(mpg+1-ipg)
252 is1=nsparr(1,ipg)
253 is2=nsparr(2,ipg)
254 in1=int(nsparr(1,ipg+1)-is1,mpi)
255 ! inside parameter group
256 ia=npgrp(ipg) ! first (global) row
257 ib=npgrp(ipg+1)-1 ! last (global) row
258 in=ib-ia+1 ! number of rows
259 ! get mapping par -> region (row-wise expansion)
260 nrgn=0
262 DO ik=2,in1-2,2
263 jpg=nsparc(is1+ik) ! first group
264 ja=npgrp(jpg) ! first (global) column
265 lj=nsparc(is1+ik-1) ! region offset
266 jn=nsparc(is1+ik+1)-lj ! number of columns
267 jb=ja+jn-1 ! last (global) column
268 nrgn=nrgn+1
269 regionoffsets(nrgn+1)=jn
270 ! mapping
271 DO WHILE (.true.)
272 pargroupstoregions(jpg)=nrgn
273 IF (jb < npgrp(jpg+1)) EXIT
274 jpg=jpg+1
275 END DO
276 END DO
277 !print *, ' listParGroups ', npg, ':', listParGroups(:,:npg)
278 ! sumup
279 regionoffsets(1)=0
280 DO ir=1,nrgn
282 END DO
283 !print *, ' region offsets ', nrgn, ':', regionOffsets(:nrgn)
284 ! rows in group
285 DO i=min(ib,nsize),ia,-1
286 ! diagonal element
287 IF (gmat(i) > 0.0_mpd) THEN
288 ! update rank, min, max eigenvalue
289 nrank=nrank+1
290 !IF (nrank == 1) THEN
291 ! evmax=gmat(i)
292 ! evmin=gmat(i)
293 !ELSE
294 ! evmax=max(evmax,gmat(i))
295 ! evmin=min(evmin,gmat(i))
296 !END IF
297 gmat(i)=1.0/gmat(i) ! (I,I) div !
298 END IF
299 !print *, ' diag ', i, nrank, gmat(i)
300
301 ! loop over (column) groups
302 !$OMP PARALLEL DO &
303 !$OMP DEFAULT(PRIVATE) &
304 !$OMP SHARED(parGroupsToRegions,regionOffsets,npgrp,nsparr,nsparc,gmat,IPG,I,IS1,IS2,IA,IN,IN1) &
305 !$OMP SCHEDULE(DYNAMIC,2)
306 DO jpg=1,ipg
307 ! region
308 ik=pargroupstoregions(jpg)
309 IF (ik == 0) cycle
310 ii=is2+regionoffsets(ik)*in
311 ik=ik+ik
312 jr=npgrp(nsparc(is1+ik)) ! first (global) column
313 lj=nsparc(is1+ik-1) ! region offset
314 jn=nsparc(is1+ik+1)-lj ! number of columns
315 ! group
316 js1=nsparr(1,jpg)
317 js2=nsparr(2,jpg)
318 jn1=int(nsparr(1,jpg+1)-js1,mpi)
319 ! loop over columns
320 ja=npgrp(jpg) ! first (global) column
321 jb=npgrp(jpg+1)-1 ! last (global) column
322 lj=(i-ia)*jn-jr+ja ! offset for row i
323 DO j=ja,jb
324 lj=lj+1
325 IF (j >= i) EXIT
326 ratio=gmat(ii+lj)*gmat(i)
327 IF (ratio == 0.0_mpd) cycle
328 jk=2
329 iij=is2+1
330 jj=js2+1
331 DO ikj=2,ik,2
332 ! region in row i
333 jai=npgrp(nsparc(is1+ikj))
334 IF (jai > j) EXIT
335 jni=nsparc(is1+ikj+1)-nsparc(is1+ikj-1)
336 jbi=min(jai+jni-1,j)
337 DO WHILE (.true.)
338 IF (jk >= jn1) THEN
339 print *, ' ERROR in skyline structure ', i, j, ipg, jpg
340 print *, nsparc(is1+1:is1+in1)
341 print *, nsparc(js1+1:js1+jn1)
342 !RETURN
343 END IF
344 jaj=npgrp(nsparc(js1+jk))
345 jnj=nsparc(js1+jk+1)-nsparc(js1+jk-1)
346 jbj=jaj+jnj-1
347 ! (region i) inside (region j)?
348 IF (jaj <= jai.AND.jbj >= jbi) EXIT
349 jk=jk+2
350 jj=jj+jnj*(npgrp(jpg+1)-npgrp(jpg))
351 END DO
352 !print *, ' inside ', jai, jbi, jaj, jbj
353 ! offsets in groups/regions
354 ki=iij+(i-ia)*jni-jai
355 kj=jj+(j-ja)*jnj-jaj
356 ! off diagonal elements
357 gmat(kj+jai:kj+jbi)=gmat(kj+jai:kj+jbi)-gmat(ki+jai:ki+jbi)*ratio
358 ! diagonal element
359 IF (jbi == j) gmat(j)=gmat(j)-gmat(ki+jbi)*ratio
360 iij=iij+in*jni
361 END DO
362 END DO
363 END DO
364 !$OMP END PARALLEL DO
365
366 ! loop over (column) group regions
367 ii=is2+1
368 DO ik=2,in1-2,2
369 jpg=nsparc(is1+ik) ! first group
370 ja=npgrp(jpg) ! first (global) column
371 lj=nsparc(is1+ik-1) ! region offset
372 jn=nsparc(is1+ik+1)-lj ! number of columns
373 jb=min(ja+jn-1,i-1) ! last (global) column
374 ki=ii+(i-ia)*jn-ja
375 gmat(ki+ja:ki+jb)=gmat(ki+ja:ki+jb)*gmat(i)
376 ii=ii+in*jn
377 END DO
378 END DO
379 END DO
380 !$POMP INST END(mpsldc)
381
382END SUBROUTINE mpsldc
383
390SUBROUTINE mpslsv(gij,gvec,nfit)
391 USE mpskyl
392
393 IMPLICIT NONE
394 INTEGER(mpi) :: i
395 INTEGER(mpi) :: k
396 REAL(mpd) :: dsum
397
398 REAL(mpd) :: gij
399 REAL(mpd), DIMENSION(:), INTENT(INOUT) :: gvec
400 INTEGER(mpi), INTENT(iN) :: nfit
401
402 INTERFACE
403 FUNCTION gij(i,j)
404 USE mpdef
405 INTEGER(mpi), INTENT(in) :: i
406 INTEGER(mpi), INTENT(in) :: j
407 END FUNCTION gij
408 END INTERFACE
409
410 DO i=nfit,1,-1
411 dsum=gvec(i)
412 DO k=nfit, i+1, -1
413 dsum=dsum-gij(k,i)*gvec(k) ! (K,I)
414 END DO
415 gvec(i)=dsum
416 END DO
417 DO i=1,nfit
418 dsum=gvec(i)*gij(i,i) ! (I,I)
419 DO k=1,i-1
420 dsum=dsum-gij(i,k)*gvec(k) ! (I,K)
421 END DO
422 gvec(i)=dsum
423 END DO
424
425END SUBROUTINE mpslsv
426
435
436!!
437SUBROUTINE mpslsv2(npgrp,nsparr,nsparc,gmat,gvec,nsize)
438 USE mpskyl
439 USE mpdalc
440
441 IMPLICIT NONE
442 INTEGER(mpi) :: i
443 INTEGER(mpi) :: ia
444 INTEGER(mpi) :: ib
445 INTEGER(mpi) :: ik
446 INTEGER(mpi) :: in
447 INTEGER(mpi) :: in1
448 INTEGER(mpi) :: ipg
449 INTEGER(mpi) :: ir
450 INTEGER(mpi) :: jpg
451 INTEGER(mpi) :: ja
452 INTEGER(mpi) :: jai
453 INTEGER(mpi) :: jb
454 INTEGER(mpi) :: jbi
455 INTEGER(mpi) :: jn
456 INTEGER(mpi) :: jr
457 INTEGER(mpi) :: js
458 INTEGER(mpi) :: lj
459 INTEGER(mpi) :: irgn
460 INTEGER(mpi) :: mpg
461 INTEGER(mpl) :: ii
462 INTEGER(mpl) :: is1
463 INTEGER(mpl) :: is2
464 INTEGER(mpl) :: jj
465 INTEGER(mpl) :: js1
466 INTEGER(mpl) :: js2
467 REAL(mpd) :: dsum
468
469 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: npgrp
470 INTEGER(mpl), DIMENSION(:,:), INTENT(IN) :: nsparr
471 INTEGER(mpi), DIMENSION(:), INTENT(IN) :: nsparc
472 REAL(mpd), DIMENSION(:), INTENT(IN) :: gmat
473 REAL(mpd), DIMENSION(:), INTENT(INOUT) :: gvec
474 INTEGER(mpi), INTENT(IN) :: nsize
475
476 !$POMP INST BEGIN(mpslsv2b)
477 ! max. used par. group
478 mpg=npar
479 DO WHILE (npgrp(mpg) > nsize)
480 mpg=mpg-1
481 END DO
482 print *, ' MPSLSV2 ', nsize, npar, mpg
483
484 ! 1. backward substitution
485 ! get mapping par -> region (column-wise expansion)
487 ! parameter groups
488 DO ipg=mpg,1,-1
489 ! expand (get last region in row)
490 irgn=int(nsparr(1,ipg+1)-nsparr(1,ipg),mpi)/2-1
491 pargroupstoregions(ipg)=irgn
492 regionoffsets(ipg)=int(nsparr(2,ipg+1)-nsparr(2,ipg),mpi)
493 !print *, ' ipg, irgn ', ipg, irgn, regionOffsets(ipg)
494 ! inside parameter group
495 ia=npgrp(ipg) ! first (global) row
496 ib=npgrp(ipg+1)-1 ! last (global) row
497 DO i=min(ib,nsize),ia,-1
498 dsum=gvec(i)
499 ! loop over rows
500 ! $OMP PARALLEL DO &
501 ! $OMP DEFAULT(PRIVATE) &
502 ! $OMP SHARED(parGroupsToRegions,regionOffsets,npgrp,nsparr,nsparc,gmat,gvec,NPAR,IPG,I,MPG,NSIZE) &
503 ! $OMP REDUCTION(+:DSUM) &
504 ! $OMP SCHEDULE(DYNAMIC,2)
505 DO jpg=mpg,ipg,-1
506 ! group
507 js1=nsparr(1,jpg)
508 js2=nsparr(2,jpg)
509 ja=npgrp(jpg) ! first (global) row
510 jb=npgrp(jpg+1)-1 ! last (global) row
511 js=max(0,jb-nsize) ! number of rows to skip at end of group
512 in=jb-ja+1 ! number of rows
513 ! get region with col 'i'
514 irgn=pargroupstoregions(jpg)
515 DO WHILE (irgn > 0)
516 ik=2*irgn
517 jr=npgrp(nsparc(js1+ik)) ! first (global) column
518 lj=nsparc(js1+ik-1) ! region offset
519 jn=nsparc(js1+ik+1)-lj ! number of columns
520 IF (jr <= i) EXIT
521 irgn=irgn-1
522 pargroupstoregions(jpg)=irgn
523 regionoffsets(jpg)=regionoffsets(jpg)-jn*in
524 END DO
525 ! not found
526 IF (irgn <= 0) cycle
527 jai=max(i+1,ja) ! first row
528 jbi=jr+jn-1 ! last col in region
529 !print *, ' jpg ', jpg, i, irgn, jr, jn , jai, jbi
530 IF (jbi < i) cycle
531 ! index of end of region
532 jj=js2+regionoffsets(jpg)
533 ! index of (jai,i)
534 ii=jj-jn*(in+ja-jai)-jr+i+1
535 dsum=dsum-dot_product(gmat(ii:jj-js*jn:jn),gvec(jai:jb-js))
536 END DO
537 ! $OMP END PARALLEL DO
538 gvec(i)=dsum
539 END DO
540 END DO
541 !$POMP INST END(mpslsv2b)
542
543 !$POMP INST BEGIN(mpslsv2f)
544 ! 2. forward substitution
545 ! parameter groups
546 DO ipg=1,mpg
547 is1=nsparr(1,ipg)
548 is2=nsparr(2,ipg)
549 in1=int(nsparr(1,ipg+1)-is1,mpi)
550 ! inside parameter group
551 ia=npgrp(ipg) ! first (global) row
552 ib=npgrp(ipg+1)-1 ! last (global) row
553 in=ib-ia+1 ! number of rows
554 ! get mapping par -> region (row-wise expansion)
555 irgn=0
557 DO ik=2,in1-2,2
558 jpg=nsparc(is1+ik) ! first group
559 ja=npgrp(jpg) ! first (global) column
560 lj=nsparc(is1+ik-1) ! region offset
561 jn=nsparc(is1+ik+1)-lj ! number of columns
562 jb=ja+jn-1 ! last (global) column
563 irgn=irgn+1
564 regionoffsets(irgn+1)=jn
565 ! mapping
566 DO WHILE (.true.)
567 pargroupstoregions(jpg)=irgn
568 IF (jb < npgrp(jpg+1)) EXIT
569 jpg=jpg+1
570 END DO
571 END DO
572 ! sumup
573 regionoffsets(1)=0
574 DO ir=1,irgn
576 END DO
577 DO i=ia,min(ib,nsize)
578 dsum=gvec(i)*gmat(i)
579 ! columns of row 'i'
580 ! loop over (column) groups
581 ! $OMP PARALLEL DO &
582 ! $OMP DEFAULT(PRIVATE) &
583 ! $OMP SHARED(parGroupsToRegions,regionOffsets,npgrp,nsparc,gmat,gvec,IPG,I,IS1,IS2,IA,IN) &
584 ! $OMP REDUCTION(+:DSUM) &
585 ! $OMP SCHEDULE(DYNAMIC,2)
586 DO jpg=1,ipg
587 ! region
588 irgn=pargroupstoregions(jpg)
589 IF (irgn == 0) cycle
590 ii=is2+regionoffsets(irgn)*in
591 ik=2*irgn
592 jr=npgrp(nsparc(is1+ik)) ! first (global) column
593 lj=nsparc(is1+ik-1) ! region offset
594 jn=nsparc(is1+ik+1)-lj ! number of columns
595 ! column range
596 ja=npgrp(jpg) ! first (global) column
597 jb=npgrp(jpg+1)-1 ! last (global) column
598 jbi=min(jb,i-1)
599 ii=ii+(i-ia)*jn-jr+1 ! offset for row 'i'
600 dsum=dsum-dot_product(gmat(ii+ja:ii+jbi),gvec(ja:jbi))
601 END DO
602 ! $OMP END PARALLEL DO
603 gvec(i)=dsum
604 END DO
605 END DO
606 !$POMP INST END(mpslsv2f)
607
608END SUBROUTINE mpslsv2
609
allocate array
Definition: mpdalc.f90:36
subroutine monpgs(i)
Progress monitoring.
Definition: mpmon.f90:68
subroutine mpslsp(npgrp, nsparr, nsparc)
Analyse skyline stucture.
Definition: mpskyl.f90:121
subroutine mpslsv2(npgrp, nsparr, nsparc, gmat, gvec, nsize)
Backward, forward substitution.
Definition: mpskyl.f90:438
subroutine mpslan(n, lrows, npgrp, nsparr)
Analyse skyline stucture.
Definition: mpskyl.f90:46
subroutine mpslsv(gij, gvec, nfit)
Backward, forward substitution.
Definition: mpskyl.f90:391
subroutine mpsldc(npgrp, nsparr, nsparc, gmat, nsize, nrank, mon)
Cholesky decomposition.
Definition: mpskyl.f90:188
(De)Allocate vectors and arrays.
Definition: mpdalc.f90:24
Definition of constants.
Definition: mpdef.f90:24
QL data.
Definition: mpskyl.f90:26
integer(mpi), dimension(:), allocatable regionoffsets
offsets for parameter group regions (in row)
Definition: mpskyl.f90:33
integer(mpi), dimension(:), allocatable pargroupstoregions
mapping of parameter groups to regions (in row)
Definition: mpskyl.f90:32
integer(mpi) npar
number of parameters
Definition: mpskyl.f90:30
integer(mpi) nthrd
number of threads
Definition: mpskyl.f90:34
integer(mpi), dimension(:), allocatable lastrowincol
last (non-zero) row in column
Definition: mpskyl.f90:31