 // implements approximation to 8x8 bilateral filtering
 __global__ void adaptiveMeanGPU8 (float* D, float* D_copy, float* D_horiz, int32_t D_width, int32_t D_height) {
   
-  // Pixel id
+  // Global coordinates and Pixel id
   uint32_t u0 = blockDim.x*blockIdx.x + threadIdx.x + 4;
   uint32_t v0 = blockDim.y*blockIdx.y + threadIdx.y + 4;
   uint32_t idx = v0*D_width + u0;
+  //Local thread coordinates
+  uint32_t ut = threadIdx.x + 4;
+  uint32_t vt = threadIdx.y + 4;
+  
 
   if(u0 > (D_width - 4) || v0 > (D_height - 4))
     return;

    *(D_horiz+idx)  = -10;
  }

  __syncthreads();
      
  // full resolution: 8 pixel bilateral filter width

    factor_sum += *(D_horiz+(v0+(i-4))*D_width+u0)*weight_sum0;
  }
  
  weight_sum2 = 0;
  factor_sum2 = 0;

  for(int32_t i=0; i < 8; i++){
    weight_sum0 = 4.0f - fabs(D_copy_S[ut][vt+(i-4)]-val_curr);
    weight_sum0 = max(0.0f, weight_sum0);
    weight_sum2 += weight_sum0;
    factor_sum2 += D_copy_S[ut][vt+(i-4)]*weight_sum0;
  }

  if(blockIdx.x == 0 && blockIdx.y == 0){
      if(weight_sum != weight_sum2){
          printf("Shared error in Y %.10f - %.10f | %d - %d\n", weight_sum, weight_sum2,threadIdx.x,threadIdx.y);
      }
  }

  if (weight_sum>0) {
      float d = factor_sum/weight_sum;
      if (d>=0) *(D+idx) = d;
