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

Refactor qubits in array symbol names



Use '%' as internal separators b/w array name and index.

Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 1ed1f0e2
Loading
Loading
Loading
Loading
+8 −8
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ QCOR_EXPECT_TRUE(m1[5] == 0);

// Test 2: Alias by slice:
// 0, 1, 2, 3 (inclusive)
let myreg_1 = q[0:3];
x myreg_1;
let myreg1 = q[0:3];
x myreg1;
// Measure all qubits
bit m2[6];
m2 = measure q;
@@ -57,8 +57,8 @@ QCOR_EXPECT_TRUE(m2[5] == 0);
reset q;

// Range with step size (0, 2, 4)
let myreg_2 = q[0:2:5];
x myreg_2;
let myreg2 = q[0:2:5];
x myreg2;
// Measure all qubits
bit m3[6];
m3 = measure q;
@@ -77,8 +77,8 @@ QCOR_EXPECT_TRUE(m3[5] == 0);
reset q;
// Range with negative step:
// 4, 3, 2
let myreg_3 = q[4:-1:2];
x myreg_3;
let myreg3 = q[4:-1:2];
x myreg3;
// Measure all qubits
bit m4[6];
m4 = measure q;
@@ -97,8 +97,8 @@ QCOR_EXPECT_TRUE(m4[5] == 0);
reset q;
// Range with start = stop
// This is q[5]
let myreg_4 = q[5:5];
x myreg_4;
let myreg4 = q[5:5];
x myreg4;
// Measure all qubits
bit m5[6];
m5 = measure q;
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ mlir::Value get_or_extract_qubit(const std::string &qreg_name,
                                 const std::size_t idx, mlir::Location location,
                                 ScopedSymbolTable &symbol_table,
                                 mlir::OpBuilder &builder) {
  auto key = qreg_name + std::to_string(idx);
  auto key = symbol_table.array_qubit_symbol_name(qreg_name, idx);
  if (symbol_table.has_symbol(key)) {
    return symbol_table.get_symbol(key);  // global_symbol_table[key];
  } else {
+13 −0
Original line number Diff line number Diff line
@@ -408,6 +408,19 @@ class ScopedSymbolTable {
    return current_scope >= 1 ? current_scope - 1 : 0;
  }

  // Util to construct a symbol name for qubit within an array (qreg)
  // This is to make sure we have a consitent symbol naming convention (for SSA tracking).
  std::string array_qubit_symbol_name(const std::string &qreg_name,
                                      const std::string &index_str) {
    // Sanity check: we should have added the qreg var to the symbol table.
    assert(has_symbol(qreg_name));
    // Use '%' separator to prevent name clashes with user-defined variables
    return qreg_name + '%' + index_str;
  }
  std::string array_qubit_symbol_name(const std::string &qreg_name, int index) {
    return array_qubit_symbol_name(qreg_name, std::to_string(index));
  }

  ~ScopedSymbolTable() {}
};
}  // namespace qcor
 No newline at end of file
