Skip to content
This repository was archived by the owner on Apr 30, 2020. It is now read-only.

Commit 00f55df

Browse files
committed
Fix for displaying nested perfmarkers
1 parent 2c5dc34 commit 00f55df

2 files changed

Lines changed: 173 additions & 53 deletions

File tree

CodeXL/Components/GpuProfiling/AMDTGpuProfiling/TraceTable.cpp

Lines changed: 133 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "OccupancyInfo.h"
3838
#include "APIColorMap.h"
3939
#include <AMDTGpuProfiling/Util.h>
40+
4041
namespace boosticl = boost::icl;
4142

4243
TraceTableItem::TraceTableItem(const QString& strAPIPrefix, const QString& strApiName, IAPIInfoDataHandler* pApiInfo, acTimelineItem* pTimelineItem, acTimelineItem* pDeviceBlock, IOccupancyInfoDataHandler* pOccupancyInfo) :
@@ -337,6 +338,9 @@ TraceTableModel::TraceTableModel(QObject* parent) : QAbstractItemModel(parent),
337338

338339
TraceTableModel::~TraceTableModel()
339340
{
341+
m_apiCallsTraceItemsMap.clear();
342+
m_perfMarkersTraceItemsMap.clear();
343+
m_perfmarkerList.clear();
340344
SAFE_DELETE(m_pRootItem);
341345
}
342346

@@ -469,11 +473,6 @@ TraceTableItem* TraceTableModel::AddTraceItem(const QString& strAPIPrefix, const
469473
pParent = m_openedPerfMarkerItemsStack.top();
470474
}
471475

472-
if (pParent != nullptr)
473-
{
474-
pParent->InsertChild(0, pRetVal);
475-
}
476-
477476
m_openedPerfMarkerItemsStack.push_back(pRetVal);
478477
}
479478

