       const int gradInputImagesTopRightAddress = gradInputImagesTopLeftAddress + gradInputImages_strideWidth;
       const int gradInputImagesBottomLeftAddress = gradInputImagesTopLeftAddress + gradInputImages_strideHeight;
       const int gradInputImagesBottomRightAddress = gradInputImagesBottomLeftAddress + gradInputImages_strideWidth;
+
+      const int inTopLeftMaskAddress = masks_strideBatch * b + masks_strideHeight * yInTopLeft + masks_strideWidth * xInTopLeft;
+      const int inTopRightMaskAddress = inTopLeftMaskAddress + masks_strideWidth;
+      const int inBottomLeftMaskAddress = inTopLeftMaskAddress + masks_strideHeight;
+      const int inBottomRightMaskAddress = inBottomLeftMaskAddress + masks_strideWidth;
+
+      const int gradMasksTopLeftAddress = gradMasks_strideBatch * b + gradMasks_strideHeight * yInTopLeft + gradMasks_strideWidth * xInTopLeft;
+      const int gradMasksTopRightAddress = gradMasksTopLeftAddress + gradMasks_strideWidth;
+      const int gradMasksBottomLeftAddress = gradMasksTopLeftAddress + gradMasks_strideHeight;
+      const int gradMasksBottomRightAddress = gradMasksBottomLeftAddress + gradMasks_strideWidth;
 
       const int gradOutputAddress = gradOutput_strideBatch * b + gradOutput_strideHeight * yOut + gradOutput_strideWidth * xOut;
 

      yf = gridData[threadIdx.y*2];
      xf = gridData[threadIdx.y*2+1];



      int yInTopLeft, xInTopLeft;
      float yWeightTopLeft, xWeightTopLeft;
      getTopLeft(xf, inputImages_width, xInTopLeft, xWeightTopLeft);

           + xWeightTopLeft * (1 - yWeightTopLeft) * inBottomLeft
           + (1 - xWeightTopLeft) * (1 - yWeightTopLeft) * inBottomRight;

         c = canvas_data[gradOutputAddress + t];

         float gradMaskValue = gradOutValue * (v - c);


         // update gradient on mask map
         if(topLeftIsIn)
         {
            if(!onlyGrid) atomicAdd(&gradMasks_data[gradMasksTopLeftAddress], xWeightTopLeft * yWeightTopLeft * gradMaskValue);
         }

         if(topRightIsIn)
         {
            if(!onlyGrid) atomicAdd(&gradMasks_data[gradMasksTopRightAddress], (1 - xWeightTopLeft) * yWeightTopLeft * gradMaskValue);
         }

         if(bottomLeftIsIn)
         {
            if(!onlyGrid) atomicAdd(&gradMasks_data[gradMasksBottomLeftAddress], xWeightTopLeft * (1 - yWeightTopLeft) * gradMaskValue);
         }

         if(bottomRightIsIn)
         {
            if(!onlyGrid) atomicAdd(&gradMasks_data[gradMasksBottomRightAddress], (1 - xWeightTopLeft) * (1 - yWeightTopLeft) * gradMaskValue);
         }
      }
      /*
         Here we reduce the dot product and compute the grid gradient before writing it.
