You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

PipelineSend.py 2.6 kB

5 years ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. from __future__ import absolute_import
  2. from .Node import Op
  3. from .. import ndarray
  4. from ..communicator.mpi_nccl_comm import ncclDataType_t, ncclRedOp_t
  5. from ..stream import create_event_handle, create_stream_handle
  6. class PipelineSendOp(Op):
  7. def __init__(self, node_A, destination, comm, stream=None, ctx=None):
  8. super().__init__(PipelineSendOp, [node_A], ctx)
  9. self.const_attr = destination
  10. self.comm = comm
  11. self.comm_stream = stream
  12. self.desc = self.name + \
  13. '(send node %s to rank %s)' % (node_A.name, str(destination))
  14. self.shape = None
  15. self.shape_is_sent = False
  16. def compute(self, input_vals, output_val, stream_handle=None):
  17. assert not self.on_cpu, "PipelineSendOp only support P2P communication between gpus"
  18. # we dont need sync and event for send
  19. self.comm.dlarraySend(input_vals[0],
  20. ncclDataType_t.ncclFloat32,
  21. self.const_attr,
  22. self.comm_stream)
  23. def gradient(self, output_grad):
  24. return []
  25. def infer_shape(self, input_shapes):
  26. shape = input_shapes[0]
  27. self.shape = shape
  28. if not self.shape_is_sent:
  29. self.shape_is_sent = True
  30. # pad shape so that len=3
  31. if len(shape) < 3:
  32. shape = [0] * (3 - len(shape)) + list(shape)
  33. # construct and send
  34. payload = ndarray.array(shape, self.ctx)
  35. self.comm.dlarraySend(payload,
  36. ncclDataType_t.ncclFloat32,
  37. self.const_attr,
  38. self.comm_stream)
  39. return shape
  40. def forward_hook(self, config):
  41. self.ctx = self.inputs[0].ctx
  42. self.on_gpu = ndarray.is_gpu_ctx(self.ctx)
  43. self.on_cpu = not self.on_gpu
  44. # add event to the previous node, ensure that the send is
  45. # blocked until previous computations are finished
  46. if self.on_gpu and self.inputs[0].event is None:
  47. self.inputs[0].event = create_event_handle(self.ctx)
  48. def pipeline_send_op(node, destination, comm, stream=None, ctx=None):
  49. """Make a new instance of PipelineSendOp and call the instance.
  50. Parameters:
  51. ----
  52. node : Node
  53. The Node to be send.
  54. destination : scalar value
  55. The gpu index for destination.
  56. Returns:
  57. ----
  58. A new Node instance created by Op.
  59. """
  60. return PipelineSendOp(node, destination, comm, stream=stream, ctx=ctx)