# HG changeset patch # User Markus Mützel # Date 1609975161 -3600 # Thu Jan 07 00:19:21 2021 +0100 # Node ID 340afdcad68408f3864d0c74ac2a7a923cd1cf95 # Parent d8cb0f06ffb1e0fff6cfbe7f706a53beda6b13a3 sparse-qr.cc: Use correct integer types (bug #57033). * liboctave/numeric/sparse-qr.cc (sparse_qr_rep): Use correct integer types for members. Check when converting to smaller type. Do not static_cast pointer types. * liboctave/util/oct-sparse.h (from_suitesparse_long, from_size_t): New functions. * liboctave/util/oct-sparse.cc (ros2rcs, cos2ccs, rod2ccd, cod2ccd, rcs2ros, ccs2cos, ros2ccs): Check when converting to smaller type. Do not static_cast pointer types. Minor style changes. diff -r d8cb0f06ffb1 -r 340afdcad684 liboctave/numeric/sparse-qr.cc --- a/liboctave/numeric/sparse-qr.cc Tue Jan 05 22:10:29 2021 +0100 +++ b/liboctave/numeric/sparse-qr.cc Thu Jan 07 00:19:21 2021 +0100 @@ -142,10 +142,10 @@ cholmod_common m_cc; cholmod_sparse *m_R; // R factor // Column permutation for A. Fill-reducing ordering. - suitesparse_integer *m_E; + SuiteSparse_long *m_E; cholmod_sparse *m_H; // Householder vectors cholmod_dense *m_Htau; // beta scalars - suitesparse_integer *m_HPinv; + SuiteSparse_long *m_HPinv; #endif }; @@ -180,7 +180,7 @@ // FIXME: Is ret.xelem (m_HPinv[i]) = i + 1 correct? for (octave_idx_type i = 0; i < nrows; i++) - ret.xelem (m_HPinv[i]) = i + 1; + ret.xelem (from_suitesparse_long (m_HPinv[i])) = i + 1; return ret; @@ -209,7 +209,7 @@ ColumnVector ret (ncols); for (octave_idx_type i = 0; i < ncols; i++) - ret(i) = static_cast (m_E[i]) + 1; + ret(i) = from_suitesparse_long (m_E[i]) + 1; return ret; @@ -257,12 +257,12 @@ ("ordering %d is not supported by SPQR", order); CHOLMOD_NAME (start) (&m_cc); - const cholmod_sparse A = ros2rcs (a); + cholmod_sparse A = ros2rcs (a); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - SuiteSparseQR (order, SPQR_DEFAULT_TOL, A.nrow, - const_cast (&A), &m_R, &m_E, &m_H, - &m_HPinv, &m_Htau, &m_cc); + SuiteSparseQR (order, static_cast (SPQR_DEFAULT_TOL), + static_cast (A.nrow), + &A, &m_R, &m_E, &m_H, &m_HPinv, &m_Htau, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; } @@ -455,10 +455,10 @@ ("sparse_qr: matrix dimension with negative or zero size"); cholmod_dense *QTB; // Q' * B - const cholmod_dense B = rod2rcd (b); + cholmod_dense B = rod2rcd (b); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - QTB = SuiteSparseQR_qmult (SPQR_QTX, m_H, m_Htau, m_HPinv, - const_cast (&B), &m_cc); + QTB = SuiteSparseQR_qmult (SPQR_QTX, m_H, m_Htau, m_HPinv, &B, + &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -645,6 +645,18 @@ #endif } + static suitesparse_integer + suitesparse_long_to_suitesparse_integer (SuiteSparse_long x) + { + if (x < std::numeric_limits::min () + || x > std::numeric_limits::max ()) + (*current_liboctave_error_handler) + ("integer dimension or index out of range for SuiteSparse's indexing type"); + + return static_cast (x); + } + + template <> template <> Matrix @@ -667,14 +679,13 @@ (*current_liboctave_error_handler) ("matrix dimension mismatch"); cholmod_dense *QTB; // Q' * B - const cholmod_dense B = rod2rcd (b); + cholmod_dense B = rod2rcd (b); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // FIXME: Process b column by column as in the CXSPARSE version below. // This avoids a large dense matrix Q' * B in memory. - QTB = SuiteSparseQR_qmult - (SPQR_QTX, m_H, m_Htau, m_HPinv, const_cast (&B), - &m_cc); + QTB = SuiteSparseQR_qmult (SPQR_QTX, m_H, m_Htau, m_HPinv, &B, + &m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; spqr_error_handler (&m_cc); @@ -684,25 +695,36 @@ R2.n = ncols; R2.m = ncols; R2.nzmax = m_R->nzmax; - R2.x = static_cast (m_R->x); - R2.i = static_cast (m_R->i); - R2.p = static_cast (m_R->p); + R2.x = static_cast (m_R->x); + R2.i = static_cast (m_R->i); + R2.p = static_cast (m_R->p); R2.nz = -1; - double *x_vec = const_cast (x.fortran_vec ()); + double *x_vec = const_cast (x.fortran_vec ()); + suitesparse_integer *E; + if (sizeof (suitesparse_integer) != sizeof (SuiteSparse_long)) + { + E = new suitesparse_integer [ncols]; + for (octave_idx_type i = 0; i < ncols; i++) + E[i] = suitesparse_long_to_suitesparse_integer (m_E[i]); + } + else + E = reinterpret_cast (m_E); for (volatile octave_idx_type j = 0; j < b_nc; j++) { // fill x(:,j) BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // solve (m_R\(Q'*B(:,j)) and store result in QTB(:,j) CXSPARSE_DNAME (_usolve) - (&R2, &(static_cast (QTB->x)[j * b_nr])); + (&R2, &(static_cast (QTB->x)[j * b_nr])); // x(:,j) = m_E' * (m_R\(Q'*B(:,j)) CXSPARSE_DNAME (_ipvec) - (m_E, &(static_cast (QTB->x)[j * b_nr]), &x_vec[j * ncols], + (E, &(static_cast (QTB->x)[j * b_nr]), &x_vec[j * ncols], ncols); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; } + if (sizeof (suitesparse_integer) != sizeof (SuiteSparse_long)) + delete [] E; CHOLMOD_NAME (free_dense) (&QTB, &m_cc); info = 0; @@ -1225,11 +1247,12 @@ ("ordering %d is not supported by SPQR", order); CHOLMOD_NAME (start) (&m_cc); - const cholmod_sparse A = cos2ccs (a); + cholmod_sparse A = cos2ccs (a); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - SuiteSparseQR (order, SPQR_DEFAULT_TOL, A.nrow, - const_cast(&A), &m_R, &m_E, &m_H, + SuiteSparseQR (order, static_cast (SPQR_DEFAULT_TOL), + static_cast (A.nrow), + &A, &m_R, &m_E, &m_H, &m_HPinv, &m_Htau, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -1321,7 +1344,7 @@ for (octave_idx_type j = 0; j < nz; j++) { ret.xridx (j) = N->L->i[j]; - ret.xdata (j) = reinterpret_cast(N->L->x)[j]; + ret.xdata (j) = reinterpret_cast (N->L->x)[j]; } return ret; @@ -1339,16 +1362,16 @@ { #if (defined (HAVE_SPQR) && defined (HAVE_CHOLMOD)) - octave_idx_type nr = static_cast (m_R->nrow); - octave_idx_type nc = static_cast (m_R->ncol); - octave_idx_type nz = static_cast (m_R->nzmax); + octave_idx_type nr = from_size_t (m_R->nrow); + octave_idx_type nc = from_size_t (m_R->ncol); + octave_idx_type nz = from_size_t (m_R->nzmax); // FIXME: Does this work if econ = true? SparseComplexMatrix ret ((econ ? (nc > nr ? nr : nc) : nr), nc, nz); octave_idx_type *Rp = to_octave_idx_type_ptr - (static_cast (m_R->p)); + (static_cast (m_R->p)); octave_idx_type *Ri = to_octave_idx_type_ptr - (static_cast (m_R->i)); + (static_cast (m_R->i)); for (octave_idx_type j = 0; j < nc + 1; j++) ret.xcidx (j) = Rp[j]; @@ -1356,7 +1379,7 @@ for (octave_idx_type j = 0; j < nz; j++) { ret.xridx (j) = Ri[j]; - ret.xdata (j) = (static_cast (m_R->x))[j]; + ret.xdata (j) = (reinterpret_cast (m_R->x))[j]; } return ret; @@ -1423,18 +1446,17 @@ ("matrix dimension with negative or zero size"); cholmod_dense *QTB; // Q' * B - const cholmod_dense B = cod2ccd (b); + cholmod_dense B = cod2ccd (b); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - QTB = SuiteSparseQR_qmult (SPQR_QTX, m_H, m_Htau, m_HPinv, - const_cast (&B), + QTB = SuiteSparseQR_qmult (SPQR_QTX, m_H, m_Htau, m_HPinv, &B, &m_cc); spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; // copy QTB into ret - Complex *QTB_x = static_cast (QTB->x); - Complex *ret_vec = static_cast (ret.fortran_vec ()); + Complex *QTB_x = reinterpret_cast (QTB->x); + Complex *ret_vec = reinterpret_cast (ret.fortran_vec ()); for (octave_idx_type j = 0; j < b_nc; j++) for (octave_idx_type i = 0; i < nr; i++) ret_vec[j * nr + i] = QTB_x[j * b_nr + i]; @@ -1521,15 +1543,15 @@ cholmod_dense *q; // I is nrows x nrows identity matrix - cholmod_dense *I = static_cast + cholmod_dense *I = reinterpret_cast (CHOLMOD_NAME (allocate_dense) (nrows, nrows, nrows, CHOLMOD_COMPLEX, &m_cc)); for (octave_idx_type i = 0; i < nrows * nrows; i++) - (static_cast (I->x))[i] = 0.0; + (reinterpret_cast (I->x))[i] = 0.0; for (octave_idx_type i = 0; i < nrows; i++) - (static_cast (I->x))[i * nrows + i] = 1.0; + (reinterpret_cast (I->x))[i * nrows + i] = 1.0; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; q = SuiteSparseQR_qmult (SPQR_QX, m_H, m_Htau, m_HPinv, I, @@ -1537,7 +1559,7 @@ spqr_error_handler (&m_cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - Complex *q_x = static_cast (q->x); + Complex *q_x = reinterpret_cast (q->x); Complex *ret_vec = const_cast (ret.fortran_vec ()); for (octave_idx_type j = 0; j < nc; j++) @@ -1964,7 +1986,7 @@ buf[j] = cs_complex_t (0.0, 0.0); BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - CXSPARSE_ZNAME (_pvec) (S->q, reinterpret_cast(Xx), + CXSPARSE_ZNAME (_pvec) (S->q, reinterpret_cast (Xx), buf, nr); CXSPARSE_ZNAME (_utsolve) (N->U, buf); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2034,7 +2056,7 @@ BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; CXSPARSE_ZNAME (_ipvec) (S->pinv, - reinterpret_cast(Xx), + reinterpret_cast (Xx), buf, nr); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2138,7 +2160,7 @@ BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; CXSPARSE_ZNAME (_pvec) (S->q, - reinterpret_cast(Xx), + reinterpret_cast (Xx), buf, nr); CXSPARSE_ZNAME (_utsolve) (N->U, buf); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2374,7 +2396,7 @@ BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; CXSPARSE_ZNAME (_ipvec) (S->pinv, - reinterpret_cast(Xx), + reinterpret_cast (Xx), buf, nr); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2661,14 +2683,12 @@ cholmod_common cc; CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = ros2rcs (a); - const cholmod_dense B = rod2rcd (b); + cholmod_sparse A = ros2rcs (a); + cholmod_dense B = rod2rcd (b); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, - const_cast (&A), - const_cast (&B), &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2695,14 +2715,12 @@ cholmod_common cc; CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = ros2rcs(a); + cholmod_sparse A = ros2rcs(a); cholmod_sparse B = ros2rcs(b); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, - const_cast(&A), &B, - &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2733,19 +2751,17 @@ CHOLMOD_NAME (start) (&cc); cholmod_sparse *A = ros2ccs (a, &cc); - const cholmod_dense B = cod2ccd (b); + cholmod_dense B = cod2ccd (b); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, A, - const_cast (&B), - &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; Complex *vec = x.fortran_vec (); for (volatile octave_idx_type i = 0; i < nc * b_nc; i++) - vec[i] = static_cast (X->x)[i]; + vec[i] = reinterpret_cast (X->x)[i]; CHOLMOD_NAME (free_sparse) (&A, &cc); CHOLMOD_NAME (finish) (&cc); @@ -2770,14 +2786,12 @@ CHOLMOD_NAME (start) (&cc); - cholmod_sparse * A = ros2ccs (a, &cc); - const cholmod_sparse B = cos2ccs (b); + cholmod_sparse *A = ros2ccs (a, &cc); + cholmod_sparse B = cos2ccs (b); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, A, - const_cast (&B), - &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2809,15 +2823,12 @@ CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = cos2ccs (a); - const cholmod_dense B = cod2ccd (b); + cholmod_sparse A = cos2ccs (a); + cholmod_dense B = cod2ccd (b); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, - const_cast (&A), - const_cast (&B), - &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2851,14 +2862,12 @@ CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = cos2ccs (a); + cholmod_sparse A = cos2ccs (a); cholmod_dense *B = rod2ccd (b, &cc); cholmod_dense *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, - const_cast (&A), - B, &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, &A, B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2890,15 +2899,12 @@ CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = cos2ccs (a); - const cholmod_sparse B = cos2ccs (b); + cholmod_sparse A = cos2ccs (a); + cholmod_sparse B = cos2ccs (b); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, - const_cast (&A), - const_cast (&B), - &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, &A, &B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; @@ -2924,14 +2930,12 @@ CHOLMOD_NAME (start) (&cc); - const cholmod_sparse A = cos2ccs (a); + cholmod_sparse A = cos2ccs (a); cholmod_sparse *B = ros2ccs (b, &cc); cholmod_sparse *X; BEGIN_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; - X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, - const_cast (&A), B, - &cc); + X = SuiteSparseQR_min2norm (order, SPQR_DEFAULT_TOL, &A, B, &cc); spqr_error_handler (&cc); END_INTERRUPT_IMMEDIATELY_IN_FOREIGN_CODE; diff -r d8cb0f06ffb1 -r 340afdcad684 liboctave/util/oct-sparse.cc --- a/liboctave/util/oct-sparse.cc Tue Jan 05 22:10:29 2021 +0100 +++ b/liboctave/util/oct-sparse.cc Thu Jan 07 00:19:21 2021 +0100 @@ -81,7 +81,7 @@ # if defined (HAVE_CHOLMOD) const cholmod_sparse - ros2rcs (const SparseMatrix &a) + ros2rcs (const SparseMatrix& a) { cholmod_sparse A; @@ -100,15 +100,15 @@ A.dtype = CHOLMOD_DOUBLE; A.nz = NULL; A.z = NULL; - A.p = const_cast (to_suitesparse_intptr (a.cidx ())); - A.i = const_cast (to_suitesparse_intptr (a.ridx ())); - A.x = const_cast (a.data ()); + A.p = const_cast (to_suitesparse_intptr (a.cidx ())); + A.i = const_cast (to_suitesparse_intptr (a.ridx ())); + A.x = const_cast (a.data ()); return A; } const cholmod_sparse - cos2ccs (const SparseComplexMatrix &a) + cos2ccs (const SparseComplexMatrix& a) { cholmod_sparse A; @@ -127,26 +127,27 @@ A.dtype = CHOLMOD_DOUBLE; A.nz = NULL; A.z = NULL; - A.p = const_cast (to_suitesparse_intptr (a.cidx ())); - A.i = const_cast (to_suitesparse_intptr (a.ridx ())); - A.x = const_cast - (reinterpret_cast (a.data ())); + A.p = const_cast (to_suitesparse_intptr (a.cidx ())); + A.i = const_cast (to_suitesparse_intptr (a.ridx ())); + A.x = const_cast + (reinterpret_cast (a.data ())); return A; } cholmod_dense* - rod2ccd (const MArray &a, cholmod_common* cc1) + rod2ccd (const MArray& a, cholmod_common *cc1) { - cholmod_dense *A = static_cast + cholmod_dense *A = reinterpret_cast (CHOLMOD_NAME (allocate_dense) (a.rows (), a.cols (), a.rows(), CHOLMOD_COMPLEX, cc1)); const double *a_x = a.data (); + Complex *A_x = reinterpret_cast (A->x); for (octave_idx_type j = 0; j < a.cols() * a.rows() ; j++) - (static_cast (A->x))[j] = Complex (a_x[j], 0.0); + A_x[j] = Complex (a_x[j], 0.0); return A; } @@ -158,12 +159,12 @@ A.ncol = a.cols (); A.nrow = a.rows (); - A.nzmax = a.cols() * a.rows(); + A.nzmax = a.cols () * a.rows (); A.xtype = CHOLMOD_REAL; A.dtype = CHOLMOD_DOUBLE; - A.z = NULL; - A.d = a.rows(); - A.x = const_cast (a.data ()); + A.z = nullptr; + A.d = a.rows (); + A.x = const_cast (a.data ()); return A; } @@ -178,8 +179,8 @@ A.nzmax = a.cols () * a.rows (); A.xtype = CHOLMOD_COMPLEX; A.dtype = CHOLMOD_DOUBLE; - A.z = NULL; - A.d = a.rows(); + A.z = nullptr; + A.d = a.rows (); A.x = const_cast (reinterpret_cast (a.data ())); @@ -189,70 +190,81 @@ SparseMatrix rcs2ros (const cholmod_sparse* y) { - SparseMatrix ret (static_cast (y->nrow), - static_cast (y->ncol), - static_cast (y->nzmax)); + octave_idx_type nrow = from_size_t (y->nrow); + octave_idx_type ncol = from_size_t (y->ncol); + octave_idx_type nz = from_size_t (y->nzmax); + SparseMatrix ret (nrow, ncol, nz); - octave_idx_type nz = static_cast (y->nzmax); + octave_idx_type *y_p + = to_octave_idx_type_ptr (reinterpret_cast (y->p)); + for (octave_idx_type j = 0; j < ncol + 1; j++) + ret.xcidx (j) = y_p[j]; - for (octave_idx_type j = 0; j < static_cast (y->ncol) + 1; - j++) - ret.xcidx (j) = (static_cast (y->p))[j]; - + octave_idx_type *y_i + = to_octave_idx_type_ptr (reinterpret_cast (y->i)); + double *y_x = reinterpret_cast (y->x); for (octave_idx_type j = 0; j < nz; j++) { - ret.xridx (j) = (static_cast (y->i))[j]; - ret.xdata (j) = (static_cast (y->x))[j]; + ret.xridx (j) = y_i[j]; + ret.xdata (j) = y_x[j]; } return ret; } SparseComplexMatrix - ccs2cos (const cholmod_sparse* a) + ccs2cos (const cholmod_sparse *a) { - SparseComplexMatrix ret (static_cast (a->nrow), - static_cast (a->ncol), - static_cast (a->nzmax)); + octave_idx_type nrow = from_size_t (a->nrow); + octave_idx_type ncol = from_size_t (a->ncol); + octave_idx_type nz = from_size_t (a->nzmax); + SparseComplexMatrix ret (nrow, ncol, nz); - octave_idx_type nz = static_cast (a->nzmax); + octave_idx_type *a_p + = to_octave_idx_type_ptr (reinterpret_cast (a->p)); + for (octave_idx_type j = 0; j < ncol + 1; j++) + ret.xcidx(j) = a_p[j]; - for (octave_idx_type j = 0; j < static_cast (a->ncol) + 1; - j++) - ret.xcidx (j) = (static_cast (a->p))[j]; - + octave_idx_type *a_i + = to_octave_idx_type_ptr (reinterpret_cast (a->i)); + Complex *a_x = reinterpret_cast (a->x); for (octave_idx_type j = 0; j < nz; j++) { - ret.xridx (j) = (static_cast (a->i))[j]; - ret.xdata (j) = (static_cast (a->x))[j]; + ret.xridx(j) = a_i[j]; + ret.xdata(j) = a_x[j]; } return ret; } cholmod_sparse* - ros2ccs (const SparseMatrix& a, cholmod_common* cc1) + ros2ccs (const SparseMatrix& a, cholmod_common *cc) { - cholmod_sparse *A = static_cast - (CHOLMOD_NAME(allocate_sparse) + cholmod_sparse *A = reinterpret_cast + (CHOLMOD_NAME (allocate_sparse) (a.rows (), a.cols (), a.nnz (), 0, 1, 0, - CHOLMOD_COMPLEX, cc1)); + CHOLMOD_COMPLEX, cc)); - for (octave_idx_type j = 0; - j < static_cast (a.cols ()) + 1; j++) - static_cast (A->p)[j] = a.cidx(j); + octave_idx_type ncol = a.cols (); + octave_idx_type *A_p + = to_octave_idx_type_ptr (reinterpret_cast (A->p)); + for (octave_idx_type j = 0; j < ncol + 1; j++) + A_p[j] = a.cidx(j); const double *a_x = a.data (); + Complex *A_x = reinterpret_cast (A->x); + octave_idx_type *A_i + = to_octave_idx_type_ptr (reinterpret_cast (A->i)); for (octave_idx_type j = 0; j < a.nnz (); j++) { - (static_cast (A->x))[j] = Complex (a_x[j], 0.0); - (static_cast (A->i))[j] = a.ridx(j); + A_x[j] = Complex (a_x[j], 0.0); + A_i[j] = a.ridx(j); } return A; } void - spqr_error_handler (const cholmod_common* cc) + spqr_error_handler (const cholmod_common *cc) { if (cc->status >= 0) return; diff -r d8cb0f06ffb1 -r 340afdcad684 liboctave/util/oct-sparse.h --- a/liboctave/util/oct-sparse.h Tue Jan 05 22:10:29 2021 +0100 +++ b/liboctave/util/oct-sparse.h Thu Jan 07 00:19:21 2021 +0100 @@ -186,15 +186,37 @@ extern OCTAVE_API suitesparse_integer * to_suitesparse_intptr (octave_idx_type *i); - extern OCTAVE_API const suitesparse_integer * + extern const OCTAVE_API suitesparse_integer * to_suitesparse_intptr (const octave_idx_type *i); extern OCTAVE_API octave_idx_type* to_octave_idx_type_ptr (suitesparse_integer *i); - extern OCTAVE_API const octave_idx_type* + extern const OCTAVE_API octave_idx_type* to_octave_idx_type_ptr (const suitesparse_integer *i); + inline octave_idx_type + from_suitesparse_long (SuiteSparse_long x) + { + if (x < std::numeric_limits::min () + || x > std::numeric_limits::max ()) + (*current_liboctave_error_handler) + ("integer dimension or index out of range for Octave's indexing type"); + + return static_cast (x); + } + + inline octave_idx_type + from_size_t (size_t x) + { + // size_t is guaranteed to be unsigned + if (x > std::numeric_limits::max ()) + (*current_liboctave_error_handler) + ("integer dimension or index out of range for Octave's index type"); + + return static_cast (x); + } + # if defined (HAVE_CHOLMOD) // Convert real sparse octave matrix to real sparse cholmod matrix. // Returns a "shallow" copy of a.