master
madrocketsci 4 weeks ago
parent 89210c99cb
commit 8a9f679a6c

Binary file not shown.

@ -14,6 +14,10 @@ namespace ams
namespace narray
{
// Forward declaration of the operator- template function
template<typename T> class narray;
template<typename T> narray<T> operator-(const narray<T> &n);
typedef int64_t narray_size_t;
static const int narray_success = 1;
@ -33,9 +37,14 @@ template<typename T> class narray
narray();
narray(const narray<T>& other);
narray(narray<T>&& other) noexcept;
narray<T>& operator=(const narray<T>& other);
narray<T>& operator=(narray<T>&& other) noexcept;
narray<T>& operator=(const std::vector<T>& other);
narray(const std::initializer_list<T> initlist);
narray<T>& operator=(const std::initializer_list<T> initlist);
~narray();
int resize(const narray_size_t newlength);
@ -49,18 +58,35 @@ template<typename T> class narray
void setall(const T& val); //sets all elements to val
//Comparators
bool operator==(const narray<T>& other) const;
bool operator!=(const narray<T>& other) const;
//Operations
narray<T> operator+(const narray<T>& other) const;
narray<T> operator-(const narray<T>& other) const;
narray<T> operator*(const narray<T>& other) const;
narray<T> operator/(const narray<T>& other) const;
narray<T> operator+(const T val) const;
narray<T> operator-(const T val) const;
narray<T> operator*(const T val) const;
narray<T> operator/(const T val) const;
template<class U> friend narray<U> operator-(const narray<U> &n);
//subarray operations
//permutations and sorting
};
void test_narray1();
void test_narray2();
void test_narray3();
}; //end namespace narray
}; //end namespace ams
#include <amscppnarray/amscppnarray_impl.hpp>
#include <amscppnarray/amscppnarray_imploper.hpp>
#endif

