Merge lp:~nickpapior/libgridxc/reshape into lp:libgridxc

Proposed by Nick Papior
Status: Merged
Approved by: Alberto Garcia
Approved revision: 32
Merged at revision: 31
Proposed branch: lp:~nickpapior/libgridxc/reshape
Merge into: lp:libgridxc
Diff against target: 1476 lines (+1102/-75)
8 files modified
src/array.F90 (+974/-0)
src/gridxc.F90 (+2/-0)
src/makefile (+39/-24)
src/mesh3d.F90 (+46/-35)
src/moreParallelSubs.F90 (+38/-13)
src/sorting.f (+1/-1)
src/xcmod.F90 (+1/-1)
version.info (+1/-1)
To merge this branch: bzr merge lp:~nickpapior/libgridxc/reshape
Reviewer Review Type Date Requested Status
Alberto Garcia Approve
Review via email: mp+317435@code.launchpad.net

Description of the change

Changes all reshape calls in mesh3d to an intrinsic copy.

The test4 has been tested with mpirun -n 4/5/6 and results are the same.

I am not sure whether all array_* calls are executed due to various present-statements in the routines.

To post a comment you must log in.
Revision history for this message
Alberto Garcia (albertog) wrote :

OK. I always wondered whether reshape was safe to use...

review: Approve
Revision history for this message
Nick Papior (nickpapior) wrote :

