From 8bbbaa5bae6c19d3d388de277f37feedcf01e4f4 Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Wed, 3 Apr 2024 22:12:08 +0200 Subject: [PATCH] copyonwrite() on nested LA types will recursively call element copyonwrites even if the top type had count=1 --- mat.h | 12 ++++++++++-- smat.h | 12 ++++++++++-- sparsemat.cc | 14 +++++++++++++- sparsemat.h | 2 +- vec.h | 11 +++++++++-- 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/mat.h b/mat.h index 5dbbf25..c76902b 100644 --- a/mat.h +++ b/mat.h @@ -126,7 +126,7 @@ public: inline int getcount() const {return count?*count:0;} //! ensure that the data of this matrix are referenced exactly once - void copyonwrite(bool detachonly=false); + void copyonwrite(bool detachonly=false, bool deep=true); //! permute matrix elements const NRMat permuted_rows(const NRPerm &p, const bool inverse=false) const; @@ -1107,7 +1107,7 @@ NRMat & NRMat::operator|=(const NRMat &rhs) { * @see NRMat::count, NRMat::operator|=() ******************************************************************************/ template -void NRMat::copyonwrite(bool detachonly) { +void NRMat::copyonwrite(bool detachonly, bool deep) { if(!count) { if(nn||mm) laerror("nonempty matrix without reference count encountered"); @@ -1115,6 +1115,14 @@ void NRMat::copyonwrite(bool detachonly) { return; } + if(*count == 1 && !LA_traits::is_plaindata() && !detachonly &&deep) //type-nested copyonwrite + { +#ifdef CUDALA + if(location != cpu) laerror("nested types not supported on gpu memory"); +#endif + for(int i=0; i::copyonwrite(v[i]); + } + if(*count > 1){ (*count)--; count = new int; diff --git a/smat.h b/smat.h index 355d55a..424c115 100644 --- a/smat.h +++ b/smat.h @@ -168,7 +168,7 @@ public: void get(int fd, bool dimensions = 1, bool transp = 0); void put(int fd, bool dimensions = 1, bool transp = 0) const; - void copyonwrite(bool detachonly=false); + void copyonwrite(bool detachonly=false, bool deep=true); void clear() {copyonwrite(LA_traits::is_plaindata()); LA_traits::clear(v,NN2);}; //zero out void resize(const int n); @@ -984,13 +984,21 @@ NRSMat & NRSMat::operator=(const NRSMat & rhs) { * @see NRSMat::operator|=, NRSMat::copyonwrite() ******************************************************************************/ template -void NRSMat::copyonwrite(bool detachonly) { +void NRSMat::copyonwrite(bool detachonly, bool deep) { if(!count) { if(nn) laerror("nonempty smat without reference count encountered"); if(_LA_warn_empty_copyonwrite) std::cout <<"Warning: copyonwrite of empty smat\n"; return; } + if(*count == 1 && !LA_traits::is_plaindata() && !detachonly && deep) //type-nested copyonwrite + { +#ifdef CUDALA + if(location != cpu) laerror("nested types not supported on gpu memory"); +#endif + for(int i=0; i::copyonwrite(v[i]); + } + if(*count > 1){ (*count)--; count = new int; diff --git a/sparsemat.cc b/sparsemat.cc index 6dc3ac6..586014d 100644 --- a/sparsemat.cc +++ b/sparsemat.cc @@ -143,7 +143,7 @@ while(l) } template -void SparseMat::copyonwrite(bool detachonly) +void SparseMat::copyonwrite(bool detachonly, bool deep) { if(!count) { @@ -152,6 +152,18 @@ void SparseMat::copyonwrite(bool detachonly) return; } + if(*count == 1 && !LA_traits::is_plaindata() && !detachonly && deep) //type-nested copyonwrite + { + matel *l =list; + while(l) + { + LA_traits::copyonwrite(l->elem); + l=l->next; + } + + } + + if(*count > 1) { (*count)--; diff --git a/sparsemat.h b/sparsemat.h index 69d2c35..dcfd509 100644 --- a/sparsemat.h +++ b/sparsemat.h @@ -139,7 +139,7 @@ public: void setunsymmetric();//unwind the matrix assuming it was indeed symmetric inline bool issymmetric() const {return symmetric;} unsigned int length() const; - void copyonwrite(bool detachonly=false); + void copyonwrite(bool detachonly=false, bool deep=true); void clear() {copyonwrite(LA_traits::is_plaindata()); if(count) {delete count; count=NULL;}} void simplify(const double sparseepsilon=SPARSEEPSILON); const T trace() const; diff --git a/vec.h b/vec.h index bb2443c..34b5b0f 100644 --- a/vec.h +++ b/vec.h @@ -177,7 +177,7 @@ public: #endif //! create separate copy of the data corresponding to this vector - void copyonwrite(bool detachonly=false); + void copyonwrite(bool detachonly=false, bool deep=true); //! purge this vector void clear() { copyonwrite(LA_traits::is_plaindata()); LA_traits::clear(v, nn); }; @@ -1127,13 +1127,20 @@ NRVec::~NRVec() { * make own copy of the underlying data connected with this vector ******************************************************************************/ template -void NRVec::copyonwrite(bool detachonly) { +void NRVec::copyonwrite(bool detachonly,bool deep) { if(!count) { if(nn) laerror("nonempty vector without reference count encountered"); if(_LA_warn_empty_copyonwrite) std::cout <<"Warning: copyonwrite of empty vector\n"; return; } + if(*count == 1 && !LA_traits::is_plaindata() && !detachonly && deep) //type-nested copyonwrite + { +#ifdef CUDALA + if(location != cpu) laerror("nested types not supported on gpu memory"); +#endif + for(int i=0; i::copyonwrite(v[i]); + } if(*count > 1) { (*count)--; count = new int;