   // A weighted average of each row of grad (according to the weights
   // specified in val) is computed and subtracted from Out.
   // adj is multiplied for each element to get backward step in autodiff
-  int m = grad->shape()[0] * grad->shape()[2] * grad->shape()[3];
-  int k = grad->shape()[1];
+  int m = grad->shape().elements() / grad->shape().back();
+  int k = grad->shape().back();
 
   int blocks = std::min(MAX_BLOCKS, m);
   int threads = std::min(MAX_THREADS, k);

                        Tensor adj) {
  cudaSetDevice(adj->getDevice());

  int rows = adj->shape()[0] * adj->shape()[2] * adj->shape()[3];
  int cols = adj->shape()[1];

  int blocks = std::min(MAX_BLOCKS, rows);
  int threads = std::min(MAX_THREADS, cols);

                      Tensor adj) {
  cudaSetDevice(adj->getDevice());

  int rows = adj->shape().elements() / adj->shape().back();
  int cols = adj->shape().back();

  int blocks = std::min(MAX_BLOCKS, rows);
  int threads = std::min(MAX_THREADS, cols);
