code: def _generate_tapes_and_cjacs(
      tape,
      operation,
      key,
      num_split_times,
      use_broadcasting,
      par_idx=None,
  ):
      """Generate the tapes and compute the classical Jacobians for one given
      generating Hamiltonian term of one pulse.
  
      Args:
          tape (QuantumScript): Tape for which to compute the stochastic pulse parameter-shift
              gradient tapes.
          operation (tuple[Operation, int, int]): Information about the pulse operation to be
              shifted. The first entry is the operation itself, the second entry is its position
              in the ``tape``, and the third entry is the index of the differentiated parameter
              (and generating term) within the ``HardwareHamiltonian`` of the operation.
          key (tuple[int]): Randomness key to create spliting times.
          num_split_times (int): Number of splitting times at which to create shifted tapes for
              the stochastic shift rule.
          use_broadcasting (bool): Whether to use broadcasting in the shift rule or not.
  
      Returns:
          list[QuantumScript]: Gradient tapes for the indicated operation and Hamiltonian term.
          list[tensor_like]: Classical Jacobian at the splitting times for the given parameter.
          float: Prefactor for the Monte Carlo estimate of the integral in the stochastic shift rule.
          tensor_like: Parameter-shift coefficients for the shift rule of the indicated term.
      """
      op, op_idx, term_idx = operation
      coeff, ob = (
          op.H.coeffs_parametrized[term_idx],
          op.H.ops_parametrized[term_idx],
      )
      if par_idx is None:
          cjac_fn = jax.jacobian(coeff, argnums=0)
      else:
          # For `par_idx is not None`, we need to extract the entry of the coefficient
          # Jacobian that belongs to the parameter of interest. This only happens when
          # more than one parameter effectively feeds into one coefficient (HardwareHamiltonian)
  
          def cjac_fn(params, t):
              return jax.jacobian(coeff, argnums=0)(params, t)[par_idx]
  
      t0, *_, t1 = op.t
      taus = jnp.sort(
          jax.random.uniform(key, shape=(num_split_times,)) * (t1 - t0)
          + t0
      )
      if isinstance(op.H, HardwareHamiltonian):
          op_data = op.H.reorder_fn(op.data, op.H.coeffs_parametrized)
      else:
          op_data = op.data
      cjacs = [cjac_fn(op_data[term_idx], tau) for tau in taus]
      if use_broadcasting:
          split_evolve_ops, psr_coeffs = _split_evol_ops(op, ob, taus)
          tapes = _split_evol_tape(tape, split_evolve_ops, op_idx)
      else:
          tapes = []
          for tau in taus:
              split_evolve_ops, psr_coeffs = _split_evol_ops(
                  op, ob, tau
              )
              tapes.extend(
                  _split_evol_tape(tape, split_evolve_ops, op_idx)
              )
      int_prefactor = (t1 - t0) / num_split_times
      return tapes, cjacs, int_prefactor, psr_coeffs
  
file_path: pennylane/pennylane/gradients/pulse_gradient.py
imports: from typing import Sequence, Callable
  from functools import partial
  import warnings
  import numpy
  import pennylane
  from pennylane.pulse import ParametrizedEvolution, HardwareHamiltonian
  from pennylane import transform
  from .parameter_shift import _make_zero_rep
  from .general_shift_rules import eigvals_to_frequencies, generate_shift_rule
  from .gradient_transform import _all_zero_grad, assert_no_state_returns, assert_no_tape_batching, assert_no_variance, choose_trainable_params, find_and_validate_gradient_methods, _no_trainable_grad, reorder_grads
label_desc: Use image node_id 7 for calling a global function with example usage: _generate_tapes_and_cjacs(tape, operation, key, num_split_times, use_broadcasting, par_idx) and returns: tapes,  cjacs,  int_prefactor,  psr_coeffs, jax