 
     // CUDA copy over needed memory information
     // disparity_grid and respective copies
-    float* d_D, *d_D_copy, *d_D_horiz;
-
-    // Allocate on global memory
+    float* d_D;
+
+    // Allocate on global memory and copy
     cudaMalloc((void**) &d_D, width*height*sizeof(float));
-    cudaMalloc((void**) &d_D_copy, width*height*sizeof(float));
-    cudaMalloc((void**) &d_D_horiz, width*height*sizeof(float));
-
     cudaMemcpy(d_D, D, width*height*sizeof(float), cudaMemcpyHostToDevice);
-    cudaMemcpy(d_D_copy, D, width*height*sizeof(float), cudaMemcpyHostToDevice);
-    cudaMemcpy(d_D_horiz, D, width*height*sizeof(float), cudaMemcpyHostToDevice);
 
     //Kernel go!
-    adaptiveMeanGPU8<<<DimGrid, DimBlock>>>(d_D, d_D_copy, d_D_horiz, width, height);
+    adaptiveMeanGPU8<<<DimGrid, DimBlock>>>(d_D, width, height);
 
     // Sync after the kernel is launched
     cudaDeviceSynchronize();

}

// 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) {
  
  // Global coordinates and Pixel id
  uint32_t u0 = blockDim.x*blockIdx.x + threadIdx.x + 4;

  uint32_t ut = threadIdx.x + 4;
  uint32_t vt = threadIdx.y + 4;
  
  //If out of filter range return instantly
  if(u0 > (D_width - 4) || v0 > (D_height - 4))
    return;

  //Allocate Shared memory array with an appropiate margin for the bitlateral filter
  //Since we are using 8 pixels with the center pixel being 5,
  //we need 4 extra on left and top and 3 extra on right and bottom
  __shared__ float D_shared[32+7][32+7];
  //Populate shared memory
  if(threadIdx.x == blockDim.x-1){
      D_shared[ut+1][vt] = D[idx+1];
      D_shared[ut+2][vt] = D[idx+2];
      D_shared[ut+3][vt] = D[idx+3];
      //D_shared[ut+4][vt] = D[idx+4];
  }
  if(threadIdx.x == 0){
      D_shared[ut-4][vt] = D[idx-4];
      D_shared[ut-3][vt] = D[idx-3];
      D_shared[ut-2][vt] = D[idx-2];
      D_shared[ut-1][vt] = D[idx-1];
  }
  if(threadIdx.y == 0){
      D_shared[ut][vt-4] = D[(v0-4)*D_width+u0];
      D_shared[ut][vt-3] = D[(v0-3)*D_width+u0];
      D_shared[ut][vt-2] = D[(v0-2)*D_width+u0];
      D_shared[ut][vt-1] = D[(v0-1)*D_width+u0];
  }
  if(threadIdx.y == blockDim.y-1){
      D_shared[ut][vt+1] = D[(v0+1)*D_width+u0];
      D_shared[ut][vt+2] = D[(v0+2)*D_width+u0];
      D_shared[ut][vt+3] = D[(v0+3)*D_width+u0];
      //D_shared[ut][vt+4] = D[(v0+4)*D_width+u0];
  }

  if(D[idx] < 0){
      // zero input disparity maps to -10 (this makes the bilateral
      // weights of all valid disparities to 0 in this region)
      D_shared[ut][vt] = -10;
  }else{
      D_shared[ut][vt] = D[idx];
  }
  __syncthreads();
      
