Пример #1
0
    def __init__(self, gd, bd, block_comm, dtype, nao, timer=nulltimer):
        KohnShamLayouts.__init__(self, gd, bd, block_comm, dtype, timer)
        self.mMdescriptor = MatrixDescriptor(nao, nao)
        self.nMdescriptor = MatrixDescriptor(bd.mynbands, nao)

        self.Mstart = 0
        self.Mstop = nao
        self.Mmax = nao
        self.mynao = nao
        self.nao = nao
        self.orbital_comm = bd.comm
Пример #2
0
    def __init__(self, blacsgrid, M, N, mb, nb, rsrc=0, csrc=0):
        assert M > 0
        assert N > 0
        assert 1 <= mb
        assert 1 <= nb
        if mb > M:
            mb = M
        if nb > N:
            nb = N
        assert 0 <= rsrc < blacsgrid.nprow
        assert 0 <= csrc < blacsgrid.npcol

        self.blacsgrid = blacsgrid
        self.M = M  # global size 1
        self.N = N  # global size 2
        self.mb = mb  # block cyclic distr dim 1
        self.nb = nb  # and 2.  How many rows or columns are on this processor
        # more info:
        # http://www.netlib.org/scalapack/slug/node75.html
        self.rsrc = rsrc
        self.csrc = csrc

        if blacsgrid.is_active():
            locN, locM = _gpaw.get_blacs_local_shape(self.blacsgrid.context,
                                                     self.N, self.M, self.nb,
                                                     self.mb, self.csrc,
                                                     self.rsrc)
            # max 1 is nonsensical, but appears
            # to be required by PBLAS
            self.lld = max(1, locN)
        else:
            # ScaLAPACK has no requirements as to what these values on an
            # inactive blacsgrid should be. This seemed reasonable to me
            # at the time.
            locN, locM = 0, 0
            # This applies only to empty matrices.  Some functions will
            # complain about lld<1, so lld=1 will make those happy.
            self.lld = 1

        # locM, locN is not allowed to be negative. This will cause the
        # redistributor to fail. This could happen on active blacsgrid
        # which does not contain any piece of the distribute matrix.
        # This is why there is a final check on the value of locM, locN.
        MatrixDescriptor.__init__(self, max(0, locM), max(0, locN))

        # This is the definition of inactive descriptor; can occur
        # on an active or inactive blacs grid.
        self.active = locM > 0 and locN > 0

        self.bshape = (self.mb, self.nb)  # Shape of one block
        self.gshape = (M, N)  # Global shape of array
Пример #3
0
 def __init__(self, blacsgrid, M, N, mb, nb, rsrc, csrc):
     assert M > 0
     assert N > 0
     assert 1 <= mb
     assert 1 <= nb
     if mb > M:
         mb = M
     if nb > N:
         nb = N
     assert 0 <= rsrc < blacsgrid.nprow
     assert 0 <= csrc < blacsgrid.npcol
     
     self.blacsgrid = blacsgrid
     self.M = M # global size 1
     self.N = N # global size 2
     self.mb = mb # block cyclic distr dim 1
     self.nb = nb # and 2.  How many rows or columns are on this processor
     # more info:
     # http://www.netlib.org/scalapack/slug/node75.html
     self.rsrc = rsrc
     self.csrc = csrc
     
     if blacsgrid.is_active():
         locN, locM = _gpaw.get_blacs_local_shape(self.blacsgrid.context,
                                                  self.N, self.M,
                                                  self.nb, self.mb, 
                                                  self.csrc, self.rsrc)
         self.lld  = max(1, locN) # max 1 is nonsensical, but appears
                                  # to be required by PBLAS
     else: 
         # ScaLAPACK has no requirements as to what these values on an
         # inactive blacsgrid should be. This seemed reasonable to me
         # at the time.
         locN, locM = 0, 0
         self.lld = 0
     
     # locM, locN is not allowed to be negative. This will cause the
     # redistributor to fail. This could happen on active blacsgrid
     # which does not contain any piece of the distribute matrix.
     # This is why there is a final check on the value of locM, locN.
     MatrixDescriptor.__init__(self, max(0, locM), max(0, locN))
     
     # This is the definition of inactive descriptor; can occur
     # on an active or inactive blacs grid.
     self.active = locM > 0 and locN > 0
     
     self.bshape = (self.mb, self.nb) # Shape of one block
     self.gshape = (M, N) # Global shape of array
