Пример #1
0
def cleanAllArmiTempDirs(olderThanDays: int):
    """
    Delete all ARMI-related files from other unrelated runs after `olderThanDays` days (in
    case this failed on earlier runs).

    .. warning:: This will break any concurrent runs that are still running.

    This is a useful utility in HPC environments when some runs crash sometimes.
    """
    # pylint: disable=import-outside-toplevel # avoid cyclic import
    from armi.utils.pathTools import cleanPath

    gracePeriod = datetime.timedelta(days=olderThanDays)
    now = datetime.datetime.now()
    thisRunFolder = os.path.basename(_FAST_PATH)

    for dirname in os.listdir(APP_DATA):
        dirPath = os.path.join(APP_DATA, dirname)
        if not os.path.isdir(dirPath):
            continue
        try:
            fromThisRun = dirname == thisRunFolder  # second chance to delete
            _rank, dateString = dirname.split("-")
            dateOfFolder = datetime.datetime.strptime(dateString,
                                                      "%Y%m%d%H%M%S%f")
            runIsOldAndLikleyComplete = (now - dateOfFolder) > gracePeriod
            if runIsOldAndLikleyComplete or fromThisRun:
                # Delete old files
                cleanPath(dirPath)
        except:  # pylint: disable=bare-except
            pass
Пример #2
0
def deleteCache(cachedFolder):
    """
    Remove this folder.

    Requires safeword because this is potentially extremely destructive.
    """
    if "Output_Cache" not in cachedFolder:
        raise RuntimeError(
            "Cache location must contain safeword: `Output_Cache`.")
    cleanPath(cachedFolder)
Пример #3
0
 def __exit__(self, exc_type, exc_value, traceback):
     DirectoryChanger.__exit__(self, exc_type, exc_value, traceback)
     try:
         pathTools.cleanPath(self.destination, context.MPI_RANK)
     except PermissionError:
         if os.name == "nt":
             runLog.warning(
                 "There is an issue where Windows will not agree to delete private directories."
                 "That is, if you create a directory with a name starting with a period, the "
                 "TempDirChanger will not be able to clean it (for instance, a '.git' dir)."
             )
     context.waitAll()
Пример #4
0
def cleanTempDirs(olderThanDays=None):
    """
    Clean up temporary files after a run.

    The Windows HPC system sends a SIGBREAK signal when the user cancels a job, which
    is NOT handled by ``atexit``. Notably SIGBREAK doesn't exist off Windows.
    For the SIGBREAK signal to work with a Microsoft HPC, the ``TaskCancelGracePeriod``
    option must be configured to be non-zero. This sets the period between SIGBREAK
    and SIGTERM/SIGINT. To do cleanups in this case, we must use the ``signal`` module.
    Actually, even then it does not work because MS ``mpiexec`` does not pass signals
    through.

    Parameters
    ----------
    olderThanDays: int, optional
        If provided, deletes other ARMI directories if they are older than the requested
        time.
    """
    # pylint: disable=import-outside-toplevel # avoid cyclic import
    from armi import runLog
    from armi.utils.pathTools import cleanPath

    disconnectAllHdfDBs()
    printMsg = runLog.getVerbosity() <= DEBUG
    if _FAST_PATH_IS_TEMPORARY and os.path.exists(_FAST_PATH):
        if printMsg:
            print(
                "Cleaning up temporary files in: {}".format(_FAST_PATH),
                file=sys.stdout,
            )
        try:
            cleanPath(_FAST_PATH)
        except Exception as error:  # pylint: disable=broad-except
            for outputStream in (sys.stderr, sys.stdout):
                if printMsg:
                    print(
                        "Failed to delete temporary files in: {}\n"
                        "    error: {}".format(_FAST_PATH, error),
                        file=outputStream,
                    )

    if olderThanDays is not None:
        cleanAllArmiTempDirs(olderThanDays)
