code: def find_best_reset_points(
      activation_sizes: List[int], nb_checkpoints: int
  ) -> Tuple[int, List[int]]:
      """
      Assuming constant memory requirement from the model, its gradients
      and the associated optimizer state (realistic for small models
      or models that are sharded enough to be considered small), this
      function computes the ideal placement for the checkpoints by
      returning the limits at which we should reset memory.
      """
      n = len(activation_sizes)
  
      @lru_cache(maxsize=None)
      def visit(pos: int, remaining: int) -> Tuple[int, List[int]]:
          if pos == n:
              return 0, []
          if remaining == 0:
              return sum(activation_sizes[pos:]), []
  
          min_val = float("inf")
          allocation = []
  
          current_chunk = 0
          for curr_pos in range(pos, n):
              current_chunk += activation_sizes[curr_pos]
              sub_result, sub_alloc = visit(curr_pos + 1, remaining - 1)
              result = max(current_chunk, sub_result)
              if result < min_val:
                  min_val = result
                  allocation = list(sub_alloc)
                  allocation.append(curr_pos + 1)
  
          return min_val, allocation
  
      best_score, best_allocation = visit(0, nb_checkpoints)
      return best_score, best_allocation[::-1]
  
imports: from contextlib import contextmanager
  from dataclasses import dataclass
  from enum import auto, Enum
  from functools import lru_cache
  from typing import Dict, List, NamedTuple, Tuple, Union
  import numpy
  import torch
  import torch.nn
  from fairscale.nn import FullyShardedDataParallel
  from vissl.utils.visualize import matplotlib_figure_to_image
label_desc: Use image node_id 1 for calling a global function with example usage: find_best_reset_points(activation_sizes, nb_checkpoints) and returns: best_score,  best_allocation, min_val,  allocation, int,  list, sum,  list