| File: | /home/sbrandt/cactus/Cactus/arrangements/Carpet/Carpet/src/TimerSet.cc |
| 1 | :#include <cassert>
|
| 2 | :#include <cstdio>
|
| 3 | :#include <cstring>
|
| 4 | :#include <list>
|
| 5 | :
|
| 6 | :#include <cctk.h>
|
| 7 | :#include <cctk_Parameters.h>
|
| 8 | :#include <util_String.h>
|
| 9 | :
|
| 10 | :#if HAVE_UNISTD_H
|
| 11 | :# include <fcntl.h>
|
| 12 | :# include <unistd.h>
|
| 13 | :#endif
|
| 14 | :
|
| 15 | :#include <defs.hh>
|
| 16 | :
|
| 17 | :#include <Timers.hh>
|
| 18 | :#include <CactusTimer.hh>
|
| 19 | :#include <TimerNode.hh>
|
| 20 | :#include <TimerSet.hh>
|
| 21 | :
|
| 22 | :namespace Carpet {
|
| 23 | :
|
| 24 | : using namespace std;
|
| 25 | :
|
| 26 | : // A global timer set
|
| 27 | : TimerSet timerSet;
|
| 28 | :
|
| 29 | : // Add a timer
|
| 30 | : void
|
| 31 | : TimerSet::add (CactusTimer * const timer)
|
| 32 | : {
|
| 33 | : timers.push_back (timer);
|
| 34 | : }
|
| 35 | :
|
| 36 | : // Remove a timer
|
| 37 | : void
|
| 38 | : TimerSet::remove (CactusTimer * const timer)
|
| 39 | : {
|
| 40 | : timers.remove (timer);
|
| 41 | : }
|
| 42 | :
|
| 43 | : // Print all timer names
|
| 44 | : void
|
| 45 | : TimerSet::printNames ()
|
| 46 | : const
|
| 47 | : {
|
| 48 | : printf ("Timer names:\n");
|
| 49 | : int n = 0;
|
| 50 | : for (list <CactusTimer *>::const_iterator
|
| 51 | : itimer = timers.begin(); itimer != timers.end(); ++ itimer)
|
| 52 | : {
|
| 53 | : printf (" [%4d] %s\n", n, (* itimer)->name().c_str());
|
| 54 | : ++ n;
|
| 55 | : }
|
| 56 | : }
|
| 57 | :
|
| 58 | : // Print all timer data
|
| 59 | : void
|
| 60 | : TimerSet::printData ()
|
| 61 | : {
|
| 62 | : for (list <CactusTimer *>::const_iterator
|
| 63 | : itimer = timers.begin(); itimer != timers.end(); ++ itimer)
|
| 64 | : {
|
| 65 | : (* itimer)->printData ();
|
| 66 | : }
|
| 67 | : printf ("\n");
|
| 68 | : }
|
| 69 | :
|
| 70 | : // Print all timer data
|
| 71 | : void
|
| 72 | : TimerSet::writeData (cGH const * const cctkGH,
|
| 73 | : char const * const filename)
|
| 74 | : {
|
| 75 | : int const oldfd = redirect (cctkGH, filename);
|
| 76 | :#if 0
|
| 77 | : printf ("********************************************************************************\n");
|
| 78 | :#endif
|
| 79 | : printf ("# Carpet timing information at iteration %d time %g:\n",
|
| 80 | : cctkGH->cctk_iteration, (double) cctkGH->cctk_time);
|
| 81 | : timerSet.printData ();
|
| 82 | : unredirect (oldfd);
|
| 83 | : }
|
| 84 | :
|
| 85 | : // If filename is not empty, then redirect stdout to a file
|
| 86 | : int
|
| 87 | : TimerSet::redirect (cGH const * const cctkGH,
|
| 88 | : char const * const filename)
|
| 89 | : {
|
| 90 | : DECLARE_CCTK_PARAMETERS;
|
| 91 | :
|
| 92 | : if (CCTK_EQUALS (filename, "")) {
|
| 93 | : return -1;
|
| 94 | : }
|
| 95 | :
|
| 96 | :#ifndef HAVE_UNISTD_H
|
| 97 | : CCTK_WARN (1, "Cannot redirect timer output to a file; the operating system does not support this");
|
| 98 | : return -1;
|
| 99 | :#else
|
| 100 | :
|
| 101 | : int const myproc = CCTK_MyProc (cctkGH);
|
| 102 | : char fullname [10000];
|
| 103 | : Util_snprintf (fullname, sizeof fullname,
|
| 104 | : "%s/%s.%04d.txt", out_dir, filename, myproc);
|
| 105 | :
|
| 106 | : int flags = O_WRONLY | O_CREAT | O_APPEND; // append
|
| 107 | : static bool first_time = true;
|
| 108 | : if (first_time) {
|
| 109 | : first_time = false;
|
| 110 | : if (IO_TruncateOutputFiles (cctkGH)) {
|
| 111 | : flags = O_WRONLY | O_CREAT | O_TRUNC; // truncate
|
| 112 | : }
|
| 113 | : }
|
| 114 | :
|
| 115 | : // Temporarily redirect stdout
|
| 116 | : fflush (stdout);
|
| 117 | : int const oldfd = dup (1); // fd 1 is stdout
|
| 118 | : int const mode = 0644; // rw-r--r--, or a+r u+w
|
| 119 | : int const fdfile = open (fullname, flags, mode);
|
| 120 | : if (fdfile < 0) {
|
| 121 | : CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING,
|
| 122 | : "Could not open timer output file \"%s\"", fullname);
|
| 123 | : close (oldfd);
|
| 124 | : return -1;
|
| 125 | : }
|
| 126 | : // close (1);
|
| 127 | : // int const fd = dup (fdfile); // dup to 1, i.e., stdout again
|
| 128 | : int const fd = dup2 (fdfile, 1); // dup to 1, i.e., stdout again
|
| 129 | : assert (fd == 1);
|
| 130 | : close (fdfile);
|
| 131 | : return oldfd;
|
| 132 | :#endif
|
| 133 | : }
|
| 134 | :
|
| 135 | : // Redirect stdout back
|
| 136 | : void
|
| 137 | : TimerSet::unredirect (int const oldfd)
|
| 138 | : {
|
| 139 | : if (oldfd < 0) return;
|
| 140 | :
|
| 141 | :#ifdef HAVE_UNISTD_H
|
| 142 | : fflush (stdout);
|
| 143 | : // close (1);
|
| 144 | : // int const fd = dup (oldfd);
|
| 145 | : int const fd = dup2 (oldfd, 1);
|
| 146 | : if (not (fd == 1)) {
|
| 147 | : fprintf(stderr, "oldfd=%d fd=%d\n", oldfd, fd);
|
| 148 | : }
|
| 149 | : assert (fd == 1);
|
| 150 | : close (oldfd);
|
| 151 | :#endif
|
| 152 | : }
|
| 153 | :
|
| 154 | :
|
| 155 | : /// Reduce each timers in the set across all processes and update
|
| 156 | : /// each timer with the reduction information.
|
| 157 | : void TimerSet::reduce()
|
| 158 | : {
|
| 159 | : // Collect timer names that each process has
|
| 160 | :
|
| 161 | : // Construct union of all timer names, sort canonically and assign
|
| 162 | : // integer identifiers
|
| 163 | :
|
| 164 | : // For each timer, identify which processes have that timer
|
| 165 | :
|
| 166 | : // Reduce the timer across all those processes (return to root proc only)
|
| 167 | :
|
| 168 | : serialise(cout);
|
| 169 | : }
|
| 170 | :
|
| 171 | : ostream& TimerSet::serialise(ostream &os)
|
| 172 | : {
|
| 173 | : for (list <CactusTimer *>::const_iterator
|
| 174 | : itimer = timers.begin(); itimer != timers.end(); ++ itimer)
|
| 175 | : {
|
| 176 | : (*itimer)->serialise(os);
|
| 177 | : os << endl;
|
| 178 | : }
|
| 179 | : return os;
|
| 180 | : }
|
| 181 | :
|
| 182 | :/*
|
| 183 | :
|
| 184 | :
|
| 185 | :Each process has a list of (string,real) pairs. I want to return a
|
| 186 | :list of these where the reals have been reduced using a reduction
|
| 187 | :operator. Not all processes have the same strings present.
|
| 188 | : */
|
| 189 | :
|
| 190 | :} // namespace Carpet
|