You could have a look at the following.

  
      github.com
  
  
    sniklaus/pytorch-spynet/blob/master/run.py#L135 101

			def forward(self, tensorInput, tensorFlow):
				if hasattr(self, 'tensorGrid') == False or self.tensorGrid.size(0) != tensorFlow.size(0) or self.tensorGrid.size(2) != tensorFlow.size(2) or self.tensorGrid.size(3) != tensorFlow.size(3):
					torchHorizontal = torch.linspace(-1.0, 1.0, tensorFlow.size(3)).view(1, 1, 1, tensorFlow.size(3)).expand(tensorFlow.size(0), 1, tensorFlow.size(2), tensorFlow.size(3))
					torchVertical = torch.linspace(-1.0, 1.0, tensorFlow.size(2)).view(1, 1, tensorFlow.size(2), 1).expand(tensorFlow.size(0), 1, tensorFlow.size(2), tensorFlow.size(3))


					self.tensorGrid = torch.cat([ torchHorizontal, torchVertical ], 1).cuda()
				# end


				tensorFlow = torch.cat([ tensorFlow[:, 0:1, :, :] / ((tensorInput.size(3) - 1.0) / 2.0), tensorFlow[:, 1:2, :, :] / ((tensorInput.size(2) - 1.0) / 2.0) ], 1)


				return torch.nn.functional.grid_sample(input=tensorInput, grid=(self.tensorGrid + tensorFlow).permute(0, 2, 3, 1), mode='bilinear', padding_mode='border')
			# end
		# end


		self.modulePreprocess = Preprocess()


		self.moduleBasic = torch.nn.ModuleList([ Basic(intLevel) for intLevel in range(6) ])


		self.moduleBackward = Backward()
	# end