Commit a1541a71 authored by Nguyen, Thien Minh's avatar Nguyen, Thien Minh
Browse files

Added a helper to print out detailed gate count comparison



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent fc0374c6
Loading
Loading
Loading
Loading
+111 −5
Original line number Diff line number Diff line
#include "pass_manager.hpp"
#include "InstructionIterator.hpp"
#include "xacc.hpp"
#include "xacc_service.hpp"
#include <iomanip>
#include <numeric>
namespace {
std::string
printGateCountComparison(const std::unordered_map<std::string, int> &before,
                         const std::unordered_map<std::string, int> &after) {
  std::stringstream stream;
  const size_t nbColumns = 3;
  const size_t columnWidth = 8;
  const auto totalWidth = nbColumns * columnWidth + 8;
  stream << std::string(totalWidth, '-') << "\n";
  // Print headers:
  stream << "| " << std::left << std::setw(8) << "GATE"
         << " |";
  stream << std::left << std::setw(8) << "BEFORE"
         << " |";
  stream << std::left << std::setw(8) << "AFTER"
         << " |\n";
  stream << std::string(totalWidth, '-') << "\n";

  const auto printEachRow = [&](const std::string &gateName, int countBefore,
                                int countAfter) {
    stream << "| " << std::setw(8) << gateName << " |";
    stream << std::setw(8) << countBefore << " |";
    stream << std::setw(8) << countAfter << " |\n";
  };

  for (const auto &[gateName, countBefore] : before) {
    const auto iter = after.find(gateName);
    const auto countAfter = (iter == after.end()) ? 0 : iter->second;
    printEachRow(gateName, countBefore, countAfter);
  }
  stream << std::string(totalWidth, '-') << "\n";
  return stream.str();
}
} // namespace

namespace qcor {
namespace internal {
PassManager::PassManager(int level):
    m_level(level) {}
PassManager::PassManager(int level) : m_level(level) {}

std::vector<PassStat> PassManager::optimize(
    std::shared_ptr<xacc::CompositeInstruction> program) const {

std::vector<PassStat> PassManager::optimize(std::shared_ptr<xacc::CompositeInstruction> program) const {
    // TODO
  // We only support level 1 atm.
  if (m_level != 1) {
    return {};
  }

  std::vector<PassStat> passData;
  for (const auto &passName : LEVEL1_PASSES) {
    PassStat stat;
    stat.passName = passName;
    // Counts gate before:
    stat.gateCountBefore = PassStat::countGates(program);
    xacc::ScopeTimer timer(passName, false);
    auto xaccOptTransform = xacc::getService<xacc::IRTransformation>(passName);
    xaccOptTransform->apply(program, nullptr);
    // Stores the elapsed time.
    stat.wallTimeMs = timer.getDurationMs();
    // Counts gate after:
    stat.gateCountAfter = PassStat::countGates(program);
    passData.emplace_back(std::move(stat));
  }

  return passData;
}

std::unordered_map<std::string, int> PassStat::countGates(
    const std::shared_ptr<xacc::CompositeInstruction> &program) {
  std::unordered_map<std::string, int> gateCount;
  xacc::InstructionIterator iter(program);
  while (iter.hasNext()) {
    auto next = iter.next();
    if (!next->isComposite()) {
      if (gateCount.find(next->name()) == gateCount.end()) {
        gateCount[next->name()] = 1;
      } else {
        gateCount[next->name()] += 1;
      }
    }
  }
  return gateCount;
}

std::string PassStat::toString(bool shortForm) const {
  const auto countNumberOfGates =
      [](const std::unordered_map<std::string, int> &gateCount) {
        return std::accumulate(gateCount.begin(), gateCount.end(), 0,
                               [](const int previousSum, const auto &element) {
                                 return previousSum + element.second;
                               });
      };

  std::stringstream ss;
  const std::string separator(40, '*');
  ss << separator << "\n";
  ss << std::string((separator.size() - passName.size()) / 2, ' ') << passName
     << "\n";
  ss << separator << "\n";
  ss << " - Elapsed time: " << wallTimeMs << " [ms]\n";
  ss << " - Number of Gates Before: " << countNumberOfGates(gateCountBefore)
     << "\n";
  ss << " - Number of Gates After: " << countNumberOfGates(gateCountAfter)
     << "\n";

  if (!shortForm) {
    // Prints the full gate count table if required (long form)
    ss << printGateCountComparison(gateCountBefore, gateCountAfter);
  }
  return ss.str();
}

} // namespace internal
} // namespace qcor
 No newline at end of file
+31 −30
Original line number Diff line number Diff line
#pragma once
#include <memory>
#include <unordered_map>
#include <vector>
#include <memory>

namespace xacc {
class CompositeInstruction;
@@ -9,8 +9,7 @@ class CompositeInstruction;
namespace qcor {
namespace internal {
// Stats about an optimization pass:
struct PassStat
{
struct PassStat {
  // Name of the pass
  std::string passName;
  // Count per gate
@@ -18,27 +17,29 @@ struct PassStat
  std::unordered_map<std::string, int> gateCountAfter;
  // Elapsed-time of this pass.
  double wallTimeMs;
  // Helper to collect stats.
  static std::unordered_map<std::string, int>
  countGates(const std::shared_ptr<xacc::CompositeInstruction> &program);
  // Pretty printer.
  std::string toString(bool shortForm = true) const;
};

class PassManager
{
class PassManager {
public:
  PassManager(int level);
  // Optimizes the input program.
  // Returns the full statistics about all the passes that have been executed.
    std::vector<PassStat> optimize(std::shared_ptr<xacc::CompositeInstruction> program) const;
  std::vector<PassStat>
  optimize(std::shared_ptr<xacc::CompositeInstruction> program) const;
  // List of passes for level 1:
  // Ordered list of passes to be executed.
  // Can have duplicated entries (run multiple times).
  static const constexpr char *const LEVEL1_PASSES[] = {
        "rotation-folding", 
        "circuit-optimizer",
        "swap-shortest-path"
    };
      "rotation-folding", "circuit-optimizer", "swap-shortest-path"};
  // TODO: define other levels if neccesary:
  // e.g. could be looping those passes multiple times.
private:
  int m_level;
};
}
}
 No newline at end of file
} // namespace internal
} // namespace qcor
 No newline at end of file
+4 −1
Original line number Diff line number Diff line
#include "qrt.hpp"
#include "Instruction.hpp"
#include "PauliOperator.hpp"
#include "pass_manager.hpp"
#include "xacc.hpp"
#include "xacc_internal_compiler.hpp"
#include "xacc_service.hpp"
@@ -283,6 +284,8 @@ void exp(qreg q, const double theta, std::shared_ptr<xacc::Observable> H) {
}

void submit(xacc::AcceleratorBuffer *buffer) {
  qcor::internal::PassManager passManager(__opt_level);
  const auto optData = passManager.optimize(program);
  xacc::internal_compiler::execute(buffer, program);
  clearProgram();
}