std::string PhysicsRecord::csvDump(std::string outputDir) const { std::stringstream s; s << Utils::csv({layerTriplet, n}) << SEP; //header s << Utils::csv({efficiencyMean, toVar(efficiencyVar)}) << SEP; //efficiency s << Utils::csv({fakeRateMean, toVar(fakeRateVar)}) << SEP; //fake rate s << Utils::csv({cloneRateMean, toVar(cloneRateVar)}); //clone rate if(outputDir != ""){ //dump histograms //eta std::stringstream outputFileEta; outputFileEta << outputDir << "/eta_" << layerTriplet << ".csv"; std::ofstream etaFile(outputFileEta.str(), std::ios::trunc); etaFile << eta.csvDump(); etaFile.close(); //pt std::stringstream outputFilePt; outputFilePt << outputDir << "/pt_" << layerTriplet << ".csv"; std::ofstream ptFile(outputFilePt.str(), std::ios::trunc); ptFile << pt.csvDump(); ptFile.close(); } return s.str(); }
int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QCoreApplication::setApplicationName("ptparse"); QCoreApplication::setApplicationVersion("0.1"); QCommandLineParser parser; parser.setApplicationDescription("Extract Intel PT data from perf.data AUX buffer"); parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument("perf.data", "path to perf.data file"); parser.process(app); const QStringList args = parser.positionalArguments(); QString perfData = "perf.data"; QString ptFileName = "extracted.pt"; /* Custom path, if needed */ if (args.size() > 0) { perfData = args.at(0); /* Input perf.data file */ ptFileName = args.at(1); /* Extracted PT file */ } QFile file(perfData); if (file.open(QFile::ReadOnly)) { uchar *buf = file.map(0, file.size()); QString str(QByteArray{(char *)buf, 8}); struct perf_file_header* perfHead; perfHead = (struct perf_file_header*) buf; //qDebug() << QString("%1").arg(perfHead->data.offset, 0, 16); //qDebug() << QString("%1").arg(perfHead->data.size, 0, 16); int pos = perfHead->data.offset; fflush(stderr); int prev_pos = 0; //qDebug() << "file size:" << file.size(); while (pos < file.size()) { struct perf_event_header *h = (struct perf_event_header *) (buf + pos); switch(h->type) { case PERF_RECORD_AUXTRACE: { struct auxtrace_event *aux = (struct auxtrace_event *) (buf + pos); if (aux->size == 0) break; QByteArray baba; /* Skip 48 bytes of auxtrace_event struct also */ char *ptData = (char *) (buf + pos) + sizeof(struct auxtrace_event); baba.setRawData(ptData, aux->size); QString extn = QString::number(aux->cpu); /* Extension is AUX buf's CPU */ /* Write per-CPU files */ QFile ptFile(ptFileName + "." + extn); //qDebug() << ptFile.fileName(); ptFile.open(QIODevice::WriteOnly | QIODevice::Append); ptFile.write(baba); ptFile.close(); /* Advance pos by AUX size */ pos += aux->size; /* Advance pos by event size */ pos += h->size; } break; default: /* Advance pos by event size */ pos += h->size; break; } /* TODO: Investigate further and make sure what the extra bytes are just before header * starts. Refer https://twitter.com/tuxology/status/742701706572668928 * * If event size is 0, assume we are not an event and bail out. Usually always happens * just after some PERF_RECORD_FINISHED_ROUND events right before the perf header at * the end of perf.data */ if (prev_pos == pos) return 0; prev_pos = pos; } } return 0; }