From f166244f7e615d714b08c3fa54b6314216e467c6 Mon Sep 17 00:00:00 2001 From: Oliver Sander Date: Fri, 3 Jan 2025 17:59:28 +0100 Subject: [PATCH 1/3] adouble: Implement move constructor --- ADOL-C/include/adolc/adouble.h | 1 + ADOL-C/src/adouble.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/ADOL-C/include/adolc/adouble.h b/ADOL-C/include/adolc/adouble.h index d6ba8b74..0365d592 100644 --- a/ADOL-C/include/adolc/adouble.h +++ b/ADOL-C/include/adolc/adouble.h @@ -275,6 +275,7 @@ class ADOLC_DLL_EXPORT adouble : public badouble { public: adouble(const adub &); adouble(const adouble &); + adouble(adouble &&) noexcept; adouble(void); adouble(double); /* adub prevents postfix operators to occur on the left diff --git a/ADOL-C/src/adouble.cpp b/ADOL-C/src/adouble.cpp index 030f6c83..fac72120 100644 --- a/ADOL-C/src/adouble.cpp +++ b/ADOL-C/src/adouble.cpp @@ -213,6 +213,18 @@ adouble::adouble(const adouble &a) { #endif } +/*--------------------------------------------------------------------------*/ +adouble::adouble(adouble &&a) noexcept { + // Take data from 'a' + location = a.loc(); + + // If 'a' wasn't initialized, this one isn't initialized either. + isInit = a.isInit; + + // Make 'a' not own the data anymore + a.isInit = false; +} + /*--------------------------------------------------------------------------*/ adouble::adouble(const adub &a) { location = next_loc(); From ce438d10a7fa381547d4ecb341d658469fb6edf3 Mon Sep 17 00:00:00 2001 From: Oliver Sander Date: Fri, 3 Jan 2025 18:05:15 +0100 Subject: [PATCH 2/3] adouble: Implement move-assignment --- ADOL-C/include/adolc/adouble.h | 1 + ADOL-C/src/adouble.cpp | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/ADOL-C/include/adolc/adouble.h b/ADOL-C/include/adolc/adouble.h index 0365d592..fdce3a8d 100644 --- a/ADOL-C/include/adolc/adouble.h +++ b/ADOL-C/include/adolc/adouble.h @@ -294,6 +294,7 @@ class ADOLC_DLL_EXPORT adouble : public badouble { adouble &operator=(double); adouble &operator=(const badouble &); adouble &operator=(const adouble &); + adouble &operator=(adouble &&); adouble &operator=(const adub &); adouble &operator=(const pdouble &); diff --git a/ADOL-C/src/adouble.cpp b/ADOL-C/src/adouble.cpp index fac72120..e463d453 100644 --- a/ADOL-C/src/adouble.cpp +++ b/ADOL-C/src/adouble.cpp @@ -635,6 +635,26 @@ badouble &badouble::operator=(const adub &a) { return *this; } +/*--------------------------------------------------------------------------*/ +/* r-value assignment */ +adouble &adouble::operator=(adouble &&a) { + // Destruct the old content of this adouble + if (isInit) { + free_loc(location); + } + + // Set to new content + location = a.loc(); + + // If 'a' wasn't initialized, this one isn't initialized either. + isInit = a.isInit; + + // Make sure that data is not touched when 'a' gets destructed + a.isInit = false; + + return (*this); +} + /*--------------------------------------------------------------------------*/ /* Assign an adouble an adub */ /* olvo 980517 new version griewank */ From db8ee93e4638c5830356f0608c665bf9c071b4f8 Mon Sep 17 00:00:00 2001 From: Oliver Sander Date: Fri, 3 Jan 2025 18:11:21 +0100 Subject: [PATCH 3/3] Really move the data when assigning adub to adouble The adub data type is used to only store temporary values, and once an adub object is assigned to an adouble object it shall never be used again. Therefore, assignment of adub to adouble can be implemented just like move-assignment, without having to touch the tape at all. For this to work, the method signature has to change from (const adub&) to (adub&), because the value that is assigned is now modified (it is invalidated). --- ADOL-C/include/adolc/adouble.h | 3 +- ADOL-C/src/adouble.cpp | 93 +++++++--------------------------- 2 files changed, 18 insertions(+), 78 deletions(-) diff --git a/ADOL-C/include/adolc/adouble.h b/ADOL-C/include/adolc/adouble.h index fdce3a8d..b1ad23a0 100644 --- a/ADOL-C/include/adolc/adouble.h +++ b/ADOL-C/include/adolc/adouble.h @@ -107,7 +107,6 @@ class ADOLC_DLL_EXPORT badouble { void declareDependent(); badouble &operator=(double); badouble &operator=(const badouble &); - badouble &operator=(const adub &); double getValue() const; inline double value() const { return getValue(); } explicit operator double(); @@ -295,7 +294,7 @@ class ADOLC_DLL_EXPORT adouble : public badouble { adouble &operator=(const badouble &); adouble &operator=(const adouble &); adouble &operator=(adouble &&); - adouble &operator=(const adub &); + adouble &operator=(adub &); adouble &operator=(const pdouble &); inline locint loc(void) const; diff --git a/ADOL-C/src/adouble.cpp b/ADOL-C/src/adouble.cpp index e463d453..391a4c7b 100644 --- a/ADOL-C/src/adouble.cpp +++ b/ADOL-C/src/adouble.cpp @@ -562,78 +562,6 @@ adouble &adouble::operator=(const adouble &x) { (*this).badouble::operator=(x); return (*this); } -/*--------------------------------------------------------------------------*/ -/* Assign an adouble an adub */ -/* olvo 980517 new version griewank */ -badouble &badouble::operator=(const adub &a) { - locint a_loc = a.loc(); - ADOLC_OPENMP_THREAD_NUMBER; - ADOLC_OPENMP_GET_THREAD_NUMBER; - int upd = 0; - /* 981020 olvo skip upd_resloc(..) if no tracing performed */ - if (ADOLC_CURRENT_TAPE_INFOS.traceFlag) -#if defined(ADOLC_TRACK_ACTIVITY) - upd = upd_resloc_check(a_loc, loc()); -#else - upd = upd_resloc(a_loc, loc()); -#endif - if (upd) { /* olvo 980708 new n2l & 980921 changed interface */ -#if defined(ADOLC_TRACK_ACTIVITY) - free_loc(location); - location = a_loc; - const_cast(a).isInit = false; -#else - revreal tempVal = ADOLC_GLOBAL_TAPE_VARS.store[a_loc]; - if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors) - ADOLC_OVERWRITE_SCAYLOR(ADOLC_GLOBAL_TAPE_VARS.store[loc()], - &ADOLC_GLOBAL_TAPE_VARS.store[a_loc]); - ADOLC_GLOBAL_TAPE_VARS.store[loc()] = tempVal; -#endif - } else { - if (ADOLC_CURRENT_TAPE_INFOS - .traceFlag) { // old: write_assign_a(loc(),a_loc); -#if defined(ADOLC_TRACK_ACTIVITY) - if (ADOLC_GLOBAL_TAPE_VARS.actStore[a_loc]) { -#endif - put_op(assign_a); - ADOLC_PUT_LOCINT(a_loc); // = arg - ADOLC_PUT_LOCINT(loc()); // = res - - ++ADOLC_CURRENT_TAPE_INFOS.numTays_Tape; - if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors) - ADOLC_WRITE_SCAYLOR(ADOLC_GLOBAL_TAPE_VARS.store[loc()]); -#if defined(ADOLC_TRACK_ACTIVITY) - } else { - if (ADOLC_GLOBAL_TAPE_VARS.actStore[location]) { - double coval = ADOLC_GLOBAL_TAPE_VARS.store[a_loc]; - if (coval == 0) { - put_op(assign_d_zero); - ADOLC_PUT_LOCINT(location); // = res - } else if (coval == 1.0) { - put_op(assign_d_one); - ADOLC_PUT_LOCINT(location); // = res - } else { - put_op(assign_d); - ADOLC_PUT_LOCINT(location); // = res - ADOLC_PUT_VAL(coval); // = coval - } - - ++ADOLC_CURRENT_TAPE_INFOS.numTays_Tape; - if (ADOLC_CURRENT_TAPE_INFOS.keepTaylors) - ADOLC_WRITE_SCAYLOR(ADOLC_GLOBAL_TAPE_VARS.store[loc()]); - } - } -#endif - } - ADOLC_GLOBAL_TAPE_VARS.store[loc()] = ADOLC_GLOBAL_TAPE_VARS.store[a_loc]; -#if defined(ADOLC_TRACK_ACTIVITY) - ADOLC_GLOBAL_TAPE_VARS.actStore[loc()] = - ADOLC_GLOBAL_TAPE_VARS.actStore[a_loc]; -#endif - } - - return *this; -} /*--------------------------------------------------------------------------*/ /* r-value assignment */ @@ -656,11 +584,24 @@ adouble &adouble::operator=(adouble &&a) { } /*--------------------------------------------------------------------------*/ -/* Assign an adouble an adub */ +/* Move an adouble an adub */ +/* This treats the input adub as an r-value: It becomes unusable at the end of this method. */ /* olvo 980517 new version griewank */ -adouble &adouble::operator=(const adub &a) { - this->loc(); // call for late init - (*this).badouble::operator=(a); +adouble &adouble::operator=(adub &a) { + // Destruct the old content of this adouble + if (isInit) { + free_loc(location); + } + + // Set to new content + location = a.loc(); + + // If 'a' wasn't initialized, this one isn't initialized either. + isInit = a.isInit; + + // Make the data is not touched when 'a' gets destructed + a.isInit = false; + return (*this); }