Yalantis/uCrop · warning

solve(): LAPACK library function dgetrs_() returned error co

Error message

solve(): LAPACK library function dgetrs_() returned error code %d.

What it means

After factoring A, CImg::solve() applies LAPACK dgetrs_() to compute the solution; nonzero INFO indicates an invalid argument (bad TRANS/N/LDA/LDB or pivot array) rather than singularity, since dgetrf_ already succeeded. CImg warns and zero-fills the affected solution column.

Source

Thrown at ucrop/src/main/jni/CImg.h:33024

        char TRANS = 'N';
        int INFO, N = _height, LWORK = 4*N, *const IPIV = new int[N];
        Ttfloat
          *const lapA = new Ttfloat[N*N],
          *const lapB = new Ttfloat[N],
          *const WORK = new Ttfloat[LWORK];
        cimg_forXY(A,k,l) lapA[k*N + l] = (Ttfloat)(A(k,l));
        cimg_forX(*this,i) {
          cimg_forY(*this,j) lapB[j] = (Ttfloat)((*this)(i,j));
          cimg::getrf(N,lapA,IPIV,INFO);
          if (INFO)
            cimg::warn(_cimg_instance
                       "solve(): LAPACK library function dgetrf_() returned error code %d.",
                       cimg_instance,
                       INFO);
          else {
            cimg::getrs(TRANS,N,lapA,IPIV,lapB,INFO);
            if (INFO)
              cimg::warn(_cimg_instance
                         "solve(): LAPACK library function dgetrs_() returned error code %d.",
                         cimg_instance,
                         INFO);
          }
          if (!INFO) cimg_forY(*this,j) (*this)(i,j) = (T)(lapB[j]); else cimg_forY(*this,j) (*this)(i,j) = (T)0;
        }
        delete[] IPIV; delete[] lapA; delete[] lapB; delete[] WORK;
#else
        CImg<Ttfloat> lu(A,false);
        CImg<Ttfloat> indx;
        bool d;
        lu._LU(indx,d);
        CImg<T> res(_width,A._width);
        cimg_pragma_openmp(parallel for cimg_openmp_if_size(_width*_height,16))
        cimg_forX(*this,i) res.draw_image(i,get_column(i)._solve(lu,indx));
        res.move_to(*this);
#endif
      } else { // Least-square solution for non-square systems

View on GitHub (pinned to f788b534b4)

Solutions

  1. Validate that B.height() == A.height() and A is square before calling solve()
  2. Link a complete, consistent LAPACK build in the NDK project
  3. Check the result for the zero-fill fallback and retry with the LU-invert path or sgels
  4. Print matrix dimensions before the call to catch shape mismatches

Example fix

// before
CImg<float> x = B.solve(A);
// after
if (B.height() != A.height()) throw std::runtime_error("solve: row mismatch between B and A");
CImg<float> x = B.solve(A);
Defensive patterns

Strategy: validation

Validate before calling

bool shapesConsistent(const CImg<float>& A, const CImg<float>& B) {
  return A.width() == A.height() && B.height() == A.height();
}

Prevention

When it happens

Trigger: Calling solve() when the internal call to dgetrs_ receives inconsistent parameters — typically from dimension mismatches between this (B) and the coefficient matrix A, or a broken LAPACK build.

Common situations: Mixed-shape inputs (B rows != A rows) in code that was not type-checked; linking a partial LAPACK in an Android NDK build with a different ABI for dgetrs_.

Related errors


AI-assisted analysis of Yalantis/uCrop@f788b534b4 (2026-09-08). Data as JSON: /api/errors/ff24f7a6193426b8. Report an issue: GitHub.