Great, I will commence fixing this in SIESTA-4.0.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/array.F90'
2--- src/array.F90 1970-01-01 00:00:00 +0000
3+++ src/array.F90 2017-02-16 10:29:06 +0000
4@@ -0,0 +1,974 @@
5+!!@LICENSE
6+!
7+!******************************************************************************
8+! MODULE array
9+! Provides utilities for copying data from one array shape to another
10+! array shape.
11+! Written by Nick R. Papior, Feb.2017
12+!******************************************************************************
13+!
14+! PUBLIC procedures available from this module:
15+! array_copy : Copies an array from one dimension to another array with another dimension
16+! array_add : Adds an array from one dimension to another array with another dimension
17+!
18+! PUBLIC parameters, types, and variables available from this module:
19+! none
20+!
21+! The intent of this module is to bypass the use of the intrinsic reshape
22+! function.
23+! Sadly many compilers implement the reshape with a guard on pointers such
24+! that a temporary array is created upon reshaping. For very large segments
25+! this turns out to be a substantial memory consumption on the heap which
26+! may easily be circumvented by doing explicit copying.
27+! These routines are extremely simple and does nothing but copy data from
28+! one shape to another.
29+!
30+! Currently only these copies and adds are implemented:
31+!
32+! 1D -> 2D [integer, real(sp), real(dp)]
33+! 1D -> 3D [integer, real(sp), real(dp)]
34+! 2D -> 1D [integer, real(sp), real(dp)]
35+! 3D -> 1D [integer, real(sp), real(dp)]
36+
37+module m_array
38+
39+ use precision, only: sp, dp
40+ use sys, only: die ! Termination routine
41+
42+ private
43+
44+ public :: array_copy
45+ public :: array_add
46+
47+ interface array_copy
48+ module procedure ac_1d_2d_ip, ac_1d_2d_sp, ac_1d_2d_dp
49+ module procedure ac_1d_3d_ip, ac_1d_3d_sp, ac_1d_3d_dp
50+ module procedure ac_2d_1d_ip, ac_2d_1d_sp, ac_2d_1d_dp
51+ module procedure ac_3d_1d_ip, ac_3d_1d_sp, ac_3d_1d_dp
52+ module procedure ac_4d_1d_ip, ac_4d_1d_sp, ac_4d_1d_dp
53+ end interface array_copy
54+
55+ interface array_add
56+ module procedure aa_1d_2d_ip, aa_1d_2d_sp, aa_1d_2d_dp
57+ module procedure aa_1d_3d_ip, aa_1d_3d_sp, aa_1d_3d_dp
58+ module procedure aa_1d_4d_ip, aa_1d_4d_sp, aa_1d_4d_dp
59+ module procedure aa_2d_1d_ip, aa_2d_1d_sp, aa_2d_1d_dp
60+ module procedure aa_3d_1d_ip, aa_3d_1d_sp, aa_3d_1d_dp
61+ module procedure aa_4d_1d_ip, aa_4d_1d_sp, aa_4d_1d_dp
62+ end interface array_add
63+
64+contains
65+
66+ ! Copies a 1D array to a 2D array
67+ subroutine ac_1d_2d_ip(from_1D, to_1D, in1D, from_2D, to_2D, out2D)
68+ integer, intent(in) :: from_1D, to_1D
69+ integer, intent(in) :: in1D(:)
70+ integer, intent(in) :: from_2D(2), to_2D(2)
71+ integer, intent(inout) :: out2D(:,:)
72+
73+ ! Local variables for copying
74+ integer :: i1D, i2D, j2D
75+
76+ i2D = from_2D(1)
77+ j2D = from_2D(2)
78+ do i1D = from_1D, to_1D
79+ out2D(i2D, j2D) = in1D(i1D)
80+ i2D = i2D + 1
81+ if ( i2D > to_2D(1) ) then
82+ i2D = from_2D(1)
83+ j2D = j2D + 1
84+ end if
85+ end do
86+
87+ if ( i2D /= from_2D(1) ) &
88+ call die("integer: 1D->2D failed (i)")
89+ if ( j2D <= to_2D(2) ) &
90+ call die("integer: 1D->2D failed (j)")
91+
92+ end subroutine ac_1d_2d_ip
93+ subroutine ac_1d_2d_sp(from_1D, to_1D, in1D, from_2D, to_2D, out2D)
94+ integer, intent(in) :: from_1D, to_1D
95+ real(sp), intent(in) :: in1D(:)
96+ integer, intent(in) :: from_2D(2), to_2D(2)
97+ real(sp), intent(inout) :: out2D(:,:)
98+
99+ ! Local variables for copying
100+ integer :: i1D, i2D, j2D
101+
102+ i2D = from_2D(1)
103+ j2D = from_2D(2)
104+ do i1D = from_1D, to_1D
105+ out2D(i2D, j2D) = in1D(i1D)
106+ i2D = i2D + 1
107+ if ( i2D > to_2D(1) ) then
108+ i2D = from_2D(1)
109+ j2D = j2D + 1
110+ end if
111+ end do
112+
113+ if ( i2D /= from_2D(1) ) &
114+ call die("real: 1D->2D failed (i)")
115+ if ( j2D <= to_2D(2) ) &
116+ call die("real: 1D->2D failed (j)")
117+
118+ end subroutine ac_1d_2d_sp
119+ subroutine ac_1d_2d_dp(from_1D, to_1D, in1D, from_2D, to_2D, out2D)
120+ integer, intent(in) :: from_1D, to_1D
121+ real(dp), intent(in) :: in1D(:)
122+ integer, intent(in) :: from_2D(2), to_2D(2)
123+ real(dp), intent(inout) :: out2D(:,:)
124+
125+ ! Local variables for copying
126+ integer :: i1D, i2D, j2D
127+
128+ i2D = from_2D(1)
129+ j2D = from_2D(2)
130+ do i1D = from_1D, to_1D
131+ out2D(i2D, j2D) = in1D(i1D)
132+ i2D = i2D + 1
133+ if ( i2D > to_2D(1) ) then
134+ i2D = from_2D(1)
135+ j2D = j2D + 1
136+ end if
137+ end do
138+
139+ if ( i2D /= from_2D(1) ) &
140+ call die("double: 1D->2D failed (i)")
141+ if ( j2D <= to_2D(2) ) &
142+ call die("double: 1D->2D failed (j)")
143+
144+ end subroutine ac_1d_2d_dp
145+
146+ ! Copies a 1D array to a 3D array
147+ subroutine ac_1d_3d_ip(from_1D, to_1D, in1D, from_3D, to_3D, out3D)
148+ integer, intent(in) :: from_1D, to_1D
149+ integer, intent(in) :: in1D(:)
150+ integer, intent(in) :: from_3D(3), to_3D(3)
151+ integer, intent(inout) :: out3D(:,:,:)
152+
153+ ! Local variables for copying
154+ integer :: i1D, i3D, j3D, k3D
155+
156+ i3D = from_3D(1)
157+ j3D = from_3D(2)
158+ k3D = from_3D(3)
159+ do i1D = from_1D, to_1D
160+ out3D(i3D, j3D, k3D) = in1D(i1D)
161+ i3D = i3D + 1
162+ if ( i3D > to_3D(1) ) then
163+ i3D = from_3D(1)
164+ j3D = j3D + 1
165+ end if
166+ if ( j3D > to_3D(2) ) then
167+ j3D = from_3D(2)
168+ k3D = k3D + 1
169+ end if
170+ end do
171+
172+ if ( i3D /= from_3D(1) ) &
173+ call die("integer: 1D->3D failed (i)")
174+ if ( j3D /= from_3D(2) ) &
175+ call die("integer: 1D->3D failed (j)")
176+ if ( k3D <= to_3D(3) ) &
177+ call die("integer: 1D->3D failed (k)")
178+
179+ end subroutine ac_1d_3d_ip
180+ subroutine ac_1d_3d_sp(from_1D, to_1D, in1D, from_3D, to_3D, out3D)
181+ integer, intent(in) :: from_1D, to_1D
182+ real(sp), intent(in) :: in1D(:)
183+ integer, intent(in) :: from_3D(3), to_3D(3)
184+ real(sp), intent(inout) :: out3D(:,:,:)
185+
186+ ! Local variables for copying
187+ integer :: i1D, i3D, j3D, k3D
188+
189+ i3D = from_3D(1)
190+ j3D = from_3D(2)
191+ k3D = from_3D(3)
192+ do i1D = from_1D, to_1D
193+ out3D(i3D, j3D, k3D) = in1D(i1D)
194+ i3D = i3D + 1
195+ if ( i3D > to_3D(1) ) then
196+ i3D = from_3D(1)
197+ j3D = j3D + 1
198+ end if
199+ if ( j3D > to_3D(2) ) then
200+ j3D = from_3D(2)
201+ k3D = k3D + 1
202+ end if
203+ end do
204+
205+ if ( i3D /= from_3D(1) ) &
206+ call die("real: 1D->3D failed (i)")
207+ if ( j3D /= from_3D(2) ) &
208+ call die("real: 1D->3D failed (j)")
209+ if ( k3D <= to_3D(3) ) &
210+ call die("real: 1D->3D failed (k)")
211+
212+ end subroutine ac_1d_3d_sp
213+ subroutine ac_1d_3d_dp(from_1D, to_1D, in1D, from_3D, to_3D, out3D)
214+ integer, intent(in) :: from_1D, to_1D
215+ real(dp), intent(in) :: in1D(:)
216+ integer, intent(in) :: from_3D(3), to_3D(3)
217+ real(dp), intent(inout) :: out3D(:,:,:)
218+
219+ ! Local variables for copying
220+ integer :: i1D, i3D, j3D, k3D
221+
222+ i3D = from_3D(1)
223+ j3D = from_3D(2)
224+ k3D = from_3D(3)
225+ do i1D = from_1D, to_1D
226+ out3D(i3D, j3D, k3D) = in1D(i1D)
227+ i3D = i3D + 1
228+ if ( i3D > to_3D(1) ) then
229+ i3D = from_3D(1)
230+ j3D = j3D + 1
231+ end if
232+ if ( j3D > to_3D(2) ) then
233+ j3D = from_3D(2)
234+ k3D = k3D + 1
235+ end if
236+ end do
237+
238+ if ( i3D /= from_3D(1) ) &
239+ call die("double: 1D->3D failed (i)")
240+ if ( j3D /= from_3D(2) ) &
241+ call die("double: 1D->3D failed (j)")
242+ if ( k3D <= to_3D(3) ) &
243+ call die("double: 1D->3D failed (k)")
244+
245+ end subroutine ac_1d_3d_dp
246+
247+ ! Copies a 2D array to a 1D array
248+ subroutine ac_2d_1d_ip(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
249+ integer, intent(in) :: from_2D(2), to_2D(2)
250+ integer, intent(in) :: in2D(:,:)
251+ integer, intent(in) :: from_1D, to_1D
252+ integer, intent(inout) :: out1D(:)
253+
254+ ! Local variables for copying
255+ integer :: i2D, j2D, i1D
256+
257+ i1D = from_1D
258+ do j2D = from_2D(2), to_2D(2)
259+ do i2D = from_2D(1), to_2D(1)
260+ out1D(i1D) = in2D(i2D, j2D)
261+ i1D = i1D + 1
262+ end do
263+ end do
264+
265+ if ( i1D <= to_1D ) &
266+ call die("integer: 2D->1D failed")
267+
268+ end subroutine ac_2d_1d_ip
269+ subroutine ac_2d_1d_sp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
270+ integer, intent(in) :: from_2D(2), to_2D(2)
271+ real(sp), intent(in) :: in2D(:,:)
272+ integer, intent(in) :: from_1D, to_1D
273+ real(sp), intent(inout) :: out1D(:)
274+
275+ ! Local variables for copying
276+ integer :: i2D, j2D, i1D
277+
278+ i1D = from_1D
279+ do j2D = from_2D(2), to_2D(2)
280+ do i2D = from_2D(1), to_2D(1)
281+ out1D(i1D) = in2D(i2D, j2D)
282+ i1D = i1D + 1
283+ end do
284+ end do
285+
286+ if ( i1D <= to_1D ) &
287+ call die("real: 2D->1D failed")
288+
289+ end subroutine ac_2d_1d_sp
290+ subroutine ac_2d_1d_dp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
291+ integer, intent(in) :: from_2D(2), to_2D(2)
292+ real(dp), intent(in) :: in2D(:,:)
293+ integer, intent(in) :: from_1D, to_1D
294+ real(dp), intent(inout) :: out1D(:)
295+
296+ ! Local variables for copying
297+ integer :: i2D, j2D, i1D
298+
299+ i1D = from_1D
300+ do j2D = from_2D(2), to_2D(2)
301+ do i2D = from_2D(1), to_2D(1)
302+ out1D(i1D) = in2D(i2D, j2D)
303+ i1D = i1D + 1
304+ end do
305+ end do
306+
307+ if ( i1D <= to_1D ) &
308+ call die("double: 2D->1D failed")
309+
310+ end subroutine ac_2d_1d_dp
311+
312+ ! Copies a 3D array to a 1D array
313+ subroutine ac_3d_1d_ip(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
314+ integer, intent(in) :: from_3D(3), to_3D(3)
315+ integer, intent(in) :: in3D(:,:,:)
316+ integer, intent(in) :: from_1D, to_1D
317+ integer, intent(inout) :: out1D(:)
318+
319+ ! Local variables for copying
320+ integer :: i3D, j3D, k3D, i1D
321+
322+ i1D = from_1D
323+ do k3D = from_3D(3), to_3D(3)
324+ do j3D = from_3D(2), to_3D(2)
325+ do i3D = from_3D(1), to_3D(1)
326+ out1D(i1D) = in3D(i3D, j3D, k3D)
327+ i1D = i1D + 1
328+ end do
329+ end do
330+ end do
331+
332+ if ( i1D <= to_1D ) &
333+ call die("integer: 3D->1D failed")
334+
335+ end subroutine ac_3d_1d_ip
336+ subroutine ac_3d_1d_sp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
337+ integer, intent(in) :: from_3D(3), to_3D(3)
338+ real(sp), intent(in) :: in3D(:,:,:)
339+ integer, intent(in) :: from_1D, to_1D
340+ real(sp), intent(inout) :: out1D(:)
341+
342+ ! Local variables for copying
343+ integer :: i3D, j3D, k3D, i1D
344+
345+ i1D = from_1D
346+ do k3D = from_3D(3), to_3D(3)
347+ do j3D = from_3D(2), to_3D(2)
348+ do i3D = from_3D(1), to_3D(1)
349+ out1D(i1D) = in3D(i3D, j3D, k3D)
350+ i1D = i1D + 1
351+ end do
352+ end do
353+ end do
354+
355+ if ( i1D <= to_1D ) &
356+ call die("real: 3D->1D failed")
357+
358+ end subroutine ac_3d_1d_sp
359+ subroutine ac_3d_1d_dp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
360+ integer, intent(in) :: from_3D(3), to_3D(3)
361+ real(dp), intent(in) :: in3D(:,:,:)
362+ integer, intent(in) :: from_1D, to_1D
363+ real(dp), intent(inout) :: out1D(:)
364+
365+ ! Local variables for copying
366+ integer :: i3D, j3D, k3D, i1D
367+
368+ i1D = from_1D
369+ do k3D = from_3D(3), to_3D(3)
370+ do j3D = from_3D(2), to_3D(2)
371+ do i3D = from_3D(1), to_3D(1)
372+ out1D(i1D) = in3D(i3D, j3D, k3D)
373+ i1D = i1D + 1
374+ end do
375+ end do
376+ end do
377+
378+ if ( i1D <= to_1D ) &
379+ call die("double: 3D->1D failed")
380+
381+ end subroutine ac_3d_1d_dp
382+
383+ ! Copies a 4D array to a 1D array
384+ subroutine ac_4d_1d_ip(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
385+ integer, intent(in) :: from_4D(4), to_4D(4)
386+ integer, intent(in) :: in4D(:,:,:,:)
387+ integer, intent(in) :: from_1D, to_1D
388+ integer, intent(inout) :: out1D(:)
389+
390+ ! Local variables for copying
391+ integer :: i4D, j4D, k4D, m4D, i1D
392+
393+ i1D = from_1D
394+ do m4D = from_4D(4), to_4D(4)
395+ do k4D = from_4D(3), to_4D(3)
396+ do j4D = from_4D(2), to_4D(2)
397+ do i4D = from_4D(1), to_4D(1)
398+ out1D(i1D) = in4D(i4D, j4D, k4D, m4D)
399+ i1D = i1D + 1
400+ end do
401+ end do
402+ end do
403+ end do
404+
405+ if ( i1D <= to_1D ) &
406+ call die("integer: 4D->1D failed")
407+
408+ end subroutine ac_4d_1d_ip
409+ subroutine ac_4d_1d_sp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
410+ integer, intent(in) :: from_4D(4), to_4D(4)
411+ real(sp), intent(in) :: in4D(:,:,:,:)
412+ integer, intent(in) :: from_1D, to_1D
413+ real(sp), intent(inout) :: out1D(:)
414+
415+ ! Local variables for copying
416+ integer :: i4D, j4D, k4D, m4D, i1D
417+
418+ i1D = from_1D
419+ do m4D = from_4D(4), to_4D(4)
420+ do k4D = from_4D(3), to_4D(3)
421+ do j4D = from_4D(2), to_4D(2)
422+ do i4D = from_4D(1), to_4D(1)
423+ out1D(i1D) = in4D(i4D, j4D, k4D, m4D)
424+ i1D = i1D + 1
425+ end do
426+ end do
427+ end do
428+ end do
429+
430+ if ( i1D <= to_1D ) &
431+ call die("real: 4D->1D failed")
432+
433+ end subroutine ac_4d_1d_sp
434+ subroutine ac_4d_1d_dp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
435+ integer, intent(in) :: from_4D(4), to_4D(4)
436+ real(dp), intent(in) :: in4D(:,:,:,:)
437+ integer, intent(in) :: from_1D, to_1D
438+ real(dp), intent(inout) :: out1D(:)
439+
440+ ! Local variables for copying
441+ integer :: i4D, j4D, k4D, m4D, i1D
442+
443+ i1D = from_1D
444+ do m4D = from_4D(4), to_4D(4)
445+ do k4D = from_4D(3), to_4D(3)
446+ do j4D = from_4D(2), to_4D(2)
447+ do i4D = from_4D(1), to_4D(1)
448+ out1D(i1D) = in4D(i4D, j4D, k4D, m4D)
449+ i1D = i1D + 1
450+ end do
451+ end do
452+ end do
453+ end do
454+
455+ if ( i1D <= to_1D ) &
456+ call die("double: 4D->1D failed")
457+
458+ end subroutine ac_4d_1d_dp
459+
460+
461+ ! Adds a 1D array to a 2D array
462+ subroutine aa_1d_2d_ip(from_1D, to_1D, a1D, from_2D, to_2D, out2D)
463+ integer, intent(in) :: from_1D, to_1D
464+ integer, intent(in) :: a1D(:)
465+ integer, intent(in) :: from_2D(2), to_2D(2)
466+ integer, intent(inout) :: out2D(:,:)
467+
468+ ! Local variables for copying
469+ integer :: i1D, i2D, j2D
470+
471+ i2D = from_2D(1)
472+ j2D = from_2D(2)
473+ do i1D = from_1D, to_1D
474+ out2D(i2D, j2D) = out2D(i2D, j2D) + a1D(i1D)
475+ i2D = i2D + 1
476+ if ( i2D > to_2D(1) ) then
477+ i2D = from_2D(1)
478+ j2D = j2D + 1
479+ end if
480+ end do
481+
482+ if ( i2D /= from_2D(1) ) &
483+ call die("integer: 1D+>2D failed (i)")
484+ if ( j2D <= to_2D(2) ) &
485+ call die("integer: 1D+>2D failed (j)")
486+
487+ end subroutine aa_1d_2d_ip
488+ subroutine aa_1d_2d_sp(from_1D, to_1D, a1D, from_2D, to_2D, out2D)
489+ integer, intent(in) :: from_1D, to_1D
490+ real(sp), intent(in) :: a1D(:)
491+ integer, intent(in) :: from_2D(2), to_2D(2)
492+ real(sp), intent(inout) :: out2D(:,:)
493+
494+ ! Local variables for copying
495+ integer :: i1D, i2D, j2D
496+
497+ i2D = from_2D(1)
498+ j2D = from_2D(2)
499+ do i1D = from_1D, to_1D
500+ out2D(i2D, j2D) = out2D(i2D, j2D) + a1D(i1D)
501+ i2D = i2D + 1
502+ if ( i2D > to_2D(1) ) then
503+ i2D = from_2D(1)
504+ j2D = j2D + 1
505+ end if
506+ end do
507+
508+ if ( i2D /= from_2D(1) ) &
509+ call die("real: 1D+>2D failed (i)")
510+ if ( j2D <= to_2D(2) ) &
511+ call die("real: 1D+>2D failed (j)")
512+
513+ end subroutine aa_1d_2d_sp
514+ subroutine aa_1d_2d_dp(from_1D, to_1D, a1D, from_2D, to_2D, out2D)
515+ integer, intent(in) :: from_1D, to_1D
516+ real(dp), intent(in) :: a1D(:)
517+ integer, intent(in) :: from_2D(2), to_2D(2)
518+ real(dp), intent(inout) :: out2D(:,:)
519+
520+ ! Local variables for copying
521+ integer :: i1D, i2D, j2D
522+
523+ i2D = from_2D(1)
524+ j2D = from_2D(2)
525+ do i1D = from_1D, to_1D
526+ out2D(i2D, j2D) = out2D(i2D, j2D) + a1D(i1D)
527+ i2D = i2D + 1
528+ if ( i2D > to_2D(1) ) then
529+ i2D = from_2D(1)
530+ j2D = j2D + 1
531+ end if
532+ end do
533+
534+ if ( i2D /= from_2D(1) ) &
535+ call die("double: 1D+>2D failed (i)")
536+ if ( j2D <= to_2D(2) ) &
537+ call die("double: 1D+>2D failed (j)")
538+
539+ end subroutine aa_1d_2d_dp
540+
541+ ! Adds a 1D array to a 3D array
542+ subroutine aa_1d_3d_ip(from_1D, to_1D, a1D, from_3D, to_3D, out3D)
543+ integer, intent(in) :: from_1D, to_1D
544+ integer, intent(in) :: a1D(:)
545+ integer, intent(in) :: from_3D(3), to_3D(3)
546+ integer, intent(inout) :: out3D(:,:,:)
547+
548+ ! Local variables for copying
549+ integer :: i1D, i3D, j3D, k3D
550+
551+ i3D = from_3D(1)
552+ j3D = from_3D(2)
553+ k3D = from_3D(3)
554+ do i1D = from_1D, to_1D
555+ out3D(i3D, j3D, k3D) = out3D(i3D, j3D, k3D) + a1D(i1D)
556+ i3D = i3D + 1
557+ if ( i3D > to_3D(1) ) then
558+ i3D = from_3D(1)
559+ j3D = j3D + 1
560+ end if
561+ if ( j3D > to_3D(2) ) then
562+ j3D = from_3D(2)
563+ k3D = k3D + 1
564+ end if
565+ end do
566+
567+ if ( i3D /= from_3D(1) ) &
568+ call die("integer: 1D+>3D failed (i)")
569+ if ( j3D /= from_3D(2) ) &
570+ call die("integer: 1D+>3D failed (j)")
571+ if ( k3D <= to_3D(3) ) &
572+ call die("integer: 1D+>3D failed (k)")
573+
574+ end subroutine aa_1d_3d_ip
575+ subroutine aa_1d_3d_sp(from_1D, to_1D, a1D, from_3D, to_3D, out3D)
576+ integer, intent(in) :: from_1D, to_1D
577+ real(sp), intent(in) :: a1D(:)
578+ integer, intent(in) :: from_3D(3), to_3D(3)
579+ real(sp), intent(inout) :: out3D(:,:,:)
580+
581+ ! Local variables for copying
582+ integer :: i1D, i3D, j3D, k3D
583+
584+ i3D = from_3D(1)
585+ j3D = from_3D(2)
586+ k3D = from_3D(3)
587+ do i1D = from_1D, to_1D
588+ out3D(i3D, j3D, k3D) = out3D(i3D, j3D, k3D) + a1D(i1D)
589+ i3D = i3D + 1
590+ if ( i3D > to_3D(1) ) then
591+ i3D = from_3D(1)
592+ j3D = j3D + 1
593+ end if
594+ if ( j3D > to_3D(2) ) then
595+ j3D = from_3D(2)
596+ k3D = k3D + 1
597+ end if
598+ end do
599+
600+ if ( i3D /= from_3D(1) ) &
601+ call die("real: 1D+>3D failed (i)")
602+ if ( j3D /= from_3D(2) ) &
603+ call die("real: 1D+>3D failed (j)")
604+ if ( k3D <= to_3D(3) ) &
605+ call die("real: 1D+>3D failed (k)")
606+
607+ end subroutine aa_1d_3d_sp
608+ subroutine aa_1d_3d_dp(from_1D, to_1D, a1D, from_3D, to_3D, out3D)
609+ integer, intent(in) :: from_1D, to_1D
610+ real(dp), intent(in) :: a1D(:)
611+ integer, intent(in) :: from_3D(3), to_3D(3)
612+ real(dp), intent(inout) :: out3D(:,:,:)
613+
614+ ! Local variables for copying
615+ integer :: i1D, i3D, j3D, k3D
616+
617+ i3D = from_3D(1)
618+ j3D = from_3D(2)
619+ k3D = from_3D(3)
620+ do i1D = from_1D, to_1D
621+ out3D(i3D, j3D, k3D) = out3D(i3D, j3D, k3D) + a1D(i1D)
622+ i3D = i3D + 1
623+ if ( i3D > to_3D(1) ) then
624+ i3D = from_3D(1)
625+ j3D = j3D + 1
626+ end if
627+ if ( j3D > to_3D(2) ) then
628+ j3D = from_3D(2)
629+ k3D = k3D + 1
630+ end if
631+ end do
632+
633+ if ( i3D /= from_3D(1) ) &
634+ call die("double: 1D+>3D failed (i)")
635+ if ( j3D /= from_3D(2) ) &
636+ call die("double: 1D+>3D failed (j)")
637+ if ( k3D <= to_3D(3) ) &
638+ call die("double: 1D+>3D failed (k)")
639+
640+ end subroutine aa_1d_3d_dp
641+
642+ ! Adds a 1D array to a 4D array
643+ subroutine aa_1d_4d_ip(from_1D, to_1D, a1D, from_4D, to_4D, out4D)
644+ integer, intent(in) :: from_1D, to_1D
645+ integer, intent(in) :: a1D(:)
646+ integer, intent(in) :: from_4D(4), to_4D(4)
647+ integer, intent(inout) :: out4D(:,:,:,:)
648+
649+ ! Local variables for copying
650+ integer :: i1D, i4D, j4D, k4D, m4D
651+
652+ i4D = from_4D(1)
653+ j4D = from_4D(2)
654+ k4D = from_4D(3)
655+ m4D = from_4D(4)
656+ do i1D = from_1D, to_1D
657+ out4D(i4D, j4D, k4D, m4D) = out4D(i4D, j4D, k4D, m4D) + a1D(i1D)
658+ i4D = i4D + 1
659+ if ( i4D > to_4D(1) ) then
660+ i4D = from_4D(1)
661+ j4D = j4D + 1
662+ end if
663+ if ( j4D > to_4D(2) ) then
664+ j4D = from_4D(2)
665+ k4D = k4D + 1
666+ end if
667+ if ( k4D > to_4D(3) ) then
668+ k4D = from_4D(3)
669+ m4D = m4D + 1
670+ end if
671+ end do
672+
673+ if ( i4D /= from_4D(1) ) &
674+ call die("integer: 1D+>4D failed (i)")
675+ if ( j4D /= from_4D(2) ) &
676+ call die("integer: 1D+>4D failed (j)")
677+ if ( k4D /= from_4D(3) ) &
678+ call die("integer: 1D+>4D failed (k)")
679+ if ( m4D <= to_4D(4) ) &
680+ call die("integer: 1D+>4D failed (m)")
681+
682+ end subroutine aa_1d_4d_ip
683+ subroutine aa_1d_4d_sp(from_1D, to_1D, a1D, from_4D, to_4D, out4D)
684+ integer, intent(in) :: from_1D, to_1D
685+ real(sp), intent(in) :: a1D(:)
686+ integer, intent(in) :: from_4D(4), to_4D(4)
687+ real(sp), intent(inout) :: out4D(:,:,:,:)
688+
689+ ! Local variables for copying
690+ integer :: i1D, i4D, j4D, k4D, m4D
691+
692+ i4D = from_4D(1)
693+ j4D = from_4D(2)
694+ k4D = from_4D(3)
695+ m4D = from_4D(4)
696+ do i1D = from_1D, to_1D
697+ out4D(i4D, j4D, k4D, m4D) = out4D(i4D, j4D, k4D, m4D) + a1D(i1D)
698+ i4D = i4D + 1
699+ if ( i4D > to_4D(1) ) then
700+ i4D = from_4D(1)
701+ j4D = j4D + 1
702+ end if
703+ if ( j4D > to_4D(2) ) then
704+ j4D = from_4D(2)
705+ k4D = k4D + 1
706+ end if
707+ if ( k4D > to_4D(3) ) then
708+ k4D = from_4D(3)
709+ m4D = m4D + 1
710+ end if
711+ end do
712+
713+ if ( i4D /= from_4D(1) ) &
714+ call die("real: 1D+>4D failed (i)")
715+ if ( j4D /= from_4D(2) ) &
716+ call die("real: 1D+>4D failed (j)")
717+ if ( k4D /= from_4D(3) ) &
718+ call die("real: 1D+>4D failed (k)")
719+ if ( m4D <= to_4D(4) ) &
720+ call die("real: 1D+>4D failed (m)")
721+
722+ end subroutine aa_1d_4d_sp
723+ subroutine aa_1d_4d_dp(from_1D, to_1D, a1D, from_4D, to_4D, out4D)
724+ integer, intent(in) :: from_1D, to_1D
725+ real(dp), intent(in) :: a1D(:)
726+ integer, intent(in) :: from_4D(4), to_4D(4)
727+ real(dp), intent(inout) :: out4D(:,:,:,:)
728+
729+ ! Local variables for copying
730+ integer :: i1D, i4D, j4D, k4D, m4D
731+
732+ i4D = from_4D(1)
733+ j4D = from_4D(2)
734+ k4D = from_4D(3)
735+ m4D = from_4D(4)
736+ do i1D = from_1D, to_1D
737+ out4D(i4D, j4D, k4D, m4D) = out4D(i4D, j4D, k4D, m4D) + a1D(i1D)
738+ i4D = i4D + 1
739+ if ( i4D > to_4D(1) ) then
740+ i4D = from_4D(1)
741+ j4D = j4D + 1
742+ end if
743+ if ( j4D > to_4D(2) ) then
744+ j4D = from_4D(2)
745+ k4D = k4D + 1
746+ end if
747+ if ( k4D > to_4D(3) ) then
748+ k4D = from_4D(3)
749+ m4D = m4D + 1
750+ end if
751+ end do
752+
753+ if ( i4D /= from_4D(1) ) &
754+ call die("double: 1D+>4D failed (i)")
755+ if ( j4D /= from_4D(2) ) &
756+ call die("double: 1D+>4D failed (j)")
757+ if ( k4D /= from_4D(3) ) &
758+ call die("double: 1D+>4D failed (k)")
759+ if ( m4D <= to_4D(4) ) &
760+ call die("double: 1D+>4D failed (m)")
761+
762+ end subroutine aa_1d_4d_dp
763+
764+ ! Adds a 2D array to a 1D array
765+ subroutine aa_2d_1d_ip(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
766+ integer, intent(in) :: from_2D(2), to_2D(2)
767+ integer, intent(in) :: in2D(:,:)
768+ integer, intent(in) :: from_1D, to_1D
769+ integer, intent(inout) :: out1D(:)
770+
771+ ! Local variables for copying
772+ integer :: i2D, j2D, i1D
773+
774+ i1D = from_1D
775+ do j2D = from_2D(2), to_2D(2)
776+ do i2D = from_2D(1), to_2D(1)
777+ out1D(i1D) = out1D(i1D) + in2D(i2D, j2D)
778+ i1D = i1D + 1
779+ end do
780+ end do
781+
782+ if ( i1D <= to_1D ) &
783+ call die("integer: 2D+>1D failed")
784+
785+ end subroutine aa_2d_1d_ip
786+ subroutine aa_2d_1d_sp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
787+ integer, intent(in) :: from_2D(2), to_2D(2)
788+ real(sp), intent(in) :: in2D(:,:)
789+ integer, intent(in) :: from_1D, to_1D
790+ real(sp), intent(inout) :: out1D(:)
791+
792+ ! Local variables for copying
793+ integer :: i2D, j2D, i1D
794+
795+ i1D = from_1D
796+ do j2D = from_2D(2), to_2D(2)
797+ do i2D = from_2D(1), to_2D(1)
798+ out1D(i1D) = out1D(i1D) + in2D(i2D, j2D)
799+ i1D = i1D + 1
800+ end do
801+ end do
802+
803+ if ( i1D <= to_1D ) &
804+ call die("real: 2D+>1D failed")
805+
806+ end subroutine aa_2d_1d_sp
807+ subroutine aa_2d_1d_dp(from_2D, to_2D, in2D, from_1D, to_1D, out1D)
808+ integer, intent(in) :: from_2D(2), to_2D(2)
809+ real(dp), intent(in) :: in2D(:,:)
810+ integer, intent(in) :: from_1D, to_1D
811+ real(dp), intent(inout) :: out1D(:)
812+
813+ ! Local variables for copying
814+ integer :: i2D, j2D, i1D
815+
816+ i1D = from_1D
817+ do j2D = from_2D(2), to_2D(2)
818+ do i2D = from_2D(1), to_2D(1)
819+ out1D(i1D) = out1D(i1D) + in2D(i2D, j2D)
820+ i1D = i1D + 1
821+ end do
822+ end do
823+
824+ if ( i1D <= to_1D ) &
825+ call die("double: 2D+>1D failed")
826+
827+ end subroutine aa_2d_1d_dp
828+
829+ ! Adds a 3D array to a 1D array
830+ subroutine aa_3d_1d_ip(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
831+ integer, intent(in) :: from_3D(3), to_3D(3)
832+ integer, intent(in) :: in3D(:,:,:)
833+ integer, intent(in) :: from_1D, to_1D
834+ integer, intent(inout) :: out1D(:)
835+
836+ ! Local variables for copying
837+ integer :: i3D, j3D, k3D, i1D
838+
839+ i1D = from_1D
840+ do k3D = from_3D(3), to_3D(3)
841+ do j3D = from_3D(2), to_3D(2)
842+ do i3D = from_3D(1), to_3D(1)
843+ out1D(i1D) = out1D(i1D) + in3D(i3D, j3D, k3D)
844+ i1D = i1D + 1
845+ end do
846+ end do
847+ end do
848+
849+ if ( i1D <= to_1D ) &
850+ call die("integer: 3D+>1D failed")
851+
852+ end subroutine aa_3d_1d_ip
853+ subroutine aa_3d_1d_sp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
854+ integer, intent(in) :: from_3D(3), to_3D(3)
855+ real(sp), intent(in) :: in3D(:,:,:)
856+ integer, intent(in) :: from_1D, to_1D
857+ real(sp), intent(inout) :: out1D(:)
858+
859+ ! Local variables for copying
860+ integer :: i3D, j3D, k3D, i1D
861+
862+ i1D = from_1D
863+ do k3D = from_3D(3), to_3D(3)
864+ do j3D = from_3D(2), to_3D(2)
865+ do i3D = from_3D(1), to_3D(1)
866+ out1D(i1D) = out1D(i1D) + in3D(i3D, j3D, k3D)
867+ i1D = i1D + 1
868+ end do
869+ end do
870+ end do
871+
872+ if ( i1D <= to_1D ) &
873+ call die("real: 3D+>1D failed")
874+
875+ end subroutine aa_3d_1d_sp
876+ subroutine aa_3d_1d_dp(from_3D, to_3D, in3D, from_1D, to_1D, out1D)
877+ integer, intent(in) :: from_3D(3), to_3D(3)
878+ real(dp), intent(in) :: in3D(:,:,:)
879+ integer, intent(in) :: from_1D, to_1D
880+ real(dp), intent(inout) :: out1D(:)
881+
882+ ! Local variables for copying
883+ integer :: i3D, j3D, k3D, i1D
884+
885+ i1D = from_1D
886+ do k3D = from_3D(3), to_3D(3)
887+ do j3D = from_3D(2), to_3D(2)
888+ do i3D = from_3D(1), to_3D(1)
889+ out1D(i1D) = out1D(i1D) + in3D(i3D, j3D, k3D)
890+ i1D = i1D + 1
891+ end do
892+ end do
893+ end do
894+
895+ if ( i1D <= to_1D ) &
896+ call die("double: 3D+>1D failed")
897+
898+ end subroutine aa_3d_1d_dp
899+
900+ ! Adds a 4D array to a 1D array
901+ subroutine aa_4d_1d_ip(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
902+ integer, intent(in) :: from_4D(4), to_4D(4)
903+ integer, intent(in) :: in4D(:,:,:,:)
904+ integer, intent(in) :: from_1D, to_1D
905+ integer, intent(inout) :: out1D(:)
906+
907+ ! Local variables for copying
908+ integer :: i4D, j4D, k4D, m4D, i1D
909+
910+ i1D = from_1D
911+ do m4D = from_4D(4), to_4D(4)
912+ do k4D = from_4D(3), to_4D(3)
913+ do j4D = from_4D(2), to_4D(2)
914+ do i4D = from_4D(1), to_4D(1)
915+ out1D(i1D) = out1D(i1D) + in4D(i4D, j4D, k4D, m4D)
916+ i1D = i1D + 1
917+ end do
918+ end do
919+ end do
920+ end do
921+
922+ if ( i1D <= to_1D ) &
923+ call die("integer: 4D+>1D failed")
924+
925+ end subroutine aa_4d_1d_ip
926+ subroutine aa_4d_1d_sp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
927+ integer, intent(in) :: from_4D(4), to_4D(4)
928+ real(sp), intent(in) :: in4D(:,:,:,:)
929+ integer, intent(in) :: from_1D, to_1D
930+ real(sp), intent(inout) :: out1D(:)
931+
932+ ! Local variables for copying
933+ integer :: i4D, j4D, k4D, m4D, i1D
934+
935+ i1D = from_1D
936+ do m4D = from_4D(4), to_4D(4)
937+ do k4D = from_4D(3), to_4D(3)
938+ do j4D = from_4D(2), to_4D(2)
939+ do i4D = from_4D(1), to_4D(1)
940+ out1D(i1D) = out1D(i1D) + in4D(i4D, j4D, k4D, m4D)
941+ i1D = i1D + 1
942+ end do
943+ end do
944+ end do
945+ end do
946+
947+ if ( i1D <= to_1D ) &
948+ call die("real: 4D+>1D failed")
949+
950+ end subroutine aa_4d_1d_sp
951+ subroutine aa_4d_1d_dp(from_4D, to_4D, in4D, from_1D, to_1D, out1D)
952+ integer, intent(in) :: from_4D(4), to_4D(4)
953+ real(dp), intent(in) :: in4D(:,:,:,:)
954+ integer, intent(in) :: from_1D, to_1D
955+ real(dp), intent(inout) :: out1D(:)
956+
957+ ! Local variables for copying
958+ integer :: i4D, j4D, k4D, m4D, i1D
959+
960+ i1D = from_1D
961+ do m4D = from_4D(4), to_4D(4)
962+ do k4D = from_4D(3), to_4D(3)
963+ do j4D = from_4D(2), to_4D(2)
964+ do i4D = from_4D(1), to_4D(1)
965+ out1D(i1D) = out1D(i1D) + in4D(i4D, j4D, k4D, m4D)
966+ i1D = i1D + 1
967+ end do
968+ end do
969+ end do
970+ end do
971+
972+ if ( i1D <= to_1D ) &
973+ call die("double: 4D+>1D failed")
974+
975+ end subroutine aa_4d_1d_dp
976+
977+end module m_array
978+
979
980=== modified file 'src/gridxc.F90'
981--- src/gridxc.F90 2017-01-20 11:55:29 +0000
982+++ src/gridxc.F90 2017-02-16 10:29:06 +0000
983@@ -605,7 +605,9 @@
984 USE m_cellXC, only: gridxc_cellXC => cellXC ! XC for a periodic unit cell
985 USE xcmod, only: gridxc_getXC => getXC ! Returns XC functional(s)
986 USE xcmod, only: gridxc_setXC => setXC ! Sets XC functional(s)
987+#ifdef LIBXC
988 USE xcmod, only: gridxc_setXC_libxc => setXC_libxc_ids ! Sets XC functional(s)
989+#endif
990
991 ! Secondary entry points for testers and lower-level programming
992 USE m_ldaxc, only: gridxc_ldaxc => ldaxc ! LDA-XC functionals
993
994=== modified file 'src/makefile'
995--- src/makefile 2017-01-20 11:55:29 +0000
996+++ src/makefile 2017-02-16 10:29:06 +0000
997@@ -29,35 +29,46 @@
998 #
999 ARCH_MAKE_DEFAULT=$(MAIN_OBJDIR)/fortran.mk
1000 ARCH_MAKE?=$(ARCH_MAKE_DEFAULT)
1001-include $(ARCH_MAKE)
1002+
1003+# Ensure that we can ALWAYS run make dep in the MAIN directory
1004+ifeq ($(VPATH),.)
1005+ -include $(ARCH_MAKE)
1006+else
1007+ include $(ARCH_MAKE)
1008+endif
1009+
1010+# Default library commands
1011+AR ?= ar
1012 RANLIB ?= ranlib
1013-#
1014+
1015 ifdef WITH_LIBXC
1016- #
1017+
1018 ifndef LIBXC_ROOT
1019 $(error you need to define LIBXC_ROOT in your arch.make)
1020 endif
1021- #
1022+
1023 LIBXC_MK_FILE_DIR ?= $(LIBXC_ROOT)
1024 FPPFLAGS += -DLIBXC
1025 include $(LIBXC_MK_FILE_DIR)/libxc.mk
1026+
1027 endif
1028-#
1029+
1030 module: libGridXC.a
1031-#
1032+
1033 dep:
1034 sfmakedepend --depend=obj --modext=o *.f *.f90 *.F *.F90
1035-#
1036+
1037 GRID_SRCS= alloc.F90 bessph.f cellsubs.f \
1038 chkgmx.f interpolation.f90 \
1039 minvec.f m_io.f moreParallelSubs.F90 \
1040 m_fft_gpfa.F m_walltime.f90 \
1041- precision.F radfft.f sorting.f sys.F
1042+ precision.F radfft.f sorting.f sys.F \
1043+ array.F90
1044 GRID_OBJS:= $(GRID_SRCS:.f=.o)
1045 GRID_OBJS:= $(GRID_OBJS:.F=.o)
1046 GRID_OBJS:= $(GRID_OBJS:.f90=.o)
1047 GRID_OBJS:= $(GRID_OBJS:.F90=.o)
1048-#
1049+
1050 LOCAL_SRCS= atomxc.F90 cellxc.F90 debugxc.f90 ggaxc.F ldaxc.F \
1051 gridxc.F90 vdwxc.F90 xcmod.f90 fft3d.F90 fftr.F90 \
1052 mesh1d.f90 mesh3d.F90 am05.f90 vv_vdwxc.F90 \
1053@@ -66,12 +77,12 @@
1054 LOCAL_OBJS:= $(LOCAL_OBJS:.F=.o)
1055 LOCAL_OBJS:= $(LOCAL_OBJS:.f90=.o)
1056 LOCAL_OBJS:= $(LOCAL_OBJS:.F90=.o)
1057-#
1058+
1059 ALL_OBJS=$(GRID_OBJS) $(LOCAL_OBJS)
1060-#
1061-#
1062+
1063+
1064 INCFLAGS:= $(LIBXC_INCFLAGS) $(INCFLAGS)
1065-#
1066+
1067 ifdef WITH_MPI
1068 MPI_INTERFACE=libmpi_f90.a
1069 FPPFLAGS:= -DMPI $(FPPFLAGS)
1070@@ -79,21 +90,21 @@
1071 else
1072 MPI_INTERFACE=
1073 endif
1074-#
1075+
1076 libmpi_f90.a:
1077 @(cd MPI_instr ; $(MAKE) \
1078 "VPATH=$(VPATH)/MPI_instr" )
1079-#
1080+
1081 libGridXC.a: $(MPI_INTERFACE) $(ALL_OBJS)
1082- ar $(ARFLAGS_EXTRA) cru libGridXC.a $(ALL_OBJS)
1083+ $(AR) $(ARFLAGS_EXTRA) cru libGridXC.a $(ALL_OBJS)
1084 @if [ ! -z "$(MPI_INTERFACE)" ] ; then \
1085- ar $(ARFLAGS_EXTRA) cru libGridXC.a MPI_instr/*.o ; fi
1086+ $(AR) $(ARFLAGS_EXTRA) cru libGridXC.a MPI_instr/*.o ; fi
1087 -$(RANLIB) libGridXC.a
1088-#
1089+
1090 MODULES_TO_INSTALL=gridxc.mod gridxc_config.mod m_atomxc.mod \
1091 m_cellxc.mod xcmod.mod m_ldaxc.mod m_ggaxc.mod \
1092 m_fft_gpfa.mod debugxc.mod mesh3d.mod
1093-#
1094+
1095 ifdef WITH_LIBXC
1096 ifdef WITH_MPI
1097 setup_mk_file:
1098@@ -112,7 +123,7 @@
1099 cp gridxc.mk.in gridxc.mk
1100 endif
1101 endif
1102-#
1103+
1104 module: setup_mk_file libGridXC.a
1105 mkdir -p $(MAIN_OBJDIR)/lib
1106 mkdir -p $(MAIN_OBJDIR)/include
1107@@ -129,17 +140,20 @@
1108 rm -f $(GRIDXC_PREFIX)/gridxc.mk
1109
1110 cp -p $(MAIN_OBJDIR)/include/* $(GRIDXC_PREFIX)/include
1111- cp -p $(MAIN_OBJDIR)/lib/libGridXC.a $(GRIDXC_PREFIX)/lib
1112+ cp -p $(MAIN_OBJDIR)/lib/libGridXC.a $(GRIDXC_PREFIX)/lib
1113 cp -p gridxc.mk $(GRIDXC_PREFIX)
1114-#
1115+
1116
1117 clean:
1118 rm -f *.o *.*d *.a gridxc.mk
1119 (cd MPI_instr ; $(MAKE) \
1120 "VPATH=$(VPATH)/MPI_instr" clean)
1121+
1122+
1123 #
1124 # DO NOT DELETE THIS LINE - used by make depend
1125 am05.o: precision.o sys.o
1126+array.o: precision.o sys.o
1127 atomxc.o: alloc.o debugxc.o ggaxc.o gridxc_config.o ldaxc.o mesh1d.o
1128 atomxc.o: precision.o radfft.o sys.o vdwxc.o xcmod.o
1129 bessph.o: precision.o sys.o
1130@@ -157,15 +171,16 @@
1131 ldaxc.o: precision.o sys.o
1132 m_io.o: sys.o
1133 mesh1d.o: interpolation.o precision.o
1134-mesh3d.o: alloc.o debugxc.o gridxc_config.o precision.o sorting.o sys.o
1135+mesh3d.o: alloc.o array.o debugxc.o gridxc_config.o precision.o sorting.o sys.o
1136 minvec.o: cellsubs.o precision.o sorting.o sys.o
1137-moreParallelSubs.o: alloc.o gridxc_config.o m_io.o precision.o sys.o
1138+moreParallelSubs.o: alloc.o array.o gridxc_config.o m_io.o precision.o sys.o
1139 radfft.o: alloc.o bessph.o m_fft_gpfa.o precision.o
1140 vdwxc.o: alloc.o debugxc.o ggaxc.o interpolation.o ldaxc.o mesh1d.o precision.o
1141 vdwxc.o: radfft.o sys.o vv_vdwxc.o
1142 vv_vdwxc.o: alloc.o debugxc.o interpolation.o mesh1d.o precision.o radfft.o
1143 vv_vdwxc.o: sys.o
1144 xcmod.o: precision.o sys.o vdwxc.o
1145+m_array.o: array.o
1146 m_atomxc.o: atomxc.o
1147 m_bessph.o: bessph.o
1148 m_cellxc.o: cellxc.o
1149
1150=== modified file 'src/mesh3d.F90'
1151--- src/mesh3d.F90 2016-05-09 12:15:45 +0000
1152+++ src/mesh3d.F90 2017-02-16 10:29:06 +0000
1153@@ -29,6 +29,8 @@
1154 ! use alloc, only: re_alloc ! Re-allocation routine
1155 ! use sys, only: die ! Termination routine
1156 ! use sorting, only: ordix ! Finds the sorting index of a vector
1157+! use m_array, only: array_copy ! Copies flattened arrays (instead of reshaping)
1158+! use m_array, only: array_add ! Adds flattened arrays (instead of reshaping)
1159 !
1160 ! USED module parameters:
1161 ! use precision, only: dp ! Real double precision type
1162@@ -648,6 +650,9 @@
1163 use debugXC, only: udebug ! Output file unit for debug info
1164 #endif /* DEBUG_XC */
1165
1166+ ! Copy and add for limiting temporary arrays
1167+ use m_array, only: array_copy, array_add
1168+
1169 ! Used MPI procedures and types
1170 #ifdef MPI
1171 use mpi_instr, only: MPI_AllGather
1172@@ -1624,17 +1629,10 @@
1173 integer,intent(in) :: box(2,3) ! My node's mesh box
1174 integer,intent(out):: boxes(2,3,0:totNodes-1) ! All node's boxes
1175
1176- integer,allocatable:: buffer(:)
1177- integer :: box1d(6) ! To avoid the creation of a temporary array
1178-
1179 #ifdef MPI
1180 ! Gather the boxes of all nodes
1181- allocate( buffer(6*totNodes) )
1182- box1d(1:6) = reshape(box,(/6/))
1183- call MPI_AllGather( box1d , 6, MPI_Integer, &
1184- buffer, 6, MPI_Integer, COMM, MPIerror )
1185- boxes = reshape( buffer, (/2,3,totNodes/) )
1186- deallocate( buffer )
1187+ call MPI_AllGather( box(1,1) , 6, MPI_Integer, &
1188+ boxes(1,1,0), 6, MPI_Integer, COMM, MPIerror )
1189 #else
1190 ! Copy the only node's box
1191 boxes(:,:,0) = box(:,:)
1192@@ -2018,7 +2016,7 @@
1193 integer:: orderNode1(nNodes), orderNode2(2*nNodes)
1194 logical:: found
1195 real(dp):: nTrsfNode(2*nNodes)
1196- integer,pointer:: buffer(:)=>null(), inTrsf(:,:)=>null(), &
1197+ integer, pointer:: inTrsf(:,:)=>null(), &
1198 myTrsf(:)=>null(), outTrsf(:,:)=>null()
1199
1200 ! In serial execution, do nothing
1201@@ -2047,11 +2045,8 @@
1202 myTrsf(1:nTrsf) = trsfDir(:)*(trsfNode(:)+1)
1203
1204 ! Gather initial transfer sequence of all nodes
1205- call re_alloc( buffer, 1,maxTrsf*nNodes, name=myName//'buffer' )
1206 call MPI_AllGather( myTrsf, maxTrsf, MPI_Integer, &
1207- buffer, maxTrsf, MPI_Integer, COMM, MPIerror )
1208- inTrsf = reshape( buffer, (/maxTrsf,nNodes/) )
1209- call de_alloc( buffer, name=myName//'buffer' )
1210+ inTrsf(1,1), maxTrsf, MPI_Integer, COMM, MPIerror )
1211
1212 ! Find the number of transfers of each node
1213 nTrsfNode(1:nNodes) = count( inTrsf(:,1:nNodes)/=0, dim=1 )
1214@@ -2399,7 +2394,7 @@
1215 character(len=*),parameter:: errHead = myName//'ERROR: '
1216 integer,allocatable:: dstBoxes(:,:,:), srcBoxes(:,:,:), &
1217 trsfDir(:), trsfNode(:)
1218- integer :: comBox(2,3), comShape(4), &
1219+ integer :: comBox(2,3), arrayS(4,2), &
1220 dstComBox(2,3,maxParts), dstNode, dstSize, &
1221 i, ic, ix, iNode, iPart, iTask, iTrsf, &
1222 maxMesh, nData, nParts, nTrsf, partSize, &
1223@@ -2573,7 +2568,7 @@
1224 if (present(prjData)) trsfSize = trsfSize + 3*maxMesh*maxParts
1225
1226 ! Allocate buffer to transfer data
1227- call re_alloc( trsfBuff, 1,trsfSize, name=myName//'trsfBuff' )
1228+ call re_alloc( trsfBuff, 1, trsfSize, name=myName//'trsfBuff' )
1229
1230 ! Loop on transfer sequence
1231 trueTrsf = 0
1232@@ -2624,12 +2619,18 @@
1233 ! Copy data from each part of common box to a transfer buffer
1234 if (present(dstData)) then
1235 do iPart = 1,nParts
1236- partSize = sizeSum(iPart) - sizeSum(iPart-1)
1237- trsfBuff(sizeSum(iPart-1)+1:sizeSum(iPart)) = &
1238- reshape( srcData(srcComBox(1,1,iPart):srcComBox(2,1,iPart), &
1239- srcComBox(1,2,iPart):srcComBox(2,2,iPart), &
1240- srcComBox(1,3,iPart):srcComBox(2,3,iPart),:), &
1241- (/partSize/) )
1242+ !partSize = sizeSum(iPart) - sizeSum(iPart-1)
1243+ arrayS(1:3,1) = srcComBox(1,:,iPart) + 1
1244+ arrayS(4,1) = 1
1245+ arrayS(1:3,2) = srcComBox(2,:,iPart) + 1
1246+ arrayS(4,2) = nData
1247+ call array_copy(arrayS(:,1), arrayS(:,2), srcData(:,:,:,:), &
1248+ sizeSum(iPart-1)+1, sizeSum(iPart), trsfBuff(:) )
1249+ !trsfBuff(sizeSum(iPart-1)+1:sizeSum(iPart)) = &
1250+ ! reshape( srcData(srcComBox(1,1,iPart):srcComBox(2,1,iPart), &
1251+ ! srcComBox(1,2,iPart):srcComBox(2,2,iPart), &
1252+ ! srcComBox(1,3,iPart):srcComBox(2,3,iPart),:), &
1253+ ! (/partSize/) )
1254 end do ! iPart
1255 trsfSize = sizeSum(nParts)
1256 else ! (.not.present(dstData))
1257@@ -2645,9 +2646,11 @@
1258 ! Find projection of srcData in comBox
1259 call projection( nMesh, srcBox, srcData(:,:,:,1), comBox, prjBuff )
1260 ! Copy projection data onto a transfer buffer
1261+ call array_copy([1, 1], [3, maxMesh], prjBuff(:,:), &
1262+ trsfSize+1, trsfSize+3*maxMesh, trsfBuff(:))
1263 ! AG: Work around gfortran bug: specify 0 lbound in reshape
1264- trsfBuff(trsfSize+1:trsfSize+3*maxMesh) = &
1265- reshape( prjBuff(:,0:), (/3*maxMesh/) )
1266+ !trsfBuff(trsfSize+1:trsfSize+3*maxMesh) = &
1267+ ! reshape( prjBuff(:,0:), (/3*maxMesh/) )
1268 trsfSize = trsfSize + 3*maxMesh
1269 end do ! iPart
1270 end if ! (present(prjData))
1271@@ -2721,15 +2724,21 @@
1272 ! Copy buffer data for each part of common box to destination array
1273 if (present(dstData)) then
1274 do iPart = 1,nParts
1275- comShape(1:3) = dstComBox(2,:,iPart) - dstComBox(1,:,iPart) + 1
1276- comShape(4) = nData
1277- dstData(dstComBox(1,1,iPart):dstComBox(2,1,iPart), &
1278- dstComBox(1,2,iPart):dstComBox(2,2,iPart), &
1279- dstComBox(1,3,iPart):dstComBox(2,3,iPart),:) = &
1280- dstData(dstComBox(1,1,iPart):dstComBox(2,1,iPart), &
1281- dstComBox(1,2,iPart):dstComBox(2,2,iPart), &
1282- dstComBox(1,3,iPart):dstComBox(2,3,iPart),:) + &
1283- reshape( trsfBuff(sizeSum(iPart-1)+1:sizeSum(iPart)), comShape )
1284+ arrayS(1:3,1) = dstComBox(1,:,iPart) + 1
1285+ arrayS(4,1) = 1
1286+ arrayS(1:3,2) = dstComBox(2,:,iPart) + 1
1287+ arrayS(4,2) = nData
1288+ call array_add(sizeSum(iPart-1)+1, sizeSum(iPart), trsfBuff(:), &
1289+ arrayS(:,1), arrayS(:,2), dstData(:,:,:,:))
1290+ !comShape(1:3) = dstComBox(2,:,iPart) - dstComBox(1,:,iPart) + 1
1291+ !comShape(4) = nData
1292+ !dstData(dstComBox(1,1,iPart):dstComBox(2,1,iPart), &
1293+ ! dstComBox(1,2,iPart):dstComBox(2,2,iPart), &
1294+ ! dstComBox(1,3,iPart):dstComBox(2,3,iPart),:) = &
1295+ !dstData(dstComBox(1,1,iPart):dstComBox(2,1,iPart), &
1296+ ! dstComBox(1,2,iPart):dstComBox(2,2,iPart), &
1297+ ! dstComBox(1,3,iPart):dstComBox(2,3,iPart),:) + &
1298+ ! reshape( trsfBuff(sizeSum(iPart-1)+1:sizeSum(iPart)), comShape )
1299 end do ! iPart
1300 trsfSize = sizeSum(nParts)
1301 else ! (.not.present(dstData))
1302@@ -2743,8 +2752,10 @@
1303 comBox(1,:) = srcComBox(1,:,iPart) + srcBox(1,:)
1304 comBox(2,:) = srcComBox(2,:,iPart) + srcBox(1,:)
1305 ! Copy transfer buffer onto a projection buffer
1306- prjBuff(:,:) = &
1307- reshape( trsfBuff(trsfSize+1:trsfSize+3*maxMesh), (/3,maxMesh/) )
1308+ call array_copy(trsfSize+1, trsfSize+3*maxMesh, trsfBuff(:), &
1309+ [1, 1], [3, maxMesh], prjBuff(:,:))
1310+ !prjBuff(:,:) = &
1311+ ! reshape( trsfBuff(trsfSize+1:trsfSize+3*maxMesh), (/3,maxMesh/) )
1312 ! Add projection of common box to output array
1313 do ix = 1,3
1314 prjData(ix,dstComBox(1,ix,iPart):dstComBox(2,ix,iPart)) = &
1315
1316=== modified file 'src/moreParallelSubs.F90'
1317--- src/moreParallelSubs.F90 2016-05-09 12:15:45 +0000
1318+++ src/moreParallelSubs.F90 2017-02-16 10:29:06 +0000
1319@@ -453,6 +453,7 @@
1320 a1, b1, c1, &
1321 a2, b2, &
1322 a3 )
1323+ use m_array, only: array_copy
1324 implicit none
1325 character(len=*),intent(in) :: op ! ('sum'|'prod'|'max'|'min')
1326 integer,optional,intent(inout) :: a0, b0, c0, d0, e0, f0
1327@@ -530,17 +531,23 @@
1328 end if
1329 if (present(a2)) then
1330 m = size(a2)
1331- sendBuff(n+1:n+m) = reshape( a2, (/m/) )
1332+ call array_copy(lbound(a2), ubound(a2), a2(:,:), &
1333+ n+1, n+m, sendBuff(:))
1334+ !sendBuff(n+1:n+m) = reshape( a2, (/m/) )
1335 n = n + m
1336 end if
1337 if (present(b2)) then
1338 m = size(b2)
1339- sendBuff(n+1:n+m) = reshape( b2, (/m/) )
1340+ call array_copy(lbound(b2), ubound(b2), b2(:,:), &
1341+ n+1, n+m, sendBuff(:))
1342+ !sendBuff(n+1:n+m) = reshape( b2, (/m/) )
1343 n = n + m
1344 end if
1345 if (present(a3)) then
1346 m = size(a3)
1347- sendBuff(n+1:n+m) = reshape( a3, (/m/) )
1348+ call array_copy(lbound(a3), ubound(a3), a3(:,:,:), &
1349+ n+1, n+m, sendBuff(:))
1350+ !sendBuff(n+1:n+m) = reshape( a3, (/m/) )
1351 n = n + m
1352 end if
1353
1354@@ -604,17 +611,23 @@
1355 end if
1356 if (present(a2)) then
1357 m = size(a2)
1358- a2 = reshape( recvBuff(n+1:n+m), shape(a2) )
1359+ call array_copy(n+1, n+m, recvBuff(:), &
1360+ lbound(a2), ubound(a2), a2(:,:))
1361+ !a2 = reshape( recvBuff(n+1:n+m), shape(a2) )
1362 n = n + m
1363 end if
1364 if (present(b2)) then
1365 m = size(b2)
1366- b2 = reshape( recvBuff(n+1:n+m), shape(b2) )
1367+ call array_copy(n+1, n+m, recvBuff(:), &
1368+ lbound(b2), ubound(b2), b2(:,:))
1369+ !b2 = reshape( recvBuff(n+1:n+m), shape(b2) )
1370 n = n + m
1371 end if
1372 if (present(a3)) then
1373 m = size(a3)
1374- a3 = reshape( recvBuff(n+1:n+m), shape(a3) )
1375+ call array_copy(n+1, n+m, recvBuff(:), &
1376+ lbound(a3), ubound(a3), a3(:,:,:))
1377+ !a3 = reshape( recvBuff(n+1:n+m), shape(a3) )
1378 n = n + m
1379 end if
1380
1381@@ -631,7 +644,7 @@
1382 a1, b1, c1, &
1383 a2, b2, &
1384 a3 )
1385-
1386+ use m_array, only: array_copy
1387 implicit none
1388 character(len=*),intent(in) :: op ! ('sum'|'prod'|'max'|'min')
1389 real(dp),optional,intent(inout) :: a0, b0, c0, d0, e0, f0
1390@@ -709,17 +722,23 @@
1391 end if
1392 if (present(a2)) then
1393 m = size(a2)
1394- sendBuff(n+1:n+m) = reshape( a2, (/m/) )
1395+ call array_copy(lbound(a2), ubound(a2), a2(:,:), &
1396+ n+1, n+m, sendBuff(:))
1397+ !sendBuff(n+1:n+m) = reshape( a2, (/m/) )
1398 n = n + m
1399 end if
1400 if (present(b2)) then
1401 m = size(b2)
1402- sendBuff(n+1:n+m) = reshape( b2, (/m/) )
1403+ call array_copy(lbound(b2), ubound(b2), b2(:,:), &
1404+ n+1, n+m, sendBuff(:))
1405+ !sendBuff(n+1:n+m) = reshape( b2, (/m/) )
1406 n = n + m
1407 end if
1408 if (present(a3)) then
1409 m = size(a3)
1410- sendBuff(n+1:n+m) = reshape( a3, (/m/) )
1411+ call array_copy(lbound(a3), ubound(a3), a3(:,:,:), &
1412+ n+1, n+m, sendBuff(:))
1413+ !sendBuff(n+1:n+m) = reshape( a3, (/m/) )
1414 n = n + m
1415 end if
1416
1417@@ -783,17 +802,23 @@
1418 end if
1419 if (present(a2)) then
1420 m = size(a2)
1421- a2 = reshape( recvBuff(n+1:n+m), shape(a2) )
1422+ call array_copy(n+1, n+m, recvBuff(:), &
1423+ lbound(a2), ubound(a2), a2(:,:))
1424+ !a2 = reshape( recvBuff(n+1:n+m), shape(a2) )
1425 n = n + m
1426 end if
1427 if (present(b2)) then
1428 m = size(b2)
1429- b2 = reshape( recvBuff(n+1:n+m), shape(b2) )
1430+ call array_copy(n+1, n+m, recvBuff(:), &
1431+ lbound(b2), ubound(b2), b2(:,:))
1432+ !b2 = reshape( recvBuff(n+1:n+m), shape(b2) )
1433 n = n + m
1434 end if
1435 if (present(a3)) then
1436 m = size(a3)
1437- a3 = reshape( recvBuff(n+1:n+m), shape(a3) )
1438+ call array_copy(n+1, n+m, recvBuff(:), &
1439+ lbound(a3), ubound(a3), a3(:,:,:))
1440+ !a3 = reshape( recvBuff(n+1:n+m), shape(a3) )
1441 n = n + m
1442 end if
1443
1444
1445=== modified file 'src/sorting.f'
1446--- src/sorting.f 2016-05-09 12:15:45 +0000
1447+++ src/sorting.f 2017-02-16 10:29:06 +0000
1448@@ -103,7 +103,7 @@
1449 integer, intent(in) :: m, n ! Dimensions of array x
1450 integer, intent(out):: indx(n) ! Increasing order of x(1,:)
1451
1452- integer:: child, child2, k, nFamily, parent
1453+ integer:: k, nFamily, parent
1454 real(dp):: ageTol
1455
1456 ! Construct the heap (family tree)
1457
1458=== modified file 'src/xcmod.F90'
1459--- src/xcmod.F90 2017-01-25 21:34:36 +0000
1460+++ src/xcmod.F90 2017-02-16 10:29:06 +0000
1461@@ -189,7 +189,7 @@
1462 character(len=*), intent(inout) :: auth
1463
1464 call die("Libxc not compiled in. Cannot handle " // &
1465- trim(XCfunc(i)) // " " // trim(XCauth(i)))
1466+ trim(func) // " " // trim(auth))
1467 end subroutine process_libxc_spec
1468
1469 #else
1470
1471=== modified file 'version.info'
1472--- version.info 2016-10-31 16:23:50 +0000
1473+++ version.info 2017-02-16 10:29:06 +0000
1474@@ -1,2 +1,2 @@
1475-libGridXC-devel-29
1476+libGridXC-devel-30--reshape-2
1477

Subscribers

People subscribed via source and target branches

to all changes: