tensorflow / tensorflow/probability

InternalError: libdevice not found at ./libdevice.10.bc

Open
#1,376 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Jupyter Notebook
Stars
4.4k
Forks
1.1k
PR merge metrics
No merged PRs in 30d

Description

Hello,
I have some problems when I try to implement jit compilation for an ode. The minimum code to reproduce is

@tf.function(jit_compile=True)
def tf_spre(O):
    A = tf.eye( np.prod(O.shape[1]), dtype = tf.complex128 )
    B = O
    N = A.shape[0]
    return tf.reshape(tf.einsum('ik,jl', A, B), [N**2, N**2])

@tf.function(jit_compile=True)
def tf_spost(O):
    A = tf.transpose(O)
    B = tf.eye( np.prod(O.shape[0]), dtype = tf.complex128 )
    N = A.shape[0]
    return tf.reshape(tf.einsum('ik,jl', A, B), [N**2, N**2])

@tf.function(jit_compile=True)
def tf_sprepost(A, B):
    return tf.tensordot(tf_spre(A), tf_spost(B), axes = 1)

@tf.function(jit_compile=True)
def lindblad_dissipator(c_op):
    prod = tf.tensordot( tfla.adjoint(c_op), c_op, axes = 1 )
    return tf_sprepost(c_op, tfla.adjoint(c_op)) - 0.5 * tf_spre(prod) - 0.5 * tf_spost(prod)

@tf.function(jit_compile=True)
def tf_liouvillian(H):
    L = -1j * (tf_spre(H) - tf_spost(H))
    return L

@tf.function(jit_compile=True)
def expval(Op, rho_s):
    tmp = tf.tensordot( rho_s, Op, axes = [[2], [0]])
    return tfmt.real( tf.einsum('ijj->i', tmp) )

@tf.function(jit_compile=True)
def drho_dt(t, rho, H, H_t, lindbladian):
    A_sin = 0.01 * tfmt.sin(t)
    H_t = H_t * tf.cast(A_sin, dtype = tf.complex128)
    return tf.tensordot(tf_liouvillian(H + H_t) + lindbladian, rho, axes = [[1], [0]])

def tf_mesolve(H, H_t, psi0, t_l, c_ops, e_ops):
    H = tf.constant( H.full(), dtype = tf.complex128 )
    H_t = tf.constant( H_t.full(), dtype = tf.complex128 )
    psi0 = tf.constant( psi0.full(), dtype = tf.complex128 )
    rho0 = tf.tensordot(psi0, tfla.adjoint(psi0), axes = 1)
    
    N = H.shape[0]
    
    if len(c_ops) != 0:
        c_ops2 = np.zeros([len(c_ops), N, N], dtype = np.complex128)
        for i in range(len(c_ops)):
            c_ops2[i] = np.array( c_ops[i].full() )
    else:
        c_ops2 = np.zeros([1, N, N], dtype = np.complex128)
    
    if len(e_ops) != 0:
        e_ops2 = np.zeros([len(e_ops), N, N], dtype = np.complex128)
        for i in range(len(e_ops)):
            e_ops2[i] = np.array( e_ops[i].full() )
    else:
        e_ops2 = np.zeros([1, N, N], dtype = np.complex128)
    
    lindbladian = np.zeros([N**2, N**2], dtype = np.complex128)
    for i in range(c_ops2.shape[0]):
        lindbladian += lindblad_dissipator(c_ops2[i])
        
    #run_fn = tf.function(lambda: tfp.math.ode.DormandPrince(rtol=1e-3, atol=1e-5).solve(drho_dt, t_l[0], tf.reshape(rho0, [N**2]),
    #                               solution_times=t_l,
    #                                constants={"H": H, "H_t": H_t, "lindbladian": lindbladian}), jit_compile=True)
    #results = run_fn()
    
    results = tfp.math.ode.DormandPrince(rtol=1e-3, atol=1e-5, first_step_size=1e-2, safety_factor=0.9,
    min_step_size_factor=0.1, max_step_size_factor=10.0).solve(drho_dt, t_l[0], tf.reshape(rho0, [N**2]),
                                   solution_times=tfp.math.ode.ChosenBySolver(final_time=t_l[-1]), constants={"H": H, "H_t": H_t, "lindbladian": lindbladian})
    
    
    times = results.times
    states = results.states
    
    states = tf.reshape(states, [times.shape[0], N, N])
    
    expvals = []
    for i in range(len(e_ops)):
        expvals.append( expval(e_ops2[i], states) )
        
    return times, states, expvals
w_q = 1

sx = qtp.sigmax()
sz = qtp.sigmaz()
sp = qtp.sigmap()
sm = qtp.sigmam()

H = 0.5 * w_q * sz

gam_q = 0.1

c_ops = []
c_ops.append(np.sqrt(gam_q) * sm)
#c_ops.append(np.sqrt(gam_q) * sz)

e_ops = []
e_ops.append(sp * sm)

psi0 = (qtp.fock(2, 0) + 1j * qtp.fock(2, 1)).unit()

t_l = np.linspace(0, 10 / gam_q, 100)

times, states, tf_expect = tf_mesolve(H, sm + sp, psi0, t_l, c_ops, e_ops)

Here H is a 2x2 matrix.
This code returns the following error:

InternalError                             Traceback (most recent call last)
<timed exec> in <module>

<ipython-input-3-897b1854b462> in tf_mesolve(H, H_t, psi0, t_l, c_ops, e_ops)
     69     #results = run_fn()
     70 
---> 71     results = tfp.math.ode.DormandPrince(rtol=1e-3, atol=1e-5, first_step_size=1e-2, safety_factor=0.9,
     72     min_step_size_factor=0.1, max_step_size_factor=10.0).solve(drho_dt, t_l[0], tf.reshape(rho0, [N**2]),
     73                                    solution_times=tfp.math.ode.ChosenBySolver(final_time=t_l[-1]), constants={"H": H, "H_t": H_t, "lindbladian": lindbladian})

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow_probability/python/math/ode/base.py in solve(self, ode_fn, initial_time, initial_state, solution_times, jacobian_fn, jacobian_sparsity, batch_ndims, previous_solver_internal_state, constants)
    473     # custom_gradient will complain even if there are no variables in `ode_fn`.
    474     with tf1.variable_scope(tf1.get_variable_scope(), use_resource=True):
--> 475       return gradient_helper(*(flat_initial_state + flat_constants))
    476 
    477   @abc.abstractmethod

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/ops/custom_gradient.py in __call__(self, *a, **k)
    259 
    260   def __call__(self, *a, **k):
--> 261     return self._d(self._f, a, k)
    262 
    263 

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/ops/custom_gradient.py in decorated(wrapped, args, kwargs)
    213 
    214     if context.executing_eagerly():
--> 215       return _eager_mode_decorator(wrapped, args, kwargs)
    216     else:
    217       return _graph_mode_decorator(wrapped, args, kwargs)

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/ops/custom_gradient.py in _eager_mode_decorator(f, args, kwargs)
    437   """Implement custom gradient decorator for eager mode."""
    438   with tape_lib.VariableWatcher() as variable_watcher:
--> 439     result, grad_fn = f(*args, **kwargs)
    440   args = nest.flatten(args)
    441   all_inputs = list(args) + list(kwargs.values())

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow_probability/python/math/ode/base.py in gradient_helper(*flat_initial_state_and_constants)
    229           constant_state_structure, flat_constants)
    230 
--> 231       results = self._solve(
    232           ode_fn=functools.partial(ode_fn, **constants),
    233           initial_time=initial_time,

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow_probability/python/math/ode/dormand_prince.py in _solve(***failed resolving arguments***)
    197       solver_internal_state = previous_solver_internal_state
    198       if solver_internal_state is None:
--> 199         solver_internal_state = self._initialize_solver_internal_state(
    200             ode_fn=ode_fn,
    201             initial_state=p.initial_state,

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow_probability/python/math/ode/dormand_prince.py in _initialize_solver_internal_state(self, ode_fn, initial_time, initial_state)
    307     p = self._prepare_common_params(initial_state, initial_time)
    308 
--> 309     initial_derivative = ode_fn(p.initial_time, p.initial_state)
    310     initial_derivative = tf.nest.map_structure(tf.convert_to_tensor,
    311                                                initial_derivative)

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/eager/def_function.py in __call__(self, *args, **kwds)
    887 
    888       with OptionalXlaContext(self._jit_compile):
--> 889         result = self._call(*args, **kwds)
    890 
    891       new_tracing_count = self.experimental_get_tracing_count()

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/eager/def_function.py in _call(self, *args, **kwds)
    954               *args, **kwds)
    955       # If we did not create any variables the trace we have is good enough.
--> 956       return self._concrete_stateful_fn._call_flat(
    957           filtered_flat_args, self._concrete_stateful_fn.captured_inputs)  # pylint: disable=protected-access
    958 

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/eager/function.py in _call_flat(self, args, captured_inputs, cancellation_manager)
   1958         and executing_eagerly):
   1959       # No tape is watching; skip to running the function.
-> 1960       return self._build_call_outputs(self._inference_function.call(
   1961           ctx, args, cancellation_manager=cancellation_manager))
   1962     forward_backward = self._select_forward_and_backward_functions(

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/eager/function.py in call(self, ctx, args, cancellation_manager)
    589       with _InterpolateFunctionError(self):
    590         if cancellation_manager is None:
--> 591           outputs = execute.execute(
    592               str(self.signature.name),
    593               num_outputs=self._num_outputs,

~/anaconda3/envs/physics/lib/python3.9/site-packages/tensorflow/python/eager/execute.py in quick_execute(op_name, num_outputs, inputs, attrs, ctx, name)
     57   try:
     58     ctx.ensure_initialized()
---> 59     tensors = pywrap_tfe.TFE_Py_Execute(ctx._handle, device_name, op_name,
     60                                         inputs, attrs, num_outputs)
     61   except core._NotOkStatusException as e:

InternalError: libdevice not found at ./libdevice.10.bc [Op:__inference_drho_dt_12917]

I noticed it comes from a conflict between @tf.function(jit_compile=True) method and the time variable inside the drho_dt function. Indeed, if i eliminate the cast of the explicit time dependence, that is

@tf.function(jit_compile=True)
def drho_dt(t, rho, H, H_t, lindbladian):
    A_sin = 0.01 * tfmt.sin(t)
    return tf.tensordot(tf_liouvillian(H + H_t) + lindbladian, rho, axes = [[1], [0]])

of if I eliminate the @tf.function(jit_compile=True) method, the problem vanishes. Of course i need the time dependence for simulate driven dissipative quantum systems, and i want to compile that function, to speed up the calculation.

Moreover, the tensorflow ode is faster than the ode implemented in qutip package only for this small system. If I enter for example 20x20 matrices, the qutip (that is cpu) ode is 10 times faster.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the minimal Python reproduction around drho_dt and tfp.math.ode.DormandPrince, comparing the jit_compile=True and non-JIT paths. Reproduce the libdevice.10.bc error and determine whether the issue is in TensorFlow Probability's ODE invocation or the TensorFlow/XLA environment; done means the time-dependent JIT path works or the required environment limitation is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, tensorflow
Domain
machine-learning, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.