starpu_fxt.c 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108
  1. /* StarPU --- Runtime system for heterogeneous multicore architectures.
  2. *
  3. * Copyright (C) 2009-2013 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 <starpu.h>
  17. #include <common/config.h>
  18. #include <common/uthash.h>
  19. #include <string.h>
  20. #ifdef STARPU_HAVE_POTI
  21. #include <poti.h>
  22. #define STARPU_POTI_STR_LEN 200
  23. #endif
  24. #ifdef STARPU_USE_FXT
  25. #include "starpu_fxt.h"
  26. #include <inttypes.h>
  27. #include <starpu_hash.h>
  28. static char *cpus_worker_colors[STARPU_NMAXWORKERS] = {"/greens9/7", "/greens9/6", "/greens9/5", "/greens9/4", "/greens9/9", "/greens9/3", "/greens9/2", "/greens9/1" };
  29. static char *cuda_worker_colors[STARPU_NMAXWORKERS] = {"/ylorrd9/9", "/ylorrd9/6", "/ylorrd9/3", "/ylorrd9/1", "/ylorrd9/8", "/ylorrd9/7", "/ylorrd9/4", "/ylorrd9/2", "/ylorrd9/1"};
  30. static char *opencl_worker_colors[STARPU_NMAXWORKERS] = {"/blues9/9", "/blues9/6", "/blues9/3", "/blues9/1", "/blues9/8", "/blues9/7", "/blues9/4", "/blues9/2", "/blues9/1"};
  31. static char *mic_worker_colors[STARPU_NMAXWORKERS] = {"/reds9/9", "/reds9/6", "/reds9/3", "/reds9/1", "/reds9/8", "/reds9/7", "/reds9/4", "/reds9/2", "/reds9/1"};
  32. static char *scc_worker_colors[STARPU_NMAXWORKERS] = {"/reds9/9", "/reds9/6", "/reds9/3", "/reds9/1", "/reds9/8", "/reds9/7", "/reds9/4", "/reds9/2", "/reds9/1"};
  33. static char *other_worker_colors[STARPU_NMAXWORKERS] = {"/greys9/9", "/greys9/8", "/greys9/7", "/greys9/6"};
  34. static char *worker_colors[STARPU_NMAXWORKERS];
  35. static unsigned opencl_index = 0;
  36. static unsigned cuda_index = 0;
  37. static unsigned cpus_index = 0;
  38. static unsigned mic_index = 0;
  39. static unsigned scc_index = 0;
  40. static unsigned other_index = 0;
  41. static void set_next_other_worker_color(int workerid)
  42. {
  43. worker_colors[workerid] = other_worker_colors[other_index++];
  44. }
  45. static void set_next_cpu_worker_color(int workerid)
  46. {
  47. worker_colors[workerid] = cpus_worker_colors[cpus_index++];
  48. }
  49. static void set_next_cuda_worker_color(int workerid)
  50. {
  51. worker_colors[workerid] = cuda_worker_colors[cuda_index++];
  52. }
  53. static void set_next_opencl_worker_color(int workerid)
  54. {
  55. worker_colors[workerid] = opencl_worker_colors[opencl_index++];
  56. }
  57. static void set_next_mic_worker_color(int workerid)
  58. {
  59. worker_colors[workerid] = mic_worker_colors[mic_index++];
  60. }
  61. static void set_next_scc_worker_color(int workerid)
  62. {
  63. worker_colors[workerid] = scc_worker_colors[scc_index++];
  64. }
  65. static const char *get_worker_color(int workerid)
  66. {
  67. return worker_colors[workerid];
  68. }
  69. static unsigned get_colour_symbol_red(char *name)
  70. {
  71. /* choose some colour ... that's disguting yes */
  72. uint32_t hash_symbol = starpu_hash_crc32c_string(name, 0);
  73. return (unsigned)starpu_hash_crc32c_string("red", hash_symbol) % 1024;
  74. }
  75. static unsigned get_colour_symbol_green(char *name)
  76. {
  77. /* choose some colour ... that's disguting yes */
  78. uint32_t hash_symbol = starpu_hash_crc32c_string(name, 0);
  79. return (unsigned)starpu_hash_crc32c_string("green", hash_symbol) % 1024;
  80. }
  81. static unsigned get_colour_symbol_blue(char *name)
  82. {
  83. /* choose some colour ... that's disguting yes */
  84. uint32_t hash_symbol = starpu_hash_crc32c_string(name, 0);
  85. return (unsigned)starpu_hash_crc32c_string("blue", hash_symbol) % 1024;
  86. }
  87. static double last_codelet_start[STARPU_NMAXWORKERS];
  88. static char last_codelet_symbol[STARPU_NMAXWORKERS][128];
  89. /* If more than a period of time has elapsed, we flush the profiling info,
  90. * otherwise they are accumulated everytime there is a new relevant event. */
  91. #define ACTIVITY_PERIOD 75.0
  92. static double last_activity_flush_timestamp[STARPU_NMAXWORKERS];
  93. static double accumulated_sleep_time[STARPU_NMAXWORKERS];
  94. static double accumulated_exec_time[STARPU_NMAXWORKERS];
  95. static double reclaiming[STARPU_MAXNODES];
  96. LIST_TYPE(_starpu_symbol_name,
  97. char *name;
  98. )
  99. static struct _starpu_symbol_name_list *symbol_list;
  100. LIST_TYPE(_starpu_communication,
  101. unsigned comid;
  102. double comm_start;
  103. double bandwidth;
  104. unsigned src_node;
  105. unsigned dst_node;
  106. )
  107. static struct _starpu_communication_list *communication_list;
  108. /*
  109. * Paje trace file tools
  110. */
  111. static FILE *out_paje_file;
  112. static FILE *distrib_time;
  113. static FILE *activity_file;
  114. /*
  115. * Generic tools
  116. */
  117. static double get_event_time_stamp(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  118. {
  119. return (((double)(ev->time-options->file_offset))/1000000.0);
  120. }
  121. static int nworkers = 0;
  122. struct worker_entry
  123. {
  124. UT_hash_handle hh;
  125. unsigned long tid;
  126. int workerid;
  127. } *worker_ids;
  128. static void register_worker_id(unsigned long tid, int workerid)
  129. {
  130. nworkers++;
  131. struct worker_entry *entry;
  132. HASH_FIND(hh, worker_ids, &tid, sizeof(tid), entry);
  133. STARPU_ASSERT_MSG(workerid < STARPU_NMAXWORKERS, "Too many workers in this trace, please increase in ./configure invocation the maximum number of CPUs and GPUs to the same value as was used for execution");
  134. /* only register a thread once */
  135. STARPU_ASSERT(entry == NULL);
  136. entry = malloc(sizeof(*entry));
  137. entry->tid = tid;
  138. entry->workerid = workerid;
  139. HASH_ADD(hh, worker_ids, tid, sizeof(tid), entry);
  140. }
  141. static int find_worker_id(unsigned long tid)
  142. {
  143. struct worker_entry *entry;
  144. HASH_FIND(hh, worker_ids, &tid, sizeof(tid), entry);
  145. if (!entry)
  146. return -1;
  147. return entry->workerid;
  148. }
  149. static void update_accumulated_time(int worker, double sleep_time, double exec_time, double current_timestamp, int forceflush)
  150. {
  151. accumulated_sleep_time[worker] += sleep_time;
  152. accumulated_exec_time[worker] += exec_time;
  153. /* If sufficient time has elapsed since the last flush, we have a new
  154. * point in our graph */
  155. double elapsed = current_timestamp - last_activity_flush_timestamp[worker];
  156. if (forceflush || (elapsed > ACTIVITY_PERIOD))
  157. {
  158. if (activity_file)
  159. fprintf(activity_file, "%d\t%.9f\t%.9f\t%.9f\t%.9f\n", worker, current_timestamp, elapsed, accumulated_exec_time[worker], accumulated_sleep_time[worker]);
  160. /* reset the accumulated times */
  161. last_activity_flush_timestamp[worker] = current_timestamp;
  162. accumulated_sleep_time[worker] = 0.0;
  163. accumulated_exec_time[worker] = 0.0;
  164. }
  165. }
  166. /*
  167. * Auxiliary functions for poti handling names
  168. */
  169. #ifdef STARPU_HAVE_POTI
  170. static char *memnode_container_alias(char *output, int len, const char *prefix, long unsigned int memnodeid)
  171. {
  172. snprintf(output, len, "%smn%lu", prefix, memnodeid);
  173. return output;
  174. }
  175. static char *memmanager_container_alias(char *output, int len, const char *prefix, long unsigned int memnodeid)
  176. {
  177. snprintf(output, len, "%smm%lu", prefix, memnodeid);
  178. return output;
  179. }
  180. static char *thread_container_alias(char *output, int len, const char *prefix, long unsigned int threadid)
  181. {
  182. snprintf(output, len, "%st%lu", prefix, threadid);
  183. return output;
  184. }
  185. static char *worker_container_alias(char *output, int len, const char *prefix, long unsigned int workerid)
  186. {
  187. snprintf(output, len, "%sw%lu", prefix, workerid);
  188. return output;
  189. }
  190. static char *mpicommthread_container_alias(char *output, int len, const char *prefix)
  191. {
  192. snprintf(output, len, "%smpict", prefix);
  193. return output;
  194. }
  195. static char *program_container_alias(char *output, int len, const char *prefix)
  196. {
  197. snprintf(output, len, "%sp", prefix);
  198. return output;
  199. }
  200. static char *scheduler_container_alias(char *output, int len, const char *prefix)
  201. {
  202. snprintf(output, len, "%ssched", prefix);
  203. return output;
  204. }
  205. #endif
  206. static void memnode_set_state(double time, const char *prefix, unsigned int memnodeid, const char *name)
  207. {
  208. #ifdef STARPU_HAVE_POTI
  209. char container[STARPU_POTI_STR_LEN];
  210. memmanager_container_alias(container, STARPU_POTI_STR_LEN, prefix, memnodeid);
  211. poti_SetState(time, container, "MS", name);
  212. #else
  213. fprintf(out_paje_file, "10 %.9f %smm%u MS %s\n", time, prefix, memnodeid, name);
  214. #endif
  215. }
  216. static void worker_set_state(double time, const char *prefix, long unsigned int workerid, const char *name)
  217. {
  218. #ifdef STARPU_HAVE_POTI
  219. char container[STARPU_POTI_STR_LEN];
  220. thread_container_alias(container, STARPU_POTI_STR_LEN, prefix, workerid);
  221. poti_SetState(time, container, "S", name);
  222. #else
  223. fprintf(out_paje_file, "10 %.9f %st%lu S %s\n", time, prefix, workerid, name);
  224. #endif
  225. }
  226. static void mpicommthread_set_state(double time, const char *prefix, const char *name)
  227. {
  228. #ifdef STARPU_HAVE_POTI
  229. char container[STARPU_POTI_STR_LEN];
  230. mpicommthread_container_alias(container, STARPU_POTI_STR_LEN, prefix);
  231. poti_SetState(time, container, "CtS", name);
  232. #else
  233. fprintf(out_paje_file, "10 %.9f %smpict CtS %s\n", time, prefix, name);
  234. #endif
  235. }
  236. /*
  237. * Initialization
  238. */
  239. static void handle_new_mem_node(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  240. {
  241. char *prefix = options->file_prefix;
  242. if (out_paje_file)
  243. {
  244. #ifdef STARPU_HAVE_POTI
  245. char program_container[STARPU_POTI_STR_LEN];
  246. program_container_alias(program_container, STARPU_POTI_STR_LEN, prefix);
  247. char new_memnode_container_alias[STARPU_POTI_STR_LEN], new_memnode_container_name[STARPU_POTI_STR_LEN];
  248. memnode_container_alias (new_memnode_container_alias, STARPU_POTI_STR_LEN, prefix, ev->param[0]);
  249. /* TODO: ramkind */
  250. snprintf(new_memnode_container_name, STARPU_POTI_STR_LEN, "%sMEMNODE%"PRIu64"", prefix, ev->param[0]);
  251. poti_CreateContainer(get_event_time_stamp(ev, options), new_memnode_container_alias, "Mn", program_container, new_memnode_container_name);
  252. memmanager_container_alias (new_memnode_container_alias, STARPU_POTI_STR_LEN, prefix, ev->param[0]);
  253. /* TODO: ramkind */
  254. snprintf(new_memnode_container_name, STARPU_POTI_STR_LEN, "%sMEMMANAGER%"PRIu64"", prefix, ev->param[0]);
  255. poti_CreateContainer(get_event_time_stamp(ev, options), new_memnode_container_alias, "Mm", new_memnode_container_alias, new_memnode_container_name);
  256. #else
  257. fprintf(out_paje_file, "7 %.9f %smn%"PRIu64" Mn %sp %sMEMNODE%"PRIu64"\n", get_event_time_stamp(ev, options), prefix, ev->param[0], prefix, options->file_prefix, ev->param[0]);
  258. fprintf(out_paje_file, "7 %.9f %smm%"PRIu64" Mm %sp %sMEMMANAGER%"PRIu64"\n", get_event_time_stamp(ev, options), prefix, ev->param[0], prefix, options->file_prefix, ev->param[0]);
  259. #endif
  260. if (!options->no_bus)
  261. #ifdef STARPU_HAVE_POTI
  262. poti_SetVariable(get_event_time_stamp(ev, options), new_memnode_container_alias, "bw", 0.0);
  263. #else
  264. fprintf(out_paje_file, "13 %.9f %smm%"PRIu64" bw 0.0\n", 0.0f, prefix, ev->param[0]);
  265. #endif
  266. }
  267. }
  268. static void handle_worker_init_start(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  269. {
  270. /*
  271. arg0 : type of worker (cuda, cpu ..)
  272. arg1 : memory node
  273. arg2 : thread id
  274. */
  275. char *prefix = options->file_prefix;
  276. int devid = ev->param[2];
  277. int workerid = ev->param[1];
  278. int nodeid = ev->param[3];
  279. int threadid = ev->param[4];
  280. register_worker_id(threadid, workerid);
  281. char *kindstr = "";
  282. struct starpu_perfmodel_arch arch;
  283. switch (ev->param[0])
  284. {
  285. case _STARPU_FUT_APPS_KEY:
  286. set_next_other_worker_color(workerid);
  287. kindstr = "APPS";
  288. break;
  289. case _STARPU_FUT_CPU_KEY:
  290. set_next_cpu_worker_color(workerid);
  291. kindstr = "CPU";
  292. arch.type = STARPU_CPU_WORKER;
  293. arch.devid = 0;
  294. arch.ncore = 0;
  295. break;
  296. case _STARPU_FUT_CUDA_KEY:
  297. set_next_cuda_worker_color(workerid);
  298. kindstr = "CUDA";
  299. arch.type = STARPU_CUDA_WORKER;
  300. arch.devid = devid;
  301. arch.ncore = 0;
  302. break;
  303. case _STARPU_FUT_OPENCL_KEY:
  304. set_next_opencl_worker_color(workerid);
  305. kindstr = "OPENCL";
  306. arch.type = STARPU_OPENCL_WORKER;
  307. arch.devid = devid;
  308. arch.ncore = 0;
  309. break;
  310. case _STARPU_FUT_MIC_KEY:
  311. set_next_mic_worker_color(workerid);
  312. kindstr = "mic";
  313. arch.type = STARPU_MIC_WORKER;
  314. arch.devid = devid;
  315. arch.ncore = 0;
  316. break;
  317. case _STARPU_FUT_SCC_KEY:
  318. set_next_scc_worker_color(workerid);
  319. kindstr = "scc";
  320. arch.type = STARPU_SCC_WORKER;
  321. arch.devid = devid;
  322. arch.ncore = 0;
  323. break;
  324. default:
  325. STARPU_ABORT();
  326. }
  327. if (out_paje_file)
  328. {
  329. #ifdef STARPU_HAVE_POTI
  330. char new_thread_container_alias[STARPU_POTI_STR_LEN];
  331. thread_container_alias (new_thread_container_alias, STARPU_POTI_STR_LEN, prefix, threadid);
  332. char new_worker_container_alias[STARPU_POTI_STR_LEN];
  333. worker_container_alias (new_worker_container_alias, STARPU_POTI_STR_LEN, prefix, workerid);
  334. char memnode_container[STARPU_POTI_STR_LEN];
  335. memnode_container_alias(memnode_container, STARPU_POTI_STR_LEN, prefix, nodeid);
  336. char new_thread_container_name[STARPU_POTI_STR_LEN];
  337. snprintf(new_thread_container_name, STARPU_POTI_STR_LEN, "%s%d", prefix, threadid);
  338. char new_worker_container_name[STARPU_POTI_STR_LEN];
  339. snprintf(new_worker_container_name, STARPU_POTI_STR_LEN, "%s%s%d", prefix, kindstr, devid);
  340. poti_CreateContainer(get_event_time_stamp(ev, options), new_thread_container_alias, "T", memnode_container, new_thread_container_name);
  341. poti_CreateContainer(get_event_time_stamp(ev, options), new_worker_container_alias, "W", new_thread_container_alias, new_worker_container_name);
  342. #else
  343. fprintf(out_paje_file, "7 %.9f %st%d T %smn%d %s%d\n",
  344. get_event_time_stamp(ev, options), prefix, threadid, prefix, nodeid, prefix, threadid);
  345. fprintf(out_paje_file, "7 %.9f %sw%d W %st%d %s%s%d\n",
  346. get_event_time_stamp(ev, options), prefix, workerid, prefix, threadid, prefix, kindstr, devid);
  347. #endif
  348. }
  349. /* start initialization */
  350. if (out_paje_file)
  351. worker_set_state(get_event_time_stamp(ev, options), prefix, threadid, "I");
  352. if (activity_file)
  353. fprintf(activity_file, "name\t%d\t%s %d\n", workerid, kindstr, devid);
  354. snprintf(options->worker_names[workerid], 256, "%s %d", kindstr, devid);
  355. options->worker_archtypes[workerid] = arch;
  356. }
  357. static void handle_worker_init_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  358. {
  359. char *prefix = options->file_prefix;
  360. if (out_paje_file)
  361. worker_set_state(get_event_time_stamp(ev, options), prefix, ev->param[0], "B");
  362. /* Initilize the accumulated time counters */
  363. int worker = find_worker_id(ev->param[0]);
  364. last_activity_flush_timestamp[worker] = get_event_time_stamp(ev, options);
  365. accumulated_sleep_time[worker] = 0.0;
  366. accumulated_exec_time[worker] = 0.0;
  367. }
  368. static void handle_worker_deinit_start(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  369. {
  370. char *prefix = options->file_prefix;
  371. if (out_paje_file)
  372. worker_set_state(get_event_time_stamp(ev, options), prefix, ev->param[0], "D");
  373. }
  374. static void handle_worker_deinit_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  375. {
  376. char *prefix = options->file_prefix;
  377. if (out_paje_file)
  378. {
  379. #ifdef STARPU_HAVE_POTI
  380. char worker_container[STARPU_POTI_STR_LEN];
  381. thread_container_alias(worker_container, STARPU_POTI_STR_LEN, prefix, ev->param[1]);
  382. poti_DestroyContainer(get_event_time_stamp(ev, options), "T", worker_container);
  383. #else
  384. fprintf(out_paje_file, "8 %.9f %st%"PRIu64" T\n",
  385. get_event_time_stamp(ev, options), prefix, ev->param[1]);
  386. #endif
  387. }
  388. }
  389. #ifdef STARPU_HAVE_POTI
  390. static void create_paje_state_color(char *name, char *type, float red, float green, float blue)
  391. {
  392. char color[STARPU_POTI_STR_LEN];
  393. snprintf(color, STARPU_POTI_STR_LEN, "%f %f %f", red, green, blue);
  394. poti_DefineEntityValue(name, type, name, color);
  395. }
  396. #endif
  397. static void create_paje_state_if_not_found(char *name, struct starpu_fxt_options *options)
  398. {
  399. struct _starpu_symbol_name *itor;
  400. for (itor = _starpu_symbol_name_list_begin(symbol_list);
  401. itor != _starpu_symbol_name_list_end(symbol_list);
  402. itor = _starpu_symbol_name_list_next(itor))
  403. {
  404. if (!strcmp(name, itor->name))
  405. {
  406. /* we found an entry */
  407. return;
  408. }
  409. }
  410. /* it's the first time ... */
  411. struct _starpu_symbol_name *entry = _starpu_symbol_name_new();
  412. entry->name = malloc(strlen(name));
  413. strcpy(entry->name, name);
  414. _starpu_symbol_name_list_push_front(symbol_list, entry);
  415. /* choose some colour ... that's disguting yes */
  416. unsigned hash_symbol_red = get_colour_symbol_red(name);
  417. unsigned hash_symbol_green = get_colour_symbol_green(name);
  418. unsigned hash_symbol_blue = get_colour_symbol_blue(name);
  419. uint32_t hash_sum = hash_symbol_red + hash_symbol_green + hash_symbol_blue;
  420. float red, green, blue;
  421. if (options->per_task_colour)
  422. {
  423. red = (1.0f * hash_symbol_red) / hash_sum;
  424. green = (1.0f * hash_symbol_green) / hash_sum;
  425. blue = (1.0f * hash_symbol_blue) / hash_sum;
  426. }
  427. else
  428. {
  429. /* Use the hardcoded value for execution mode */
  430. red = 0.0f;
  431. green = 0.6f;
  432. blue = 0.4f;
  433. }
  434. /* create the Paje state */
  435. if (out_paje_file)
  436. {
  437. #ifdef STARPU_HAVE_POTI
  438. create_paje_state_color(name, "S", red, green, blue);
  439. create_paje_state_color(name, "Ctx1", 255.0, 102.0, 255.0);
  440. create_paje_state_color(name, "Ctx2", .0, 255.0, 0.0);
  441. create_paje_state_color(name, "Ctx3", 255.0, 255.0, .0);
  442. create_paje_state_color(name, "Ctx4", .0, 245.0, 255.0);
  443. create_paje_state_color(name, "Ctx5", .0, .0, .0);
  444. create_paje_state_color(name, "Ctx6", .0, .0, 128.0);
  445. create_paje_state_color(name, "Ctx7", 105.0, 105.0, 105.0);
  446. create_paje_state_color(name, "Ctx8", 255.0, .0, 255.0);
  447. create_paje_state_color(name, "Ctx9", .0, .0, 1.0);
  448. create_paje_state_color(name, "Ctx10", 154.0, 205.0, 50.0);
  449. #else
  450. fprintf(out_paje_file, "6 %s S %s \"%f %f %f\" \n", name, name, red, green, blue);
  451. fprintf(out_paje_file, "6 %s Ctx1 %s \"255.0 102.0 255.0\" \n", name, name);
  452. fprintf(out_paje_file, "6 %s Ctx2 %s \".0 255.0 .0\" \n", name, name);
  453. fprintf(out_paje_file, "6 %s Ctx3 %s \"225.0 225.0 .0\" \n", name, name);
  454. fprintf(out_paje_file, "6 %s Ctx4 %s \".0 245.0 255.0\" \n", name, name);
  455. fprintf(out_paje_file, "6 %s Ctx5 %s \".0 .0 .0\" \n", name, name);
  456. fprintf(out_paje_file, "6 %s Ctx6 %s \".0 .0 128.0\" \n", name, name);
  457. fprintf(out_paje_file, "6 %s Ctx7 %s \"105.0 105.0 105.0\" \n", name, name);
  458. fprintf(out_paje_file, "6 %s Ctx8 %s \"255.0 .0 255.0\" \n", name, name);
  459. fprintf(out_paje_file, "6 %s Ctx9 %s \".0 .0 1.0\" \n", name, name);
  460. fprintf(out_paje_file, "6 %s Ctx10 %s \"154.0 205.0 50.0\" \n", name, name);
  461. #endif
  462. }
  463. }
  464. static void handle_start_codelet_body(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  465. {
  466. int worker;
  467. worker = find_worker_id(ev->param[2]);
  468. unsigned sched_ctx = ev->param[1];
  469. if (worker < 0) return;
  470. char *prefix = options->file_prefix;
  471. unsigned long has_name = ev->param[3];
  472. char *name = has_name?(char *)&ev->param[4]:"unknown";
  473. snprintf(last_codelet_symbol[worker], sizeof(last_codelet_symbol[worker]), "%s", name);
  474. double start_codelet_time = get_event_time_stamp(ev, options);
  475. last_codelet_start[worker] = start_codelet_time;
  476. create_paje_state_if_not_found(name, options);
  477. if (out_paje_file)
  478. {
  479. worker_set_state(start_codelet_time, prefix, ev->param[2], name);
  480. if (sched_ctx != 0)
  481. {
  482. #ifdef STARPU_HAVE_POTI
  483. char container[STARPU_POTI_STR_LEN];
  484. char ctx[6];
  485. snprintf(ctx, sizeof(ctx), "Ctx%d", sched_ctx);
  486. thread_container_alias(container, STARPU_POTI_STR_LEN, prefix, ev->param[2]);
  487. poti_SetState(start_codelet_time, container, ctx, name);
  488. #else
  489. fprintf(out_paje_file, "10 %.9f %st%"PRIu64" Ctx%d %s\n", start_codelet_time, prefix, ev->param[2], sched_ctx, name);
  490. #endif
  491. }
  492. }
  493. }
  494. static long dumped_codelets_count;
  495. static struct starpu_fxt_codelet_event *dumped_codelets;
  496. static void handle_end_codelet_body(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  497. {
  498. int worker;
  499. worker = find_worker_id(ev->param[4]);
  500. if (worker < 0) return;
  501. char *prefix = options->file_prefix;
  502. double end_codelet_time = get_event_time_stamp(ev, options);
  503. size_t codelet_size = ev->param[1];
  504. uint32_t codelet_hash = ev->param[2];
  505. if (out_paje_file)
  506. worker_set_state(end_codelet_time, prefix, ev->param[4], "B");
  507. double codelet_length = (end_codelet_time - last_codelet_start[worker]);
  508. update_accumulated_time(worker, 0.0, codelet_length, end_codelet_time, 0);
  509. if (distrib_time)
  510. fprintf(distrib_time, "%s\t%s%d\t%ld\t%"PRIx32"\t%.9f\n", last_codelet_symbol[worker],
  511. prefix, worker, (unsigned long) codelet_size, codelet_hash, codelet_length);
  512. if (options->dumped_codelets)
  513. {
  514. struct starpu_perfmodel_arch* arch = ev->param[3];
  515. dumped_codelets_count++;
  516. dumped_codelets = realloc(dumped_codelets, dumped_codelets_count*sizeof(struct starpu_fxt_codelet_event));
  517. snprintf(dumped_codelets[dumped_codelets_count - 1].symbol, 256, "%s", last_codelet_symbol[worker]);
  518. dumped_codelets[dumped_codelets_count - 1].workerid = worker;
  519. dumped_codelets[dumped_codelets_count - 1].arch = *arch;
  520. dumped_codelets[dumped_codelets_count - 1].size = codelet_size;
  521. dumped_codelets[dumped_codelets_count - 1].hash = codelet_hash;
  522. dumped_codelets[dumped_codelets_count - 1].time = codelet_length;
  523. }
  524. }
  525. static void handle_user_event(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  526. {
  527. int worker;
  528. unsigned long code = ev->param[0];
  529. #ifdef STARPU_HAVE_POTI
  530. char paje_value[STARPU_POTI_STR_LEN], container[STARPU_POTI_STR_LEN];
  531. snprintf(paje_value, STARPU_POTI_STR_LEN, "%lu", code);
  532. #endif
  533. char *prefix = options->file_prefix;
  534. worker = find_worker_id(ev->param[1]);
  535. if (worker < 0)
  536. {
  537. if (out_paje_file)
  538. #ifdef STARPU_HAVE_POTI
  539. program_container_alias (container, STARPU_POTI_STR_LEN, prefix);
  540. #else
  541. fprintf(out_paje_file, "9 %.9f event %sp %lu\n", get_event_time_stamp(ev, options), prefix, code);
  542. #endif
  543. }
  544. else
  545. {
  546. if (out_paje_file)
  547. #ifdef STARPU_HAVE_POTI
  548. thread_container_alias (container, STARPU_POTI_STR_LEN, prefix, ev->param[1]);
  549. #else
  550. fprintf(out_paje_file, "9 %.9f event %st%"PRIu64" %lu\n", get_event_time_stamp(ev, options), prefix, ev->param[1], code);
  551. #endif
  552. }
  553. #ifdef STARPU_HAVE_POTI
  554. if (out_paje_file)
  555. poti_NewEvent(get_event_time_stamp(ev, options), container, "event", paje_value);
  556. #endif
  557. }
  558. static void handle_start_callback(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  559. {
  560. int worker;
  561. worker = find_worker_id(ev->param[1]);
  562. if (worker < 0)
  563. return;
  564. if (out_paje_file)
  565. worker_set_state(get_event_time_stamp(ev, options), options->file_prefix, ev->param[1], "C");
  566. }
  567. static void handle_end_callback(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  568. {
  569. int worker;
  570. worker = find_worker_id(ev->param[1]);
  571. if (worker < 0)
  572. return;
  573. if (out_paje_file)
  574. worker_set_state(get_event_time_stamp(ev, options), options->file_prefix, ev->param[1], "B");
  575. }
  576. static void handle_worker_status(struct fxt_ev_64 *ev, struct starpu_fxt_options *options, const char *newstatus)
  577. {
  578. int worker;
  579. worker = find_worker_id(ev->param[1]);
  580. if (worker < 0)
  581. return;
  582. if (out_paje_file)
  583. worker_set_state(get_event_time_stamp(ev, options), options->file_prefix, ev->param[1], newstatus);
  584. }
  585. static double last_sleep_start[STARPU_NMAXWORKERS];
  586. static void handle_start_sleep(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  587. {
  588. int worker;
  589. worker = find_worker_id(ev->param[0]);
  590. if (worker < 0) return;
  591. double start_sleep_time = get_event_time_stamp(ev, options);
  592. last_sleep_start[worker] = start_sleep_time;
  593. if (out_paje_file)
  594. worker_set_state(get_event_time_stamp(ev, options), options->file_prefix, ev->param[0], "Sl");
  595. }
  596. static void handle_end_sleep(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  597. {
  598. int worker;
  599. worker = find_worker_id(ev->param[0]);
  600. if (worker < 0) return;
  601. double end_sleep_timestamp = get_event_time_stamp(ev, options);
  602. if (out_paje_file)
  603. worker_set_state(end_sleep_timestamp, options->file_prefix, ev->param[0], "B");
  604. double sleep_length = end_sleep_timestamp - last_sleep_start[worker];
  605. update_accumulated_time(worker, sleep_length, 0.0, end_sleep_timestamp, 0);
  606. }
  607. static void handle_data_copy(void)
  608. {
  609. }
  610. static void handle_start_driver_copy(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  611. {
  612. unsigned src = ev->param[0];
  613. unsigned dst = ev->param[1];
  614. unsigned size = ev->param[2];
  615. unsigned comid = ev->param[3];
  616. char *prefix = options->file_prefix;
  617. if (!options->no_bus)
  618. {
  619. if (out_paje_file)
  620. {
  621. double time = get_event_time_stamp(ev, options);
  622. memnode_set_state(time, prefix, dst, "Co");
  623. #ifdef STARPU_HAVE_POTI
  624. char paje_value[STARPU_POTI_STR_LEN], paje_key[STARPU_POTI_STR_LEN], src_memnode_container[STARPU_POTI_STR_LEN];
  625. char program_container[STARPU_POTI_STR_LEN];
  626. snprintf(paje_value, STARPU_POTI_STR_LEN, "%u", size);
  627. snprintf(paje_key, STARPU_POTI_STR_LEN, "com_%u", comid);
  628. program_container_alias(program_container, STARPU_POTI_STR_LEN, prefix);
  629. memmanager_container_alias(src_memnode_container, STARPU_POTI_STR_LEN, prefix, src);
  630. poti_StartLink(time, program_container, "L", src_memnode_container, paje_value, paje_key);
  631. #else
  632. fprintf(out_paje_file, "18 %.9f L %sp %u %smm%u com_%u\n", time, prefix, size, prefix, src, comid);
  633. #endif
  634. }
  635. /* create a structure to store the start of the communication, this will be matched later */
  636. struct _starpu_communication *com = _starpu_communication_new();
  637. com->comid = comid;
  638. com->comm_start = get_event_time_stamp(ev, options);
  639. com->src_node = src;
  640. com->dst_node = dst;
  641. _starpu_communication_list_push_back(communication_list, com);
  642. }
  643. }
  644. static void handle_end_driver_copy(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  645. {
  646. unsigned dst = ev->param[1];
  647. unsigned size = ev->param[2];
  648. unsigned comid = ev->param[3];
  649. char *prefix = options->file_prefix;
  650. if (!options->no_bus)
  651. {
  652. if (out_paje_file)
  653. {
  654. double time = get_event_time_stamp(ev, options);
  655. memnode_set_state(time, prefix, dst, "No");
  656. #ifdef STARPU_HAVE_POTI
  657. char paje_value[STARPU_POTI_STR_LEN], paje_key[STARPU_POTI_STR_LEN];
  658. char dst_memnode_container[STARPU_POTI_STR_LEN], program_container[STARPU_POTI_STR_LEN];
  659. snprintf(paje_value, STARPU_POTI_STR_LEN, "%u", size);
  660. snprintf(paje_key, STARPU_POTI_STR_LEN, "com_%u", comid);
  661. program_container_alias(program_container, STARPU_POTI_STR_LEN, prefix);
  662. memmanager_container_alias(dst_memnode_container, STARPU_POTI_STR_LEN, prefix, dst);
  663. poti_EndLink(time, program_container, "L", dst_memnode_container, paje_value, paje_key);
  664. #else
  665. fprintf(out_paje_file, "19 %.9f L %sp %u %smm%u com_%u\n", time, prefix, size, prefix, dst, comid);
  666. #endif
  667. }
  668. /* look for a data transfer to match */
  669. struct _starpu_communication *itor;
  670. for (itor = _starpu_communication_list_begin(communication_list);
  671. itor != _starpu_communication_list_end(communication_list);
  672. itor = _starpu_communication_list_next(itor))
  673. {
  674. if (itor->comid == comid)
  675. {
  676. double comm_end = get_event_time_stamp(ev, options);
  677. double bandwidth = (double)((0.001*size)/(comm_end - itor->comm_start));
  678. itor->bandwidth = bandwidth;
  679. struct _starpu_communication *com = _starpu_communication_new();
  680. com->comid = comid;
  681. com->comm_start = get_event_time_stamp(ev, options);
  682. com->bandwidth = -bandwidth;
  683. com->src_node = itor->src_node;
  684. com->dst_node = itor->dst_node;
  685. _starpu_communication_list_push_back(communication_list, com);
  686. break;
  687. }
  688. }
  689. }
  690. }
  691. static void handle_start_driver_copy_async(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  692. {
  693. unsigned dst = ev->param[1];
  694. char *prefix = options->file_prefix;
  695. if (!options->no_bus)
  696. if (out_paje_file)
  697. memnode_set_state(get_event_time_stamp(ev, options), prefix, dst, "CoA");
  698. }
  699. static void handle_end_driver_copy_async(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  700. {
  701. unsigned dst = ev->param[1];
  702. char *prefix = options->file_prefix;
  703. if (!options->no_bus)
  704. if (out_paje_file)
  705. memnode_set_state(get_event_time_stamp(ev, options), prefix, dst, "Co");
  706. }
  707. static void handle_memnode_event(struct fxt_ev_64 *ev, struct starpu_fxt_options *options, const char *eventstr)
  708. {
  709. unsigned memnode = ev->param[0];
  710. if (out_paje_file)
  711. memnode_set_state(get_event_time_stamp(ev, options), options->file_prefix, memnode, eventstr);
  712. }
  713. /*
  714. * Number of task submitted to the scheduler
  715. */
  716. static int curq_size = 0;
  717. static void handle_job_push(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  718. {
  719. double current_timestamp = get_event_time_stamp(ev, options);
  720. curq_size++;
  721. if (!options->no_counter && out_paje_file)
  722. {
  723. #ifdef STARPU_HAVE_POTI
  724. char container[STARPU_POTI_STR_LEN];
  725. scheduler_container_alias(container, STARPU_POTI_STR_LEN, options->file_prefix);
  726. poti_SetVariable(current_timestamp, container, "ntask", (double)curq_size);
  727. #else
  728. fprintf(out_paje_file, "13 %.9f %ssched ntask %f\n", current_timestamp, options->file_prefix, (float)curq_size);
  729. #endif
  730. }
  731. if (activity_file)
  732. fprintf(activity_file, "cnt_ready\t%.9f\t%d\n", current_timestamp, curq_size);
  733. }
  734. static void handle_job_pop(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  735. {
  736. double current_timestamp = get_event_time_stamp(ev, options);
  737. curq_size--;
  738. if (!options->no_counter && out_paje_file)
  739. {
  740. #ifdef STARPU_HAVE_POTI
  741. char container[STARPU_POTI_STR_LEN];
  742. scheduler_container_alias(container, STARPU_POTI_STR_LEN, options->file_prefix);
  743. poti_SetVariable(current_timestamp, container, "ntask", (double)curq_size);
  744. #else
  745. fprintf(out_paje_file, "13 %.9f %ssched ntask %f\n", current_timestamp, options->file_prefix, (float)curq_size);
  746. #endif
  747. }
  748. if (activity_file)
  749. fprintf(activity_file, "cnt_ready\t%.9f\t%d\n", current_timestamp, curq_size);
  750. }
  751. static
  752. void handle_update_task_cnt(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  753. {
  754. double current_timestamp = get_event_time_stamp(ev, options);
  755. unsigned long nsubmitted = ev->param[0];
  756. if (activity_file)
  757. fprintf(activity_file, "cnt_submitted\t%.9f\t%lu\n", current_timestamp, nsubmitted);
  758. }
  759. static void handle_codelet_tag(struct fxt_ev_64 *ev)
  760. {
  761. uint64_t tag;
  762. unsigned long job;
  763. tag = ev->param[0];
  764. job = ev->param[1];
  765. _starpu_fxt_dag_add_tag(tag, job);
  766. }
  767. static void handle_codelet_tag_deps(struct fxt_ev_64 *ev)
  768. {
  769. uint64_t child;
  770. uint64_t father;
  771. child = ev->param[0];
  772. father = ev->param[1];
  773. _starpu_fxt_dag_add_tag_deps(child, father);
  774. }
  775. static void handle_task_deps(struct fxt_ev_64 *ev)
  776. {
  777. unsigned long dep_prev = ev->param[0];
  778. unsigned long dep_succ = ev->param[1];
  779. /* There is a dependency between both job id : dep_prev -> dep_succ */
  780. _starpu_fxt_dag_add_task_deps(dep_prev, dep_succ);
  781. }
  782. static void handle_task_done(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  783. {
  784. unsigned long job_id;
  785. job_id = ev->param[0];
  786. unsigned long has_name = ev->param[3];
  787. char *name = has_name?(char *)&ev->param[4]:"unknown";
  788. int worker;
  789. worker = find_worker_id(ev->param[1]);
  790. const char *colour;
  791. char buffer[32];
  792. if (options->per_task_colour)
  793. {
  794. snprintf(buffer, 32, "#%x%x%x",
  795. get_colour_symbol_red(name)/4,
  796. get_colour_symbol_green(name)/4,
  797. get_colour_symbol_blue(name)/4);
  798. colour = &buffer[0];
  799. }
  800. else
  801. {
  802. colour= (worker < 0)?"#aaaaaa":get_worker_color(worker);
  803. }
  804. unsigned exclude_from_dag = ev->param[2];
  805. if (!exclude_from_dag)
  806. _starpu_fxt_dag_set_task_done(job_id, name, colour);
  807. }
  808. static void handle_tag_done(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  809. {
  810. uint64_t tag_id;
  811. tag_id = ev->param[0];
  812. unsigned long has_name = ev->param[2];
  813. char *name = has_name?(char *)&ev->param[3]:"unknown";
  814. int worker;
  815. worker = find_worker_id(ev->param[1]);
  816. const char *colour;
  817. char buffer[32];
  818. if (options->per_task_colour)
  819. {
  820. snprintf(buffer, 32, "%.4f,%.4f,%.4f",
  821. get_colour_symbol_red(name)/1024.0,
  822. get_colour_symbol_green(name)/1024.0,
  823. get_colour_symbol_blue(name)/1024.0);
  824. colour = &buffer[0];
  825. }
  826. else
  827. {
  828. colour= (worker < 0)?"0.0,0.0,0.0":get_worker_color(worker);
  829. }
  830. _starpu_fxt_dag_set_tag_done(tag_id, colour);
  831. }
  832. static void handle_mpi_barrier(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  833. {
  834. int rank = ev->param[0];
  835. STARPU_ASSERT(rank == options->file_rank || options->file_rank == -1);
  836. /* Add an event in the trace */
  837. if (out_paje_file)
  838. {
  839. #ifdef STARPU_HAVE_POTI
  840. char container[STARPU_POTI_STR_LEN], paje_value[STARPU_POTI_STR_LEN];
  841. snprintf(container, STARPU_POTI_STR_LEN, "%sp", options->file_prefix);
  842. snprintf(container, STARPU_POTI_STR_LEN, "%d", rank);
  843. poti_NewEvent(get_event_time_stamp(ev, options), container, "event", paje_value);
  844. #else
  845. fprintf(out_paje_file, "9 %.9f event %sp %d\n", get_event_time_stamp(ev, options), options->file_prefix, rank);
  846. #endif
  847. }
  848. }
  849. static void handle_mpi_start(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  850. {
  851. double date = get_event_time_stamp(ev, options);
  852. char *prefix = options->file_prefix;
  853. if (out_paje_file)
  854. {
  855. #ifdef STARPU_HAVE_POTI
  856. char program_container[STARPU_POTI_STR_LEN];
  857. program_container_alias(program_container, STARPU_POTI_STR_LEN, prefix);
  858. char new_mpicommthread_container_alias[STARPU_POTI_STR_LEN], new_mpicommthread_container_name[STARPU_POTI_STR_LEN];
  859. mpicommthread_container_alias(new_mpicommthread_container_alias, STARPU_POTI_STR_LEN, prefix);
  860. snprintf(new_mpicommthread_container_alias, STARPU_POTI_STR_LEN, "%smpict", prefix);
  861. poti_CreateContainer(date, new_mpicommthread_container_alias, "MPICt", program_container, new_mpicommthread_container_name);
  862. #else
  863. fprintf(out_paje_file, "7 %.9f %smpict MPICt %sp %smpict\n", date, prefix, prefix, prefix);
  864. #endif
  865. mpicommthread_set_state(date, prefix, "Sl");
  866. }
  867. }
  868. static void handle_mpi_stop(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  869. {
  870. double date = get_event_time_stamp(ev, options);
  871. char *prefix = options->file_prefix;
  872. if (out_paje_file)
  873. {
  874. #ifdef STARPU_HAVE_POTI
  875. char mpicommthread_container[STARPU_POTI_STR_LEN];
  876. mpicommthread_container_alias(mpicommthread_container, STARPU_POTI_STR_LEN, prefix);
  877. poti_DestroyContainer(date, "MPICt", mpicommthread_container);
  878. #else
  879. fprintf(out_paje_file, "8 %.9f %smpict MPICt\n",
  880. date, prefix);
  881. #endif
  882. }
  883. }
  884. static void handle_mpi_isend_submit_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  885. {
  886. double date = get_event_time_stamp(ev, options);
  887. if (out_paje_file)
  888. mpicommthread_set_state(date, options->file_prefix, "SdS");
  889. }
  890. static void handle_mpi_isend_submit_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  891. {
  892. int dest = ev->param[0];
  893. int mpi_tag = ev->param[1];
  894. size_t size = ev->param[2];
  895. double date = get_event_time_stamp(ev, options);
  896. if (out_paje_file)
  897. mpicommthread_set_state(date, options->file_prefix, "P");
  898. _starpu_fxt_mpi_add_send_transfer(options->file_rank, dest, mpi_tag, size, date);
  899. }
  900. static void handle_mpi_irecv_submit_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  901. {
  902. double date = get_event_time_stamp(ev, options);
  903. if (out_paje_file)
  904. mpicommthread_set_state(date, options->file_prefix, "RvS");
  905. }
  906. static void handle_mpi_irecv_submit_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  907. {
  908. double date = get_event_time_stamp(ev, options);
  909. if (out_paje_file)
  910. mpicommthread_set_state(date, options->file_prefix, "P");
  911. }
  912. static void handle_mpi_isend_complete_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  913. {
  914. double date = get_event_time_stamp(ev, options);
  915. if (out_paje_file)
  916. mpicommthread_set_state(date, options->file_prefix, "SdC");
  917. }
  918. static void handle_mpi_isend_complete_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  919. {
  920. double date = get_event_time_stamp(ev, options);
  921. if (out_paje_file)
  922. mpicommthread_set_state(date, options->file_prefix, "P");
  923. }
  924. static void handle_mpi_irecv_complete_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  925. {
  926. int src = ev->param[0];
  927. int mpi_tag = ev->param[1];
  928. double date = get_event_time_stamp(ev, options);
  929. if (out_paje_file)
  930. mpicommthread_set_state(date, options->file_prefix, "RvC");
  931. _starpu_fxt_mpi_add_recv_transfer(src, options->file_rank, mpi_tag, date);
  932. }
  933. static void handle_mpi_irecv_complete_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  934. {
  935. double date = get_event_time_stamp(ev, options);
  936. if (out_paje_file)
  937. mpicommthread_set_state(date, options->file_prefix, "P");
  938. }
  939. static void handle_mpi_sleep_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  940. {
  941. double date = get_event_time_stamp(ev, options);
  942. if (out_paje_file)
  943. mpicommthread_set_state(date, options->file_prefix, "Sl");
  944. }
  945. static void handle_mpi_sleep_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  946. {
  947. double date = get_event_time_stamp(ev, options);
  948. if (out_paje_file)
  949. mpicommthread_set_state(date, options->file_prefix, "P");
  950. }
  951. static void handle_mpi_dtesting_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  952. {
  953. double date = get_event_time_stamp(ev, options);
  954. if (out_paje_file)
  955. mpicommthread_set_state(date, options->file_prefix, "DT");
  956. }
  957. static void handle_mpi_dtesting_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  958. {
  959. double date = get_event_time_stamp(ev, options);
  960. if (out_paje_file)
  961. mpicommthread_set_state(date, options->file_prefix, "P");
  962. }
  963. static void handle_mpi_utesting_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  964. {
  965. double date = get_event_time_stamp(ev, options);
  966. if (out_paje_file)
  967. mpicommthread_set_state(date, options->file_prefix, "UT");
  968. }
  969. static void handle_mpi_utesting_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  970. {
  971. double date = get_event_time_stamp(ev, options);
  972. if (out_paje_file)
  973. mpicommthread_set_state(date, options->file_prefix, "P");
  974. }
  975. static void handle_mpi_uwait_begin(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  976. {
  977. double date = get_event_time_stamp(ev, options);
  978. if (out_paje_file)
  979. mpicommthread_set_state(date, options->file_prefix, "UW");
  980. }
  981. static void handle_mpi_uwait_end(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  982. {
  983. double date = get_event_time_stamp(ev, options);
  984. if (out_paje_file)
  985. mpicommthread_set_state(date, options->file_prefix, "P");
  986. }
  987. static void handle_set_profiling(struct fxt_ev_64 *ev, struct starpu_fxt_options *options)
  988. {
  989. int status = ev->param[0];
  990. if (activity_file)
  991. fprintf(activity_file, "set_profiling\t%.9f\t%d\n", get_event_time_stamp(ev, options), status);
  992. }
  993. static void handle_task_wait_for_all(void)
  994. {
  995. _starpu_fxt_dag_add_sync_point();
  996. }
  997. static
  998. void _starpu_fxt_display_bandwidth(struct starpu_fxt_options *options)
  999. {
  1000. float current_bandwidth_per_node[STARPU_MAXNODES] = {0.0};
  1001. char *prefix = options->file_prefix;
  1002. struct _starpu_communication*itor;
  1003. for (itor = _starpu_communication_list_begin(communication_list);
  1004. itor != _starpu_communication_list_end(communication_list);
  1005. itor = _starpu_communication_list_next(itor))
  1006. {
  1007. current_bandwidth_per_node[itor->src_node] += itor->bandwidth;
  1008. if (out_paje_file)
  1009. {
  1010. #ifdef STARPU_HAVE_POTI
  1011. char src_memnode_container[STARPU_POTI_STR_LEN];
  1012. memmanager_container_alias(src_memnode_container, STARPU_POTI_STR_LEN, prefix, itor->src_node);
  1013. poti_SetVariable(itor->comm_start, src_memnode_container, "bw", current_bandwidth_per_node[itor->src_node]);
  1014. #else
  1015. fprintf(out_paje_file, "13 %.9f %smm%u bw %f\n",
  1016. itor->comm_start, prefix, itor->src_node, current_bandwidth_per_node[itor->src_node]);
  1017. #endif
  1018. }
  1019. current_bandwidth_per_node[itor->dst_node] += itor->bandwidth;
  1020. if (out_paje_file)
  1021. {
  1022. #ifdef STARPU_HAVE_POTI
  1023. char dst_memnode_container[STARPU_POTI_STR_LEN];
  1024. memmanager_container_alias(dst_memnode_container, STARPU_POTI_STR_LEN, prefix, itor->dst_node);
  1025. poti_SetVariable(itor->comm_start, dst_memnode_container, "bw", current_bandwidth_per_node[itor->dst_node]);
  1026. #else
  1027. fprintf(out_paje_file, "13 %.9f %smm%u bw %f\n",
  1028. itor->comm_start, prefix, itor->dst_node, current_bandwidth_per_node[itor->dst_node]);
  1029. #endif
  1030. }
  1031. }
  1032. }
  1033. /*
  1034. * Public functions
  1035. */
  1036. static
  1037. void starpu_fxt_parse_new_file(char *filename_in, struct starpu_fxt_options *options)
  1038. {
  1039. /* Open the trace file */
  1040. int fd_in;
  1041. fd_in = open(filename_in, O_RDONLY);
  1042. if (fd_in < 0)
  1043. {
  1044. perror("open failed :");
  1045. exit(-1);
  1046. }
  1047. static fxt_t fut;
  1048. fut = fxt_fdopen(fd_in);
  1049. if (!fut)
  1050. {
  1051. perror("fxt_fdopen :");
  1052. exit(-1);
  1053. }
  1054. fxt_blockev_t block;
  1055. block = fxt_blockev_enter(fut);
  1056. symbol_list = _starpu_symbol_name_list_new();
  1057. communication_list = _starpu_communication_list_new();
  1058. char *prefix = options->file_prefix;
  1059. /* TODO starttime ...*/
  1060. /* create the "program" container */
  1061. if (out_paje_file)
  1062. {
  1063. #ifdef STARPU_HAVE_POTI
  1064. char new_program_container_alias[STARPU_POTI_STR_LEN], new_program_container_name[STARPU_POTI_STR_LEN];
  1065. program_container_alias(new_program_container_alias, STARPU_POTI_STR_LEN, prefix);
  1066. snprintf(new_program_container_name, STARPU_POTI_STR_LEN, "program %s", prefix);
  1067. poti_CreateContainer (0, new_program_container_alias, "P", "MPIroot", new_program_container_name);
  1068. if (!options->no_counter)
  1069. {
  1070. char new_scheduler_container_alias[STARPU_POTI_STR_LEN], new_scheduler_container_name[STARPU_POTI_STR_LEN];
  1071. scheduler_container_alias(new_scheduler_container_alias, STARPU_POTI_STR_LEN, prefix);
  1072. snprintf(new_scheduler_container_name, STARPU_POTI_STR_LEN, "scheduler %s", prefix);
  1073. poti_CreateContainer(0.0, new_scheduler_container_alias, "Sc", new_program_container_alias, new_scheduler_container_name);
  1074. poti_SetVariable(0.0, new_scheduler_container_alias, "ntask", 0.0);
  1075. }
  1076. #else
  1077. fprintf(out_paje_file, "7 0.0 %sp P MPIroot %sprogram \n", prefix, prefix);
  1078. /* create a variable with the number of tasks */
  1079. if (!options->no_counter)
  1080. {
  1081. fprintf(out_paje_file, "7 %.9f %ssched Sc %sp scheduler\n", 0.0, prefix, prefix);
  1082. fprintf(out_paje_file, "13 0.0 %ssched ntask 0.0\n", prefix);
  1083. }
  1084. #endif
  1085. }
  1086. struct fxt_ev_64 ev;
  1087. while(1)
  1088. {
  1089. int ret = fxt_next_ev(block, FXT_EV_TYPE_64, (struct fxt_ev *)&ev);
  1090. if (ret != FXT_EV_OK)
  1091. {
  1092. break;
  1093. }
  1094. switch (ev.code)
  1095. {
  1096. case _STARPU_FUT_WORKER_INIT_START:
  1097. handle_worker_init_start(&ev, options);
  1098. break;
  1099. case _STARPU_FUT_WORKER_INIT_END:
  1100. handle_worker_init_end(&ev, options);
  1101. break;
  1102. case _STARPU_FUT_NEW_MEM_NODE:
  1103. handle_new_mem_node(&ev, options);
  1104. break;
  1105. /* detect when the workers were idling or not */
  1106. case _STARPU_FUT_START_CODELET_BODY:
  1107. handle_start_codelet_body(&ev, options);
  1108. break;
  1109. case _STARPU_FUT_END_CODELET_BODY:
  1110. handle_end_codelet_body(&ev, options);
  1111. break;
  1112. case _STARPU_FUT_START_CALLBACK:
  1113. handle_start_callback(&ev, options);
  1114. break;
  1115. case _STARPU_FUT_END_CALLBACK:
  1116. handle_end_callback(&ev, options);
  1117. break;
  1118. case _STARPU_FUT_UPDATE_TASK_CNT:
  1119. handle_update_task_cnt(&ev, options);
  1120. break;
  1121. /* monitor stack size */
  1122. case _STARPU_FUT_JOB_PUSH:
  1123. handle_job_push(&ev, options);
  1124. break;
  1125. case _STARPU_FUT_JOB_POP:
  1126. handle_job_pop(&ev, options);
  1127. break;
  1128. /* check the memory transfer overhead */
  1129. case _STARPU_FUT_START_FETCH_INPUT:
  1130. handle_worker_status(&ev, options, "Fi");
  1131. break;
  1132. case _STARPU_FUT_START_PUSH_OUTPUT:
  1133. handle_worker_status(&ev, options, "Po");
  1134. break;
  1135. case _STARPU_FUT_START_PROGRESS:
  1136. handle_worker_status(&ev, options, "P");
  1137. break;
  1138. case _STARPU_FUT_START_UNPARTITION:
  1139. handle_worker_status(&ev, options, "U");
  1140. break;
  1141. case _STARPU_FUT_END_FETCH_INPUT:
  1142. case _STARPU_FUT_END_PROGRESS:
  1143. case _STARPU_FUT_END_PUSH_OUTPUT:
  1144. case _STARPU_FUT_END_UNPARTITION:
  1145. handle_worker_status(&ev, options, "B");
  1146. break;
  1147. case _STARPU_FUT_WORKER_SLEEP_START:
  1148. handle_start_sleep(&ev, options);
  1149. break;
  1150. case _STARPU_FUT_WORKER_SLEEP_END:
  1151. handle_end_sleep(&ev, options);
  1152. break;
  1153. case _STARPU_FUT_TAG:
  1154. handle_codelet_tag(&ev);
  1155. break;
  1156. case _STARPU_FUT_TAG_DEPS:
  1157. handle_codelet_tag_deps(&ev);
  1158. break;
  1159. case _STARPU_FUT_TASK_DEPS:
  1160. handle_task_deps(&ev);
  1161. break;
  1162. case _STARPU_FUT_TASK_DONE:
  1163. handle_task_done(&ev, options);
  1164. break;
  1165. case _STARPU_FUT_TAG_DONE:
  1166. handle_tag_done(&ev, options);
  1167. break;
  1168. case _STARPU_FUT_DATA_COPY:
  1169. if (!options->no_bus)
  1170. handle_data_copy();
  1171. break;
  1172. case _STARPU_FUT_START_DRIVER_COPY:
  1173. if (!options->no_bus)
  1174. handle_start_driver_copy(&ev, options);
  1175. break;
  1176. case _STARPU_FUT_END_DRIVER_COPY:
  1177. if (!options->no_bus)
  1178. handle_end_driver_copy(&ev, options);
  1179. break;
  1180. case _STARPU_FUT_START_DRIVER_COPY_ASYNC:
  1181. if (!options->no_bus)
  1182. handle_start_driver_copy_async(&ev, options);
  1183. break;
  1184. case _STARPU_FUT_END_DRIVER_COPY_ASYNC:
  1185. if (!options->no_bus)
  1186. handle_end_driver_copy_async(&ev, options);
  1187. break;
  1188. case _STARPU_FUT_WORK_STEALING:
  1189. /* XXX */
  1190. break;
  1191. case _STARPU_FUT_WORKER_DEINIT_START:
  1192. handle_worker_deinit_start(&ev, options);
  1193. break;
  1194. case _STARPU_FUT_WORKER_DEINIT_END:
  1195. handle_worker_deinit_end(&ev, options);
  1196. break;
  1197. case _STARPU_FUT_START_ALLOC:
  1198. if (!options->no_bus)
  1199. handle_memnode_event(&ev, options, "A");
  1200. break;
  1201. case _STARPU_FUT_START_ALLOC_REUSE:
  1202. if (!options->no_bus)
  1203. handle_memnode_event(&ev, options, "Ar");
  1204. break;
  1205. case _STARPU_FUT_END_ALLOC:
  1206. case _STARPU_FUT_END_ALLOC_REUSE:
  1207. if (!options->no_bus)
  1208. handle_memnode_event(&ev, options, "No");
  1209. break;
  1210. case _STARPU_FUT_START_FREE:
  1211. if (!options->no_bus)
  1212. {
  1213. handle_memnode_event(&ev, options, "F");
  1214. }
  1215. break;
  1216. case _STARPU_FUT_END_FREE:
  1217. if (!options->no_bus)
  1218. {
  1219. unsigned memnode = ev.param[0];
  1220. if (reclaiming[memnode])
  1221. handle_memnode_event(&ev, options, "R");
  1222. else
  1223. handle_memnode_event(&ev, options, "No");
  1224. }
  1225. break;
  1226. case _STARPU_FUT_START_WRITEBACK:
  1227. if (!options->no_bus)
  1228. {
  1229. handle_memnode_event(&ev, options, "W");
  1230. }
  1231. break;
  1232. case _STARPU_FUT_END_WRITEBACK:
  1233. if (!options->no_bus)
  1234. {
  1235. unsigned memnode = ev.param[0];
  1236. if (reclaiming[memnode])
  1237. handle_memnode_event(&ev, options, "R");
  1238. else
  1239. handle_memnode_event(&ev, options, "No");
  1240. }
  1241. break;
  1242. case _STARPU_FUT_START_MEMRECLAIM:
  1243. if (!options->no_bus)
  1244. {
  1245. unsigned memnode = ev.param[0];
  1246. reclaiming[memnode] = 1;
  1247. handle_memnode_event(&ev, options, "R");
  1248. }
  1249. break;
  1250. case _STARPU_FUT_END_MEMRECLAIM:
  1251. if (!options->no_bus)
  1252. {
  1253. unsigned memnode = ev.param[0];
  1254. reclaiming[memnode] = 0;
  1255. handle_memnode_event(&ev, options, "No");
  1256. }
  1257. break;
  1258. case _STARPU_FUT_USER_EVENT:
  1259. handle_user_event(&ev, options);
  1260. break;
  1261. case FUT_MPI_START:
  1262. handle_mpi_start(&ev, options);
  1263. break;
  1264. case FUT_MPI_STOP:
  1265. handle_mpi_stop(&ev, options);
  1266. break;
  1267. case FUT_MPI_BARRIER:
  1268. handle_mpi_barrier(&ev, options);
  1269. break;
  1270. case FUT_MPI_ISEND_SUBMIT_BEGIN:
  1271. handle_mpi_isend_submit_begin(&ev, options);
  1272. break;
  1273. case FUT_MPI_ISEND_SUBMIT_END:
  1274. handle_mpi_isend_submit_end(&ev, options);
  1275. break;
  1276. case FUT_MPI_IRECV_SUBMIT_BEGIN:
  1277. handle_mpi_irecv_submit_begin(&ev, options);
  1278. break;
  1279. case FUT_MPI_IRECV_SUBMIT_END:
  1280. handle_mpi_irecv_submit_end(&ev, options);
  1281. break;
  1282. case FUT_MPI_ISEND_COMPLETE_BEGIN:
  1283. handle_mpi_isend_complete_begin(&ev, options);
  1284. break;
  1285. case FUT_MPI_ISEND_COMPLETE_END:
  1286. handle_mpi_isend_complete_end(&ev, options);
  1287. break;
  1288. case FUT_MPI_IRECV_COMPLETE_BEGIN:
  1289. handle_mpi_irecv_complete_begin(&ev, options);
  1290. break;
  1291. case FUT_MPI_IRECV_COMPLETE_END:
  1292. handle_mpi_irecv_complete_end(&ev, options);
  1293. break;
  1294. case FUT_MPI_SLEEP_BEGIN:
  1295. handle_mpi_sleep_begin(&ev, options);
  1296. break;
  1297. case FUT_MPI_SLEEP_END:
  1298. handle_mpi_sleep_end(&ev, options);
  1299. break;
  1300. case FUT_MPI_DTESTING_BEGIN:
  1301. handle_mpi_dtesting_begin(&ev, options);
  1302. break;
  1303. case FUT_MPI_DTESTING_END:
  1304. handle_mpi_dtesting_end(&ev, options);
  1305. break;
  1306. case FUT_MPI_UTESTING_BEGIN:
  1307. handle_mpi_utesting_begin(&ev, options);
  1308. break;
  1309. case FUT_MPI_UTESTING_END:
  1310. handle_mpi_utesting_end(&ev, options);
  1311. break;
  1312. case FUT_MPI_UWAIT_BEGIN:
  1313. handle_mpi_uwait_begin(&ev, options);
  1314. break;
  1315. case FUT_MPI_UWAIT_END:
  1316. handle_mpi_uwait_end(&ev, options);
  1317. break;
  1318. case _STARPU_FUT_SET_PROFILING:
  1319. handle_set_profiling(&ev, options);
  1320. break;
  1321. case _STARPU_FUT_TASK_WAIT_FOR_ALL:
  1322. handle_task_wait_for_all();
  1323. break;
  1324. case _STARPU_FUT_LOCKING_MUTEX:
  1325. break;
  1326. case _STARPU_FUT_MUTEX_LOCKED:
  1327. break;
  1328. case _STARPU_FUT_UNLOCKING_MUTEX:
  1329. break;
  1330. case _STARPU_FUT_MUTEX_UNLOCKED:
  1331. break;
  1332. case _STARPU_FUT_TRYLOCK_MUTEX:
  1333. break;
  1334. case _STARPU_FUT_RDLOCKING_RWLOCK:
  1335. break;
  1336. case _STARPU_FUT_RWLOCK_RDLOCKED:
  1337. break;
  1338. case _STARPU_FUT_WRLOCKING_RWLOCK:
  1339. break;
  1340. case _STARPU_FUT_RWLOCK_WRLOCKED:
  1341. break;
  1342. case _STARPU_FUT_UNLOCKING_RWLOCK:
  1343. break;
  1344. case _STARPU_FUT_RWLOCK_UNLOCKED:
  1345. break;
  1346. case _STARPU_FUT_LOCKING_SPINLOCK:
  1347. break;
  1348. case _STARPU_FUT_SPINLOCK_LOCKED:
  1349. break;
  1350. case _STARPU_FUT_UNLOCKING_SPINLOCK:
  1351. break;
  1352. case _STARPU_FUT_SPINLOCK_UNLOCKED:
  1353. break;
  1354. case _STARPU_FUT_TRYLOCK_SPINLOCK:
  1355. break;
  1356. case _STARPU_FUT_COND_WAIT_BEGIN:
  1357. break;
  1358. case _STARPU_FUT_COND_WAIT_END:
  1359. break;
  1360. case _STARPU_FUT_MEMORY_FULL:
  1361. break;
  1362. default:
  1363. #ifdef STARPU_VERBOSE
  1364. fprintf(stderr, "unknown event.. %x at time %llx WITH OFFSET %llx\n",
  1365. (unsigned)ev.code, (long long unsigned)ev.time, (long long unsigned)(ev.time-options->file_offset));
  1366. #endif
  1367. break;
  1368. }
  1369. }
  1370. /* Close the trace file */
  1371. if (close(fd_in))
  1372. {
  1373. perror("close failed :");
  1374. exit(-1);
  1375. }
  1376. }
  1377. /* Initialize FxT options to default values */
  1378. void starpu_fxt_options_init(struct starpu_fxt_options *options)
  1379. {
  1380. options->per_task_colour = 0;
  1381. options->no_counter = 0;
  1382. options->no_bus = 0;
  1383. options->ninputfiles = 0;
  1384. options->out_paje_path = "paje.trace";
  1385. options->dag_path = "dag.dot";
  1386. options->distrib_time_path = "distrib.data";
  1387. options->dumped_codelets = NULL;
  1388. options->activity_path = "activity.data";
  1389. }
  1390. static
  1391. void starpu_fxt_distrib_file_init(struct starpu_fxt_options *options)
  1392. {
  1393. dumped_codelets_count = 0;
  1394. dumped_codelets = NULL;
  1395. if (options->distrib_time_path)
  1396. {
  1397. distrib_time = fopen(options->distrib_time_path, "w+");
  1398. }
  1399. else
  1400. {
  1401. distrib_time = NULL;
  1402. }
  1403. }
  1404. static
  1405. void starpu_fxt_distrib_file_close(struct starpu_fxt_options *options)
  1406. {
  1407. if (distrib_time)
  1408. fclose(distrib_time);
  1409. if (options->dumped_codelets)
  1410. {
  1411. *options->dumped_codelets = dumped_codelets;
  1412. options->dumped_codelets_count = dumped_codelets_count;
  1413. }
  1414. }
  1415. static
  1416. void starpu_fxt_activity_file_init(struct starpu_fxt_options *options)
  1417. {
  1418. if (options->activity_path)
  1419. activity_file = fopen(options->activity_path, "w+");
  1420. else
  1421. activity_file = NULL;
  1422. }
  1423. static
  1424. void starpu_fxt_activity_file_close(void)
  1425. {
  1426. if (activity_file)
  1427. fclose(activity_file);
  1428. }
  1429. static
  1430. void starpu_fxt_paje_file_init(struct starpu_fxt_options *options)
  1431. {
  1432. /* create a new file */
  1433. if (options->out_paje_path)
  1434. {
  1435. out_paje_file = fopen(options->out_paje_path, "w+");
  1436. if (!out_paje_file)
  1437. {
  1438. fprintf(stderr,"error while opening %s\n", options->out_paje_path);
  1439. perror("fopen");
  1440. exit(1);
  1441. }
  1442. #ifdef STARPU_HAVE_POTI
  1443. poti_init (out_paje_file);
  1444. #endif
  1445. _starpu_fxt_write_paje_header(out_paje_file);
  1446. }
  1447. else
  1448. {
  1449. out_paje_file = NULL;
  1450. }
  1451. }
  1452. static
  1453. void starpu_fxt_paje_file_close(void)
  1454. {
  1455. if (out_paje_file)
  1456. fclose(out_paje_file);
  1457. }
  1458. static uint64_t starpu_fxt_find_start_time(char *filename_in)
  1459. {
  1460. /* Open the trace file */
  1461. int fd_in;
  1462. fd_in = open(filename_in, O_RDONLY);
  1463. if (fd_in < 0)
  1464. {
  1465. perror("open failed :");
  1466. exit(-1);
  1467. }
  1468. static fxt_t fut;
  1469. fut = fxt_fdopen(fd_in);
  1470. if (!fut)
  1471. {
  1472. perror("fxt_fdopen :");
  1473. exit(-1);
  1474. }
  1475. fxt_blockev_t block;
  1476. block = fxt_blockev_enter(fut);
  1477. struct fxt_ev_64 ev;
  1478. int ret = fxt_next_ev(block, FXT_EV_TYPE_64, (struct fxt_ev *)&ev);
  1479. STARPU_ASSERT (ret == FXT_EV_OK);
  1480. /* Close the trace file */
  1481. if (close(fd_in))
  1482. {
  1483. perror("close failed :");
  1484. exit(-1);
  1485. }
  1486. return (ev.time);
  1487. }
  1488. void starpu_fxt_generate_trace(struct starpu_fxt_options *options)
  1489. {
  1490. _starpu_fxt_dag_init(options->dag_path);
  1491. starpu_fxt_distrib_file_init(options);
  1492. starpu_fxt_activity_file_init(options);
  1493. starpu_fxt_paje_file_init(options);
  1494. if (options->ninputfiles == 0)
  1495. {
  1496. return;
  1497. }
  1498. else if (options->ninputfiles == 1)
  1499. {
  1500. /* we usually only have a single trace */
  1501. uint64_t file_start_time = starpu_fxt_find_start_time(options->filenames[0]);
  1502. options->file_prefix = "";
  1503. options->file_offset = file_start_time;
  1504. options->file_rank = -1;
  1505. starpu_fxt_parse_new_file(options->filenames[0], options);
  1506. }
  1507. else
  1508. {
  1509. unsigned inputfile;
  1510. uint64_t offsets[64];
  1511. /*
  1512. * Find the trace offsets:
  1513. * - If there is no sync point
  1514. * psi_k(x) = x - start_k
  1515. * - If there is a sync point sync_k
  1516. * psi_k(x) = x - sync_k + M
  1517. * where M = max { sync_i - start_i | there exists sync_i}
  1518. * More generally:
  1519. * - psi_k(x) = x - offset_k
  1520. */
  1521. int unique_keys[64];
  1522. int rank_k[64];
  1523. uint64_t start_k[64];
  1524. uint64_t sync_k[64];
  1525. unsigned sync_k_exists[64];
  1526. uint64_t M = 0;
  1527. unsigned found_one_sync_point = 0;
  1528. int key = 0;
  1529. unsigned display_mpi = 0;
  1530. /* Compute all start_k */
  1531. for (inputfile = 0; inputfile < options->ninputfiles; inputfile++)
  1532. {
  1533. uint64_t file_start = starpu_fxt_find_start_time(options->filenames[inputfile]);
  1534. start_k[inputfile] = file_start;
  1535. }
  1536. /* Compute all sync_k if they exist */
  1537. for (inputfile = 0; inputfile < options->ninputfiles; inputfile++)
  1538. {
  1539. int ret = _starpu_fxt_mpi_find_sync_point(options->filenames[inputfile],
  1540. &sync_k[inputfile],
  1541. &unique_keys[inputfile],
  1542. &rank_k[inputfile]);
  1543. if (ret == -1)
  1544. {
  1545. /* There was no sync point, we assume there is no offset */
  1546. sync_k_exists[inputfile] = 0;
  1547. }
  1548. else
  1549. {
  1550. if (!found_one_sync_point)
  1551. {
  1552. key = unique_keys[inputfile];
  1553. display_mpi = 1;
  1554. found_one_sync_point = 1;
  1555. }
  1556. else
  1557. {
  1558. if (key != unique_keys[inputfile])
  1559. {
  1560. fprintf(stderr, "Warning: traces are coming from different run so we will not try to display MPI communications.\n");
  1561. display_mpi = 0;
  1562. }
  1563. }
  1564. STARPU_ASSERT(sync_k[inputfile] >= start_k[inputfile]);
  1565. sync_k_exists[inputfile] = 1;
  1566. uint64_t diff = sync_k[inputfile] - start_k[inputfile];
  1567. if (diff > M)
  1568. M = diff;
  1569. }
  1570. }
  1571. /* Compute the offset */
  1572. for (inputfile = 0; inputfile < options->ninputfiles; inputfile++)
  1573. {
  1574. offsets[inputfile] = sync_k_exists[inputfile]?
  1575. (sync_k[inputfile]-M):start_k[inputfile];
  1576. }
  1577. /* generate the Paje trace for the different files */
  1578. for (inputfile = 0; inputfile < options->ninputfiles; inputfile++)
  1579. {
  1580. int filerank = rank_k[inputfile];
  1581. #ifdef STARPU_VERBOSE
  1582. fprintf(stderr, "Handle file %s (rank %d)\n", options->filenames[inputfile], filerank);
  1583. #endif
  1584. char file_prefix[32];
  1585. snprintf(file_prefix, 32, "%d_", filerank);
  1586. options->file_prefix = file_prefix;
  1587. options->file_offset = offsets[inputfile];
  1588. options->file_rank = filerank;
  1589. starpu_fxt_parse_new_file(options->filenames[inputfile], options);
  1590. }
  1591. /* display the MPI transfers if possible */
  1592. if (display_mpi)
  1593. _starpu_fxt_display_mpi_transfers(options, rank_k, out_paje_file);
  1594. }
  1595. _starpu_fxt_display_bandwidth(options);
  1596. /* close the different files */
  1597. starpu_fxt_paje_file_close();
  1598. starpu_fxt_activity_file_close();
  1599. starpu_fxt_distrib_file_close(options);
  1600. _starpu_fxt_dag_terminate();
  1601. options->nworkers = nworkers;
  1602. }
  1603. #define DATA_STR_MAX_SIZE 15
  1604. struct parse_task
  1605. {
  1606. unsigned exec_time;
  1607. unsigned data_total;
  1608. char *codelet_name;
  1609. };
  1610. static struct parse_task tasks[STARPU_NMAXWORKERS];
  1611. struct starpu_data_trace_kernel
  1612. {
  1613. UT_hash_handle hh;
  1614. char *name;
  1615. FILE *file;
  1616. } *kernels;
  1617. #define NANO_SEC_TO_MILI_SEC 0.000001
  1618. static FILE *codelet_list;
  1619. static void write_task(struct parse_task pt)
  1620. {
  1621. struct starpu_data_trace_kernel *kernel;
  1622. char *codelet_name = pt.codelet_name;
  1623. HASH_FIND_STR(kernels, codelet_name, kernel);
  1624. //fprintf(stderr, "%p %p %s\n", kernel, kernels, codelet_name);
  1625. if(kernel == NULL)
  1626. {
  1627. kernel = malloc(sizeof(*kernel));
  1628. kernel->name = strdup(codelet_name);
  1629. //fprintf(stderr, "%s\n", kernel->name);
  1630. kernel->file = fopen(codelet_name, "w+");
  1631. if(!kernel->file)
  1632. {
  1633. perror("open failed :");
  1634. exit(-1);
  1635. }
  1636. HASH_ADD_STR(kernels, name, kernel);
  1637. fprintf(codelet_list, "%s\n", codelet_name);
  1638. }
  1639. double time = pt.exec_time * NANO_SEC_TO_MILI_SEC;
  1640. fprintf(kernel->file, "%lf %d\n", time, pt.data_total);
  1641. }
  1642. void starpu_fxt_write_data_trace(char *filename_in)
  1643. {
  1644. int fd_in;
  1645. fd_in = open(filename_in, O_RDONLY);
  1646. if (fd_in < 0)
  1647. {
  1648. perror("open failed :");
  1649. exit(-1);
  1650. }
  1651. static fxt_t fut;
  1652. fut = fxt_fdopen(fd_in);
  1653. if (!fut)
  1654. {
  1655. perror("fxt_fdopen :");
  1656. exit(-1);
  1657. }
  1658. codelet_list = fopen("codelet_list", "w+");
  1659. if(!codelet_list)
  1660. {
  1661. perror("open failed :");
  1662. exit(-1);
  1663. }
  1664. fxt_blockev_t block;
  1665. block = fxt_blockev_enter(fut);
  1666. struct fxt_ev_64 ev;
  1667. unsigned workerid;
  1668. unsigned long has_name = 0;
  1669. while(1)
  1670. {
  1671. int ret = fxt_next_ev(block, FXT_EV_TYPE_64, (struct fxt_ev *)&ev);
  1672. if (ret != FXT_EV_OK)
  1673. {
  1674. break;
  1675. }
  1676. switch (ev.code)
  1677. {
  1678. case _STARPU_FUT_WORKER_INIT_START:
  1679. register_worker_id(ev.param[4], ev.param[1]);
  1680. break;
  1681. case _STARPU_FUT_START_CODELET_BODY:
  1682. workerid = find_worker_id(ev.param[2]);
  1683. tasks[workerid].exec_time = ev.time;
  1684. has_name = ev.param[3];
  1685. tasks[workerid].codelet_name = strdup(has_name ? (char *) &ev.param[4] : "unknow");
  1686. //fprintf(stderr, "start codelet :[%d][%s]\n", workerid, tasks[workerid].codelet_name);
  1687. break;
  1688. case _STARPU_FUT_END_CODELET_BODY:
  1689. workerid = find_worker_id(ev.param[4]);
  1690. tasks[workerid].exec_time = ev.time - tasks[workerid].exec_time;
  1691. write_task(tasks[workerid]);
  1692. break;
  1693. case _STARPU_FUT_DATA_LOAD:
  1694. workerid = ev.param[0];
  1695. tasks[workerid].data_total = ev.param[1];
  1696. break;
  1697. default:
  1698. #ifdef STARPU_VERBOSE
  1699. fprintf(stderr, "unknown event.. %x at time %llx WITH OFFSET %llx\n",
  1700. (unsigned)ev.code, (long long unsigned)ev.time, (long long unsigned)(ev.time));
  1701. #endif
  1702. break;
  1703. }
  1704. }
  1705. if (close(fd_in))
  1706. {
  1707. perror("close failed :");
  1708. exit(-1);
  1709. }
  1710. if(fclose(codelet_list))
  1711. {
  1712. perror("close failed :");
  1713. exit(-1);
  1714. }
  1715. struct starpu_data_trace_kernel *kernel, *tmp;
  1716. HASH_ITER(hh, kernels, kernel, tmp)
  1717. {
  1718. if(fclose(kernel->file))
  1719. {
  1720. perror("close failed :");
  1721. exit(-1);
  1722. }
  1723. HASH_DEL(kernels, kernel);
  1724. free(kernel->name);
  1725. free(kernel);
  1726. }
  1727. }
  1728. #endif // STARPU_USE_FXT