souffle  2.0.2-371-g6315b36
Data Structures | Namespaces | Functions | Variables
Tui.h File Reference
#include "souffle/profile/CellInterface.h"
#include "souffle/profile/HtmlGenerator.h"
#include "souffle/profile/Iteration.h"
#include "souffle/profile/OutputProcessor.h"
#include "souffle/profile/ProfileDatabase.h"
#include "souffle/profile/ProfileEvent.h"
#include "souffle/profile/ProgramRun.h"
#include "souffle/profile/Reader.h"
#include "souffle/profile/Relation.h"
#include "souffle/profile/Row.h"
#include "souffle/profile/Rule.h"
#include "souffle/profile/StringUtils.h"
#include "souffle/profile/Table.h"
#include "souffle/profile/UserInputReader.h"
#include "souffle/utility/MiscUtil.h"
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <iterator>
#include <map>
#include <memory>
#include <ratio>
#include <set>
#include <string>
#include <thread>
#include <unordered_map>
#include <utility>
#include <vector>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
Include dependency graph for Tui.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

class  souffle::profile::Tui
 
struct  souffle::profile::Tui::Usage
 

Namespaces

 souffle
 
 souffle::profile
 

Functions

void configuration ()
 
std::string genJson ()
 
std::stringstream & genJsonAtoms (std::stringstream &ss)
 
std::stringstream & genJsonConfiguration (std::stringstream &ss)
 
std::stringstream & souffle::genJsonRules (std::stringstream &ss, const std::string &name, size_t maxRows)
 
std::stringstream & souffle::genJsonUsage (std::stringstream &ss)
 
uint32_t getTermWidth ()
 
std::set< Usage > getUsageStats (size_t width=size_t(-1))
 
void graphBySize (std::vector< size_t > list)
 
void graphByTime (std::vector< std::chrono::microseconds > list)
 
static void help ()
 
void id (std::string col)
 
void iterRel (std::string c, std::string col)
 
void iterRul (std::string c, std::string col)
 
void memoryUsage (std::chrono::microseconds, std::chrono::microseconds, uint32_t height=20)
 
void memoryUsage (uint32_t height=20)
 
void outputHtml (std::string filename="profiler_html/")
 
void quit ()
 
void rel (size_t limit, bool showLimit=true)
 
void relRul (std::string str)
 
void rul (size_t limit, bool showLimit=true)
 
void setResultLimit (size_t limit)
 
void setupTabCompletion ()
 
void top ()
 
void updateDB ()
 
void usage (std::chrono::microseconds endTime, std::chrono::microseconds startTime, uint32_t height=20)
 
void usage (uint32_t height=20)
 
void usageRelation (std::string id)
 
void usageRule (std::string id)
 
void verAtoms (Table &atomTable, const std::string &ruleName="")
 
void verGraph (std::string c, std::string col)
 
void verRul (std::string str)
 

Variables

class souffle::profile::Tui souffle::profile::ss
 

Function Documentation

◆ configuration()

void configuration ( )

Definition at line 1009 of file Tui.h.

1009  {
1010  std::cout << "Configuration" << '\n';
1011  printf("%30s %s", "Key", "Value\n\n");
1012  for (auto& kvp :
1013  ProfileEventSingleton::instance().getDB().getStringMap({"program", "configuration"})) {
1014  if (kvp.first == "") {
1015  printf("%30s %s\n", "Datalog input file", kvp.second.c_str());
1016  continue;
1017  }
1018  printf("%30s %s\n", kvp.first.c_str(), kvp.second.c_str());
1019  }
1020  std::cout << std::endl;
1021  }

References souffle::ProfileEventSingleton::instance(), and tinyformat::printf().

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ genJson()

std::string genJson ( )

Definition at line 611 of file Tui.h.

611  {
612  std::stringstream ss;
613 
614  genJsonTop(ss);
615  ss << ",\n";
616  genJsonRelations(ss, "topRel", 3);
617  ss << ",\n";
618  genJsonRules(ss, "topRul", 3);
619  ss << ",\n";
620  genJsonRelations(ss, "rel", relationTable.rows.size());
621  ss << ",\n";
622  genJsonRules(ss, "rul", ruleTable.rows.size());
623  ss << ",\n";
624  genJsonUsage(ss);
625  ss << ",\n";
627  ss << ",\n";
628  genJsonAtoms(ss);
629  ss << '\n';
630 
631  ss << "};\n";
632 
633  return ss.str();
634  }

References genJsonAtoms(), genJsonConfiguration(), souffle::profile::Tui::genJsonRelations(), souffle::genJsonRules(), souffle::profile::Tui::genJsonTop(), souffle::genJsonUsage(), souffle::profile::Tui::relationTable, souffle::profile::Table::rows, souffle::profile::Tui::ruleTable, and souffle::profile::ss.

Referenced by outputHtml().

Here is the call graph for this function:

◆ genJsonAtoms()

std::stringstream& genJsonAtoms ( std::stringstream &  ss)

Definition at line 549 of file Tui.h.

549  {
550  const std::shared_ptr<ProgramRun>& run = out.getProgramRun();
551 
552  auto comma = [&ss](bool& first, const std::string& delimiter = ", ") {
553  if (!first) {
554  ss << delimiter;
555  } else {
556  first = false;
557  }
558  };
559 
560  ss << R"_("atoms": {)_";
561 
562  bool firstRow = true;
563  for (auto& relation : run->getRelationMap()) {
564  // Get atoms for non-recursive rules
565  for (auto& rule : relation.second->getRuleMap()) {
566  comma(firstRow, ", \n");
567  ss << '"' << rule.second->getId() << R"_(": [)_";
568  bool firstCol = true;
569  for (auto& atom : rule.second->getAtoms()) {
570  comma(firstCol);
571  std::string relationName = atom.identifier;
572  relationName = relationName.substr(0, relationName.find('('));
573  auto* relation = out.getProgramRun()->getRelation(relationName);
574  std::string relationSize = relation == nullptr ? "" : std::to_string(relation->size());
575  ss << '[';
576  ss << '"' << Tools::cleanJsonOut(Tools::cleanString(atom.rule)) << R"_(", )_";
577  ss << '"' << Tools::cleanJsonOut(atom.identifier) << R"_(", )_";
578  ss << relationSize << ", ";
579  ss << atom.frequency << ']';
580  }
581  ss << "]";
582  }
583  // Get atoms for recursive rules
584  for (auto& iteration : relation.second->getIterations()) {
585  for (auto& rule : iteration->getRules()) {
586  comma(firstRow, ", \n");
587  ss << '"' << rule.second->getId() << R"_(": [)_";
588  bool firstCol = true;
589  for (auto& atom : rule.second->getAtoms()) {
590  comma(firstCol);
591  std::string relationName = atom.identifier;
592  relationName = relationName.substr(0, relationName.find('('));
593  auto* relation = out.getProgramRun()->getRelation(relationName);
594  std::string relationSize =
595  relation == nullptr ? "" : std::to_string(relation->size());
596  ss << '[';
597  ss << '"' << Tools::cleanJsonOut(Tools::cleanString(atom.rule)) << R"_(", )_";
598  ss << '"' << Tools::cleanJsonOut(atom.identifier) << R"_(", )_";
599  ss << relationSize << ", ";
600  ss << atom.frequency << ']';
601  }
602  ss << "]";
603  }
604  }
605  }
606 
607  ss << '}';
608  return ss;
609  }

