コード例 #1
0
    def bbgky_noneqm(self, times, **odeint_kwargs):
        """
        Evolves the BBGKY dynamics for selected phase points
        call with bbgky(t), where t is an array of times
        returns the "nonequilibrium" field correlations
        i.e. correlations w.r.t. the initial field
        """
        N = self.latsize

        if type(times).__module__ == np.__name__ :
            #An empty grid of size N X nalphas
            #Each element of this list is a dataset
            localdata = [[None for f in range(self.local_atoms.size)] \
              for kvec in self.kvecs]
            if pbar_avail:
                if self.comm.rank == root and self.verbose:
                    pbar_max = \
                      self.kvecs.shape[0] * self.local_atoms.size * nalphas - 1
                    bar = progressbar.ProgressBar(widgets=widgets_bbgky,\
                      max_value=pbar_max, redirect_stdout=False)
            bar_pos = 0
            if self.verbose and pbar_avail and self.comm.rank == root:
                bar.update(bar_pos)
            for tpl, mth_atom in np.ndenumerate(self.local_atoms):
                (atom_count,) = tpl
                corrs_summedover_alpha = \
                  np.zeros((self.kvecs.shape[0], times.size), \
                    dtype=np.complex_)
                for alpha in xrange(nalphas):
                    s_t = odeint(lindblad_bbgky_pywrap, \
                      mth_atom.state[alpha], times, args=(self,), Dfun=None, **odeint_kwargs)
                    (s_t, info) = s_t if type(s_t) is tuple else (s_t, None)  
                    #Update the final state
                    self.local_atoms[atom_count].state[alpha] = s_t[-1]
                    for kcount in xrange(self.kvecs.shape[0]):
                        self.kvec = self.kvecs[kcount]
                        corrs_summedover_alpha[kcount] += \
                          self.field_correlations(times, alpha, s_t[:,0:3*N], mth_atom)
                        if self.verbose and pbar_avail and self.comm.rank == root:
                            bar.update(bar_pos)
                        localdata[kcount][atom_count] = corrs_summedover_alpha[kcount]
                        bar_pos += 1

            duplicate_comm = Intracomm(self.comm)
            alldata = np.array([None for i in self.kvecs])
            for kcount in xrange(self.kvecs.shape[0]):
                localsum_data = np.sum(np.array(localdata[kcount]), axis=0)
                if self.comm.size == 1:
                    alldata[kcount] = localsum_data
                else:
                    alldata[kcount] = duplicate_comm.reduce(localsum_data, root=root)

            if self.comm.rank == root:
                alldata /= self.corr_norm
            if self.verbose and self.comm.rank == root:
                print("Integrator info:")
                pprint(info)
            return alldata
コード例 #2
0
ファイル: parallel.py プロジェクト: kiwikuma/modred
    def __init__(self):
        """Constructor, tries to import mpi4py and reductions."""
        try:
            from mpi4py import MPI
            self.comm = MPI.COMM_WORLD

            self._node_ID = self.find_node_ID()
            node_IDs = self.comm.allgather(self._node_ID)
            node_IDs_no_duplicates = []
            for ID in node_IDs:
                if not (ID in node_IDs_no_duplicates):
                    node_IDs_no_duplicates.append(ID)

            self._num_nodes = len(node_IDs_no_duplicates)

            # Must use custom_comm for reduce commands! This is
            # more scalable, see reductions.py for more details
            from reductions import Intracomm
            self.custom_comm = Intracomm(self.comm)

            # To adjust number of procs, use submission script/mpiexec
            self._num_MPI_workers = self.comm.Get_size()
            self._rank = self.comm.Get_rank()
            if self._num_MPI_workers > 1:
                self.distributed = True
            else:
                self.distributed = False
        except ImportError:
            self._num_nodes = 1
            self._num_MPI_workers = 1
            self._rank = 0
            self.comm = None
            self.distributed = False
