code: def test_sparse_gradients(
      self,
      optimizer_class,
      init_kwargs={},
      expect_model_sparse_variable_updates=False,
      expect_optimizer_sparse_variable_updates=False,
  ):
      # This test verifies that:
      # - Optimizers use Keras ops everywhere instead of native operators
      #   (e.g. `ops.add()` instead of `+`) where sparse gradients are handled
      # - The used ops handle sparse gradients (`tf.IndexedSlices`)
      # - Optimizers use `self.assign/assign_add/assign_sub` instead of
      #   calling the method on the variable directly. Otherwise, the sparse
      #   updates are densified before being applied.
      # - For some optimizers, a sparse gradient actually results in a sparse
      #   variable update as per `expect_model_sparse_variable_updates` and
      #   `expect_optimizer_sparse_variable_updates`
  
      model_variable = backend.Variable(
          initializer=tf.ones, shape=(5, 10)
      )
      optimizer = optimizer_class(**init_kwargs)
  
      # Mocking "tensorflow.Variable" won't work as it gets substituted with
      # the resource variable class.
      tf_variable_class = model_variable._value.__class__
  
      optimizer_to_patch = (
          optimizer.inner_optimizer
          if isinstance(optimizer, optimizers.LossScaleOptimizer)
          else optimizer
      )
  
      model_sparse_variable_updates = False
      optimizer_sparse_variable_updates = False
  
      def mock_optimizer_assign(variable, value):
          nonlocal model_sparse_variable_updates
          nonlocal optimizer_sparse_variable_updates
          if isinstance(variable, backend.Variable):
              variable = variable._value
          if isinstance(value, tf.IndexedSlices):
              if variable is model_variable._value:
                  model_sparse_variable_updates = True
              elif any(
                  variable is v._value for v in optimizer.variables
              ):
                  optimizer_sparse_variable_updates = True
  
      def mock_variable_assign(variable, value):
          # Make an exception for scalar variables
          if len(variable.shape):
              pytest.fail(
                  "Optimizer is calling `assign`, `assign_add` or "
                  "`assign_sub` directly on a variable. Use "
                  "`self.assign/assign_add/assign_sub(variable, value)` "
                  "instead to support sparse updates."
              )
  
      # patch "_apply_weight_decay" to exclude this special case.
      # patch the optimizer "assign" methods to detect sparse udpates.
      # patch the tf.Variable "assign" methods to detect direct assign calls.
      with mock.patch.object(
          optimizer_to_patch, "_apply_weight_decay", autospec=True
      ), mock.patch.object(
          optimizer_to_patch, "assign", autospec=True
      ) as optimizer_assign, mock.patch.object(
          optimizer_to_patch, "assign_add", autospec=True
      ) as optimizer_assign_add, mock.patch.object(
          optimizer_to_patch, "assign_sub", autospec=True
      ) as optimizer_assign_sub, mock.patch.object(
          tf_variable_class, "assign", autospec=True
      ) as variable_assign, mock.patch.object(
          tf_variable_class, "assign_add", autospec=True
      ) as variable_assign_add, mock.patch.object(
          tf_variable_class, "assign_sub", autospec=True
      ) as variable_assign_sub:
          optimizer_assign.side_effect = mock_optimizer_assign
          optimizer_assign_add.side_effect = mock_optimizer_assign
          optimizer_assign_sub.side_effect = mock_optimizer_assign
          variable_assign.side_effect = mock_variable_assign
          variable_assign_add.side_effect = mock_variable_assign
          variable_assign_sub.side_effect = mock_variable_assign
  
          grad = tf.IndexedSlices(
              values=tf.ones((3, 10)),
              indices=(0, 2, 4),
              dense_shape=(5, 10),
          )
          optimizer.apply_gradients(zip([grad], [model_variable]))
  
      self.assertEqual(
          model_sparse_variable_updates,
          expect_model_sparse_variable_updates,
      )
      self.assertEqual(
          optimizer_sparse_variable_updates,
          expect_optimizer_sparse_variable_updates,
      )
  
file_path: keras/keras/backend/tensorflow/optimizer_sparse_test.py
imports: from unittest import mock
  import pytest
  import tensorflow
  from absl.testing import parameterized
  from keras import backend
  from keras import optimizers
  from keras import testing
label_desc: Use image node_id 1 for calling the OptimizerSparseTest obj's underlying member method code with example usage: obj.test_sparse_gradients(optimizer_class, init_kwargs, expect_model_sparse_variable_updates, expect_optimizer_sparse_variable_updates) without return types