code: def send_message(
      self,
      message: PipeMessage,
      sync: bool = False,
      skip_header: bool = False,
  ) -> None:
      tensors = message.tensors
      message.tensors = tuple()
      torch.cuda.current_stream().synchronize()
      if not skip_header:
          message.tensor_shapes = [t.size() for t in tensors]
          message.tensor_dtypes = [t.dtype for t in tensors]
          torch.distributed.send(
              pyobject_to_tensor(message, MESSAGE_TENSOR_SIZE).cuda(),
              message.dest,
              tag=message.queue_name,
              group=get_pipeline_parallel_group(),
          )
      for index, t in enumerate(tensors):
          if t.device.type == "cpu":
              t = t.cuda()
          torch.distributed.send(
              t.contiguous(),
              message.dest,
              tag=message.tag + index,
              group=get_pipeline_parallel_group(),
          )
  
imports: from abc import ABC
  from dataclasses import dataclass
  from queue import Empty
  from queue import Queue
  from typing import Dict, List, Optional
  import torch
  from fairscale.internal.object import pyobject_to_tensor, tensor_to_pyobject
  from fairscale.nn.model_parallel import get_pipeline_parallel_group
  from .types import MESSAGE_GENERATION_START, InputDevice, PipeMessage, Tensors
label_desc: Use image node_id 1 for calling the SendRecvTransport obj's underlying member method code with example usage: obj.send_message(message, sync, skip_header) without return types