51 SUBROUTINE ab_contract(abint, sab, sphi_a, sphi_b, ncoa, ncob, nsgfa, nsgfb)
53 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: abint
54 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: sab, sphi_a, sphi_b
55 INTEGER,
INTENT(IN) :: ncoa, ncob, nsgfa, nsgfb
57 CHARACTER(LEN=*),
PARAMETER :: routinen =
'ab_contract'
60 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: cpp
62 CALL timeset(routinen, handle)
64 cpassert(ncob <=
SIZE(sab, 2))
66 IF ((nsgfa*ncob*(ncoa + nsgfb)) <= (nsgfb*ncoa*(ncob + nsgfa)))
THEN
67 ALLOCATE (cpp(nsgfa, ncob))
69 CALL dgemm(
"T",
"N", nsgfa, ncob, ncoa, 1._dp, sphi_a,
SIZE(sphi_a, 1), sab,
SIZE(sab, 1), 0.0_dp, cpp, nsgfa)
71 CALL dgemm(
"N",
"N", nsgfa, nsgfb, ncob, 1._dp, cpp, nsgfa, sphi_b,
SIZE(sphi_b, 1), 0.0_dp, &
72 abint,
SIZE(abint, 1))
74 ALLOCATE (cpp(ncoa, nsgfb))
76 CALL dgemm(
"N",
"N", ncoa, nsgfb, ncob, 1._dp, sab,
SIZE(sab, 1), sphi_b,
SIZE(sphi_b, 1), 0.0_dp, cpp, ncoa)
78 CALL dgemm(
"T",
"N", nsgfa, nsgfb, ncoa, 1._dp, sphi_a,
SIZE(sphi_a, 1), cpp, ncoa, 0.0_dp, &
79 abint,
SIZE(abint, 1))
103 SUBROUTINE abc_contract(abcint, sabc, sphi_a, sphi_b, sphi_c, ncoa, ncob, ncoc, &
106 REAL(kind=
dp),
DIMENSION(:, :, :) :: abcint, sabc
107 REAL(kind=
dp),
DIMENSION(:, :) :: sphi_a, sphi_b, sphi_c
108 INTEGER,
INTENT(IN) :: ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc
110 CHARACTER(LEN=*),
PARAMETER :: routinen =
'abc_contract'
112 INTEGER :: handle, i, m1, m2, m3, msphia, msphib, &
114 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: tmp
116 CALL timeset(routinen, handle)
118 cpassert(
SIZE(abcint, 1) == nsgfa)
119 cpassert(
SIZE(abcint, 2) == nsgfb)
121 msphia =
SIZE(sphi_a, 1)
122 msphib =
SIZE(sphi_b, 1)
123 msphic =
SIZE(sphi_c, 1)
131 ALLOCATE (tmp(nsgfa, mx, m3 + 1))
133 CALL dgemm(
"T",
"N", nsgfa, m2*m3, ncoa, 1._dp, sphi_a, msphia, sabc, m1, 0.0_dp, tmp(:, :, 2), nsgfa)
135 CALL dgemm(
"N",
"N", nsgfa, nsgfb, ncob, 1._dp, tmp(:, :, i + 1), nsgfa, sphi_b, msphib, &
136 0.0_dp, tmp(:, :, i), nsgfa)
138 CALL dgemm(
"N",
"N", nsgfa*nsgfb, nsgfc, ncoc, 1._dp, tmp, nsgfa*mx, sphi_c, msphic, 0.0_dp, &
143 CALL timestop(handle)
165 SUBROUTINE abcd_contract(abcdint, sabcd, sphi_a, sphi_b, sphi_c, sphi_d, ncoa, ncob, &
166 ncoc, ncod, nsgfa, nsgfb, nsgfc, nsgfd)
168 REAL(kind=
dp),
DIMENSION(:, :, :, :), &
169 INTENT(INOUT) :: abcdint
170 REAL(kind=
dp),
DIMENSION(:, :, :, :),
INTENT(IN) :: sabcd
171 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: sphi_a, sphi_b, sphi_c, sphi_d
172 INTEGER,
INTENT(IN) :: ncoa, ncob, ncoc, ncod, nsgfa, nsgfb, &
175 CHARACTER(LEN=*),
PARAMETER :: routinen =
'abcd_contract'
177 INTEGER :: handle, isgfc, isgfd, m1, m2, m3, m4, &
178 msphia, msphib, msphic, msphid
179 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: temp_cccc, work_cpcc
180 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: temp_cpcc, work_cppc
181 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :, :) :: cpcc, cppc, cppp
183 CALL timeset(routinen, handle)
185 msphia =
SIZE(sphi_a, 1)
186 msphib =
SIZE(sphi_b, 1)
187 msphic =
SIZE(sphi_c, 1)
188 msphid =
SIZE(sphi_d, 1)
195 ALLOCATE (cppp(nsgfa, m2, m3, m4), cppc(nsgfa, m2, m3, nsgfd), &
196 cpcc(nsgfa, m2, nsgfc, nsgfd))
198 ALLOCATE (work_cppc(nsgfa, m2, m3), temp_cpcc(nsgfa, m2, nsgfc))
202 ALLOCATE (work_cpcc(nsgfa, m2), temp_cccc(nsgfa, nsgfb))
206 CALL dgemm(
"T",
"N", nsgfa, m2*m3*m4, ncoa, 1._dp, sphi_a, msphia, sabcd, m1, &
208 CALL dgemm(
"N",
"N", nsgfa*m2*m3, nsgfd, ncod, 1._dp, cppp, nsgfa*m2*m3, &
209 sphi_d, msphid, 0.0_dp, cppc, nsgfa*m2*m3)
212 work_cppc(:, :, :) = cppc(:, :, :, isgfd)
213 CALL dgemm(
"N",
"N", nsgfa*m2, nsgfc, ncoc, 1._dp, work_cppc, nsgfa*m2, &
214 sphi_c, msphic, 0.0_dp, temp_cpcc, nsgfa*m2)
215 cpcc(:, :, :, isgfd) = temp_cpcc(:, :, :)
217 work_cpcc(:, :) = cpcc(:, :, isgfc, isgfd)
218 CALL dgemm(
"N",
"N", nsgfa, nsgfb, ncob, 1._dp, work_cpcc, nsgfa, sphi_b, &
219 msphib, 0.0_dp, temp_cccc, nsgfa)
220 abcdint(:, :, isgfc, isgfd) = temp_cccc(:, :)
224 DEALLOCATE (cpcc, cppc, cppp)
225 DEALLOCATE (work_cpcc, work_cppc, temp_cpcc, temp_cccc)
227 CALL timestop(handle)
254 nsgfa, nsgfb, nsgfc, cpp_buffer, ccp_buffer, prefac, pstfac)
256 REAL(kind=
dp),
DIMENSION(:, :, :) :: abcint
257 REAL(kind=
dp),
DIMENSION(*),
INTENT(IN) :: sabc
258 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: sphi_a, sphi_b, sphi_c
259 INTEGER,
INTENT(IN) :: ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc
260 REAL(kind=
dp),
DIMENSION(:),
ALLOCATABLE :: cpp_buffer, ccp_buffer
261 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: prefac, pstfac
263 CHARACTER(LEN=*),
PARAMETER :: routinen =
'abc_contract_xsmm'
265 REAL(kind=
dp) :: alpha, beta
266 INTEGER(KIND=int_8) :: cpp_size, ccp_size
269#if defined(__LIBXSMM)
270 TYPE(libxsmm_dmmfunction) :: xmm1, xmm2
273 CALL timeset(routinen, handle)
276 IF (
PRESENT(prefac)) alpha = prefac
279 IF (
PRESENT(pstfac)) beta = pstfac
282 IF ((nsgfa*ncob*(ncoa + nsgfb)) <= (ncoa*nsgfb*(ncob + nsgfa)))
THEN
283 cpp_size = nsgfa*ncob
286 cpp_size = ncoa*nsgfb
290 ccp_size = nsgfa*nsgfb*ncoc
291 IF (.NOT.
ALLOCATED(ccp_buffer))
THEN
292 ALLOCATE (ccp_buffer(ccp_size))
293 ELSE IF (
SIZE(ccp_buffer) < ccp_size)
THEN
294 DEALLOCATE (ccp_buffer)
295 ALLOCATE (ccp_buffer(ccp_size))
298 IF (.NOT.
ALLOCATED(cpp_buffer))
THEN
299 ALLOCATE (cpp_buffer(cpp_size))
300 ELSE IF (
SIZE(cpp_buffer) < cpp_size)
THEN
301 DEALLOCATE (cpp_buffer)
302 ALLOCATE (cpp_buffer(cpp_size))
306#if defined(__LIBXSMM)
308 CALL libxsmm_dispatch(xmm1, nsgfa, ncob, ncoa, beta=0.0_dp, prefetch=libxsmm_prefetch_none)
309 CALL libxsmm_dispatch(xmm2, nsgfa, nsgfb, ncob, beta=0.0_dp, prefetch=libxsmm_prefetch_none)
311 CALL libxsmm_dispatch(xmm1, ncoa, nsgfb, ncob, beta=0.0_dp, prefetch=libxsmm_prefetch_none)
312 CALL libxsmm_dispatch(xmm2, nsgfa, nsgfb, ncoa, beta=0.0_dp, prefetch=libxsmm_prefetch_none)
315 IF (libxsmm_available(xmm1) .AND. libxsmm_available(xmm2))
THEN
319 CALL libxsmm_dmmcall(xmm1, sphi_a, sabc(i*ncoa*ncob + 1), cpp_buffer)
321 CALL libxsmm_dmmcall(xmm2, cpp_buffer, sphi_b, ccp_buffer(i*nsgfa*nsgfb + 1))
326 CALL libxsmm_dmmcall(xmm1, sabc(i*ncoa*ncob + 1), sphi_b, cpp_buffer)
328 CALL libxsmm_dmmcall(xmm2, sphi_a, cpp_buffer, ccp_buffer(i*nsgfa*nsgfb + 1))
335 CALL dgemm(
"N",
"N", nsgfa, ncob, ncoa, 1.0_dp, sphi_a, nsgfa, sabc(i*ncoa*ncob + 1), &
336 ncoa, 0.0_dp, cpp_buffer, nsgfa)
337 CALL dgemm(
"N",
"N", nsgfa, nsgfb, ncob, 1.0_dp, cpp_buffer, nsgfa, sphi_b, ncob, 0.0_dp, &
338 ccp_buffer(i*nsgfa*nsgfb + 1), nsgfa)
342 CALL dgemm(
"N",
"N", ncoa, nsgfb, ncob, 1.0_dp, sabc(i*ncoa*ncob + 1), ncoa, sphi_b, &
343 ncob, 0.0_dp, cpp_buffer, ncoa)
344 CALL dgemm(
"N",
"N", nsgfa, nsgfb, ncoa, 1.0_dp, sphi_a, nsgfa, cpp_buffer, ncoa, 0.0_dp, &
345 ccp_buffer(i*nsgfa*nsgfb + 1), nsgfa)
348#if defined(__LIBXSMM)
352 CALL dgemm(
"N",
"N", nsgfa*nsgfb, nsgfc, ncoc, alpha, ccp_buffer, nsgfa*nsgfb, &
353 sphi_c, ncoc, beta, abcint, nsgfa*nsgfb)
355 CALL timestop(handle)
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
subroutine, public abcd_contract(abcdint, sabcd, sphi_a, sphi_b, sphi_c, sphi_d, ncoa, ncob, ncoc, ncod, nsgfa, nsgfb, nsgfc, nsgfd)
contract four-center overlap integrals (a,b,c,d) and transfer to spherical Gaussians
subroutine, public abc_contract_xsmm(abcint, sabc, sphi_a, sphi_b, sphi_c, ncoa, ncob, ncoc, nsgfa, nsgfb, nsgfc, cpp_buffer, ccp_buffer, prefac, pstfac)
3-center contraction routine from primitive cartesian Gaussians to spherical Gaussian functions; can ...