 
         int m = a.shape()[0];
         int n = a.shape()[1];
-        int lda = std::min(m, n);
+        int mn = std::min(m, n);
 
         Array Q = Empty(Shape({0}), dtype, device);
         Array R = Empty(a.shape(), dtype, device);
         device.backend().CallKernel<CopyKernel>(a, R);  // QR decomposition is done in-place
-        Array tau = Empty(Shape({lda, 1}), dtype, device);
+        R = R.Transpose();
+        Array tau = Empty(Shape({mn}), dtype, device);
 
         auto qr_impl = [&](auto pt, auto geqrf_bufferSize, auto orgqr_bufferSize, auto geqrf, auto orgqr) -> std::tuple<Array, Array> {
             using T = typename decltype(pt)::type;

            }

            if (mode == QRMode::r) {
                // R = R[range(0, lda), :]
                // R = triu(R)
                return std::make_tuple(std::move(Q), std::move(R));
            }

            if (mode == QRMode::raw) {
                R = R.Transpose();
                return std::make_tuple(std::move(R), std::move(tau));
            }

            // int mc;

            if (mode == QRMode::complete && m > n) {
                // mc = m;
                Q = Empty(Shape({m, m}), dtype, device);
            } else {
                // mc = lda;
                Q = Empty(Shape({m, n}), dtype, device);
            }

            // Q[:, range(0, n)] = R

            device_internals.cusolver_handle().Call(
                orgqr,
                m, n, n, q_ptr, lda, tau_ptr, work_ptr, lwork, devInfo);

            CheckCudaError(cudaMemcpy(&devInfo_h, devInfo, sizeof(int), cudaMemcpyDeviceToHost));
            if (devInfo_h != 0) {
                throw ChainerxError{"Unsuccessfull orgqr (QR) execution. Info = ", devInfo_h};
            }

            // Q = Q[:, range(0, mc)]
            // R = R[range(0, mc), :]
            // R = triu(R)
            return std::make_tuple(std::move(Q), std::move(R));
        };


            int *devInfo;
            CheckCudaError(cudaMalloc(&devInfo, sizeof(int)));

            int buffersize_geqrf = 0;
            device_internals.cusolver_handle().Call(
                geqrf_bufferSize,
                m, n, r_ptr, n, &buffersize_geqrf);

            Array work = Empty(Shape({buffersize_geqrf}), dtype, device);
            T* work_ptr = static_cast<T*>(internal::GetRawOffsetData(work));

            device_internals.cusolver_handle().Call(
                geqrf,
                m, n, r_ptr, m, tau_ptr, work_ptr, buffersize_geqrf, devInfo);

            int devInfo_h = 0;
            CheckCudaError(cudaMemcpy(&devInfo_h, devInfo, sizeof(int), cudaMemcpyDeviceToHost));