Пример #4
0
 def __init__(self, gd, bd, dtype, nao, timer=nulltimer):
     KohnShamLayouts.__init__(self, gd, bd, dtype, timer)
     self.mMdescriptor = MatrixDescriptor(nao, nao)
     self.nMdescriptor = MatrixDescriptor(bd.mynbands, nao)
     
     self.Mstart = 0
     self.Mstop = nao
     self.Mmax = nao
     self.mynao = nao
     self.nao = nao
     # a problem with forces when 
     # domain-decomposition = (1, 1, 1)
     # bd.comm.size > 1
     # kpt.comm.size > 1
     # Uncomment line 145 in gpaw/test/parallel/lcao_parallel.py
     self.orbital_comm = serial_comm
Пример #5
0
    def iterate_one_k_point(self, ham, wfs, kpt):
        """Setup H and S matries and diagonalize for the kpoint"""

        self.timer.start('DirectPW')
        H_GG, S_GG = wfs.hs(ham, kpt.q, kpt.s)
        npw = len(H_GG)
        eps_n = np.empty(npw)
        md = MatrixDescriptor(npw, npw)
        psit_nG = md.empty(dtype=complex)
        md.general_diagonalize_dc(H_GG, S_GG, psit_nG, eps_n,
                                  iu=wfs.bd.nbands)
        kpt.eps_n[:] = eps_n[:wfs.bd.nbands]
        wfs.pt.integrate(kpt.psit_nG, kpt.P_ani, kpt.q)
        self.timer.stop('DirectPW')
        error = 0.0
        return error