コード例 #3
0
def sum_reduce_all_data(param, datalist_loc, t, mpcomm):
    """
    Does the parallel sum reduction of all data
    """
    #Do local sums
    sx_locsum = np.sum(data.sx for data in datalist_loc)
    sy_locsum = np.sum(data.sy for data in datalist_loc)
    sz_locsum = np.sum(data.sz for data in datalist_loc)
    sxvar_locsum = np.sum(data.sxvar for data in datalist_loc)
    syvar_locsum = np.sum(data.syvar for data in datalist_loc)
    szvar_locsum = np.sum(data.szvar for data in datalist_loc)
    sxyvar_locsum = np.sum(data.sxyvar for data in datalist_loc)
    sxzvar_locsum = np.sum(data.sxzvar for data in datalist_loc)
    syzvar_locsum = np.sum(data.syzvar for data in datalist_loc)

    #Only root processor will actually get the data
    sx_totals = np.zeros_like(sx_locsum) if mpcomm.rank == root\
      else None
    sy_totals = np.zeros_like(sy_locsum) if mpcomm.rank == root\
      else None
    sz_totals = np.zeros_like(sz_locsum) if mpcomm.rank == root\
      else None
    sxvar_totals = np.zeros_like(sxvar_locsum) if mpcomm.rank == root\
      else None
    syvar_totals = np.zeros_like(syvar_locsum) if mpcomm.rank == root\
      else None
    szvar_totals = np.zeros_like(szvar_locsum) if mpcomm.rank == root\
      else None
    sxyvar_totals = np.zeros_like(sxyvar_locsum) if mpcomm.rank == root\
      else None
    sxzvar_totals = np.zeros_like(sxzvar_locsum) if mpcomm.rank == root\
      else None
    syzvar_totals = np.zeros_like(syzvar_locsum) if mpcomm.rank == root\
      else None

    #To prevent conflicts with other comms
    duplicate_comm = Intracomm(mpcomm)
    sx_totals = duplicate_comm.reduce(sx_locsum, root=root)
    sy_totals = duplicate_comm.reduce(sy_locsum, root=root)
    sz_totals = duplicate_comm.reduce(sz_locsum, root=root)
    sxvar_totals = duplicate_comm.reduce(sxvar_locsum, root=root)
    syvar_totals = duplicate_comm.reduce(syvar_locsum, root=root)
    szvar_totals = duplicate_comm.reduce(szvar_locsum, root=root)
    sxyvar_totals = duplicate_comm.reduce(sxyvar_locsum, root=root)
    sxzvar_totals = duplicate_comm.reduce(sxzvar_locsum, root=root)
    syzvar_totals = duplicate_comm.reduce(syzvar_locsum, root=root)

    if mpcomm.rank == root:
        return OutData(t, sx_totals, sy_totals, sz_totals, sxvar_totals, \
            syvar_totals, szvar_totals, sxyvar_totals, sxzvar_totals,\
              syzvar_totals, param)
    else:
        return None
コード例 #4
0
def sum_reduce_all_data(param, datalist_loc, t, mpcomm):
    """
    Does the parallel sum reduction of all data
    """
    # Do local sums
    sx_locsum = np.sum(data.sx for data in datalist_loc)
    sy_locsum = np.sum(data.sy for data in datalist_loc)
    sz_locsum = np.sum(data.sz for data in datalist_loc)
    sxvar_locsum = np.sum(data.sxvar for data in datalist_loc)
    syvar_locsum = np.sum(data.syvar for data in datalist_loc)
    szvar_locsum = np.sum(data.szvar for data in datalist_loc)
    sxyvar_locsum = np.sum(data.sxyvar for data in datalist_loc)
    sxzvar_locsum = np.sum(data.sxzvar for data in datalist_loc)
    syzvar_locsum = np.sum(data.syzvar for data in datalist_loc)

    # Only root processor will actually get the data
    sx_totals = np.zeros_like(sx_locsum) if mpcomm.rank == root else None
    sy_totals = np.zeros_like(sy_locsum) if mpcomm.rank == root else None
    sz_totals = np.zeros_like(sz_locsum) if mpcomm.rank == root else None
    sxvar_totals = np.zeros_like(sxvar_locsum) if mpcomm.rank == root else None
    syvar_totals = np.zeros_like(syvar_locsum) if mpcomm.rank == root else None
    szvar_totals = np.zeros_like(szvar_locsum) if mpcomm.rank == root else None
    sxyvar_totals = np.zeros_like(sxyvar_locsum) if mpcomm.rank == root else None
    sxzvar_totals = np.zeros_like(sxzvar_locsum) if mpcomm.rank == root else None
    syzvar_totals = np.zeros_like(syzvar_locsum) if mpcomm.rank == root else None

    # To prevent conflicts with other comms
    duplicate_comm = Intracomm(mpcomm)
    sx_totals = duplicate_comm.reduce(sx_locsum, root=root)
    sy_totals = duplicate_comm.reduce(sy_locsum, root=root)
    sz_totals = duplicate_comm.reduce(sz_locsum, root=root)
    sxvar_totals = duplicate_comm.reduce(sxvar_locsum, root=root)
    syvar_totals = duplicate_comm.reduce(syvar_locsum, root=root)
    szvar_totals = duplicate_comm.reduce(szvar_locsum, root=root)
    sxyvar_totals = duplicate_comm.reduce(sxyvar_locsum, root=root)
    sxzvar_totals = duplicate_comm.reduce(sxzvar_locsum, root=root)
    syzvar_totals = duplicate_comm.reduce(syzvar_locsum, root=root)

    if mpcomm.rank == root:
        return OutData(
            t,
            sx_totals,
            sy_totals,
            sz_totals,
            sxvar_totals,
            syvar_totals,
            szvar_totals,
            sxyvar_totals,
            sxzvar_totals,
            syzvar_totals,
            param,
        )
    else:
        return None
