code: def test_net_comparison(self):
      # (a + b) * (c + d) == a * c + a * d + b * c + b * d
      net1 = core.Net("net1")
      a, b, c, d = net1.AddExternalInputs("a", "b", "c", "d")
      a_b = net1.Sum([a, b], "a+b")
      c_d = net1.Sum([c, d], "c+d")
      x = net1.Mul([a_b, c_d], "x")
  
      net2 = core.Net("net2")
      ac = net2.Mul([a, c], "ac")
      ad = net2.Mul([a, d], "ad")
      bc = net2.Mul([b, c], "bc")
      bd = net2.Mul([b, d], "bd")
      y = net2.Sum([ac, ad, bc, bd], "y")
  
      input_values = {
          blob: np.array([i], dtype=np.float32)
          for i, blob in enumerate([a, b, c, d])
      }
  
      NetGradientChecker.CompareNets(
          [net1, net2],
          [[x], [y]],
          [0],
          inputs_with_grads=[a, b, c, d],
          input_values=input_values,
      )
  
imports: import numpy
  from caffe2.python import brew, core, device_checker, gradient_checker, model_helper, test_util, workspace
  from caffe2.python.gradient_checker import NetGradientChecker
  from caffe2.python.net_builder import ops, NetBuilder
  from caffe2.proto import caffe2_pb2
  import unittest
  from typing import Optional
label_desc: Use image node_id 2 for calling the TestNetGradientChecker obj's underlying member method code with example usage: obj.test_net_comparison() without return types