References souffle::profile::Tools::cleanJsonOut(), souffle::profile::Tools::cleanString(), souffle::profile::OutputProcessor::getProgramRun(), iteration, souffle::profile::Tui::out, relation, rule, and souffle::profile::ss.

Referenced by genJson().

Here is the call graph for this function:

◆ genJsonConfiguration()

std::stringstream& genJsonConfiguration ( std::stringstream &  ss)

Definition at line 528 of file Tui.h.

528  {
529  auto comma = [&ss](bool& first, const std::string& delimiter = ", ") {
530  if (!first) {
531  ss << delimiter;
532  } else {
533  first = false;
534  }
535  };
536 
537  // Add configuration key-value pairs
538  ss << R"_("configuration": {)_";
539  bool firstRow = true;
540  for (auto& kvp :
541  ProfileEventSingleton::instance().getDB().getStringMap({"program", "configuration"})) {
542  comma(firstRow);
543  ss << '"' << kvp.first << R"_(": ")_" << Tools::cleanJsonOut(kvp.second) << '"';
544  }
545  ss << '}';
546  return ss;
547  }

References souffle::profile::Tools::cleanJsonOut(), souffle::ProfileEventSingleton::getDB(), souffle::ProfileEventSingleton::instance(), and souffle::profile::ss.

Referenced by genJson().

Here is the call graph for this function:

◆ getTermWidth()

uint32_t getTermWidth ( )
protected

Definition at line 1478 of file Tui.h.

1478  {
1479  struct winsize w {};
1480  ioctl(0, TIOCGWINSZ, &w);
1481  uint32_t width = w.ws_col > 0 ? w.ws_col : 80;
1482  return width;
1483  }

Referenced by memoryUsage(), top(), and usage().

◆ getUsageStats()

std::set<Usage> getUsageStats ( size_t  width = size_t(-1))

Definition at line 768 of file Tui.h.

768  {
769  std::set<Usage> usages;
770  DirectoryEntry* usageStats = dynamic_cast<DirectoryEntry*>(
771  ProfileEventSingleton::instance().getDB().lookupEntry({"program", "usage", "timepoint"}));
772  if (usageStats == nullptr || usageStats->getKeys().size() < 2) {
773  return usages;
774  }
775  std::chrono::microseconds endTime{};
776  std::chrono::microseconds startTime{};
777  std::chrono::microseconds timeStep{};
778  // Translate the string ordered text usage stats to a time ordered binary form.
779  std::set<Usage> allUsages;
780  for (auto& currentKey : usageStats->getKeys()) {
781  Usage currentUsage{};
782  uint64_t cur = std::stoul(currentKey);
783  currentUsage.time = std::chrono::duration<uint64_t, std::micro>(cur);
784  cur = dynamic_cast<SizeEntry*>(
785  usageStats->readDirectoryEntry(currentKey)->readEntry("systemtime"))
786  ->getSize();
787  currentUsage.systemtime = std::chrono::duration<uint64_t, std::micro>(cur);
788  cur = dynamic_cast<SizeEntry*>(usageStats->readDirectoryEntry(currentKey)->readEntry("usertime"))
789  ->getSize();
790  currentUsage.usertime = std::chrono::duration<uint64_t, std::micro>(cur);
791  currentUsage.maxRSS =
792  dynamic_cast<SizeEntry*>(usageStats->readDirectoryEntry(currentKey)->readEntry("maxRSS"))
793  ->getSize();
794 
795  // Duplicate times are possible
796  if (allUsages.find(currentUsage) != allUsages.end()) {
797  auto& existing = *allUsages.find(currentUsage);
798  currentUsage.systemtime = std::max(existing.systemtime, currentUsage.systemtime);
799  currentUsage.usertime = std::max(existing.usertime, currentUsage.usertime);
800  currentUsage.maxRSS = std::max(existing.maxRSS, currentUsage.maxRSS);
801  allUsages.erase(currentUsage);
802  }
803  allUsages.insert(currentUsage);
804  }
805 
806  // cpu times aren't quite recorded in a monotonic way, so skip the invalid ones.
807  for (auto it = ++allUsages.begin(); it != allUsages.end(); ++it) {
808  auto previous = std::prev(it);
809  if (it->usertime < previous->usertime || it->systemtime < previous->systemtime ||
810  it->time == previous->time) {
811  it = allUsages.erase(it);
812  --it;
813  }
814  }
815 
816  // Extract our overall stats
817  startTime = allUsages.begin()->time;
818  endTime = allUsages.rbegin()->time;
819 
820  // If we don't have enough records, just return what we can
821  if (allUsages.size() < width) {
822  return allUsages;
823  }
824 
825  timeStep = (endTime - startTime) / width;
826 
827  // Store the timepoints we need for the graph
828  for (uint32_t i = 1; i <= width; ++i) {
829  auto it = allUsages.upper_bound(Usage{startTime + timeStep * i, 0, {}, {}});
830  if (it != allUsages.begin()) {
831  --it;
832  }
833  usages.insert(*it);
834  }
835 
836  return usages;
837  }

References souffle::ProfileEventSingleton::getDB(), i, and souffle::ProfileEventSingleton::instance().

Referenced by souffle::genJsonUsage(), memoryUsage(), and usage().

Here is the call graph for this function:

◆ graphBySize()

void graphBySize ( std::vector< size_t >  list)

Definition at line 1421 of file Tui.h.

1421  {
1422  size_t max = 0;
1423  for (auto& l : list) {
1424  if (l > max) {
1425  max = l;
1426  }
1427  }
1428  std::sort(list.begin(), list.end());
1429  std::reverse(list.begin(), list.end());
1430  uint32_t i = 0;
1431  for (auto& l : list) {
1432  size_t len = max == 0 ? 0 : 64.0 * l / max;
1433  std::string bar = "";
1434  for (uint32_t j = 0; j < len; j++) {
1435  bar += "*";
1436  }
1437 
1438  std::printf("%4d %8s | %s\n", i++, Tools::formatNum(precision, l).c_str(), bar.c_str());
1439  }
1440  }

References souffle::profile::Tools::formatNum(), i, j, l, souffle::profile::Tui::precision, and tinyformat::printf().

Referenced by iterRel(), iterRul(), and verGraph().

Here is the call graph for this function:

◆ graphByTime()

void graphByTime ( std::vector< std::chrono::microseconds >  list)

Definition at line 1399 of file Tui.h.

1399  {
1400  std::chrono::microseconds max{};
1401  for (auto& d : list) {
1402  if (d > max) {
1403  max = d;
1404  }
1405  }
1406 
1407  std::sort(list.begin(), list.end());
1408  std::reverse(list.begin(), list.end());
1409  int i = 0;
1410  for (auto& d : list) {
1411  uint32_t len = 67.0 * d.count() / max.count();
1412  std::string bar = "";
1413  for (uint32_t j = 0; j < len; j++) {
1414  bar += "*";
1415  }
1416 
1417  std::printf("%4d %10.8f | %s\n", i++, (d.count() / 1000000.0), bar.c_str());
1418  }
1419  }

References d, i, j, and tinyformat::printf().

Referenced by iterRel(), iterRul(), and verGraph().

Here is the call graph for this function:

◆ help()

static void help ( )
static

