class_docstr: Test the helper routine ``_parshift_and_integrate``. Most tests use uniform
  return types and parameters, so that we can test against simple tensor contractions.
class_docstr_tok: ["Test","the","helper","routine","``","_parshift_and_integrate","``",".","Most","tests","use","uniform","return","types","and","parameters",",","so","that","we","can","test","against","simple","tensor","contractions","."]
docstr: Test that ``_parshift_and_integrate`` works with results for multiple measurements
  per shift and splitting time and with multiple shot settings. This corresponds to
  ``single_measure=False and has_partitioned_shots=True``. The test is parametrized with whether
  or not there are multiple Hamiltonian terms to take into account (and sum their
  contributions), with the shape of the single measurement and of the parameter, with
  the number of shifts in the shift rule and with the number of splitting times.
  This is the variant of the previous test that uses broadcasting.
docstr_tok: ["Test","that","``","_parshift_and_integrate","``","works","with","results","for","multiple","measurements","per","shift","and","splitting","time","and","with","multiple","shot","settings",".","This","corresponds","to","``","single_measure=False","and","has_partitioned_shots=True","``",".","The","test","is","parametrized","with","whether","or","not","there","are","multiple","Hamiltonian","terms","to","take","into","account","(","and","sum","their","contributions",")",",","with","the","shape","of","the","single","measurement","and","of","the","parameter",",","with","the","number","of","shifts","in","the","shift","rule","and","with","the","number","of","splitting","times",".","This","is","the","variant","of","the","previous","test","that","uses","broadcasting","."]
code: def test_multi_measure_multi_shots_broadcast(
      self,
      num_split_times,
      num_shifts,
      par_shape,
      multi_term,
      meas_shape,
  ):
      """Test that ``_parshift_and_integrate`` works with results for multiple measurements
      per shift and splitting time and with multiple shot settings. This corresponds to
      ``single_measure=False and has_partitioned_shots=True``. The test is parametrized with whether
      or not there are multiple Hamiltonian terms to take into account (and sum their
      contributions), with the shape of the single measurement and of the parameter, with
      the number of shifts in the shift rule and with the number of splitting times.
      This is the variant of the previous test that uses broadcasting.
      """
      from jax import numpy as jnp
  
      np.random.seed(3751)
  
      num_shots = 3
      num_meas = 5
  
      cjac_shape = (num_split_times,) + par_shape
      if multi_term > 1:
          cjacs = tuple(
              np.random.random(cjac_shape) for _ in range(multi_term)
          )
          psr_coeffs = tuple(
              np.random.random(num_shifts) for _ in range(multi_term)
          )
      else:
          cjacs = np.random.random(cjac_shape)
          psr_coeffs = np.random.random(num_shifts)
  
      results_shape = (
          num_shifts * multi_term,
          num_shots,
          num_meas,
          (num_split_times + 2),
      ) + meas_shape
      new_results_shape = (
          multi_term,
          num_shifts,
          num_shots,
          num_meas,
          num_split_times + 2,
      ) + meas_shape
      results = np.random.random(results_shape)
  
      prefactor = 0.3214
  
      res = _parshift_and_integrate(
          results,
          cjacs,
          prefactor,
          psr_coeffs,
          single_measure=False,
          has_partitioned_shots=True,
          use_broadcasting=True,
      )
  
      assert isinstance(res, tuple)
      assert len(res) == num_shots
      for r in res:
          assert isinstance(r, tuple)
          assert len(r) == num_meas
          assert all(isinstance(_r, jnp.ndarray) for _r in r)
          assert all(_r.shape == meas_shape + par_shape for _r in r)
  
      _results = np.reshape(results, new_results_shape)
      _cjacs = np.stack(cjacs).reshape((multi_term,) + cjac_shape)
      _psr_coeffs = np.stack(psr_coeffs).reshape(
          (multi_term, num_shifts)
      )
      meas_letter = "" if meas_shape == () else "a"
      # Slice away excess results
      _results = _results[:, :, :, :, 1:-1]
      # With broadcasting, the axes of different shifts and splitting times are
      # switched for the results tensor, compared to without broadcasting.
      contraction = f"ms,msNnt{meas_letter},mt...->Nn{meas_letter}..."
      expected = np.einsum(contraction, _psr_coeffs, _results, _cjacs)
      assert np.allclose(np.stack(res), expected * prefactor)
  
imports: import warnings
  import copy
  import pytest
  import numpy
  import pennylane
  from pennylane.gradients.general_shift_rules import eigvals_to_frequencies, generate_shift_rule
  from pennylane.gradients.pulse_gradient import _parshift_and_integrate, _split_evol_ops, _split_evol_tape, stoch_pulse_grad
label_desc: Use image node_id 6 for calling the TestParshiftAndIntegrate obj's underlying member method code with example usage: obj.test_multi_measure_multi_shots_broadcast(num_split_times, num_shifts, par_shape, multi_term, meas_shape) without return types