code: def FanInProd() -> InternalLayerMasked:
      """Fan-in product.
  
      This layer takes a number of inputs (e.g. produced by
      :obj:`~neural_tangents.stax.FanOut`) and elementwise-multiplies the inputs to
      produce a single output.
  
      Returns:
        `(init_fn, apply_fn, kernel_fn)`.
      """
      init_fn, _ = ostax.FanInSum
  
      def apply_fn(params, inputs, **kwargs):
          return functools.reduce(jnp.multiply, inputs)
  
      def kernel_fn(ks: Kernels, **kwargs) -> Kernel:
          ks, is_reversed = _preprocess_kernels_for_fan_in(ks)
          if not all(
              [
                  k.shape1 == ks[0].shape1 and k.shape2 == ks[0].shape2
                  for k in ks[1:]
              ]
          ):
              raise ValueError(
                  "All shapes should be equal in `FanInProd`."
              )
  
          is_gaussian = len(ks) == 1 and ks[0].is_gaussian
  
          def _mats_prod(nngps, ntks):
              if None in ntks:
                  return functools.reduce(jnp.multiply, nngps), None
  
              nngp_prod, ntk_prod = 1.0, 0.0
              for nngp, ntk in zip(nngps, ntks):
                  ntk_prod = ntk_prod * nngp + nngp_prod * ntk
                  nngp_prod *= nngp
              return nngp_prod, ntk_prod
  
          cov1s = [k.cov1 for k in ks]
          cov2s = [k.cov2 for k in ks]
          nngps = [k.nngp for k in ks]
          ntks = [k.ntk for k in ks]
  
          cov1 = functools.reduce(jnp.multiply, cov1s)
          cov2 = (
              None
              if None in cov2s
              else functools.reduce(jnp.multiply, cov2s)
          )
          nngp, ntk = _mats_prod(nngps, ntks)
  
          return Kernel(
              cov1=cov1,
              cov2=cov2,
              nngp=nngp,
              ntk=ntk,
              x1_is_x2=ks[0].x1_is_x2,
              is_gaussian=is_gaussian,
              is_reversed=is_reversed,
              is_input=ks[0].is_input,
              diagonal_batch=ks[0].diagonal_batch,
              diagonal_spatial=ks[0].diagonal_spatial,
              shape1=None,
              shape2=None,
              batch_axis=ks[0].batch_axis,
              channel_axis=ks[0].channel_axis,
              mask1=None,
              mask2=None,
          )  # pytype:disable=wrong-keyword-args
  
      def mask_fn(mask, input_shape):
          return _sum_masks(mask)
  
      return init_fn, apply_fn, kernel_fn, mask_fn
  
imports: import functools
  from typing import Callable, Iterable, Optional, Sequence
  import warnings
  from jax import numpy
  import jax.example_libraries.stax
  from ..utils.kernel import Kernel
  from ..utils.typing import InternalLayer
  from ..utils.typing import InternalLayerMasked
  from ..utils.typing import Kernels
  from .requirements import layer
  from .requirements import supports_masking
label_desc: Use image node_id 3 for calling a global function with example usage: FanInProd() and returns: init_fn,  apply_fn,  kernel_fn,  mask_fn, functools, Kernel, _sum_masks, nngp_prod,  ntk_prod, functools,  None