text: """
  SOLO for non-commercial purposes
  
  Copyright (c) 2019 the authors
  All rights reserved.
  
  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions are met:
  
  * Redistributions of source code must retain the above copyright notice, this
    list of conditions and the following disclaimer.
  
  * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the following disclaimer in the documentation
    and/or other materials provided with the distribution.
  
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  
  Adapted from: https://github.com/WXinlong/SOLO/blob/master/mmdet/ops/dcn/deform_conv.py
  """
  from torch import nn
  
  from detectron2.layers import DeformConv
  from detectron2.layers.deform_conv import deform_conv
  from torch.nn.modules.utils import _pair
  
  
  class DeformConvPack(DeformConv):
      """A Deformable Conv Encapsulation that acts as normal Conv layers.
      Args:
          in_channels (int): Same as nn.Conv2d.
          out_channels (int): Same as nn.Conv2d.
          kernel_size (int or tuple[int]): Same as nn.Conv2d.
          stride (int or tuple[int]): Same as nn.Conv2d.
          padding (int or tuple[int]): Same as nn.Conv2d.
          dilation (int or tuple[int]): Same as nn.Conv2d.
          groups (int): Same as nn.Conv2d.
          bias (bool or str): If specified as `auto`, it will be decided by the
              norm_cfg. Bias will be set as True if norm_cfg is None, otherwise
              False.
      """
  
      _version = 2
  
      def __init__(self, *args, **kwargs):
          super(DeformConvPack, self).__init__(*args, **kwargs)
  
          self.conv_offset = nn.Conv2d(
              self.in_channels,
              self.deformable_groups * 2 * self.kernel_size[0] *
              self.kernel_size[1],
              kernel_size=self.kernel_size,
              stride=_pair(self.stride),
              padding=_pair(self.padding),
              bias=True)
          self.init_offset()
  
      def init_offset(self):
          self.conv_offset.weight.data.zero_()
          self.conv_offset.bias.data.zero_()
  
      def forward(self, x):
          offset = self.conv_offset(x)
          return deform_conv(x, offset, self.weight, self.stride, self.padding,
                             self.dilation, self.groups, self.deformable_groups)
  
      def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict,
                                missing_keys, unexpected_keys, error_msgs):
          version = local_metadata.get('version', None)
  
          if version is None or version < 2:
              # the key is different in early versions
              # In version < 2, DeformConvPack loads previous benchmark models.
              if (prefix + 'conv_offset.weight' not in state_dict
                      and prefix[:-1] + '_offset.weight' in state_dict):
                  state_dict[prefix + 'conv_offset.weight'] = state_dict.pop(
                      prefix[:-1] + '_offset.weight')
              if (prefix + 'conv_offset.bias' not in state_dict
                      and prefix[:-1] + '_offset.bias' in state_dict):
                  state_dict[prefix +
                             'conv_offset.bias'] = state_dict.pop(prefix[:-1] +
                                                                  '_offset.bias')
  
  
          super()._load_from_state_dict(state_dict, prefix, local_metadata,
                                        strict, missing_keys, unexpected_keys,
                                        error_msgs)