starpu_regression_display.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2011 Université de Bordeaux 1
  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 <assert.h>
  17. #include <unistd.h>
  18. #include <stdio.h>
  19. #include <starpu.h>
  20. #include <starpu_perfmodel.h>
  21. #include <core/perfmodel/perfmodel.h> // we need to browse the list associated to history-based models
  22. #ifdef __MINGW32__
  23. #include <windows.h>
  24. #endif
  25. static struct starpu_perfmodel_t model;
  26. /* what kernel ? */
  27. static char *symbol = NULL;
  28. /* which architecture ? (NULL = all)*/
  29. static char *arch = NULL;
  30. static struct starpu_fxt_codelet_event *dumped_codelets;
  31. static long dumped_codelets_count;
  32. static struct starpu_fxt_options options;
  33. static int archtype_is_found[STARPU_NARCH_VARIATIONS];
  34. static long dumped_per_archtype_count[STARPU_NARCH_VARIATIONS];
  35. static char data_file_name[256];
  36. static char gnuplot_file_name[256];
  37. static void usage(char **argv)
  38. {
  39. fprintf(stderr, "Usage: %s [ options ]\n", argv[0]);
  40. fprintf(stderr, "\n");
  41. fprintf(stderr, "One must specify a symbol with the -s option\n");
  42. fprintf(stderr, "Options:\n");
  43. fprintf(stderr, " -s <symbol> specify the symbol\n");
  44. fprintf(stderr, " -i <Fxt files> input FxT files generated by StarPU\n");
  45. fprintf(stderr, " -a <arch> specify the architecture (e.g. cpu, cpu:k, cuda, gordon)\n");
  46. fprintf(stderr, "\n");
  47. }
  48. static void parse_args(int argc, char **argv)
  49. {
  50. /* Default options */
  51. starpu_fxt_options_init(&options);
  52. options.out_paje_path = NULL;
  53. options.activity_path = NULL;
  54. options.distrib_time_path = NULL;
  55. options.dag_path = NULL;
  56. options.dumped_codelets = &dumped_codelets;
  57. /* We want to support arguments such as "-i trace_*" */
  58. unsigned reading_input_filenames = 0;
  59. int i;
  60. for (i = 1; i < argc; i++) {
  61. if (strcmp(argv[i], "-s") == 0) {
  62. symbol = argv[++i];
  63. continue;
  64. }
  65. if (strcmp(argv[i], "-i") == 0) {
  66. options.filenames[options.ninputfiles++] = argv[++i];
  67. reading_input_filenames = 1;
  68. continue;
  69. }
  70. if (strcmp(argv[i], "-a") == 0) {
  71. arch = argv[++i];
  72. continue;
  73. }
  74. if (strcmp(argv[i], "-h") == 0) {
  75. usage(argv);
  76. exit(-1);
  77. }
  78. /* If the reading_input_filenames flag is set, and that the
  79. * argument does not match an option, we assume this may be
  80. * another filename */
  81. if (reading_input_filenames)
  82. {
  83. options.filenames[options.ninputfiles++] = argv[i];
  84. continue;
  85. }
  86. }
  87. }
  88. static void display_perf_model(FILE *gnuplot_file, struct starpu_perfmodel_t *model, enum starpu_perf_archtype arch, int *first)
  89. {
  90. if (!archtype_is_found[arch])
  91. return;
  92. if (*first)
  93. {
  94. *first = 0;
  95. }
  96. else {
  97. fprintf(gnuplot_file, ",\\\n\t");
  98. }
  99. char arch_name[256];
  100. starpu_perfmodel_get_arch_name(arch, arch_name, 256);
  101. fprintf(gnuplot_file, "\"< grep -w \\^%d %s\" using 2:3 title \"%s\"", arch, data_file_name, arch_name);
  102. struct starpu_per_arch_perfmodel_t *arch_model = &model->per_arch[arch];
  103. /* Only display the regression model if we could actually build a model */
  104. if (arch_model->regression.valid)
  105. {
  106. fprintf(stderr, "\tLinear: y = alpha size ^ beta\n");
  107. fprintf(stderr, "\t\talpha = %le\n", arch_model->regression.alpha * 0.001);
  108. fprintf(stderr, "\t\tbeta = %le\n", arch_model->regression.beta);
  109. fprintf(gnuplot_file, ",\\\n\t");
  110. fprintf(gnuplot_file, "0.001 * %f * x ** %f title \"Linear Regression %s\"",
  111. arch_model->regression.alpha, arch_model->regression.beta, arch_name);
  112. }
  113. if (arch_model->regression.nl_valid)
  114. {
  115. fprintf(stderr, "\tNon-Linear: y = a size ^b + c\n");
  116. fprintf(stderr, "\t\ta = %le\n", arch_model->regression.a * 0.001);
  117. fprintf(stderr, "\t\tb = %le\n", arch_model->regression.b);
  118. fprintf(stderr, "\t\tc = %le\n", arch_model->regression.c * 0.001);
  119. fprintf(gnuplot_file, ",\\\n\t");
  120. fprintf(gnuplot_file, "0.001 * %f * x ** %f + 0.001 * %f title \"Non-Linear Regression %s\"",
  121. arch_model->regression.a, arch_model->regression.b, arch_model->regression.c, arch_name);
  122. }
  123. }
  124. static void dump_data_file(FILE *data_file)
  125. {
  126. memset(archtype_is_found, 0, STARPU_NARCH_VARIATIONS*sizeof(int));
  127. int i;
  128. for (i = 0; i < options.dumped_codelets_count; i++)
  129. {
  130. /* Dump only if the symbol matches user's request */
  131. if (strcmp(dumped_codelets[i].symbol, symbol) == 0) {
  132. int workerid = dumped_codelets[i].workerid;
  133. enum starpu_perf_archtype archtype = options.worker_archtypes[workerid];
  134. archtype_is_found[archtype] = 1;
  135. size_t size = dumped_codelets[i].size;
  136. float time = dumped_codelets[i].time;
  137. fprintf(data_file, "%d %f %f\n", archtype, (float)size, time);
  138. }
  139. }
  140. }
  141. static void display_selected_models(FILE *gnuplot_file, struct starpu_perfmodel_t *model)
  142. {
  143. fprintf(gnuplot_file, "#!/usr/bin/gnuplot -persist\n");
  144. fprintf(gnuplot_file, "\n");
  145. fprintf(gnuplot_file, "set term postscript eps enhanced color\n");
  146. fprintf(gnuplot_file, "set output \"regression_%s.eps\"\n", symbol);
  147. fprintf(gnuplot_file, "set title \"Model for codelet %s\"\n", symbol);
  148. fprintf(gnuplot_file, "set xlabel \"Size\"\n");
  149. fprintf(gnuplot_file, "set ylabel \"Time\"\n");
  150. fprintf(gnuplot_file, "\n");
  151. fprintf(gnuplot_file, "set logscale x\n");
  152. fprintf(gnuplot_file, "set logscale y\n");
  153. fprintf(gnuplot_file, "\n");
  154. int first = 1;
  155. fprintf(gnuplot_file, "plot\t");
  156. if (arch == NULL)
  157. {
  158. /* display all architectures */
  159. unsigned archid;
  160. for (archid = 0; archid < STARPU_NARCH_VARIATIONS; archid++)
  161. display_perf_model(gnuplot_file, model, archid, &first);
  162. }
  163. else {
  164. if (strcmp(arch, "cpu") == 0) {
  165. display_perf_model(gnuplot_file, model, STARPU_CPU_DEFAULT, &first);
  166. return;
  167. }
  168. int k;
  169. if (sscanf(arch, "cpu:%d", &k) == 1)
  170. {
  171. /* For combined CPU workers */
  172. if ((k < 1) || (k > STARPU_NMAXCPUS))
  173. {
  174. fprintf(stderr, "Invalid CPU size\n");
  175. exit(-1);
  176. }
  177. display_perf_model(gnuplot_file, model, STARPU_CPU_DEFAULT + k - 1, &first);
  178. return;
  179. }
  180. if (strcmp(arch, "cuda") == 0) {
  181. unsigned archid;
  182. for (archid = STARPU_CUDA_DEFAULT; archid < STARPU_CUDA_DEFAULT + STARPU_MAXCUDADEVS; archid++)
  183. {
  184. char archname[32];
  185. starpu_perfmodel_get_arch_name(archid, archname, 32);
  186. display_perf_model(gnuplot_file, model, archid, &first);
  187. }
  188. return;
  189. }
  190. /* There must be a cleaner way ! */
  191. int gpuid;
  192. int nmatched;
  193. nmatched = sscanf(arch, "cuda_%d", &gpuid);
  194. if (nmatched == 1)
  195. {
  196. unsigned archid = STARPU_CUDA_DEFAULT+ gpuid;
  197. display_perf_model(gnuplot_file, model, archid, &first);
  198. return;
  199. }
  200. if (strcmp(arch, "gordon") == 0) {
  201. display_perf_model(gnuplot_file, model, STARPU_GORDON_DEFAULT, &first);
  202. return;
  203. }
  204. fprintf(stderr, "Unknown architecture requested, aborting.\n");
  205. exit(-1);
  206. }
  207. }
  208. int main(int argc, char **argv)
  209. {
  210. #ifdef __MINGW32__
  211. WSADATA wsadata;
  212. WSAStartup(MAKEWORD(1,0), &wsadata);
  213. #endif
  214. parse_args(argc, argv);
  215. /* We need at least a symbol name */
  216. if (!symbol)
  217. {
  218. fprintf(stderr, "No symbol was specified\n");
  219. return 1;
  220. }
  221. /* Load the performance model associated to the symbol */
  222. int ret = starpu_load_history_debug(symbol, &model);
  223. if (ret == 1)
  224. {
  225. fprintf(stderr, "The performance model could not be loaded\n");
  226. return 1;
  227. }
  228. starpu_fxt_generate_trace(&options);
  229. snprintf(data_file_name, 256, "starpu_%s.data", symbol);
  230. snprintf(gnuplot_file_name, 256, "starpu_%s.gp", symbol);
  231. FILE *data_file = fopen(data_file_name, "w+");
  232. STARPU_ASSERT(data_file);
  233. dump_data_file(data_file);
  234. fclose(data_file);
  235. FILE *gnuplot_file = fopen(gnuplot_file_name, "w+");
  236. STARPU_ASSERT(gnuplot_file);
  237. display_selected_models(gnuplot_file, &model);
  238. fclose(gnuplot_file);
  239. return 0;
  240. }