Definition at line 685 of file Tui.h.

685  {
686  std::cout << "\nAvailable profiling commands:" << std::endl;
687  std::printf(" %-30s%-5s %s\n", "rel", "-", "display relation table.");
688  std::printf(" %-30s%-5s %s\n", "rel <relation id>", "-", "display all rules of a given relation.");
689  std::printf(" %-30s%-5s %s\n", "rul", "-", "display rule table");
690  std::printf(" %-30s%-5s %s\n", "rul <rule id>", "-", "display all version of given rule.");
691  std::printf(" %-30s%-5s %s\n", "rul id", "-", "display all rules names and ids.");
692  std::printf(
693  " %-30s%-5s %s\n", "rul id <rule id>", "-", "display the rule name for the given rule id.");
694  std::printf(" %-30s%-5s %s\n", "graph <relation id> <type>", "-",
695  "graph a relation by type: (tot_t/copy_t/tuples).");
696  std::printf(" %-30s%-5s %s\n", "graph <rule id> <type>", "-",
697  "graph recursive(C) rule by type(tot_t/tuples).");
698  std::printf(" %-30s%-5s %s\n", "graph ver <rule id> <type>", "-",
699  "graph recursive(C) rule versions by type(tot_t/copy_t/tuples).");
700  std::printf(" %-30s%-5s %s\n", "top", "-", "display top-level summary of program run.");
701  std::printf(" %-30s%-5s %s\n", "configuration", "-", "display configuration settings for this run.");
702  std::printf(" %-30s%-5s %s\n", "usage [relation id|rule id]", "-",
703  "display CPU usage graphs for a relation or rule.");
704  std::printf(" %-30s%-5s %s\n", "memory", "-", "display memory usage.");
705  std::printf(" %-30s%-5s %s\n", "help", "-", "print this.");
706 
707  std::cout << "\nInteractive mode only commands:" << std::endl;
708  // if (alive) std::printf(" %-30s%-5s %s\n", "stop", "-",
709  // "stop the current live run.");
710  std::printf(" %-30s%-5s %s\n", "limit <row count>", "-", "limit number of results shown.");
711  std::printf(" %-30s%-5s %s\n", "sort <col number>", "-", "sort tables by given column number.");
712  std::printf(" %-30s%-5s %s\n", "q", "-", "exit program.");
713  }

References tinyformat::printf().

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ id()

void id ( std::string  col)

Definition at line 1124 of file Tui.h.

1124  {
1125  ruleTable.sort(6);
1126  std::vector<std::vector<std::string>> table = Tools::formatTable(ruleTable, precision);
1127 
1128  if (col == "0") {
1129  std::printf("%7s%2s%s\n\n", "ID", "", "NAME");
1130  for (auto& row : table) {
1131  std::printf("%7s%2s%s\n", row[6].c_str(), "", row[5].c_str());
1132  }
1133  } else {
1134  for (auto& row : table) {
1135  if (row[6] == col) {
1136  std::printf("%7s%2s%s\n", row[6].c_str(), "", row[5].c_str());
1137  }
1138  }
1139  }
1140  }

References souffle::profile::Tools::formatTable(), souffle::profile::Tui::precision, tinyformat::printf(), souffle::profile::Tui::ruleTable, and souffle::profile::Table::sort().

Referenced by souffle::ram::TupleOperation::getTupleId(), souffle::profile::Tui::runCommand(), and souffle::profile::Rule::setId().

Here is the call graph for this function:

◆ iterRel()

void iterRel ( std::string  c,
std::string  col 
)

Definition at line 1250 of file Tui.h.

1250  {
1251  const std::shared_ptr<ProgramRun>& run = out.getProgramRun();
1252  std::vector<std::vector<std::string>> table = Tools::formatTable(relationTable, -1);
1253  std::vector<std::shared_ptr<Iteration>> iter;
1254  for (auto& row : table) {
1255  if (row[6] == c) {
1256  std::printf("%4s%2s%s\n\n", row[6].c_str(), "", row[5].c_str());
1257  iter = run->getRelation(row[5])->getIterations();
1258  if (col == "tot_t") {
1259  std::vector<std::chrono::microseconds> list;
1260  for (auto& i : iter) {
1261  list.emplace_back(i->getRuntime());
1262  }
1263  std::printf("%4s %s\n\n", "NO", "RUNTIME");
1264  graphByTime(list);
1265  } else if (col == "copy_t") {
1266  std::vector<std::chrono::microseconds> list;
1267  for (auto& i : iter) {
1268  list.emplace_back(i->getCopytime());
1269  }
1270  std::printf("%4s %s\n\n", "NO", "COPYTIME");
1271  graphByTime(list);
1272  } else if (col == "tuples") {
1273  std::vector<size_t> list;
1274  for (auto& i : iter) {
1275  list.emplace_back(i->size());
1276  }
1277  std::printf("%4s %s\n\n", "NO", "TUPLES");
1278  graphBySize(list);
1279  }
1280  return;
1281  }
1282  }
1283  for (auto& row : table) {
1284  if (row[5] == c) {
1285  std::printf("%4s%2s%s\n\n", row[6].c_str(), "", row[5].c_str());
1286  const std::shared_ptr<ProgramRun>& run = out.getProgramRun();
1287  iter = run->getRelation(row[5])->getIterations();
1288  if (col == "tot_t") {
1289  std::vector<std::chrono::microseconds> list;
1290  for (auto& i : iter) {
1291  list.emplace_back(i->getRuntime());
1292  }
1293  std::printf("%4s %s\n\n", "NO", "RUNTIME");
1294  graphByTime(list);
1295  } else if (col == "copy_t") {
1296  std::vector<std::chrono::microseconds> list;
1297  for (auto& i : iter) {
1298  list.emplace_back(i->getCopytime());
1299  }
1300  std::printf("%4s %s\n\n", "NO", "COPYTIME");
1301  graphByTime(list);
1302  } else if (col == "tuples") {
1303  std::vector<size_t> list;
1304  for (auto& i : iter) {
1305  list.emplace_back(i->size());
1306  }
1307  std::printf("%4s %s\n\n", "NO", "TUPLES");
1308  graphBySize(list);
1309  }
1310  return;
1311  }
1312  }
1313  }

References souffle::profile::Tools::formatTable(), souffle::profile::OutputProcessor::getProgramRun(), graphBySize(), graphByTime(), i, souffle::profile::Tui::out, tinyformat::printf(), and souffle::profile::Tui::relationTable.

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ iterRul()

void iterRul ( std::string  c,
std::string  col 
)

Definition at line 1315 of file Tui.h.

