code: def mask_nodes_by_property(
      property_values, part_ratios, random_seed=None
  ):
      """Provide the split masks for a node split with distributional shift based on a given
      node property, as proposed in `Evaluating Robustness and Uncertainty of Graph Models
      Under Structural Distributional Shifts <https://arxiv.org/abs/2302.13875>`__
  
      It considers the in-distribution (ID) and out-of-distribution (OOD) subsets of nodes.
      The ID subset includes training, validation and testing parts, while the OOD subset
      includes validation and testing parts. It sorts the nodes in the ascending order of
      their property values, splits them into 5 non-intersecting parts, and creates 5
      associated node mask arrays:
          - 3 for the ID nodes: ``'in_train_mask'``, ``'in_valid_mask'``, ``'in_test_mask'``,
          - and 2 for the OOD nodes: ``'out_valid_mask'``, ``'out_test_mask'``.
  
      Parameters
      ----------
      property_values : numpy ndarray
          The node property (float) values by which the dataset will be split.
          The length of the array must be equal to the number of nodes in graph.
      part_ratios : list
          A list of 5 ratios for training, ID validation, ID test,
          OOD validation, OOD testing parts. The values in the list must sum to one.
      random_seed : int, optional
          Random seed to fix for the initial permutation of nodes. It is
          used to create a random order for the nodes that have the same
          property values or belong to the ID subset. (default: None)
  
      Returns
      ----------
      split_masks : dict
          A python dict storing the mask names as keys and the corresponding
          node mask arrays as values.
  
      Examples
      --------
      >>> num_nodes = 1000
      >>> property_values = np.random.uniform(size=num_nodes)
      >>> part_ratios = [0.3, 0.1, 0.1, 0.3, 0.2]
      >>> split_masks = dgl.data.utils.mask_nodes_by_property(property_values, part_ratios)
      >>> print('in_valid_mask' in split_masks)
      True
      """
  
      num_nodes = len(property_values)
      part_sizes = np.round(num_nodes * np.array(part_ratios)).astype(
          int
      )
      part_sizes[-1] -= np.sum(part_sizes) - num_nodes
  
      generator = np.random.RandomState(random_seed)
      permutation = generator.permutation(num_nodes)
  
      node_indices = np.arange(num_nodes)[permutation]
      property_values = property_values[permutation]
      in_distribution_size = np.sum(part_sizes[:3])
  
      node_indices_ordered = node_indices[np.argsort(property_values)]
      node_indices_ordered[
          :in_distribution_size
      ] = generator.permutation(
          node_indices_ordered[:in_distribution_size]
      )
  
      sections = np.cumsum(part_sizes)
      node_split = np.split(node_indices_ordered, sections)[:-1]
      mask_names = [
          "in_train_mask",
          "in_valid_mask",
          "in_test_mask",
          "out_valid_mask",
          "out_test_mask",
      ]
      split_masks = {}
  
      for mask_name, node_indices in zip(mask_names, node_split):
          split_mask = idx2mask(node_indices, num_nodes)
          split_masks[mask_name] = generate_mask_tensor(split_mask)
  
      return split_masks
  
imports: from __future__ import absolute_import
  import errno
  import hashlib
  import os
  import pickle
  import sys
  import warnings
  import networkx.algorithms
  import numpy
  import requests
  from tqdm import tqdm
  from ..None import backend
  from .graph_serialize import load_graphs, load_labels, save_graphs
  from .tensor_serialize import load_tensors, save_tensors
label_desc: Use image node_id 17 for calling a global function with example usage: mask_nodes_by_property(property_values, part_ratios, random_seed) and returns: split_masks