1
$\begingroup$

I am trying to use Stim in C++. Until now, most functionality worked as expected. However, I recently tried to construct a Stim circuit in C++ and pass it to Python via pybind11, and this causes a weird behavior. For example, with my function:

void circuit_append(
        stim::Circuit &self,
        const std::string &gate_name,
        const std::vector<uint32_t> &targets,
        const std::vector<double> &args,
        bool backwards_compat) {    

        if (backwards_compat && stim::GATE_DATA.at(gate_name).arg_count == 1) {
            // If the gate expects exactly one argument but none provided, use a default value.
            if (args.empty()) {
                self.safe_append_ua(gate_name, targets, 0.0);
            } else if (args.size() == 1) {
                self.safe_append_ua(gate_name, targets, args[0]);
            } else {
                throw std::invalid_argument("Gate expects exactly one argument.");
            }
        } else {
            // For gates that do not specifically require backwards compatibility handling or
            // can accept multiple arguments.
            if (args.size() == 1) {
                // If only one argument is provided, you could still use safe_append_ua for consistency.
                self.safe_append_ua(gate_name, targets, args[0]);
            } else {
                // Use safe_append_u for gates with multiple arguments or no arguments at all.
                self.safe_append_u(gate_name, targets, args);
            }
        }
    }

It checks the conditions for the wrong gates regarding the args etc. For example, trying to do:

append_custom(circuit, "DEPOLARIZE1", [1], [0.1])

corresponding to a "DEPOLARIZE1" channel on qubit 0 with 0.1 as the error probability it will throw:

ValueError: Gate H_YZ was given 1 parens arguments (0.1) but takes 0 parens arguments.

Does anyone know how to solve this issue?

$\endgroup$
1
  • $\begingroup$ Moreover, if I try to read a stim circuit from a .stim file in CPP with circuit.append_from_file, the gates in the circuit it will create will be completely different except "M", "MR" and "TICK". $\endgroup$ Commented Mar 25 at 18:33

1 Answer 1

1
$\begingroup$

My best guess is that you're interacting different versions of the C++ code, and they disagree on the indexing of the GateType enum (since this has not been kept consistent over time). If anything, you're lucky this manifested in such a simple way, since there are many many other ways in which binary compatibility is broken from version to version (e.g. adding/removing/reordering fields in structs).

A simple way to test this is to see if the problem goes away if you ensure the source you are building from matches the version of the stim wheel that you have installed. For example, if you have the v1.13.0 wheel installed (use print(stim.__version__) to get the wheel's version), then you should be building from tag v1.13.0 (which is commit b01e42391583d03db4266b387d907eda1d7ae488). Alternatively, build your own version of the wheel from the same version of the source code you are mucking around with (IMO the easiest way is the bazel method).

A simple workaround, for passing a circuit between versions of stim that are not guaranteed to be binary compatible, is to serialize to a string and parse the string. For example:

pybind11::object wrap_circuit(const stim::Circuit &circuit) {
    pybind11::object serialized = pybind11::cast(circuit.str());
    pybind11::object python_circuit_class = pybind11::module_::import("stim").attr("Circuit");
    return python_circuit_class(serialized);
}

stim::Circuit unwrap_circuit(const pybind11::object &circuit) {
    std::string contents = pybind11::cast<std::string>(pybind11::str(circuit));
    return stim::Circuit(contents.data());
}

This workaround is why pymatching can take circuits and detector error models despite being built with binary linking to a version of stim that may disagree with the version in the wheel the user has installed.

$\endgroup$
1
  • $\begingroup$ Building the stim_dev_wheel worked for me, thank you! $\endgroup$ Commented Mar 28 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.