void TrackingKymoView::DeleteSameTData(std::set<unsigned int> samet_selection) { std::set<unsigned int>::iterator sel_iter = samet_selection.begin(); TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashc[*sel_iter]); int new_id = this->GetMaxId()+1; // first find the trace line in the data to erase it: std::vector<TraceLine*>* trace_lines = m_tobj->GetTraceLinesPointer(); std::vector<TraceLine*>::iterator trace_lines_iter; for(trace_lines_iter = trace_lines->begin() ;trace_lines_iter!= trace_lines->end(); ++trace_lines_iter) { if(tline->GetId() == (*trace_lines_iter)->GetId()) { trace_lines->erase(trace_lines_iter); break; } } printf("I am here\n"); TraceLine * tline_tmp = new TraceLine(); tline_tmp = tline; sel_iter = samet_selection.begin(); while(sel_iter != samet_selection.end()) { TraceBit tb1 = tline->subtrace_hash[*sel_iter].at(0); TraceBit tb2 = tline->subtrace_hash[*sel_iter].at(1); int maxtime = MAX(tb1.time,tb2.time); tline_tmp = this->DeleteTlineRecursive(tline_tmp,*sel_iter,new_id,maxtime); ++new_id; ++sel_iter; } trace_lines->push_back(tline_tmp); }
// for code lines InstrItem::InstrItem(InstrView* iv, QTreeWidget* parent, Addr addr, bool inside, const QString& code, const QString& cmd, const QString& args, TraceInstr* instr) : QTreeWidgetItem(parent) { _view = iv; _addr = addr; _instr = instr; _instrCall = 0; _instrJump = 0; _inside = inside; setTextAlignment(0, Qt::AlignRight); setTextAlignment(1, Qt::AlignRight); setTextAlignment(2, Qt::AlignRight); if (args == "...") setText(0, args); else setText(0, addr.pretty()); setText(4, code); setText(5, cmd); setText(6, args); TraceLine* l; if (instr && (l = instr->line())) setText(7, l->name()); updateGroup(); updateCost(); }
void SourceView::context(QListViewItem* i, const QPoint & p, int c) { QPopupMenu popup; // Menu entry: TraceLineCall* lc = i ? ((SourceItem*) i)->lineCall() : 0; TraceLineJump* lj = i ? ((SourceItem*) i)->lineJump() : 0; TraceFunction* f = lc ? lc->call()->called() : 0; TraceLine* line = lj ? lj->lineTo() : 0; if (f) { QString name = f->name(); if ((int)name.length()>Configuration::maxSymbolLength()) name = name.left(Configuration::maxSymbolLength()) + "..."; popup.insertItem(i18n("Go to '%1'").arg(name), 93); popup.insertSeparator(); } else if (line) { popup.insertItem(i18n("Go to Line %1").arg(line->name()), 93); popup.insertSeparator(); } if ((c == 1) || (c == 2)) { addCostMenu(&popup); popup.insertSeparator(); } addGoMenu(&popup); int r = popup.exec(p); if (r == 93) { if (f) activated(f); if (line) activated(line); } }
void TrackingKymoView::GenerateTracks() { printf("Started GenerateTracks\n"); // std::vector<std::vector<ftk::LabelImageFeatures>> *f = m_model->getFeatures(); std::vector< std::vector<ftk::IntrinsicFeatures> > *f = &myfeatures; int max_track_num = 0; for(int cox=0; cox< f->size(); cox++) { for(int coy =0; coy < (*f)[cox].size(); coy ++) { max_track_num = MAX((*f)[cox][coy].num,max_track_num); } } printf("Computed max_track_num = %d\n",max_track_num); double time_offset = 5;//(m_model->getRawImagePointer(0)->GetLargestPossibleRegion().GetSize()[2])*3;//*((*f)[0][0].spacing[2]); printf("About to start creating tobj\n"); m_tobj = new TraceObject(); for(int counter= 0; counter<= max_track_num; counter++) { TraceLine *tline = new TraceLine(); bool once = false; for(int cox=0; cox< f->size(); cox++) { for(int coy =0; coy < (*f)[cox].size(); coy ++) { if((*f)[cox][coy].num == counter) { TraceBit tbit; tbit.x = (*f)[cox][coy].Centroid[0]*1.0; tbit.y = (*f)[cox][coy].Centroid[1]*1.0; tbit.z = ((*f)[cox][coy].time)*(time_offset); tbit.time = (*f)[cox][coy].time; tbit.id = (*f)[cox][coy].num; printf("About to add TraceBit\n"); tline->AddTraceBit(tbit); once = true; } } } if(once) { m_tobj->GetTraceLinesPointer()->push_back(tline); printf("Added one tline\n"); } else { delete tline; } } printf("Finished GenerateTracks() \n"); return; }
void TrackingKymoView::DeleteDiffTData(std::set<unsigned int> difft_selection) { std::set<unsigned int>::iterator sel_iter; for(sel_iter = difft_selection.begin(); sel_iter!= difft_selection.end(); ++sel_iter) { unsigned int vtk_cell_id = *sel_iter; TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashc[vtk_cell_id]); std::cout<<"deleting cell:"<<vtk_cell_id<<" with id: "<<tline->GetId()<<std::endl; TraceBit tb1 = tline->subtrace_hash[vtk_cell_id].at(0); TraceBit tb2 = tline->subtrace_hash[vtk_cell_id].at(1); int maxtime = MAX(tb1.time,tb2.time); std::vector<TraceLine*>* trace_lines = m_tobj->GetTraceLinesPointer(); std::vector<TraceLine*>::iterator trace_lines_iter; for(trace_lines_iter = trace_lines->begin() ;trace_lines_iter!= trace_lines->end(); ++trace_lines_iter) { if(tline->GetId() == (*trace_lines_iter)->GetId()) { int new_id = this->GetMaxId()+1; trace_lines->erase(trace_lines_iter); TraceLine::TraceBitsType::iterator tbit_iter = tline->GetTraceBitIteratorBegin(); TraceLine * new_tline1 = new TraceLine(); TraceLine * new_tline2 = new TraceLine(); ObjectSelection::Point point; while(tbit_iter != tline->GetTraceBitIteratorEnd()) { if((*tbit_iter).time < maxtime) { new_tline1->AddTraceBit(*tbit_iter); } else { point.id = tbit_iter->id; point.time = tbit_iter->time; (*tbit_iter).id = new_id; point.new_id = new_id; points_from_delete.push_back(point); new_tline2->AddTraceBit(*tbit_iter); } ++tbit_iter; } trace_lines->push_back(new_tline1); new_tline2->SetId(new_id); trace_lines->push_back(new_tline2); break; } } } }
void TrackingKymoView::DeleteAndRelabelData(void) { if(TSelection.empty()) return; std::vector<unsigned int> tmp_selection; std::set<unsigned int> samet_selection; // list of sub-tracks selected within the same track //std::set<unsigned int> difft_selection; std::map<int, std::set<unsigned int> > selection_map; std::set<unsigned int>::iterator sel_iter; for(sel_iter = TSelection.begin(); sel_iter!= TSelection.end(); ++sel_iter) tmp_selection.push_back(*sel_iter); // figure out the number of different selected tracks: std::set<int> selected_ids; for(int i = 0; i< tmp_selection.size(); ++i) { TraceLine *tline1 = reinterpret_cast<TraceLine*>(m_tobj->hashc[tmp_selection.at(i)]); selected_ids.insert(tline1->GetId()); } std::set<int>::iterator sel_ids_iter; for(sel_ids_iter = selected_ids.begin(); sel_ids_iter!= selected_ids.end(); ++sel_ids_iter) { std::set<unsigned int> samet_selection; for(int i = 0; i< tmp_selection.size(); ++i) { TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashc[tmp_selection.at(i)]); int id = tline->GetId(); if(tline->GetId() == *sel_ids_iter) samet_selection.insert(tmp_selection.at(i)); } selection_map[*sel_ids_iter] = samet_selection; } std::map<int, std::set<unsigned int> >::iterator select_map_iter; for(select_map_iter = selection_map.begin(); select_map_iter!= selection_map.end(); ++select_map_iter) { if(!(*select_map_iter).second.empty()&& (*select_map_iter).second.size()>1) this->DeleteSameTData((*select_map_iter).second); else if(!(*select_map_iter).second.empty()&& (*select_map_iter).second.size()==1) this->DeleteDiffTData((*select_map_iter).second); } if(!points_from_delete.empty()) { Selection->SelectPoints(points_from_delete); points_from_delete.clear(); } }
void NVMain::PrintPreTrace( NVMainRequest *request ) { /* * Here we can generate a data trace to use with trace-based testing later. */ if( p->PrintPreTrace || p->EchoPreTrace ) { TraceLine tl; tl.SetLine( request->address, request->type, GetEventQueue( )->GetCurrentCycle( ), request->data, request->threadId ); preTracer->SetNextAccess( &tl ); } }
/** * The main import function... */ int CachegrindLoader::loadInternal(TraceData* data, QIODevice* device, const QString& filename) { if (!data || !device) return 0; _data = data; _filename = filename; _lineNo = 0; loadStart(_filename); FixFile file(device, _filename); if (!file.exists()) { loadFinished(QStringLiteral("File does not exist")); return 0; } int statusProgress = 0; #if USE_FIXCOST // FixCost Memory Pool FixPool* pool = _data->fixPool(); #endif _part = 0; partsAdded = 0; prepareNewPart(); FixString line; char c; // current position nextLineType = SelfCost; // default if there is no "positions:" line hasLineInfo = true; hasAddrInfo = false; while (file.nextLine(line)) { _lineNo++; #if TRACE_LOADER qDebug() << "[CachegrindLoader] " << _filename << ":" << _lineNo << " - '" << QString(line) << "'"; #endif // if we cannot strip a character, this was an empty line if (!line.first(c)) continue; if (c <= '9') { if (c == '#') continue; // parse position(s) if (!parsePosition(line, currentPos)) { error(QStringLiteral("Invalid position specification '%1'").arg(line)); continue; } // go through after big switch } else { // if (c > '9') line.stripFirst(c); /* in order of probability */ switch(c) { case 'f': // fl= if (line.stripPrefix("l=")) { setFile(line); // this is the default for new functions currentFunctionFile = currentFile; continue; } // fi=, fe= if (line.stripPrefix("i=") || line.stripPrefix("e=")) { setFile(line); continue; } // fn= if (line.stripPrefix("n=")) { if (currentFile != currentFunctionFile) currentFile = currentFunctionFile; setFunction(line); // on a new function, update status int progress = (int)(100.0 * file.current() / file.len() +.5); if (progress != statusProgress) { statusProgress = progress; /* When this signal is connected, it most probably * should lead to GUI update. Thus, when multiple * "long operations" (like file loading) are in progress, * this can temporarly switch to another operation. */ loadProgress(statusProgress); } continue; } break; case 'c': // cob= if (line.stripPrefix("ob=")) { setCalledObject(line); continue; } // cfi= / cfl= if (line.stripPrefix("fl=") || line.stripPrefix("fi=")) { setCalledFile(line); continue; } // cfn= if (line.stripPrefix("fn=")) { setCalledFunction(line); continue; } // calls= if (line.stripPrefix("alls=")) { // ignore long lines... line.stripUInt64(currentCallCount); nextLineType = CallCost; continue; } // cmd: if (line.stripPrefix("md:")) { QString command = QString(line).trimmed(); if (!_data->command().isEmpty() && _data->command() != command) { error(QStringLiteral("Redefined command, was '%1'").arg(_data->command())); } _data->setCommand(command); continue; } // creator: if (line.stripPrefix("reator:")) { // ignore ... continue; } break; case 'j': // jcnd= if (line.stripPrefix("cnd=")) { bool valid; valid = line.stripUInt64(jumpsFollowed) && line.stripPrefix("/") && line.stripUInt64(jumpsExecuted) && parsePosition(line, targetPos); if (!valid) { error(QStringLiteral("Invalid line after 'jcnd'")); } else nextLineType = CondJump; continue; } if (line.stripPrefix("ump=")) { bool valid; valid = line.stripUInt64(jumpsExecuted) && parsePosition(line, targetPos); if (!valid) { error(QStringLiteral("Invalid line after 'jump'")); } else nextLineType = BoringJump; continue; } // jfi= if (line.stripPrefix("fi=")) { currentJumpToFile = compressedFile(line); continue; } // jfn= if (line.stripPrefix("fn=")) { if (!currentJumpToFile) { // !=0 as functions needs file currentJumpToFile = currentFile; } currentJumpToFunction = compressedFunction(line, currentJumpToFile, currentObject); continue; } break; case 'o': // ob= if (line.stripPrefix("b=")) { setObject(line); continue; } break; case '#': continue; case 'a': // "arch: arm" if (line.stripPrefix("rch: arm")) { TraceData::Arch a = _data->architecture(); if ((a != TraceData::ArchUnknown) && (a != TraceData::ArchARM)) { error(QStringLiteral("Redefined architecture!")); } _data->setArchitecture(TraceData::ArchARM); continue; } break; case 't': // totals: if (line.stripPrefix("otals:")) continue; // thread: if (line.stripPrefix("hread:")) { prepareNewPart(); _part->setThreadID(QString(line).toInt()); continue; } // timeframe (BB): if (line.stripPrefix("imeframe (BB):")) { _part->setTimeframe(line); continue; } break; case 'd': // desc: if (line.stripPrefix("esc:")) { line.stripSurroundingSpaces(); // desc: Trigger: if (line.stripPrefix("Trigger:")) { _part->setTrigger(line); } continue; } break; case 'e': // events: if (line.stripPrefix("vents:")) { prepareNewPart(); mapping = _data->eventTypes()->createMapping(line); _part->setEventMapping(mapping); continue; } // event:<name>[=<formula>][:<long name>] if (line.stripPrefix("vent:")) { line.stripSurroundingSpaces(); FixString e, f, l; if (!line.stripName(e)) { error(QStringLiteral("Invalid event")); continue; } line.stripSpaces(); if (!line.stripFirst(c)) continue; if (c=='=') f = line.stripUntil(':'); line.stripSpaces(); // add to known cost types if (line.isEmpty()) line = e; EventType::add(new EventType(e,line,f)); continue; } break; case 'p': // part: if (line.stripPrefix("art:")) { prepareNewPart(); _part->setPartNumber(QString(line).toInt()); continue; } // pid: if (line.stripPrefix("id:")) { prepareNewPart(); _part->setProcessID(QString(line).toInt()); continue; } // positions: if (line.stripPrefix("ositions:")) { prepareNewPart(); QString positions(line); hasLineInfo = positions.contains(QStringLiteral("line")); hasAddrInfo = positions.contains(QStringLiteral("instr")); continue; } break; case 'v': // version: if (line.stripPrefix("ersion:")) { // ignore for now continue; } break; case 's': // summary: if (line.stripPrefix("ummary:")) { if (!mapping) { error(QStringLiteral("No event line found. Skipping file")); delete _part; return false; } _part->totals()->set(mapping, line); continue; } case 'r': // rcalls= (deprecated) if (line.stripPrefix("calls=")) { // handle like normal calls: we need the sum of call count // recursive cost is discarded in cycle detection line.stripUInt64(currentCallCount); nextLineType = CallCost; warning(QStringLiteral("Old file format using deprecated 'rcalls'")); continue; } break; default: break; } error(QStringLiteral("Invalid line '%1%2'").arg(c).arg(line)); continue; } if (!mapping) { error(QStringLiteral("No event line found. Skipping file")); delete _part; return false; } // for a cost line, we always need a current function ensureFunction(); if (!currentFunctionSource || (currentFunctionSource->file() != currentFile)) { currentFunctionSource = currentFunction->sourceFile(currentFile, true); } #if !USE_FIXCOST if (hasAddrInfo) { if (!currentInstr || (currentInstr->addr() != currentPos.fromAddr)) { currentInstr = currentFunction->instr(currentPos.fromAddr, true); if (!currentInstr) { error(QString("Invalid address '%1'").arg(currentPos.fromAddr.toString())); continue; } currentPartInstr = currentInstr->partInstr(_part, currentPartFunction); } } if (hasLineInfo) { if (!currentLine || (currentLine->lineno() != currentPos.fromLine)) { currentLine = currentFunctionSource->line(currentPos.fromLine, true); currentPartLine = currentLine->partLine(_part, currentPartFunction); } if (hasAddrInfo && currentInstr) currentInstr->setLine(currentLine); } #endif #if TRACE_LOADER qDebug() << _filename << ":" << _lineNo; qDebug() << " currentInstr " << (currentInstr ? qPrintable(currentInstr->toString()) : "."); qDebug() << " currentLine " << (currentLine ? qPrintable(currentLine->toString()) : ".") << "( file " << currentFile->name() << ")"; qDebug() << " currentFunction " << qPrintable(currentFunction->prettyName()); qDebug() << " currentCalled " << (currentCalledFunction ? qPrintable(currentCalledFunction->prettyName()) : "."); #endif // create cost item if (nextLineType == SelfCost) { #if USE_FIXCOST new (pool) FixCost(_part, pool, currentFunctionSource, currentPos, currentPartFunction, line); #else if (hasAddrInfo) { TracePartInstr* partInstr; partInstr = currentInstr->partInstr(_part, currentPartFunction); if (hasLineInfo) { // we need to set <line> back after reading for the line int l = line.len(); const char* s = line.ascii(); partInstr->addCost(mapping, line); line.set(s,l); } else partInstr->addCost(mapping, line); } if (hasLineInfo) { TracePartLine* partLine; partLine = currentLine->partLine(_part, currentPartFunction); partLine->addCost(mapping, line); } #endif if (!line.isEmpty()) { error(QStringLiteral("Garbage at end of cost line ('%1')").arg(line)); } } else if (nextLineType == CallCost) { nextLineType = SelfCost; TraceCall* calling = currentFunction->calling(currentCalledFunction); TracePartCall* partCalling = calling->partCall(_part, currentPartFunction, currentCalledPartFunction); #if USE_FIXCOST FixCallCost* fcc; fcc = new (pool) FixCallCost(_part, pool, currentFunctionSource, hasLineInfo ? currentPos.fromLine : 0, hasAddrInfo ? currentPos.fromAddr : Addr(0), partCalling, currentCallCount, line); fcc->setMax(_data->callMax()); _data->updateMaxCallCount(fcc->callCount()); #else if (hasAddrInfo) { TraceInstrCall* instrCall; TracePartInstrCall* partInstrCall; instrCall = calling->instrCall(currentInstr); partInstrCall = instrCall->partInstrCall(_part, partCalling); partInstrCall->addCallCount(currentCallCount); if (hasLineInfo) { // we need to set <line> back after reading for the line int l = line.len(); const char* s = line.ascii(); partInstrCall->addCost(mapping, line); line.set(s,l); } else partInstrCall->addCost(mapping, line); // update maximum of call cost _data->callMax()->maxCost(partInstrCall); _data->updateMaxCallCount(partInstrCall->callCount()); } if (hasLineInfo) { TraceLineCall* lineCall; TracePartLineCall* partLineCall; lineCall = calling->lineCall(currentLine); partLineCall = lineCall->partLineCall(_part, partCalling); partLineCall->addCallCount(currentCallCount); partLineCall->addCost(mapping, line); // update maximum of call cost _data->callMax()->maxCost(partLineCall); _data->updateMaxCallCount(partLineCall->callCount()); } #endif currentCalledFile = 0; currentCalledPartFile = 0; currentCalledObject = 0; currentCalledPartObject = 0; currentCallCount = 0; if (!line.isEmpty()) { error(QStringLiteral("Garbage at end of call cost line ('%1')").arg(line)); } } else { // (nextLineType == BoringJump || nextLineType == CondJump) TraceFunctionSource* targetSource; if (!currentJumpToFunction) currentJumpToFunction = currentFunction; targetSource = (currentJumpToFile) ? currentJumpToFunction->sourceFile(currentJumpToFile, true) : currentFunctionSource; #if USE_FIXCOST new (pool) FixJump(_part, pool, /* source */ hasLineInfo ? currentPos.fromLine : 0, hasAddrInfo ? currentPos.fromAddr : 0, currentPartFunction, currentFunctionSource, /* target */ hasLineInfo ? targetPos.fromLine : 0, hasAddrInfo ? targetPos.fromAddr : Addr(0), currentJumpToFunction, targetSource, (nextLineType == CondJump), jumpsExecuted, jumpsFollowed); #else if (hasAddrInfo) { TraceInstr* jumpToInstr; TraceInstrJump* instrJump; TracePartInstrJump* partInstrJump; jumpToInstr = currentJumpToFunction->instr(targetPos.fromAddr, true); instrJump = currentInstr->instrJump(jumpToInstr, (nextLineType == CondJump)); partInstrJump = instrJump->partInstrJump(_part); partInstrJump->addExecutedCount(jumpsExecuted); if (nextLineType == CondJump) partInstrJump->addFollowedCount(jumpsFollowed); } if (hasLineInfo) { TraceLine* jumpToLine; TraceLineJump* lineJump; TracePartLineJump* partLineJump; jumpToLine = targetSource->line(targetPos.fromLine, true); lineJump = currentLine->lineJump(jumpToLine, (nextLineType == CondJump)); partLineJump = lineJump->partLineJump(_part); partLineJump->addExecutedCount(jumpsExecuted); if (nextLineType == CondJump) partLineJump->addFollowedCount(jumpsFollowed); } #endif if (0) { qDebug() << _filename << ":" << _lineNo << " - jump from 0x" << currentPos.fromAddr.toString() << " (line " << currentPos.fromLine << ") to 0x" << targetPos.fromAddr.toString() << " (line " << targetPos.fromLine << ")"; if (nextLineType == BoringJump) qDebug() << " Boring Jump, count " << jumpsExecuted.pretty(); else qDebug() << " Cond. Jump, followed " << jumpsFollowed.pretty() << ", executed " << jumpsExecuted.pretty(); } nextLineType = SelfCost; currentJumpToFunction = 0; currentJumpToFile = 0; if (!line.isEmpty()) { error(QStringLiteral("Garbage at end of jump cost line ('%1')").arg(line)); } } } loadFinished(); if (mapping) { _part->invalidate(); _part->totals()->clear(); _part->totals()->addCost(_part); data->addPart(_part); partsAdded++; } else { delete _part; } device->close(); return partsAdded; }
/* If sourceList is empty we set the source file name into the header, * else this code is of a inlined function, and we add "inlined from..." */ void SourceView::fillSourceFile(TraceFunctionSource* sf, int fileno) { if (!sf) return; if (0) qDebug("Selected Item %s", _selectedItem ? _selectedItem->name().ascii() : "(none)"); TraceLineMap::Iterator lineIt, lineItEnd; int nextCostLineno = 0, lastCostLineno = 0; bool validSourceFile = (!sf->file()->name().isEmpty()); TraceLine* sLine = 0; if (_selectedItem) { if (_selectedItem->type() == TraceItem::Line) sLine = (TraceLine*) _selectedItem; if (_selectedItem->type() == TraceItem::Instr) sLine = ((TraceInstr*)_selectedItem)->line(); } if (validSourceFile) { TraceLineMap* lineMap = sf->lineMap(); if (lineMap) { lineIt = lineMap->begin(); lineItEnd = lineMap->end(); // get first line with cost of selected type while(lineIt != lineItEnd) { if (&(*lineIt) == sLine) break; if ((*lineIt).hasCost(_costType)) break; if (_costType2 && (*lineIt).hasCost(_costType2)) break; ++lineIt; } nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno(); if (nextCostLineno<0) { kdError() << "SourceView::fillSourceFile: Negative line number " << nextCostLineno << endl << " Function '" << sf->function()->name() << "'" << endl << " File '" << sf->file()->name() << "'" << endl; nextCostLineno = 0; } } if (nextCostLineno == 0) { new SourceItem(this, this, fileno, 0, false, i18n("There is no cost of current selected type associated")); new SourceItem(this, this, fileno, 1, false, i18n("with any source line of this function in file")); new SourceItem(this, this, fileno, 2, false, QString(" '%1'").arg(sf->function()->prettyName())); new SourceItem(this, this, fileno, 3, false, i18n("Thus, no annotated source can be shown.")); return; } } QString filename = sf->file()->shortName(); QString dir = sf->file()->directory(); if (!dir.isEmpty()) filename = dir + "/" + filename; if (nextCostLineno>0) { // we have debug info... search for source file if (!QFile::exists(filename)) { QStringList list = Configuration::sourceDirs(_data, sf->function()->object()); QStringList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { dir = *it; if (checkFileExistance(dir, sf->file()->shortName())) break; } if (it == list.end()) nextCostLineno = 0; else { filename = dir + "/" + sf->file()->shortName(); // no need to search again sf->file()->setDirectory(dir); } } } // do it here, because the source directory could have been set before if (childCount()==0) { setColumnText(4, validSourceFile ? i18n("Source ('%1')").arg(filename) : i18n("Source (unknown)")); } else { new SourceItem(this, this, fileno, 0, true, validSourceFile ? i18n("--- Inlined from '%1' ---").arg(filename) : i18n("--- Inlined from unknown source ---")); } if (nextCostLineno == 0) { new SourceItem(this, this, fileno, 0, false, i18n("There is no source available for the following function:")); new SourceItem(this, this, fileno, 1, false, QString(" '%1'").arg(sf->function()->prettyName())); if (sf->file()->name().isEmpty()) { new SourceItem(this, this, fileno, 2, false, i18n("This is because no debug information is present.")); new SourceItem(this, this, fileno, 3, false, i18n("Recompile source and redo the profile run.")); if (sf->function()->object()) { new SourceItem(this, this, fileno, 4, false, i18n("The function is located in this ELF object:")); new SourceItem(this, this, fileno, 5, false, QString(" '%1'") .arg(sf->function()->object()->prettyName())); } } else { new SourceItem(this, this, fileno, 2, false, i18n("This is because its source file cannot be found:")); new SourceItem(this, this, fileno, 3, false, QString(" '%1'").arg(sf->file()->name())); new SourceItem(this, this, fileno, 4, false, i18n("Add the folder of this file to the source folder list.")); new SourceItem(this, this, fileno, 5, false, i18n("The list can be found in the configuration dialog.")); } return; } // initialisation for arrow drawing // create sorted list of jumps (for jump arrows) TraceLineMap::Iterator it = lineIt, nextIt; _lowList.clear(); _highList.clear(); while(1) { nextIt = it; ++nextIt; while(nextIt != lineItEnd) { if (&(*nextIt) == sLine) break; if ((*nextIt).hasCost(_costType)) break; if (_costType2 && (*nextIt).hasCost(_costType2)) break; ++nextIt; } TraceLineJumpList jlist = (*it).lineJumps(); TraceLineJump* lj; for (lj=jlist.first();lj;lj=jlist.next()) { if (lj->executedCount()==0) continue; // skip jumps to next source line with cost //if (lj->lineTo() == &(*nextIt)) continue; _lowList.append(lj); _highList.append(lj); } it = nextIt; if (it == lineItEnd) break; } _lowList.sort(); _highList.sort(); _lowList.first(); // iterators to list start _highList.first(); _jump.resize(0); char buf[256]; bool inside = false, skipLineWritten = true; int readBytes; int fileLineno = 0; SubCost most = 0; TraceLine* currLine; SourceItem *si, *si2, *item = 0, *first = 0, *selected = 0; QFile file(filename); if (!file.open(IO_ReadOnly)) return; while (1) { readBytes=file.readLine(buf, sizeof( buf )); if (readBytes<=0) { // for nice empty 4 lines after function with EOF buf[0] = 0; } if (readBytes >= (int) sizeof( buf )) { qDebug("%s:%d Line too long\n", sf->file()->name().ascii(), fileLineno); } else if ((readBytes>0) && (buf[readBytes-1] == '\n')) buf[readBytes-1] = 0; // keep fileLineno inside [lastCostLineno;nextCostLineno] fileLineno++; if (fileLineno == nextCostLineno) { currLine = &(*lineIt); // get next line with cost of selected type ++lineIt; while(lineIt != lineItEnd) { if (&(*lineIt) == sLine) break; if ((*lineIt).hasCost(_costType)) break; if (_costType2 && (*lineIt).hasCost(_costType2)) break; ++lineIt; } lastCostLineno = nextCostLineno; nextCostLineno = (lineIt == lineItEnd) ? 0 : (*lineIt).lineno(); } else currLine = 0; // update inside if (!inside) { if (currLine) inside = true; } else { if ( (fileLineno > lastCostLineno) && ((nextCostLineno == 0) || (fileLineno < nextCostLineno - Configuration::noCostInside()) )) inside = false; } int context = Configuration::context(); if ( ((lastCostLineno==0) || (fileLineno > lastCostLineno + context)) && ((nextCostLineno==0) || (fileLineno < nextCostLineno - context))) { if (lineIt == lineItEnd) break; if (!skipLineWritten) { skipLineWritten = true; // a "skipping" line: print "..." instead of a line number strcpy(buf,"..."); } else continue; } else skipLineWritten = false; si = new SourceItem(this, this, fileno, fileLineno, inside, QString(buf), currLine); if (!currLine) continue; if (!selected && (currLine == sLine)) selected = si; if (!first) first = si; if (currLine->subCost(_costType) > most) { item = si; most = currLine->subCost(_costType); } si->setOpen(true); TraceLineCallList list = currLine->lineCalls(); TraceLineCall* lc; for (lc=list.first();lc;lc=list.next()) { if ((lc->subCost(_costType)==0) && (lc->subCost(_costType2)==0)) continue; if (lc->subCost(_costType) > most) { item = si; most = lc->subCost(_costType); } si2 = new SourceItem(this, si, fileno, fileLineno, currLine, lc); if (!selected && (lc->call()->called() == _selectedItem)) selected = si2; } TraceLineJumpList jlist = currLine->lineJumps(); TraceLineJump* lj; for (lj=jlist.first();lj;lj=jlist.next()) { if (lj->executedCount()==0) continue; new SourceItem(this, si, fileno, fileLineno, currLine, lj); } } if (selected) item = selected; if (item) first = item; if (first) { ensureItemVisible(first); _inSelectionUpdate = true; setCurrentItem(first); _inSelectionUpdate = false; } file.close(); // for arrows: go down the list according to list sorting sort(); QListViewItem *item1, *item2; for (item1=firstChild();item1;item1 = item1->nextSibling()) { si = (SourceItem*)item1; updateJumpArray(si->lineno(), si, true, false); for (item2=item1->firstChild();item2;item2 = item2->nextSibling()) { si2 = (SourceItem*)item2; if (si2->lineJump()) updateJumpArray(si->lineno(), si2, false, true); else si2->setJumpArray(_jump); } } if (arrowLevels()) setColumnWidth(3, 10 + 6*arrowLevels() + itemMargin() * 2); else setColumnWidth(3, 0); }
bool TrackingKymoView::IsValidNodeConnection(void) { if(NSelection.empty()|| NSelection.size()!=2) return false; std::set<unsigned int>::iterator node_vtk_ids_iter; std::vector<unsigned int> node_ids; for(node_vtk_ids_iter = NSelection.begin(); node_vtk_ids_iter!= NSelection.end(); ++node_vtk_ids_iter) { TraceLine *tline = reinterpret_cast<TraceLine*>(m_tobj->hashp[*node_vtk_ids_iter]); int tbit_time = tline->points_hash[*node_vtk_ids_iter].time; TraceLine::TraceBitsType::iterator tbit_iter = tline->GetTraceBitIteratorBegin(); bool endNode = true; bool beginNode = true; std::vector<bool> tmp_vector; //bool singleNode = false; while(tbit_iter!=tline->GetTraceBitIteratorEnd()) { if(tbit_iter->time > tbit_time) endNode = false; else if (tbit_iter->time < tbit_time) beginNode = false; ++tbit_iter; } tline->points_hash[*node_vtk_ids_iter].end = endNode; tline->points_hash[*node_vtk_ids_iter].begin = beginNode; node_ids.push_back(*node_vtk_ids_iter); } // now compare the two nodes: if(node_ids.size()!=2) { printf("something is up with the selection\n"); return false; } TraceBit tbit1 = (reinterpret_cast<TraceLine*>(m_tobj->hashp[node_ids.at(0)]))->points_hash[node_ids.at(0)]; TraceBit tbit2 = (reinterpret_cast<TraceLine*>(m_tobj->hashp[node_ids.at(1)]))->points_hash[node_ids.at(1)]; bool isvalid = false; // one is at end and the other is at begin: if(tbit1.end == true && tbit1.begin == false && tbit2.end == false && tbit2.begin == true) { int timediff = (tbit2.time - tbit1.time); if( timediff >0 && timediff< 3) isvalid = true; } else if (tbit1.end == false && tbit1.begin == true && tbit2.end == true && tbit2.begin == false) { int timediff = (tbit1.time - tbit2.time); if( timediff >0 && timediff< 4) isvalid = true; } // one is at end or begin and the other is a single node: else if (tbit1.end == true && tbit1.begin == true && tbit2.end == true && tbit2.begin == false) { int timediff = (tbit1.time - tbit2.time); if( timediff >0 && timediff< 3) isvalid = true; } else if (tbit1.end == true && tbit1.begin == true && tbit2.end == false && tbit2.begin == true) { int timediff = (tbit2.time - tbit1.time); if( timediff >0 && timediff< 3) isvalid = true; } else if (tbit1.end == false && tbit1.begin == true && tbit2.end == true && tbit2.begin == true) { int timediff = (tbit1.time - tbit2.time); if( timediff >0 && timediff< 3) isvalid = true; } else if (tbit1.end == true && tbit1.begin == false && tbit2.end == true && tbit2.begin == true) { int timediff = (tbit2.time - tbit1.time); if( timediff >0 && timediff< 3) isvalid = true; } return isvalid; }
int TraceMain::RunTrace( int argc, char *argv[] ) { Stats *stats = new Stats( ); Config *config = new Config( ); GenericTraceReader *trace = NULL; TraceLine *tl = new TraceLine( ); SimInterface *simInterface = new NullInterface( ); NVMain *nvmain = new NVMain( ); EventQueue *mainEventQueue = new EventQueue( ); GlobalEventQueue *globalEventQueue = new GlobalEventQueue( ); TagGenerator *tagGenerator = new TagGenerator( 1000 ); bool IgnoreData = false; bool EventDriven = false; uint64_t simulateCycles; uint64_t currentCycle; if( argc < 4 ) { std::cout << "Usage: nvmain CONFIG_FILE TRACE_FILE CYCLES [PARAM=value ...]" << std::endl; return 1; } /* Print out the command line that was provided. */ std::cout << "NVMain command line is:" << std::endl; for( int curArg = 0; curArg < argc; ++curArg ) { std::cout << argv[curArg] << " "; } std::cout << std::endl << std::endl; config->Read( argv[1] ); config->SetSimInterface( simInterface ); SetEventQueue( mainEventQueue ); SetGlobalEventQueue( globalEventQueue ); SetStats( stats ); SetTagGenerator( tagGenerator ); std::ofstream statStream; /* Allow for overriding config parameter values for trace simulations from command line. */ if( argc > 4 ) { for( int curArg = 4; curArg < argc; ++curArg ) { std::string clParam, clValue, clPair; clPair = argv[curArg]; clParam = clPair.substr( 0, clPair.find_first_of("=")); clValue = clPair.substr( clPair.find_first_of("=") + 1, std::string::npos ); std::cout << "Overriding " << clParam << " with '" << clValue << "'" << std::endl; config->SetValue( clParam, clValue ); } } if( config->KeyExists( "StatsFile" ) ) { statStream.open( config->GetString( "StatsFile" ).c_str(), std::ofstream::out | std::ofstream::app ); } if( config->KeyExists( "IgnoreData" ) && config->GetString( "IgnoreData" ) == "true" ) { IgnoreData = true; } config->GetBool( "EventDriven", EventDriven ); /* Add any specified hooks */ std::vector<std::string>& hookList = config->GetHooks( ); for( size_t i = 0; i < hookList.size( ); i++ ) { std::cout << "Creating hook " << hookList[i] << std::endl; NVMObject *hook = HookFactory::CreateHook( hookList[i] ); if( hook != NULL ) { AddHook( hook ); hook->SetParent( this ); hook->Init( config ); } else { std::cout << "Warning: Could not create a hook named `" << hookList[i] << "'." << std::endl; } } AddChild( nvmain ); nvmain->SetParent( this ); globalEventQueue->SetFrequency( config->GetEnergy( "CPUFreq" ) * 1000000.0 ); globalEventQueue->AddSystem( nvmain, config ); simInterface->SetConfig( config, true ); nvmain->SetConfig( config, "defaultMemory", true ); std::cout << "traceMain (" << (void*)(this) << ")" << std::endl; nvmain->PrintHierarchy( ); if( config->KeyExists( "TraceReader" ) ) trace = TraceReaderFactory::CreateNewTraceReader( config->GetString( "TraceReader" ) ); else trace = TraceReaderFactory::CreateNewTraceReader( "NVMainTrace" ); trace->SetTraceFile( argv[2] ); if( argc == 3 ) simulateCycles = 0; else simulateCycles = atoi( argv[3] ); std::cout << "*** Simulating " << simulateCycles << " input cycles. ("; /* * The trace cycle is assumed to be the rate that the CPU/LLC is issuing. * Scale the simulation cycles to be the number of *memory cycles* to run. */ simulateCycles = (uint64_t)ceil( ((double)(config->GetValue( "CPUFreq" )) / (double)(config->GetValue( "CLK" ))) * simulateCycles ); std::cout << simulateCycles << " memory cycles) ***" << std::endl; currentCycle = 0; while( currentCycle <= simulateCycles || simulateCycles == 0 ) { if( !trace->GetNextAccess( tl ) ) { /* Force all modules to drain requests. */ bool draining = Drain( ); std::cout << "Could not read next line from trace file!" << std::endl; /* Wait for requests to drain. */ while( outstandingRequests > 0 ) { if( EventDriven ) globalEventQueue->Cycle( 1 ); else GetChild( )->Cycle( 1 ); currentCycle++; /* Retry drain each cycle if it failed. */ if( !draining ) draining = Drain( ); } break; } NVMainRequest *request = new NVMainRequest( ); request->address = tl->GetAddress( ); request->type = tl->GetOperation( ); request->bulkCmd = CMD_NOP; request->threadId = tl->GetThreadId( ); if( !IgnoreData ) request->data = tl->GetData( ); if( !IgnoreData ) request->oldData = tl->GetOldData( ); request->status = MEM_REQUEST_INCOMPLETE; request->owner = (NVMObject *)this; /* * If you want to ignore the cycles used in the trace file, just set * the cycle to 0. */ if( config->KeyExists( "IgnoreTraceCycle" ) && config->GetString( "IgnoreTraceCycle" ) == "true" ) tl->SetLine( tl->GetAddress( ), tl->GetOperation( ), 0, tl->GetData( ), tl->GetOldData( ), tl->GetThreadId( ) ); if( request->type != READ && request->type != WRITE ) std::cout << "traceMain: Unknown Operation: " << request->type << std::endl; /* * If the next operation occurs after the requested number of cycles, * we can quit. */ if( tl->GetCycle( ) > simulateCycles && simulateCycles != 0 ) { if( EventDriven ) { globalEventQueue->Cycle( simulateCycles - currentCycle ); currentCycle += simulateCycles - currentCycle; break; } /* Just ride it out 'til the end. */ while( currentCycle < simulateCycles ) { GetChild( )->Cycle( 1 ); currentCycle++; } break; } else { /* * If the command is in the past, it can be issued. This would * occur since the trace was probably generated with an inaccurate * memory * simulator, so the cycles may not match up. Otherwise, * we need to wait. */ if( tl->GetCycle( ) > currentCycle ) { if( EventDriven ) { globalEventQueue->Cycle( tl->GetCycle() - currentCycle ); currentCycle = globalEventQueue->GetCurrentCycle( ); } else { /* Wait until currentCycle is the trace operation's cycle. */ while( currentCycle < tl->GetCycle( ) ) { if( currentCycle >= simulateCycles && simulateCycles != 0 ) break; GetChild( )->Cycle( 1 ); currentCycle++; } } if( currentCycle >= simulateCycles && simulateCycles != 0 ) break; } /* * Wait for the memory controller to accept the next command.. * the trace reader is "stalling" until then. */ while( !GetChild( )->IsIssuable( request ) ) { if( currentCycle >= simulateCycles && simulateCycles != 0 ) break; if( EventDriven ) { globalEventQueue->Cycle( 1 ); currentCycle = globalEventQueue->GetCurrentCycle( ); } else { GetChild( )->Cycle( 1 ); currentCycle++; } } outstandingRequests++; GetChild( )->IssueCommand( request ); if( currentCycle >= simulateCycles && simulateCycles != 0 ) break; } } GetChild( )->CalculateStats( ); std::ostream& refStream = (statStream.is_open()) ? statStream : std::cout; stats->PrintAll( refStream ); std::cout << "Exiting at cycle " << currentCycle << " because simCycles " << simulateCycles << " reached." << std::endl; if( outstandingRequests > 0 ) std::cout << "Note: " << outstandingRequests << " requests still in-flight." << std::endl; delete config; delete stats; return 0; }