fxt.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2008-2020 Université de Bordeaux, CNRS (LaBRI UMR 5800), Inria
  4. *
  5. * StarPU is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU Lesser General Public License as published by
  7. * the Free Software Foundation; either version 2.1 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * StarPU is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. *
  14. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  15. */
  16. #include <starpu.h>
  17. #include <common/config.h>
  18. #include <common/utils.h>
  19. #include <core/simgrid.h>
  20. #include <starpu_util.h>
  21. #include <starpu_profiling.h>
  22. /* we need to identify each task to generate the DAG. */
  23. unsigned long _starpu_job_cnt = 0;
  24. #ifdef STARPU_USE_FXT
  25. #include <common/fxt.h>
  26. #include <starpu_fxt.h>
  27. #ifdef STARPU_HAVE_WINDOWS
  28. #include <windows.h>
  29. #endif
  30. #ifdef __linux__
  31. #include <sys/syscall.h> /* for SYS_gettid */
  32. #elif defined(__FreeBSD__)
  33. #include <sys/thr.h> /* for thr_self() */
  34. #endif
  35. static char _STARPU_PROF_FILE_USER[128];
  36. int _starpu_fxt_started = 0;
  37. int _starpu_fxt_willstart = 1;
  38. starpu_pthread_mutex_t _starpu_fxt_started_mutex = STARPU_PTHREAD_MUTEX_INITIALIZER;
  39. starpu_pthread_cond_t _starpu_fxt_started_cond = STARPU_PTHREAD_COND_INITIALIZER;
  40. /* and their submission order. */
  41. unsigned long _starpu_submit_order = 0;
  42. static int _starpu_written = 0;
  43. static int _starpu_id;
  44. static unsigned int initial_key_mask = FUT_KEYMASKALL;
  45. #ifdef STARPU_SIMGRID
  46. /* Give virtual time to FxT */
  47. uint64_t fut_getstamp(void)
  48. {
  49. return starpu_timing_now()*1000.;
  50. }
  51. #endif
  52. long _starpu_gettid(void)
  53. {
  54. /* TODO: test at configure whether __thread is available, and use that
  55. * to cache the value.
  56. * Don't use the TSD, this is getting called before we would have the
  57. * time to allocate it. */
  58. #ifdef STARPU_SIMGRID
  59. # ifdef HAVE_SG_ACTOR_SELF
  60. return (uintptr_t) sg_actor_self();
  61. # else
  62. return (uintptr_t) MSG_process_self();
  63. # endif
  64. #else
  65. #if defined(__linux__)
  66. return syscall(SYS_gettid);
  67. #elif defined(__FreeBSD__)
  68. long tid;
  69. thr_self(&tid);
  70. return tid;
  71. #elif defined(_WIN32) && !defined(__CYGWIN__)
  72. return (long) GetCurrentThreadId();
  73. #else
  74. return (long) starpu_pthread_self();
  75. #endif
  76. #endif
  77. }
  78. static void _starpu_profile_set_tracefile(void)
  79. {
  80. char *user;
  81. char *fxt_prefix = starpu_getenv("STARPU_FXT_PREFIX");
  82. if (!fxt_prefix)
  83. fxt_prefix = "/tmp/";
  84. user = starpu_getenv("USER");
  85. if (!user)
  86. user = "";
  87. char suffix[128];
  88. snprintf(suffix, sizeof(suffix), "prof_file_%s_%d", user, _starpu_id);
  89. snprintf(_STARPU_PROF_FILE_USER, sizeof(_STARPU_PROF_FILE_USER), "%s%s", fxt_prefix, suffix);
  90. }
  91. void starpu_profiling_set_id(int new_id)
  92. {
  93. _STARPU_DEBUG("Set id to <%d>\n", new_id);
  94. _starpu_id = new_id;
  95. _starpu_profile_set_tracefile();
  96. #ifdef HAVE_FUT_SET_FILENAME
  97. fut_set_filename(_STARPU_PROF_FILE_USER);
  98. #endif
  99. }
  100. void starpu_fxt_autostart_profiling(int autostart)
  101. {
  102. if (autostart)
  103. initial_key_mask = FUT_KEYMASKALL;
  104. else
  105. initial_key_mask = _STARPU_FUT_KEYMASK_META;
  106. }
  107. void starpu_fxt_start_profiling()
  108. {
  109. unsigned threadid = _starpu_gettid();
  110. fut_keychange(FUT_ENABLE, FUT_KEYMASKALL, threadid);
  111. _STARPU_TRACE_META("start_profiling");
  112. }
  113. void starpu_fxt_stop_profiling()
  114. {
  115. unsigned threadid = _starpu_gettid();
  116. _STARPU_TRACE_META("stop_profiling");
  117. fut_keychange(FUT_SETMASK, _STARPU_FUT_KEYMASK_META, threadid);
  118. }
  119. int starpu_fxt_is_enabled()
  120. {
  121. return starpu_get_env_number_default("STARPU_FXT_TRACE", 1);
  122. }
  123. #ifdef HAVE_FUT_SETUP_FLUSH_CALLBACK
  124. void _starpu_fxt_flush_callback()
  125. {
  126. _STARPU_MSG("FxT is flushing trace to disk ! This can impact performance.\n");
  127. _STARPU_MSG("Maybe you should increase the value of STARPU_TRACE_BUFFER_SIZE ?\n");
  128. starpu_fxt_trace_user_event_string("fxt flush");
  129. }
  130. #endif
  131. void _starpu_fxt_init_profiling(uint64_t trace_buffer_size)
  132. {
  133. unsigned threadid;
  134. STARPU_PTHREAD_MUTEX_LOCK(&_starpu_fxt_started_mutex);
  135. if (!(_starpu_fxt_willstart = starpu_fxt_is_enabled()))
  136. {
  137. STARPU_PTHREAD_COND_BROADCAST(&_starpu_fxt_started_cond);
  138. STARPU_PTHREAD_MUTEX_UNLOCK(&_starpu_fxt_started_mutex);
  139. return;
  140. }
  141. STARPU_ASSERT(!_starpu_fxt_started);
  142. _starpu_fxt_started = 1;
  143. _starpu_written = 0;
  144. _starpu_profile_set_tracefile();
  145. #ifdef HAVE_FUT_SET_FILENAME
  146. fut_set_filename(_STARPU_PROF_FILE_USER);
  147. #endif
  148. #ifdef HAVE_ENABLE_FUT_FLUSH
  149. // when the event buffer is full, fxt stops recording events.
  150. // The trace may thus be incomplete.
  151. // Enable the fut_flush function which is called when the
  152. // fxt event buffer is full to flush the buffer to disk,
  153. // therefore allowing to record the remaining events.
  154. enable_fut_flush();
  155. #endif
  156. threadid = _starpu_gettid();
  157. #ifdef HAVE_FUT_SETUP_FLUSH_CALLBACK
  158. if (fut_setup_flush_callback(trace_buffer_size / sizeof(unsigned long), initial_key_mask, threadid, &_starpu_fxt_flush_callback) < 0)
  159. #else
  160. if (fut_setup(trace_buffer_size / sizeof(unsigned long), initial_key_mask, threadid) < 0)
  161. #endif
  162. {
  163. perror("fut_setup");
  164. STARPU_ABORT();
  165. }
  166. STARPU_PTHREAD_COND_BROADCAST(&_starpu_fxt_started_cond);
  167. STARPU_PTHREAD_MUTEX_UNLOCK(&_starpu_fxt_started_mutex);
  168. return;
  169. }
  170. static void _starpu_generate_paje_trace_read_option(const char *option, struct starpu_fxt_options *options)
  171. {
  172. if (strcmp(option, "-c") == 0)
  173. {
  174. options->per_task_colour = 1;
  175. }
  176. else if (strcmp(option, "-no-events") == 0)
  177. {
  178. options->no_events = 1;
  179. }
  180. else if (strcmp(option, "-no-counter") == 0)
  181. {
  182. options->no_counter = 1;
  183. }
  184. else if (strcmp(option, "-no-bus") == 0)
  185. {
  186. options->no_bus = 1;
  187. }
  188. else if (strcmp(option, "-no-flops") == 0)
  189. {
  190. options->no_flops = 1;
  191. }
  192. else if (strcmp(option, "-no-smooth") == 0)
  193. {
  194. options->no_smooth = 1;
  195. }
  196. else if (strcmp(option, "-no-acquire") == 0)
  197. {
  198. options->no_acquire = 1;
  199. }
  200. else if (strcmp(option, "-memory-states") == 0)
  201. {
  202. options->memory_states = 1;
  203. }
  204. else if (strcmp(option, "-internal") == 0)
  205. {
  206. options->internal = 1;
  207. }
  208. else if (strcmp(option, "-label-deps") == 0)
  209. {
  210. options->label_deps = 1;
  211. }
  212. else
  213. {
  214. _STARPU_MSG("Option <%s> is not a valid option for starpu_fxt_tool\n", option);
  215. }
  216. }
  217. static void _starpu_generate_paje_trace(char *input_fxt_filename, char *output_paje_filename)
  218. {
  219. /* We take default options */
  220. struct starpu_fxt_options options;
  221. starpu_fxt_options_init(&options);
  222. char *trace_options = starpu_getenv("STARPU_GENERATE_TRACE_OPTIONS");
  223. if (trace_options)
  224. {
  225. char *option = strtok(trace_options, " ");
  226. while (option)
  227. {
  228. _starpu_generate_paje_trace_read_option(option, &options);
  229. option = strtok(NULL, " ");
  230. }
  231. }
  232. options.ninputfiles = 1;
  233. options.filenames[0] = input_fxt_filename;
  234. options.out_paje_path = output_paje_filename;
  235. options.file_prefix = "";
  236. options.file_rank = -1;
  237. starpu_fxt_generate_trace(&options);
  238. }
  239. void _starpu_fxt_dump_file(void)
  240. {
  241. if (!_starpu_fxt_started)
  242. return;
  243. #ifdef STARPU_VERBOSE
  244. _STARPU_MSG("Writing FxT traces into file %s\n", _STARPU_PROF_FILE_USER);
  245. #endif
  246. fut_endup(_STARPU_PROF_FILE_USER);
  247. }
  248. void _starpu_stop_fxt_profiling(void)
  249. {
  250. if (!_starpu_fxt_started)
  251. return;
  252. if (!_starpu_written)
  253. {
  254. #ifdef STARPU_VERBOSE
  255. char hostname[128];
  256. gethostname(hostname, 128);
  257. _STARPU_MSG("Writing FxT traces into file %s:%s\n", hostname, _STARPU_PROF_FILE_USER);
  258. #endif
  259. fut_endup(_STARPU_PROF_FILE_USER);
  260. /* Should we generate a Paje trace directly ? */
  261. int generate_trace = starpu_get_env_number("STARPU_GENERATE_TRACE");
  262. if (generate_trace == 1)
  263. _starpu_generate_paje_trace(_STARPU_PROF_FILE_USER, "paje.trace");
  264. int ret = fut_done();
  265. if (ret < 0)
  266. {
  267. /* Something went wrong with the FxT trace (eg. there
  268. * was too many events) */
  269. _STARPU_MSG("Warning: the FxT trace could not be generated properly\n");
  270. }
  271. _starpu_written = 1;
  272. _starpu_fxt_started = 0;
  273. }
  274. }
  275. #else // STARPU_USE_FXT
  276. void starpu_fxt_autostart_profiling(int autostart STARPU_ATTRIBUTE_UNUSED)
  277. {
  278. }
  279. void starpu_fxt_start_profiling()
  280. {
  281. }
  282. void starpu_fxt_stop_profiling()
  283. {
  284. }
  285. #endif // STARPU_USE_FXT
  286. void starpu_fxt_trace_user_event(unsigned long code STARPU_ATTRIBUTE_UNUSED)
  287. {
  288. #ifdef STARPU_USE_FXT
  289. _STARPU_TRACE_USER_EVENT(code);
  290. #endif
  291. }
  292. void starpu_fxt_trace_user_event_string(const char *s STARPU_ATTRIBUTE_UNUSED)
  293. {
  294. #ifdef STARPU_USE_FXT
  295. _STARPU_TRACE_EVENT(s);
  296. #endif
  297. }