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.

PipelineReceive.py 2.4 kB

5 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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 PipelineReceiveOp(Op):
  7. def __init__(self, source, comm, stream=None, ctx=None):
  8. assert ctx, "PipelineReceiveOp must be initialized with the ctx argument!"
  9. super().__init__(PipelineReceiveOp, [], ctx)
  10. self.const_attr = source
  11. self.comm = comm
  12. self.comm_stream = stream
  13. self.desc = self.name + \
  14. '(%s receive from %s)' % (str(self.ctx.device_id), str(source))
  15. self.shape = None
  16. self.shape_is_received = False
  17. def compute(self, input_vals, output_val, stream_handle=None):
  18. assert not self.on_cpu, "PipelineReceiveOp only support P2P communication between gpus"
  19. assert self.comm_stream, "communicate stream should not be None"
  20. if self.event == None:
  21. self.event = create_event_handle(self.ctx)
  22. self.comm.dlarrayRecv(output_val,
  23. ncclDataType_t.ncclFloat32,
  24. self.const_attr,
  25. self.comm_stream)
  26. self.event.record(self.comm_stream)
  27. def gradient(self, output_grad):
  28. return []
  29. def infer_shape(self, input_shapes):
  30. if not self.shape_is_received:
  31. # receive
  32. shape_arr = ndarray.array([0, 0, 0], self.ctx)
  33. self.comm.dlarrayRecv(shape_arr,
  34. ncclDataType_t.ncclFloat32,
  35. self.const_attr,
  36. self.comm_stream)
  37. # remove padding and save
  38. shape_arr = [int(x) for x in list(shape_arr.asnumpy()) if x != 0]
  39. self.shape = tuple(shape_arr)
  40. self.shape_is_received = True
  41. return self.shape
  42. def forward_hook(self, config):
  43. self.on_gpu = ndarray.is_gpu_ctx(self.ctx)
  44. self.on_cpu = not self.on_gpu
  45. def pipeline_receive_op(source, comm, stream=None, ctx=None):
  46. """Make a new instance of PipelineReceiveOp and call the instance.
  47. Parameters:
  48. ----
  49. source : scalar value
  50. The gpu index for source.
  51. Returns:
  52. ----
  53. A new Node instance created by Op.
  54. """
  55. return PipelineReceiveOp(source, comm, stream=stream, ctx=ctx)