class_docstr: A two-stage pipeline, which will run all stages in parallel.
  
  A simple usage:
  ```
      pipeline = Pipeline([
          ("preprocess", preprocess, {}),
          ("inference", model, {}),
      ])
      outputs = pipeline.run(inputs)
  ```
class_docstr_tok: ["A","two-stage","pipeline",",","which","will","run","all","stages","in","parallel",".","A","simple","usage",":","``","`","pipeline","=","Pipeline","(","[","(","``","preprocess","''",",","preprocess",",","{","}",")",",","(","``","inference","''",",","model",",","{","}",")",",","]",")","outputs","=","pipeline.run","(","inputs",")","``","`"]
docstr: Create a pipeline with given stages.
  
  For example,
  ```
      pipeline = Pipeline([
          ("preprocess", preprocess, {"cores_per_worker": 4, 'worker_num': 1}),
          ("inference", model, {"cores_per_worker": 8, 'worker_num': 1}),
      ])
  ```
  will create a pipeline which has stage "preprocess" and "inference",
  and the "preprocess" stage will call `preprocess(input)` with 4 CPU cores
  for openmp worload, while the "inference" stage will call `model(input)`
  with 8 CPU cores for openmp workload.
  
  :param stages: A list of configurations for each stage, each stage should consist of
      a 'name'(str), a 'function'(Callable), and a 'config'(dict).
docstr_tok: ["Create","a","pipeline","with","given","stages",".","For","example",",","``","`","pipeline","=","Pipeline","(","[","(","``","preprocess","''",",","preprocess",",","{","``","cores_per_worker","''",":","4",",","'worker_num","'",":","1","}",")",",","(","``","inference","''",",","model",",","{","``","cores_per_worker","''",":","8",",","'worker_num","'",":","1","}",")",",","]",")","``","`","will","create","a","pipeline","which","has","stage","``","preprocess","''","and","``","inference","''",",","and","the","``","preprocess","''","stage","will","call","`","preprocess","(","input",")","`","with","4","CPU","cores","for","openmp","worload",",","while","the","``","inference","''","stage","will","call","`","model","(","input",")","`","with","8","CPU","cores","for","openmp","workload",".",":","param","stages",":","A","list","of","configurations","for","each","stage",",","each","stage","should","consist","of","a","'name","'","(","str",")",",","a","'function","'","(","Callable",")",",","and","a","'config","'","(","dict",")","."]
code: def __init__(self, stages: List[Tuple]):
      """
      Create a pipeline with given stages.
  
      For example,
      ```
          pipeline = Pipeline([
              ("preprocess", preprocess, {"cores_per_worker": 4, 'worker_num': 1}),
              ("inference", model, {"cores_per_worker": 8, 'worker_num': 1}),
          ])
      ```
      will create a pipeline which has stage "preprocess" and "inference",
      and the "preprocess" stage will call `preprocess(input)` with 4 CPU cores
      for openmp worload, while the "inference" stage will call `model(input)`
      with 8 CPU cores for openmp workload.
  
      :param stages: A list of configurations for each stage, each stage should consist of
          a 'name'(str), a 'function'(Callable), and a 'config'(dict).
      """
      queues = [mp.Queue() for _ in range(len(stages) + 1)]
      self.send_ = queues[0]
      self.recv_ = queues[-1]
      self.cores = schedule_workers(1)[0]
      self.ps = list(
          itertools.chain(
              self._launch_stage(stage, queues[i], queues[i + 1])
              for i, stage in enumerate(stages)
          )
      )
  
file_path: BigDL/python/nano/src/bigdl/nano/pytorch/inference/pipeline.py
imports: import itertools
  import multiprocessing
  import warnings
  from typing import List, Tuple, Callable
  from bigdl.nano.utils.common import EnvContext
  from bigdl.nano.utils.common import invalidInputError
  from bigdl.nano.utils.common import schedule_workers
  from torch import nn
label_desc: Use image node_id 1 to create a new Pipeline object  with example: obj = Pipeline(stages)