code: def create_mask(
      input_dim,
      context_dim,
      hidden_dims,
      permutation,
      output_dim_multiplier,
  ):
      """
      Creates MADE masks for a conditional distribution
  
      :param input_dim: the dimensionality of the input variable
      :type input_dim: int
      :param context_dim: the dimensionality of the variable that is conditioned on (for conditional densities)
      :type context_dim: int
      :param hidden_dims: the dimensionality of the hidden layers(s)
      :type hidden_dims: list[int]
      :param permutation: the order of the input variables
      :type permutation: torch.LongTensor
      :param output_dim_multiplier: tiles the output (e.g. for when a separate mean and scale parameter are desired)
      :type output_dim_multiplier: int
      """
      # Create mask indices for input, hidden layers, and final layer
      # We use 0 to refer to the elements of the variable being conditioned on,
      # and range(1:(D_latent+1)) for the input variable
      var_index = torch.empty(
          permutation.shape, dtype=torch.get_default_dtype()
      )
      var_index[permutation] = torch.arange(
          input_dim, dtype=torch.get_default_dtype()
      )
  
      # Create the indices that are assigned to the neurons
      input_indices = torch.cat(
          (torch.zeros(context_dim), 1 + var_index)
      )
  
      # For conditional MADE, introduce a 0 index that all the conditioned variables are connected to
      # as per Paige and Wood (2016) (see below)
      if context_dim > 0:
          hidden_indices = [
              sample_mask_indices(input_dim, h) - 1 for h in hidden_dims
          ]
      else:
          hidden_indices = [
              sample_mask_indices(input_dim - 1, h) for h in hidden_dims
          ]
  
      output_indices = (var_index + 1).repeat(output_dim_multiplier)
  
      # Create mask from input to output for the skips connections
      mask_skip = (
          output_indices.unsqueeze(-1) > input_indices.unsqueeze(0)
      ).type_as(var_index)
  
      # Create mask from input to first hidden layer, and between subsequent hidden layers
      masks = [
          (
              hidden_indices[0].unsqueeze(-1)
              >= input_indices.unsqueeze(0)
          ).type_as(var_index)
      ]
      for i in range(1, len(hidden_dims)):
          masks.append(
              (
                  hidden_indices[i].unsqueeze(-1)
                  >= hidden_indices[i - 1].unsqueeze(0)
              ).type_as(var_index)
          )
  
      # Create mask from last hidden layer to output layer
      masks.append(
          (
              output_indices.unsqueeze(-1)
              > hidden_indices[-1].unsqueeze(0)
          ).type_as(var_index)
      )
  
      return masks, mask_skip
  
imports: import warnings
  import torch
  import torch.nn
  from torch.nn import functional
label_desc: Use image node_id 2 for calling a global function with example usage: create_mask(input_dim, context_dim, hidden_dims, permutation, output_dim_multiplier) and returns: masks,  mask_skip