code: def _vector_eval(self, f, *args):
      self._queue = []
      self._vectorized = True
      self._semaphore = multiprocessing.Semaphore(0)
      self._processed_semaphore = multiprocessing.Semaphore(0)
  
      # make sure correct evaluations lead to counter increments
      def wrap(*args):
          result = f(*args)
          # signal mgr to add next future
          self.semaphore.release()
          return result
  
      # create list of futures
      futures = []
      for ar in zip(*args):
          futures.append(parallel.Future(wrap, *ar))
          try:
              self.semaphore.acquire()
          except functions.MaximumEvaluationsException:
              if not len(self.queue):
                  # FIXME: some threads may be running atm
                  raise
              break
  
      # process queue
      self.flush_queue()
  
      # notify all waiting futures
      for _ in range(len(self.queue)):
          self.processed_semaphore.release()
  
      # gather results
      results = [f() for f in futures]
      for f in futures:
          f.join()
      return results
  
imports: from __future__ import print_function
  import json
  import sys
  import socket
  import itertools
  from .None import functions
  from .None import parallel
  import math
  import multiprocessing
  import threading
label_desc: Use image node_id 8 for calling the EvalManager obj's underlying member method code with example usage: obj._vector_eval(f) and returns: results, result