gpu4pyscf 0.7.2__tar.gz → 0.7.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {gpu4pyscf-0.7.2/gpu4pyscf.egg-info → gpu4pyscf-0.7.4}/PKG-INFO +1 -1
  2. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/README.md +21 -2
  3. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/__init__.py +1 -1
  4. gpu4pyscf-0.7.4/gpu4pyscf/cc/__init__.py +1 -0
  5. gpu4pyscf-0.7.4/gpu4pyscf/cc/ccsd_incore.py +542 -0
  6. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/grad/uhf.py +5 -2
  7. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/grad/uks.py +13 -10
  8. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/uhf.py +1 -1
  9. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/grad/pcm.py +2 -1
  10. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/grad/smd.py +5 -4
  11. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/hessian/pcm.py +23 -9
  12. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/hessian/smd.py +24 -10
  13. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/pcm.py +4 -7
  14. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/smd.py +2 -2
  15. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4/gpu4pyscf.egg-info}/PKG-INFO +1 -1
  16. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf.egg-info/SOURCES.txt +2 -0
  17. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/LICENSE +0 -0
  18. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/MANIFEST.in +0 -0
  19. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/__config__.py +0 -0
  20. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/__init__.py +0 -0
  21. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/cderi.py +0 -0
  22. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/df.py +0 -0
  23. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/df_jk.py +0 -0
  24. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/grad/__init__.py +0 -0
  25. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/grad/rhf.py +0 -0
  26. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/grad/rks.py +0 -0
  27. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/hessian/__init__.py +0 -0
  28. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/hessian/rhf.py +0 -0
  29. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/hessian/rks.py +0 -0
  30. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/hessian/uhf.py +0 -0
  31. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/hessian/uks.py +0 -0
  32. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/int3c2e.py +0 -0
  33. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/df/patch_pyscf.py +0 -0
  34. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/__init__.py +0 -0
  35. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/gen_grid.py +0 -0
  36. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/gks.py +0 -0
  37. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/libxc.py +0 -0
  38. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/libxc_structs.py +0 -0
  39. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/numint.py +0 -0
  40. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/patch_pyscf.py +0 -0
  41. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/radi.py +0 -0
  42. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/rks.py +0 -0
  43. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/roks.py +0 -0
  44. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/uks.py +0 -0
  45. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/xc_alias.py +0 -0
  46. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/dft/xc_deriv.py +0 -0
  47. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/fci/__init__.py +0 -0
  48. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/fci/direct_spin1.py +0 -0
  49. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/__init__.py +0 -0
  50. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/dispersion.py +0 -0
  51. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/patch_pyscf.py +0 -0
  52. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/rhf.py +0 -0
  53. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/rks.py +0 -0
  54. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/uhf.py +0 -0
  55. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/grad/uks.py +0 -0
  56. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/gto/__init__.py +0 -0
  57. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/gto/mole.py +0 -0
  58. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/hessian/__init__.py +0 -0
  59. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/hessian/dispersion.py +0 -0
  60. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/hessian/rhf.py +0 -0
  61. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/hessian/rks.py +0 -0
  62. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/hessian/uhf.py +0 -0
  63. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/hessian/uks.py +0 -0
  64. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/__init__.py +0 -0
  65. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/cublas.py +0 -0
  66. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/cupy_helper.py +0 -0
  67. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/cusolver.py +0 -0
  68. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/cutensor.py +0 -0
  69. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/dftd3.py +0 -0
  70. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/dftd4.py +0 -0
  71. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/diis.py +0 -0
  72. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/logger.py +0 -0
  73. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/lib/utils.py +0 -0
  74. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/patch_pyscf.py +0 -0
  75. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/qmmm/__init__.py +0 -0
  76. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/qmmm/chelpg.py +0 -0
  77. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/__init__.py +0 -0
  78. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/cphf.py +0 -0
  79. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/diis.py +0 -0
  80. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/dispersion.py +0 -0
  81. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/ghf.py +0 -0
  82. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/hf.py +0 -0
  83. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/int4c2e.py +0 -0
  84. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/patch_pyscf.py +0 -0
  85. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/rohf.py +0 -0
  86. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/scf/ucphf.py +0 -0
  87. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/__init__.py +0 -0
  88. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/_attach_solvent.py +0 -0
  89. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/grad/__init__.py +0 -0
  90. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf/solvent/hessian/__init__.py +0 -0
  91. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf.egg-info/dependency_links.txt +0 -0
  92. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf.egg-info/requires.txt +0 -0
  93. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/gpu4pyscf.egg-info/top_level.txt +0 -0
  94. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/setup.cfg +0 -0
  95. {gpu4pyscf-0.7.2 → gpu4pyscf-0.7.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gpu4pyscf
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: GPU extensions for PySCF
5
5
  Home-page: UNKNOWN
6
6
  Author: Qiming Sun
@@ -51,6 +51,7 @@ Features
51
51
  - Nonlocal functional correction (vv10) for SCF and gradient;
52
52
  - ECP is supported and calculated on CPU;
53
53
  - PCM models, SMD model, their analytical gradients, and semi-analytical Hessian matrix;
54
+ - Unrestricted Hartree-Fock and Unrestricted DFT, gradient, and Hessian
54
55
 
55
56
  Limitations
56
57
  --------
@@ -87,7 +88,25 @@ h = mf.Hessian()
87
88
  h_dft = h.kernel() # compute analytical Hessian
88
89
 
89
90
  ```
90
- Find more examples in gpu4pyscf/examples
91
+
92
+ `to_gpu` is supported since PySCF 2.5.0
93
+ ```python
94
+ import pyscf
95
+ from pyscf.dft import rks
96
+
97
+ atom ='''
98
+ O 0.0000000000 -0.0000000000 0.1174000000
99
+ H -0.7570000000 -0.0000000000 -0.4696000000
100
+ H 0.7570000000 0.0000000000 -0.4696000000
101
+ '''
102
+
103
+ mol = pyscf.M(atom=atom, basis='def2-tzvpp')
104
+ mf = rks.RKS(mol, xc='LDA').density_fit().to_gpu() # move PySCF object to GPU4PySCF object
105
+ e_dft = mf.kernel() # compute total energy
106
+
107
+ ```
108
+
109
+ Find more examples in [gpu4pyscf/examples](https://github.com/pyscf/gpu4pyscf/tree/master/examples)
91
110
 
92
111
  Benchmarks
93
112
  --------
@@ -108,5 +127,5 @@ Speedup with GPU4PySCF v0.6.0 on A100-80G over Q-Chem 6.1 on 32-cores CPU (Desit
108
127
  | 095_Azadirachtin | 95 | 5.58 | 7.72 | 24.18 | 26.84 | 25.21 |
109
128
  | 113_Taxol | 113 | 5.44 | 6.81 | 24.58 | 29.14 | nan |
110
129
 
111
- Find more benchmarks in gpu4pyscf/benchmarks
130
+ Find more benchmarks in [gpu4pyscf/benchmarks](https://github.com/pyscf/gpu4pyscf/tree/master/benchmarks)
112
131
 
@@ -1,6 +1,6 @@
1
1
  from . import lib, grad, hessian, solvent, scf, dft
2
2
 
3
- __version__ = '0.7.2'
3
+ __version__ = '0.7.4'
4
4
 
5
5
  # monkey patch libxc reference due to a bug in nvcc
6
6
  from pyscf.dft import libxc
@@ -0,0 +1 @@
1
+ from .cc import ccsd_incore
@@ -0,0 +1,542 @@
1
+ # Copyright 2024 The GPU4PySCF Authors. All Rights Reserved.
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+
17
+ '''
18
+ Rewrite the pyscf/cc/ccsd.py using cupy, and GPU for ERIs.
19
+ This implementation requires that the GPU memory is large enough to hold at
20
+ least two t2 tensors.
21
+ '''
22
+
23
+ import time
24
+ import ctypes
25
+ import cupy
26
+ import numpy as np
27
+ from pyscf import gto
28
+ from pyscf import lib
29
+ from pyscf.ao2mo.outcore import balance_partition
30
+ from pyscf.ao2mo import _ao2mo
31
+ from pyscf.cc import ccsd
32
+ from pyscf.cc import _ccsd
33
+ from pyscf import __config__
34
+ from gpu4pyscf.scf import hf as gpu_hf
35
+ from gpu4pyscf.lib.cupy_helper import load_library
36
+ from gpu4pyscf.lib import logger
37
+
38
+ FREE_CUPY_CACHE = True
39
+
40
+ BLKMIN = getattr(__config__, 'cc_ccsd_blkmin', 4)
41
+ MEMORYMIN = getattr(__config__, 'cc_ccsd_memorymin', 2000)
42
+
43
+ libgint = load_library('libgint')
44
+ libgint.GINTfill_int2e.restype = ctypes.c_int
45
+
46
+ def update_amps(mycc, t1, t2, eris):
47
+ time0 = logger.process_clock(), logger.perf_counter()
48
+ log = logger.Logger(mycc.stdout, mycc.verbose)
49
+ nocc, nvir = t1.shape
50
+ fock = eris.fock
51
+ mo_e_o = eris.mo_energy[:nocc]
52
+ mo_e_v = eris.mo_energy[nocc:] + mycc.level_shift
53
+ orbo = eris.mo_coeff[:,:nocc]
54
+ orbv = eris.mo_coeff[:,nocc:]
55
+
56
+ wpq, t1new, t2new, wVOov, wVooV = _direct_ovvv_vvvv(mycc, t1, t2)
57
+ t2new *= .5 # *.5 because t2+t2.transpose(1,0,3,2) at the end
58
+
59
+ _einsum = cupy.einsum
60
+
61
+ fov = fock[:nocc,nocc:].copy()
62
+ t1new += fock[:nocc,nocc:]
63
+
64
+ foo = fock[:nocc,:nocc] - np.diag(mo_e_o)
65
+ foo += .5 * np.einsum('ia,ja->ij', fock[:nocc,nocc:], t1)
66
+
67
+ fvv = lib.einsum('pa,qp,qb->ab', orbv, wpq, orbv)
68
+ t1new -= lib.einsum('ab,ib->ia', fvv, t1)
69
+
70
+ fvv += fock[nocc:,nocc:] - np.diag(mo_e_v)
71
+ fvv -= .5 * np.einsum('ia,ib->ab', t1, fock[:nocc,nocc:])
72
+
73
+ foo += lib.einsum('pi,qp,qj->ij', orbo, wpq, orbo)
74
+ fov += lib.einsum('pi,qp,qa->ia', orbo, wpq, orbv)
75
+
76
+ t1, t1_cpu = cupy.asarray(t1), t1
77
+ t2, t2_cpu = cupy.asarray(t2), t2
78
+ tau = _einsum('ia,jb->ijab', t1, t1)
79
+ tau += t2
80
+ woooo = _einsum('ijab,kabl->ijkl', tau, eris.ovvo)
81
+ woooo += cupy.asarray(eris.oooo).transpose(0,2,1,3)
82
+ tmp = _einsum('la,jaik->lkji', t1, eris.ovoo)
83
+ woooo += tmp
84
+ woooo += tmp.transpose(1,0,3,2)
85
+ t2new += .5 * _einsum('ijkl,klab->ijab', woooo, tau).get()
86
+ woooo = tau = None
87
+
88
+ wVOov -= lib.einsum('jbik,ka->bjia', eris.ovoo, t1_cpu)
89
+ t2new += wVOov.transpose(1,2,0,3)
90
+
91
+ wVooV += lib.einsum('kbij,ka->bija', eris.ovoo, t1_cpu)
92
+ wVooV -= eris.oovv.transpose(2,0,1,3)
93
+ wVOov += wVooV*.5 #: bjia + bija*.5
94
+ wVOov += eris.ovvo.transpose(2,3,0,1)
95
+
96
+ t2new += (eris.ovvo*0.5).transpose(0,3,1,2)
97
+ t1new += lib.einsum('pi,pq,qa->ia', orbo, wpq, orbv)
98
+
99
+ tmp = lib.einsum('ic,kjbc->ikjb', t1_cpu, eris.oovv)
100
+ tmp += lib.einsum('jbck,ic->jkib', eris.ovvo, t1_cpu)
101
+ t2new -= lib.einsum('ka,jkib->jiba', t1_cpu, tmp)
102
+ tmp = None
103
+
104
+ tau = t2 * .5
105
+ tau += _einsum('ia,jb->ijab', t1, t1)
106
+ wVooV += _einsum('kbci,jkca->bija', eris.ovvo, tau).get()
107
+ tau = None
108
+
109
+ tmp = _einsum('jkca,ckib->jaib', t2, wVooV).get()
110
+ t2new += tmp.transpose(2,0,1,3)
111
+ tmp *= .5
112
+ t2new += tmp.transpose(0,2,1,3)
113
+ tmp = None
114
+
115
+ tau = np.einsum('ia,jb->iajb', t1_cpu*.5, t1_cpu)
116
+ tau += t2_cpu.transpose(0,2,1,3)
117
+ eris_ovOV = eris.ovvo.transpose(0,1,3,2) * 2
118
+ eris_ovOV -= eris.ovvo.transpose(3,1,0,2)
119
+ fvv -= lib.einsum('jcia,jcib->ab', tau, eris_ovOV)
120
+ foo += lib.einsum('iakb,jakb->ij', eris_ovOV, tau)
121
+
122
+ theta = t2.transpose(0,2,1,3) * 2
123
+ theta -= t2.transpose(1,2,0,3)
124
+ tau = theta * .25
125
+ tau -= _einsum('ia,jb->jaib', t1*.5, t1)
126
+ wVOov += _einsum('kcia,kcjb->aijb', eris_ovOV, tau).get()
127
+ eris_ovOV = tau = None
128
+
129
+ t2new += _einsum('kcia,ckjb->ijab', theta, wVOov).get()
130
+ theta = wVOov = wVooV = None
131
+
132
+ t1new += np.einsum('jb,ijab->ia', fov, t2_cpu) * 2
133
+ t1new -= np.einsum('jb,ijba->ia', fov, t2_cpu)
134
+ ovoo = eris.ovoo * 2
135
+ ovoo -= eris.ovoo.transpose(2,1,0,3)
136
+ t1new -= lib.einsum('jbki,jkba->ia', ovoo, t2_cpu)
137
+ ovoo = None
138
+
139
+ ft_ij = foo + np.einsum('ja,ia->ij', .5*t1_cpu, fov)
140
+ ft_ab = fvv - np.einsum('ia,ib->ab', .5*t1_cpu, fov)
141
+ t2new += lib.einsum('ijac,bc->ijab', t2_cpu, ft_ab)
142
+ t2new -= lib.einsum('ki,kjab->ijab', ft_ij, t2_cpu)
143
+
144
+ eia = mo_e_o[:,None] - mo_e_v
145
+ t1new += lib.einsum('ib,ab->ia', t1_cpu, fvv)
146
+ t1new -= lib.einsum('ja,ji->ia', t1_cpu, foo)
147
+ t1new /= eia
148
+
149
+ t2new = t2new + t2new.transpose(1,0,3,2)
150
+ t2new /= eia[:,None,:,None] + eia[:,None,:]
151
+
152
+ time0 = log.timer_debug1('update t1 t2', *time0)
153
+ return t1new, t2new
154
+
155
+ # Corresponds to the _add_vvvv_tril function in pyscf.cc.ccsd
156
+ def _direct_ovvv_vvvv(mycc, t1, t2):
157
+ nocc, nvir = t1.shape
158
+ nocc2 = nocc*(nocc+1)//2
159
+ nao_cart = mycc.mol.nao_nr(cart=True)
160
+ max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0])
161
+ blksize = ((max_memory*.9e6-t2.size*4*8)/8/nao_cart**2/3.5)**.5
162
+ Ht2_mem = nocc2*nao_cart**2 * 8 * 2 # x2 and Ht2
163
+ mem_avail = int(cupy.cuda.runtime.memGetInfo()[0] * .75)
164
+ if mem_avail * .9 < Ht2_mem:
165
+ raise RuntimeError(
166
+ f'Not enough GPU memory. Available {mem_avail*1e-6} MB, required {Ht2_mem/.9e-6} MB')
167
+ # Reserve some memory for ERIs?
168
+ cupy.get_default_memory_pool().set_limit(mem_avail)
169
+
170
+ blksize = max(BLKMIN, int(min((nao_cart+3)/4, blksize,
171
+ ((mem_avail-Ht2_mem)*.5/8/nao_cart**2)**.5)))
172
+ logger.debug1(mycc, 'blksize %d nao %d', blksize, nao_cart)
173
+
174
+ vhfopt = gpu_hf._VHFOpt(mycc.mol, 'int2e')
175
+ vhfopt.build(group_size=blksize, diag_block_with_triu=True)
176
+ mol = vhfopt.mol
177
+
178
+ _einsum = cupy.einsum
179
+
180
+ mo = vhfopt.coeff.dot(cupy.asarray(mycc.mo_coeff))
181
+ orbo = cupy.asarray(mo[:,:nocc])
182
+ orbv = cupy.asarray(mo[:,nocc:])
183
+ t1po = orbv.dot(cupy.asarray(t1).T)
184
+ tau = make_tau_tril(t1, t2)
185
+ x2 = _einsum('xab,pa->xpb', tau, orbv)
186
+ x2 = _einsum('xpb,qb->xpq', x2, orbv)
187
+ tau = None
188
+
189
+ nao, nmo = mo.shape
190
+ ao_loc = mol.ao_loc
191
+ nao2 = nao * nao
192
+
193
+ x2 = cupy.asarray(x2, order='C')
194
+ Ht2ao = cupy.zeros_like(x2)
195
+ _dgemm = cupy.cuda.cublas.dgemm
196
+ handle = cupy.cuda.device.get_cublas_handle()
197
+ N = cupy.cuda.cublas.CUBLAS_OP_N
198
+ T = cupy.cuda.cublas.CUBLAS_OP_T
199
+ one = np.ones(1)
200
+ one_ptr = one.ctypes.data
201
+ x2_ptr = x2.data.ptr
202
+ Ht2ao_ptr = Ht2ao.data.ptr
203
+ def contract_vvvv_(eri, i0, i1, j0, j1):
204
+ ic = i1 - i0
205
+ jc = j1 - j0
206
+ eri = eri.reshape(-1,jc*nao)
207
+ #:Ht2[:,j0:j1] += np.einsum('xef,efab->xab', x2[:,i0:i1], eri)
208
+ _dgemm(handle, N, N, jc*nao, nocc2, ic*nao,
209
+ one_ptr, eri.data.ptr, jc*nao, x2_ptr+i0*nao*8, nao2,
210
+ one_ptr, Ht2ao_ptr+j0*nao*8, nao2)
211
+
212
+ if i0 > j0:
213
+ #:Ht2[:,i0:i1] += np.einsum('xef,abef->xab', x2[:,j0:j1], eri)
214
+ _dgemm(handle, T, N, ic*nao, nocc2, jc*nao,
215
+ one_ptr, eri.data.ptr, jc*nao, x2_ptr+j0*nao*8, nao2,
216
+ one_ptr, Ht2ao_ptr+i0*nao*8, nao2)
217
+
218
+ l_ctr_offsets = vhfopt.l_ctr_offsets
219
+ log_qs = vhfopt.log_qs
220
+ cp_idx, cp_jdx = np.tril_indices(len(vhfopt.uniq_l_ctr))
221
+
222
+ if vhfopt.uniq_l_ctr[:,0].max() <= gpu_hf.LMAX_ON_GPU:
223
+ # Computing ERIs on GPU
224
+ idx, idy = cupy.tril_indices(nao)
225
+ #eribuf = cupy.empty(blksize**2*nao**2)
226
+ def fint(ish0, ish1, jsh0, jsh1, group_id):
227
+ i0, i1 = ao_loc[ish0], ao_loc[ish1]
228
+ j0, j1 = ao_loc[jsh0], ao_loc[jsh1]
229
+ #eri = cupy.ndarray((i1-i0, nao, j1-j0, nao), memptr=eribuf.data)
230
+ #eri.fill(0.)
231
+ eri = cupy.zeros([i1-i0,nao,j1-j0,nao])
232
+
233
+ # strides to ensure data order consistent with eri(k1-k0,nao,l1-l0,nao)
234
+ strides = [1, (j1-j0)*nao, (j1-j0)*nao**2, nao]
235
+ ao_offsets = [0, 0, i0, j0]
236
+ _fill_eri_block(eri, strides, ao_offsets, vhfopt, group_id)
237
+ # Fill lower triangular part
238
+ eri[:,idx,:,idy] = eri[:,idy,:,idx]
239
+ return eri
240
+ else:
241
+ intor = mol._add_suffix('int2e')
242
+ ao2mopt = _ao2mo.AO2MOpt(mol, intor, 'CVHFnr_schwarz_cond',
243
+ 'CVHFsetnr_direct_scf')
244
+ eribuf = np.empty((blksize,blksize,nao,nao))
245
+ loadbuf = np.empty((blksize,blksize,nao,nao))
246
+ def fint(ish0, ish1, jsh0, jsh1, group_id):
247
+ if ish0 != jsh0:
248
+ i0, i1 = ao_loc[ish0], ao_loc[ish1]
249
+ j0, j1 = ao_loc[jsh0], ao_loc[jsh1]
250
+ eri = gto.moleintor.getints4c(
251
+ intor, mol._atm, mol._bas, mol._env,
252
+ shls_slice=(ish0,ish1,jsh0,jsh1), aosym='s2kl',
253
+ ao_loc=ao_loc, cintopt=ao2mopt._cintopt, out=eribuf)
254
+ aoblk = np.ndarray((i1-i0,nao,j1-j0,nao), buffer=loadbuf)
255
+ _ccsd.libcc.CCload_eri(aoblk.ctypes.data_as(ctypes.c_void_p),
256
+ eri.ctypes.data_as(ctypes.c_void_p),
257
+ (ctypes.c_int*4)(i0, i1, j0, j1),
258
+ ctypes.c_int(nao))
259
+ else:
260
+ i0, i1 = ao_loc[ish0], ao_loc[ish1]
261
+ eri = gto.moleintor.getints4c(
262
+ intor, mol._atm, mol._bas, mol._env,
263
+ shls_slice=(ish0,ish1,ish0,ish1), aosym='s4',
264
+ ao_loc=ao_loc, cintopt=ao2mopt._cintopt, out=eribuf)
265
+ eri = lib.unpack_tril(eri, axis=0)
266
+ aoblk = np.ndarray((i1-i0,nao,i1-i0,nao), buffer=loadbuf)
267
+ _ccsd.libcc.CCload_eri(aoblk.ctypes.data_as(ctypes.c_void_p),
268
+ eri.ctypes.data_as(ctypes.c_void_p),
269
+ (ctypes.c_int*4)(i0, i1, i0, i1),
270
+ ctypes.c_int(nao))
271
+ return cupy.asarray(aoblk)
272
+
273
+ wVVoo = np.zeros((nao,nao,nocc,nocc))
274
+ wVvoO = np.zeros((nao,nao,nocc,nocc))
275
+
276
+ #mempool = cupy.get_default_memory_pool()
277
+ for cp_ij_id, log_q_ij in enumerate(log_qs):
278
+ cpi = cp_idx[cp_ij_id]
279
+ cpj = cp_jdx[cp_ij_id]
280
+ li = vhfopt.uniq_l_ctr[cpi,0]
281
+ lj = vhfopt.uniq_l_ctr[cpj,0]
282
+ if li > gpu_hf.LMAX_ON_GPU or lj > gpu_hf.LMAX_ON_GPU or log_q_ij.size == 0:
283
+ continue
284
+
285
+ ish0 = l_ctr_offsets[cpi]
286
+ jsh0 = l_ctr_offsets[cpj]
287
+ ish1 = l_ctr_offsets[cpi+1]
288
+ jsh1 = l_ctr_offsets[cpj+1]
289
+ aoblk = fint(ish0, ish1, jsh0, jsh1, cp_ij_id)
290
+
291
+ i0, i1 = ao_loc[ish0], ao_loc[ish1]
292
+ j0, j1 = ao_loc[jsh0], ao_loc[jsh1]
293
+ contract_vvvv_(aoblk, i0, i1, j0, j1)
294
+
295
+ #:fvv += 2*np.einsum('kc,kcab->ab', t1, eris_ovvv)
296
+ #:fvv -= np.einsum('kc,kbca->ab', t1, eris_ovvv)
297
+ pppo = _einsum('prqs,si->prqi', aoblk, orbo)
298
+ wVvoO[j0:j1] += _einsum('prqi,pj->qrij', pppo, t1po[i0:i1]).get()
299
+ wVVoo[i0:i1,j0:j1] = _einsum('prqi,rj->pqij', pppo, t1po).get()
300
+ pppo = None
301
+
302
+ if ish0 != jsh0:
303
+ wVVoo[j0:j1,i0:i1] = wVVoo[i0:i1,j0:j1].transpose(1,0,2,3)
304
+ #mempool.free_all_blocks()
305
+ wVvoO[i0:i1] += _einsum('prqs,ri,qj->psij',
306
+ aoblk, orbo, t1po[j0:j1]).get()
307
+ aoblk = None
308
+ eribuf = loadbuf = x2 = None
309
+
310
+ #:t1new += 2*lib.einsum('edac,ikcd->ikea', eris_ovvv, t2)
311
+ #:t1new += -lib.einsum('edac,ikdc->ikea', eris_ovvv, t2)
312
+ Ht2full = _unpack_t2_tril(Ht2ao, nocc, nao)
313
+ t1tmp = _einsum('ijpq,qj->ip', Ht2full, orbo) * 2
314
+ t1tmp -= _einsum('ijqp,qj->ip', Ht2full, orbo)
315
+ t1new = t1tmp.dot(orbv).get()
316
+
317
+ # vvvv-t2 contractions back to MO repr.
318
+ Ht2tril = _einsum('xpq,pa->xaq', Ht2ao, orbv)
319
+ Ht2tril = _einsum('xaq,qb->xab', Ht2tril, orbv)
320
+
321
+ # part of ovvv-t2 contractions back to MO repr.
322
+ #: tmp = np.einsum('ijcd,ka,kdcb->ijba', tau, t1, eris.ovvv)
323
+ #: t2new -= tmp + tmp.transpose(1,0,3,2)
324
+ t1pv = orbo.dot(cupy.asarray(t1))
325
+ tmp = _einsum('xpq,pa->xaq', Ht2ao, orbv)
326
+ Ht2tril -= _einsum('xaq,qb->xab', tmp, t1pv)
327
+
328
+ tmp = _einsum('xpq,pa->xaq', Ht2ao, t1pv)
329
+ Ht2tril -= _einsum('xaq,qb->xab', tmp, orbv)#_einsum('xpq,pa,qb->xab', Ht2ao, t1pv, orbv)
330
+
331
+ t2new = _unpack_t2_tril(Ht2tril, nocc, nvir).get()
332
+ Ht2ao = Ht2full = None
333
+
334
+ c = vhfopt.coeff.get()
335
+ wpq = 2 * lib.einsum('pqkk,pi,qj->ij', wVVoo, c, c)
336
+ wpq -= lib.einsum('pqkk,pi,qj->ji', wVvoO, c, c)
337
+
338
+ tmp = _einsum('pqji,qb->pbji', cupy.asarray(wVvoO), orbv)
339
+ wVOov = _einsum('pbji,pa->bjia', tmp, orbv).get()
340
+ #wVOov = _einsum('pqji,qb,pa->bjia', cupy.asarray(wVvoO), orbv, orbv).get()
341
+
342
+ tmp = _einsum('pqji,pa->aqji', cupy.asarray(wVVoo), -orbv)
343
+ wVooV = _einsum('aqji,qb->bjia', tmp, orbv).get()
344
+ #wVooV = _einsum('pqji,pa,qb->bjia', cupy.asarray(wVVoo),-orbv, orbv).get()
345
+ wVVoo = None
346
+
347
+ if FREE_CUPY_CACHE:
348
+ cupy.get_default_memory_pool().free_all_blocks()
349
+ return wpq, t1new, t2new, wVOov, wVooV
350
+
351
+ def make_tau_tril(t1, t2):
352
+ nocc, nvir = t1.shape
353
+ t1 = cupy.asarray(t1)
354
+ tau = cupy.einsum('ia,jb->ijab', t1, t1)
355
+ tau += cupy.asarray(t2)
356
+ return tau[cupy.tril_indices(nocc)]
357
+
358
+ def _unpack_t2_tril(t2tril, nocc, nvir):
359
+ t2 = cupy.empty((nocc,nocc,nvir,nvir))
360
+ idx,idy = cupy.tril_indices(nocc)
361
+ t2[idy,idx] = t2tril.transpose(0,2,1)
362
+ t2[idx,idy] = t2tril
363
+ return t2
364
+
365
+ def _fill_eri_block(eri, strides, ao_offsets, vhfopt, group_id):
366
+ log_qs = vhfopt.log_qs
367
+ cp_kl_id = group_id
368
+ log_q_kl = log_qs[cp_kl_id]
369
+ if log_q_kl.size == 0:
370
+ return eri
371
+
372
+ cp_idx, cp_jdx = np.tril_indices(len(vhfopt.uniq_l_ctr))
373
+ cpk = cp_idx[cp_kl_id]
374
+ cpl = cp_jdx[cp_kl_id]
375
+ lk = vhfopt.uniq_l_ctr[cpk,0]
376
+ ll = vhfopt.uniq_l_ctr[cpl,0]
377
+ if lk > gpu_hf.LMAX_ON_GPU or ll > gpu_hf.LMAX_ON_GPU:
378
+ raise NotImplementedError
379
+
380
+ stream = cupy.cuda.get_current_stream()
381
+ log_cutoff = np.log(vhfopt.direct_scf_tol)
382
+ omega = 0.
383
+
384
+ l_symb = lib.param.ANGULAR
385
+ nao = vhfopt.coeff.shape[0]
386
+ bins_locs_kl = vhfopt.bins[cp_kl_id]
387
+ bins_floor_kl = vhfopt.bins_floor[cp_kl_id]
388
+ nbins_kl = len(bins_locs_kl) - 1
389
+
390
+ fn = libgint.GINTfill_int2e
391
+ for cp_ij_id, log_q_ij in enumerate(log_qs):
392
+ cpi = cp_idx[cp_ij_id]
393
+ cpj = cp_jdx[cp_ij_id]
394
+ li = vhfopt.uniq_l_ctr[cpi,0]
395
+ lj = vhfopt.uniq_l_ctr[cpj,0]
396
+ if li > gpu_hf.LMAX_ON_GPU or lj > gpu_hf.LMAX_ON_GPU or log_q_ij.size == 0:
397
+ continue
398
+
399
+ t0 = time.perf_counter()
400
+ bins_locs_ij = vhfopt.bins[cp_ij_id]
401
+ bins_floor_ij = vhfopt.bins_floor[cp_ij_id]
402
+ nbins_ij = len(bins_locs_ij) - 1
403
+
404
+ err = fn(ctypes.cast(stream.ptr, ctypes.c_void_p), vhfopt.bpcache,
405
+ ctypes.cast(eri.data.ptr, ctypes.c_void_p), ctypes.c_int(nao),
406
+ (ctypes.c_int*4)(*strides), (ctypes.c_int*4)(*ao_offsets),
407
+ bins_locs_ij.ctypes.data_as(ctypes.c_void_p),
408
+ bins_locs_kl.ctypes.data_as(ctypes.c_void_p),
409
+ bins_floor_ij.ctypes.data_as(ctypes.c_void_p),
410
+ bins_floor_kl.ctypes.data_as(ctypes.c_void_p),
411
+ ctypes.c_int(nbins_ij), ctypes.c_int(nbins_kl),
412
+ ctypes.c_int(cp_ij_id), ctypes.c_int(cp_kl_id),
413
+ ctypes.c_double(log_cutoff),
414
+ ctypes.c_double(omega))
415
+ if err != 0:
416
+ detail = f'CUDA Error for ({l_symb[li]}{l_symb[lj]}|{l_symb[lk]}{l_symb[ll]})'
417
+ raise RuntimeError(detail)
418
+ logger.debug1(vhfopt.mol, '(%s%s|%s%s) on GPU %.3fs',
419
+ l_symb[li], l_symb[lj], l_symb[lk], l_symb[ll],
420
+ time.perf_counter() - t0)
421
+ return eri
422
+
423
+ def _make_eris_incore(mycc, mo_coeff=None):
424
+ cput0 = (logger.process_clock(), logger.perf_counter())
425
+ log = logger.Logger(mycc.stdout, mycc.verbose)
426
+ eris = ccsd._ChemistsERIs()
427
+ eris._common_init_(mycc, mo_coeff)
428
+
429
+ # Cupy memory buffer may be created in previous SCF calculations.
430
+ if FREE_CUPY_CACHE:
431
+ cupy.get_default_memory_pool().free_all_blocks()
432
+
433
+ mol = mycc.mol
434
+ mo_coeff = cupy.asarray(eris.mo_coeff, order='F')
435
+ nocc = eris.nocc
436
+ nmo = mo_coeff.shape[1]
437
+ nvir = nmo - nocc
438
+
439
+ nao_cart = mycc.mol.nao_nr(cart=True)
440
+ max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0])
441
+ blksize = ((max_memory*.9e6-nocc**2*nao_cart**2*2*8)/8/nao_cart**2/2.5)**.5
442
+ mem_avail = int(cupy.cuda.runtime.memGetInfo()[0] * .75)
443
+ cupy.get_default_memory_pool().set_limit(mem_avail)
444
+ blksize = max(BLKMIN, int(min((nao_cart+3)/4, blksize,
445
+ (mem_avail*.5/8/nao_cart**2)**.5)))
446
+ logger.debug1(mycc, 'blksize %d nao %d', blksize, nao_cart)
447
+
448
+ vhfopt = gpu_hf._VHFOpt(mycc.mol, 'int2e')
449
+ vhfopt.build(group_size=blksize, diag_block_with_triu=True)
450
+ mol = vhfopt.mol
451
+ mo = vhfopt.coeff.dot(mo_coeff)
452
+ orbo = cupy.asarray(mo[:,:nocc])
453
+ orbv = cupy.asarray(mo[:,nocc:])
454
+ ao_loc = mol.ao_loc
455
+ nao = mo.shape[0]
456
+
457
+ l_ctr_offsets = vhfopt.l_ctr_offsets
458
+ log_qs = vhfopt.log_qs
459
+ cp_idx, cp_jdx = np.tril_indices(len(vhfopt.uniq_l_ctr))
460
+
461
+ ppOO = np.empty((nao,nao,nocc,nocc))
462
+ pPoO = np.zeros((nao,nao,nocc,nocc))
463
+ eribuf = cupy.empty(blksize**2*nao**2)
464
+ #mempool = cupy.get_default_memory_pool()
465
+ idx, idy = cupy.tril_indices(nao)
466
+
467
+ for cp_ij_id, log_q_ij in enumerate(log_qs):
468
+ cpi = cp_idx[cp_ij_id]
469
+ cpj = cp_jdx[cp_ij_id]
470
+ li = vhfopt.uniq_l_ctr[cpi,0]
471
+ lj = vhfopt.uniq_l_ctr[cpj,0]
472
+ if li > gpu_hf.LMAX_ON_GPU or lj > gpu_hf.LMAX_ON_GPU or log_q_ij.size == 0:
473
+ continue
474
+
475
+ ish0 = l_ctr_offsets[cpi]
476
+ jsh0 = l_ctr_offsets[cpj]
477
+ ish1 = l_ctr_offsets[cpi+1]
478
+ jsh1 = l_ctr_offsets[cpj+1]
479
+ i0, i1 = ao_loc[ish0], ao_loc[ish1]
480
+ j0, j1 = ao_loc[jsh0], ao_loc[jsh1]
481
+ eri = cupy.ndarray((nao, i1-i0, j1-j0, nao), memptr=eribuf.data)
482
+ eri.fill(0.)
483
+ # strides to ensure data order consistent with eri(nao,k1-k0,l1-l0,nao)
484
+ strides = [1, (i1-i0)*(j1-j0)*nao, (j1-j0)*nao, nao]
485
+ ao_offsets = [0, 0, i0, j0]
486
+ _fill_eri_block(eri, strides, ao_offsets, vhfopt, cp_ij_id)
487
+ # Fill lower triangular part
488
+ eri[idx,:,:,idy] = eri[idy,:,:,idx]
489
+
490
+ pijo = cupy.dot(eri.reshape(-1,nao), orbo)
491
+ ijoo = cupy.dot(pijo.reshape(nao,-1).T, orbo)
492
+ ppOO[i0:i1,j0:j1] = ijoo.get().reshape(i1-i0,j1-j0,nocc,nocc)
493
+ ijoo = None
494
+
495
+ jopi = cupy.asarray(pijo.reshape(nao*(i1-i0),(j1-j0)*nocc).T, order='C')
496
+ jopo = cupy.dot(jopi.reshape(-1,i1-i0), orbo[i0:i1])
497
+ pPoO[j0:j1] += jopo.get().reshape(j1-j0,nocc,nao,nocc).transpose(0,2,1,3)
498
+ pijo = jopo = None
499
+
500
+ if ish0 != jsh0:
501
+ ppOO[j0:j1,i0:i1] = ppOO[i0:i1,j0:j1].transpose(1,0,2,3)
502
+ opio = cupy.dot(jopi.reshape(j1-j0,-1).T, orbo[j0:j1])
503
+ pPoO[i0:i1] += opio.get().reshape(nocc,nao,i1-i0,nocc).transpose(2,1,0,3)
504
+ jopi = opio = None
505
+
506
+ ppOO = cupy.asarray(ppOO)
507
+ pooo = cupy.dot(ppOO.reshape(nao,-1).T, orbo)
508
+ oooo = cupy.dot(pooo.reshape(nao,-1).T, orbo).reshape(nocc,nocc,nocc,nocc)
509
+ ooov = cupy.dot(pooo.reshape(nao,-1).T, orbv).reshape(nocc,nocc,nocc,nvir)
510
+ eris.oooo = oooo.get()
511
+ eris.ovoo = lib.transpose(ooov.get().reshape(nocc*nocc,nocc*nvir)).reshape(nocc,nvir,nocc,nocc)
512
+ pooo = oooo = ooov = None
513
+
514
+ poov = cupy.dot(ppOO.reshape(nao,-1).T, orbv)
515
+ oovv = cupy.dot(poov.reshape(nao,-1).T, orbv).reshape(nocc,nocc,nvir,nvir)
516
+ eris.oovv = oovv.get()
517
+ ppOO = poov = oovv = None
518
+
519
+ pPoO = cupy.asarray(pPoO)
520
+ poov = cupy.dot(pPoO.reshape(nao,-1).T, orbv)
521
+ voov = cupy.dot(orbv.T, poov.reshape(nao,-1))
522
+ eris.ovvo = lib.transpose(voov.get().reshape(nvir*nocc,nocc*nvir)).reshape(nocc,nvir,nvir,nocc)
523
+ eris.ovov = eris.ovvo.transpose(0,1,3,2)
524
+ pPoO = poov = voov = None
525
+ log.timer('CCSD integral transformation', *cput0)
526
+
527
+ if FREE_CUPY_CACHE:
528
+ cupy.get_default_memory_pool().free_all_blocks()
529
+ return eris
530
+
531
+ class CCSD(ccsd.CCSD):
532
+ from gpu4pyscf.lib.utils import to_cpu, to_gpu, device
533
+
534
+ def __init__(self, mf, *args, **kwargs):
535
+ if hasattr(mf, 'to_cpu'):
536
+ mf = mf.to_cpu()
537
+ if hasattr(mf, 'with_df') and mf.with_df:
538
+ lib.logger.warn(mf.mol, 'DF-CCSD not available. Run the standard CCSD.')
539
+ ccsd.CCSD.__init__(self, mf, *args, **kwargs)
540
+
541
+ update_amps = update_amps
542
+ ao2mo = _make_eris_incore
@@ -254,6 +254,9 @@ def get_jk(mf_grad, mol=None, dm0=None, hermi=0, with_j=True, with_k=True, omega
254
254
 
255
255
  class Gradients(uhf_grad.Gradients):
256
256
  '''Unrestricted density-fitting Hartree-Fock gradients'''
257
+
258
+ _keys = {'with_df', 'auxbasis_response'}
259
+
257
260
  def __init__(self, mf):
258
261
  # Whether to include the response of DF auxiliary basis when computing
259
262
  # nuclear gradients of J/K matrices
@@ -262,7 +265,7 @@ class Gradients(uhf_grad.Gradients):
262
265
  uhf_grad.Gradients.__init__(self, mf)
263
266
 
264
267
  get_jk = get_jk
265
-
268
+
266
269
  # TODO: finish these two functions
267
270
  def get_j(self, mol=None, dm=None, hermi=0, mo_coeff=None, mo_occ=None, dm2 = None):
268
271
  vj, _, vjaux, _ = self.get_jk(mol, dm, with_k=False, mo_coeff=mo_coeff, mo_occ=mo_occ, dm2=dm2)
@@ -271,7 +274,7 @@ class Gradients(uhf_grad.Gradients):
271
274
  def get_k(self, mol=None, dm=None, hermi=0, mo_coeff=None, mo_occ=None, dm2 = None):
272
275
  _, vk, _, vkaux = self.get_jk(mol, dm, with_j=False, mo_coeff=mo_coeff, mo_occ=mo_occ, dm2=dm2)
273
276
  return vk, vkaux
274
-
277
+
275
278
 
276
279
  def get_veff(self, mol=None, dm=None):
277
280
  vj0, vk0, vjaux0, vkaux0 = self.get_jk(mol, dm[0], mo_coeff=self.base.mo_coeff[0], mo_occ=self.base.mo_occ[0])
@@ -100,7 +100,7 @@ def get_veff(ks_grad, mol=None, dm=None):
100
100
  vxc += vj0 + vj1 + vj0_m1 + vj1_m0
101
101
  else:
102
102
  omega, alpha, hyb = ni.rsh_and_hybrid_coeff(mf.xc, spin=mol.spin)
103
-
103
+
104
104
  vj0, vk0, vjaux0, vkaux0 = ks_grad.get_jk(mol, dm[0], mo_coeff=ks_grad.base.mo_coeff[0], mo_occ=ks_grad.base.mo_occ[0])
105
105
  vj1, vk1, vjaux1, vkaux1 = ks_grad.get_jk(mol, dm[1], mo_coeff=ks_grad.base.mo_coeff[1], mo_occ=ks_grad.base.mo_occ[1])
106
106
  vj0_m1, vjaux0_m1 = ks_grad.get_j(mol, dm[0], mo_coeff=ks_grad.base.mo_coeff[0], mo_occ=ks_grad.base.mo_occ[0], dm2=dm[1])
@@ -110,29 +110,32 @@ def get_veff(ks_grad, mol=None, dm=None):
110
110
  if ks_grad.auxbasis_response:
111
111
  vj_aux = vjaux0 + vjaux1 + vjaux0_m1 + vjaux1_m0
112
112
  vk_aux = (vkaux0+vkaux1) * hyb
113
-
113
+
114
114
  if omega != 0:
115
115
  vk_lr0, vkaux_lr0 = ks_grad.get_k(mol, dm[0], mo_coeff=ks_grad.base.mo_coeff[0], mo_occ=ks_grad.base.mo_occ[0], omega=omega)
116
- vk_lr1, vkaux_lr1 = ks_grad.get_k(mol, dm[1], mo_coeff=ks_grad.base.mo_coeff[1], mo_occ=ks_grad.base.mo_occ[1], omega=omega)
116
+ vk_lr1, vkaux_lr1 = ks_grad.get_k(mol, dm[1], mo_coeff=ks_grad.base.mo_coeff[1], mo_occ=ks_grad.base.mo_occ[1], omega=omega)
117
117
  vk += (vk_lr0 + vk_lr1) * (alpha-hyb)
118
118
  if ks_grad.auxbasis_response:
119
119
  vk_aux += (vkaux_lr0 + vkaux_lr1) * (alpha-hyb)
120
-
120
+
121
121
  vxc += vj - vk
122
122
  if ks_grad.auxbasis_response:
123
123
  e1_aux = vj_aux - vk_aux
124
-
124
+
125
125
  if ks_grad.auxbasis_response:
126
126
  logger.debug1(ks_grad, 'sum(auxbasis response) %s', e1_aux.sum(axis=0))
127
127
  else:
128
- e1_aux = None
129
-
128
+ e1_aux = None
129
+
130
130
  vxc = tag_array(vxc, aux=e1_aux)
131
-
131
+
132
132
  return vxc
133
133
 
134
134
 
135
135
  class Gradients(uks_grad.Gradients):
136
+
137
+ _keys = {'with_df', 'auxbasis_response'}
138
+
136
139
  def __init__(self, mf):
137
140
  # Whether to include the response of DF auxiliary basis when computing
138
141
  # nuclear gradients of J/K matrices
@@ -140,7 +143,7 @@ class Gradients(uks_grad.Gradients):
140
143
  uks_grad.Gradients.__init__(self, mf)
141
144
 
142
145
  get_jk = get_jk
143
-
146
+
144
147
  def get_j(self, mol=None, dm=None, hermi=0, mo_coeff=None, mo_occ=None, dm2 = None, omega=None):
145
148
  vj, _, vjaux, _ = self.get_jk(mol, dm, with_k=False, mo_coeff=mo_coeff, mo_occ=mo_occ, dm2=dm2, omega=omega)
146
149
  return vj, vjaux
@@ -148,7 +151,7 @@ class Gradients(uks_grad.Gradients):
148
151
  def get_k(self, mol=None, dm=None, hermi=0, mo_coeff=None, mo_occ=None, dm2 = None, omega=None):
149
152
  _, vk, _, vkaux = self.get_jk(mol, dm, with_j=False, mo_coeff=mo_coeff, mo_occ=mo_occ, dm2=dm2, omega=omega)
150
153
  return vk, vkaux
151
-
154
+
152
155
  get_veff = get_veff
153
156
 
154
157
  def extra_force(self, atom_id, envs):
@@ -113,7 +113,7 @@ def get_fock(mf, h1e=None, s1e=None, vhf=None, dm=None, cycle=-1, diis=None,
113
113
  class UHF(uhf.UHF):
114
114
  from gpu4pyscf.lib.utils import to_cpu, to_gpu, device
115
115
 
116
- _keys = {'e_disp', 'screen_tol', 'conv_tol_cpscf'}
116
+ _keys = {'e_disp', 'screen_tol', 'conv_tol_cpscf', 'h1e', 's1e'}
117
117
 
118
118
  screen_tol = 1e-14
119
119
  conv_tol_cpscf = 1e-3
@@ -344,7 +344,8 @@ class WithSolventGrad:
344
344
  dm = kwargs.pop('dm', None)
345
345
  if dm is None:
346
346
  dm = self.base.make_rdm1(ao_repr=True)
347
-
347
+ if dm.ndim == 3:
348
+ dm = dm[0] + dm[1]
348
349
  self.de_solute = super().kernel(*args, **kwargs)
349
350
  self.de_solvent = grad_qv(self.base.with_solvent, dm)
350
351
  self.de_solvent+= grad_solver(self.base.with_solvent, dm)
@@ -255,14 +255,15 @@ class WithSolventGrad:
255
255
  dm = kwargs.pop('dm', None)
256
256
  if dm is None:
257
257
  dm = self.base.make_rdm1(ao_repr=True)
258
-
259
- self.de_solute = super().kernel(*args, **kwargs)
258
+ if dm.ndim == 3:
259
+ dm = dm[0] + dm[1]
260
+ self.de_solute = super().kernel(*args, **kwargs)
260
261
  self.de_solvent = pcm_grad.grad_qv(self.base.with_solvent, dm)
261
262
  self.de_solvent+= pcm_grad.grad_solver(self.base.with_solvent, dm)
262
263
  self.de_solvent+= pcm_grad.grad_nuc(self.base.with_solvent, dm)
264
+ self.de_cds = get_cds(self.base.with_solvent)
265
+ self.de = self.de_solute + self.de_solvent + self.de_cds
263
266
 
264
- self.de = self.de_solute + self.de_solvent
265
- self.de += get_cds(self.base.with_solvent)
266
267
  if self.verbose >= logger.NOTE:
267
268
  logger.note(self, '--------------- %s (+%s) gradients ---------------',
268
269
  self.base.__class__.__name__,
@@ -21,8 +21,7 @@ Gradient of PCM family solvent model
21
21
  import numpy
22
22
  import cupy
23
23
  from cupyx import scipy
24
- from pyscf import lib
25
- from pyscf import gto, df
24
+ from pyscf import lib, scf, gto, df
26
25
  from pyscf.grad import rhf as rhf_grad
27
26
  from gpu4pyscf.solvent.pcm import PI, switch_h
28
27
  from gpu4pyscf.solvent.grad.pcm import grad_switch_h, get_dF_dA, get_dD_dS, grad_qv, grad_solver, grad_nuc
@@ -155,7 +154,7 @@ def hess_elec(pcmobj, dm, verbose=None):
155
154
  pcmobj.reset(pmol)
156
155
  return de
157
156
 
158
- def fd_grad_vmat(pcmobj, mo_coeff, mo_occ, atmlst=None, verbose=None):
157
+ def fd_grad_vmat(pcmobj, dm, mo_coeff, mo_occ, atmlst=None, verbose=None):
159
158
  '''
160
159
  dv_solv / da
161
160
  slow version with finite difference
@@ -169,7 +168,6 @@ def fd_grad_vmat(pcmobj, mo_coeff, mo_occ, atmlst=None, verbose=None):
169
168
  nao, nmo = mo_coeff.shape
170
169
  mocc = mo_coeff[:,mo_occ>0]
171
170
  nocc = mocc.shape[1]
172
- dm = cupy.dot(mocc, mocc.T) * 2
173
171
  coords = mol.atom_coords(unit='Bohr')
174
172
  def pcm_vmat_scanner(mol):
175
173
  pcmobj.reset(mol)
@@ -250,6 +248,8 @@ class WithSolventHess:
250
248
  dm = kwargs.pop('dm', None)
251
249
  if dm is None:
252
250
  dm = self.base.make_rdm1(ao_repr=True)
251
+ if dm.ndim == 3:
252
+ dm = dm[0] + dm[1]
253
253
  is_equilibrium = self.base.with_solvent.equilibrium_solvation
254
254
  self.base.with_solvent.equilibrium_solvation = True
255
255
  self.de_solvent = hess_elec(self.base.with_solvent, dm, verbose=self.verbose)
@@ -263,11 +263,25 @@ class WithSolventHess:
263
263
  if atmlst is None:
264
264
  atmlst = range(self.mol.natm)
265
265
  h1ao = super().make_h1(mo_coeff, mo_occ, atmlst=atmlst, verbose=verbose)
266
- dv = fd_grad_vmat(self.base.with_solvent, mo_coeff, mo_occ, atmlst=atmlst, verbose=verbose)
267
- for i0, ia in enumerate(atmlst):
268
- h1ao[i0] += dv[i0]
269
- return h1ao
270
-
266
+ if isinstance(self.base, scf.hf.RHF):
267
+ dm = self.base.make_rdm1(ao_repr=True)
268
+ dv = fd_grad_vmat(self.base.with_solvent, dm, mo_coeff, mo_occ, atmlst=atmlst, verbose=verbose)
269
+ for i0, ia in enumerate(atmlst):
270
+ h1ao[i0] += dv[i0]
271
+ return h1ao
272
+ elif isinstance(self.base, scf.uhf.UHF):
273
+ h1aoa, h1aob = h1ao
274
+ solvent = self.base.with_solvent
275
+ dm = self.base.make_rdm1(ao_repr=True)
276
+ dm = dm[0] + dm[1]
277
+ dva = fd_grad_vmat(solvent, dm, mo_coeff[0], mo_occ[0], atmlst=atmlst, verbose=verbose)
278
+ dvb = fd_grad_vmat(solvent, dm, mo_coeff[1], mo_occ[1], atmlst=atmlst, verbose=verbose)
279
+ for i0, ia in enumerate(atmlst):
280
+ h1aoa[i0] += dva[i0]
281
+ h1aob[i0] += dvb[i0]
282
+ return h1aoa, h1aob
283
+ else:
284
+ raise NotImplementedError('Base object is not supported')
271
285
  def _finalize(self):
272
286
  # disable _finalize. It is called in grad_method.kernel method
273
287
  # where self.de was not yet initialized.
@@ -20,9 +20,7 @@ Gradient of PCM family solvent model
20
20
 
21
21
  import numpy as np
22
22
  import cupy
23
- #from cupyx import scipy, jit
24
- from pyscf import lib
25
- from pyscf import gto, df
23
+ from pyscf import gto, df, scf, lib
26
24
  from pyscf.grad import rhf as rhf_grad
27
25
  from pyscf.data import radii
28
26
  from pyscf.solvent import ddcosmo_grad
@@ -278,13 +276,15 @@ class WithSolventHess:
278
276
  dm = kwargs.pop('dm', None)
279
277
  if dm is None:
280
278
  dm = self.base.make_rdm1(ao_repr=True)
279
+ if dm.ndim == 3:
280
+ dm = dm[0] + dm[1]
281
281
  is_equilibrium = self.base.with_solvent.equilibrium_solvation
282
282
  self.base.with_solvent.equilibrium_solvation = True
283
283
  self.de_solvent = pcm_hess.hess_elec(self.base.with_solvent, dm, verbose=self.verbose)
284
284
  #self.de_solvent+= hess_nuc(self.base.with_solvent)
285
285
  self.de_solute = super().kernel(*args, **kwargs)
286
- self.de = self.de_solute + self.de_solvent
287
- self.de += get_cds(self.base.with_solvent)
286
+ self.de_cds = get_cds(self.base.with_solvent)
287
+ self.de = self.de_solute + self.de_solvent + self.de_cds
288
288
  self.base.with_solvent.equilibrium_solvation = is_equilibrium
289
289
  return self.de
290
290
 
@@ -292,11 +292,25 @@ class WithSolventHess:
292
292
  if atmlst is None:
293
293
  atmlst = range(self.mol.natm)
294
294
  h1ao = super().make_h1(mo_coeff, mo_occ, atmlst=atmlst, verbose=verbose)
295
- dv = pcm_hess.fd_grad_vmat(self.base.with_solvent, mo_coeff, mo_occ, atmlst=atmlst, verbose=verbose)
296
- for i0, ia in enumerate(atmlst):
297
- h1ao[i0] += dv[i0]
298
- return h1ao
299
-
295
+ if isinstance(self.base, scf.hf.RHF):
296
+ dm = self.base.make_rdm1(ao_repr=True)
297
+ dv = pcm_hess.fd_grad_vmat(self.base.with_solvent, dm, mo_coeff, mo_occ, atmlst=atmlst, verbose=verbose)
298
+ for i0, ia in enumerate(atmlst):
299
+ h1ao[i0] += dv[i0]
300
+ return h1ao
301
+ elif isinstance(self.base, scf.uhf.UHF):
302
+ h1aoa, h1aob = h1ao
303
+ solvent = self.base.with_solvent
304
+ dm = self.base.make_rdm1(ao_repr=True)
305
+ dm = dm[0] + dm[1]
306
+ dva = pcm_hess.fd_grad_vmat(solvent, dm, mo_coeff[0], mo_occ[0], atmlst=atmlst, verbose=verbose)
307
+ dvb = pcm_hess.fd_grad_vmat(solvent, dm, mo_coeff[1], mo_occ[1], atmlst=atmlst, verbose=verbose)
308
+ for i0, ia in enumerate(atmlst):
309
+ h1aoa[i0] += dva[i0]
310
+ h1aob[i0] += dvb[i0]
311
+ return h1aoa, h1aob
312
+ else:
313
+ raise NotImplementedError('Base object is not supported')
300
314
  def _finalize(self):
301
315
  # disable _finalize. It is called in grad_method.kernel method
302
316
  # where self.de was not yet initialized.
@@ -310,7 +310,6 @@ class PCM(ddcosmo.DDCOSMO):
310
310
  def _get_vind(self, dms):
311
311
  if not self._intermediates:
312
312
  self.build()
313
-
314
313
  nao = dms.shape[-1]
315
314
  dms = dms.reshape(-1,nao,nao)
316
315
  if dms.shape[0] == 2:
@@ -335,7 +334,6 @@ class PCM(ddcosmo.DDCOSMO):
335
334
  self._intermediates['q'] = q[0]
336
335
  self._intermediates['q_sym'] = q_sym[0]
337
336
  self._intermediates['v_grids'] = v_grids[0]
338
-
339
337
  return epcm, vmat[0]
340
338
 
341
339
  def _get_v(self, dms):
@@ -363,7 +361,7 @@ class PCM(ddcosmo.DDCOSMO):
363
361
  if self.frozen:
364
362
  raise RuntimeError('Frozen solvent model is not supported')
365
363
  from gpu4pyscf import scf
366
- if isinstance(grad_method.base, scf.hf.RHF):
364
+ if isinstance(grad_method.base, (scf.hf.RHF, scf.uhf.UHF)):
367
365
  return pcm_grad.make_grad_object(grad_method)
368
366
  else:
369
367
  raise RuntimeError('Only SCF gradient is supported')
@@ -373,7 +371,7 @@ class PCM(ddcosmo.DDCOSMO):
373
371
  if self.frozen:
374
372
  raise RuntimeError('Frozen solvent model is not supported')
375
373
  from gpu4pyscf import scf
376
- if isinstance(hess_method.base, scf.hf.RHF):
374
+ if isinstance(hess_method.base, (scf.hf.RHF, scf.uhf.UHF)):
377
375
  return pcm_hess.make_hess_object(hess_method)
378
376
  else:
379
377
  raise RuntimeError('Only SCF gradient is supported')
@@ -387,7 +385,7 @@ class PCM(ddcosmo.DDCOSMO):
387
385
  def _B_dot_x(self, dms):
388
386
  if not self._intermediates:
389
387
  self.build()
390
-
388
+ out_shape = dms.shape
391
389
  nao = dms.shape[-1]
392
390
  dms = dms.reshape(-1,nao,nao)
393
391
 
@@ -403,6 +401,5 @@ class PCM(ddcosmo.DDCOSMO):
403
401
  q_sym = (q + qt)/2.0
404
402
 
405
403
  vmat = self._get_vmat(q_sym)
406
-
407
- return vmat
404
+ return vmat.reshape(out_shape)
408
405
 
@@ -572,7 +572,7 @@ class SMD(pcm.PCM):
572
572
  if self.frozen:
573
573
  raise RuntimeError('Frozen solvent model is not supported')
574
574
  from gpu4pyscf import scf
575
- if isinstance(grad_method.base, scf.hf.RHF):
575
+ if isinstance(grad_method.base, (scf.hf.RHF, scf.uhf.UHF)):
576
576
  return smd_grad.make_grad_object(grad_method)
577
577
  else:
578
578
  raise RuntimeError('Only SCF gradient is supported')
@@ -582,7 +582,7 @@ class SMD(pcm.PCM):
582
582
  if self.frozen:
583
583
  raise RuntimeError('Frozen solvent model is not supported')
584
584
  from gpu4pyscf import scf
585
- if isinstance(hess_method.base, scf.hf.RHF):
585
+ if isinstance(hess_method.base, (scf.hf.RHF, scf.uhf.UHF)):
586
586
  return smd_hess.make_hess_object(hess_method)
587
587
  else:
588
588
  raise RuntimeError('Only SCF gradient is supported')
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gpu4pyscf
3
- Version: 0.7.2
3
+ Version: 0.7.4
4
4
  Summary: GPU extensions for PySCF
5
5
  Home-page: UNKNOWN
6
6
  Author: Qiming Sun
@@ -10,6 +10,8 @@ gpu4pyscf.egg-info/SOURCES.txt
10
10
  gpu4pyscf.egg-info/dependency_links.txt
11
11
  gpu4pyscf.egg-info/requires.txt
12
12
  gpu4pyscf.egg-info/top_level.txt
13
+ gpu4pyscf/cc/__init__.py
14
+ gpu4pyscf/cc/ccsd_incore.py
13
15
  gpu4pyscf/df/__init__.py
14
16
  gpu4pyscf/df/cderi.py
15
17
  gpu4pyscf/df/df.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes