NVIDIA/cuda-quantum

[c++] qvector initialization from vector of doubles fails for f32 simulator

annagrin opened this issue · 2 comments

Required prerequisites

  • Consult the security policy. If reporting a security vulnerability, do not report the bug using this form. Use the process described in the policy to report the issue.
  • Make sure you've read the documentation. Your issue may be addressed there.
  • Search the issue tracker to verify that this hasn't already been reported. +1 or comment there if it has.
  • If possible, make a PR with a failing test to give us a starting point to work on!

Describe the bug

__qpu__ void test(std::vector<double> inState) {
  cudaq::qvector q = inState;
}

int main() {
  std::vector<double> vec{M_SQRT1_2, 0., 0., M_SQRT1_2};
  auto counts = cudaq::sample(test, vec);
  counts.dump();

  printf("size %zu\n", counts.size());
}

Running

Running this example on a f32 simulator results in a runtime failure:

nvq++ --enable-mlir -v from_state.cpp -o temp && ./temp

terminate called after throwing an instance of 'std::runtime_error'
  what():  Invalid user-provided state data. Simulator is FP32 but state data is FP64.
Aborted

MLIR

cudaq-quake -D CUDAQ_SIMULATION_SCALAR_FP32 from_state.cpp |cudaq-opt

module attributes {llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.triple = "x86_64-unknown-linux-gnu", quake.mangled_name_map = {__nvqpp__mlirgen__function_test._Z4testSt6vectorIdSaIdEE = "_Z4testSt6vectorIdSaIdEE"}} {
  func.func @__nvqpp__mlirgen__function_test._Z4testSt6vectorIdSaIdEE(%arg0: !cc.stdvec<f64>) attributes {"cudaq-entrypoint", "cudaq-kernel", no_this} {
    %0 = cc.stdvec_size %arg0 : (!cc.stdvec<f64>) -> i64
    %1 = math.cttz %0 : i64
    %2 = cc.stdvec_data %arg0 : (!cc.stdvec<f64>) -> !cc.ptr<f64>
    %3 = quake.alloca !quake.veq<?>[%1 : i64]
    %4 = quake.init_state %3, %2 : (!quake.veq<?>, !cc.ptr<f64>) -> !quake.veq<?>
    return
  }
  func.func @_Z4testSt6vectorIdSaIdEE(%arg0: !cc.ptr<!cc.struct<{!cc.ptr<f64>, !cc.ptr<f64>, !cc.ptr<f64>}>>) attributes {no_this} {
    return
  }
}

Steps to reproduce the bug

__qpu__ void test(std::vector<double> inState) {
  cudaq::qvector q = inState;
}

int main() {
  std::vector<double> vec{M_SQRT1_2, 0., 0., M_SQRT1_2};
  auto counts = cudaq::sample(test, vec);
  counts.dump();

  printf("size %zu\n", counts.size());
}

nvq++ --enable-mlir -v from_state.cpp -o temp && ./temp

Expected behavior

Qvector constructor should copy and cast the initializer data to the data types matching the simulation precision, so the example should complete successfully

Is this a regression? If it is, put the last known working version (or commit) here.

Not a regression

Environment

  • CUDA Quantum version:
  • Python version:
  • C++ compiler:
  • Operating system:

Suggestions

No response

Update: looks like the code generates unexpected results now, after the PRs above:

{ 00:1000 }
size 1 

Expected: 2