1315  {
1316  std::vector<std::vector<std::string>> table = Tools::formatTable(ruleTable, precision);
1317  std::vector<std::shared_ptr<Iteration>> iter;
1318  for (auto& row : table) {
1319  if (row[6] == c) {
1320  std::printf("%6s%2s%s\n\n", row[6].c_str(), "", row[5].c_str());
1321  const std::shared_ptr<ProgramRun>& run = out.getProgramRun();
1322  iter = run->getRelation(row[7])->getIterations();
1323  if (col == "tot_t") {
1324  std::vector<std::chrono::microseconds> list;
1325  for (auto& i : iter) {
1326  bool add = false;
1327  std::chrono::microseconds totalTime{};
1328  for (auto& rul : i->getRules()) {
1329  if (rul.second->getId() == c) {
1330  totalTime += rul.second->getRuntime();
1331  add = true;
1332  }
1333  }
1334  if (add) {
1335  list.emplace_back(totalTime);
1336  }
1337  }
1338  std::printf("%4s %s\n\n", "NO", "RUNTIME");
1339  graphByTime(list);
1340  } else if (col == "tuples") {
1341  std::vector<size_t> list;
1342  for (auto& i : iter) {
1343  bool add = false;
1344  size_t totalSize = 0L;
1345  for (auto& rul : i->getRules()) {
1346  if (rul.second->getId() == c) {
1347  totalSize += rul.second->size();
1348  add = true;
1349  }
1350  }
1351  if (add) {
1352  list.emplace_back(totalSize);
1353  }
1354  }
1355  std::printf("%4s %s\n\n", "NO", "TUPLES");
1356  graphBySize(list);
1357  }
1358  break;
1359  }
1360  }
1361  }

References souffle::profile::Tools::formatTable(), souffle::profile::OutputProcessor::getProgramRun(), graphBySize(), graphByTime(), i, souffle::profile::Tui::out, souffle::profile::Tui::precision, tinyformat::printf(), rul(), and souffle::profile::Tui::ruleTable.

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ memoryUsage() [1/2]

void memoryUsage ( std::chrono::microseconds  ,
std::chrono::microseconds  ,
uint32_t  height = 20 
)

Definition at line 944 of file Tui.h.

945  {
946  uint32_t width = getTermWidth() - 8;
947  uint64_t maxMaxRSS = 0;
948 
949  std::set<Usage> usages = getUsageStats(width);
950  char grid[height][width];
951  for (uint32_t i = 0; i < height; ++i) {
952  for (uint32_t j = 0; j < width; ++j) {
953  grid[i][j] = ' ';
954  }
955  }
956 
957  for (auto& usage : usages) {
958  maxMaxRSS = std::max(maxMaxRSS, usage.maxRSS);
959  }
960  size_t col = 0;
961  for (const Usage& currentUsage : usages) {
962  uint64_t curHeight = height * currentUsage.maxRSS / maxMaxRSS;
963  for (uint32_t row = 0; row < curHeight; ++row) {
964  grid[row][col] = '*';
965  }
966  ++col;
967  }
968 
969  // Print array
970  for (int32_t row = height - 1; row >= 0; --row) {
971  printf("%6s ", Tools::formatMemory(maxMaxRSS * (row + 1) / height).c_str());
972  for (uint32_t col = 0; col < width; ++col) {
973  std::cout << grid[row][col];
974  }
975  std::cout << std::endl;
976  }
977  for (uint32_t col = 0; col < 8; ++col) {
978  std::cout << ' ';
979  }
980  for (uint32_t col = 0; col < width; ++col) {
981  std::cout << '-';
982  }
983  std::cout << std::endl;
984  }

References souffle::profile::Tools::formatMemory(), getTermWidth(), getUsageStats(), i, j, tinyformat::printf(), and usage().

Here is the call graph for this function:

◆ memoryUsage() [2/2]

void memoryUsage ( uint32_t  height = 20)

Definition at line 940 of file Tui.h.

940  {
941  memoryUsage({}, {}, height);
942  }

Referenced by souffle::profile::Tui::runCommand().

◆ outputHtml()

void outputHtml ( std::string  filename = "profiler_html/")

Definition at line 636 of file Tui.h.

636  {
637  std::cout << "SouffleProf\n";
638  std::cout << "Generating HTML files...\n";
639 
640  DIR* dir;
641  bool exists = false;
642 
643  if (filename.find('/') != std::string::npos) {
644  std::string path = filename.substr(0, filename.find('/'));
645  if ((dir = opendir(path.c_str())) != nullptr) {
646  exists = true;
647  closedir(dir);
648  }
649  if (!exists) {
650  mode_t nMode = 0733; // UNIX style permissions
651  int nError = 0;
652  nError = mkdir(path.c_str(), nMode);
653  if (nError != 0) {
654  std::cerr << "directory " << path
655  << " could not be created. Please create it and try again.";
656  exit(2);
657  }
658  }
659  }
660  std::string filetype = ".html";
661  std::string newFile = filename;
662 
663  if (filename.size() <= filetype.size() ||
664  !std::equal(filetype.rbegin(), filetype.rend(), filename.rbegin())) {
665  int i = 0;
666  do {
667  ++i;
668  newFile = filename + std::to_string(i) + ".html";
669  } while (Tools::file_exists(newFile));
670  }
671 
672  std::ofstream outfile(newFile);
673 
674  outfile << HtmlGenerator::getHtml(genJson());
675 
676  std::cout << "file output to: " << newFile << std::endl;
677  }

References souffle::profile::Tools::file_exists(), genJson(), souffle::profile::HtmlGenerator::getHtml(), and i.

Here is the call graph for this function:

◆ quit()

void quit ( )

Definition at line 679 of file Tui.h.

679  {
680  if (updater.joinable()) {
681  updater.join();
682  }
683  }

References souffle::profile::Tui::updater.

Referenced by souffle::profile::Tui::runProf().

◆ rel()

void rel ( size_t  limit,
bool  showLimit = true 
)

Definition at line 1086 of file Tui.h.

1086  {
1087  relationTable.sort(sortColumn);
1088  std::cout << " ----- Relation Table -----\n";
1089  std::printf("%8s%8s%8s%8s%8s%8s%8s%8s%8s%6s %s\n\n", "TOT_T", "NREC_T", "REC_T", "COPY_T", "LOAD_T",
1090  "SAVE_T", "TUPLES", "READS", "TUP/s", "ID", "NAME");
1091  size_t count = 0;
1092  for (auto& row : Tools::formatTable(relationTable, precision)) {
1093  if (++count > limit) {
1094  if (showLimit) {
1095  std::cout << (relationTable.getRows().size() - resultLimit) << " rows not shown"
1096  << std::endl;
1097  }
1098  break;
1099  }
1100  std::printf("%8s%8s%8s%8s%8s%8s%8s%8s%8s%6s %s\n", row[0].c_str(), row[1].c_str(), row[2].c_str(),
1101  row[3].c_str(), row[9].c_str(), row[10].c_str(), row[4].c_str(), row[12].c_str(),
1102  row[8].c_str(), row[6].c_str(), row[5].c_str());
1103  }
1104  }

References souffle::test::count(), souffle::profile::Tools::formatTable(), souffle::profile::Table::getRows(), souffle::profile::Tui::precision, tinyformat::printf(), souffle::profile::Tui::relationTable, souffle::profile::Tui::resultLimit, souffle::profile::Table::sort(), and souffle::profile::Tui::sortColumn.