@@ -483,6 +482,17 @@ TraceTableItem* TraceTableModel::AddTraceItem(const QString& strAPIPrefix, const
483482
TraceTableItem* TraceTableModel::CloseLastOpenedPerfMarker(acTimelineItem* pTimelineItem)
484483
{
485484
TraceTableItem* pOpenedItem = m_openedPerfMarkerItemsStack.pop();
485+
486+
Marker marker;
487+
marker.m_pPerfMarkerItem = pOpenedItem;
488+
489+
if (!m_openedPerfMarkerItemsStack.empty())
490+
{
491+
marker.m_pParentMarker = m_openedPerfMarkerItemsStack.top();
492+
}
493+
494+
m_perfmarkerList.push_back(marker);
495+
486496
GT_IF_WITH_ASSERT(pOpenedItem != nullptr)
487497
{
488498
// Set the timeline pTableItem:
@@ -702,6 +712,46 @@ IOccupancyInfoDataHandler* TraceTableModel::GetOccupancyItem(const QModelIndex&
702712
return pRetVal;
703713
}
704714

715+
bool TraceTableItemComparer(TraceTableItem* pFirst, TraceTableItem* pSecond)
716+
{
717+
if (pFirst->m_itemType == API && pSecond->m_itemType == PERFMARKER)
718+
{
719+
// API - PERFMARKER
720+
if (pFirst->GetTimelineItem()->endTime() <= pSecond->GetTimelineItem()->startTime())
721+
{
722+
return true;
723+
}
724+
}
725+
726+
if (pFirst->m_itemType == PERFMARKER && pSecond->m_itemType == API)
727+
{
728+
// PERFMARKER - API
729+
if (pFirst->GetTimelineItem()->startTime() <= pSecond->GetTimelineItem()->startTime() &&
730+
pFirst->GetTimelineItem()->endTime() >= pSecond->GetTimelineItem()->endTime())
731+
{
732+
return true;
733+
}
734+
}
735+
736+
if (pFirst->m_itemType == PERFMARKER && pSecond->m_itemType == PERFMARKER)
737+
{
738+
// PERFMARKER - PERFMARKER
739+
if (pFirst->GetTimelineItem()->startTime() <= pSecond->GetTimelineItem()->startTime() &&
740+
pFirst->GetTimelineItem()->endTime() >= pSecond->GetTimelineItem()->endTime())
741+
{
742+
return true;
743+
}
744+
}
745+
746+
// Other Cases
747+
if (pFirst->GetTimelineItem()->endTime() <= pSecond->GetTimelineItem()->startTime())
748+
{
749+
return true;
750+
}
751+
752+
return false;
753+
}
754+
705755
bool TraceTableModel::InitializeModel()
706756
{
707757
bool retVal = false;
@@ -725,11 +775,28 @@ bool TraceTableModel::InitializeModel()
725775
afProgressBarWrapper::instance().setProgressText(GPU_STR_TraceViewLoadingTraceTableItemsProgress);
726776

727777
// Go over the API items and the markers item, and add them to the table:
728-
while ((apiIter != apiIterEnd) || (markersIter != markersIterEnd))
778+
std::vector<TraceTableItem*> leftTraceTableItemList;
779+
780+
for (auto itr = m_apiCallsTraceItemsMap.begin(); itr != m_apiCallsTraceItemsMap.end(); ++itr)
781+
{
782+
itr->second->m_itemType = API;
783+
leftTraceTableItemList.push_back(itr->second);
784+
}
785+
786+
for (auto itr = m_perfMarkersTraceItemsMap.begin(); itr != m_perfMarkersTraceItemsMap.end(); ++itr)
787+
{
788+
itr.value()->m_itemType = PERFMARKER;
789+
leftTraceTableItemList.push_back(itr.value());
790+
}
791+
792+
std::sort(leftTraceTableItemList.begin(), leftTraceTableItemList.end(), TraceTableItemComparer);
793+
unsigned int listIndx = 0;
794+
795+
while (listIndx < leftTraceTableItemList.size())
729796
{
730797
/// calculate next item and advance iterator
731-
TraceTableItem* pNextItemToAdd = CalculateNextTraceTableItem(markersIter, markersIterEnd, apiIter, apiIterEnd);
732-
TraceTableItem* pParent = GetNextItemParent(pNextItemToAdd);
798+
TraceTableItem* pNextItemToAdd = leftTraceTableItemList[listIndx];
799+
TraceTableItem* pParent = GetNextItemParent(pNextItemToAdd, pNextItemToAdd->m_itemType);
733800
GT_IF_WITH_ASSERT(pParent != nullptr)
734801
{
735802
// Add the child to the appropriate parent:
@@ -742,6 +809,7 @@ bool TraceTableModel::InitializeModel()
742809

743810
afProgressBarWrapper::instance().incrementProgressBar();
744811
}
812+
listIndx++;
745813
}
746814

747815
m_apiCallsTraceItemsMap.clear();
@@ -754,84 +822,103 @@ bool TraceTableModel::InitializeModel()
754822
return retVal;
755823
}
756824
/// returns items parent , by default it's a root item,unless overlapping marker item is found
757-
TraceTableItem* TraceTableModel::GetNextItemParent(const TraceTableItem* pNextItemToAdd) const
825+
TraceTableItem* TraceTableModel::GetNextItemParent(const TraceTableItem* pNextItemToAdd, const TraceTableItemType& itemType) const
758826
{
759-
//// Look for the right parent for this item:
760-
/// By default all items are immediate children of the root node
827+
// Look for the right parent for this item:
828+
// By default all items are immediate children of the root node
761829
TraceTableItem* pParent = m_pRootItem;
762830
GT_IF_WITH_ASSERT(pNextItemToAdd != nullptr)
763831
{
764832
quint64 nextItemStartTime = pNextItemToAdd->GetTimelineItem()->startTime();
765833
quint64 nextItemEndTime = pNextItemToAdd->GetTimelineItem()->endTime();
766834

767835
// Temporary Solution - Intervals is not feasible with same lower and upper bound
768-
if(nextItemStartTime == nextItemEndTime)
836+
if (nextItemStartTime == nextItemEndTime)
769837
{
770838
nextItemEndTime++;
771839
}
772840

773-
const auto nextItemTimeInterval = boosticl::interval<quint64>::right_open(nextItemStartTime, nextItemEndTime);
841+
if (itemType == API)
842+
{
843+
const auto nextItemTimeInterval = boosticl::interval<quint64>::right_open(nextItemStartTime, nextItemEndTime);
774844

775-
auto itr = m_markerIntervals.find(nextItemTimeInterval);
845+
auto itr = m_markerIntervals.find(nextItemTimeInterval);
776846

777-
if (itr != m_markerIntervals.end())
778-
{
779-
auto pMarker = itr->second;
847+
if (itr != m_markerIntervals.end())
848+
{
849+
auto pMarker = itr->second;
780850

781-
//check if next item we're adding overlapped by the found marker , if so make it next item parent
782-
if (pMarker != pNextItemToAdd &&
783-
pMarker->GetTimelineItem() != nullptr &&
784-
pMarker->GetTimelineItem()->startTime() <= nextItemStartTime &&
785-
pMarker->GetTimelineItem()->endTime() >= nextItemEndTime)
851+
//check if next item we're adding overlapped by the found marker , if so make it next item parent
852+
if (pMarker != pNextItemToAdd)
853+
{
854+
if (pMarker->GetTimelineItem() != nullptr &&
855+
pMarker->GetTimelineItem()->startTime() <= nextItemStartTime &&
856+
pMarker->GetTimelineItem()->endTime() >= nextItemEndTime)
857+
{
858+
pParent = pMarker;
859+
}
860+
}
861+
}
862+
}
863+
else
864+
{
865+
for (std::vector<Marker>::const_iterator it = m_perfmarkerList.begin();
866+
it != m_perfmarkerList.end(); ++it)
786867
{
787-
pParent = pMarker;
868+
if (pNextItemToAdd == it->m_pPerfMarkerItem && nullptr != it->m_pParentMarker)
869+
{
870+
pParent = it->m_pParentMarker;
871+
}
788872
}
789873
}
790874
}
875+
791876
return pParent;
792877
}
793878

794879
/// calculates next item and advance one of iterators - marker or api iterator
795880
TraceTableItem* TraceTableModel::CalculateNextTraceTableItem(PerfMarkersMapItr& markersIter, const PerfMarkersMapItr& markersIterEnd,
796-
ApiCallsTraceMapItr& apiIter, const ApiCallsTraceMapItr& apiIterEnd) const
881+
ApiCallsTraceMapItr& apiIter, const ApiCallsTraceMapItr& apiIterEnd, TraceTableItemType& itemType) const
797882
{
798883
TraceTableItem* pNextItemToAdd = nullptr;
799884
TraceTableItem* pCurrentAPI = (apiIter != apiIterEnd) ? apiIter->second : nullptr;
800885
TraceTableItem* pCurrentMarker = (markersIter != markersIterEnd) ? markersIter.value() : nullptr;
801886

802-
//no more markers --> api is next item
803-
if ((pCurrentAPI != nullptr) && (pCurrentMarker == nullptr))
887+
quint64 currentApiStartTime = 0u;
888+
quint64 currentMarkerStartTime = 0u;
889+
890+
if (nullptr != pCurrentAPI)
804891
{
805-
pNextItemToAdd = pCurrentAPI;
806-
apiIter++;
892+
currentApiStartTime = pCurrentAPI->GetTimelineItem()->startTime();
807893
}
808-
// no more api's --> marker is the next item
809-
else if ((pCurrentAPI == nullptr) && (pCurrentMarker != nullptr))
894+
895+
if (nullptr != pCurrentMarker)
810896
{
811-
pNextItemToAdd = pCurrentMarker;
812-
markersIter++;
897+
currentMarkerStartTime = pCurrentMarker->GetTimelineItem()->startTime();
813898
}
814-
//choose by start time
815-
else
816-
{
817-
// We have both next API and markers. Compare the start time to decide which of them should be added next:
818-
quint64 apiStart = pCurrentAPI->GetTimelineItem()->startTime();
819-
quint64 markerStart = markersIter.key().first;
820899

821-
// Next item should be an API item:
822-
if (apiStart <= markerStart)
900+
// There are some markers which are not yet added
901+
if (nullptr != pCurrentMarker)
902+
{
903+
if (currentMarkerStartTime <= currentApiStartTime)
823904
{
824-
pNextItemToAdd = pCurrentAPI;
825-
apiIter++;
905+
pNextItemToAdd = pCurrentMarker;
906+
itemType = PERFMARKER;
907+
++markersIter;
826908
}
827-
828-
// Next one should be a marker item:
829909
else
830910
{
831-
pNextItemToAdd = pCurrentMarker;
832-
markersIter++;
911+
pNextItemToAdd = pCurrentAPI;
912+
itemType = API;
913+
++apiIter;
833914
}
834915
}
916+
else if (nullptr != pCurrentAPI)
917+
{
918+
pNextItemToAdd = pCurrentAPI;
919+
itemType = API;
920+
++apiIter;
921+
}
835922

836923
return pNextItemToAdd;
837924
}

CodeXL/Components/GpuProfiling/AMDTGpuProfiling/TraceTable.h

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
// forward declarations
4040
class acTimelineItem;
4141

42+
/// enum for trace table item types
43+
enum TraceTableItemType
44+
{
45+
API, ///< API Item
46+
PERFMARKER ///< Perfmarker Item
47+
};
48+
4249
/// Class to hold the item data for the API Trace table model
4350
class TraceTableItem
4451
{
@@ -137,6 +144,9 @@ class TraceTableItem
137144
/// \param strMarkerName the new marker name for the item
138145
void UpdateMarkerName(const QString& strMarkerName);
139146

147+
/// type of the trace table item
148+
TraceTableItemType m_itemType;
149+
140150
private:
141151
/// Disable copy constructor
142152
TraceTableItem(const TraceTableItem&);
@@ -228,7 +238,6 @@ class TraceTableModel : public QAbstractItemModel
228238
/// \param defaultForegroundColor the default color used for items in the table
229239
/// \param linkColor the color to use for painting hyper-links
230240
/// \param font the font used in the table
231-
/// \param filteredColumns list of columns that should not be displayed
232241
void SetVisualProperties(const QColor& defaultForegroundColor, const QColor& linkColor, const QFont& font);
233242

234243
/// Build the list of headers that should be displayed:
@@ -261,12 +270,12 @@ class TraceTableModel : public QAbstractItemModel
261270
TraceTableItem* AddTraceItem(const QString& strAPIPrefix, const QString& strMarkerName, IPerfMarkerInfoDataHandler* pMarkerEntry);
262271

263272
/// Gets the device block data for the specified row
264-
/// \param rowIndex the index of the row
273+
/// \param index the index of the row
265274
/// \return the timeline item representing the device block
266275
acTimelineItem* GetDeviceBlock(const QModelIndex& index);
267276

268277
/// Gets the occupancy data for the specified row
269-
/// \param rowIndex the index of the row
278+
/// \param index the index of the row
270279
/// \return the occupancy info
271280
IOccupancyInfoDataHandler* GetOccupancyItem(const QModelIndex& index);
272281

@@ -287,7 +296,7 @@ class TraceTableModel : public QAbstractItemModel
287296
/// \param apiNum the api calls number for this thread
288297
void SetAPICallsNumber(unsigned int apiNum);
289298

290-
// get the number of Api Calls Trace Items to be set
299+
/// get the number of Api Calls Trace Items to be set
291300
int GetReservedApiCallsTraceItems() const {return m_reservedApiCallsTraceItems;}
292301

293302
/// Export the model data to a CSV file
@@ -307,6 +316,7 @@ class TraceTableModel : public QAbstractItemModel
307316

308317
///Methods
309318
private:
319+
310320
/// This method :
311321
/// 1. calculates next TraceTableItem to be connected with its parent during table initialization
312322
/// 2. advances input api and markers iterators
@@ -316,13 +326,16 @@ class TraceTableModel : public QAbstractItemModel
316326
/// \param apiIterEnd api end iterator
317327
/// \return TraceTableItem* pointer to next TraceTableItem that shall be connected to it's parent root or marker
318328
TraceTableItem* CalculateNextTraceTableItem(PerfMarkersMapItr& markersIter, const PerfMarkersMapItr& markersIterEnd,
319-
ApiCallsTraceMapItr& apiIter, const ApiCallsTraceMapItr& apiIterEnd) const;
329+
ApiCallsTraceMapItr& apiIter, const ApiCallsTraceMapItr& apiIterEnd, TraceTableItemType& itemType) const;
330+
331+
320332
/// This method returns items parent , by default it's a root item,unless time overlapping marker item is found
321333
/// \param pNextItemToAdd item for which parent needs to be found
322334
/// \return TraceTableItem* pointer to parent for a given item
323-
TraceTableItem* GetNextItemParent(const TraceTableItem* pNextItemToAdd) const;
335+
TraceTableItem* GetNextItemParent(const TraceTableItem* pNextItemToAdd, const TraceTableItemType& itemType) const;
324336

325337
private:
338+
326339
QStringList m_headerData; ///< the header data for this model
327340
TraceTableItem* m_pRootItem; ///< the root item of the trace table (tree)
328341
QColor m_defaultForegroundColor; ///< the default foreground (font) color for this model
@@ -335,14 +348,34 @@ class TraceTableModel : public QAbstractItemModel
335348
/// Maps containing the API call trace items:
336349
std::map<quint64, TraceTableItem*> m_apiCallsTraceItemsMap;
337350

338-
// number of reserved items for m_apiCallsTraceItemsMap -
351+
/// number of reserved items for m_apiCallsTraceItemsMap -
339352
int m_reservedApiCallsTraceItems;
340353

341354
/// Maps containing the perf markers trace items:
342355
QMap<TimeRange, TraceTableItem*> m_perfMarkersTraceItemsMap;
356+
357+
343358
/// holds all markers sorted by their time range intervals
344359
boost::icl::split_interval_map<quint64, TraceTableItem*, boost::icl::partial_absorber, std::less, boost::icl::inplace_max> m_markerIntervals;
345360

361+
/// structure for holding marker information
362+
struct Marker
363+
{
364+
/// pointer to the marker
365+
TraceTableItem* m_pPerfMarkerItem;
366+
367+
/// pointer to the parent of the marker
368+
TraceTableItem* m_pParentMarker;
369+
370+
/// Constructor
371+
Marker() : m_pPerfMarkerItem(nullptr),
372+
m_pParentMarker(nullptr)
373+
{}
374+
};
375+
376+
/// list of the perf markers
377+
std::vector<Marker> m_perfmarkerList;
378+
346379
/// Was the model initialized already?
347380
bool m_isInitialized;
348381

0 commit comments

Comments
 (0)