Пример #5
0
    def test_cleanPathMpi(self):
        # """Simple tests of cleanPath(), in the MPI scenario"""
        with TemporaryDirectoryChanger():
            # TEST 0: File is not safe to delete, due to name pathing
            filePath0 = "test0_cleanPathNoMpi"
            open(filePath0, "w").write("something")

            self.assertTrue(os.path.exists(filePath0))
            with self.assertRaises(Exception):
                pathTools.cleanPath(filePath0, mpiRank=context.MPI_RANK)
            context.waitAll()

            # TEST 1: Delete a single file
            filePath1 = "test1_cleanPathNoMpi_mongoose"
            open(filePath1, "w").write("something")

            self.assertTrue(os.path.exists(filePath1))
            pathTools.cleanPath(filePath1, mpiRank=context.MPI_RANK)
            context.waitAll()
            self.assertFalse(os.path.exists(filePath1))

            # TEST 2: Delete an empty directory
            dir2 = "mongoose"
            os.mkdir(dir2)

            self.assertTrue(os.path.exists(dir2))
            pathTools.cleanPath(dir2, mpiRank=context.MPI_RANK)
            context.waitAll()
            self.assertFalse(os.path.exists(dir2))

            # TEST 3: Delete a directory with two files inside
            # create directory
            dir3 = "mongoose"
            os.mkdir(dir3)

            # throw in a couple of simple text files
            open(os.path.join(dir3, "file1.txt"), "w").write("something1")
            open(os.path.join(dir3, "file2.txt"), "w").write("something2")

            # delete the directory and test
            self.assertTrue(os.path.exists(dir3))
            self.assertTrue(os.path.exists(os.path.join(dir3, "file1.txt")))
            self.assertTrue(os.path.exists(os.path.join(dir3, "file2.txt")))
            pathTools.cleanPath(dir3, mpiRank=context.MPI_RANK)
            context.waitAll()
            self.assertFalse(os.path.exists(dir3))
Пример #6
0
    def snapshotRequest(self, cycle, node):
        """
        Process a snapshot request at this time.

        This copies various physics input and output files to a special folder that
        follow-on analysis be executed upon later.

        Notes
        -----
        This was originally used to produce MC2/DIF3D inputs for external
        parties (who didn't have ARMI) to review. Since then, the concept
        of snapshots has evolved with respect to the
        :py:class:`~armi.operators.snapshots.OperatorSnapshots`.
        """
        runLog.info("Producing snapshot for cycle {0} node {1}".format(
            cycle, node))
        self.r.core.zones.summary()

        newFolder = "snapShot{0}_{1}".format(cycle, node)
        if os.path.exists(newFolder):
            runLog.important(
                "Deleting existing snapshot data in {0}".format(newFolder))
            pathTools.cleanPath(newFolder)  # careful with cleanPath!
            # give it a minute.
            time.sleep(1)

        if os.path.exists(newFolder):
            runLog.warning(
                "Deleting existing snapshot data in {0} failed".format(
                    newFolder))
        else:
            os.mkdir(newFolder)

        # copy the cross section inputs
        for fileName in os.listdir("."):
            if "mcc" in fileName and re.search(r"[A-Z]AF?\d?.inp", fileName):
                base, ext = os.path.splitext(fileName)
                # add the cycle and timenode to the XS input file names so that a rx-coeff case that runs
                # in here won't overwrite them.
                shutil.copy(
                    fileName,
                    os.path.join(
                        newFolder,
                        "{0}_{1:03d}_{2:d}{3}".format(base, cycle, node, ext)),
                )

        isoFName = "ISOTXS-c{0}".format(cycle)
        pathTools.copyOrWarn("ISOTXS for snapshot", isoFName,
                             pathTools.armiAbsPath(newFolder, "ISOTXS"))
        pathTools.copyOrWarn(
            "DIF3D output for snapshot",
            self.cs.caseTitle + "{0:03d}.out".format(cycle),
            newFolder,
        )
        pathTools.copyOrWarn("Shuffle logic for snapshot",
                             self.cs["shuffleLogic"], newFolder)
        pathTools.copyOrWarn("Geometry file for snapshot", self.cs["geomFile"],
                             newFolder)
        pathTools.copyOrWarn("Loading definition for snapshot",
                             self.cs["loadingFile"], newFolder)
        pathTools.copyOrWarn(
            "Flow history for snapshot",
            self.cs.caseTitle + ".flow_history.txt",
            newFolder,
        )
        pathTools.copyOrWarn(
            "Pressure history for snapshot",
            self.cs.caseTitle + ".pressure_history.txt",
            newFolder,
        )
Пример #7
0
 def __exit__(self, exc_type, exc_value, traceback):
     DirectoryChanger.__exit__(self, exc_type, exc_value, traceback)
     pathTools.cleanPath(self.destination)