ganttwidget.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. /*
  2. = StarPU-Top for StarPU =
  3. Copyright (C) 2011
  4. William Braik
  5. Yann Courtois
  6. Jean-Marie Couteyen
  7. Anthony Roy
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the GNU Lesser General Public
  10. License as published by the Free Software Foundation; either
  11. version 2.1 of the License, or (at your option) any later version.
  12. This library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. Lesser General Public License for more details.
  16. You should have received a copy of the GNU Lesser General Public
  17. License along with this library; if not, write to the Free Software
  18. Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  19. */
  20. #include "ganttwidget.h"
  21. #include "mainwindow.h"
  22. #include "taskmanager.h"
  23. #include <math.h>
  24. #include <QtOpenGL>
  25. #include <QTimer>
  26. #include <sstream>
  27. const int MAX_CPU_NUM = 6;
  28. const int MAX_GPU_NUM = 3;
  29. const int MARGIN = 5;
  30. const int DEFAULT_TIME_TOTAL = 20000;
  31. const int HEIGHT_TIME_AXIS = 20;
  32. const int WIDTH_GLOBAL_PU = 50; // Width of the big CPU rect
  33. const int WIDTH_PROGRAM = 50;
  34. const int WIDTH_PU = 70;
  35. const int GRAD_NUM = 5; // Number of gradations between each label
  36. const int WIDTH_PRESENT_LINE = 1;
  37. const int SIGNIF_NUM = 100;
  38. const int FIRST_THRESHOLD = 25;
  39. const int SECOND_THRESHOLD = 75;
  40. const int SHIFT_LEFT_TIME_AXIS = 3;
  41. const int SHIFT_TOP_TIME_AXIS = 3;
  42. const QColor GANTT_BACKGROUND_COLOR = Qt::gray;
  43. const QFont::StyleHint GANTT_TEXT_FONT = QFont::Times;
  44. const QColor GANTT_TEXT_COLOR = Qt::white;
  45. const QColor GANTT_PU_COLOR = Qt::blue;
  46. const QColor GANTT_TIMELINE_COLOR = Qt::blue;
  47. const QColor GANTT_PRESENTLINE_COLOR = Qt::black;
  48. const QColor GANTT_IDLE_COLOR = Qt::red;
  49. const QColor GANTT_WORKING_COLOR = Qt::green;
  50. const QColor GANTT_PREV_COLOR = Qt::yellow;
  51. GanttWidget::GanttWidget(MainWindow *mainWindow, TaskManager *taskManager) :
  52. QGLWidget(QGLFormat(QGL::SampleBuffers), mainWindow)
  53. {
  54. _mainWindow = mainWindow;
  55. _taskManager = taskManager;
  56. setAutoFillBackground(false);
  57. _background = QBrush(GANTT_BACKGROUND_COLOR);
  58. _textPen = QPen(GANTT_TEXT_COLOR);
  59. _textFont.setPixelSize(50);
  60. _textFont.setStyleHint(GANTT_TEXT_FONT);
  61. _coordxPresentLine = 0;
  62. _numPUs = 0;
  63. _wasRunning = false;
  64. _timeTotal = DEFAULT_TIME_TOTAL;
  65. _timeBefore = _timeTotal * 0.66;
  66. _timeAfter = _timeTotal * 0.34;
  67. _lastValPrevLine = 66;
  68. _timePresent = 0;
  69. _timeToShow = 0;
  70. _numCPUs = 0;
  71. _numGPUs = 0;
  72. _heightPU = 0;
  73. _initCompleted = false;
  74. _PUsByDevice = 0;
  75. _PUsByPos = 0;
  76. // Start display update timer
  77. _timer = new QTimer(this);
  78. _timer->start(35);
  79. // Connect events
  80. QObject::connect(_mainWindow, SIGNAL(sessionOpened()),
  81. this, SLOT(connected()));
  82. QObject::connect(_mainWindow, SIGNAL(sessionClosed()),
  83. this, SLOT(disconnected()));
  84. QObject::connect(_mainWindow, SIGNAL(debugLocked()),
  85. this, SLOT(ganttLocked()));
  86. QObject::connect(_mainWindow, SIGNAL(debugStepped()),
  87. this, SLOT(ganttUnlocked()));
  88. QObject::connect(_timer, SIGNAL(timeout()),
  89. this, SLOT(update()));
  90. }
  91. GanttWidget::~GanttWidget()
  92. {
  93. delete _timer;
  94. delete _rectPUs;
  95. }
  96. void GanttWidget::defaultScreen(QPainter *painter)
  97. {
  98. painter->setPen(GANTT_TEXT_COLOR);
  99. drawPresentLine(painter);
  100. drawTime(painter);
  101. }
  102. // Called each time the window is resized
  103. void GanttWidget::resizeGL(int width, int height)
  104. {
  105. update();
  106. }
  107. void GanttWidget::paintEvent(QPaintEvent *event)
  108. {
  109. QPainter painter;
  110. painter.begin(this);
  111. painter.setRenderHint(QPainter::Antialiasing);
  112. paint(&painter, event);
  113. painter.end();
  114. }
  115. /* Draw CPU and GPU rects */
  116. void GanttWidget::drawPUs(QPainter *painter)
  117. {
  118. QFont f;
  119. QPen penRect;
  120. QPen penText;
  121. QPointF coordTxt;
  122. QString txt;
  123. QStaticText name;
  124. f.setFamily("utf8");
  125. f.setWeight(QFont::Bold);
  126. f.setPixelSize(12);
  127. painter->setFont(f);
  128. penRect.setColor(GANTT_PU_COLOR);
  129. penText.setColor(GANTT_TEXT_COLOR);
  130. painter->setPen(penRect);
  131. _rectPUs = new QRectF[_numCPUs + _numGPUs];
  132. int height_allowed = size().height() - HEIGHT_TIME_AXIS - MARGIN;
  133. // height of each processor unit rectangles
  134. int height = height_allowed / (_numCPUs + _numGPUs);
  135. _heightPU = height;
  136. int height_cpublock = height * _numCPUs;
  137. int height_gpublock = height * _numGPUs;
  138. /* The CPUs rect */
  139. if (_numCPUs > 0)
  140. {
  141. _rectCPUblock = QRectF(WIDTH_PROGRAM + MARGIN,
  142. HEIGHT_TIME_AXIS + MARGIN, WIDTH_GLOBAL_PU,
  143. height_cpublock - MARGIN);
  144. painter->drawRect(_rectCPUblock);
  145. painter->fillRect(_rectCPUblock, GANTT_PU_COLOR);
  146. painter->setPen(penText);
  147. coordTxt = QPointF(
  148. _rectCPUblock.center().rx() - (WIDTH_GLOBAL_PU / 2) + 3,
  149. _rectCPUblock.center().ry() - f.pixelSize());
  150. txt = QString("CPU(s)");
  151. name = QStaticText(txt);
  152. name.setPerformanceHint(QStaticText::AggressiveCaching);
  153. painter->drawStaticText(coordTxt, name);
  154. }
  155. f.setWeight(QFont::Light);
  156. f.setPixelSize(10);
  157. painter->setFont(f);
  158. painter->setPen(penRect);
  159. /* devices */
  160. for (int i = 0; i < _numCPUs + _numGPUs; i++)
  161. {
  162. painter->setPen(penRect);
  163. _rectPUs[i] = QRectF(WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN,
  164. HEIGHT_TIME_AXIS + MARGIN + i * height, WIDTH_PU,
  165. height - MARGIN);
  166. painter->drawRect(_rectPUs[i]);
  167. painter->fillRect(_rectPUs[i], Qt::blue);
  168. painter->setPen(penText);
  169. if (_heightPU >= f.pixelSize() * 2)
  170. {
  171. painter->drawText(_rectPUs[i], Qt::AlignVCenter, _PUsByPos[i].name);
  172. }
  173. }
  174. f.setFamily("utf8");
  175. f.setWeight(QFont::Bold);
  176. f.setPixelSize(12);
  177. painter->setFont(f);
  178. painter->setPen(penRect);
  179. /* The GPUs rect */
  180. if (_numGPUs > 0)
  181. {
  182. _rectGPUblock = QRectF(WIDTH_PROGRAM + MARGIN,
  183. HEIGHT_TIME_AXIS + MARGIN + height_cpublock, WIDTH_GLOBAL_PU,
  184. height_gpublock - MARGIN);
  185. painter->drawRect(_rectGPUblock);
  186. painter->fillRect(_rectGPUblock, Qt::blue);
  187. coordTxt = QPointF(
  188. _rectGPUblock.center().rx() - (WIDTH_GLOBAL_PU / 2) + 3,
  189. _rectGPUblock.center().ry() - f.pixelSize());
  190. txt = QString("GPU(s)");
  191. name = QStaticText(txt);
  192. name.setPerformanceHint(QStaticText::AggressiveCaching);
  193. painter->setPen(penText);
  194. painter->drawStaticText(coordTxt, name);
  195. }
  196. }
  197. /* calculate abscissa on the screen for a given time (in ms) if it's displayable
  198. return -1 if timestampMs is outside time displayable because of scale*/
  199. qreal GanttWidget::coordxForTime(qlonglong timestampMs)
  200. {
  201. qreal startx = (qreal) WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN
  202. + WIDTH_PU + MARGIN;
  203. qreal widthAllowed = (qreal) size().width() - startx;
  204. qreal scale = (qreal) widthAllowed / _timeTotal;
  205. qreal coordx = -1;
  206. if (timestampMs >= 0)
  207. {
  208. if ((timestampMs <= _timePresent) && (timestampMs >= (_timePresent
  209. - _timeBefore)))
  210. {
  211. coordx = (qreal) startx + (qreal)(
  212. (_timeBefore - (_timePresent - timestampMs)) * scale);
  213. }
  214. else if ((timestampMs > _timePresent) && timestampMs <= (_timeAfter
  215. + _timePresent))
  216. {
  217. coordx = (qreal) _coordxPresentLine + (qreal)(
  218. (timestampMs - _timePresent) * scale);
  219. }
  220. }
  221. return coordx;
  222. }
  223. void GanttWidget::drawTime(QPainter *painter)
  224. {
  225. QFont f;
  226. QPen penRect;
  227. QPen penText;
  228. penRect.setColor(GANTT_TIMELINE_COLOR);
  229. penText.setColor(GANTT_TEXT_COLOR);
  230. painter->setPen(penRect);
  231. f.setFamily("utf8");
  232. f.setWeight(QFont::DemiBold);
  233. f.setPixelSize(10);
  234. painter->setFont(f);
  235. _rectTime = QRectF(0, 0, size().width(), 20);
  236. painter->drawRect(_rectTime);
  237. painter->fillRect(_rectTime, Qt::blue);
  238. QString titre = QString("Time (ms)");
  239. QStaticText titreTxt = QStaticText(titre);
  240. titreTxt.setPerformanceHint(QStaticText::AggressiveCaching);
  241. QPointF coordRect = QPointF(_rectTime.left() + SHIFT_LEFT_TIME_AXIS,
  242. _rectTime.center().ry() - f.pixelSize() + SHIFT_TOP_TIME_AXIS);
  243. painter->setPen(penText);
  244. painter->drawStaticText(coordRect, titreTxt);
  245. f.setWeight(QFont::Light);
  246. f.setPixelSize(10);
  247. painter->setFont(f);
  248. qreal ourStartx = WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN
  249. + WIDTH_PU + MARGIN;
  250. qreal widthAvailable = ((qreal)(size().width() - ourStartx));
  251. qreal scale = ((qreal)(_timeBefore + _timeAfter) / widthAvailable);
  252. qreal scale_time_px = (qreal) widthAvailable / (_timeBefore + _timeAfter);
  253. int timeInterval = computeTimeInterval(_timeTotal);
  254. qreal sizeInterval = ((qreal)(timeInterval * scale_time_px));
  255. qreal step_x = (qreal)(sizeInterval / GRAD_NUM);
  256. //we calculate the location of the next gradation in the future part
  257. qlonglong first = _timePresent - _timePresent % ((qlonglong) timeInterval);
  258. qlonglong cur_t = first;
  259. //gradations in the past
  260. while (cur_t > _timePresent - _timeBefore)
  261. {
  262. if (cur_t >= (qlonglong) 0)
  263. {
  264. qreal cur_x =
  265. ((qreal)((_timeBefore - (_timePresent - cur_t)) / scale)
  266. + ourStartx);
  267. QString buffer;
  268. buffer.append(QString("%1").arg(cur_t));
  269. QStaticText gradTxt = QStaticText(buffer);
  270. gradTxt.setPerformanceHint(QStaticText::AggressiveCaching);
  271. //calculate the fading
  272. int fading = 3 * (cur_x - ourStartx);
  273. if (fading < 0)
  274. {
  275. fading = 0;
  276. }
  277. if (fading > 255)
  278. {
  279. fading = 255;
  280. }
  281. _textPen.setColor(QColor(255, 255, 255, fading));
  282. painter->setPen(_textPen);
  283. painter->drawLine(
  284. QLineF(cur_x, 0, cur_x, HEIGHT_TIME_AXIS - MARGIN));
  285. if (widthAvailable > 500)
  286. {
  287. painter->drawStaticText(
  288. QPointF(cur_x,
  289. HEIGHT_TIME_AXIS - MARGIN - f.pixelSize()),
  290. gradTxt);
  291. }
  292. for (int k = 1; k < GRAD_NUM; k++)
  293. { // k=1 ,because of spans
  294. painter->drawLine(
  295. QLineF(cur_x + step_x * k, 0, cur_x + step_x * k,
  296. HEIGHT_TIME_AXIS - MARGIN * 3));
  297. }
  298. }
  299. cur_t -= timeInterval;
  300. }
  301. //in the future
  302. cur_t = first + timeInterval;
  303. while (cur_t < _timePresent + _timeAfter)
  304. {
  305. qreal cur_x = ((qreal)((_timeBefore - (_timePresent - cur_t)) / scale)
  306. + ourStartx);
  307. QString buffer;
  308. buffer.append(QString("%1").arg(cur_t));
  309. QStaticText gradTxt = QStaticText(buffer);
  310. gradTxt.setPerformanceHint(QStaticText::AggressiveCaching);
  311. //calculate the fading
  312. int fading = 3 * (size().width() - cur_x);
  313. if (fading > 255)
  314. {
  315. fading = 255;
  316. }
  317. _textPen.setColor(QColor(255, 255, 255, fading));
  318. painter->setPen(_textPen);
  319. painter->drawLine(QLineF(cur_x, 0, cur_x, HEIGHT_TIME_AXIS - MARGIN));
  320. if (widthAvailable > 500)
  321. {
  322. painter->drawStaticText(
  323. QPointF(cur_x, HEIGHT_TIME_AXIS - MARGIN - f.pixelSize()),
  324. gradTxt);
  325. }
  326. for (int k = 1; k < GRAD_NUM; k++)
  327. {
  328. painter->drawLine(
  329. QLineF(cur_x + step_x * k, 0, cur_x + step_x * k,
  330. HEIGHT_TIME_AXIS - MARGIN * 3));
  331. }
  332. cur_t += timeInterval;
  333. }
  334. _textPen.setColor(QColor(255, 255, 255));
  335. painter->setPen(_textPen);
  336. }
  337. //calculate un lapse of time to get at least 20 gradations if 1000 <= timeTotal
  338. //and <=24 * 10^X
  339. int GanttWidget::computeTimeInterval(int timeTotal)
  340. {
  341. int coef = 1;
  342. while (timeTotal >= SIGNIF_NUM)
  343. {
  344. timeTotal = timeTotal / 10;
  345. coef *= 10;
  346. }
  347. //we have a number between 1 and 99
  348. if (timeTotal < FIRST_THRESHOLD)
  349. {
  350. return coef;
  351. }
  352. else if (timeTotal < SECOND_THRESHOLD)
  353. {
  354. return coef * 5;
  355. }
  356. else
  357. {
  358. return coef * 10;
  359. }
  360. }
  361. void GanttWidget::drawProgram(QPainter *painter)
  362. {
  363. QFont f;
  364. QPen penRect;
  365. QPen penText;
  366. penRect.setColor(GANTT_PU_COLOR);
  367. penText.setColor(GANTT_TEXT_COLOR);
  368. f.setFamily("utf8");
  369. f.setWeight(QFont::Black);
  370. f.setPixelSize(10);
  371. painter->setFont(f);
  372. painter->setPen(penRect);
  373. _rectProg = QRectF(0, HEIGHT_TIME_AXIS + MARGIN, WIDTH_PROGRAM,
  374. size().height() - HEIGHT_TIME_AXIS - MARGIN * 2);
  375. painter->drawRect(_rectProg);
  376. painter->fillRect(_rectProg, Qt::blue);
  377. QPointF coordTxt = QPointF(
  378. _rectProg.center().rx() - (WIDTH_PROGRAM / 2) + 3,
  379. _rectProg.center().ry() - f.pixelSize());
  380. QString txt = QString("Program");
  381. QStaticText name = QStaticText(txt);
  382. name.setPerformanceHint(QStaticText::AggressiveCaching);
  383. painter->setPen(penText);
  384. painter->drawStaticText(coordTxt, name);
  385. }
  386. void GanttWidget::drawPresentLine(QPainter *painter)
  387. {
  388. QPen pen;
  389. pen.setColor(GANTT_PRESENTLINE_COLOR);
  390. painter->setPen(pen);
  391. qreal widthAllowed = (qreal)(
  392. size().width() - WIDTH_PROGRAM - MARGIN - WIDTH_GLOBAL_PU - MARGIN
  393. - WIDTH_PU - MARGIN);
  394. int timeTotal = _timeBefore + _timeAfter;
  395. int x, y, w, h;
  396. x = WIDTH_PROGRAM + MARGIN + WIDTH_GLOBAL_PU + MARGIN + WIDTH_PU + MARGIN;
  397. y = (HEIGHT_TIME_AXIS + MARGIN);
  398. w = WIDTH_PRESENT_LINE;
  399. h = size().height() - (HEIGHT_TIME_AXIS + MARGIN);
  400. qreal scale = (qreal)(widthAllowed / timeTotal);
  401. qreal gap_x = (qreal)(scale * _timeBefore);
  402. _linePresent = QRectF(x + gap_x, y, w, h);
  403. _coordxPresentLine = (qreal)(x + gap_x);
  404. painter->drawRect(_linePresent);
  405. painter->fillRect(_linePresent, Qt::black);
  406. }
  407. /* Draw whole gantt diagram depending on time showing line present location.
  408. Useful to draw the diagram after the complete execution. */
  409. void GanttWidget::drawFromTime(QPainter *painter, qlonglong timestamp)
  410. {
  411. Q_ASSERT_X(timestamp >= 0, "GanttWidget::drawFromTime",
  412. "Negative timestamp !");
  413. /* program rect */
  414. drawProgram(painter);
  415. _timePresent = timestamp;
  416. /* time line */
  417. drawTime(painter);
  418. drawPUs(painter);
  419. /* Tasks */
  420. drawIdlePU(painter);
  421. qlonglong borneBefore = _timePresent - _timeBefore;
  422. if (borneBefore < 0)
  423. {
  424. borneBefore = 0;
  425. }
  426. _tasks = _taskManager->tasks(borneBefore, _timePresent);
  427. foreach(starpu_top_task t, _tasks)
  428. {
  429. drawWorkPU(painter,t);
  430. }
  431. }
  432. /* draw idle time for each processor */
  433. void GanttWidget::drawIdlePU(QPainter *painter)
  434. {
  435. int starty = HEIGHT_TIME_AXIS + MARGIN;
  436. int widthAllowed = size().width() - WIDTH_PROGRAM - MARGIN
  437. - WIDTH_GLOBAL_PU - MARGIN - WIDTH_PU - MARGIN;
  438. int timeTotal = _timeBefore + _timeAfter;
  439. qreal posBlockx = 0;
  440. qreal placeTime = 0;
  441. bool isStartx = false;
  442. qreal scale = (qreal) widthAllowed / timeTotal;
  443. QRectF rectIdle;
  444. qlonglong timestampS = 0;
  445. if (_timePresent >= _timeBefore)
  446. {
  447. timestampS = _timePresent - _timeBefore;
  448. }
  449. /* drawIdlePu */
  450. for (qlonglong j = timestampS; j < _timePresent; j++)
  451. {
  452. if (!isStartx)
  453. {
  454. isStartx = true;
  455. posBlockx = coordxForTime(j);
  456. }
  457. placeTime++;
  458. }
  459. QFont f;
  460. QPen pen;
  461. f.setFamily("utf8");
  462. f.setWeight(QFont::DemiBold);
  463. f.setPixelSize(10);
  464. painter->setFont(f);
  465. pen.setColor(GANTT_IDLE_COLOR.lighter(110));
  466. painter->setPen(pen);
  467. for (int i = 0; i < _numPUs; i++)
  468. {
  469. rectIdle = QRectF(posBlockx, starty + (_heightPU) * i,
  470. placeTime * scale, (_heightPU - MARGIN));
  471. painter->drawRect(rectIdle);
  472. painter->fillRect(rectIdle, GANTT_IDLE_COLOR);
  473. }
  474. }
  475. /* draw forecasted working time for each processor */
  476. void GanttWidget::drawPrevWorkPU(QPainter *painter, starpu_top_task t)
  477. {
  478. int starty = HEIGHT_TIME_AXIS + MARGIN;
  479. int widthAllowed = size().width() - WIDTH_PROGRAM - MARGIN
  480. - WIDTH_GLOBAL_PU - MARGIN - WIDTH_PU - MARGIN;
  481. qreal posBlockx = 0;
  482. qreal placeTime = 0;
  483. bool isStartx = false;
  484. qreal scale = (qreal) widthAllowed / _timeTotal;
  485. QRectF rectForecast;
  486. //either the beginning is in the Future Part
  487. //( timeAfter ) or either in the Past Part (timeBefore)
  488. qlonglong timestampS = (t.timestampStart - _timePresent);
  489. if (timestampS > 0)
  490. {
  491. // the beginning is in the Future part (displayable here)
  492. timestampS = t.timestampStart;
  493. }
  494. else
  495. {
  496. // the beginning is in the Past part (not displayable here)
  497. timestampS = _timePresent;
  498. // +1 just to be sure we don't draw over the line of Present
  499. posBlockx = _coordxPresentLine + WIDTH_PRESENT_LINE + 1;
  500. isStartx = true;
  501. placeTime -= WIDTH_PRESENT_LINE + 1;
  502. }
  503. qlonglong timestampE = (t.timestampEnd - _timePresent);
  504. if (timestampE > 0)
  505. {
  506. if (timestampE <= _timeAfter)
  507. {
  508. timestampE = t.timestampEnd; // the end is displayable
  509. }
  510. else
  511. {
  512. // the end is not displayable because it's in the future
  513. // more than timePresent + timeAfter
  514. timestampE = _timePresent + _timeAfter;
  515. }
  516. }
  517. else
  518. {
  519. // the end is not displayable because it's in the past
  520. timestampE = _timePresent;
  521. posBlockx = _coordxPresentLine + WIDTH_PRESENT_LINE + 1;
  522. isStartx = true;
  523. placeTime -= WIDTH_PRESENT_LINE + 1;
  524. }
  525. /* Future */
  526. for (qlonglong i = timestampS; i <= timestampE; i++)
  527. {
  528. if (!isStartx)
  529. {
  530. isStartx = true;
  531. posBlockx = coordxForTime(i);
  532. }
  533. placeTime++;
  534. }
  535. int pos = _PUsByDevice[t.deviceId].id;
  536. QFont f;
  537. QPen pen;
  538. pen.setColor(GANTT_TEXT_COLOR);
  539. painter->setPen(pen);
  540. f.setFamily("utf8");
  541. f.setWeight(QFont::DemiBold);
  542. f.setPixelSize(10);
  543. painter->setFont(f);
  544. QLinearGradient gradient(posBlockx,
  545. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2,
  546. posBlockx + placeTime * scale,
  547. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2);
  548. QColor prevColor = GANTT_PREV_COLOR;
  549. gradient.setColorAt(0.2, prevColor.lighter(110));
  550. gradient.setColorAt(0.3, Qt::yellow);
  551. gradient.setColorAt(0.80, prevColor.darker(270));
  552. QBrush brush(gradient);
  553. pen.setBrush(brush);
  554. painter->setPen(pen);
  555. rectForecast = QRectF(posBlockx, starty + (_heightPU) * pos,
  556. placeTime * scale, (_heightPU - MARGIN));
  557. painter->drawRect(rectForecast);
  558. painter->fillRect(rectForecast, brush);
  559. }
  560. /* Draw working time for each processor. Working PUs.
  561. We don't mind about task values because the taskmanager gives us only the tasks
  562. between timeBefore and timePresent so
  563. we haven't to test if they are displayable or not. We just have to calculate
  564. which part of time is displayable.
  565. The task t has its begin or its end between time Before and timePresent */
  566. void GanttWidget::drawWorkPU(QPainter *painter, starpu_top_task t)
  567. {
  568. int starty = HEIGHT_TIME_AXIS + MARGIN;
  569. int widthAllowed = size().width() - WIDTH_PROGRAM - MARGIN
  570. - WIDTH_GLOBAL_PU - MARGIN - WIDTH_PU - MARGIN;
  571. qreal posBlockx = 0;
  572. qreal placeTime = 0;
  573. bool isStartx = false;
  574. qreal scale = (qreal) widthAllowed / _timeTotal;
  575. QRectF rectWorking;
  576. qlonglong timestampS = (_timePresent - t.timestampStart);
  577. qlonglong timestampE = -1;
  578. if (timestampS > _timeBefore)
  579. {
  580. // Begin time of task t is not displayable
  581. timestampS = _timePresent - _timeBefore;
  582. }
  583. else
  584. {
  585. timestampS = t.timestampStart; // Begin time of task t is displayable
  586. }
  587. if (t.timestampEnd == -1)
  588. {
  589. for (qlonglong i = timestampS; i <= _timePresent; i++)
  590. {
  591. if (!isStartx)
  592. {
  593. isStartx = true;
  594. posBlockx = coordxForTime(i);
  595. }
  596. placeTime++;
  597. }
  598. }
  599. else
  600. {
  601. timestampE = t.timestampEnd;
  602. if (timestampE > _timePresent)
  603. {
  604. timestampE = _timePresent;
  605. }
  606. for (qlonglong i = timestampS; i <= timestampE; i++)
  607. {
  608. if (!isStartx)
  609. {
  610. isStartx = true;
  611. posBlockx = coordxForTime(i);
  612. }
  613. placeTime++;
  614. }
  615. }
  616. int pos = _PUsByDevice[t.deviceId].id;
  617. QFont f;
  618. QPen pen;
  619. f.setFamily("utf8");
  620. f.setWeight(QFont::DemiBold);
  621. f.setPixelSize(10);
  622. painter->setFont(f);
  623. rectWorking = QRectF(posBlockx, starty + (_heightPU) * pos,
  624. placeTime * scale, (_heightPU - MARGIN));
  625. painter->drawRect(rectWorking);
  626. QLinearGradient gradient(posBlockx,
  627. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2,
  628. posBlockx + placeTime * scale,
  629. starty + (_heightPU) * pos + (_heightPU - MARGIN) / 2);
  630. QColor workingColor = GANTT_WORKING_COLOR;
  631. gradient.setColorAt(0.2, workingColor.lighter(110));
  632. gradient.setColorAt(0.3, Qt::green);
  633. gradient.setColorAt(0.8, workingColor.darker(270));
  634. gradient.setSpread(QGradient::PadSpread);
  635. QBrush brush(gradient);
  636. pen.setBrush(brush);
  637. painter->setPen(pen);
  638. painter->fillRect(rectWorking, brush);
  639. }
  640. void GanttWidget::updateZoom(double value)
  641. {
  642. qDebug() << "VALEUR === " << value;
  643. // if(!(value == 0.0))
  644. // {
  645. _timeTotal = value;
  646. updatePrevLine( _lastValPrevLine);
  647. //}
  648. }
  649. void GanttWidget::updatePrevLine(double value)
  650. {
  651. _timeBefore = _timeTotal * (value / 100);
  652. _timeAfter = _timeTotal * ((100 - value) / 100);
  653. _lastValPrevLine = value;
  654. if (!(_timer->isActive()))
  655. {
  656. update();
  657. }
  658. }
  659. void GanttWidget::updateTimeView(int time)
  660. {
  661. qlonglong newTimeToShow = time;
  662. if (!(_timer->isActive()))
  663. {
  664. _timeToShow = newTimeToShow;
  665. update();
  666. }
  667. }
  668. void GanttWidget::connected()
  669. {
  670. _wasRunning = false;
  671. _initCompleted = false;
  672. _timePresent = 0;
  673. if (!(_timer->isActive()))
  674. {
  675. _timer->start(35);
  676. }
  677. }
  678. void GanttWidget::disconnected()
  679. {
  680. _wasRunning = true;
  681. if (_timer->isActive())
  682. {
  683. _timer->stop();
  684. }
  685. }
  686. void GanttWidget::ganttLocked()
  687. {
  688. update(); // a last drawing update before to freeze the drawing
  689. if (_timer->isActive())
  690. {
  691. _timer->stop(); // freeze the drawing
  692. }
  693. }
  694. void GanttWidget::ganttUnlocked()
  695. {
  696. if (!(_timer->isActive()))
  697. {
  698. _timer->start(35); // start the timer again
  699. }
  700. }
  701. void GanttWidget::countPUs()
  702. {
  703. int length;
  704. _numCPUs = 0;
  705. _numGPUs = 0;
  706. length = _mainWindow->serverDevices()->length();
  707. _numPUs = length;
  708. delete _PUsByDevice;
  709. delete _PUsByPos;
  710. _PUsByDevice = new starpu_top_device[length];
  711. _PUsByPos = new starpu_top_device[length];
  712. int pos = 0;
  713. /* CPUs */
  714. foreach(starpu_top_device sD,*_mainWindow->serverDevices())
  715. {
  716. if(sD.type == 0)
  717. {
  718. _PUsByDevice[sD.id].name = sD.name;
  719. _PUsByDevice[sD.id].type = sD.type;
  720. _PUsByDevice[sD.id].id = pos; // actual location
  721. _PUsByPos[pos].id = sD.id; // the reak id
  722. _PUsByPos[pos].name = sD.name;
  723. _PUsByPos[pos].type = sD.type;
  724. _numCPUs++;
  725. pos++;
  726. }
  727. }
  728. /* GPUs */
  729. foreach (starpu_top_device sD , *_mainWindow->serverDevices())
  730. {
  731. if(sD.type == 1 || sD.type == 2)
  732. {
  733. _PUsByDevice[sD.id].name = sD.name;
  734. _PUsByDevice[sD.id].type = sD.type;
  735. _PUsByDevice[sD.id].id = pos; // actually location
  736. _PUsByPos[pos].id = sD.id; // the real id
  737. _PUsByPos[pos].name = sD.name;
  738. _PUsByPos[pos].type = sD.type;
  739. pos++;
  740. _numGPUs++;
  741. }
  742. }
  743. }
  744. void GanttWidget::paint(QPainter *painter, QPaintEvent *event)
  745. {
  746. painter->fillRect(event->rect(), _background);
  747. painter->setPen(_textPen);
  748. if (_mainWindow->isReady())
  749. {
  750. if (!_initCompleted)
  751. { // do not call countPUs more than once per execution
  752. countPUs();
  753. _initCompleted = true;
  754. }
  755. drawProgram(painter);
  756. drawPUs(painter);
  757. if (_mainWindow->isRunning())
  758. {
  759. _timePresent = _mainWindow->effectiveRunningTime();
  760. _timeToShow = _timePresent; // saved the time of end
  761. drawTime(painter);
  762. drawPresentLine(painter);
  763. drawIdlePU(painter);
  764. /* Past part */
  765. qlonglong borneBefore = _timePresent - _timeBefore;
  766. if (borneBefore < 0)
  767. {
  768. borneBefore = 0;
  769. }
  770. _tasks = _taskManager->tasks(borneBefore, _timePresent);
  771. foreach (starpu_top_task t, _tasks)
  772. {
  773. drawWorkPU(painter,t);
  774. }
  775. /* Future past */
  776. qlonglong borneAfter = _timePresent + _timeAfter;
  777. _tasks = _taskManager->prevTasks(_timePresent, borneAfter);
  778. foreach (starpu_top_task t, _tasks)
  779. {
  780. drawPrevWorkPU(painter,t);
  781. }
  782. }
  783. else if (!_wasRunning)
  784. {
  785. defaultScreen(painter);
  786. }
  787. }
  788. else
  789. {
  790. if (_wasRunning)
  791. {
  792. // display wanted part of execution (only if it's finished)
  793. drawFromTime(painter,_timeToShow);
  794. }
  795. }
  796. }