diff --git a/build_linux64/libamscppnarray.linux64.a b/build_linux64/libamscppnarray.linux64.a index 04e2098..eb22e83 100644 Binary files a/build_linux64/libamscppnarray.linux64.a and b/build_linux64/libamscppnarray.linux64.a differ diff --git a/build_linux64/objstore/amscppnarray.o b/build_linux64/objstore/amscppnarray.o index 20758ff..c482dc4 100644 Binary files a/build_linux64/objstore/amscppnarray.o and b/build_linux64/objstore/amscppnarray.o differ diff --git a/build_linux64/tests b/build_linux64/tests index 1beebae..1953c10 100644 Binary files a/build_linux64/tests and b/build_linux64/tests differ diff --git a/include/amscppnarray/amscppnarray.hpp b/include/amscppnarray/amscppnarray.hpp index 70ec991..9bce8c9 100644 --- a/include/amscppnarray/amscppnarray.hpp +++ b/include/amscppnarray/amscppnarray.hpp @@ -14,6 +14,10 @@ namespace ams namespace narray { +// Forward declaration of the operator- template function +template class narray; +template narray operator-(const narray &n); + typedef int64_t narray_size_t; static const int narray_success = 1; @@ -33,9 +37,14 @@ template class narray narray(); narray(const narray& other); + narray(narray&& other) noexcept; + narray& operator=(const narray& other); + narray& operator=(narray&& other) noexcept; + narray& operator=(const std::vector& other); narray(const std::initializer_list initlist); + narray& operator=(const std::initializer_list initlist); ~narray(); int resize(const narray_size_t newlength); @@ -49,18 +58,35 @@ template class narray void setall(const T& val); //sets all elements to val //Comparators + bool operator==(const narray& other) const; + bool operator!=(const narray& other) const; //Operations - + narray operator+(const narray& other) const; + narray operator-(const narray& other) const; + narray operator*(const narray& other) const; + narray operator/(const narray& other) const; + narray operator+(const T val) const; + narray operator-(const T val) const; + narray operator*(const T val) const; + narray operator/(const T val) const; + template friend narray operator-(const narray &n); + + //subarray operations + + //permutations and sorting }; void test_narray1(); +void test_narray2(); +void test_narray3(); }; //end namespace narray }; //end namespace ams #include +#include #endif \ No newline at end of file diff --git a/include/amscppnarray/amscppnarray_impl.hpp b/include/amscppnarray/amscppnarray_impl.hpp index b766755..30b6a56 100644 --- a/include/amscppnarray/amscppnarray_impl.hpp +++ b/include/amscppnarray/amscppnarray_impl.hpp @@ -8,6 +8,8 @@ namespace narray template narray::narray() { + //printf("debug: constructor called for %p.\n",this); + length = 0; data = NULL; @@ -59,6 +61,8 @@ template narray::narray(const narray& other) length = 0; data = NULL; + //printf("debug: copy constructor called for\n\t%p\n\t%p\n", this, &other); + if(this!=&other) { res = this->resize(other.length); @@ -76,12 +80,48 @@ template narray::narray(const narray& other) } } +template narray::narray(narray&& other) noexcept +{ + //this is a move operator + //I still need to understand when these are called. + + //printf("debug: move constructor called for\n\t%p\n\t%p\n", this, &other); + + //steal the resources from other and reset other to prevent double deletion + length = other.length; + data = other.data; + + other.length = 0; + other.data = NULL; + + return; +} + +template narray& narray::operator=(narray&& other) noexcept +{ + + //printf("debug: move= called for\n\t%p\n\t%p\n", this, &other); + + if(this!=&other) + { + if(data!=NULL) {delete[] data; data=NULL;} + + length = other.length; + data = other.data; + + other.length = 0; + other.data = NULL; + } + return *this; +} template narray& narray::operator=(const narray& other) { narray_size_t I; int res; + //printf("debug: operator= called for\n\t%p\n\t%p\n", this, &other); + if(this!=&other) { res = this->resize(other.length); @@ -116,7 +156,7 @@ template narray& narray::operator=(const std::vector& other { for(I=0;I narray::narray(const std::initializer_list initlist) } } +template narray& narray::operator=(const std::initializer_list initlist) +{ + narray_size_t I; + int res; + + res = this->resize(initlist.size()); + if(res!=narray_success) + { + this->length = 0; + if(this->data != NULL) {delete[] this->data; this->data=NULL;} + return *this; + } + else + { + I = 0; + for(T elem : initlist) + { + data[I] = elem; + if(I narray::~narray() { + //printf("debug: destructor called for %p\n",this); length = 0; if(data!=NULL) {delete[] data; data=NULL;} return; @@ -179,10 +245,27 @@ template void narray::clear() return; } +template void narray_setall_tf(narray *q, const T& val, int threadnum, int nthreads) +{ + int I0,I1,Is,I; + + Is = q->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? q->length: Is*(threadnum+1); + for(I=I0;Idata[I] = val; + } + + return; +} + template void narray::setall(const T& val) { narray_size_t I; + int J; int nthreads; + std::vector threads; if(length void narray::setall(const T& val) else { //threaded operation - nthreads = std::thread::hardware_concurrency; - + nthreads = std::thread::hardware_concurrency(); + if(nthreads<1) nthreads=1; + if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J,this,val,J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } } return; } diff --git a/include/amscppnarray/amscppnarray_imploper.hpp b/include/amscppnarray/amscppnarray_imploper.hpp new file mode 100644 index 0000000..9efc485 --- /dev/null +++ b/include/amscppnarray/amscppnarray_imploper.hpp @@ -0,0 +1,736 @@ +#ifndef __AMSCPPNARRAY_IMPLOPER_HPP__ +#define __AMSCPPNARRAY_IMPLOPER_HPP__ + +namespace ams +{ +namespace narray +{ + + template void narray_operator_comp_tf( + const narray *a, + const narray *b, + narray *cmp, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + cmp->data[threadnum] = 1; + for(I=I0;Idata[I]!=b->data[I]) + { + cmp->data[threadnum] = 0; + break; + } + } + return; + } + + template bool narray::operator==(const narray& other) const + { + bool ret = 1; + narray cmp; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(this->length != other.length) + { + ret = 0; + return ret; + } + if(this->length == 0) + { + ret = 1; + return ret; + } + if(this->length < narray_thread_sz) + { + for(I=0;Ilength;I++) + { + if(this->data[I]!=other.data[I]) + { + ret = 0; + break; + } + } + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + cmp.resize(nthreads); + for(J=0;J, + this, + &other, + &cmp, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + + ret = 1; + for(J=0;J bool narray::operator!=(const narray& other) const + { + return !(*this==other); + } + + template void narray_operator_add_tf( + const narray *a, + const narray *b, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] + b->data[I]; + } + + return; + } + + template narray narray::operator+(const narray& other) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(this->length!=other.length) + { + ret.resize(0); + printf("narray::operator+:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length); + } + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] + other.data[I]; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + &other, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_sub_tf( + const narray *a, + const narray *b, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] - b->data[I]; + } + + return; + } + + template narray narray::operator-(const narray& other) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(this->length!=other.length) + { + ret.resize(0); + printf("narray::operator-:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length); + } + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] + other.data[I]; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + &other, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_mult_tf( + const narray *a, + const narray *b, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] * b->data[I]; + } + + return; + } + + template narray narray::operator*(const narray& other) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(this->length!=other.length) + { + ret.resize(0); + printf("narray::operator*:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length); + } + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] * other.data[I]; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + &other, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_div_tf( + const narray *a, + const narray *b, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] / b->data[I]; + } + + return; + } + + template narray narray::operator/(const narray& other) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + if(this->length!=other.length) + { + ret.resize(0); + printf("narray::operator/:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length); + } + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] / other.data[I]; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + &other, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_add2_tf( + const narray *a, + const T val, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] + val; + } + + return; + } + + template narray narray::operator+(const T val) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] + val; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + val, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_sub2_tf( + const narray *a, + const T val, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] - val; + } + + return; + } + + template narray narray::operator-(const T val) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] - val; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + val, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_mult2_tf( + const narray *a, + const T val, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] * val; + } + + return; + } + + template narray narray::operator*(const T val) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] * val; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + val, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + template void narray_operator_div2_tf( + const narray *a, + const T val, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = a->data[I] / val; + } + + return; + } + + template narray narray::operator/(const T val) const + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + ret.resize(this->length); + + if(this->lengthlength;I++) ret.data[I] = this->data[I] / val; + } + else + { + //threaded operation + nthreads = std::thread::hardware_concurrency(); + nthreads = (nthreads<1) ? 1 : nthreads; + nthreads = (nthreads>narray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + this, + val, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + + + template void narray_operator_negative_tf( + const narray *a, + narray *out, + int threadnum, int nthreads + ) + { + int I0,I1,Is,I; + + Is = a->length/nthreads; + I0 = Is*threadnum; + I1 = (threadnum>=(nthreads-1))? a->length: Is*(threadnum+1); + for(I=I0;Idata[I] = -a->data[I]; + } + + return; + } + + template narray operator-(const narray &n) + { + narray ret; + narray_size_t I; + int J; + int nthreads; + std::vector threads; + + ret.resize(n.length); + + if(n.lengthnarray_max_threads) ? narray_max_threads : nthreads; + //if(nthreads<1) nthreads=1; + //if(nthreads>narray_max_threads) nthreads = narray_max_threads; + threads.resize(nthreads); + for(J=0;J, + &n, + &ret, + J,nthreads + ); + } + for(J=0;Jjoin(); + delete threads[J]; + threads[J]= NULL; + } + } + } + return ret; + } + +}; //end namespace narray +}; //end namespace ams + +#endif \ No newline at end of file diff --git a/src/amscppnarray/amscppnarray.cpp b/src/amscppnarray/amscppnarray.cpp index d962e01..7458e9d 100644 --- a/src/amscppnarray/amscppnarray.cpp +++ b/src/amscppnarray/amscppnarray.cpp @@ -5,12 +5,97 @@ namespace ams namespace narray { + void test_narray1() { - + int I; + narray a; + narray *b = NULL; + narray tmp; + + b = new(std::nothrow) narray(); + a.resize(100); + b->resize(100000); + a.setall(2.5f); + b->setall(3.0f); + + for(I=0;I<100000;I++) + { + if(b->at(I)!=3.0f) + { + printf("Error: b[%d]=%1.3f, not %1.3f\n",I,b->at(I),3.0f); + break; + } + } + + a.resize(100000); + + tmp = a; + a = *b; + *b = tmp; + + *b = tmp+a; + for(I=0;Ilength;I++) + { + if(b->at(I) != tmp[I] + a[I]) + { + printf("addition error in index %d",I); + } + } + + printf("threaded boolean test: %d\n", (*b==(a+tmp))); + + + + delete b; + return; } +void test_narray2() +{ + int I; + narray a,b,c,d; + + a.resize(100000); a.setall(1.0f); + b.resize(100000); for(I=0;I a,b,c,d; + + a.resize(5); a.setall(1.0f); + b = {0,0.25,0.5,0.675,0.8675}; + c.resize(5); c.setall(2.0f); + + d = -a*(b+c); + for(I=0;I<5;I++) + { + printf("d[%d]=%1.3f\n",I,d[I]); + + } + + printf("d==-a*(b+c):%d\n",d==(-a*(b+c))); + d[4] = 0.0f; + printf("d==-a*(b+c):%d\n",d==(-a*(b+c))); + +} + }; //end namespace narray }; //end namespace ams \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a24d585..fc25301 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,7 +4,9 @@ int main(int argc, char* argv[]) { int ret = 0; printf("ams c++ numeric array library tests.\n"); - ams::narray::test_narray1(); + //ams::narray::test_narray1(); + //ams::narray::test_narray2(); + ams::narray::test_narray3(); return ret; } \ No newline at end of file