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
|
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;
|
typedef int64_t narray_size_t;
|
||||||
|
|
||||||
static const int narray_success = 1;
|
static const int narray_success = 1;
|
||||||
@ -33,9 +37,14 @@ template<typename T> class narray
|
|||||||
|
|
||||||
narray();
|
narray();
|
||||||
narray(const narray<T>& other);
|
narray(const narray<T>& other);
|
||||||
|
narray(narray<T>&& other) noexcept;
|
||||||
|
|
||||||
narray<T>& operator=(const narray<T>& other);
|
narray<T>& operator=(const narray<T>& other);
|
||||||
|
narray<T>& operator=(narray<T>&& other) noexcept;
|
||||||
|
|
||||||
narray<T>& operator=(const std::vector<T>& other);
|
narray<T>& operator=(const std::vector<T>& other);
|
||||||
narray(const std::initializer_list<T> initlist);
|
narray(const std::initializer_list<T> initlist);
|
||||||
|
narray<T>& operator=(const std::initializer_list<T> initlist);
|
||||||
~narray();
|
~narray();
|
||||||
|
|
||||||
int resize(const narray_size_t newlength);
|
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
|
void setall(const T& val); //sets all elements to val
|
||||||
|
|
||||||
//Comparators
|
//Comparators
|
||||||
|
bool operator==(const narray<T>& other) const;
|
||||||
|
bool operator!=(const narray<T>& other) const;
|
||||||
|
|
||||||
//Operations
|
//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_narray1();
|
||||||
|
void test_narray2();
|
||||||
|
void test_narray3();
|
||||||
|
|
||||||
}; //end namespace narray
|
}; //end namespace narray
|
||||||
}; //end namespace ams
|
}; //end namespace ams
|
||||||
|
|
||||||
#include <amscppnarray/amscppnarray_impl.hpp>
|
#include <amscppnarray/amscppnarray_impl.hpp>
|
||||||
|
#include <amscppnarray/amscppnarray_imploper.hpp>
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -8,6 +8,8 @@ namespace narray
|
|||||||
|
|
||||||
template<typename T> narray<T>::narray()
|
template<typename T> narray<T>::narray()
|
||||||
{
|
{
|
||||||
|
//printf("debug: constructor called for %p.\n",this);
|
||||||
|
|
||||||
length = 0;
|
length = 0;
|
||||||
data = NULL;
|
data = NULL;
|
||||||
|
|
||||||
@ -59,6 +61,8 @@ template<typename T> narray<T>::narray(const narray<T>& other)
|
|||||||
length = 0;
|
length = 0;
|
||||||
data = NULL;
|
data = NULL;
|
||||||
|
|
||||||
|
//printf("debug: copy constructor called for\n\t%p\n\t%p\n", this, &other);
|
||||||
|
|
||||||
if(this!=&other)
|
if(this!=&other)
|
||||||
{
|
{
|
||||||
res = this->resize(other.length);
|
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)
|
template<typename T> narray<T>& narray<T>::operator=(const narray<T>& other)
|
||||||
{
|
{
|
||||||
narray_size_t I;
|
narray_size_t I;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
|
//printf("debug: operator= called for\n\t%p\n\t%p\n", this, &other);
|
||||||
|
|
||||||
if(this!=&other)
|
if(this!=&other)
|
||||||
{
|
{
|
||||||
res = this->resize(other.length);
|
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++)
|
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()
|
template<typename T> narray<T>::~narray()
|
||||||
{
|
{
|
||||||
|
//printf("debug: destructor called for %p\n",this);
|
||||||
length = 0;
|
length = 0;
|
||||||
if(data!=NULL) {delete[] data; data=NULL;}
|
if(data!=NULL) {delete[] data; data=NULL;}
|
||||||
return;
|
return;
|
||||||
@ -179,10 +245,27 @@ template<typename T> void narray<T>::clear()
|
|||||||
return;
|
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)
|
template<typename T> void narray<T>::setall(const T& val)
|
||||||
{
|
{
|
||||||
narray_size_t I;
|
narray_size_t I;
|
||||||
|
int J;
|
||||||
int nthreads;
|
int nthreads;
|
||||||
|
std::vector<std::thread*> threads;
|
||||||
|
|
||||||
if(length<narray_thread_sz)
|
if(length<narray_thread_sz)
|
||||||
{
|
{
|
||||||
@ -191,8 +274,25 @@ template<typename T> void narray<T>::setall(const T& val)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
//threaded operation
|
//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;
|
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
|
namespace narray
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
void test_narray1()
|
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;
|
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 narray
|
||||||
}; //end namespace ams
|
}; //end namespace ams
|
@ -4,7 +4,9 @@ int main(int argc, char* argv[])
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
printf("ams c++ numeric array library tests.\n");
|
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;
|
return ret;
|
||||||
}
|
}
|
Reference in New Issue
Block a user