Пример #6
0
    def diagonalize_full_hamiltonian(self, ham, atoms, occupations, txt,
                                     nbands=None, scalapack=None, expert=False):
        assert self.dtype == complex

        if nbands is None:
            nbands = self.pd.ngmin // self.bd.comm.size * self.bd.comm.size
        else:
            assert nbands <= self.pd.ngmin

        if expert:
            iu = nbands
        else:
            iu = None

        self.bd = bd = BandDescriptor(nbands, self.bd.comm)

        p = functools.partial(print, file=txt)
        p('Diagonalizing full Hamiltonian ({0} lowest bands)'.format(nbands))
        p('Matrix size (min, max): {0}, {1}'.format(self.pd.ngmin,
                                                    self.pd.ngmax))
        mem = 3 * self.pd.ngmax**2 * 16 / bd.comm.size / 1024**2
        p('Approximate memory usage per core: {0:.3f} MB'.format(mem))
        if bd.comm.size > 1:
            if isinstance(scalapack, (list, tuple)):
                nprow, npcol, b = scalapack
            else:
                nprow = int(round(bd.comm.size**0.5))
                while bd.comm.size % nprow != 0:
                    nprow -= 1
                npcol = bd.comm.size // nprow
                b = 64
            p('ScaLapack grid: {0}x{1},'.format(nprow, npcol),
              'block-size:', b)
            bg = BlacsGrid(bd.comm, bd.comm.size, 1)
            bg2 = BlacsGrid(bd.comm, nprow, npcol)
            scalapack = True
        else:
            nprow = npcol = 1
            scalapack = False

        self.pt.set_positions(atoms.get_scaled_positions())
        self.kpt_u[0].P_ani = None
        self.allocate_arrays_for_projections(self.pt.my_atom_indices)

        myslice = bd.get_slice()

        pb = ProgressBar(txt)
        nkpt = len(self.kpt_u)
        
        for u, kpt in enumerate(self.kpt_u):
            pb.update(u / nkpt)
            npw = len(self.pd.Q_qG[kpt.q])
            if scalapack:
                mynpw = -(-npw // bd.comm.size)
                md = BlacsDescriptor(bg, npw, npw, mynpw, npw)
                md2 = BlacsDescriptor(bg2, npw, npw, b, b)
            else:
                md = md2 = MatrixDescriptor(npw, npw)

            with self.timer('Build H and S'):
                H_GG, S_GG = self.hs(ham, kpt.q, kpt.s, md)

            if scalapack:
                r = Redistributor(bd.comm, md, md2)
                H_GG = r.redistribute(H_GG)
                S_GG = r.redistribute(S_GG)

            psit_nG = md2.empty(dtype=complex)
            eps_n = np.empty(npw)

            with self.timer('Diagonalize'):
                if not scalapack:
                    md2.general_diagonalize_dc(H_GG, S_GG, psit_nG, eps_n, 
                                               iu=iu)
                else:
                    md2.general_diagonalize_dc(H_GG, S_GG, psit_nG, eps_n)
            del H_GG, S_GG

            kpt.eps_n = eps_n[myslice].copy()

            if scalapack:
                md3 = BlacsDescriptor(bg, npw, npw, bd.mynbands, npw)
                r = Redistributor(bd.comm, md2, md3)
                psit_nG = r.redistribute(psit_nG)

            kpt.psit_nG = psit_nG[:bd.mynbands].copy()
            del psit_nG

            with self.timer('Projections'):
                self.pt.integrate(kpt.psit_nG, kpt.P_ani, kpt.q)

            kpt.f_n = None

        pb.finish()
        
        occupations.calculate(self)
Пример #7
0
    def diagonalize_full_hamiltonian(self, ham, atoms, occupations, log,
                                     nbands=None, ecut=None, scalapack=None,
                                     expert=False):

        if self.dtype != complex:
            raise ValueError('Your wavefunctions are not complex as '
                             'required by the PW diagonalization routine.\n'
                             'Please supply GPAW(..., dtype=complex, ...) '
                             'as an argument to the calculator to enforce '
                             'complex wavefunctions.')

        if nbands is None and ecut is None:
            nbands = self.pd.ngmin // self.bd.comm.size * self.bd.comm.size
        elif nbands is None:
            ecut /= units.Hartree
            vol = abs(np.linalg.det(self.gd.cell_cv))
            nbands = int(vol * ecut**1.5 * 2**0.5 / 3 / pi**2)
        else:
            assert nbands <= self.pd.ngmin

        if expert:
            iu = nbands
        else:
            iu = None

        self.bd = bd = BandDescriptor(nbands, self.bd.comm)

        log('Diagonalizing full Hamiltonian ({0} lowest bands)'.format(nbands))
        log('Matrix size (min, max): {0}, {1}'.format(self.pd.ngmin,
                                                      self.pd.ngmax))
        mem = 3 * self.pd.ngmax**2 * 16 / bd.comm.size / 1024**2
        log('Approximate memory usage per core: {0:.3f} MB'.format(mem))
        if bd.comm.size > 1:
            if isinstance(scalapack, (list, tuple)):
                nprow, npcol, b = scalapack
            else:
                nprow = int(round(bd.comm.size**0.5))
                while bd.comm.size % nprow != 0:
                    nprow -= 1
                npcol = bd.comm.size // nprow
                b = 64
            log('ScaLapack grid: {0}x{1},'.format(nprow, npcol),
                'block-size:', b)
            bg = BlacsGrid(bd.comm, bd.comm.size, 1)
            bg2 = BlacsGrid(bd.comm, nprow, npcol)
            scalapack = True
        else:
            nprow = npcol = 1
            scalapack = False

        self.set_positions(atoms.get_scaled_positions())
        self.kpt_u[0].P_ani = None
        self.allocate_arrays_for_projections(self.pt.my_atom_indices)

        myslice = bd.get_slice()

        pb = ProgressBar(log.fd)
        nkpt = len(self.kpt_u)

        for u, kpt in enumerate(self.kpt_u):
            pb.update(u / nkpt)
            npw = len(self.pd.Q_qG[kpt.q])
            if scalapack:
                mynpw = -(-npw // bd.comm.size)
                md = BlacsDescriptor(bg, npw, npw, mynpw, npw)
                md2 = BlacsDescriptor(bg2, npw, npw, b, b)
            else:
                md = md2 = MatrixDescriptor(npw, npw)

            with self.timer('Build H and S'):
                H_GG, S_GG = self.hs(ham, kpt.q, kpt.s, md)

            if scalapack:
                r = Redistributor(bd.comm, md, md2)
                H_GG = r.redistribute(H_GG)
                S_GG = r.redistribute(S_GG)

            psit_nG = md2.empty(dtype=complex)
            eps_n = np.empty(npw)

            with self.timer('Diagonalize'):
                if not scalapack:
                    md2.general_diagonalize_dc(H_GG, S_GG, psit_nG, eps_n,
                                               iu=iu)
                else:
                    md2.general_diagonalize_dc(H_GG, S_GG, psit_nG, eps_n)
            del H_GG, S_GG

            kpt.eps_n = eps_n[myslice].copy()

            if scalapack:
                md3 = BlacsDescriptor(bg, npw, npw, bd.mynbands, npw)
                r = Redistributor(bd.comm, md2, md3)
                psit_nG = r.redistribute(psit_nG)

            kpt.psit_nG = psit_nG[:bd.mynbands].copy()
            del psit_nG

            with self.timer('Projections'):
                self.pt.integrate(kpt.psit_nG, kpt.P_ani, kpt.q)

            kpt.f_n = None

        pb.finish()

        occupations.calculate(self)

        return nbands