fxt.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2012 Université de Bordeaux 1
  4. * Copyright (C) 2010, 2011, 2012 Centre National de la Recherche Scientifique
  5. *
  6. * StarPU is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation; either version 2.1 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * StarPU is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  14. *
  15. * See the GNU Lesser General Public License in COPYING.LGPL for more details.
  16. */
  17. #include <starpu.h>
  18. #include <common/config.h>
  19. #include <common/utils.h>
  20. #include <starpu_util.h>
  21. #include <starpu_profiling.h>
  22. #ifdef STARPU_USE_FXT
  23. #include <common/fxt.h>
  24. #include <starpu_fxt.h>
  25. #ifdef STARPU_HAVE_WINDOWS
  26. #include <windows.h>
  27. #endif
  28. #ifdef __linux__
  29. #include <sys/syscall.h> /* for SYS_gettid */
  30. #elif defined(__FreeBSD__)
  31. #include <sys/thr.h> /* for thr_self() */
  32. #endif
  33. #define _STARPU_PROF_BUFFER_SIZE (8*1024*1024)
  34. static char _STARPU_PROF_FILE_USER[128];
  35. static int _starpu_fxt_started = 0;
  36. static int _starpu_written = 0;
  37. static int _starpu_id;
  38. long _starpu_gettid()
  39. {
  40. #if defined(__linux__)
  41. return syscall(SYS_gettid);
  42. #elif defined(__FreeBSD__)
  43. long tid;
  44. thr_self(&tid);
  45. return tid;
  46. #else
  47. return (long) pthread_self();
  48. #endif
  49. }
  50. static void _starpu_profile_set_tracefile(void *last, ...)
  51. {
  52. va_list vl;
  53. char *user;
  54. char *fxt_prefix = getenv("STARPU_FXT_PREFIX");
  55. if (!fxt_prefix)
  56. fxt_prefix = "/tmp/";
  57. va_start(vl, last);
  58. vsprintf(_STARPU_PROF_FILE_USER, fxt_prefix, vl);
  59. va_end(vl);
  60. user = getenv("USER");
  61. if (!user)
  62. user = "";
  63. char suffix[128];
  64. snprintf(suffix, 128, "prof_file_%s_%d", user, _starpu_id);
  65. strcat(_STARPU_PROF_FILE_USER, suffix);
  66. }
  67. void starpu_set_profiling_id(int new_id)
  68. {
  69. _STARPU_DEBUG("Set id to <%d>\n", new_id);
  70. _starpu_id = new_id;
  71. _starpu_profile_set_tracefile(NULL);
  72. }
  73. void _starpu_start_fxt_profiling(void)
  74. {
  75. unsigned threadid;
  76. if (!_starpu_fxt_started)
  77. {
  78. _starpu_fxt_started = 1;
  79. _starpu_profile_set_tracefile(NULL);
  80. }
  81. #ifdef HAVE_FUT_SET_FILENAME
  82. fut_set_filename(_STARPU_PROF_FILE_USER);
  83. #endif
  84. #ifdef HAVE_ENABLE_FUT_FLUSH
  85. // when the event buffer is full, fxt stops recording events.
  86. // The trace may thus be incomplete.
  87. // Enable the fut_flush function which is called when the
  88. // fxt event buffer is full to flush the buffer to disk,
  89. // therefore allowing to record the remaining events.
  90. enable_fut_flush();
  91. #endif
  92. threadid = _starpu_gettid();
  93. atexit(_starpu_stop_fxt_profiling);
  94. if (fut_setup(_STARPU_PROF_BUFFER_SIZE, FUT_KEYMASKALL, threadid) < 0)
  95. {
  96. perror("fut_setup");
  97. STARPU_ABORT();
  98. }
  99. fut_keychange(FUT_ENABLE, FUT_KEYMASKALL, threadid);
  100. return;
  101. }
  102. static void _starpu_generate_paje_trace(char *input_fxt_filename, char *output_paje_filename)
  103. {
  104. /* We take default options */
  105. struct starpu_fxt_options options;
  106. starpu_fxt_options_init(&options);
  107. /* TODO parse some STARPU_GENERATE_TRACE_OPTIONS env variable */
  108. options.ninputfiles = 1;
  109. options.filenames[0] = input_fxt_filename;
  110. options.out_paje_path = output_paje_filename;
  111. options.file_prefix = "";
  112. options.file_rank = -1;
  113. starpu_fxt_generate_trace(&options);
  114. }
  115. void _starpu_stop_fxt_profiling(void)
  116. {
  117. if (!_starpu_written)
  118. {
  119. #ifdef STARPU_VERBOSE
  120. char hostname[128];
  121. gethostname(hostname, 128);
  122. fprintf(stderr, "Writing FxT traces into file %s:%s\n", hostname, _STARPU_PROF_FILE_USER);
  123. #endif
  124. fut_endup(_STARPU_PROF_FILE_USER);
  125. /* Should we generate a Paje trace directly ? */
  126. int generate_trace = starpu_get_env_number("STARPU_GENERATE_TRACE");
  127. if (generate_trace == 1)
  128. _starpu_generate_paje_trace(_STARPU_PROF_FILE_USER, "paje.trace");
  129. int ret = fut_done();
  130. if (ret < 0)
  131. {
  132. /* Something went wrong with the FxT trace (eg. there
  133. * was too many events) */
  134. fprintf(stderr, "Warning: the FxT trace could not be generated properly\n");
  135. }
  136. _starpu_written = 1;
  137. }
  138. }
  139. void _starpu_fxt_register_thread(unsigned cpuid)
  140. {
  141. FUT_DO_PROBE2(FUT_NEW_LWP_CODE, cpuid, _starpu_gettid());
  142. }
  143. #endif // STARPU_USE_FXT
  144. void starpu_trace_user_event(unsigned long code STARPU_ATTRIBUTE_UNUSED)
  145. {
  146. #ifdef STARPU_USE_FXT
  147. _STARPU_TRACE_USER_EVENT(code);
  148. #endif
  149. }