コード例 #5
0
    def dtwa_bbgky(self, time_info, sampling, **odeint_kwargs):
        comm = self.comm
        old_settings = np.seterr(all='ignore') #Prevent overflow warnings
        N = self.latsize
        rank = comm.rank
        if rank == root and self.verbose:
            pprint("# Run parameters:")
            #Copy params to another object, then delete
            #the output that you don't want printed
            out = copy.copy(self)
            out.dsdotdg = 0.0
            out.delta_eps_tensor = 0.0
            out.jmat = 0.0
            out.deltamn = 0.0
            pprint(vars(out), depth=2)
        if rank == root and not self.verbose:
            pprint("# Starting run ...")
        if type(time_info) is tuple:
            (t_init, t_final, n_steps) = time_info
            dt = (t_final-t_init)/(n_steps-1.0)
            t_output = np.arange(t_init, t_final, dt)
        elif type(time_info) is list  or np.ndarray:
            t_output = time_info
        elif rank == root:
            print("Please enter either a tuple or a list for the time interval")
            exit(0)
        else:
            exit(0)

        #Let each process get its chunk of n_t by round robin
        nt_loc = 0
        iterator = rank
        while iterator < self.n_t:
            nt_loc += 1
            iterator += comm.size
        if pbar_avail:
            if self.comm.rank == root and self.verbose:
                pbar_max = nt_loc-1
                bar = progressbar.ProgressBar(widgets=widgets_bbgky,\
                  max_value=pbar_max, redirect_stdout=False)

        #Scatter unique seeds for generating unique random number arrays :
        #each processor gets its own nt_loc seeds, and allocates nt_loc
        #initial conditions. Each i.c. is a 2N sized array
        #now, each process sends its value of nt_loc to root
        all_ntlocs = comm.gather(nt_loc, root=root)
        #Let the root process initialize nt unique integers for random seeds
        if rank == root:
            all_seeds = np.arange(self.n_t, dtype=np.int64)+1
            all_ntlocs = np.array(all_ntlocs)
            all_displacements = np.roll(np.cumsum(all_ntlocs), root+1)
            all_displacements[root] = 0 # First displacement
        else:
            all_seeds = None
            all_displacements = None
        local_seeds = np.zeros(nt_loc, dtype=np.int64)
        #Root scatters nt_loc sized seed data to that particular process
        comm.Scatterv([all_seeds, all_ntlocs, all_displacements,\
          MPI.DOUBLE],local_seeds)

        list_of_local_data = []

        if self.verbose:
            list_of_dhwdt_abs2 = []

        for runcount in xrange(0, nt_loc, 1):
            s_init_spins, s_init_corrs = sample(self, sampling, \
              local_seeds[runcount] + self.seed_offset)
            #Redirect unwanted stdout warning messages to /dev/null
            with stdout_redirected():
                if self.jac:
                    s = odeint(func_dtwa_bbgky, \
                      np.concatenate((s_init_spins, s_init_corrs)), t_output, \
                        args=(self,), Dfun=jac_dtwa_bbgky, **odeint_kwargs)
                else:
                    s = odeint(func_dtwa_bbgky, \
                      np.concatenate((s_init_spins, s_init_corrs)),t_output, \
                        args=(self,), Dfun=None, **odeint_kwargs)
                (s, info) = s if type(s) is tuple else (s, None)
            #Computes |dH/dt|^2 for a particular alphavec & weighes it
            #If the rms over alphavec of these are 0, then each H is const
            if self.verbose:
                hws = weyl_hamilt(s,t_output, self)
                dhwdt = np.array([t_deriv(hw, t_output) for hw in hws])
                dhwdt_abs2 = np.square(dhwdt)
                list_of_dhwdt_abs2.extend(dhwdt_abs2)

            s = np.array(s, dtype="float128")#Widen memory to reduce overflows
            localdata = bbgky_observables(t_output, s, self)
            list_of_local_data.append(localdata)
            if self.verbose and pbar_avail and self.comm.rank == root:
                bar.update(runcount)

        #After loop above  sum reduce (don't forget to average) all locally
        #calculated expectations at each time to root
        outdat = \
          sum_reduce_all_data(self, list_of_local_data, t_output, comm)
        if self.verbose:
            dhwdt_abs2_locsum = np.sum(list_of_dhwdt_abs2, axis=0)
            dhwdt_abs2_totals = np.zeros_like(dhwdt_abs2_locsum)\
              if rank == root else None
            temp_comm = Intracomm(comm)
            dhwdt_abs2_totals = temp_comm.reduce(dhwdt_abs2_locsum, root=root)
            if rank == root:
                dhwdt_abs2_totals = dhwdt_abs2_totals/(self.n_t * N * N)
                dhwdt_abs_totals = np.sqrt(dhwdt_abs2_totals)

        if rank == root:
            outdat.normalize_data(self.n_t, N)
            if self.verbose:
                print("  ")
                print("Integration output info:")
                pprint(info)
                print("\nt-deriv of Hamilt (abs square) with wigner avg: ")
                print("  ")
                print(tabulate({"time": t_output, \
                  "dhwdt_abs": dhwdt_abs_totals}, \
                  headers="keys", floatfmt=".6f"))
            if self.jac and self.verbose:
                print('# Cumulative number of Jacobian evaluations by root:', \
                  np.sum(info['nje']))
            print('# Done!')
            np.seterr(**old_settings)  # reset to default
            return outdat
        else:
            np.seterr(**old_settings)  # reset to default
            return None
