diff options
Diffstat (limited to 'Carpet/Timers/src/CactusTimerSet.cc')
-rw-r--r-- | Carpet/Timers/src/CactusTimerSet.cc | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/Carpet/Timers/src/CactusTimerSet.cc b/Carpet/Timers/src/CactusTimerSet.cc new file mode 100644 index 000000000..54eed2f70 --- /dev/null +++ b/Carpet/Timers/src/CactusTimerSet.cc @@ -0,0 +1,179 @@ +#include <cassert> +#include <cstdio> +#include <cstring> +#include <list> + +#include <cctk.h> +#include <cctk_Parameters.h> +#include <util_String.h> + +#if HAVE_UNISTD_H +# include <fcntl.h> +# include <unistd.h> +#endif + +#include <defs.hh> + +#include <CactusTimer.hh> +#include <CactusTimerSet.hh> +#include <Timer.hh> +#include <TimerTree.hh> + + + +namespace Timers { + + using namespace std; + + // A global timer set + CactusTimerSet timerSet; + + // Add a timer + void CactusTimerSet::add(CactusTimer* const timer) + { + timers.insert(timer); + } + + // Remove a timer + void CactusTimerSet::remove(CactusTimer* const timer) + { + timers.erase(timer); + } + + // Print all timer names + void CactusTimerSet::printNames() const + { + printf("Timer names:\n"); + int n = 0; + for (timers_t::const_iterator + itimer = timers.begin(); itimer != timers.end(); ++itimer) + { + printf(" [%4d] %s\n", n, (*itimer)->name().c_str()); + ++n; + } + } + + // Print all timer data + void CactusTimerSet::printData() + { + for (timers_t::const_iterator + itimer = timers.begin(); itimer != timers.end(); ++itimer) + { + (*itimer)->printData(); + } + printf("\n"); + } + + // Print all timer data + void CactusTimerSet::writeData(const cGH* const cctkGH, + const char* const filename) + { + const int oldfd = redirect(cctkGH, filename); +#if 0 + printf("********************************************************************************\n"); +#endif + printf("# Carpet timing information at iteration %d time %g:\n", + cctkGH->cctk_iteration, double(cctkGH->cctk_time)); + timerSet.printData(); + unredirect(oldfd); + } + + // If filename is not empty, then redirect stdout to a file + int CactusTimerSet::redirect(const cGH* const cctkGH, + const char* const filename) + { + DECLARE_CCTK_PARAMETERS; + + if (CCTK_EQUALS (filename, "")) { + return -1; + } + +#ifndef HAVE_UNISTD_H + CCTK_WARN(CCTK_WARN_ALERT, + "Cannot redirect timer output to a file; the operating system does not support this"); + return -1; +#else + + const int myproc = CCTK_MyProc(cctkGH); + char fullname[10000]; + Util_snprintf(fullname, sizeof fullname, + "%s/%s.%04d.txt", out_dir, filename, myproc); + + int flags = O_WRONLY | O_CREAT | O_APPEND; // append + static bool first_time = true; + if (first_time) { + first_time = false; + if (IO_TruncateOutputFiles(cctkGH)) { + flags = O_WRONLY | O_CREAT | O_TRUNC; // truncate + } + } + + // Temporarily redirect stdout + fflush(stdout); + const int oldfd = dup(1); // fd 1 is stdout + const int mode = 0644; // rw-r--r--, or a+r u+w + const int fdfile = open(fullname, flags, mode); + if (fdfile < 0) { + CCTK_VWarn(CCTK_WARN_ABORT, __LINE__, __FILE__, CCTK_THORNSTRING, + "Could not open timer output file \"%s\"", fullname); + close(oldfd); + return -1; + } + // close(1); + // const int fd = dup(fdfile); // dup to 1, i.e., stdout again + const int fd = dup2(fdfile, 1); // dup to 1, i.e., stdout again + assert(fd == 1); + close(fdfile); + return oldfd; +#endif + } + + // Redirect stdout back + void CactusTimerSet::unredirect(const int oldfd) + { + if (oldfd < 0) return; + +#ifdef HAVE_UNISTD_H + fflush (stdout); + // close(1); + // const int fd = dup(oldfd); + const int fd = dup2(oldfd, 1); + if (not (fd == 1)) { + fprintf(stderr, "oldfd=%d fd=%d\n", oldfd, fd); + } + assert(fd == 1); + close(oldfd); +#endif + } + + +#if 0 + /// Reduce each timer in the set across all processes and update + /// each timer with the reduction information. + void CactusTimerSet::reduce() + { + // Collect timer names that each process has + + // Construct union of all timer names, sort canonically and assign + // integer identifiers + + // For each timer, identify which processes have that timer + + // Reduce the timer across all those processes (return to root proc only) + + serialise(cout); + } + + ostream& CactusTimerSet::serialise(ostream &os) + { + for (timers_t::const_iterator + itimer = timers.begin(); itimer != timers.end(); ++itimer) + { + (*itimer)->serialise(os); + os << endl; + } + return os; + } +#endif + +} // namespace Carpet |