+12 −12
Original line number Diff line number Diff line
@@ -93,9 +93,9 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
              // Put the *alias* qubit (alias-name + index) into the symbol
              // table: mapped to the original qubit:
              const std::string alias_qubit_var_name =
                  in_aliasName + std::to_string(counter);
                  symbol_table.array_qubit_symbol_name(in_aliasName, counter);
              const std::string original_qubit_var_name =
                  allocated_variable + std::to_string(idx);
                  symbol_table.array_qubit_symbol_name(allocated_variable, idx);
              if (!symbol_table.has_symbol(original_qubit_var_name)) {
                // This original qubit has never been extracted...
                // Just create an extract and cache to the symbol table
@@ -194,6 +194,8 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
            };
            const auto new_size =
                slice_size_calc(orig_size, range_start, range_step, range_stop);
            symbol_table.add_symbol(in_aliasName, array_slice,
                                    {std::to_string(new_size)});
            // std::cout << "Adding symbol 2 " << in_aliasName << "\n";
            for (int dest_idx = 0; dest_idx < new_size; ++dest_idx) {
              const int64_t range_start_pos =
@@ -203,9 +205,10 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
              // Put the *alias* qubit (alias-name + index) into the symbol
              // table: mapped to the original qubit:
              const std::string alias_qubit_var_name =
                  in_aliasName + std::to_string(dest_idx);
                  symbol_table.array_qubit_symbol_name(in_aliasName, dest_idx);
              const std::string original_qubit_var_name =
                  allocated_variable + std::to_string(source_idx);
                  symbol_table.array_qubit_symbol_name(allocated_variable,
                                                       source_idx);
              if (!symbol_table.has_symbol(original_qubit_var_name)) {
                // This original qubit has never been extracted...
                // Just create an extract and cache to the symbol table
@@ -221,9 +224,6 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
              symbol_table.add_symbol_ref_alias(original_qubit_var_name,
                                                alias_qubit_var_name);
            }

            symbol_table.add_symbol(in_aliasName, array_slice,
                                    {std::to_string(new_size)});
          } else {
            printErrorMessage("Could not parse the alias statement.",
                              in_indexIdentifierContext);
@@ -275,6 +275,8 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
              builder.create<mlir::quantum::ArrayConcatOp>(
                  location, array_type, first_reg_symbol, second_reg_symbol);
          const auto new_size = first_reg_size + second_reg_size;
          symbol_table.add_symbol(in_aliasName, array_concat,
                                  {std::to_string(new_size)});
          // std::cout << "Concatenate " << lhs_temp_var << "[" <<
          // first_reg_size
          //           << "] with " << rhs_temp_var << "[" << second_reg_size
@@ -294,9 +296,10 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
            // Put the *alias* qubit (alias-name + index) into the symbol
            // table: mapped to the original qubit:
            const std::string alias_qubit_var_name =
                in_aliasName + std::to_string(dest_idx);
                symbol_table.array_qubit_symbol_name(in_aliasName, dest_idx);
            const std::string original_qubit_var_name =
                source_reg_name + std::to_string(source_idx);
                symbol_table.array_qubit_symbol_name(source_reg_name,
                                                     source_idx);
            if (!symbol_table.has_symbol(original_qubit_var_name)) {
              // This original qubit has never been extracted...
              // Just create an extract and cache to the symbol table
@@ -312,9 +315,6 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
            symbol_table.add_symbol_ref_alias(original_qubit_var_name,
                                              alias_qubit_var_name);
          }

          symbol_table.add_symbol(in_aliasName, array_concat,
                                  {std::to_string(new_size)});
        } else {
          printErrorMessage("Could not parse the alias statement.",
                            in_indexIdentifierContext);
+9 −7
Original line number Diff line number Diff line
@@ -299,10 +299,12 @@ antlrcpp::Any qasm3_visitor::visitQuantumGateCall(
    if (idx_identifier->LBRACKET()) {
      // this is a qubit indexed from an array
      auto idx_str = idx_identifier->expressionList()->expression(0)->getText();
      const auto qubit_symbol_name =
          symbol_table.array_qubit_symbol_name(qbit_var_name, idx_str);
      mlir::Value value;
      try {
        if (symbol_table.has_symbol(qbit_var_name + idx_str)) {
          value = symbol_table.get_symbol(qbit_var_name + idx_str);
        if (symbol_table.has_symbol(qubit_symbol_name)) {
          value = symbol_table.get_symbol(qubit_symbol_name);
        } else {
          // try catch is on this std::stoi(), if idx_str is not an integer,
          // then we drop out and try to evaluate the expression.
@@ -322,8 +324,8 @@ antlrcpp::Any qasm3_visitor::visitQuantumGateCall(
          }
          value = builder.create<mlir::quantum::ExtractQubitOp>(
              location, qubit_type, qubits, qbit);
          if (!symbol_table.has_symbol(qbit_var_name + idx_str))
            symbol_table.add_symbol(qbit_var_name + idx_str, value);
          if (!symbol_table.has_symbol(qubit_symbol_name))
            symbol_table.add_symbol(qubit_symbol_name, value);
        } else {
          qasm3_expression_generator exp_generator(builder, symbol_table,
                                                   file_name, qubit_type);
@@ -347,14 +349,14 @@ antlrcpp::Any qasm3_visitor::visitQuantumGateCall(

            value = builder.create<mlir::quantum::ExtractQubitOp>(
                location, qubit_type, qubits, value);
            if (!symbol_table.has_symbol(qbit_var_name + idx_str))
              symbol_table.add_symbol(qbit_var_name + idx_str, value);
            if (!symbol_table.has_symbol(qubit_symbol_name))
              symbol_table.add_symbol(qubit_symbol_name, value);
          }
        }
      }

      qbit_values.push_back(value);
      qubit_symbol_table_keys.push_back(qbit_var_name + idx_str);
      qubit_symbol_table_keys.push_back(qubit_symbol_name);

    } else {
      // this is a qubit