コード例 #6
0
 def setUp(self):
     self.comm = Intracomm(MPI.COMM_WORLD.Dup())
コード例 #7
0
class TestWD(BaseTest, unittest.TestCase):
    def setUp(self):
        self.comm = Intracomm(MPI.COMM_WORLD.Dup())

    def tearDown(self):
        self.comm.Free()
コード例 #8
0
 def setUp(self):
     self.comm = Intracomm(MPI.COMM_SELF.Dup())
コード例 #9
0
    def dtwa_bbgky(self, time_info, sampling, **odeint_kwargs):
        comm = self.comm
        old_settings = np.seterr(all='ignore')  #Prevent overflow warnings
        N = self.latsize
        rank = comm.rank
        if rank == root and self.verbose:
            pprint("# Run parameters:")
            #Copy params to another object, then delete
            #the output that you don't want printed
            out = copy.copy(self)
            out.dsdotdg = 0.0
            out.delta_eps_tensor = 0.0
            out.jmat = 0.0
            out.deltamn = 0.0
            pprint(vars(out), depth=2)
        if rank == root and not self.verbose:
            pprint("# Starting run ...")
        if type(time_info) is tuple:
            (t_init, t_final, n_steps) = time_info
            dt = (t_final - t_init) / (n_steps - 1.0)
            t_output = np.arange(t_init, t_final, dt)
        elif type(time_info) is list or np.ndarray:
            t_output = time_info
        elif rank == root:
            print(
                "Please enter either a tuple or a list for the time interval")
            exit(0)
        else:
            exit(0)

        #Let each process get its chunk of n_t by round robin
        nt_loc = 0
        iterator = rank
        while iterator < self.n_t:
            nt_loc += 1
            iterator += comm.size
        if pbar_avail:
            if self.comm.rank == root and self.verbose:
                pbar_max = nt_loc - 1
                bar = progressbar.ProgressBar(widgets=widgets_bbgky,\
                  max_value=pbar_max, redirect_stdout=False)

        #Scatter unique seeds for generating unique random number arrays :
        #each processor gets its own nt_loc seeds, and allocates nt_loc
        #initial conditions. Each i.c. is a 2N sized array
        #now, each process sends its value of nt_loc to root
        all_ntlocs = comm.gather(nt_loc, root=root)
        #Let the root process initialize nt unique integers for random seeds
        if rank == root:
            all_seeds = np.arange(self.n_t, dtype=np.int64) + 1
            all_ntlocs = np.array(all_ntlocs)
            all_displacements = np.roll(np.cumsum(all_ntlocs), root + 1)
            all_displacements[root] = 0  # First displacement
        else:
            all_seeds = None
            all_displacements = None
        local_seeds = np.zeros(nt_loc, dtype=np.int64)
        #Root scatters nt_loc sized seed data to that particular process
        comm.Scatterv([all_seeds, all_ntlocs, all_displacements,\
          MPI.DOUBLE],local_seeds)

        list_of_local_data = []

        if self.verbose:
            list_of_dhwdt_abs2 = []

        for runcount in xrange(0, nt_loc, 1):
            s_init_spins, s_init_corrs = sample(self, sampling, \
              local_seeds[runcount] + self.seed_offset)
            #Redirect unwanted stdout warning messages to /dev/null
            with stdout_redirected():
                if self.jac:
                    s = odeint(func_dtwa_bbgky, \
                      np.concatenate((s_init_spins, s_init_corrs)), t_output, \
                        args=(self,), Dfun=jac_dtwa_bbgky, **odeint_kwargs)
                else:
                    s = odeint(func_dtwa_bbgky, \
                      np.concatenate((s_init_spins, s_init_corrs)),t_output, \
                        args=(self,), Dfun=None, **odeint_kwargs)
                (s, info) = s if type(s) is tuple else (s, None)
            #Computes |dH/dt|^2 for a particular alphavec & weighes it
            #If the rms over alphavec of these are 0, then each H is const
            if self.verbose:
                hws = weyl_hamilt(s, t_output, self)
                dhwdt = np.array([t_deriv(hw, t_output) for hw in hws])
                dhwdt_abs2 = np.square(dhwdt)
                list_of_dhwdt_abs2.extend(dhwdt_abs2)

            s = np.array(s,
                         dtype="float128")  #Widen memory to reduce overflows
            localdata = bbgky_observables(t_output, s, self)
            list_of_local_data.append(localdata)
            if self.verbose and pbar_avail and self.comm.rank == root:
                bar.update(runcount)

        #After loop above  sum reduce (don't forget to average) all locally
        #calculated expectations at each time to root
        outdat = \
          sum_reduce_all_data(self, list_of_local_data, t_output, comm)
        if self.verbose:
            dhwdt_abs2_locsum = np.sum(list_of_dhwdt_abs2, axis=0)
            dhwdt_abs2_totals = np.zeros_like(dhwdt_abs2_locsum)\
              if rank == root else None
            temp_comm = Intracomm(comm)
            dhwdt_abs2_totals = temp_comm.reduce(dhwdt_abs2_locsum, root=root)
            if rank == root:
                dhwdt_abs2_totals = dhwdt_abs2_totals / (self.n_t * N * N)
                dhwdt_abs_totals = np.sqrt(dhwdt_abs2_totals)

        if rank == root:
            outdat.normalize_data(self.n_t, N)
            if self.verbose:
                print("  ")
                print("Integration output info:")
                pprint(info)
                print("\nt-deriv of Hamilt (abs square) with wigner avg: ")
                print("  ")
                print(tabulate({"time": t_output, \
                  "dhwdt_abs": dhwdt_abs_totals}, \
                  headers="keys", floatfmt=".6f"))
            if self.jac and self.verbose:
                print('# Cumulative number of Jacobian evaluations by root:', \
                  np.sum(info['nje']))
            print('# Done!')
            np.seterr(**old_settings)  # reset to default
            return outdat
        else:
            np.seterr(**old_settings)  # reset to default
            return None
