text: # functions/add.py
  import torch
  from torch.autograd import Function
  from .._ext import roi_crop
  from cffi import FFI
  ffi = FFI()
  
  class RoICropFunction(Function):
      def forward(self, input1, input2):
          self.input1 = input1
          self.input2 = input2
          self.device_c = ffi.new("int *")
          output = torch.zeros(input2.size()[0], input1.size()[1], input2.size()[1], input2.size()[2])
          if input1.is_cuda:
              self.device = torch.cuda.current_device()
          else:
              self.device = -1
          self.device_c[0] = self.device
          if not input1.is_cuda:
              roi_crop.BilinearSamplerBHWD_updateOutput(input1, input2, output)
          else:
              output = output.cuda(self.device)
              roi_crop.BilinearSamplerBHWD_updateOutput_cuda(input1, input2, output)
          return output
  
      def backward(self, grad_output):
          grad_input1 = torch.zeros(self.input1.size())
          grad_input2 = torch.zeros(self.input2.size())
          if not grad_output.is_cuda:
              roi_crop.BilinearSamplerBHWD_updateGradInput(self.input1, self.input2, grad_input1, grad_input2, grad_output)
          else:
              grad_input1 = grad_input1.cuda(self.device)
              grad_input2 = grad_input2.cuda(self.device)
              roi_crop.BilinearSamplerBHWD_updateGradInput_cuda(self.input1, self.input2, grad_input1, grad_input2, grad_output)
          return grad_input1, grad_input2
  