   float scale = luaL_optnumber(L, 4, 1);
   int kW = luaT_getfieldcheckint(L, 1, "kW");
   int dW = luaT_getfieldcheckint(L, 1, "dW");
-  long nInputFrame = input->size[0];
-  long nOutputFrame = gradOutput->size[0];
+  long nInputFrame;
+  long nOutputFrame;
 
   THCudaTensor *gradWeight = (THCudaTensor*)luaT_getfieldcheckudata(L, 1, "gradWeight", "torch.CudaTensor");
   THCudaTensor *gradBias = (THCudaTensor*)luaT_getfieldcheckudata(L, 1, "gradBias", "torch.CudaTensor");
 
   THCudaTensor *gradOutputWindow;
   THCudaTensor *inputWindow;
-  long k;
+  long k, i;
+  
+  int dimS = 0; // sequence dimension
+  int dimF = 1; // feature dimension
+  
+  if (gradOutput->nDimension == 3) 
+  {
+    dimS = 1;
+    dimF = 2;
+  }
+  
+  nInputFrame = input->size[dimS];
+  nOutputFrame = gradOutput->size[dimS];
 
 
   /* Not necessary with partial backprop: */

  gradOutputWindow = THCudaTensor_new();
  inputWindow = THCudaTensor_new();

  /* bias first */
  for(k = 0; k < nOutputFrame; k++)
  {
    THCudaTensor_select(gradOutputWindow, gradOutput, 0, k);
    THCudaTensor_cadd(gradBias, scale, gradOutputWindow);
  }

  /* ouch */
  for(k = 0; nOutputFrame > 0; k++)
  {
    long outputFrameStride = (kW-1)/dW+1;
    long inputFrameStride = outputFrameStride*dW;
    long nFrame = (nInputFrame-k*dW-kW)/inputFrameStride + 1;
    nOutputFrame -= nFrame;

    THCudaTensor_setStorage2d(inputWindow, input->storage,
                            input->storageOffset+k*dW*input->size[1],
                            nFrame, inputFrameStride*input->size[1],
                            kW*input->size[1], 1);

    THCudaTensor_setStorage2d(gradOutputWindow, gradOutput->storage, 
                            gradOutput->storageOffset + k*gradOutput->size[1],
                            nFrame, outputFrameStride*gradOutput->size[1],
                            gradOutput->size[1], 1);

    THCudaTensor_transpose(gradOutputWindow, NULL, 0, 1);
    THCudaTensor_addmm(gradWeight, 1, scale, gradOutputWindow, inputWindow);
    THCudaTensor_transpose(gradOutputWindow, NULL, 0, 1);
  }

  THCudaTensor_free(gradOutputWindow);


      THCudaTensor_addmm(gradInputWindow, 1, 1, gradOutputWindow, weight);
    }
  }
  else
  {
    THCudaTensor *gradOutputSample = THCudaTensor_(new)();
