Hihi! I’m exploring an application for Catalyst callbacks where I need to call a Python function that doesn’t particularly fit into the ‘pure_callback’ requirement from the docs. Concretely, my function accesses a global object living in Python-controlled space and returns different results from the same inputs because it depends on the global state.
Surprisingly, it works quite well.
My question is: in what scenarios should I expect impure callbacks to cause failures? Can I still hope for correct execution if I don’t use differentiation? Or if I only run circuit in one-shot mcm mode?
Thanks!
PS
Consider the following code as an illustration of callback overuse
def test_pl_random_callback_works():
prob=0.5
num_shots=1000
@pure_callback
def random_callback(key, prob:ShapedArray([],dtype=float)) -> ShapedArray([],dtype=bool):
res_bool = random.random() < float(prob)
return jnp.array(res_bool, dtype=bool)
@qjit
@qml.qnode(qml.device("lightning.qubit",wires=17), shots=num_shots, mcm_method="one-shot")
def _circuit():
return random_callback(0, prob)
res=_circuit()
print(res)
assert len(res)==num_shots
percentage1 = len([b for b in res if b])/num_shots
print(percentage1, prob)
assert_allclose(percentage1, prob, atol=0.1, rtol=0.1)