def finished(self): """Write elapsed time to log file and move the log file to the data directory""" from mpi4py.MPI import COMM_WORLD as comm from mpi4py.MPI import Wtime # Wait until all processors are done comm.barrier() seconds = Wtime() - self.wt if comm.rank == 0: # import subprocess from datetime import datetime # Time at end of simulation i = datetime.now() endtime = i.strftime("%d/%m/%Y at %H:%M:%S") f = open(self.data_folder + "psecas.log", "a") f.write("\nCalculation ended on " + endtime + "\n") m, s = divmod(seconds, 60) h, m = divmod(m, 60) d, h = divmod(h, 24) msg = ( "Time elapsed was {} days {} hours {} minutes {:1.4} seconds" ) f.write(msg.format(d, h, m, s)) f.close()
def main(argv=None): args = process_command_line(argv) # note that in MPI mode, lengths will be global, whereas data will # be local (i.e. only this node's data). lengths, data = load_trjs_or_features(args) kwargs = {} if args.cluster_iterations is not None: kwargs['kmedoids_updates'] = int(args.cluster_iterations) clustering = args.Clusterer(metric=args.cluster_distance, n_clusters=args.cluster_number, cluster_radius=args.cluster_radius, mpi_mode=mpi_mode, **kwargs) clustering.fit(data) logger.info("Clustered %s frames into %s clusters in %s seconds.", sum(lengths), len(clustering.centers_), clustering.runtime_) result = clustering.result_ if mpi_mode: local_ctr_inds, local_dists, local_assigs = \ result.center_indices, result.distances, result.assignments with timed("Reassembled dist and assign arrays in %.2f sec", logging.info): all_dists = mpi.ops.assemble_striped_ragged_array( local_dists, lengths) all_assigs = mpi.ops.assemble_striped_ragged_array( local_assigs, lengths) ctr_inds = mpi.ops.convert_local_indices(local_ctr_inds, lengths) result = ClusterResult(center_indices=ctr_inds, distances=all_dists, assignments=all_assigs, centers=result.centers) result = result.partition(lengths) if mpi_comm.Get_rank() == 0: write_centers_indices(args.center_indices, [(t, f * args.subsample) for t, f in result.center_indices]) write_centers(result, args) write_assignments_and_distances_with_reassign(result, args) mpi_comm.barrier() logger.info("Success! Data can be found in %s.", os.path.dirname(args.distances)) return 0
def __init__(self, system, data_folder, experiment, steps, tag=""): """ Initialisation creates the output directory and saves the path to the io object. It also copies the experiment script to the data directory and saves a dictionary with important information. """ from mpi4py.MPI import COMM_WORLD as comm from mpi4py.MPI import Wtime from numpy import arange self.system = system self.steps = steps self.index_global = arange(steps) self.index_local = self.index_global[comm.rank :: comm.size] self.steps_local = len(self.index_local) # Folder where data is stored assert data_folder[-1] == "/", "data_folder should end with /" self.data_folder = data_folder if comm.rank == 0: import subprocess from datetime import datetime from numpy import float64 # Create datafolder subprocess.call("mkdir " + self.data_folder, shell=True) # Copy the experiment to the data folder # experiment = path.basename(experiment) subprocess.call( "cp " + experiment + " " + data_folder + experiment, shell=True, ) info = {"experiment": experiment} # Save git commit number try: git_commit = subprocess.check_output(["git", "rev-parse", "HEAD"]) git_commit = git_commit.strip().decode("utf-8") info.update({"git_commit": git_commit}) except: pass # Save the hostname hostname = subprocess.check_output(["hostname"]) hostname = hostname.strip().decode("utf-8") info.update({"hostname": hostname}) # Save the time at the start of simulation i = datetime.now() simulation_start = i.strftime("%d/%m/%Y at %H:%M:%S") info.update({"simulation_start": simulation_start}) # Add tag which can be used to group simulations together info.update({"tag": tag}) # Collect all variables in local namespace that are int, float or # float64. These will in general be the values set by us. # for key in local_vars.keys(): # if type(local_vars[key]) in (float, float64, int): # info.update({key: local_vars[key]}) # Save the number of MPI processes used info.update({"MPI": comm.size}) # Save the dictionary info to the file info.p # pickle.dump(info, open(data_folder+'info.p', 'wb')) # Start a log file f = open(self.data_folder + "psecas.log", "w") f.write("Log file for EVP run\n") f.write( "Solving {} evp problems on {} processors\n\n".format( self.steps, comm.size ) ) # Write start date and time f.write("Calculation started on " + simulation_start + "\n\n") # Write the contents of info.p for convenience f.write("Contents of info.p is printed below \n") for key in info.keys(): f.write(key + " = {} \n".format(info[key])) f.write("\nContents of system is printed below \n") for key in self.system.__dict__.keys(): if type(self.system.__dict__[key]) in (float, int, list): f.write(key + " = {}\n".format(self.system.__dict__[key])) grid = self.system.grid f.write("\nUsing {} with\n".format(type(grid))) for key in grid.__dict__.keys(): if type(grid.__dict__[key]) in (float, float64, int): f.write(key + " = {} \n".format(grid.__dict__[key])) f.write("\n\nEntering main calculation loop \n") f.close() # Used for computing total runtime self.wt = Wtime() # Wait until all processors are done comm.barrier()
def _create_tempdir(request, mode=None): """ Adapted from DOLFIN's dolfin_utils/test/fixtures.py. """ # Get directory name of test_foo.py file testfile = request.module.__file__ testfiledir = os.path.dirname(os.path.abspath(testfile)) # Construct name test_foo_tempdir from name test_foo.py testfilename = os.path.basename(testfile) if hasattr(request.config, "slaveinput"): outputname = testfilename.replace( ".py", "_tempdir_{}".format(request.config.slaveinput["slaveid"])) else: outputname = testfilename.replace(".py", "_tempdir") # Get function name test_something from test_foo.py function = request.function.__name__ if mode == "save": function = function.replace("_save", "_io") elif mode == "load": function = function.replace("_load", "_io") # Join all of these to make a unique path for this test function basepath = os.path.join(testfiledir, outputname) path = os.path.join(basepath, function) # Add a sequence number to avoid collisions when tests are otherwise parameterized if COMM_WORLD.rank == 0: _create_tempdir._sequencenumber[path] += 1 sequencenumber = _create_tempdir._sequencenumber[path] sequencenumber = COMM_WORLD.allreduce(sequencenumber, op=SUM) else: sequencenumber = COMM_WORLD.allreduce(0, op=SUM) path += "__" + str(sequencenumber) # Delete and re-create directory on root node if COMM_WORLD.rank == 0: # First time visiting this basepath, delete the old and create # a new if mode is not load if basepath not in _create_tempdir._basepaths: _create_tempdir._basepaths.add(basepath) if mode == "load": assert os.path.exists(basepath) else: if os.path.exists(basepath): shutil.rmtree(basepath) # Make sure we have the base path test_foo_tempdir for # this test_foo.py file if not os.path.exists(basepath): os.mkdir(basepath) # Delete path from old test run if mode is not load if mode == "load": assert os.path.exists(path) else: if os.path.exists(path): shutil.rmtree(path) # Make sure we have the path for this test execution: # e.g. test_foo_tempdir/test_something__3 if not os.path.exists(path): os.mkdir(path) COMM_WORLD.barrier() return path
os.mkdir('./vtk/') recs = os.listdir(path) recs.sort() if np.mod(len(recs) - 1, comm.size) != 0: if comm.rank == 0: print('Number of records is not dividable by number of procs ') recs = recs[comm.rank::comm.size] if selection == 'latest': recs = [ recs[-1], ] comm.barrier() for rec in recs: record = h5py.File(path + rec, 'r') base_str = '/data' flds_str = '/fields/' parts_str = '/species/' info_str = '/info/' Args = {} iter = int(rec.split('.')[0]) iter_str = str(iter) for key in ['Xgrid', 'Rgrid', 'dx', 'M', 'dt', 'FrameVelocity']: Args[key] = record[base_str + info_str + key].value