def _make_eris_outcore(mycc, mo_coeff=None): cput0 = (logger.process_clock(), logger.perf_counter()) log = logger.Logger(mycc.stdout, mycc.verbose) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) mol = mycc.mol mo_coeff = eris.mo_coeff nocc = eris.nocc nao, nmo = mo_coeff.shape nvir = nmo - nocc eris.feri1 = lib.H5TmpFile() eris.oooo = eris.feri1.create_dataset('oooo', (nocc, nocc, nocc, nocc), 'f8') eris.ovoo = eris.feri1.create_dataset('ovoo', (nocc, nvir, nocc, nocc), 'f8', chunks=(nocc, 1, nocc, nocc)) eris.ovov = eris.feri1.create_dataset('ovov', (nocc, nvir, nocc, nvir), 'f8', chunks=(nocc, 1, nocc, nvir)) eris.ovvo = eris.feri1.create_dataset('ovvo', (nocc, nvir, nvir, nocc), 'f8', chunks=(nocc, 1, nvir, nocc)) eris.ovvv = eris.feri1.create_dataset('ovvv', (nocc, nvir, nvir, nvir), 'f8') eris.oovv = eris.feri1.create_dataset('oovv', (nocc, nocc, nvir, nvir), 'f8', chunks=(nocc, nocc, 1, nvir)) max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0]) ftmp = lib.H5TmpFile() ao2mo.full(mol, mo_coeff, ftmp, max_memory=max_memory, verbose=log) eri = ftmp['eri_mo'] nocc_pair = nocc * (nocc + 1) // 2 tril2sq = lib.square_mat_in_trilu_indices(nmo) oo = eri[:nocc_pair] eris.oooo[:] = ao2mo.restore(1, oo[:, :nocc_pair], nocc) oovv = lib.take_2d(oo, tril2sq[:nocc, :nocc].ravel(), tril2sq[nocc:, nocc:].ravel()) eris.oovv[:] = oovv.reshape(nocc, nocc, nvir, nvir) oo = oovv = None tril2sq = lib.square_mat_in_trilu_indices(nmo) blksize = min(nvir, max(BLKMIN, int(max_memory * 1e6 / 8 / nmo**3 / 2))) for p0, p1 in lib.prange(0, nvir, blksize): q0, q1 = p0 + nocc, p1 + nocc off0 = q0 * (q0 + 1) // 2 off1 = q1 * (q1 + 1) // 2 buf = lib.unpack_tril(eri[off0:off1]) tmp = buf[tril2sq[q0:q1, :nocc] - off0] eris.ovoo[:, p0:p1] = tmp[:, :, :nocc, :nocc].transpose(1, 0, 2, 3) eris.ovvo[:, p0:p1] = tmp[:, :, nocc:, :nocc].transpose(1, 0, 2, 3) eris.ovov[:, p0:p1] = tmp[:, :, :nocc, nocc:].transpose(1, 0, 2, 3) eris.ovvv[:, p0:p1] = tmp[:, :, nocc:, nocc:].transpose(1, 0, 2, 3) buf = tmp = None log.timer('GW integral transformation', *cput0) return eris
def test_add_vvVV(self): myucc = uccsd.UCCSD(mf_s2) nocca, noccb = 6,4 nmo = mf_s2.mo_occ[0].size nvira, nvirb = nmo-nocca, nmo-noccb numpy.random.seed(9) t1 = [numpy.zeros((nocca,nvira)), numpy.zeros((noccb,nvirb))] t2 = [numpy.random.random((nocca,nocca,nvira,nvira))-.9, numpy.random.random((nocca,noccb,nvira,nvirb))-.9, numpy.random.random((noccb,noccb,nvirb,nvirb))-.9] t2[0] = t2[0] - t2[0].transpose(1,0,2,3) t2[0] = t2[0] - t2[0].transpose(0,1,3,2) t2[2] = t2[2] - t2[2].transpose(1,0,2,3) t2[2] = t2[2] - t2[2].transpose(0,1,3,2) eris1 = copy.copy(eris) idxa = lib.square_mat_in_trilu_indices(nvira) idxb = lib.square_mat_in_trilu_indices(nvirb) vvVV = eris1.vvVV[:,idxb][idxa] ref = lib.einsum('acbd,ijcd->ijab', vvVV, t2[1]) t2a = myucc._add_vvVV((t1[0]*0,t1[1]*0), t2[1], eris) self.assertAlmostEqual(abs(ref-t2a).max(), 0, 12) myucc.direct = True eris1.vvvv = None # == with_ovvv=True in the call below eris1.VVVV = None eris1.vvVV = None t1 = None myucc.mo_coeff, eris1.mo_coeff = eris1.mo_coeff, None t2b = myucc._add_vvVV(t1, t2[1], eris1) self.assertAlmostEqual(abs(ref-t2b).max(), 0, 12)
def test_add_vvVV(self): myucc = uccsd.UCCSD(mf_s2) nocca, noccb = 6, 4 nmo = mf_s2.mo_occ[0].size nvira, nvirb = nmo - nocca, nmo - noccb numpy.random.seed(9) t1 = [numpy.zeros((nocca, nvira)), numpy.zeros((noccb, nvirb))] t2 = [ numpy.random.random((nocca, nocca, nvira, nvira)) - .9, numpy.random.random((nocca, noccb, nvira, nvirb)) - .9, numpy.random.random((noccb, noccb, nvirb, nvirb)) - .9 ] t2[0] = t2[0] - t2[0].transpose(1, 0, 2, 3) t2[0] = t2[0] - t2[0].transpose(0, 1, 3, 2) t2[2] = t2[2] - t2[2].transpose(1, 0, 2, 3) t2[2] = t2[2] - t2[2].transpose(0, 1, 3, 2) eris1 = copy.copy(eris) idxa = lib.square_mat_in_trilu_indices(nvira) idxb = lib.square_mat_in_trilu_indices(nvirb) vvVV = eris1.vvVV[:, idxb][idxa] ref = lib.einsum('acbd,ijcd->ijab', vvVV, t2[1]) t2a = myucc._add_vvVV((t1[0] * 0, t1[1] * 0), t2[1], eris) self.assertAlmostEqual(abs(ref - t2a).max(), 0, 12) myucc.direct = True eris1.vvvv = None # == with_ovvv=True in the call below eris1.VVVV = None eris1.vvVV = None t1 = None myucc.mo_coeff, eris1.mo_coeff = eris1.mo_coeff, None t2b = myucc._add_vvVV(t1, t2[1], eris1) self.assertAlmostEqual(abs(ref - t2b).max(), 0, 12)
def test_eris_contract_vvvv_t2(self): mol = gto.Mole() nocca, noccb, nvira, nvirb = 5, 4, 12, 13 nvira_pair = nvira*(nvira+1)//2 nvirb_pair = nvirb*(nvirb+1)//2 numpy.random.seed(9) t2 = numpy.random.random((nocca,noccb,nvira,nvirb)) eris = uccsd._ChemistsERIs() eris.vvVV = numpy.random.random((nvira_pair,nvirb_pair)) eris.mol = mol myucc.max_memory, bak = 0, myucc.max_memory vt2 = eris._contract_vvVV_t2(myucc, t2, eris.vvVV) myucc.max_memory = bak self.assertAlmostEqual(lib.finger(vt2), 12.00904827896089, 11) idxa = lib.square_mat_in_trilu_indices(nvira) idxb = lib.square_mat_in_trilu_indices(nvirb) vvVV = eris.vvVV[:,idxb][idxa] ref = lib.einsum('acbd,ijcd->ijab', vvVV, t2) self.assertAlmostEqual(abs(vt2 - ref).max(), 0, 11) # _contract_VVVV_t2, testing complex and real mixed contraction VVVV =(numpy.random.random((nvirb,nvirb,nvirb,nvirb)) + numpy.random.random((nvirb,nvirb,nvirb,nvirb))*1j - (.5+.5j)) VVVV = VVVV + VVVV.transpose(1,0,3,2).conj() VVVV = VVVV + VVVV.transpose(2,3,0,1) eris.VVVV = VVVV t2 = numpy.random.random((noccb,noccb,nvirb,nvirb)) t2 = t2 - t2.transpose(0,1,3,2) t2 = t2 - t2.transpose(1,0,3,2) myucc.max_memory, bak = 0, myucc.max_memory vt2 = eris._contract_VVVV_t2(myucc, t2, eris.VVVV) myucc.max_memory = bak self.assertAlmostEqual(lib.finger(vt2), 47.903883794299404-50.501573400833429j, 11) ref = lib.einsum('acbd,ijcd->ijab', eris.VVVV, t2) self.assertAlmostEqual(abs(vt2 - ref).max(), 0, 11)
def test_eris_contract_vvvv_t2(self): mol = gto.Mole() nocca, noccb, nvira, nvirb = 5, 4, 12, 13 nvira_pair = nvira*(nvira+1)//2 nvirb_pair = nvirb*(nvirb+1)//2 numpy.random.seed(9) t2 = numpy.random.random((nocca,noccb,nvira,nvirb)) eris = uccsd._ChemistsERIs() eris.vvVV = numpy.random.random((nvira_pair,nvirb_pair)) eris.mol = mol myucc.max_memory, bak = 0, myucc.max_memory vt2 = eris._contract_vvVV_t2(myucc, t2, eris.vvVV) myucc.max_memory = bak self.assertAlmostEqual(lib.finger(vt2), 12.00904827896089, 11) idxa = lib.square_mat_in_trilu_indices(nvira) idxb = lib.square_mat_in_trilu_indices(nvirb) vvVV = eris.vvVV[:,idxb][idxa] ref = lib.einsum('acbd,ijcd->ijab', vvVV, t2) self.assertAlmostEqual(abs(vt2 - ref).max(), 0, 11) # _contract_VVVV_t2, testing complex and real mixed contraction VVVV =(numpy.random.random((nvirb,nvirb,nvirb,nvirb)) + numpy.random.random((nvirb,nvirb,nvirb,nvirb))*1j - (.5+.5j)) VVVV = VVVV + VVVV.transpose(1,0,3,2).conj() VVVV = VVVV + VVVV.transpose(2,3,0,1) eris.VVVV = VVVV t2 = numpy.random.random((noccb,noccb,nvirb,nvirb)) t2 = t2 - t2.transpose(0,1,3,2) t2 = t2 - t2.transpose(1,0,3,2) myucc.max_memory, bak = 0, myucc.max_memory vt2 = eris._contract_VVVV_t2(myucc, t2, eris.VVVV) myucc.max_memory = bak self.assertAlmostEqual(lib.finger(vt2), 47.903883794299404-50.501573400833429j, 11) ref = lib.einsum('acbd,ijcd->ijab', eris.VVVV, t2) self.assertAlmostEqual(abs(vt2 - ref).max(), 0, 11)
def _make_eris_outcore(mycc, mo_coeff=None): cput0 = (time.clock(), time.time()) log = logger.Logger(mycc.stdout, mycc.verbose) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) mol = mycc.mol mo_coeff = eris.mo_coeff nocc = eris.nocc nao, nmo = mo_coeff.shape nvir = nmo - nocc orbo = mo_coeff[:,:nocc] orbv = mo_coeff[:,nocc:] nvpair = nvir * (nvir+1) // 2 eris.feri1 = lib.H5TmpFile() eris.oooo = eris.feri1.create_dataset('oooo', (nocc,nocc,nocc,nocc), 'f8') eris.ovoo = eris.feri1.create_dataset('ovoo', (nocc,nvir,nocc,nocc), 'f8', chunks=(nocc,1,nocc,nocc)) eris.ovov = eris.feri1.create_dataset('ovov', (nocc,nvir,nocc,nvir), 'f8', chunks=(nocc,1,nocc,nvir)) eris.ovvo = eris.feri1.create_dataset('ovvo', (nocc,nvir,nvir,nocc), 'f8', chunks=(nocc,1,nvir,nocc)) eris.ovvv = eris.feri1.create_dataset('ovvv', (nocc,nvir,nvir,nvir), 'f8') eris.oovv = eris.feri1.create_dataset('oovv', (nocc,nocc,nvir,nvir), 'f8', chunks=(nocc,nocc,1,nvir)) eris.vvvv = eris.feri1.create_dataset('vvvv', (nvir,nvir,nvir,nvir), 'f8') max_memory = max(MEMORYMIN, mycc.max_memory-lib.current_memory()[0]) ftmp = lib.H5TmpFile() ao2mo.full(mol, mo_coeff, ftmp, max_memory=max_memory, verbose=log) eri = ftmp['eri_mo'] nocc_pair = nocc*(nocc+1)//2 tril2sq = lib.square_mat_in_trilu_indices(nmo) oo = eri[:nocc_pair] eris.oooo[:] = ao2mo.restore(1, oo[:,:nocc_pair], nocc) oovv = lib.take_2d(oo, tril2sq[:nocc,:nocc].ravel(), tril2sq[nocc:,nocc:].ravel()) eris.oovv[:] = oovv.reshape(nocc,nocc,nvir,nvir) oo = oovv = None tril2sq = lib.square_mat_in_trilu_indices(nmo) blksize = min(nvir, max(BLKMIN, int(max_memory*1e6/8/nmo**3/2))) for p0, p1 in lib.prange(0, nvir, blksize): q0, q1 = p0+nocc, p1+nocc off0 = q0*(q0+1)//2 off1 = q1*(q1+1)//2 buf = lib.unpack_tril(eri[off0:off1]) tmp = buf[ tril2sq[q0:q1,:nocc] - off0 ] eris.ovoo[:,p0:p1] = tmp[:,:,:nocc,:nocc].transpose(1,0,2,3) eris.ovvo[:,p0:p1] = tmp[:,:,nocc:,:nocc].transpose(1,0,2,3) eris.ovov[:,p0:p1] = tmp[:,:,:nocc,nocc:].transpose(1,0,2,3) eris.ovvv[:,p0:p1] = tmp[:,:,nocc:,nocc:].transpose(1,0,2,3) tmp = buf[ tril2sq[q0:q1,nocc:q1] - off0 ] eris.vvvv[p0:p1,:p1] = tmp[:,:,nocc:,nocc:] if p0 > 0: eris.vvvv[:p0,p0:p1] = tmp[:,:p0,nocc:,nocc:].transpose(1,0,2,3) buf = tmp = None log.timer('CCSD integral transformation', *cput0) return eris
def _get_jk_2c_ints(mol, ia, ja): zi = mol.atom_charge(ia) zj = mol.atom_charge(ja) ri = mol.atom_coord(ia) #?*lib.param.BOHR rj = mol.atom_coord(ja) #?*lib.param.BOHR w = numpy.zeros((10, 10)) e1b = numpy.zeros(10) e2a = numpy.zeros(10) enuc = numpy.zeros(1) AM1_MODEL = 2 repp(zi, zj, ri, rj, w, e1b, e2a, enuc, MOPAC_ALP, MOPAC_DD, MOPAC_QQ, MOPAC_AM, MOPAC_AD, MOPAC_AQ, MOPAC_IDEA_FN1, MOPAC_IDEA_FN2, MOPAC_IDEA_FN3, AM1_MODEL) tril2sq = lib.square_mat_in_trilu_indices(4) w = w[:, tril2sq][tril2sq] e1b = e1b[tril2sq] e2a = e2a[tril2sq] if mopac_param.CORE[zj] <= 1: e2a = e2a[:1, :1] w = w[:, :, :1, :1] if mopac_param.CORE[zi] <= 1: e1b = e1b[:1, :1] w = w[:1, :1] # enuc from repp integrals is wrong due to the unit of MOPAC_IDEA_FN2 and # MOPAC_ALP return w, e1b, e2a, enuc[0]
def get_jk(agf2, eri, rdm1, with_j=True, with_k=True): ''' Get the J/K matrices. Args: eri : ndarray or H5 dataset Electronic repulsion integrals (NOT as _ChemistsERIs) rdm1 : 2D array Reduced density matrix Kwargs: with_j : bool Whether to compute J. Default value is True with_k : bool Whether to compute K. Default value is True Returns: tuple of ndarrays corresponding to J and K, if either are not requested then they are set to None. ''' if isinstance(eri, np.ndarray): vj, vk = _vhf.incore(eri, rdm1, with_j=with_j, with_k=with_k) else: nmo = rdm1.shape[0] npair = nmo * (nmo + 1) // 2 vj = vk = None if with_j: rdm1_tril = lib.pack_tril(rdm1 + np.tril(rdm1, k=-1)) vj = np.zeros_like(rdm1_tril) if with_k: vk = np.zeros_like(rdm1) blksize = _agf2.get_blksize(agf2.max_memory, (nmo * npair, nmo**3)) blksize = min(1, max(BLKMIN, blksize)) logger.debug1(agf2, 'blksize (ragf2.get_jk) = %d' % blksize) tril2sq = lib.square_mat_in_trilu_indices(nmo) for p0, p1 in lib.prange(0, nmo, blksize): idx = list(np.concatenate(tril2sq[p0:p1])) eri0 = eri[idx] # vj built in tril layout with scaled rdm1_tril if with_j: vj[idx] = np.dot(eri0, rdm1_tril) if with_k: eri0 = lib.unpack_tril(eri0, axis=-1) eri0 = eri0.reshape(p1 - p0, nmo, nmo, nmo) vk[p0:p1] = lib.einsum('ijkl,jk->il', eri0, rdm1) if with_j: vj = lib.unpack_tril(vj) return vj, vk
def _make_qmo_eris_outcore(agf2, eri, coeffs): ''' Returns H5 dataset ''' cput0 = (logger.process_clock(), logger.perf_counter()) log = logger.Logger(agf2.stdout, agf2.verbose) nmo = eri.nmo ci, cj, ca = coeffs ni = ci.shape[1] nj = cj.shape[1] na = ca.shape[1] npair = nmo * (nmo + 1) // 2 mask = get_frozen_mask(agf2) frozen = np.sum(~mask) # possible to have incore MO, outcore QMO if getattr(eri, 'feri', None) is None: eri.feri = lib.H5TmpFile() elif 'qmo' in eri.feri: del eri.feri['qmo'] eri.feri.create_dataset('qmo', (nmo - frozen, ni, nj, na), 'f8') blksize = _agf2.get_blksize(agf2.max_memory, (nmo * npair, nj * na, npair), (nmo * ni, nj * na)) blksize = min(nmo, max(BLKMIN, blksize)) log.debug1('blksize (ragf2._make_qmo_eris_outcore) = %d', blksize) tril2sq = lib.square_mat_in_trilu_indices(nmo) q1 = 0 for p0, p1 in lib.prange(0, nmo, blksize): if not np.any(mask[p0:p1]): # block is fully frozen continue inds = np.arange(p0, p1)[mask[p0:p1]] q0, q1 = q1, q1 + len(inds) idx = list(np.concatenate(tril2sq[inds])) buf = eri.eri[idx] # (blk, nmo, npair) buf = buf.reshape((q1 - q0) * nmo, -1) # (blk*nmo, npair) jasym, nja, cja, sja = ao2mo.incore._conc_mos(cj, ca, compact=True) buf = ao2mo._ao2mo.nr_e2(buf, cja, sja, 's2kl', 's1') buf = buf.reshape(q1 - q0, nmo, nj, na) buf = lib.einsum('xpja,pi->xija', buf, ci) eri.feri['qmo'][q0:q1] = np.asarray(buf, order='C') log.timer('QMO integral transformation', *cput0) return eri.feri['qmo']
def restore(symmetry, eri, norb, tao=None): r'''Convert the 2e integrals (in Chemist's notation) between different level of permutation symmetry (8-fold, 4-fold, or no symmetry) Args: symmetry : int or str code to present the target symmetry of 2e integrals | 's8' or '8' or 8 : 8-fold symmetry | 's4' or '4' or 4 : 4-fold symmetry | 's1' or '1' or 1 : no symmetry | 's2ij' or '2ij' : symmetric ij pair for (ij|kl) (TODO) | 's2ij' or '2kl' : symmetric kl pair for (ij|kl) (TODO) Note the 4-fold symmetry requires (ij|kl) == (ij|lk) == (ij|lk) while (ij|kl) != (kl|ij) is not required. eri : ndarray The symmetry of eri is determined by the size of eri and norb norb : int The symmetry of eri is determined by the size of eri and norb Returns: ndarray. The shape depends on the target symmetry. | 8 : (norb*(norb+1)/2)*(norb*(norb+1)/2+1)/2 | 4 : (norb*(norb+1)/2, norb*(norb+1)/2) | 1 : (norb, norb, norb, norb) Examples: >>> from pyscf import gto >>> from pyscf.scf import _vhf >>> from pyscf import ao2mo >>> mol = gto.M(atom='O 0 0 0; H 0 1 0; H 0 0 1', basis='sto3g') >>> eri = mol.intor('int2e') >>> eri1 = ao2mo.restore(1, eri, mol.nao_nr()) >>> eri4 = ao2mo.restore(4, eri, mol.nao_nr()) >>> eri8 = ao2mo.restore(8, eri, mol.nao_nr()) >>> print(eri1.shape) (7, 7, 7, 7) >>> print(eri1.shape) (28, 28) >>> print(eri1.shape) (406,) ''' targetsym = _stand_sym_code(symmetry) if targetsym not in ('8', '4', '1', '2kl', '2ij'): raise ValueError('symmetry = %s' % symmetry) if eri.dtype != numpy.double: raise RuntimeError('Complex integrals not supported') eri = numpy.asarray(eri, order='C') npair = norb*(norb+1)//2 if eri.size == norb**4: # s1 if targetsym == '1': return eri.reshape(norb,norb,norb,norb) elif targetsym == '2kl': eri = lib.pack_tril(eri.reshape(norb**2,norb,norb)) return eri.reshape(norb,norb,npair) elif targetsym == '2ij': eri = lib.pack_tril(eri.reshape(norb,norb,norb**2), axis=0) return eri.reshape(npair,norb,norb) else: return _convert('1', targetsym, eri, norb) elif eri.size == npair**2: # s4 if targetsym == '4': return eri.reshape(npair,npair) elif targetsym == '8': return lib.pack_tril(eri.reshape(npair,npair)) elif targetsym == '2kl': return lib.unpack_tril(eri, lib.SYMMETRIC, axis=0) elif targetsym == '2ij': return lib.unpack_tril(eri, lib.SYMMETRIC, axis=-1) else: return _convert('4', targetsym, eri, norb) elif eri.size == npair*(npair+1)//2: # 8-fold if targetsym == '8': return eri.ravel() elif targetsym == '4': return lib.unpack_tril(eri.ravel(), lib.SYMMETRIC) elif targetsym == '2kl': return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=0) elif targetsym == '2ij': return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=-1) else: return _convert('8', targetsym, eri, norb) elif eri.size == npair*norb**2 and eri.shape[0] == npair: # s2ij if targetsym == '2ij': return eri.reshape(npair,norb,norb) elif targetsym == '8': eri = lib.pack_tril(eri.reshape(npair,norb,norb)) return lib.pack_tril(eri) elif targetsym == '4': return lib.pack_tril(eri.reshape(npair,norb,norb)) elif targetsym == '1': eri = lib.unpack_tril(eri.reshape(npair,norb**2), lib.SYMMETRIC, axis=0) return eri.reshape(norb,norb,norb,norb) elif targetsym == '2kl': tril2sq = lib.square_mat_in_trilu_indices(norb) trilidx = numpy.tril_indices(norb) eri = lib.take_2d(eri.reshape(npair,norb**2), tril2sq.ravel(), trilidx[0]*norb+trilidx[1]) return eri.reshape(norb,norb,npair) elif eri.size == npair*norb**2 and eri.shape[-1] == npair: # s2kl if targetsym == '2kl': return eri.reshape(norb,norb,npair) elif targetsym == '8': eri = lib.pack_tril(eri.reshape(norb,norb,npair), axis=0) return lib.pack_tril(eri) elif targetsym == '4': return lib.pack_tril(eri.reshape(norb,norb,npair), axis=0) elif targetsym == '1': eri = lib.unpack_tril(eri.reshape(norb**2,npair), lib.SYMMETRIC, axis=-1) return eri.reshape(norb,norb,norb,norb) elif targetsym == '2ij': tril2sq = lib.square_mat_in_trilu_indices(norb) trilidx = numpy.tril_indices(norb) eri = lib.take_2d(eri.reshape(norb**2,npair), trilidx[0]*norb+trilidx[1], tril2sq.ravel()) return eri.reshape(npair,norb,norb) else: raise RuntimeError('eri.size = %d, norb = %d' % (eri.size, norb))
def _make_eris_outcore(mycc, mo_coeff=None): cput0 = (logger.process_clock(), logger.perf_counter()) log = logger.Logger(mycc.stdout, mycc.verbose) eris = _PhysicistsERIs() eris._common_init_(mycc, mo_coeff) nocc = eris.nocc nao, nmo = eris.mo_coeff.shape nvir = nmo - nocc assert(eris.mo_coeff.dtype == np.double) mo_a = eris.mo_coeff[:nao//2] mo_b = eris.mo_coeff[nao//2:] orbspin = eris.orbspin feri = eris.feri = lib.H5TmpFile() dtype = np.result_type(eris.mo_coeff).char eris.oooo = feri.create_dataset('oooo', (nocc,nocc,nocc,nocc), dtype) eris.ooov = feri.create_dataset('ooov', (nocc,nocc,nocc,nvir), dtype) eris.oovv = feri.create_dataset('oovv', (nocc,nocc,nvir,nvir), dtype) eris.ovov = feri.create_dataset('ovov', (nocc,nvir,nocc,nvir), dtype) eris.ovvo = feri.create_dataset('ovvo', (nocc,nvir,nvir,nocc), dtype) eris.ovvv = feri.create_dataset('ovvv', (nocc,nvir,nvir,nvir), dtype) if orbspin is None: orbo_a = mo_a[:,:nocc] orbv_a = mo_a[:,nocc:] orbo_b = mo_b[:,:nocc] orbv_b = mo_b[:,nocc:] max_memory = mycc.max_memory-lib.current_memory()[0] blksize = min(nocc, max(2, int(max_memory*1e6/8/(nmo**3*2)))) max_memory = max(MEMORYMIN, max_memory) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, (orbo_a,mo_a,mo_a,mo_a), fswap, 'aaaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbo_a,mo_a,mo_b,mo_b), fswap, 'aabb', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbo_b,mo_b,mo_a,mo_a), fswap, 'bbaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbo_b,mo_b,mo_b,mo_b), fswap, 'bbbb', max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nocc, blksize): tmp = np.asarray(fswap['aaaa'][p0*nmo:p1*nmo]) tmp += np.asarray(fswap['aabb'][p0*nmo:p1*nmo]) tmp += np.asarray(fswap['bbaa'][p0*nmo:p1*nmo]) tmp += np.asarray(fswap['bbbb'][p0*nmo:p1*nmo]) tmp = lib.unpack_tril(tmp).reshape(p1-p0,nmo,nmo,nmo) eris.oooo[p0:p1] = (tmp[:,:nocc,:nocc,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,:nocc,:nocc].transpose(0,2,3,1)) eris.ooov[p0:p1] = (tmp[:,:nocc,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,:nocc].transpose(0,2,3,1)) eris.ovvv[p0:p1] = (tmp[:,nocc:,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,nocc:].transpose(0,2,3,1)) eris.oovv[p0:p1] = (tmp[:,nocc:,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,nocc:].transpose(0,2,3,1)) eris.ovov[p0:p1] = (tmp[:,:nocc,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,:nocc].transpose(0,2,3,1)) eris.ovvo[p0:p1] = (tmp[:,nocc:,nocc:,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,nocc:,nocc:].transpose(0,2,3,1)) tmp = None cput0 = log.timer_debug1('transforming ovvv', *cput0) eris.vvvv = feri.create_dataset('vvvv', (nvir,nvir,nvir,nvir), dtype) tril2sq = lib.square_mat_in_trilu_indices(nvir) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, (orbv_a,orbv_a,orbv_a,orbv_a), fswap, 'aaaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbv_a,orbv_a,orbv_b,orbv_b), fswap, 'aabb', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbv_b,orbv_b,orbv_a,orbv_a), fswap, 'bbaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbv_b,orbv_b,orbv_b,orbv_b), fswap, 'bbbb', max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nvir, blksize): off0 = p0*(p0+1)//2 off1 = p1*(p1+1)//2 tmp = np.asarray(fswap['aaaa'][off0:off1]) tmp += np.asarray(fswap['aabb'][off0:off1]) tmp += np.asarray(fswap['bbaa'][off0:off1]) tmp += np.asarray(fswap['bbbb'][off0:off1]) if p0 > 0: c = tmp[ tril2sq[p0:p1,:p0] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p0,-1)) eris.vvvv[p0:p1,:p0] = c.reshape(p1-p0,p0,nvir,nvir) c = tmp[ tril2sq[:p1,p0:p1] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p1,-1)) eris.vvvv[:p1,p0:p1] = c.reshape(p1,p1-p0,nvir,nvir) tmp = None for p0, p1 in lib.prange(0, nvir, blksize): tmp = np.asarray(eris.vvvv[p0:p1]) eris.vvvv[p0:p1] = tmp.transpose(0,2,1,3) - tmp.transpose(0,2,3,1) cput0 = log.timer_debug1('transforming vvvv', *cput0) else: # with orbspin mo = mo_a + mo_b orbo = mo[:,:nocc] orbv = mo[:,nocc:] max_memory = mycc.max_memory-lib.current_memory()[0] blksize = min(nocc, max(2, int(max_memory*1e6/8/(nmo**3*2)))) max_memory = max(MEMORYMIN, max_memory) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, (orbo,mo,mo,mo), fswap, max_memory=max_memory, verbose=log) sym_forbid = orbspin[:,None] != orbspin for p0, p1 in lib.prange(0, nocc, blksize): tmp = np.asarray(fswap['eri_mo'][p0*nmo:p1*nmo]) tmp = lib.unpack_tril(tmp).reshape(p1-p0,nmo,nmo,nmo) tmp[sym_forbid[p0:p1]] = 0 tmp[:,:,sym_forbid] = 0 eris.oooo[p0:p1] = (tmp[:,:nocc,:nocc,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,:nocc,:nocc].transpose(0,2,3,1)) eris.ooov[p0:p1] = (tmp[:,:nocc,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,:nocc].transpose(0,2,3,1)) eris.ovvv[p0:p1] = (tmp[:,nocc:,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,nocc:].transpose(0,2,3,1)) eris.oovv[p0:p1] = (tmp[:,nocc:,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,nocc:].transpose(0,2,3,1)) eris.ovov[p0:p1] = (tmp[:,:nocc,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,:nocc].transpose(0,2,3,1)) eris.ovvo[p0:p1] = (tmp[:,nocc:,nocc:,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,nocc:,nocc:].transpose(0,2,3,1)) tmp = None cput0 = log.timer_debug1('transforming ovvv', *cput0) eris.vvvv = feri.create_dataset('vvvv', (nvir,nvir,nvir,nvir), dtype) sym_forbid = (orbspin[nocc:,None]!=orbspin[nocc:])[np.tril_indices(nvir)] tril2sq = lib.square_mat_in_trilu_indices(nvir) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, orbv, fswap, max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nvir, blksize): off0 = p0*(p0+1)//2 off1 = p1*(p1+1)//2 tmp = np.asarray(fswap['eri_mo'][off0:off1]) tmp[sym_forbid[off0:off1]] = 0 tmp[:,sym_forbid] = 0 if p0 > 0: c = tmp[ tril2sq[p0:p1,:p0] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p0,-1)) eris.vvvv[p0:p1,:p0] = c.reshape(p1-p0,p0,nvir,nvir) c = tmp[ tril2sq[:p1,p0:p1] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p1,-1)) eris.vvvv[:p1,p0:p1] = c.reshape(p1,p1-p0,nvir,nvir) tmp = None for p0, p1 in lib.prange(0, nvir, blksize): tmp = np.asarray(eris.vvvv[p0:p1]) eris.vvvv[p0:p1] = tmp.transpose(0,2,1,3) - tmp.transpose(0,2,3,1) cput0 = log.timer_debug1('transforming vvvv', *cput0) return eris
def _make_qmo_eris_outcore(agf2, eri, coeffs_a, coeffs_b, spin=None): ''' Returns nested tuple of H5 dataset spin = None: ((aaaa, aabb), (bbaa, bbbb)) spin = 0: (aaaa, aabb) spin = 1: (bbbb, bbaa) ''' cput0 = (time.clock(), time.time()) log = logger.Logger(agf2.stdout, agf2.verbose) nmo = eri.nmo nmoa, nmob = nmo cxa = np.eye(nmoa) cxb = np.eye(nmob) mask = get_frozen_mask(agf2) frozena = np.sum(~mask[0]) frozenb = np.sum(~mask[1]) npaira, npairb = nmoa*(nmoa+1)//2, nmob*(nmob+1)//2 cia, cja, caa = coeffs_a cib, cjb, cab = coeffs_b nia, nja, naa = [x.shape[1] for x in coeffs_a] nib, njb, nab = [x.shape[1] for x in coeffs_b] # possible to have incore MO, outcore QMO if getattr(eri, 'feri', None) is None: eri.feri = lib.H5TmpFile() else: for key in ['aa', 'ab', 'ba', 'bb']: if 'qmo/%s'%key in eri.feri: del eri.feri['qmo/%s'%key] if spin is None or spin == 0: eri.feri.create_dataset('qmo/aa', (nmoa-frozena, nia, nja, naa), 'f8') eri.feri.create_dataset('qmo/ab', (nmoa-frozena, nia, njb, nab), 'f8') blksize = _agf2.get_blksize(agf2.max_memory, (nmoa**3, nmoa*nja*naa), (nmoa*nmob**2, nmoa*njb*nab)) blksize = min(nmoa, max(BLKMIN, blksize)) log.debug1('blksize (uagf2._make_qmo_eris_outcore) = %d', blksize) tril2sq = lib.square_mat_in_trilu_indices(nmoa) q1 = 0 for p0, p1 in lib.prange(0, nmoa, blksize): if not np.any(mask[0][p0:p1]): # block is fully frozen continue inds = np.arange(p0, p1)[mask[0][p0:p1]] q0, q1 = q1, q1 + len(inds) idx = list(np.concatenate(tril2sq[inds])) # aa buf = eri.eri_aa[idx] # (blk, nmoa, npaira) buf = buf.reshape((q1-q0)*nmoa, -1) # (blk*nmoa, npaira) jasym_aa, nja_aa, cja_aa, sja_aa = ao2mo.incore._conc_mos(cja, caa) buf = ao2mo._ao2mo.nr_e2(buf, cja_aa, sja_aa, 's2kl', 's1') buf = buf.reshape(q1-q0, nmoa, nja, naa) buf = lib.einsum('xpja,pi->xija', buf, cia) eri.feri['qmo/aa'][q0:q1] = np.asarray(buf, order='C') # ab buf = eri.eri_ab[idx] # (blk, nmoa, npairb) buf = buf.reshape((q1-q0)*nmob, -1) # (blk*nmoa, npairb) jasym_ab, nja_ab, cja_ab, sja_ab = ao2mo.incore._conc_mos(cjb, cab) buf = ao2mo._ao2mo.nr_e2(buf, cja_ab, sja_ab, 's2kl', 's1') buf = buf.reshape(q1-q0, nmoa, njb, nab) buf = lib.einsum('xpja,pi->xija', buf, cia) eri.feri['qmo/ab'][q0:q1] = np.asarray(buf, order='C') if spin is None or spin == 1: eri.feri.create_dataset('qmo/ba', (nmob-frozenb, nib, nja, naa), 'f8') eri.feri.create_dataset('qmo/bb', (nmob-frozenb, nib, njb, nab), 'f8') max_memory = agf2.max_memory - lib.current_memory()[0] blksize = int((max_memory/8e-6) / max(nmob**3+nmob*njb*nab, nmob*nmoa**2*nja*naa)) blksize = min(nmob, max(BLKMIN, blksize)) log.debug1('blksize (uagf2._make_qmo_eris_outcore) = %d', blksize) tril2sq = lib.square_mat_in_trilu_indices(nmob) q1 = 0 for p0, p1 in lib.prange(0, nmob, blksize): if not np.any(mask[1][p0:p1]): # block is fully frozen continue inds = np.arange(p0, p1)[mask[1][p0:p1]] q0, q1 = q1, q1 + len(inds) idx = list(np.concatenate(tril2sq[inds])) # ba buf = eri.eri_ba[idx] # (blk, nmob, npaira) buf = buf.reshape((q1-q0)*nmob, -1) # (blk*nmob, npaira) jasym_ba, nja_ba, cja_ba, sja_ba = ao2mo.incore._conc_mos(cja, caa) buf = ao2mo._ao2mo.nr_e2(buf, cja_ba, sja_ba, 's2kl', 's1') buf = buf.reshape(q1-q0, nmob, nja, naa) buf = lib.einsum('xpja,pi->xija', buf, cib) eri.feri['qmo/ba'][q0:q1] = np.asarray(buf, order='C') # bb buf = eri.eri_bb[idx] # (blk, nmob, npairb) buf = buf.reshape((q1-q0)*nmob, -1) # (blk*nmob, npairb) jasym_bb, nja_bb, cja_bb, sja_bb = ao2mo.incore._conc_mos(cjb, cab) buf = ao2mo._ao2mo.nr_e2(buf, cja_bb, sja_bb, 's2kl', 's1') buf = buf.reshape(q1-q0, nmob, njb, nab) buf = lib.einsum('xpja,pi->xija', buf, cib) eri.feri['qmo/bb'][q0:q1] = np.asarray(buf, order='C') if spin is None: qeri = ((eri.feri['qmo/aa'], eri.feri['qmo/ab']), (eri.feri['qmo/ba'], eri.feri['qmo/bb'])) elif spin == 0: qeri = (eri.feri['qmo/aa'], eri.feri['qmo/ab']) elif spin == 1: qeri = (eri.feri['qmo/bb'], eri.feri['qmo/ba']) log.timer('QMO integral transformation', *cput0) return qeri
def _contract_vvvv_t2(mycc, mol, vvL, t2, out=None, verbose=None): '''Ht2 = numpy.einsum('ijcd,acdb->ijab', t2, vvvv) Args: vvvv : None or integral object if vvvv is None, contract t2 to AO-integrals using AO-direct algorithm ''' _dgemm = lib.numpy_helper._dgemm time0 = time.clock(), time.time() log = logger.new_logger(mol, verbose) naux = vvL.shape[-1] nvira, nvirb = t2.shape[-2:] x2 = t2.reshape(-1, nvira, nvirb) nocc2 = x2.shape[0] nvir2 = nvira * nvirb Ht2 = numpy.ndarray(x2.shape, buffer=out) Ht2[:] = 0 max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0]) def contract_blk_(eri, i0, i1, j0, j1): ic = i1 - i0 jc = j1 - j0 #:Ht2[:,j0:j1] += numpy.einsum('xef,efab->xab', x2[:,i0:i1], eri) _dgemm('N', 'N', nocc2, jc * nvirb, ic * nvirb, x2.reshape(-1, nvir2), eri.reshape(-1, jc * nvirb), Ht2.reshape(-1, nvir2), 1, 1, i0 * nvirb, 0, j0 * nvirb) if i0 > j0: #:Ht2[:,i0:i1] += numpy.einsum('xef,abef->xab', x2[:,j0:j1], eri) _dgemm('N', 'T', nocc2, ic * nvirb, jc * nvirb, x2.reshape(-1, nvir2), eri.reshape(-1, jc * nvirb), Ht2.reshape(-1, nvir2), 1, 1, j0 * nvirb, 0, i0 * nvirb) #TODO: check if vvL can be entirely loaded into memory nvir_pair = nvirb * (nvirb + 1) // 2 dmax = numpy.sqrt(max_memory * .7e6 / 8 / nvirb**2 / 2) dmax = int(min((nvira + 3) // 4, max(ccsd.BLKMIN, dmax))) vvblk = (max_memory * 1e6 / 8 - dmax**2 * (nvirb**2 * 1.5 + naux)) / naux vvblk = int(min((nvira + 3) // 4, max(ccsd.BLKMIN, vvblk / naux))) eribuf = numpy.empty((dmax, dmax, nvir_pair)) loadbuf = numpy.empty((dmax, dmax, nvirb, nvirb)) tril2sq = lib.square_mat_in_trilu_indices(nvira) for i0, i1 in lib.prange(0, nvira, dmax): off0 = i0 * (i0 + 1) // 2 off1 = i1 * (i1 + 1) // 2 vvL0 = _cp(vvL[off0:off1]) for j0, j1 in lib.prange(0, i1, dmax): ijL = vvL0[tril2sq[i0:i1, j0:j1] - off0].reshape(-1, naux) eri = numpy.ndarray(((i1 - i0) * (j1 - j0), nvir_pair), buffer=eribuf) for p0, p1 in lib.prange(0, nvir_pair, vvblk): vvL1 = _cp(vvL[p0:p1]) eri[:, p0:p1] = lib.ddot(ijL, vvL1.T) vvL1 = None tmp = numpy.ndarray((i1 - i0, nvirb, j1 - j0, nvirb), buffer=loadbuf) _ccsd.libcc.CCload_eri(tmp.ctypes.data_as(ctypes.c_void_p), eri.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(i0, i1, j0, j1), ctypes.c_int(nvirb)) contract_blk_(tmp, i0, i1, j0, j1) time0 = log.timer_debug1('vvvv [%d:%d,%d:%d]' % (i0, i1, j0, j1), *time0) return Ht2.reshape(t2.shape)
def _add_ovvv_(mycc, t1, t2, eris, fvv, t1new, t2new, fswap): time1 = logger.process_clock(), logger.perf_counter() log = logger.Logger(mycc.stdout, mycc.verbose) nocc, nvir = t1.shape nvir_pair = nvir * (nvir + 1) // 2 if fswap is None: wVOov = numpy.zeros((nvir, nocc, nocc, nvir)) else: wVOov = fswap.create_dataset('wVOov', (nvir, nocc, nocc, nvir), 'f8') wooVV = numpy.zeros((nocc, nocc * nvir_pair)) max_memory = mycc.max_memory - lib.current_memory()[0] unit = nocc * nvir**2 * 3 + nocc**2 * nvir + 2 blksize = min( nvir, max(BLKMIN, int((max_memory * .95e6 / 8 - wooVV.size) / unit))) if not mycc.direct: unit = nocc * nvir**2 * 3 + nocc**2 * nvir + 2 + nocc * nvir**2 + nocc * nvir blksize = min( nvir, max( BLKMIN, int((max_memory * .95e6 / 8 - wooVV.size - nocc**2 * nvir) / unit))) log.debug1('max_memory %d MB, nocc,nvir = %d,%d blksize = %d', max_memory, nocc, nvir, blksize) def load_ovvv(buf, p0): if p0 < nvir: p1 = min(nvir, p0 + blksize) buf[:p1 - p0] = eris.ovvv[:, p0:p1].transpose(1, 0, 2) with lib.call_in_background(load_ovvv, sync=not mycc.async_io) as prefetch: buf = numpy.empty((blksize, nocc, nvir_pair)) buf_prefetch = numpy.empty((blksize, nocc, nvir_pair)) load_ovvv(buf_prefetch, 0) for p0, p1 in lib.prange(0, nvir, blksize): buf, buf_prefetch = buf_prefetch, buf prefetch(buf_prefetch, p1) eris_vovv = buf[:p1 - p0] eris_vovv = lib.unpack_tril( eris_vovv.reshape((p1 - p0) * nocc, nvir_pair)) eris_vovv = eris_vovv.reshape(p1 - p0, nocc, nvir, nvir) wVOov[p0:p1] = lib.einsum('biac,jc->bija', eris_vovv, t1) theta = t2[:, :, p0:p1].transpose(1, 2, 0, 3) * 2 theta -= t2[:, :, p0:p1].transpose(0, 2, 1, 3) t1new += lib.einsum('icjb,cjba->ia', theta, eris_vovv) theta = None time1 = log.timer_debug1('vovv [%d:%d]' % (p0, p1), *time1) if fswap is None: wooVV = lib.unpack_tril(wooVV.reshape(nocc**2, nvir_pair)) return wVOov, wooVV.reshape(nocc, nocc, nvir, nvir).transpose(2, 1, 0, 3) else: fswap.create_dataset('wVooV', (nvir, nocc, nocc, nvir), 'f8') wooVV = wooVV.reshape(nocc, nocc, nvir_pair) tril2sq = lib.square_mat_in_trilu_indices(nvir) for p0, p1 in lib.prange(0, nvir, blksize): fswap['wVooV'][p0:p1] = wooVV[:, :, tril2sq[p0:p1]].transpose( 2, 1, 0, 3) return fswap['wVOov'], fswap['wVooV']
def _contract_vvvv_t2(mycc, mol, vvL, t2, out=None, verbose=None): '''Ht2 = numpy.einsum('ijcd,acdb->ijab', t2, vvvv) Args: vvvv : None or integral object if vvvv is None, contract t2 to AO-integrals using AO-direct algorithm ''' _dgemm = lib.numpy_helper._dgemm time0 = time.clock(), time.time() log = logger.new_logger(mol, verbose) naux = vvL.shape[-1] nvira, nvirb = t2.shape[-2:] x2 = t2.reshape(-1,nvira,nvirb) nocc2 = x2.shape[0] nvir2 = nvira * nvirb Ht2 = numpy.ndarray(x2.shape, buffer=out) Ht2[:] = 0 max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0]) def contract_blk_(eri, i0, i1, j0, j1): ic = i1 - i0 jc = j1 - j0 #:Ht2[:,j0:j1] += numpy.einsum('xef,efab->xab', x2[:,i0:i1], eri) _dgemm('N', 'N', nocc2, jc*nvirb, ic*nvirb, x2.reshape(-1,nvir2), eri.reshape(-1,jc*nvirb), Ht2.reshape(-1,nvir2), 1, 1, i0*nvirb, 0, j0*nvirb) if i0 > j0: #:Ht2[:,i0:i1] += numpy.einsum('xef,abef->xab', x2[:,j0:j1], eri) _dgemm('N', 'T', nocc2, ic*nvirb, jc*nvirb, x2.reshape(-1,nvir2), eri.reshape(-1,jc*nvirb), Ht2.reshape(-1,nvir2), 1, 1, j0*nvirb, 0, i0*nvirb) #TODO: check if vvL can be entirely loaded into memory nvir_pair = nvirb * (nvirb+1) // 2 dmax = numpy.sqrt(max_memory*.7e6/8/nvirb**2/2) dmax = int(min((nvira+3)//4, max(ccsd.BLKMIN, dmax))) vvblk = (max_memory*1e6/8 - dmax**2*(nvirb**2*1.5+naux))/naux vvblk = int(min((nvira+3)//4, max(ccsd.BLKMIN, vvblk/naux))) eribuf = numpy.empty((dmax,dmax,nvir_pair)) loadbuf = numpy.empty((dmax,dmax,nvirb,nvirb)) tril2sq = lib.square_mat_in_trilu_indices(nvira) for i0, i1 in lib.prange(0, nvira, dmax): off0 = i0*(i0+1)//2 off1 = i1*(i1+1)//2 vvL0 = _cp(vvL[off0:off1]) for j0, j1 in lib.prange(0, i1, dmax): ijL = vvL0[tril2sq[i0:i1,j0:j1] - off0].reshape(-1,naux) eri = numpy.ndarray(((i1-i0)*(j1-j0),nvir_pair), buffer=eribuf) for p0, p1 in lib.prange(0, nvir_pair, vvblk): vvL1 = _cp(vvL[p0:p1]) eri[:,p0:p1] = lib.ddot(ijL, vvL1.T) vvL1 = None tmp = numpy.ndarray((i1-i0,nvirb,j1-j0,nvirb), buffer=loadbuf) _ccsd.libcc.CCload_eri(tmp.ctypes.data_as(ctypes.c_void_p), eri.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(i0, i1, j0, j1), ctypes.c_int(nvirb)) contract_blk_(tmp, i0, i1, j0, j1) time0 = log.timer_debug1('vvvv [%d:%d,%d:%d]'%(i0,i1,j0,j1), *time0) return Ht2.reshape(t2.shape)
def restore(symmetry, eri, norb, tao=None): r'''Convert the 2e integrals (in Chemist's notation) between different level of permutation symmetry (8-fold, 4-fold, or no symmetry) Args: symmetry : int or str code to present the target symmetry of 2e integrals | 's8' or '8' or 8 : 8-fold symmetry | 's4' or '4' or 4 : 4-fold symmetry | 's1' or '1' or 1 : no symmetry | 's2ij' or '2ij' : symmetric ij pair for (ij|kl) (TODO) | 's2ij' or '2kl' : symmetric kl pair for (ij|kl) (TODO) Note the 4-fold symmetry requires (ij|kl) == (ij|lk) == (ij|lk) while (ij|kl) != (kl|ij) is not required. eri : ndarray The symmetry of eri is determined by the size of eri and norb norb : int The symmetry of eri is determined by the size of eri and norb Returns: ndarray. The shape depends on the target symmetry. | 8 : (norb*(norb+1)/2)*(norb*(norb+1)/2+1)/2 | 4 : (norb*(norb+1)/2, norb*(norb+1)/2) | 1 : (norb, norb, norb, norb) Examples: >>> from pyscf import gto >>> from pyscf.scf import _vhf >>> from pyscf import ao2mo >>> mol = gto.M(atom='O 0 0 0; H 0 1 0; H 0 0 1', basis='sto3g') >>> eri = mol.intor('int2e') >>> eri1 = ao2mo.restore(1, eri, mol.nao_nr()) >>> eri4 = ao2mo.restore(4, eri, mol.nao_nr()) >>> eri8 = ao2mo.restore(8, eri, mol.nao_nr()) >>> print(eri1.shape) (7, 7, 7, 7) >>> print(eri1.shape) (28, 28) >>> print(eri1.shape) (406,) ''' targetsym = _stand_sym_code(symmetry) if targetsym not in ('8', '4', '1', '2kl', '2ij'): raise ValueError('symmetry = %s' % symmetry) if eri.dtype != numpy.double: raise RuntimeError('Complex integrals not supported') eri = numpy.asarray(eri, order='C') npair = norb * (norb + 1) // 2 if eri.size == norb**4: # s1 if targetsym == '1': return eri.reshape(norb, norb, norb, norb) elif targetsym == '2kl': eri = lib.pack_tril(eri.reshape(norb**2, norb, norb)) return eri.reshape(norb, norb, npair) elif targetsym == '2ij': eri = lib.pack_tril(eri.reshape(norb, norb, norb**2), axis=0) return eri.reshape(npair, norb, norb) else: return _convert('1', targetsym, eri, norb) elif eri.size == npair**2: # s4 if targetsym == '4': return eri.reshape(npair, npair) elif targetsym == '8': return lib.pack_tril(eri.reshape(npair, npair)) elif targetsym == '2kl': return lib.unpack_tril(eri, lib.SYMMETRIC, axis=0) elif targetsym == '2ij': return lib.unpack_tril(eri, lib.SYMMETRIC, axis=-1) else: return _convert('4', targetsym, eri, norb) elif eri.size == npair * (npair + 1) // 2: # 8-fold if targetsym == '8': return eri.ravel() elif targetsym == '4': return lib.unpack_tril(eri.ravel(), lib.SYMMETRIC) elif targetsym == '2kl': return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=0) elif targetsym == '2ij': return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=-1) else: return _convert('8', targetsym, eri, norb) elif eri.size == npair * norb**2 and eri.shape[0] == npair: # s2ij if targetsym == '2ij': return eri.reshape(npair, norb, norb) elif targetsym == '8': eri = lib.pack_tril(eri.reshape(npair, norb, norb)) return lib.pack_tril(eri) elif targetsym == '4': return lib.pack_tril(eri.reshape(npair, norb, norb)) elif targetsym == '1': eri = lib.unpack_tril(eri.reshape(npair, norb**2), lib.SYMMETRIC, axis=0) return eri.reshape(norb, norb, norb, norb) elif targetsym == '2kl': tril2sq = lib.square_mat_in_trilu_indices(norb) trilidx = numpy.tril_indices(norb) eri = lib.take_2d(eri.reshape(npair, norb**2), tril2sq.ravel(), trilidx[0] * norb + trilidx[1]) return eri.reshape(norb, norb, npair) elif eri.size == npair * norb**2 and eri.shape[-1] == npair: # s2kl if targetsym == '2kl': return eri.reshape(norb, norb, npair) elif targetsym == '8': eri = lib.pack_tril(eri.reshape(norb, norb, npair), axis=0) return lib.pack_tril(eri) elif targetsym == '4': return lib.pack_tril(eri.reshape(norb, norb, npair), axis=0) elif targetsym == '1': eri = lib.unpack_tril(eri.reshape(norb**2, npair), lib.SYMMETRIC, axis=-1) return eri.reshape(norb, norb, norb, norb) elif targetsym == '2ij': tril2sq = lib.square_mat_in_trilu_indices(norb) trilidx = numpy.tril_indices(norb) eri = lib.take_2d(eri.reshape(norb**2, npair), trilidx[0] * norb + trilidx[1], tril2sq.ravel()) return eri.reshape(npair, norb, norb) else: raise RuntimeError('eri.size = %d, norb = %d' % (eri.size, norb))
def _make_eris_outcore(mycc, mo_coeff=None): cput0 = (time.clock(), time.time()) log = logger.Logger(mycc.stdout, mycc.verbose) eris = _PhysicistsERIs() eris._common_init_(mycc, mo_coeff) nocc = eris.nocc nao, nmo = eris.mo_coeff.shape nvir = nmo - nocc assert(eris.mo_coeff.dtype == np.double) mo_a = eris.mo_coeff[:nao//2] mo_b = eris.mo_coeff[nao//2:] orbspin = eris.orbspin feri = eris.feri = lib.H5TmpFile() dtype = np.result_type(eris.mo_coeff).char eris.oooo = feri.create_dataset('oooo', (nocc,nocc,nocc,nocc), dtype) eris.ooov = feri.create_dataset('ooov', (nocc,nocc,nocc,nvir), dtype) eris.oovv = feri.create_dataset('oovv', (nocc,nocc,nvir,nvir), dtype) eris.ovov = feri.create_dataset('ovov', (nocc,nvir,nocc,nvir), dtype) eris.ovvo = feri.create_dataset('ovvo', (nocc,nvir,nvir,nocc), dtype) eris.ovvv = feri.create_dataset('ovvv', (nocc,nvir,nvir,nvir), dtype) if orbspin is None: orbo_a = mo_a[:,:nocc] orbv_a = mo_a[:,nocc:] orbo_b = mo_b[:,:nocc] orbv_b = mo_b[:,nocc:] max_memory = mycc.max_memory-lib.current_memory()[0] blksize = min(nocc, max(2, int(max_memory*1e6/8/(nmo**3*2)))) max_memory = max(MEMORYMIN, max_memory) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, (orbo_a,mo_a,mo_a,mo_a), fswap, 'aaaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbo_a,mo_a,mo_b,mo_b), fswap, 'aabb', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbo_b,mo_b,mo_a,mo_a), fswap, 'bbaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbo_b,mo_b,mo_b,mo_b), fswap, 'bbbb', max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nocc, blksize): tmp = np.asarray(fswap['aaaa'][p0*nmo:p1*nmo]) tmp += np.asarray(fswap['aabb'][p0*nmo:p1*nmo]) tmp += np.asarray(fswap['bbaa'][p0*nmo:p1*nmo]) tmp += np.asarray(fswap['bbbb'][p0*nmo:p1*nmo]) tmp = lib.unpack_tril(tmp).reshape(p1-p0,nmo,nmo,nmo) eris.oooo[p0:p1] = (tmp[:,:nocc,:nocc,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,:nocc,:nocc].transpose(0,2,3,1)) eris.ooov[p0:p1] = (tmp[:,:nocc,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,:nocc].transpose(0,2,3,1)) eris.ovvv[p0:p1] = (tmp[:,nocc:,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,nocc:].transpose(0,2,3,1)) eris.oovv[p0:p1] = (tmp[:,nocc:,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,nocc:].transpose(0,2,3,1)) eris.ovov[p0:p1] = (tmp[:,:nocc,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,:nocc].transpose(0,2,3,1)) eris.ovvo[p0:p1] = (tmp[:,nocc:,nocc:,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,nocc:,nocc:].transpose(0,2,3,1)) tmp = None cput0 = log.timer_debug1('transforming ovvv', *cput0) eris.vvvv = feri.create_dataset('vvvv', (nvir,nvir,nvir,nvir), dtype) tril2sq = lib.square_mat_in_trilu_indices(nvir) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, (orbv_a,orbv_a,orbv_a,orbv_a), fswap, 'aaaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbv_a,orbv_a,orbv_b,orbv_b), fswap, 'aabb', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbv_b,orbv_b,orbv_a,orbv_a), fswap, 'bbaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mycc.mol, (orbv_b,orbv_b,orbv_b,orbv_b), fswap, 'bbbb', max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nvir, blksize): off0 = p0*(p0+1)//2 off1 = p1*(p1+1)//2 tmp = np.asarray(fswap['aaaa'][off0:off1]) tmp += np.asarray(fswap['aabb'][off0:off1]) tmp += np.asarray(fswap['bbaa'][off0:off1]) tmp += np.asarray(fswap['bbbb'][off0:off1]) if p0 > 0: c = tmp[ tril2sq[p0:p1,:p0] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p0,-1)) eris.vvvv[p0:p1,:p0] = c.reshape(p1-p0,p0,nvir,nvir) c = tmp[ tril2sq[:p1,p0:p1] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p1,-1)) eris.vvvv[:p1,p0:p1] = c.reshape(p1,p1-p0,nvir,nvir) tmp = None for p0, p1 in lib.prange(0, nvir, blksize): tmp = np.asarray(eris.vvvv[p0:p1]) eris.vvvv[p0:p1] = tmp.transpose(0,2,1,3) - tmp.transpose(0,2,3,1) cput0 = log.timer_debug1('transforming vvvv', *cput0) else: # with orbspin mo = mo_a + mo_b orbo = mo[:,:nocc] orbv = mo[:,nocc:] max_memory = mycc.max_memory-lib.current_memory()[0] blksize = min(nocc, max(2, int(max_memory*1e6/8/(nmo**3*2)))) max_memory = max(MEMORYMIN, max_memory) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, (orbo,mo,mo,mo), fswap, max_memory=max_memory, verbose=log) sym_forbid = orbspin[:,None] != orbspin for p0, p1 in lib.prange(0, nocc, blksize): tmp = np.asarray(fswap['eri_mo'][p0*nmo:p1*nmo]) tmp = lib.unpack_tril(tmp).reshape(p1-p0,nmo,nmo,nmo) tmp[sym_forbid[p0:p1]] = 0 tmp[:,:,sym_forbid] = 0 eris.oooo[p0:p1] = (tmp[:,:nocc,:nocc,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,:nocc,:nocc].transpose(0,2,3,1)) eris.ooov[p0:p1] = (tmp[:,:nocc,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,:nocc].transpose(0,2,3,1)) eris.ovvv[p0:p1] = (tmp[:,nocc:,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,nocc:].transpose(0,2,3,1)) eris.oovv[p0:p1] = (tmp[:,nocc:,:nocc,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,:nocc,nocc:].transpose(0,2,3,1)) eris.ovov[p0:p1] = (tmp[:,:nocc,nocc:,nocc:].transpose(0,2,1,3) - tmp[:,nocc:,nocc:,:nocc].transpose(0,2,3,1)) eris.ovvo[p0:p1] = (tmp[:,nocc:,nocc:,:nocc].transpose(0,2,1,3) - tmp[:,:nocc,nocc:,nocc:].transpose(0,2,3,1)) tmp = None cput0 = log.timer_debug1('transforming ovvv', *cput0) eris.vvvv = feri.create_dataset('vvvv', (nvir,nvir,nvir,nvir), dtype) sym_forbid = (orbspin[nocc:,None]!=orbspin[nocc:])[np.tril_indices(nvir)] tril2sq = lib.square_mat_in_trilu_indices(nvir) fswap = lib.H5TmpFile() ao2mo.kernel(mycc.mol, orbv, fswap, max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nvir, blksize): off0 = p0*(p0+1)//2 off1 = p1*(p1+1)//2 tmp = np.asarray(fswap['eri_mo'][off0:off1]) tmp[sym_forbid[off0:off1]] = 0 tmp[:,sym_forbid] = 0 if p0 > 0: c = tmp[ tril2sq[p0:p1,:p0] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p0,-1)) eris.vvvv[p0:p1,:p0] = c.reshape(p1-p0,p0,nvir,nvir) c = tmp[ tril2sq[:p1,p0:p1] - off0 ] c = lib.unpack_tril(c.reshape((p1-p0)*p1,-1)) eris.vvvv[:p1,p0:p1] = c.reshape(p1,p1-p0,nvir,nvir) tmp = None for p0, p1 in lib.prange(0, nvir, blksize): tmp = np.asarray(eris.vvvv[p0:p1]) eris.vvvv[p0:p1] = tmp.transpose(0,2,1,3) - tmp.transpose(0,2,3,1) cput0 = log.timer_debug1('transforming vvvv', *cput0) return eris