コード例 #10
0
    def bbgky_eqm(self, times, **odeint_kwargs):
        """
        Evolves the BBGKY dynamics for selected phase points
        call with bbgky(t), where t is an array of times
        returns the "equilibrium" field correlations
        i.e. correlations w.r.t. the final steady state
        """
        r_t = [None, None, None, None]
        if self.comm.rank ==  root:
            verboseprint(self.verbose, "Starting up the BBGKY dynamics...")
        if type(times).__module__ == np.__name__ :
            #An empty grid of size N X nalphas
            #Each element of this list is a dataset
            localdata = [[None for f in range(self.local_atoms.size)] \
                                                              for kvec in self.kvecs]
            if pbar_avail and self.comm.rank == root and self.verbose:
                pbar_max = self.kvecs.shape[0] * self.local_atoms.size * nalphas - 1
                bar = progressbar.ProgressBar(widgets=widgets_bbgky,\
                                       max_value=pbar_max, redirect_stdout=False)
                bar_pos = 0
                bar.update(bar_pos)
            for tpl, mth_atom in np.ndenumerate(self.local_atoms):
                (atom_count,) = tpl
                corrs_summedover_alpha = np.zeros((self.kvecs.shape[0], times.size),\
                                                                   dtype=np.complex_)
                for alpha in xrange(nalphas):
                    r_t[0] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][0],\
                                                      times, args=(self,), **odeint_kwargs)
                    r_t[1] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][1],\
                                                      times, args=(self,), **odeint_kwargs)
                    r_t[2] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][2],\
                                                      times, args=(self,), **odeint_kwargs)
                    r_t[3] = odeint(lindblad_bbgky_pywrap, mth_atom.state[alpha][3],\
                                                      times, args=(self,), **odeint_kwargs)
                    #Update the final state
                    self.local_atoms[atom_count].state[alpha][0] = r_t[0][-1]
                    self.local_atoms[atom_count].state[alpha][1] = r_t[1][-1]
                    self.local_atoms[atom_count].state[alpha][2] = r_t[2][-1]
                    self.local_atoms[atom_count].state[alpha][3] = r_t[3][-1]
                    for kcount in xrange(self.kvecs.shape[0]):
                        corrs_summedover_alpha[kcount] += \
                               self.field_correlations(self.kvecs[kcount], alpha,\
                                                                   r_t, mth_atom)
                        if self.verbose and pbar_avail and self.comm.rank == root:
                            bar.update(bar_pos)
                            bar_pos += 1
                        localdata[kcount][atom_count] = corrs_summedover_alpha[kcount]

            duplicate_comm = Intracomm(self.comm)
            alldata = np.array([None for i in self.kvecs])
            for kcount in xrange(self.kvecs.shape[0]):
                localsum_data = np.sum(np.array(localdata[kcount]), axis=0)
                if self.comm.size == 1:
                    alldata[kcount] = localsum_data
                else:
                    alldata[kcount] = duplicate_comm.reduce(localsum_data, root=root)
                if self.comm.rank == root:
                    alldata[kcount] = alldata[kcount]/self.norms[kcount]

            if self.comm.rank == root:
                alldata /= self.corr_norm

            return alldata
