# HG changeset patch # User John W. Eaton # Date 1632947110 14400 # Node ID 8670f516543063d40254278f114c02e68ced0de7 # Parent b8841fcd28c8a3ac7681b8cc531259e189f7df71 use distinct classes for interleaved and separate numeric mxarray objects This change is the first step to improving performance of the conversion from numeric mxArray objects to octave_value objects when the mxArray objects use interleaved complex storage or when the arrays are real valued. * mex.cc (class mxArray_base_full): Rename from mxArray_number. (class mxArray_interleaved_full, class mxArray_separate_full): New classes, derived from mxArray_base_full. These classes currently do nothing different from mxArray_base_full except that the interleaved argument is omitted from the constructors. (class mxArray_base_sparse): Rename from mxArray_sparse. (class mxArray_interleaved_sparse, class mxArray_separate_sparse): New classes, derived from mxArray_base_sparse. These classes currently do nothing different from mxArray_base_sparse except that the interleaved argument is omitted from the constructors. (mxArray::create_rep): Conditionally create distinct interleaved or separate objects here. diff -r b8841fcd28c8 -r 8670f5165430 libinterp/corefcn/mex.cc --- a/libinterp/corefcn/mex.cc Wed Sep 29 15:41:21 2021 -0400 +++ b/libinterp/corefcn/mex.cc Wed Sep 29 16:25:10 2021 -0400 @@ -1561,13 +1561,13 @@ return 0; \ } -class mxArray_number : public mxArray_matlab +class mxArray_base_full : public mxArray_matlab { public: - mxArray_number (bool interleaved, mxClassID id, mwSize ndims, - const mwSize *dims, mxComplexity flag = mxREAL, - bool init = true) + mxArray_base_full (bool interleaved, mxClassID id, mwSize ndims, + const mwSize *dims, mxComplexity flag = mxREAL, + bool init = true) : mxArray_matlab (interleaved, id, ndims, dims), m_complex (flag == mxCOMPLEX), m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())), @@ -1578,8 +1578,8 @@ : nullptr)) { } - mxArray_number (bool interleaved, mxClassID id, const dim_vector& dv, - mxComplexity flag = mxREAL) + mxArray_base_full (bool interleaved, mxClassID id, const dim_vector& dv, + mxComplexity flag = mxREAL) : mxArray_matlab (interleaved, id, dv), m_complex (flag == mxCOMPLEX), m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), m_pi (m_interleaved @@ -1589,8 +1589,8 @@ : nullptr)) { } - mxArray_number (bool interleaved, mxClassID id, mwSize m, mwSize n, - mxComplexity flag = mxREAL, bool init = true) + mxArray_base_full (bool interleaved, mxClassID id, mwSize m, mwSize n, + mxComplexity flag = mxREAL, bool init = true) : mxArray_matlab (interleaved, id, m, n), m_complex (flag == mxCOMPLEX), m_pr (mxArray::alloc (init, get_number_of_elements (), get_element_size ())), m_pi (m_interleaved @@ -1600,7 +1600,7 @@ : nullptr)) { } - mxArray_number (bool interleaved, mxClassID id, double val) + mxArray_base_full (bool interleaved, mxClassID id, double val) : mxArray_matlab (interleaved, id, 1, 1), m_complex (false), m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), m_pi (nullptr) @@ -1609,7 +1609,7 @@ dpr[0] = val; } - mxArray_number (bool interleaved, mxClassID id, mxLogical val) + mxArray_base_full (bool interleaved, mxClassID id, mxLogical val) : mxArray_matlab (interleaved, id, 1, 1), m_complex (false), m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), m_pi (nullptr) @@ -1618,7 +1618,7 @@ lpr[0] = val; } - mxArray_number (bool interleaved, const char *str) + mxArray_base_full (bool interleaved, const char *str) : mxArray_matlab (interleaved, mxCHAR_CLASS, str ? (strlen (str) ? 1 : 0) : 0, str ? strlen (str) : 0), @@ -1633,7 +1633,7 @@ } // FIXME: ??? - mxArray_number (bool interleaved, mwSize m, const char **str) + mxArray_base_full (bool interleaved, mwSize m, const char **str) : mxArray_matlab (interleaved, mxCHAR_CLASS, m, max_str_len (m, str)), m_complex (false), m_pr (mxArray::calloc (get_number_of_elements (), get_element_size ())), @@ -1662,14 +1662,14 @@ // No assignment! FIXME: should this be implemented? Note that we // do have a copy constructor. - mxArray_number& operator = (const mxArray_number&); + mxArray_base_full& operator = (const mxArray_base_full&); mxArray_base * dup (void) const { - return new mxArray_number (*this); + return new mxArray_base_full (*this); } - ~mxArray_number (void) + ~mxArray_base_full (void) { mxFree (m_pr); mxFree (m_pi); @@ -2030,7 +2030,7 @@ protected: - mxArray_number (const mxArray_number& val) + mxArray_base_full (const mxArray_base_full& val) : mxArray_matlab (val), m_complex (val.m_complex), m_pr (mxArray::malloc (get_number_of_elements () * get_element_size ())), m_pi (m_interleaved @@ -2085,14 +2085,124 @@ void *m_pi; }; -// Matlab-style sparse arrays. - -class mxArray_sparse : public mxArray_matlab +class mxArray_interleaved_full : public mxArray_base_full +{ +public: + + mxArray_interleaved_full (mxClassID id, mwSize ndims, const mwSize *dims, + mxComplexity flag = mxREAL, bool init = true) + : mxArray_base_full (true, id, ndims, dims, flag, init) + { } + + mxArray_interleaved_full (mxClassID id, const dim_vector& dv, + mxComplexity flag = mxREAL) + : mxArray_base_full (true, id, dv, flag) + { } + + mxArray_interleaved_full (mxClassID id, mwSize m, mwSize n, + mxComplexity flag = mxREAL, bool init = true) + : mxArray_base_full (true, id, m, n, flag, init) + { } + + mxArray_interleaved_full (mxClassID id, double val) + : mxArray_base_full (true, id, val) + { } + + mxArray_interleaved_full (mxClassID id, mxLogical val) + : mxArray_base_full (true, id, val) + { } + + mxArray_interleaved_full (const char *str) + : mxArray_base_full (true, str) + { } + + // FIXME: ??? + mxArray_interleaved_full (mwSize m, const char **str) + : mxArray_base_full (true, m, str) + { } + + // No assignment! FIXME: should this be implemented? Note that we + // do have a copy constructor. + + mxArray_interleaved_full& operator = (const mxArray_interleaved_full&); + + mxArray_base * dup (void) const + { + return new mxArray_interleaved_full (*this); + } + + ~mxArray_interleaved_full (void) = default; + +protected: + + mxArray_interleaved_full (const mxArray_interleaved_full& val) + : mxArray_base_full (val) + { } +}; + +class mxArray_separate_full : public mxArray_base_full { public: - mxArray_sparse (bool interleaved, mxClassID id, mwSize m, mwSize n, - mwSize nzmax, mxComplexity flag = mxREAL) + mxArray_separate_full (mxClassID id, mwSize ndims, const mwSize *dims, + mxComplexity flag = mxREAL, bool init = true) + : mxArray_base_full (false, id, ndims, dims, flag, init) + { } + + mxArray_separate_full (mxClassID id, const dim_vector& dv, + mxComplexity flag = mxREAL) + : mxArray_base_full (false, id, dv, flag) + { } + + mxArray_separate_full (mxClassID id, mwSize m, mwSize n, + mxComplexity flag = mxREAL, bool init = true) + : mxArray_base_full (false, id, m, n, flag, init) + { } + + mxArray_separate_full (mxClassID id, double val) + : mxArray_base_full (false, id, val) + { } + + mxArray_separate_full (mxClassID id, mxLogical val) + : mxArray_base_full (false, id, val) + { } + + mxArray_separate_full (const char *str) + : mxArray_base_full (false, str) + { } + + // FIXME: ??? + mxArray_separate_full (mwSize m, const char **str) + : mxArray_base_full (false, m, str) + { } + + // No assignment! FIXME: should this be implemented? Note that we + // do have a copy constructor. + + mxArray_separate_full& operator = (const mxArray_separate_full&); + + mxArray_base * dup (void) const + { + return new mxArray_separate_full (*this); + } + + ~mxArray_separate_full (void) = default; + +protected: + + mxArray_separate_full (const mxArray_separate_full& val) + : mxArray_base_full (val) + { } +}; + +// Matlab-style sparse arrays. + +class mxArray_base_sparse : public mxArray_matlab +{ +public: + + mxArray_base_sparse (bool interleaved, mxClassID id, mwSize m, mwSize n, + mwSize nzmax, mxComplexity flag = mxREAL) : mxArray_matlab (interleaved, id, m, n), m_complex (flag == mxCOMPLEX), m_nzmax (nzmax > 0 ? nzmax : 1), @@ -2106,9 +2216,9 @@ m_jc (static_cast (mxArray::calloc (n + 1, sizeof (mwIndex)))) { } -private: - - mxArray_sparse (const mxArray_sparse& val) +protected: + + mxArray_base_sparse (const mxArray_base_sparse& val) : mxArray_matlab (val), m_nzmax (val.m_nzmax), m_pr (mxArray::malloc (m_nzmax * get_element_size ())), m_pi (m_interleaved @@ -2139,14 +2249,14 @@ // No assignment! FIXME: should this be implemented? Note that we // do have a copy constructor. - mxArray_sparse& operator = (const mxArray_sparse&); + mxArray_base_sparse& operator = (const mxArray_base_sparse&); mxArray_base * dup (void) const { - return new mxArray_sparse (*this); + return new mxArray_base_sparse (*this); } - ~mxArray_sparse (void) + ~mxArray_base_sparse (void) { mxFree (m_pr); mxFree (m_pi); @@ -2327,6 +2437,66 @@ mwIndex *m_jc; }; +class mxArray_interleaved_sparse : public mxArray_base_sparse +{ +public: + + mxArray_interleaved_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, + mxComplexity flag = mxREAL) + : mxArray_base_sparse (true, id, m, n, nzmax, flag) + { } + +private: + + mxArray_interleaved_sparse (const mxArray_interleaved_sparse& val) + : mxArray_base_sparse (val) + { } + +public: + + // No assignment! FIXME: should this be implemented? Note that we + // do have a copy constructor. + + mxArray_interleaved_sparse& operator = (const mxArray_interleaved_sparse&); + + mxArray_base * dup (void) const + { + return new mxArray_interleaved_sparse (*this); + } + + ~mxArray_interleaved_sparse (void) = default; +}; + +class mxArray_separate_sparse : public mxArray_base_sparse +{ +public: + + mxArray_separate_sparse (mxClassID id, mwSize m, mwSize n, mwSize nzmax, + mxComplexity flag = mxREAL) + : mxArray_base_sparse (false, id, m, n, nzmax, flag) + { } + +private: + + mxArray_separate_sparse (const mxArray_separate_sparse& val) + : mxArray_base_sparse (val) + { } + +public: + + // No assignment! FIXME: should this be implemented? Note that we + // do have a copy constructor. + + mxArray_separate_sparse& operator = (const mxArray_separate_sparse&); + + mxArray_base * dup (void) const + { + return new mxArray_separate_sparse (*this); + } + + ~mxArray_separate_sparse (void) = default; +}; + // Matlab-style struct arrays. class mxArray_struct : public mxArray_matlab @@ -2802,52 +2972,76 @@ mxArray::create_rep (bool interleaved, mxClassID id, mwSize ndims, const mwSize *dims, mxComplexity flag, bool init) { - return new mxArray_number (interleaved, id, ndims, dims, flag, init); + if (interleaved) + return new mxArray_interleaved_full (id, ndims, dims, flag, init); + else + return new mxArray_separate_full (id, ndims, dims, flag, init); } mxArray_base * mxArray::create_rep (bool interleaved, mxClassID id, const dim_vector& dv, mxComplexity flag) { - return new mxArray_number (interleaved, id, dv, flag); + if (interleaved) + return new mxArray_interleaved_full (id, dv, flag); + else + return new mxArray_separate_full (id, dv, flag); } mxArray_base * mxArray::create_rep (bool interleaved, mxClassID id, mwSize m, mwSize n, mxComplexity flag, bool init) { - return new mxArray_number (interleaved, id, m, n, flag, init); + if (interleaved) + return new mxArray_interleaved_full (id, m, n, flag, init); + else + return new mxArray_separate_full (id, m, n, flag, init); } mxArray_base * mxArray::create_rep (bool interleaved, mxClassID id, double val) { - return new mxArray_number (interleaved, id, val); + if (interleaved) + return new mxArray_interleaved_full (id, val); + else + return new mxArray_separate_full (id, val); } mxArray_base * mxArray::create_rep (bool interleaved, mxClassID id, mxLogical val) { - return new mxArray_number (interleaved, id, val); + if (interleaved) + return new mxArray_interleaved_full (id, val); + else + return new mxArray_separate_full (id, val); } mxArray_base * mxArray::create_rep (bool interleaved, const char *str) { - return new mxArray_number (interleaved, str); + if (interleaved) + return new mxArray_interleaved_full (str); + else + return new mxArray_separate_full (str); } mxArray_base * mxArray::create_rep (bool interleaved, mwSize m, const char **str) { - return new mxArray_number (interleaved, m, str); + if (interleaved) + return new mxArray_interleaved_full (m, str); + else + return new mxArray_separate_full (m, str); } mxArray_base * mxArray::create_rep (bool interleaved, mxClassID id, mwSize m, mwSize n, mwSize nzmax, mxComplexity flag) { - return new mxArray_sparse (interleaved, id, m, n, nzmax, flag); + if (interleaved) + return new mxArray_interleaved_sparse (id, m, n, nzmax, flag); + else + return new mxArray_separate_sparse (id, m, n, nzmax, flag); } void