class_docstr: This calculator will only assign < 1 gpu to each job because some job cannot be parallelized
code: def get_resources_per_job(
      self,
      total_num_cpus,
      total_num_gpus,
      num_jobs,
      minimum_cpu_per_job,
      minimum_gpu_per_job,
      wrap_resources_per_job_into_placement_group=False,
      **kwargs,
  ):
      assert (
          0 < minimum_gpu_per_job <= 1
      ), f"{self.__class__.__name__} only supports assigning < 1 gpu to each job"
      cpu_per_job = max(
          minimum_cpu_per_job, int(total_num_cpus // num_jobs)
      )
      gpu_per_job = min(minimum_gpu_per_job, 1)
      num_parallel_jobs = num_jobs
      if cpu_per_job:
          num_parallel_jobs = min(
              num_parallel_jobs, total_num_cpus // cpu_per_job
          )
      if gpu_per_job:
          num_parallel_jobs = min(
              num_parallel_jobs, total_num_gpus // gpu_per_job
          )
      if num_parallel_jobs == 0:
          raise AssertionError(
              "Cannot train model with provided resources! "
              f"(num_cpus, num_gpus)==({total_num_cpus}, {total_num_gpus}) | "
              f"(min_cpus, min_gpus)==({cpu_per_job}, {gpu_per_job})"
          )
      cpu_per_job = int(total_num_cpus // num_parallel_jobs)
      gpu_per_job = min(1, total_num_gpus / num_parallel_jobs)
  
      resources_per_job = dict(cpu=cpu_per_job, gpu=gpu_per_job)
      if wrap_resources_per_job_into_placement_group:
          resources_per_job = (
              self.wrap_resources_per_job_into_placement_group(
                  resources_per_job
              )
          )
      batches = math.ceil(num_jobs / num_parallel_jobs)
  
      resources_info = dict(
          resources_per_job=resources_per_job,
          num_parallel_jobs=num_parallel_jobs,
          batches=batches,
          cpu_per_job=cpu_per_job,
          gpu_per_job=gpu_per_job,
      )
      logger.log(
          10,
          f"Resources info for {self.__class__.__name__}: {resources_info}",
      )
  
      return resources_info
  
imports: import logging
  import math
  from abc import ABC, abstractmethod
  from autogluon.common.utils.resource_utils import ResourceManager
label_desc: Use image node_id 2 for calling the NonParallelGpuResourceCalculator obj's underlying member method code with example usage: obj.get_resources_per_job(total_num_cpus, total_num_gpus, num_jobs, minimum_cpu_per_job, minimum_gpu_per_job, wrap_resources_per_job_into_placement_group) and returns: resources_info