fxt.c 7.9 KB

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