code: def cumprod_backward(x, dy, axis, exclusive, reverse, **kw):
      zero_mask = np.where(x == 0, 1, 0)
  
      # Create masks for following calculation
      # [1, ... , 1, 0, 0, ... , 0]
      before_first_zero_mask = np.where(
          cumsum(zero_mask, axis, False, reverse) == 0, 1, 0
      )
      # [0, ... , 0, 0, 1, ... , 1]
      after_first_zero_mask = np.where(
          cumsum(zero_mask, axis, True, reverse) == 0, 0, 1
      )
      # [0, ... , 0, 1, 0, ... , 0]
      first_zero_mask = np.where(
          before_first_zero_mask + after_first_zero_mask == 0, 1, 0
      )
  
      masked_x = np.where(first_zero_mask == 1, 1, x)
  
      # Check if masks are correctly generated.
      assert np.all(
          first_zero_mask
          + before_first_zero_mask
          + after_first_zero_mask
          == 1
      )
      assert np.all(masked_x - x == first_zero_mask)
      assert np.all(x * first_zero_mask == 0)
  
      normal_cumprod = cumprod(x, axis, exclusive, reverse)
      masked_cumprod = cumprod(masked_x, axis, exclusive, reverse)
  
      cumprod_dy = normal_cumprod * dy
      masked_cumprod_dy = masked_cumprod * dy
  
      reversed_cumprod_dy = cumsum(
          cumprod_dy, axis, exclusive, not reverse
      )
      reversed_masked_cumprod_dy = cumsum(
          masked_cumprod_dy, axis, exclusive, not reverse
      )
  
      # Calculate dx
      full_masked_x = np.where(x == 0, 1, x)  # Avoid generating `nan`
      dx_before_zero_pos = (
          reversed_cumprod_dy / full_masked_x * before_first_zero_mask
      )
      dx_zero_pos = reversed_masked_cumprod_dy * first_zero_mask
      dx = dx_before_zero_pos + dx_zero_pos
      return dx.flatten()
  
imports: from __future__ import division
  from six.moves import range
  import itertools
  import numpy
label_desc: Use image node_id 24 for calling a global function with example usage: cumprod_backward(x, dy, axis, exclusive, reverse) and returns: dx