< Summary - Igor Pro Universal Testing Framework

Information
Class: procedures.igortest-tracing-analytics
Assembly: procedures
File(s): /builds/mirror/igortest/procedures/igortest-tracing-analytics.ipf
Tag: 74147b3
Line coverage
10%
Covered lines: 25
Uncovered lines: 222
Coverable lines: 247
Total lines: 325
Line coverage: 10.1%
Branch coverage
50%
Covered branches: 4
Total branches: 8
Branch coverage: 50%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/builds/mirror/igortest/procedures/igortest-tracing-analytics.ipf

#LineLine coverage
 1#pragma rtGlobals=3
 2#pragma TextEncoding="UTF-8"
 3#pragma rtFunctionErrors=1
 4#pragma version=1.10
 5#pragma ModuleName=IUTF_Tracing_Analytics
 6
 7#undef UTF_ALLOW_TRACING
 8#if Exists("TUFXOP_Version")
 9
 10#if IgorVersion() >= 10.00
 11#define UTF_ALLOW_TRACING
 12#elif (IgorVersion() >= 9.00) && (NumberByKey("BUILD", IgorInfo(0)) >= 38812)
 13#define UTF_ALLOW_TRACING
 14#endif
 15
 16#endif
 17
 18#ifdef UTF_ALLOW_TRACING
 19
 20static Structure CollectionResult
 21  WAVE/T functions
 22  WAVE lines
 23  WAVE calls
 24  WAVE sums
 25  variable count
 26EndStructure
 27
 028static Function GetMaxFuncCount()
 029  WAVE/WAVE funcLocations = IUTF_Tracing#GetFuncLocations()
 030  variable  size          = DimSize(funcLocations, UTF_ROW)
 31
 032  Make/FREE=1/N=(size) helper = DimSize(funcLocations[p][%FUNCLIST], UTF_ROW)
 033  return WaveMax(helper)
 034End
 35
 036static Function GetMaxProcLineCount()
 037  WAVE wv = IUTF_Tracing#GetProcSizes()
 38
 039  return WaveMax(wv)
 040End
 41
 642static Function/WAVE GetTotals()
 643  variable i, numWaves
 44
 645  TUFXOP_GetStorage/N="IUTF_TestRun" storage
 646  numWaves = DimSize(storage, UTF_ROW)
 647  WAVE/ZZ totals
 648  for(i = 0; i < numWaves; i++)
 649    WAVE/Z/WAVE entryOuter = storage[i]
 650    if(!WaveExists(entryOuter))
 051      continue
 652    endif
 653    WAVE entry = entryOuter[0]
 654    if(WaveExists(totals))
 055      FastOp totals += entry
 656    else
 657      Duplicate/FREE=1 entry, totals
 058    endif
 059  endfor
 60
 061  if(!WaveExists(totals))
 062    Make/N=0/FREE=1 totals
 063  endif
 64
 065  return totals
 666End
 67
 068static Function CollectFunctions(WAVE totals, WAVE/T procs, STRUCT CollectionResult &result)
 069  variable i, j, startIndex, endIndex, funcCount
 070  variable  procCount     = DimSize(procs, UTF_ROW)
 071  variable  maxFuncCount  = GetMaxFuncCount()
 072  DFREF     dfr           = GetPackageFolder()
 073  WAVE/WAVE funcLocations = IUTF_Tracing#GetFuncLocations()
 074  variable  lbFuncList    = FindDimLabel(funcLocations, UTF_COLUMN, "FUNCLIST")
 075  variable  lbFuncStart   = FindDimLabel(funcLocations, UTF_COLUMN, "FUNCSTART")
 76
 077  Make/FREE=1/N=(procCount, maxFuncCount)/T result.functions
 078  Make/FREE=1/N=(procCount, maxFuncCount) result.lines, result.calls, result.sums
 79
 080  for(i = 0; i < procCount; i++)
 081    WAVE/T procFuncNames = funcLocations[i][lbFuncList]
 082    WAVE   procFuncLines = funcLocations[i][lbFuncStart]
 083    funcCount = DimSize(procFuncNames, UTF_ROW)
 084    if(!funcCount)
 085      continue
 086    endif
 087    result.count += funcCount
 88
 089    result.functions[i][0, funcCount - 1] = procFuncNames[q]
 090    result.lines[i][0, funcCount - 1]     = procFuncLines[q]
 091    result.calls[i][0, funcCount - 1]     = totals[procFuncLines[q]][0][i]
 092    for(j = 0; j < funcCount; j++)
 093      startIndex = procFuncLines[j]
 094      endIndex   = j + 1 < funcCount ? procFuncLines[j + 1] : DimSize(totals, UTF_ROW)
 095      WaveStats/M=1/Q/RMD=[startIndex, endIndex - 1][0, 0][i, i] totals
 096      result.sums[i][j] = V_sum
 097    endfor
 098  endfor
 099End
 100
 0101static Function CollectLines(WAVE totals, WAVE/T procs, STRUCT CollectionResult &result)
 0102  variable i, j, funcCount
 0103  string name
 0104  variable  procCount     = DimSize(procs, UTF_ROW)
 0105  variable  lineCount     = GetMaxProcLineCount()
 0106  DFREF     dfr           = GetPackageFolder()
 0107  WAVE/WAVE funcLocations = IUTF_Tracing#GetFuncLocations()
 0108  variable  lbFuncList    = FindDimLabel(funcLocations, UTF_COLUMN, "FUNCLIST")
 0109  variable  lbFuncStart   = FindDimLabel(funcLocations, UTF_COLUMN, "FUNCSTART")
 110
 0111  Make/FREE=1/N=(procCount, lineCount)/T result.functions = ""
 0112  Make/FREE=1/N=(procCount, lineCount) result.lines = q
 0113  Make/FREE=1/N=(procCount, lineCount) result.calls = totals[q][0][p]
 114
 0115  WAVE procSizes = IUTF_Tracing#GetProcSizes()
 0116  for(i = 0; i < procCount; i++)
 0117    WAVE/T procFuncNames = funcLocations[i][lbFuncList]
 0118    WAVE   procFuncLines = funcLocations[i][lbFuncStart]
 0119    lineCount     = procSizes[i]
 0120    result.count += lineCount
 121
 0122    // insert the function names at the lines of their declaration.
 0123    funcCount = DimSize(procFuncNames, UTF_ROW)
 0124    for(j = 0; j < funcCount; j++)
 0125      result.functions[i][procFuncLines[j]] = procFuncNames[j]
 0126    endfor
 127
 0128    // fill in the gaps between the function declaration with the name
 0129    // of the previous function declaration
 0130    name = ""
 0131    for(j = 0; j < lineCount; j++)
 0132      if(IUTF_Utils#IsEmpty(result.functions[i][j]))
 0133        result.functions[i][j] = name
 0134      else
 0135        name = result.functions[i][j]
 0136      endif
 0137    endfor
 0138  endfor
 0139End
 140
 0141static Function/WAVE SearchHighestWithMeta(WAVE/T procs, STRUCT CollectionResult &collectionResult, variable sorting)
 0142  variable i, searchIndex, metaIndex
 0143  string msg
 144
 0145  Make/FREE=1/N=(collectionResult.count, 5)/T result
 0146  SetDimLabel UTF_COLUMN, 0, 'Function Calls', result
 0147  SetDimLabel UTF_COLUMN, 1, 'Sum of called Lines', result
 0148  SetDimLabel UTF_COLUMN, 2, Procedure, result
 0149  SetDimLabel UTF_COLUMN, 3, Function, result
 0150  SetDimLabel UTF_COLUMN, 4, Line, result
 151
 0152  if(sorting == UTF_ANALYTICS_CALLS)
 0153    WAVE searchWave = collectionResult.calls
 0154    searchIndex = 0
 0155    WAVE metaWave = collectionResult.sums
 0156    metaIndex = 1
 0157  elseif(sorting == UTF_ANALYTICS_SUM)
 0158    WAVE searchWave = collectionResult.sums
 0159    searchIndex = 1
 0160    WAVE metaWave = collectionResult.calls
 0161    metaIndex = 0
 0162  else
 0163    sprintf msg, "Bug: Sorting %d is not supported", sorting
 0164    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0165    return result
 0166  endif
 167
 0168  for(i = 0; i < collectionResult.count; i++)
 0169    WaveStats/M=1/Q searchWave
 0170    if(V_max <= 0)
 0171      Redimension/N=(i, -1) result
 0172      return result
 0173    endif
 0174    result[i][searchIndex]               = num2istr(V_max)
 0175    result[i][metaIndex]                 = num2istr(metaWave[V_maxRowLoc][V_maxColLoc])
 0176    result[i][2]                         = procs[V_maxRowLoc]
 0177    result[i][3]                         = collectionResult.functions[V_maxRowLoc][V_maxColLoc]
 0178    result[i][4]                         = num2istr(collectionResult.lines[V_maxRowLoc][V_maxColLoc])
 0179    searchWave[V_maxRowLoc][V_maxColLoc] = NaN
 0180  endfor
 181
 0182  return result
 0183End
 184
 0185static Function/WAVE SearchHighest(WAVE/T procs, STRUCT CollectionResult &collectionResult, variable sorting)
 0186  variable i
 0187  string   msg
 188
 0189  Make/FREE=1/N=(collectionResult.count, 4)/T result
 0190  SetDimLabel UTF_COLUMN, 0, Calls, result
 0191  SetDimLabel UTF_COLUMN, 1, Procedure, result
 0192  SetDimLabel UTF_COLUMN, 2, Function, result
 0193  SetDimLabel UTF_COLUMN, 3, Line, result
 194
 0195  if(sorting == UTF_ANALYTICS_CALLS)
 0196    WAVE searchWave = collectionResult.calls
 0197  else
 0198    sprintf msg, "Bug: Sorting %d is not supported", sorting
 0199    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0200    return result
 0201  endif
 202
 0203  for(i = 0; i < collectionResult.count; i++)
 0204    WaveStats/M=1/Q searchWave
 0205    if(V_max <= 0)
 0206      Redimension/N=(i, -1) result
 0207      return result
 0208    endif
 0209    result[i][0]                         = num2istr(V_max)
 0210    result[i][1]                         = procs[V_maxRowLoc]
 0211    result[i][2]                         = collectionResult.functions[V_maxRowLoc][V_maxColLoc]
 0212    result[i][3]                         = num2istr(collectionResult.lines[V_maxRowLoc][V_maxColLoc])
 0213    searchWave[V_maxRowLoc][V_maxColLoc] = NaN
 0214  endfor
 215
 0216  return result
 0217End
 218
 0219static Function/S GetWaveHeader(WAVE wv)
 0220  variable i
 0221  string   header = ""
 0222  variable size   = DimSize(wv, UTF_COLUMN)
 223
 0224  for(i = size - 1; i >= 0; i--)
 0225    header = AddListItem(GetDimLabel(wv, UTF_COLUMN, i), header)
 0226  endfor
 227
 0228  return header
 0229End
 230
 6231static Function HasTracingData()
 6232  DFREF dfr = GetPackageFolder()
 233
 6234  WAVE/Z/SDFR=dfr FuncLocations
 6235  WAVE/Z/SDFR=dfr ProcSizes
 6236  if(!WaveExists(FuncLocations) || !WaveExists(ProcSizes))
 0237    return 0
 6238  endif
 239
 6240  TUFXOP_GetStorage/Z/N="IUTF_TestRun" storage
 6241  if(V_flag)
 0242    return 0
 6243  endif
 244
 6245  return 1
 6246End
 247
 248/// @brief Show the top functions after a tracing run in the history area
 249/// @param count   The maximum number of items that should be output.
 250/// @param mode    (optional, default UTF_ANALYTICS_FUNCTIONS) defines the data selection.
 251///                Can be UTF_ANALYTICS_FUNCTIONS or UTF_ANALYTICS_LINES.
 252/// @param sorting (optional, default UTF_ANALYTICS_CALLS) defines the metric for sorting.
 253///                Can be UTF_ANALYTICS_CALLS or UTF_ANALYTICS_SUM. UTF_ANALYTICS_SUM is only
 254///                supported for the mode UTF_ANALYTICS_FUNCTIONS.
 0255Function ShowTopFunctions(variable count, [variable mode, variable sorting])
 0256  STRUCT CollectionResult collectionResult
 0257  string msg, header
 0258  WAVE/T procs = IUTF_Tracing#GetTracedProcedureNames()
 0259  DFREF  dfr   = GetPackageFolder()
 260
 0261  mode    = ParamIsDefault(mode) ? UTF_ANALYTICS_FUNCTIONS : mode
 0262  sorting = ParamIsDefault(sorting) ? UTF_ANALYTICS_CALLS : sorting
 263
 0264  if(mode != UTF_ANALYTICS_FUNCTIONS && mode != UTF_ANALYTICS_LINES)
 0265    sprintf msg, "Mode %d is an unsupported mode", mode
 0266    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0267    return NaN
 0268  endif
 0269  if(sorting != UTF_ANALYTICS_CALLS && sorting != UTF_ANALYTICS_SUM)
 0270    sprintf msg, "Sorting %d is an unsupported sorting", sorting
 0271    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0272    return NaN
 0273  endif
 0274  if(sorting == UTF_ANALYTICS_SUM && mode != UTF_ANALYTICS_FUNCTIONS)
 0275    IUTF_Reporting#IUTF_PrintStatusMessage("Sum sorting is only available for the functions mode")
 0276    return NaN
 0277  endif
 0278  if(count < 0 || IUTF_Utils#IsNaN(count))
 0279    sprintf msg, "Invalid count: %d", count
 0280    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0281    return NaN
 0282  endif
 0283  if(!HasTracingData())
 0284    IUTF_Reporting#IUTF_PrintStatusMessage("No Tracing data exists. Try to run tracing first.")
 0285    return NaN
 0286  endif
 287
 0288  WAVE totals = GetTotals()
 0289  if(!DimSize(totals, UTF_ROW))
 0290    // this can happen after stored Experiment is loaded to a fresh instance of Igor
 0291    IUTF_Reporting#IUTF_PrintStatusMessage("TUFXOP has no data. Try to rerun tracing to get new data.")
 0292    return NaN
 0293  endif
 294
 0295  if(mode == UTF_ANALYTICS_FUNCTIONS)
 0296    CollectFunctions(totals, procs, collectionResult)
 0297  elseif(mode == UTF_ANALYTICS_LINES)
 0298    CollectLines(totals, procs, collectionResult)
 0299  else
 0300    sprintf msg, "Bug: Unknown mode %d for collection", mode
 0301    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0302    return NaN
 0303  endif
 304
 0305  if(count < collectionResult.count)
 0306    collectionResult.count = count
 0307  endif
 308
 0309  if(mode == UTF_ANALYTICS_FUNCTIONS)
 0310    WAVE/T result = SearchHighestWithMeta(procs, collectionResult, sorting)
 0311  elseif(mode == UTF_ANALYTICS_LINES)
 0312    WAVE/T result = SearchHighest(procs, collectionResult, sorting)
 0313  else
 0314    sprintf msg, "Bug: Unknown mode %d for sorting", mode
 0315    IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0316  endif
 317
 0318  Duplicate/O result, dfr:TracingAnalyticResult
 319
 0320  header = GetWaveHeader(result)
 0321  msg    = IUTF_Utils#NicifyTableText(result, header)
 0322  IUTF_Reporting#IUTF_PrintStatusMessage(msg)
 0323End
 324
 325#endif // UTF_ALLOW_TRACING