Source code for asap3.Internal.UtilityFunctions

"""Asap utility functions

This module defines the following functions:
PrintVersion
"""

__docformat__ = "restructuredtext en"


from asap3.Internal.Builtins import _asap, get_version, get_short_version
from asap3 import __file__ as _asapfile
import numpy as np
import ase
import sys
import os

def print_version(level = 0):
    """Print the version number of the loaded version of Asap.

    Parameters
    ----------
    level : int, optional
        If 1 or higher, also print the pathnames of the most important files
        and the versions of Python, NumPy and ASE.  The default is 0.
    """
    try:
        compiledfile = _asap.__file__
    except AttributeError:
        compiledfile = "<built-in>"
    print(get_version())
    if level >= 1:
        pv = sys.version.split('\n')
        print("  Python module: ", _asapfile)
        print("  C++ module:    ", compiledfile)
        print("  ase module:    ", ase.__file__)
        print()
        print("  Python version:", pv[0])
        for pvline in pv[1:]:
            print("                 ", pvline)
        print("  numpy version: ", np.version.version)
        print("  ase version:   ", ase.__version__)

[docs] def DebugOutput(filename, stdout=1, nomaster=False, sync=True): """Send debugging output on each node to a different file. Redirect stderr to a different file on each node. The file is opened with minimal buffering, and stderr is redirected to it (also for C/C++ extensions). Standard output for C/C++ extensions is never touched. This is mainly useful for parallel simulations. Parameters ---------- filename : str The name of the file. It should contain ``%d``, which is replaced by the node number. stdout : bool, optional If true (the default), Python's ``sys.stdout`` is also redirected to the same file. nomaster : bool, optional If ``True``, the master task does not redirect its output. The default is ``False``. sync : bool, optional Open the file in synchronous mode. The default is ``True``. """ if stdout: sys.stdout = sys.stderr try: import asap3.mpi node = asap3.mpi.world.rank except (AttributeError, ImportError): node = 0 if nomaster and node == 0: return flag = os.O_WRONLY|os.O_CREAT|os.O_TRUNC if sync: flag = flag|os.O_SYNC newerror = os.open((filename % (node,)), flag, 0o660) try: os.dup2(newerror, sys.stderr.fileno()) except: sys.stderr.write("Cannot redirect sys.stderr as it is fake.") # This Python file must NOT go away. Attach it to the sys module. sys._AsapStandardError = newerror
def print_memory(txt, a=None): import asap3.mpi procfile = open("/proc/self/status") vmsize = vmpeak = vmdata = vmrss = -1 for line in procfile: words = line.split() if words[0] == "VmSize:": vmsize = int(words[1]) elif words[0] == "VmPeak:": vmpeak = int(words[1]) elif words[0] == "VmData:": vmdata = int(words[1]) elif words[0] == "VmRSS:": vmrss = int(words[1]) print("Memory [proc %d '%s']: %d MB total (%d MB peak, %d MB data, %d MB rss)" % ( asap3.mpi.world.rank, txt, (vmsize+512) / 1024, (vmpeak+512) / 1024, (vmdata+512) / 1024, (vmrss+512)/1024)) #, file=sys.stderr) procfile.close() if a is not None: memory_usage(a) def memory_usage(obj, total=True): """Print the memory usage of some kinds of objects. Supported objects are atoms, EMT calculators and neighbor lists. Parameters ---------- obj : object The object whose memory usage is reported. total : bool, optional Print the total memory usage. The default is ``True``. Returns ------- int The memory usage in bytes. """ mem = 0 if hasattr(obj, "arrays"): mem += _memory_usage_atoms(obj) try: calc = obj.calc except AttributeError: calc = None if calc is not None: mem += memory_usage(calc, total=False) elif hasattr(obj, "print_memory"): mem += obj.print_memory() else: print("*MEM* Memory usage of this object is not supported:", obj) return 0 if total: print("*MEM* Total %d MB." % (mem,)) return mem def _memory_usage_atoms(atoms): arr = atoms.arrays mem = 0 nat = len(atoms) nvar = 0 megabyte = 1024*1024 for k in arr.keys(): mem += arr[k].size * arr[k].itemsize nvar += 1 gmem = 0 gvar = 0 if hasattr(atoms, "ghosts"): arr = atoms.ghosts for k in arr.keys(): gmem += arr[k].size * arr[k].itemsize gvar += 1 mem = (mem + gmem + megabyte/2) / megabyte gmem = (gmem + megabyte/2) / megabyte print("*MEM* Atoms %d MB. [ %d atoms, %d arrays, %d gh_arr of %d MB ]" % ( mem, nat, nvar, gvar, gmem)) return mem