Referenced by souffle::ParserDriver::addIoFromDeprecatedTag(), souffle::ast::Program::addRelation(), souffle::profile::Reader::addRelation(), souffle::SouffleProgram::addRelation(), souffle::ast::analysis::RecursiveClausesAnalysis::computeIsRecursive(), souffle::interpreter::Engine::execute(), souffle::ExplainProvenanceImpl::ExplainProvenanceImpl(), souffle::ExplainProvenanceImpl::findTuple(), souffle::profile::OutputProcessor::getAtomTable(), souffle::ast::transform::getInlinedLiteral(), souffle::profile::OutputProcessor::getRelTable(), souffle::profile::OutputProcessor::getRulTable(), souffle::profile::OutputProcessor::getSubrulTable(), souffle::synthesiser::Relation::getSynthesiserRelation(), souffle::ast::transform::MagicSetTransformer::getTriviallyIgnoredRelations(), souffle::profile::OutputProcessor::getVersionAtoms(), souffle::profile::OutputProcessor::getVersions(), souffle::ast::analysis::ProfileUseAnalysis::hasRelationSize(), souffle::interpreter::NodeGenerator::lookup(), souffle::ram::transform::MakeIndexTransformer::makeIndex(), souffle::ram::transform::ParallelTransformer::parallelizeOperations(), souffle::ast::transform::MagicSetTransformer::NormaliseDatabaseTransformer::partitionIO(), souffle::ast::analysis::SCCGraphAnalysis::print(), souffle::interpreter::ProgInterface::ProgInterface(), souffle::ExplainProvenanceImpl::queryProcess(), souffle::ast::transform::MinimiseProgramTransformer::reduceLocallyEquivalentClauses(), souffle::ast::transform::MinimiseProgramTransformer::reduceSingletonRelations(), souffle::ast::transform::RemoveEmptyRelationsTransformer::removeEmptyRelations(), souffle::ast::transform::RemoveRelationCopiesTransformer::removeRelationCopies(), souffle::profile::Tui::runCommand(), souffle::ast::analysis::SCCGraphAnalysis::SCCGraphAnalysis(), souffle::ast::transform::SemanticCheckerImpl::SemanticCheckerImpl(), top(), souffle::ast::transform::ComponentInstantiationTransformer::transform(), souffle::ast::transform::RemoveRedundantRelationsTransformer::transform(), souffle::ast::transform::ExecutionPlanChecker::transform(), souffle::ast::transform::IOAttributesTransformer::transform(), souffle::ast::transform::MagicSetTransformer::LabelDatabaseTransformer::PositiveLabellingTransformer::transform(), souffle::ast::transform::MagicSetTransformer::AdornDatabaseTransformer::transform(), souffle::ast2ram::AstToRamTranslator::translateNonRecursiveRelation(), souffle::ast2ram::AstToRamTranslator::translateRecursiveRelation(), usageRelation(), usageRule(), souffle::interpreter::NodeGenerator::visitLogSize(), and souffle::interpreter::NodeGenerator::visitQuery().

Here is the call graph for this function:

◆ relRul()

void relRul ( std::string  str)

Definition at line 1142 of file Tui.h.

1142  {
1143  ruleTable.sort(sortColumn);
1144 
1145  std::vector<std::vector<std::string>> formattedRuleTable = Tools::formatTable(ruleTable, precision);
1146  std::vector<std::vector<std::string>> formattedRelationTable =
1147  Tools::formatTable(relationTable, precision);
1148 
1149  std::cout << " ----- Rules of a Relation -----\n";
1150  std::printf("%8s%8s%8s%8s%8s %s\n\n", "TOT_T", "NREC_T", "REC_T", "TUPLES", "ID", "NAME");
1151  std::string name = "";
1152  for (auto& row : formattedRelationTable) {
1153  // Test for relation name or relation id
1154  if (row[5] == str || row[6] == str) {
1155  std::printf("%8s%8s%8s%8s%8s %s\n", row[0].c_str(), row[1].c_str(), row[2].c_str(),
1156  row[4].c_str(), row[6].c_str(), row[5].c_str());
1157  name = row[5];
1158  break;
1159  }
1160  }
1161  std::cout << " ---------------------------------------------------------\n";
1162  for (auto& row : formattedRuleTable) {
1163  if (row[7] == name) {
1164  std::printf("%8s%8s%8s%8s%8s %s\n", row[0].c_str(), row[1].c_str(), row[2].c_str(),
1165  row[4].c_str(), row[6].c_str(), row[7].c_str());
1166  }
1167  }
1168  std::string src = "";
1169  const std::shared_ptr<ProgramRun>& run = out.getProgramRun();
1170  if (run->getRelation(name) != nullptr) {
1171  src = run->getRelation(name)->getLocator();
1172  }
1173  std::cout << "\nSrc locator: " << src << "\n\n";
1174  for (auto& row : formattedRuleTable) {
1175  if (row[7] == name) {
1176  std::printf("%7s%2s%s\n", row[6].c_str(), "", row[5].c_str());
1177  }
1178  }
1179  }

References souffle::profile::Tools::formatTable(), souffle::profile::OutputProcessor::getProgramRun(), souffle::profile::Tui::out, souffle::profile::Tui::precision, tinyformat::printf(), souffle::profile::Tui::relationTable, souffle::profile::Tui::ruleTable, souffle::profile::Table::sort(), souffle::profile::Tui::sortColumn, and str.

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ rul()

void rul ( size_t  limit,
bool  showLimit = true 
)

Definition at line 1106 of file Tui.h.

1106  {
1107  ruleTable.sort(sortColumn);
1108  std::cout << " ----- Rule Table -----\n";
1109  std::printf(
1110  "%8s%8s%8s%8s%8s%8s %s\n\n", "TOT_T", "NREC_T", "REC_T", "TUPLES", "TUP/s", "ID", "RELATION");
1111  size_t count = 0;
1112  for (auto& row : Tools::formatTable(ruleTable, precision)) {
1113  if (++count > limit) {
1114  if (showLimit) {
1115  std::cout << (ruleTable.getRows().size() - resultLimit) << " rows not shown" << std::endl;
1116  }
1117  break;
1118  }
1119  std::printf("%8s%8s%8s%8s%8s%8s %s\n", row[0].c_str(), row[1].c_str(), row[2].c_str(),
1120  row[4].c_str(), row[9].c_str(), row[6].c_str(), row[7].c_str());
1121  }
1122  }

References souffle::test::count(), souffle::profile::Tools::formatTable(), souffle::profile::Table::getRows(), souffle::profile::Tui::precision, tinyformat::printf(), souffle::profile::Tui::resultLimit, souffle::profile::Tui::ruleTable, souffle::profile::Table::sort(), and souffle::profile::Tui::sortColumn.

Referenced by souffle::profile::Relation::createRecID(), souffle::genJsonRules(), souffle::profile::Relation::getRuleRecList(), souffle::profile::Relation::getTotalRecursiveRuleSize(), iterRul(), souffle::profile::Tui::runCommand(), top(), souffle::profile::Iteration::toString(), souffle::profile::Relation::toString(), and usageRule().

Here is the call graph for this function:

◆ setResultLimit()

void setResultLimit ( size_t  limit)

Definition at line 1082 of file Tui.h.

1082  {
1083  resultLimit = limit;
1084  }

References souffle::profile::Tui::resultLimit.

Referenced by souffle::profile::Tui::runCommand().

◆ setupTabCompletion()

void setupTabCompletion ( )

Definition at line 985 of file Tui.h.

