class_docstr: A thread-safe data structure used to respond to resource request,
     maintaining the available computation resources in each worker.
  
  Attributes:
      worker_hostname (dict): A dict to record worker hostname.
      worker_vacant_jobs (dict): Record which vacant jobs does each
                                 worker has.
      worker_used_jobs (dict): Record which used jobs does each
                                 worker has.
      master_ip (str): IP address of the master node.
class_docstr_tok: ["A","thread-safe","data","structure","used","to","respond","to","resource","request",",","maintaining","the","available","computation","resources","in","each","worker",".","Attributes",":","worker_hostname","(","dict",")",":","A","dict","to","record","worker","hostname",".","worker_vacant_jobs","(","dict",")",":","Record","which","vacant","jobs","does","each","worker","has",".","worker_used_jobs","(","dict",")",":","Record","which","used","jobs","does","each","worker","has",".","master_ip","(","str",")",":","IP","address","of","the","master","node","."]
docstr: Allocate n_cpu CPUs and n_gpu GPUS from the worker.
  Args:
      worker_address (str): The worker which allocates CPU and GPU resources.
      n_cpu (int): allocate n_cpu CPUs
      n_gpu (int): allocate n_gpu GPUs
  Returns:
      allocated_cpu (``AllocateCpu``): The allocation information of CPU
      allocated_gpu (``AllocateGpu``): The allocation information of GPU
docstr_tok: ["Allocate","n_cpu","CPUs","and","n_gpu","GPUS","from","the","worker",".","Args",":","worker_address","(","str",")",":","The","worker","which","allocates","CPU","and","GPU","resources",".","n_cpu","(","int",")",":","allocate","n_cpu","CPUs","n_gpu","(","int",")",":","allocate","n_gpu","GPUs","Returns",":","allocated_cpu","(","``","AllocateCpu","``",")",":","The","allocation","information","of","CPU","allocated_gpu","(","``","AllocateGpu","``",")",":","The","allocation","information","of","GPU"]
code: def allocate(self, worker_address, n_cpu, n_gpu):
      """Allocate n_cpu CPUs and n_gpu GPUS from the worker.
      Args:
          worker_address (str): The worker which allocates CPU and GPU resources.
          n_cpu (int): allocate n_cpu CPUs
          n_gpu (int): allocate n_gpu GPUs
      Returns:
          allocated_cpu (``AllocateCpu``): The allocation information of CPU
          allocated_gpu (``AllocateGpu``): The allocation information of GPU
      """
      allocated_cpu = AllocatedCpu(worker_address, 0)
      allocated_gpu = AllocatedGpu(worker_address, "")
      if n_cpu > 0:
          allocated_cpu = self.cpu_resource.allocate(
              worker_address, n_cpu
          )
      if n_gpu > 0:
          allocated_gpu = self.gpu_resource.allocate(
              worker_address, n_gpu
          )
      return allocated_cpu, allocated_gpu
  
imports: import threading
  import random
  from collections import defaultdict
  from collections import namedtuple
  from parl.utils import logger
  from parl.remote import remote_constants
  from parl.remote.cpu_resource import CpuResource
  from parl.remote.gpu_resource import GpuResource
  from parl.remote.message import AllocatedCpu
  from parl.remote.message import AllocatedGpu
label_desc: Use image node_id 10 for calling the WorkerManager obj's underlying member method code with example usage: obj.allocate(worker_address, n_cpu, n_gpu) and returns: allocated_cpu,  allocated_gpu