updates
This commit is contained in:
Binary file not shown.
Binary file not shown.
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;
|
||||
}
|
||||
|
736
include/amscppnarray/amscppnarray_imploper.hpp
Normal file
736
include/amscppnarray/amscppnarray_imploper.hpp
Normal file
@ -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;
|
||||
}
|
Reference in New Issue
Block a user