985  {
986  linereader.clearTabCompletion();
987 
988  linereader.appendTabCompletion("rel");
989  linereader.appendTabCompletion("rul");
990  linereader.appendTabCompletion("rul id");
991  linereader.appendTabCompletion("graph ");
992  linereader.appendTabCompletion("top");
993  linereader.appendTabCompletion("help");
994  linereader.appendTabCompletion("usage");
995  linereader.appendTabCompletion("limit ");
996  linereader.appendTabCompletion("memory");
997  linereader.appendTabCompletion("configuration");
998 
999  // add rel tab completes after the rest so users can see all commands first
1000  for (auto& row : Tools::formatTable(relationTable, precision)) {
1001  linereader.appendTabCompletion("rel " + row[5]);
1002  linereader.appendTabCompletion("graph " + row[5] + " tot_t");
1003  linereader.appendTabCompletion("graph " + row[5] + " copy_t");
1004  linereader.appendTabCompletion("graph " + row[5] + " tuples");
1005  linereader.appendTabCompletion("usage " + row[5]);
1006  }
1007  }

References souffle::profile::InputReader::appendTabCompletion(), souffle::profile::InputReader::clearTabCompletion(), souffle::profile::Tools::formatTable(), souffle::profile::Tui::linereader, souffle::profile::Tui::precision, and souffle::profile::Tui::relationTable.

Referenced by souffle::profile::Tui::runCommand(), and souffle::profile::Tui::runProf().

Here is the call graph for this function:

◆ top()

void top ( )

Definition at line 1023 of file Tui.h.

1023  {
1024  const std::shared_ptr<ProgramRun>& run = out.getProgramRun();
1025  auto* totalRelationsEntry =
1026  dynamic_cast<TextEntry*>(ProfileEventSingleton::instance().getDB().lookupEntry(
1027  {"program", "configuration", "relationCount"}));
1028  auto* totalRulesEntry =
1029  dynamic_cast<TextEntry*>(ProfileEventSingleton::instance().getDB().lookupEntry(
1030  {"program", "configuration", "ruleCount"}));
1031  size_t totalRelations = 0;
1032  if (totalRelationsEntry != nullptr) {
1033  totalRelations = std::stoul(totalRelationsEntry->getText());
1034  } else {
1035  totalRelations = run->getRelationMap().size();
1036  }
1037  size_t totalRules = 0;
1038  if (totalRulesEntry != nullptr) {
1039  totalRules = std::stoul(totalRulesEntry->getText());
1040  } else {
1041  totalRules = ruleTable.getRows().size();
1042  }
1043  std::printf("%11s%10s%10s%10s%10s%20s\n", "runtime", "loadtime", "savetime", "relations", "rules",
1044  "tuples generated");
1045 
1046  std::printf("%11s%10s%10s%10s%10s%14s\n", run->getRuntime().c_str(),
1047  run->formatTime(run->getTotalLoadtime()).c_str(),
1048  run->formatTime(run->getTotalSavetime()).c_str(), run->formatNum(0, totalRelations).c_str(),
1049  run->formatNum(0, totalRules).c_str(),
1050  run->formatNum(precision, run->getTotalSize()).c_str());
1051 
1052  // Progress bar
1053  // Determine number of relations processed
1054  size_t processedRelations = run->getRelationMap().size();
1055  size_t screenWidth = getTermWidth() - 10;
1056  if (alive && totalRelationsEntry != nullptr) {
1057  std::cout << "Progress ";
1058  for (size_t i = 0; i < screenWidth; ++i) {
1059  if (screenWidth * processedRelations / totalRelations > i) {
1060  std::cout << '#';
1061  } else {
1062  std::cout << '_';
1063  }
1064  }
1065  }
1066  std::cout << std::endl;
1067 
1068  std::cout << "Slowest relations to fully evaluate\n";
1069  rel(3, false);
1070  for (size_t i = relationTable.getRows().size(); i < 3; ++i) {
1071  std::cout << "\n";
1072  }
1073  std::cout << "Slowest rules to fully evaluate\n";
1074  rul(3, false);
1075  for (size_t i = ruleTable.getRows().size(); i < 3; ++i) {
1076  std::cout << "\n";
1077  }
1078 
1079  usage(10);
1080  }

References souffle::profile::Tui::alive, souffle::ProfileEventSingleton::getDB(), souffle::profile::OutputProcessor::getProgramRun(), souffle::profile::Table::getRows(), getTermWidth(), i, souffle::ProfileEventSingleton::instance(), souffle::profile::Tui::out, souffle::profile::Tui::precision, tinyformat::printf(), rel(), souffle::profile::Tui::relationTable, rul(), souffle::profile::Tui::ruleTable, and usage().

Referenced by souffle::profile::Tui::runCommand(), and souffle::profile::Tui::runProf().

Here is the call graph for this function:

◆ updateDB()

void updateDB ( )
protected

Definition at line 1472 of file Tui.h.

1472  {
1473  reader->processFile();
1474  ruleTable = out.getRulTable();
1475  relationTable = out.getRelTable();
1476  }

References souffle::profile::OutputProcessor::getRelTable(), souffle::profile::OutputProcessor::getRulTable(), souffle::profile::Tui::out, souffle::profile::Tui::reader, souffle::profile::Tui::relationTable, and souffle::profile::Tui::ruleTable.

Referenced by souffle::profile::Tui::runCommand(), and souffle::profile::Tui::Tui().

Here is the call graph for this function:

◆ usage() [1/2]

void usage ( std::chrono::microseconds  endTime,
std::chrono::microseconds  startTime,
uint32_t  height = 20 
)

Definition at line 843 of file Tui.h.

843  {
844  uint32_t width = getTermWidth() - 8;
845 
846  std::set<Usage> usages = getUsageStats(width);
847 
848  if (usages.size() < 2) {
849  for (uint8_t i = 0; i < height + 2; ++i) {
850  std::cout << std::endl;
851  }
852  std::cout << "Insufficient data for usage statistics." << std::endl;
853  return;
854  }
855 
856  double maxIntervalUsage = 0;
857 
858  // Extract our overall stats
859  if (startTime.count() == 0) {
860  startTime = usages.begin()->time;
861  }
862  if (endTime.count() == 0) {
863  endTime = usages.rbegin()->time;
864  }
865 
866  if (usages.size() < width) {
867  width = usages.size();
868  }
869 
870  // Find maximum so we can normalise the graph
871  Usage previousUsage{{}, 0, {}, {}};
872  for (auto& currentUsage : usages) {
873  double usageDiff = (currentUsage.systemtime - previousUsage.systemtime + currentUsage.usertime -
874  previousUsage.usertime)
875  .count();
876  usageDiff /= (currentUsage.time - previousUsage.time).count();
877  if (usageDiff > maxIntervalUsage) {
878  maxIntervalUsage = usageDiff;
879  }
880 
881  previousUsage = currentUsage;
882  }
883 
884  double intervalUsagePercent = 100.0 * maxIntervalUsage;
885  std::printf("%11s\n", "cpu total");
886  std::printf("%11s\n", Tools::formatTime(usages.rbegin()->usertime).c_str());
887 
888  // Add columns to the graph
889  char grid[height][width];
890  for (uint32_t i = 0; i < height; ++i) {
891  for (uint32_t j = 0; j < width; ++j) {
892  grid[i][j] = ' ';
893  }
894  }
895 
896  previousUsage = {{}, 0, {}, {}};
897  uint32_t col = 0;
898  for (const Usage& currentUsage : usages) {
899  uint64_t curHeight = 0;
900  uint64_t curSystemHeight = 0;
901  // Usage may be 0
902  if (maxIntervalUsage != 0) {
903  curHeight = (currentUsage.systemtime - previousUsage.systemtime + currentUsage.usertime -
904  previousUsage.usertime)
905  .count();
906  curHeight /= (currentUsage.time - previousUsage.time).count();
907  curHeight *= height / maxIntervalUsage;
908 
909  curSystemHeight = (currentUsage.systemtime - previousUsage.systemtime).count();
910  curSystemHeight /= (currentUsage.time - previousUsage.time).count();
911  curSystemHeight *= height / maxIntervalUsage;
912  }
913  for (uint32_t row = 0; row < curHeight; ++row) {
914  grid[row][col] = '*';
915  }
916  for (uint32_t row = curHeight - curSystemHeight; row < curHeight; ++row) {
917  grid[row][col] = '+';
918  }
919  previousUsage = currentUsage;
920  ++col;
921  }
922 
923  // Print array
924  for (int32_t row = height - 1; row >= 0; --row) {
925  printf("%6d%% ", uint32_t(intervalUsagePercent * (row + 1) / height));
926  for (uint32_t col = 0; col < width; ++col) {
927  std::cout << grid[row][col];
928  }
929  std::cout << std::endl;
930  }
931  for (uint32_t col = 0; col < 8; ++col) {
932  std::cout << ' ';
933  }
934  for (uint32_t col = 0; col < width; ++col) {
935  std::cout << '-';
936  }
937  std::cout << std::endl;
938  }