コード例 #11
0
    def dtwa_ising_longrange_2ndorder(self, time_info, sampling):
        old_settings = np.seterr(all='ignore')  #Prevent overflow warnings
        comm = self.comm
        N = self.latsize
        (t_init, n_cycles, n_steps) = time_info
        rank = comm.rank
        if rank == root and self.verbose:
            pprint("# Run parameters:")
            #Copy params to another object, then delete
            #the output that you don't want printed
            out = copy.copy(self)
            out.dsdotdg = 0.0
            out.delta_eps_tensor = 0.0
            out.jmat = 0.0
            out.deltamn = 0.0
            pprint(vars(out), depth=2)
        if rank == root and not self.verbose:
            pprint("# Starting run ...")
        if self.omega == 0:
            t_final = t_init + n_cycles
        else:
            t_final = t_init + (n_cycles * (2.0 * np.pi / self.omega))
        dt = (t_final - t_init) / (n_steps - 1.0)
        t_output = np.arange(t_init, t_final, dt)
        #Let each process get its chunk of n_t by round robin
        nt_loc = 0
        iterator = rank
        while iterator < self.n_t:
            nt_loc += 1
            iterator += comm.size
        #Scatter unique seeds for generating unique random number arrays :
        #each processor gets its own nt_loc seeds, and allocates nt_loc
        #initial conditions. Each i.c. is a 2N sized array
        #now, each process sends its value of nt_loc to root
        all_ntlocs = comm.gather(nt_loc, root=root)
        #Let the root process initialize nt unique integers for random seeds
        if rank == root:
            all_seeds = np.arange(self.n_t, dtype=np.int64) + 1
            all_ntlocs = np.array(all_ntlocs)
            all_displacements = np.roll(np.cumsum(all_ntlocs), root + 1)
            all_displacements[root] = 0  # First displacement
        else:
            all_seeds = None
            all_displacements = None
        local_seeds = np.zeros(nt_loc, dtype=np.int64)
        #Root scatters nt_loc sized seed data to that particular process
        comm.Scatterv([all_seeds, all_ntlocs, all_displacements,\
          MPI.DOUBLE],local_seeds)

        list_of_local_data = []

        if self.verbose:
            list_of_dhwdt_abs2 = []

        if self.sitedata:
            list_of_local_ijdata = []

        for runcount in xrange(0, nt_loc, 1):
            random.seed(local_seeds[runcount] + self.seed_offset)
            sx_init = np.ones(N)
            if sampling == "spr":
                #According to Schachenmayer, the wigner function of the quantum
                #state generates the below initial conditions classically
                sy_init = 2.0 * np.random.randint(0, 2, size=N) - 1.0
                sz_init = 2.0 * np.random.randint(0, 2, size=N) - 1.0
                #Set initial conditions for the dynamics locally to vector
                #s_init and store it as [s^x,s^x,s^x, .... s^y,s^y,s^y ...,
                #s^z,s^z,s^z, ...]
                s_init_spins = np.concatenate((sx_init, sy_init, sz_init))
            elif sampling == "1-0":
                spin_choices = np.array([(1, 1, 0), (1, 0, 1), (1, -1, 0),
                                         (1, 0, -1)])
                spins = np.array(
                    [random.choice(spin_choices) for i in xrange(N)])
                s_init_spins = spins.T.flatten()
            elif sampling == "all":
                spin_choices_spr = np.array([(1, 1, 1), (1, 1, -1), (1, -1, 1),
                                             (1, -1, -1)])
                spin_choices_10 = np.array([(1, 1, 0), (1, 0, 1), (1, -1, 0),
                                            (1, 0, -1)])
                spin_choices = np.concatenate(
                    (spin_choices_10, spin_choices_spr))
                spins = np.array(
                    [random.choice(spin_choices) for i in xrange(N)])
                s_init_spins = spins.T.flatten()
            else:
                pass

            # Set initial correlations to 0.
            s_init_corrs = np.zeros(9 * N * N)
            #Redirect unwanted stdout warning messages to /dev/null
            with stdout_redirected():
                if self.verbose:
                    if self.jac:
                        s, info = odeint(func_2ndorder, \
                          np.concatenate((s_init_spins, s_init_corrs)), t_output, \
                            args=(self,), Dfun=jac_2ndorder, full_output=True)
                    else:
                        s, info = odeint(func_2ndorder, \
                          np.concatenate((s_init_spins, s_init_corrs)),t_output, \
                            args=(self,), Dfun=None, full_output=True)
                else:
                    if self.jac:
                        s = odeint(func_2ndorder, \
                          np.concatenate((s_init_spins, s_init_corrs)), \
                            t_output, args=(self,), Dfun=jac_2ndorder)
                    else:
                        s = odeint(func_2ndorder, \
                          np.concatenate((s_init_spins, s_init_corrs)), t_output, \
                            args=(self,), Dfun=None)

            #Computes |dH/dt|^2 for a particular alphavec & weighes it
            #If the rms over alphavec of these are 0, then each H is const
            if self.verbose:
                hws = weyl_hamilt(s, t_output, self)
                dhwdt = np.array([t_deriv(hw, t_output) for hw in hws])
                dhwdt_abs2 = np.square(dhwdt)
                list_of_dhwdt_abs2.extend(dhwdt_abs2)

            s = np.array(s,
                         dtype="float128")  #Widen memory to reduce overflows
            #Compute expectations <sx> and \sum_{ij}<sx_i sx_j> -<sx>^2 with
            #wigner func at t_output values LOCALLY for each initcond and
            #store them
            sx_expectations = np.sum(s[:, 0:N], axis=1)
            sy_expectations = np.sum(s[:, N:2 * N], axis=1)
            sz_expectations = np.sum(s[:, 2 * N:3 * N], axis=1)

            if self.sitedata:
                (i, j) = self.tpnt_sites
                sxi, syi, szi = s[:, i], s[:, i + N], s[:, i + 2 * N]
                sxi, syi, szi = sxi , syi ,\
                  szi
                sxj, syj, szj = s[:, j], s[:, j + N], s[:, j + 2 * N]
                sxj, syj, szj = sxj , syj ,\
                  szj
                sview = s.view()
                gij = sview[:,3*N:].reshape(\
                  t_output.size,3, 3, N, N)[:, :, :, i, j]
                #Calculate Spatial Correlations
                sy_iplusk = s[:, N:2 * N][:, i:]  #This is a matrix
                syy_k = np.array([sy_iplusk[t] * syi[t] \
                  for t in xrange(t_output.size)])# This is also a matrix
                localdataij = OutData_ij(t_output, self.tpnt_sites, \
                                                          sxi, syi, szi,\
                                                            sxj, syj, szj,\
                                                                sy_iplusk,\
                                                                  syy_k,\
                                                                        gij)
                list_of_local_ijdata.append(localdataij)

            #svec  is the tensor s^l_\mu
            #G = s[3*N:].reshape(3,3,N,N) is the tensor g^{ab}_{\mu\nu}.
            s = np.array(s, dtype="float128")  #Enlarge in mem
            sview = s.view()
            gt = sview[:, 3 * N:].reshape(s.shape[0], 3, 3, N, N)
            gt[:, :, :, range(N), range(N)] = 0.0  #Set diags to 0
            #Quantum spin variance
            sx_var = np.sum(gt[:, 0, 0, :, :], axis=(-1, -2))
            sx_var += (np.sum(s[:, 0:N], axis=1)**2 \
              - np.sum(s[:, 0:N]**2, axis=1))

            sy_var = np.sum(gt[:, 1, 1, :, :], axis=(-1, -2))
            sy_var += (np.sum(s[:, N:2*N], axis=1)**2 \
            - np.sum(s[:, N:2*N]**2, axis=1))

            sz_var = np.sum(gt[:, 2, 2, :, :], axis=(-1, -2))
            sz_var += (np.sum(s[:, 2*N:3*N], axis=1)**2 \
            - np.sum(s[:, 2*N:3*N]**2, axis=1))

            sxy_var = np.sum(gt[:, 0, 1, :, :], axis=(-1, -2))
            sxy_var += np.sum([fftconvolve(s[m, 0:N], s[m, N:2*N]) \
            for m in xrange(t_output.size)], axis=1)
            #Remove the diagonal parts
            sxy_var -= np.sum(s[:, 0:N] * s[:, N:2 * N], axis=1)

            sxz_var = np.sum(gt[:, 0, 2, :, :], axis=(-1, -2))
            sxz_var += np.sum([fftconvolve(s[m, 0:N], s[m, 2*N:3*N]) \
              for m in xrange(t_output.size)], axis=1)
            #Remove the diagonal parts
            sxz_var -= np.sum(s[:, 0:N] * s[:, 2 * N:3 * N], axis=1)

            syz_var = np.sum(gt[:, 1, 2, :, :], axis=(-1, -2))
            syz_var += np.sum([fftconvolve(s[m, N:2*N], s[m, 2*N:3*N]) \
              for m in xrange(t_output.size)], axis=1)
            #Remove the diagonal parts
            syz_var -= np.sum(s[:, N:2 * N] * s[:, 2 * N:3 * N], axis=1)

            localdata = OutData(t_output, sx_expectations, sy_expectations,\
              sz_expectations, sx_var, sy_var, sz_var, sxy_var, sxz_var, \
                syz_var, self)
            list_of_local_data.append(localdata)
        #After loop above  sum reduce (don't forget to average) all locally
        #calculated expectations at each time to root
        outdat = \
          self.sum_reduce_all_data(list_of_local_data, t_output, comm)
        if self.verbose:
            dhwdt_abs2_locsum = np.sum(list_of_dhwdt_abs2, axis=0)
            dhwdt_abs2_totals = np.zeros_like(dhwdt_abs2_locsum)\
              if rank == root else None

        if self.sitedata:
            sij = self.sum_reduce_site_data(list_of_local_ijdata, t_output,\
              self.tpnt_sites, comm)
            if rank == root:
                sij.normalize_data(self.n_t)
                sij.dump_data()

        if self.verbose:
            temp_comm = Intracomm(comm)
            dhwdt_abs2_totals = temp_comm.reduce(dhwdt_abs2_locsum, root=root)
            if rank == root:
                dhwdt_abs2_totals = dhwdt_abs2_totals / (self.n_t * N * N)
                dhwdt_abs_totals = np.sqrt(dhwdt_abs2_totals)

        #Dump to file
        if rank == root:
            outdat.normalize_data(self.n_t, N)
            if self.file_output:
                outdat.dump_data()
            if self.verbose:
                print("t-deriv of Hamilt (abs square) with wigner avg: ")
                print("  ")
                print(tabulate({"time": t_output, \
                  "dhwdt_abs": dhwdt_abs_totals}, \
                  headers="keys", floatfmt=".6f"))
            if self.jac and self.verbose:
                print('# Cumulative number of Jacobian evaluations by root:', \
                  np.sum(info['nje']))
            print('# Done!')
            np.seterr(**old_settings)  # reset to default
            return outdat
        else:
            np.seterr(**old_settings)  # reset to default
            return None
