Implements data parallelism at the module level. This container parallelizes the application of the given module by splitting the input across the specified devices by chunking in the batch dimension. In the forward pass, the module is replicated on each device, and each replica
| 105 | |
| 106 | |
| 107 | class MyDataParallel(Module): |
| 108 | """ |
| 109 | Implements data parallelism at the module level. |
| 110 | This container parallelizes the application of the given module by |
| 111 | splitting the input across the specified devices by chunking in the batch |
| 112 | dimension. In the forward pass, the module is replicated on each device, |
| 113 | and each replica handles a portion of the input. During the backwards |
| 114 | pass, gradients from each replica are summed into the original module. |
| 115 | The batch size should be larger than the number of GPUs used. |
| 116 | See also: :ref:`cuda-nn-dataparallel-instead` |
| 117 | Arbitrary positional and keyword inputs are allowed to be passed into |
| 118 | DataParallel EXCEPT Tensors. All tensors will be scattered on dim |
| 119 | specified (default 0). Primitive types will be broadcasted, but all |
| 120 | other types will be a shallow copy and can be corrupted if written to in |
| 121 | the model's forward pass. |
| 122 | .. warning:: |
| 123 | Forward and backward hooks defined on :attr:`module` and its submodules |
| 124 | will be invoked ``len(device_ids)`` times, each with inputs located on |
| 125 | a particular device. Particularly, the hooks are only guaranteed to be |
| 126 | executed in correct order with respect to operations on corresponding |
| 127 | devices. For example, it is not guaranteed that hooks set via |
| 128 | :meth:`~torch.nn.Module.register_forward_pre_hook` be executed before |
| 129 | `all` ``len(device_ids)`` :meth:`~torch.nn.Module.forward` calls, but |
| 130 | that each such hook be executed before the corresponding |
| 131 | :meth:`~torch.nn.Module.forward` call of that device. |
| 132 | .. warning:: |
| 133 | When :attr:`module` returns a scalar (i.e., 0-dimensional tensor) in |
| 134 | :func:`forward`, this wrapper will return a vector of length equal to |
| 135 | number of devices used in data parallelism, containing the result from |
| 136 | each device. |
| 137 | .. note:: |
| 138 | There is a subtlety in using the |
| 139 | ``pack sequence -> recurrent network -> unpack sequence`` pattern in a |
| 140 | :class:`~torch.nn.Module` wrapped in :class:`~torch.nn.DataParallel`. |
| 141 | See :ref:`pack-rnn-unpack-with-data-parallelism` section in FAQ for |
| 142 | details. |
| 143 | Args: |
| 144 | module: module to be parallelized |
| 145 | device_ids: CUDA devices (default: all devices) |
| 146 | output_device: device location of output (default: device_ids[0]) |
| 147 | Attributes: |
| 148 | module (Module): the module to be parallelized |
| 149 | Example:: |
| 150 | >>> net = torch.nn.DataParallel(model, device_ids=[0, 1, 2]) |
| 151 | >>> output = net(input_var) |
| 152 | """ |
| 153 | |
| 154 | # TODO: update notes/cuda.rst when this class handles 8+ GPUs well |
| 155 | |
| 156 | def __init__(self, module, device_ids=None, output_device=None, dim=0, gather=True): |
| 157 | super(MyDataParallel, self).__init__() |
| 158 | |
| 159 | if not torch.cuda.is_available(): |
| 160 | self.module = module |
| 161 | self.device_ids = [] |
| 162 | return |
| 163 | |
| 164 | if device_ids is None: |
nothing calls this directly
no outgoing calls
no test coverage detected