@ -8,6 +8,8 @@ namespace narray
template<typename T> narray<T>::narray()
{
//printf("debug: constructor called for %p.\n",this);
length = 0;
data = NULL;
@ -59,6 +61,8 @@ template<typename T> narray<T>::narray(const narray<T>& 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<typename T> narray<T>::narray(const narray<T>& other)
}
}
template<typename T> narray<T>::narray(narray<T>&& 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<typename T> narray<T>& narray<T>::operator=(narray<T>&& 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<typename T> narray<T>& narray<T>::operator=(const narray<T>& 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<typename T> narray<T>& narray<T>::operator=(const std::vector<T>& other
{
for(I=0;I<length && I<other.size();I++)
{
data[I] = other.data[I];
data[I] = other[I];
}
}
}
@ -146,8 +186,34 @@ template<typename T> narray<T>::narray(const std::initializer_list<T> initlist)
}
}
template<typename T> narray<T>& narray<T>::operator=(const std::initializer_list<T> 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<length) I++;
}
}
return *this;
}
template<typename T> narray<T>::~narray()
{
//printf("debug: destructor called for %p\n",this);
length = 0;
if(data!=NULL) {delete[] data; data=NULL;}
return;
@ -179,10 +245,27 @@ template<typename T> void narray<T>::clear()
return;
}
template<typename T> void narray_setall_tf(narray<T> *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;I<I1;I++)
{
q->data[I] = val;
}
return;
}
template<typename T> void narray<T>::setall(const T& val)
{
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
if(length<narray_thread_sz)
{
@ -191,8 +274,25 @@ template<typename T> void narray<T>::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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_setall_tf<T>,this,val,J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return;
}

@ -0,0 +1,736 @@
#ifndef __AMSCPPNARRAY_IMPLOPER_HPP__
#define __AMSCPPNARRAY_IMPLOPER_HPP__
namespace ams
{
namespace narray
{
template<typename T> void narray_operator_comp_tf(
const narray<T> *a,
const narray<T> *b,
narray<bool> *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;I<I1;I++)
{
if(a->data[I]!=b->data[I])
{
cmp->data[threadnum] = 0;
break;
}
}
return;
}
template<typename T> bool narray<T>::operator==(const narray<T>& other) const
{
bool ret = 1;
narray<bool> cmp;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> 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;I<this->length;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<nthreads;J++)
{
//printf("debug: launching thread %d\n",J);
threads[J] = new(std::nothrow) std::thread(
&narray_operator_comp_tf<T>,
this,
&other,
&cmp,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
ret = 1;
for(J=0;J<nthreads;J++)
{
if(cmp[J]==0)
{
ret = 0;
break;
}
}
cmp.resize(0);
}
return ret;
}
template<typename T> bool narray<T>::operator!=(const narray<T>& other) const
{
return !(*this==other);
}
template<typename T> void narray_operator_add_tf(
const narray<T> *a,
const narray<T> *b,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] + b->data[I];
}
return;
}
template<typename T> narray<T> narray<T>::operator+(const narray<T>& other) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
if(this->length!=other.length)
{
ret.resize(0);
printf("narray<T>::operator+:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length);
}
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
//printf("debug: launching thread %d\n",J);
threads[J] = new(std::nothrow) std::thread(
&narray_operator_add_tf<T>,
this,
&other,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_sub_tf(
const narray<T> *a,
const narray<T> *b,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] - b->data[I];
}
return;
}
template<typename T> narray<T> narray<T>::operator-(const narray<T>& other) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
if(this->length!=other.length)
{
ret.resize(0);
printf("narray<T>::operator-:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length);
}
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_sub_tf<T>,
this,
&other,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_mult_tf(
const narray<T> *a,
const narray<T> *b,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] * b->data[I];
}
return;
}
template<typename T> narray<T> narray<T>::operator*(const narray<T>& other) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
if(this->length!=other.length)
{
ret.resize(0);
printf("narray<T>::operator*:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length);
}
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_mult_tf<T>,
this,
&other,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_div_tf(
const narray<T> *a,
const narray<T> *b,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] / b->data[I];
}
return;
}
template<typename T> narray<T> narray<T>::operator/(const narray<T>& other) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
if(this->length!=other.length)
{
ret.resize(0);
printf("narray<T>::operator/:: error - array sizes %ld and %ld are not the same.\n",(long)this->length,(long)other.length);
}
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_div_tf<T>,
this,
&other,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_add2_tf(
const narray<T> *a,
const T val,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] + val;
}
return;
}
template<typename T> narray<T> narray<T>::operator+(const T val) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_add2_tf<T>,
this,
val,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_sub2_tf(
const narray<T> *a,
const T val,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] - val;
}
return;
}
template<typename T> narray<T> narray<T>::operator-(const T val) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_sub2_tf<T>,
this,
val,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_mult2_tf(
const narray<T> *a,
const T val,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] * val;
}
return;
}
template<typename T> narray<T> narray<T>::operator*(const T val) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_mult2_tf<T>,
this,
val,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_div2_tf(
const narray<T> *a,
const T val,
narray<T> *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;I<I1;I++)
{
out->data[I] = a->data[I] / val;
}
return;
}
template<typename T> narray<T> narray<T>::operator/(const T val) const
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
ret.resize(this->length);
if(this->length<narray_thread_sz)
{
for(I=0;I<this->length;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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_div2_tf<T>,
this,
val,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
template<typename T> void narray_operator_negative_tf(
const narray<T> *a,
narray<T> *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;I<I1;I++)
{
out->data[I] = -a->data[I];
}
return;
}
template<class T> narray<T> operator-(const narray<T> &n)
{
narray<T> ret;
narray_size_t I;
int J;
int nthreads;
std::vector<std::thread*> threads;
ret.resize(n.length);
if(n.length<narray_thread_sz)
{
for(I=0;I<n.length;I++) ret.data[I] = -n.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<nthreads;J++)
{
threads[J] = new(std::nothrow) std::thread(
&narray_operator_negative_tf<T>,
&n,
&ret,
J,nthreads
);
}
for(J=0;J<nthreads;J++)
{
if(threads[J]!=NULL)
{
threads[J]->join();
delete threads[J];
threads[J]= NULL;
}
}
}
return ret;
}
}; //end namespace narray
}; //end namespace ams
#endif

@ -5,12 +5,97 @@ namespace ams
namespace narray
{
void test_narray1()
{
int I;
narray<float> a;
narray<float> *b = NULL;
narray<float> tmp;
b = new(std::nothrow) narray<float>();
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;I<b->length;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<float> a,b,c,d;
a.resize(100000); a.setall(1.0f);
b.resize(100000); for(I=0;I<b.length;I++) b[I] = 0.5f*I;
c.resize(100000); 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[50000] = 0.0f;
printf("d==-a*(b+c):%d\n",d==(-a*(b+c)));
}
void test_narray3()
{
int I;
narray<float> 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

@ -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;
}
Loading…
Cancel
Save