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

Updated exatn-gen gate count



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 9ab43ed3
Loading
Loading
Loading
Loading
+45 −15
Original line number Diff line number Diff line
@@ -252,7 +252,8 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::initialize(
  // Default number of layers
  m_layersReconstruct = 4;
  m_countByGates = false;
  m_layerTracker.clear();
  // m_layerTracker.clear();
  m_qubitToGateCount.clear();
  if (options.keyExists<int>("reconstruct-gates")) {
    m_layersReconstruct = options.get<int>("reconstruct-gates");
    xacc::info("Reconstruct tensor network every " +
@@ -385,6 +386,9 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::initialize(
template <typename TNQVM_COMPLEX_TYPE>
void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::finalize() {
  m_buffer->addExtraInfo("reconstruction-fidelity", m_reconstructionFidelity);
  if (m_layerCounter > 0) {
    reconstructCircuitTensor(true);
  }
  // This is a single-circuit execution.
  // Do the evaluation now.
  if (!m_obsTensorOperator && !m_measuredBits.empty()) {
@@ -681,12 +685,15 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::appendGateTensor(
}

template <typename TNQVM_COMPLEX_TYPE>
void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::reconstructCircuitTensor() {
void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::reconstructCircuitTensor(bool forced) {
  if (m_layersReconstruct <= 0) {
    return;
  }
  if (m_layerCounter >= m_layersReconstruct) {
  if (m_layerCounter > m_layersReconstruct || forced) {
    xacc::info("Reconstruct Tensor Expansion");
    // Flush the count every reconstruct:
    m_qubitToGateCount.clear();
    // m_tensorExpansion.printIt();
    auto target = std::make_shared<exatn::TensorExpansion>(m_tensorExpansion);
    // List of Approximate tensors to delete:
    static std::vector<std::string> TENSORS_TO_DESTROY;
@@ -1042,23 +1049,46 @@ void ExatnGenVisitor<TNQVM_COMPLEX_TYPE>::updateLayerCounter(
  if (m_countByGates) {
    ++m_layerCounter;
  } else {
    bool canCombine = true;
    const auto q1 = gate.bits()[0];
    const auto q2 = gate.bits()[1];
    if (m_qubitToGateCount.find(q1) != m_qubitToGateCount.end()) {
      m_qubitToGateCount[q1] = m_qubitToGateCount[q1] + 1;
    } else {
      m_qubitToGateCount[q1] = 1;
    }

    for (const auto& [bit1, bit2]: m_layerTracker) {
      if ((q1 == bit1 || q1 == bit2) || (q2 == bit1 || q2 == bit2)) {
        canCombine = false;
        break;
    if (m_qubitToGateCount.find(q2) != m_qubitToGateCount.end()) {
      m_qubitToGateCount[q2] = m_qubitToGateCount[q2] + 1;
    } else {
      m_qubitToGateCount[q2] = 1;
    }

    // Update layer counter = max qubit counter across all qubits.
    for (const auto &[qId, counter] : m_qubitToGateCount) {
      if (counter > m_layerCounter) {
        m_layerCounter = counter;
      }
    if (canCombine) {
      m_layerTracker.emplace(std::make_pair(q1, q2));
    } else {
      ++m_layerCounter;
      m_layerTracker.clear();
      m_layerTracker.emplace(std::make_pair(q1, q2));
    }
    {
      std::stringstream ss;
      ss << "Processing " << gate.toString() << " : " << m_layerCounter;
      xacc::info(ss.str());
    }
    

    // for (const auto& [bit1, bit2]: m_layerTracker) {
    //   if ((q1 == bit1 || q1 == bit2) || (q2 == bit1 || q2 == bit2)) {
    //     canCombine = false;
    //     break;
    //   } 
    // }
    // if (canCombine) {
    //   m_layerTracker.emplace(std::make_pair(q1, q2));
    // } else {
    //   ++m_layerCounter;
    //   m_layerTracker.clear();
    //   m_layerTracker.emplace(std::make_pair(q1, q2));
    // }
  }
}
} // end namespace tnqvm
+3 −2
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ private:
  analyzeObsSubCircuit(std::shared_ptr<CompositeInstruction> in_function) const;
  exatn::TensorOperator
  constructObsTensorOperator(const std::vector<ObsOpType> &in_obsOps) const;
  void reconstructCircuitTensor();
  void reconstructCircuitTensor(bool forced = false);
  // Compute the wave-function slice or amplitude (if all bits are set):
  std::vector<TNQVM_COMPLEX_TYPE>
  computeWaveFuncSlice(const exatn::TensorNetwork &in_tensorNetwork,
@@ -142,7 +142,8 @@ private:

private:
  void updateLayerCounter(const xacc::Instruction &in_gateInstruction);
  std::set<std::pair<size_t, size_t>> m_layerTracker;
  // std::set<std::pair<size_t, size_t>> m_layerTracker;
  std::unordered_map<size_t, size_t> m_qubitToGateCount;
  std::shared_ptr<exatn::TensorNetwork> m_qubitNetwork;
  exatn::TensorExpansion m_tensorExpansion;
  std::shared_ptr<exatn::TensorExpansion> m_previousOptExpansion;
+77 −3
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@ TEST(ExaTnGenTester, checkExpVal) {
  {
    // Check exp-val by tensor expansion
    auto accelerator =
        xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"}});
        xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"}, {"reconstruct-gates", -1}});
    auto xasmCompiler = xacc::getCompiler("xasm");
    auto program = xasmCompiler
                       ->compile(R"(__qpu__ void testRY(qbit q, double t) {
@@ -46,7 +46,7 @@ TEST(ExaTnGenTester, checkExpVal) {
  }
  {
    auto accelerator =
        xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"}});
        xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"}, {"reconstruct-gates", -1}});
    auto xasmCompiler = xacc::getCompiler("xasm");
    auto ir = xasmCompiler->compile(R"(__qpu__ void ansatz(qbit q, double t)
    {
@@ -84,7 +84,7 @@ TEST(ExaTnGenTester, checkExpVal) {

TEST(ExaTnGenTester, checkVqeH2) {
  auto accelerator =
      xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"}});
      xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"}, {"reconstruct-gates", -1}});
  // Create the N=2 deuteron Hamiltonian
  auto H_N_2 = xacc::quantum::getObservable(
      "pauli", std::string("5.907 - 2.1433 X0X1 "
@@ -253,6 +253,80 @@ TEST(ExaTnGenTester, checkVqeH3Approx) {
  EXPECT_NEAR(energies[0], -2.04482, 0.25);
}

TEST(ExaTnGenTester, checkNewLayerCount) {
  // Use very high tolerance to save test time
  auto accelerator =
      xacc::getAccelerator("tnqvm", {{"tnqvm-visitor", "exatn-gen"},
                                     {"reconstruct-layers", 4},
                                     {"reconstruct-tolerance", 0.1}});
  xacc::set_verbose(true);
  xacc::qasm(R"(
        .compiler xasm
        .circuit test_layers
        .qbit q
        X(q[0]);
        CX(q[0], q[1]);
        CX(q[0], q[1]);
        CX(q[2], q[3]);
        CX(q[2], q[3]);
        CX(q[4], q[5]);
        CX(q[4], q[5]);
        CX(q[6], q[7]);
        CX(q[6], q[7]);
        CX(q[1], q[2]);
        CX(q[1], q[2]);
        CX(q[3], q[4]);
        CX(q[3], q[4]);
        CX(q[5], q[6]);
        CX(q[5], q[6]);
        CX(q[0], q[1]);
        CX(q[0], q[1]);
        CX(q[2], q[3]);
        CX(q[2], q[3]);
        CX(q[4], q[5]);
        CX(q[4], q[5]);
        CX(q[6], q[7]);
        CX(q[6], q[7]);
        CX(q[1], q[2]);
        CX(q[1], q[2]);
        CX(q[3], q[4]);
        CX(q[3], q[4]);
        CX(q[5], q[6]);
        CX(q[5], q[6]);
        CX(q[0], q[1]);
        CX(q[0], q[1]);
        CX(q[2], q[3]);
        CX(q[2], q[3]);
        CX(q[4], q[5]);
        CX(q[4], q[5]);
        CX(q[6], q[7]);
        CX(q[6], q[7]);
        CX(q[1], q[2]);
        CX(q[1], q[2]);
        CX(q[3], q[4]);
        CX(q[3], q[4]);
        CX(q[5], q[6]);
        CX(q[5], q[6]);
        CX(q[0], q[1]);
        CX(q[0], q[1]);
        CX(q[2], q[3]);
        CX(q[2], q[3]);
        CX(q[4], q[5]);
        CX(q[4], q[5]);
        CX(q[6], q[7]);
        CX(q[6], q[7]);
        CX(q[1], q[2]);
        CX(q[1], q[2]);
        CX(q[3], q[4]);
        CX(q[3], q[4]);
        CX(q[5], q[6]);
        CX(q[5], q[6]);
    )");
  auto qreg = xacc::qalloc(8);
  auto program = xacc::getCompiled("test_layers");
  accelerator->execute(qreg, program);
}

int main(int argc, char **argv) {
  xacc::Initialize(argc, argv);
  ::testing::InitGoogleTest(&argc, argv);