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

Work on qubit array slice



Signed-off-by: default avatarThien Nguyen <nguyentm@ornl.gov>
parent 9ba7c6d0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ def AssignQubitOp : QuantumOp<"qassign", []> {
    let results = (outs);
}

// Extract array slice
def ArraySliceOp : QuantumOp<"qarray_slice", []> {
    let arguments = (ins ArrayType:$qreg, Variadic<I64>:$slice_range);
    let results = (outs ArrayType:$array_slice);
}

def InstOp : QuantumOp<"inst", [AttrSizedOperandSegments]> {
    let arguments = (ins StrAttr:$name, Variadic<QubitType>:$qubits, Variadic<F64>:$params);
    let results = (outs Optional<ResultType>:$bit);
+41 −2
Original line number Diff line number Diff line
@@ -59,11 +59,50 @@ antlrcpp::Any qasm3_visitor::visitAliasStatement(
      builder.create<mlir::quantum::AssignQubitOp>(
          location, alias_allocation, dest_idx, allocated_symbol, src_idx);
    }

  } else if (auto range_def = context->indexIdentifier()->rangeDefinition()) {
    // handle range definition
    // I think we can handle RANGE with a memref<3xi64>...
    const size_t n_expr = range_def->expression().size();
    // Minimum is two expressions and not more than 3
    if (n_expr < 2 || n_expr > 3) {
      printErrorMessage("Invalid array slice range.");
    }

    auto range_start_expr = range_def->expression(0);
    auto range_stop_expr =
        (n_expr == 2) ? range_def->expression(1) : range_def->expression(2);

    const auto resolve_range_value = [&](auto *range_item_expr) -> int64_t {
      const std::string range_item_str = range_item_expr->getText();
      try {
        return std::stoi(range_item_str);
      } catch (std::exception &ex) {
        return symbol_table.evaluate_constant_integer_expression(
            range_item_str);
      }
    };

    const int64_t range_start = resolve_range_value(range_start_expr);
    const int64_t range_stop = resolve_range_value(range_stop_expr);
    const int64_t range_step =
        (n_expr == 2) ? 1 : resolve_range_value(range_def->expression(1));

    // Step must not be zero:
    if (range_step == 0) {
      printErrorMessage("Invalid range: step size must be non-zero.");
    }

    std::cout << "Range: Start = " << range_start << "; Step = " << range_step << "; Stop = " << range_stop << "\n";
    auto range_start_mlir_val = get_or_create_constant_integer_value(
        range_start, location, builder.getI64Type(), symbol_table, builder);
    auto range_step_mlir_val = get_or_create_constant_integer_value(
        range_step, location, builder.getI64Type(), symbol_table, builder);
    auto range_stop_mlir_val = get_or_create_constant_integer_value(
        range_stop, location, builder.getI64Type(), symbol_table, builder);
    // I think we can handle RANGE with a memref<3xi64>...
    mlir::Value array_slice = builder.create<mlir::quantum::ArraySliceOp>(
        location, array_type, allocated_symbol,
        llvm::makeArrayRef(std::vector<mlir::Value>{
            range_start_mlir_val, range_step_mlir_val, range_stop_mlir_val}));
  } else {
    // handle concatenation
  }
+5 −0
Original line number Diff line number Diff line
@@ -68,6 +68,11 @@ int8_t *__quantum__rt__array_get_element_ptr_1d(Array *q, uint64_t idx);
Array *__quantum__rt__array_copy(Array *array, bool forceNewInstance);
// Concatenate
Array *__quantum__rt__array_concatenate(Array *head, Array *tail);
// Slice
// Creates and returns an array that is a slice of an existing array. 
// The int dim which dimension the slice is on (0 for 1d arrays). 
// The Range range specifies the slice.
Array *__quantum__rt__array_slice(Array *array, int32_t dim, Range range);
// Ref. counting
void __quantum__rt__array_update_alias_count(Array *array, int64_t increment);
void __quantum__rt__array_update_reference_count(Array *aux, int64_t count);
+7 −0
Original line number Diff line number Diff line
@@ -78,3 +78,10 @@ enum Pauli : int8_t {
};

enum QRT_MODE { FTQC, NISQ };

// QIR Range type:
struct Range {
  int64_t start;
  int64_t step;
  int64_t end;
};
 No newline at end of file
+9 −0
Original line number Diff line number Diff line
@@ -15,6 +15,15 @@ int64_t __quantum__rt__array_get_size_1d(Array *state1) {
  return state1->size();
}

Array *__quantum__rt__array_slice(Array *array, int32_t dim, Range range) {
  if (verbose)
    std::cout << "[qir-qrt] Extract array slice for the range [" << range.start
              << ":" << range.step << ":" << range.end << "].\n";

  // TODO:
  return array;
}

void __quantum__rt__array_update_alias_count(Array *array, int64_t increment) {
  // TODO
  if (verbose)
Loading