From 5480de6ff21c3d153f39dab2d88a3a1827a722de Mon Sep 17 00:00:00 2001 From: Jiri Pittner Date: Wed, 9 Jun 2021 15:33:24 +0200 Subject: [PATCH] suport for data preserving in NRVec::resize --- la_traits.h | 9 +++++ t.cc | 4 +-- vec.h | 101 ++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 86 insertions(+), 28 deletions(-) diff --git a/la_traits.h b/la_traits.h index 7d82146..7ff8c87 100644 --- a/la_traits.h +++ b/la_traits.h @@ -81,6 +81,10 @@ template class NRSMat_from1; template class SparseMat; template class SparseSMat; template class CSRMat; +template class NRPerm; +template class CyclePerm; +template class Partition; +template class CompressedPartition; //trick to allow real and imag part of complex as l-values template @@ -375,6 +379,11 @@ generate_traits(NRVec_from1) generate_traits(SparseMat) generate_traits(SparseSMat) //product leading to non-symmetric result not implemented generate_traits(CSRMat) +generate_traits(NRPerm) +generate_traits(CyclePerm) +generate_traits(Partition) +generate_traits(CompressedPartition) + #undef generate_traits diff --git a/t.cc b/t.cc index 6634357..7fb9227 100644 --- a/t.cc +++ b/t.cc @@ -2146,7 +2146,7 @@ int tot=p.generate_all_lex(printme); cout <<"generated "<>n >>unitary_n; @@ -2158,7 +2158,7 @@ if(tot!=partitions(n)) laerror("internal error in partition generation or enumer if(space_dim!=longpow(unitary_n,n)) {cout<>n ; diff --git a/vec.h b/vec.h index 5fd193e..0a09195 100644 --- a/vec.h +++ b/vec.h @@ -299,8 +299,8 @@ public: //! determine the number of elements inline int size() const; - //! resize the current vector - void resize(const int n); + //! resize the current vector, optionally preserving data + void resize(const int n, const bool preserve=false); //!deallocate the current vector void dealloc(void) {resize(0);} @@ -965,14 +965,25 @@ NRVec & NRVec::operator=(const NRVec &rhs) { * @param[in] n requested size ******************************************************************************/ template -void NRVec::resize(const int n) { +void NRVec::resize(const int n, const bool preserve) +{ #ifdef DEBUG - if(n < 0) laerror("illegal dimension"); + if(n < 0) laerror("illegal dimension in NRVec::resize"); #endif - if(count){ - if(n == 0){ - if(--(*count) <= 0){ - if(v){ +if(preserve && n::resize(const int n) { gpufree(v); } #endif - } + } delete count; - } + } count = 0; nn = 0; v = 0; return; - } - if(*count > 1) { + } + if(*count > 1) //detach from shared data + { (*count)--; count = 0; + vold=v; v = 0; + nnold=nn; nn = 0; + preserved=true; + } } - } - if(!count){ + if(!count) //we were not allocated or we just detached + { count = new int; *count = 1; nn = n; @@ -1009,25 +1025,58 @@ void NRVec::resize(const int n) { else v = (T*) gpualloc(nn*sizeof(T)); #endif + if(preserved && preserve) goto do_preserve; return; - } - // *count = 1 in this branch - if (n != nn) { - nn = n; + } +// *count == 1 in this branch +if (n == nn) return; //nothing to do +nnold=nn; +nn = n; #ifdef CUDALA - if(location == cpu){ + if(location == cpu) + { #endif - - delete[] v; + if(preserve) {vold=v; do_delete=true;} else delete[] v; v = new T[nn]; #ifdef CUDALA - }else{ - - gpufree(v); + } + else + { + if(preserve) {vold=v; do_delete=true;} else gpufree(v); v = (T*) gpualloc(nn*sizeof(T)); - } + } #endif - } + +if(!preserve) return; + +//copy data from old location and zero excess allocated memory +do_preserve: +if(!preserve || !preserved) laerror("assertion failed in NRVec::resize"); +// omit this check since we would need to have traits for presently unknown user defined classes +// if(!LA_traits::is_plaindata()) laerror("do not know how to preserve non-plain data"); +if(nnold>=nn) laerror("assertion2 failed in NRVec::resize"); + +#ifdef CUDALA +if(location == cpu) + { +#endif + for(int i=0; i