code: def _batch_call(func, ids, *args, N=10, **kwargs):
      # we're running in batch mode, just loop over each item and call the scalar version of the
      # function
      output_ids = np.zeros((len(ids), N), dtype=np.int32)
      output_scores = np.zeros((len(ids), N), dtype=np.float32)
  
      user_items = (
          kwargs.pop("user_items") if "user_items" in kwargs else None
      )
      item_users = (
          kwargs.pop("item_users") if "item_users" in kwargs else None
      )
  
      # pylint: disable=unsubscriptable-object
      for i, idx in enumerate(ids):
          current_kwargs = kwargs
          if user_items is not None:
              current_kwargs = {"user_items": user_items[i], **kwargs}
          elif item_users is not None:
              current_kwargs = {"item_users": item_users[i], **kwargs}
  
          batch_ids, batch_scores = func(
              idx, *args, N=N, **current_kwargs
          )
  
          # pad out to N items if we're returned fewer
          missing_items = N - len(batch_ids)
          if missing_items > 0:
              batch_ids = np.append(
                  batch_ids, np.full(missing_items, -1)
              )
              batch_scores = np.append(
                  batch_scores,
                  np.full(missing_items, -np.finfo(np.float32).max),
              )
  
          output_ids[i] = batch_ids[:N]
          output_scores[i] = batch_scores[:N]
  
      return output_ids, output_scores
  
file_path: implicit/implicit/utils.py
imports: import time
  import warnings
  import numpy
  import scipy.sparse
  import threadpoolctl
label_desc: Use image node_id 5 for calling a global function with example usage: _batch_call(func, ids) and returns: output_ids,  output_scores