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

Implemented CLI option to use arbitrary placement



Included ability to pass qubit map from CLI

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 714f529f
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -31,6 +31,12 @@ public:
#endif
#ifdef __internal__qcor__compile__opt__passes
    xacc::internal_compiler::__user_opt_passes = __internal__qcor__compile__opt__passes;
#endif
#ifdef __internal__qcor__compile__placement__name
    xacc::internal_compiler::__placement_name = __internal__qcor__compile__placement__name;
#endif
#ifdef __internal__qcor__compile__qubit__map
    xacc::internal_compiler::__qubit_map = xacc::internal_compiler::parse_qubit_map(__internal__qcor__compile__qubit__map);
#endif
  }
};
+20 −3
Original line number Diff line number Diff line
@@ -42,7 +42,9 @@ printGateCountComparison(const std::unordered_map<std::string, int> &before,

namespace qcor {
namespace internal {
PassManager::PassManager(int level) : m_level(level) {}
PassManager::PassManager(int level, const std::vector<int> &qubitMap,
                         const std::string &placementName)
  : m_level(level), m_qubitMap(qubitMap), m_placement(placementName) {}

PassStat PassManager::runPass(const std::string &passName, std::shared_ptr<xacc::CompositeInstruction> program) {
  PassStat stat;
@@ -92,7 +94,18 @@ std::vector<PassStat> PassManager::optimize(
  return passData;
}

void PassManager::applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program, const std::string &placementName) {
void PassManager::applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program) const {
  const std::string placementName = [&]() -> std::string {
    // If the qubit-map was provided, always use default-placement
    if (!m_qubitMap.empty()) {
      return "default-placement";
    }
    // Use the specified placement if any.
    // Note: placement will only be activated if the accelerator
    // has a connectivity graph.
    return m_placement.empty() ? DEFAULT_PLACEMENT : m_placement;
  }();
  
  if (!xacc::hasService<xacc::IRTransformation>(placementName)
      && !xacc::hasContributedService<xacc::IRTransformation>(placementName)) {
    // Graciously ignores services which cannot be located.
@@ -103,9 +116,13 @@ void PassManager::applyPlacement(std::shared_ptr<xacc::CompositeInstruction> pro
  if (irt->type() == xacc::IRTransformationType::Placement &&
    xacc::internal_compiler::qpu &&
    !xacc::internal_compiler::qpu->getConnectivity().empty()) {
    if (placementName == "default-placement") {
      irt->apply(program, xacc::internal_compiler::qpu, {{"qubit-map", m_qubitMap}});
    } else {
      irt->apply(program, xacc::internal_compiler::qpu);
    }
  }
}

std::unordered_map<std::string, int> PassStat::countGates(
    const std::shared_ptr<xacc::CompositeInstruction> &program) {
+6 −2
Original line number Diff line number Diff line
@@ -26,13 +26,13 @@ struct PassStat {

class PassManager {
public:
  PassManager(int level);
  PassManager(int level, const std::vector<int> &qubitMap = {}, const std::string &placementName = "");
  // Static helper to run an optimization pass
  static PassStat runPass(const std::string &passName, std::shared_ptr<xacc::CompositeInstruction> program);
  // Default placement strategy
  static constexpr const char *DEFAULT_PLACEMENT = "swap-shortest-path";
  // Apply placement
  static void applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program, const std::string &placementName = DEFAULT_PLACEMENT);
  void applyPlacement(std::shared_ptr<xacc::CompositeInstruction> program) const;

  // Optimizes the input program.
  // Returns the full statistics about all the passes that have been executed.
@@ -64,7 +64,11 @@ public:
    "circuit-optimizer",
  };
private:
  // Circuit optimization level
  int m_level;
  // Placement config.
  std::vector<int> m_qubitMap;
  std::string m_placement;
};
} // namespace internal
} // namespace qcor
 No newline at end of file
+23 −4
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@ int __opt_level = 0;
bool __print_opt_stats = false;
std::vector<int> __controlledIdx = {};
std::string __user_opt_passes = "";
std::string __placement_name = "";
std::vector<int> __qubit_map = {};

void simplified_qrt_call_one_qbit(const char *gate_name,
                                  const char *buffer_name,
@@ -39,7 +41,7 @@ void simplified_qrt_call_two_qbits(const char *gate_name,
}

void execute_pass_manager() {
  qcor::internal::PassManager passManager(__opt_level);
  qcor::internal::PassManager passManager(__opt_level, __qubit_map, __placement_name);
  auto optData = passManager.optimize(::quantum::program);
  
  std::vector<std::string> user_passes;
@@ -64,11 +66,28 @@ void execute_pass_manager() {
      std::cout << passData.toString(false);
    }
  }
  // Apply placement:
  // TODO: add option to change the placement strategy.
  qcor::internal::PassManager::applyPlacement(::quantum::program);

  passManager.applyPlacement(::quantum::program);
}

std::vector<int> parse_qubit_map(const char *qubit_map_str) {
  std::vector<int> qubitMap;
  std::stringstream ss(qubit_map_str);
  while (ss.good()) {
    // Split by ',' delimiter
    try {
      std::string qubitId;
      std::getline(ss, qubitId, ',');
      qubitMap.emplace_back(std::stoi(qubitId));
    }
    catch (...)
    {
      // Cannot parse the integer.
      return {};
    }
  }
  return qubitMap;
}

} // namespace internal_compiler
} // namespace xacc
+8 −0
Original line number Diff line number Diff line
@@ -124,6 +124,14 @@ extern bool __print_opt_stats;
// User-customized passes to run
extern std::string __user_opt_passes;

// Placement strategy specified in the QCOR command line.
extern std::string __placement_name;
// Qubit map for DefaultPlacement transformation.
// If provided in the command line (not empty),
// we'll map qubits according to this.
extern std::vector<int> __qubit_map;
extern std::vector<int> parse_qubit_map(const char *qubit_map_str);

void simplified_qrt_call_one_qbit(const char *gate_name,
                                  const char *buffer_name,
                                  const std::size_t idx);
Loading