コード例 #12
0
    def sum_reduce_site_data(self, datalist_loc, t, sites, mpcomm):
        """
        Does the parallel sum reduction of site data
        """
        sxi_locsum = np.sum(data.sxi for data in datalist_loc)
        syi_locsum = np.sum(data.syi for data in datalist_loc)
        szi_locsum = np.sum(data.szi for data in datalist_loc)
        sxj_locsum = np.sum(data.sxj for data in datalist_loc)
        syj_locsum = np.sum(data.syj for data in datalist_loc)
        szj_locsum = np.sum(data.szj for data in datalist_loc)
        sy_iplusk_locsum = np.sum(data.sy_iplusk for data in datalist_loc)
        syy_k_locsum = np.sum(data.syy_k for data in datalist_loc)

        try:  #This is to take care of the case when gij = None
            gijs_locsum = np.sum(data.gij for data in datalist_loc)
        except AttributeError:
            gijs_locsum = None

        sxi_totals = np.zeros_like(sxi_locsum) if mpcomm.rank == root\
          else None
        syi_totals = np.zeros_like(syi_locsum) if mpcomm.rank == root\
          else None
        szi_totals = np.zeros_like(szi_locsum) if mpcomm.rank == root\
          else None
        sxj_totals = np.zeros_like(sxj_locsum) if mpcomm.rank == root\
          else None
        syj_totals = np.zeros_like(syj_locsum) if mpcomm.rank == root \
          else None
        szj_totals = np.zeros_like(szj_locsum) if mpcomm.rank == root \
          else None
        sy_iplusk_totals = np.zeros_like(sy_iplusk_locsum) \
          if mpcomm.rank == root else None
        syy_k_totals = np.zeros_like(syy_k_locsum) \
          if mpcomm.rank == root else None

        gijs_totals = np.zeros_like(gijs_locsum) if mpcomm.rank == root \
          else None

        #To prevent conflicts with other comms
        duplicate_comm = Intracomm(mpcomm)
        #Broadcast these reductions to root
        sxi_totals = duplicate_comm.reduce(sxi_locsum, root=root)
        syi_totals = duplicate_comm.reduce(syi_locsum, root=root)
        szi_totals = duplicate_comm.reduce(szi_locsum, root=root)
        sxj_totals = duplicate_comm.reduce(sxj_locsum, root=root)
        syj_totals = duplicate_comm.reduce(syj_locsum, root=root)
        szj_totals = duplicate_comm.reduce(szj_locsum, root=root)
        sy_iplusk_totals = duplicate_comm.reduce(sy_iplusk_locsum, root=root)
        syy_k_totals = duplicate_comm.reduce(syy_k_locsum, root=root)

        if gijs_locsum is not None:
            gijs_totals = duplicate_comm.reduce(gijs_locsum, root=root)
        else:
            gijs_totals = None

        if mpcomm.rank == root:
            return OutData_ij(t, sites, sxi_totals, syi_totals, \
              szi_totals, sxj_totals, syj_totals, szj_totals, \
                sy_iplusk_totals, syy_k_totals, gijs_totals)
        else:
            return None