References souffle::test::count(), souffle::profile::Tools::formatTime(), getTermWidth(), getUsageStats(), i, j, and tinyformat::printf().

Here is the call graph for this function:

◆ usage() [2/2]

void usage ( uint32_t  height = 20)

Definition at line 839 of file Tui.h.

839  {
840  usage({}, {}, height);
841  }

Referenced by souffle::genJsonUsage(), memoryUsage(), souffle::profile::Tui::runCommand(), top(), usageRelation(), and usageRule().

◆ usageRelation()

void usageRelation ( std::string  id)

Definition at line 715 of file Tui.h.

715  {
716  std::vector<std::vector<std::string>> formattedRelationTable =
717  Tools::formatTable(relationTable, precision);
718  std::string name = "";
719  bool found = false;
720  for (auto& row : formattedRelationTable) {
721  if (row[5] == id || row[6] == id) {
722  name = row[5];
723  found = true;
724  break;
725  }
726  }
727  if (!found) {
728  std::cout << "Relation does not exist.\n";
729  return;
730  }
731 
732  const Relation* rel = out.getProgramRun()->getRelation(name);
733  usage(rel->getEndtime(), rel->getStarttime());
734  }

References souffle::profile::Tools::formatTable(), souffle::profile::OutputProcessor::getProgramRun(), souffle::profile::Tui::out, souffle::profile::Tui::precision, rel(), souffle::profile::Tui::relationTable, and usage().

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ usageRule()

void usageRule ( std::string  id)

Definition at line 736 of file Tui.h.

736  {
737  std::vector<std::vector<std::string>> formattedRuleTable = Tools::formatTable(ruleTable, precision);
738  std::string relName = "";
739  std::string srcLocator = "";
740  bool found = false;
741  for (auto& row : formattedRuleTable) {
742  if (row[5] == id || row[6] == id) {
743  relName = row[7];
744  srcLocator = row[10];
745  found = true;
746  break;
747  }
748  }
749  if (!found) {
750  std::cout << "Rule does not exist.\n";
751  return;
752  }
753 
754  auto* rel = out.getProgramRun()->getRelation(relName);
755  if (rel == nullptr) {
756  std::cout << "Relation ceased to exist. Odd." << std::endl;
757  return;
758  }
759  if (rel->getRuleMap().count(srcLocator) == 0) {
760  std::cout << "Rule ceased to exist. Odd." << std::endl;
761  return;
762  }
763 
764  auto& rul = rel->getRuleMap().at(srcLocator);
765  usage(rul->getEndtime(), rul->getStarttime());
766  }

References souffle::profile::Tools::formatTable(), souffle::profile::OutputProcessor::getProgramRun(), souffle::profile::Tui::out, souffle::profile::Tui::precision, rel(), rul(), souffle::profile::Tui::ruleTable, and usage().

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ verAtoms()

void verAtoms ( Table &  atomTable,
const std::string &  ruleName = "" 
)
protected

Definition at line 1443 of file Tui.h.

1443  {
1444  // If there are no subrules then just print out any atoms found
1445  // If we do find subrules, then label atoms with their subrules.
1446  if (atomTable.rows.empty()) {
1447  return;
1448  }
1449  bool firstRun = true;
1450  std::string lastRule = ruleName;
1451  for (auto& _row : atomTable.rows) {
1452  Row& row = *_row;
1453  std::string rule = row[0]->toString(precision);
1454  if (rule != lastRule) {
1455  lastRule = rule;
1456  std::cout << " " << row[0]->toString(precision) << std::endl;
1457  firstRun = true;
1458  }
1459  if (firstRun) {
1460  std::printf(" %-16s%-16s%s\n", "FREQ", "RELSIZE", "ATOM");
1461  firstRun = false;
1462  }
1463  std::string relationName = row[1]->getStringVal();
1464  relationName = relationName.substr(0, relationName.find('('));
1465  auto* relation = out.getProgramRun()->getRelation(relationName);
1466  std::string relationSize = relation == nullptr ? "--" : std::to_string(relation->size());
1467  std::printf(" %-16s%-16s%s\n", row[3]->toString(precision).c_str(), relationSize.c_str(),
1468  row[1]->getStringVal().c_str());
1469  }
1470  std::cout << '\n';
1471  }

References souffle::profile::OutputProcessor::getProgramRun(), souffle::profile::Tui::out, souffle::profile::Tui::precision, tinyformat::printf(), relation, rule, and souffle::toString().

Referenced by verRul().

Here is the call graph for this function:

◆ verGraph()

void verGraph ( std::string  c,
std::string  col 
)

Definition at line 1363 of file Tui.h.

1363  {
1364  if (c.find('.') == std::string::npos) {
1365  std::cout << "Rule does not exist";
1366  return;
1367  }
1368 
1369  std::vector<std::string> part = Tools::split(c, ".");
1370  std::string strRel = "R" + part[0].substr(1);
1371 
1372  Table versionTable = out.getVersions(strRel, c);
1373  std::printf("%6s%2s%s\n\n", (*versionTable.rows[0])[6]->toString(0).c_str(), "",
1374  (*versionTable.rows[0])[5]->toString(0).c_str());
1375  if (col == "tot_t") {
1376  std::vector<std::chrono::microseconds> list;
1377  for (auto& row : versionTable.rows) {
1378  list.emplace_back((*row)[0]->getTimeVal());
1379  }
1380  std::printf("%4s %s\n\n", "NO", "RUNTIME");
1381  graphByTime(list);
1382  } else if (col == "copy_t") {
1383  std::vector<std::chrono::microseconds> list;
1384  for (auto& row : versionTable.rows) {
1385  list.emplace_back((*row)[3]->getTimeVal());
1386  }
1387  std::printf("%4s %s\n\n", "NO", "COPYTIME");
1388  graphByTime(list);
1389  } else if (col == "tuples") {
1390  std::vector<size_t> list;
1391  for (auto& row : versionTable.rows) {
1392  list.emplace_back((*row)[4]->getLongVal());
1393  }
1394  std::printf("%4s %s\n\n", "NO", "TUPLES");
1395  graphBySize(list);
1396  }
1397  }

