profiler.c 7.8 KB
Newer Older
1 2
/*******************************************************************************
 * This file is part of SWIFT.
Matthieu Schaller's avatar
Matthieu Schaller committed
3
 * Copyright (c) 2016 James S. Willis (james.s.willis@durham.ac.uk)
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 ******************************************************************************/

/* Config parameters. */
#include "../config.h"

/* Some standard headers. */
24
#include <math.h>
25 26 27
#include <string.h>

/* This object's header. */
28
#include "profiler.h"
29

30 31 32 33 34
/* Local includes */
#include "clocks.h"
#include "hydro.h"
#include "version.h"

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
/* Array to store the list of file names. Order must match profiler_types
 * enumerator and profiler_func_names. */
const char *profiler_file_names[profiler_length] = {"enginecollecttimesteps",
                                                    "enginedrift",
                                                    "enginerebuild",
                                                    "schedulerreweight",
                                                    "schedulerclearwaits",
                                                    "schedulerrewait",
                                                    "schedulerenqueue",
                                                    "engineprintstats",
                                                    "enginelaunch",
                                                    "spacerebuild",
                                                    "enginemaketasks",
                                                    "enginemarktasks",
                                                    "spaceregrid",
                                                    "spacepartssort",
                                                    "spacesplit",
                                                    "spacegetcellid",
                                                    "spacecountparts"};

/* Array to store the list of function names. Order must match profiler_types
 * enumerator and profiler_file_names. */
const char *profiler_func_names[profiler_length] = {"engine_collect_timesteps",
                                                    "engine_drift",
                                                    "engine_rebuild",
                                                    "scheduler_reweight",
                                                    "scheduler_clear_waits",
                                                    "scheduler_rewait",
                                                    "scheduler_enqueue",
                                                    "engine_print_stats",
                                                    "engine_launch",
                                                    "space_rebuild",
                                                    "engine_maketasks",
                                                    "engine_marktasks",
                                                    "space_regrid",
                                                    "space_parts_sort",
                                                    "space_split",
                                                    "space_get_cell_id",
                                                    "space_count_parts"};

75 76 77
/**
 * @brief Resets all timers.
 *
78
 * @param profiler #profiler object that holds file pointers and
James Willis's avatar
James Willis committed
79 80
 * function timers.
 */
81
void profiler_reset_timers(struct profiler *profiler) {
82 83
  /* Iterate over times array and reset values. */
  for (int i = 0; i < profiler_length; i++) profiler->times[i] = 0;
84 85
}

86 87 88 89 90 91
/**
 * @brief Opens an output file and populates the header.
 *
 * @param e #engine object to get various properties.
 * @param fileName name of file to be written to.
 * @param functionName name of function that is being timed.
92
 * @param file (return) pointer used to open output file.
James Willis's avatar
James Willis committed
93
 */
94 95 96
void profiler_write_timing_info_header(const struct engine *e,
                                       const char *fileName,
                                       const char *functionName, FILE **file) {
97

98
  /* Create the file name in the format: "fileName_(no. of threads)" */
99
  char fullFileName[200] = "";
James Willis's avatar
James Willis committed
100 101
  sprintf(fullFileName + strlen(fullFileName), "%s_%d.txt", fileName,
          e->nr_nodes * e->nr_threads);
102

103
  /* Open the file and write the header. */
104 105
  *file = fopen(fullFileName, "w");
  fprintf(*file,
James Willis's avatar
James Willis committed
106 107 108 109 110
          "# Host: %s\n# Branch: %s\n# Revision: %s\n# Compiler: %s, "
          "Version: %s \n# "
          "Number of threads: %d\n# Number of MPI ranks: %d\n# Hydrodynamic "
          "scheme: %s\n# Hydrodynamic kernel: %s\n# No. of neighbours: %.2f "
          "+/- %.2f\n# Eta: %f\n"
111
          "# %6s %14s %14s %10s %10s %10s %16s [%s]\n",
James Willis's avatar
James Willis committed
112 113 114 115 116
          hostname(), functionName, git_revision(), compiler_name(),
          compiler_version(), e->nr_threads, e->nr_nodes, SPH_IMPLEMENTATION,
          kernel_name, e->hydro_properties->target_neighbours,
          e->hydro_properties->delta_neighbours,
          e->hydro_properties->eta_neighbours, "Step", "Time", "Time-step",
117 118
          "Updates", "g-Updates", "s-Updates", "Wall-clock time",
          clocks_getunit());
119 120 121 122

  fflush(*file);
}

123
/**
James Willis's avatar
James Willis committed
124 125
 * @brief Writes the headers for all output files. Should be called once at the
 * start of the simulation, it could be called in engine_init() for example.
126 127
 *
 * @param e #engine object to get various properties.
128
 * @param profiler #profiler object that holds file pointers and
James Willis's avatar
James Willis committed
129 130
 * function timers.
 */
131
void profiler_write_all_timing_info_headers(const struct engine *e,
James Willis's avatar
James Willis committed
132
                                            struct profiler *profiler) {
133 134 135 136 137
  /* Iterate over files array and write file headers. */
  for (int i = 0; i < profiler_length; i++) {
    profiler_write_timing_info_header(
        e, profiler_file_names[i], profiler_func_names[i], &profiler->files[i]);
  }
138 139
}

140 141 142 143
/**
 * @brief Writes timing info to the output file.
 *
 * @param e #engine object to get various properties.
144 145
 * @param time Time in ticks to be written to the output file.
 * @param file pointer used to open output file.
James Willis's avatar
James Willis committed
146
 */
147 148
void profiler_write_timing_info(const struct engine *e, ticks time,
                                FILE *file) {
149

150 151
  fprintf(file, "  %6d %14e %14e %10lld %10lld %10lld %21.3f\n", e->step,
          e->time, e->time_step, e->updates, e->g_updates, e->s_updates,
152
          clocks_from_ticks(time));
153
  fflush(file);
154 155
}

156
/**
James Willis's avatar
James Willis committed
157 158
 * @brief Writes timing info to all output files. Should be called at the end of
 * every time step, in engine_step() for example.
159 160
 *
 * @param e #engine object to get various properties.
161
 * @param profiler #profiler object that holds file pointers and
James Willis's avatar
James Willis committed
162 163
 * function timers.
 */
164
void profiler_write_all_timing_info(const struct engine *e,
James Willis's avatar
James Willis committed
165 166
                                    struct profiler *profiler) {

167 168 169 170
  /* Iterate over times array and print timing info to files. */
  for (int i = 0; i < profiler_length; i++) {
    profiler_write_timing_info(e, profiler->times[i], profiler->files[i]);
  }
171
  /* Reset timers. */
James Willis's avatar
James Willis committed
172
  profiler_reset_timers(profiler);
173
}
174 175

/**
James Willis's avatar
James Willis committed
176 177
 * @brief Closes all output files, should be called at the end of the
 * simulation.
178
 *
179
 * @param profiler #profiler object that holds file pointers and
James Willis's avatar
James Willis committed
180 181
 * function timers.
 */
182 183
void profiler_close_files(struct profiler *profiler) {

184 185
  /* Iterate over files array and close files. */
  for (int i = 0; i < profiler_length; i++) fclose(profiler->files[i]);
186
}