References souffle::profile::OutputProcessor::getVersions(), graphBySize(), graphByTime(), souffle::profile::Tui::out, tinyformat::printf(), and souffle::profile::Tools::split().

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:

◆ verRul()

void verRul ( std::string  str)

Definition at line 1181 of file Tui.h.

1181  {
1182  if (str.find(".") == std::string::npos) {
1183  std::cout << "Rule does not exist\n";
1184  return;
1185  }
1186  std::vector<std::string> part = Tools::split(str, ".");
1187  std::string strRel = "R" + part[0].substr(1);
1188 
1189  Table versionTable = out.getVersions(strRel, str);
1190  versionTable.sort(sortColumn);
1191 
1192  ruleTable.sort(sortColumn); // why isnt it sorted in the original java?!?
1193 
1194  std::vector<std::vector<std::string>> formattedRuleTable = Tools::formatTable(ruleTable, precision);
1195 
1196  bool found = false;
1197  std::string ruleName;
1198  std::string srcLocator;
1199  // Check that the rule exists, and print it out if so.
1200  for (auto& row : formattedRuleTable) {
1201  if (row[6] == str) {
1202  std::cout << row[5] << std::endl;
1203  found = true;
1204  ruleName = row[5];
1205  srcLocator = row[10];
1206  }
1207  }
1208 
1209  // If the rule exists, print out the source locator.
1210  if (found) {
1211  if (versionTable.rows.size() > 0) {
1212  if (versionTable.rows[0]->cells[9] != nullptr) {
1213  std::cout << "Src locator-: " << (*versionTable.rows[0])[9]->getStringVal() << "\n\n";
1214  } else {
1215  std::cout << "Src locator-: -\n\n";
1216  }
1217  } else if (formattedRuleTable.size() > 0) {
1218  std::cout << "Src locator-: " << formattedRuleTable[0][10] << "\n\n";
1219  }
1220  }
1221 
1222  // Print out the versions of this rule.
1223  std::cout << " ----- Rule Versions Table -----\n";
1224  std::printf("%8s%8s%8s%16s%6s\n\n", "TOT_T", "NREC_T", "REC_T", "TUPLES", "VER");
1225  for (auto& row : formattedRuleTable) {
1226  if (row[6] == str) {
1227  std::printf("%8s%8s%8s%16s%6s\n", row[0].c_str(), row[1].c_str(), row[2].c_str(),
1228  row[4].c_str(), "");
1229  }
1230  }
1231  std::cout << " ---------------------------------------------\n";
1232  for (auto& _row : versionTable.rows) {
1233  Row row = *_row;
1234 
1235  std::printf("%8s%8s%8s%16s%6s\n", row[0]->toString(precision).c_str(),
1236  row[1]->toString(precision).c_str(), row[2]->toString(precision).c_str(),
1237  row[4]->toString(precision).c_str(), row[8]->toString(precision).c_str());
1238  Table atom_table = out.getVersionAtoms(strRel, srcLocator, row[8]->getLongVal());
1239  verAtoms(atom_table);
1240  }
1241 
1242  if (!versionTable.rows.empty()) {
1243  return;
1244  }
1245 
1246  Table atom_table = out.getAtomTable(strRel, str);
1247  verAtoms(atom_table, ruleName);
1248  }

References souffle::profile::Tools::formatTable(), souffle::profile::OutputProcessor::getAtomTable(), souffle::profile::OutputProcessor::getVersionAtoms(), souffle::profile::OutputProcessor::getVersions(), souffle::profile::Tui::out, souffle::profile::Tui::precision, tinyformat::printf(), souffle::profile::Tui::ruleTable, souffle::profile::Table::sort(), souffle::profile::Tui::sortColumn, souffle::profile::Tools::split(), str, souffle::toString(), and verAtoms().

Referenced by souffle::profile::Tui::runCommand().

Here is the call graph for this function:
souffle::profile::Tools::file_exists
bool file_exists(const std::string &name)
Definition: StringUtils.h:196
genJson
std::string genJson()
Definition: Tui.h:611
tinyformat::printf
void printf(const char *fmt)
Definition: tinyformat.h:1101
verAtoms
void verAtoms(Table &atomTable, const std::string &ruleName="")
Definition: Tui.h:1443
souffle::profile::Tools::cleanString
std::string cleanString(std::string val)
Remove and \t characters, and \t sequence of two chars, and wrapping quotes.
Definition: StringUtils.h:206
souffle::profile::Tools::formatTable
std::vector< std::vector< std::string > > formatTable(Table table, int precision)
Definition: StringUtils.h:145
souffle::genJsonRules
std::stringstream & genJsonRules(std::stringstream &ss, const std::string &name, size_t maxRows)
Definition: Tui.h:339
souffle::genJsonUsage
std::stringstream & genJsonUsage(std::stringstream &ss)
Definition: Tui.h:468
relation
Relation & relation
Definition: Reader.h:130
souffle::profile::Tools::formatMemory
std::string formatMemory(uint64_t kbytes)
Definition: StringUtils.h:97
iteration
Iteration & iteration
Definition: Reader.h:129
j
var j
Definition: htmlJsChartistMin.h:15
str
const std::string & str
Definition: json11.h:662
souffle::toString
const std::string & toString(const std::string &str)
A generic function converting strings into strings (trivial case).
Definition: StringUtil.h:234
genJsonAtoms
std::stringstream & genJsonAtoms(std::stringstream &ss)
Definition: Tui.h:549
l
var l
Definition: htmlJsChartistMin.h:15
souffle::profile::Tools::formatNum
std::string formatNum(double amount)
Definition: StringUtils.h:40
i
size_t i
Definition: json11.h:663
getUsageStats
std::set< Usage > getUsageStats(size_t width=size_t(-1))
Definition: Tui.h:768
graphBySize
void graphBySize(std::vector< size_t > list)
Definition: Tui.h:1421
rul
void rul(size_t limit, bool showLimit=true)
Definition: Tui.h:1106
souffle::profile::Tools::cleanJsonOut
std::string cleanJsonOut(std::string value)
escape escapes and quotes, and remove surrounding quotes
Definition: StringUtils.h:232
souffle::test::count
int count(const C &c)
Definition: table_test.cpp:40
souffle::profile::Tools::split
std::vector< std::string > split(std::string toSplit, std::string delimiter)
split on the delimiter
Definition: StringUtils.h:162
graphByTime
void graphByTime(std::vector< std::chrono::microseconds > list)
Definition: Tui.h:1399
souffle::profile::Tools::formatTime
std::string formatTime(std::chrono::microseconds number)
Definition: StringUtils.h:108
rule
Rule & rule
Definition: Reader.h:85
d
else d
Definition: htmlJsChartistMin.h:15
memoryUsage
void memoryUsage(uint32_t height=20)
Definition: Tui.h:940
rel
void rel(size_t limit, bool showLimit=true)
Definition: Tui.h:1086
usage
void usage(uint32_t height=20)
Definition: Tui.h:839
genJsonConfiguration
std::stringstream & genJsonConfiguration(std::stringstream &ss)
Definition: Tui.h:528
getTermWidth
uint32_t getTermWidth()
Definition: Tui.h:1478
souffle::profile::ss
class souffle::profile::Tui ss
Definition: Tui.h:336