Permalink
Browse files

made compatible with gcc44, started to work on array, SSE specialization

  • Loading branch information...
lvv committed Dec 9, 2008
1 parent 0858e10 commit 9a29127415452fdb534797715c78088cf817bb92
Showing with 102 additions and 96 deletions.
  1. +9 −3 README.txt
  2. +36 −37 array.h
  3. +9 −7 check.h
  4. +4 −3 include.mk
  5. +1 −1 t-array.cc
  6. +1 −0 t-check.cc
  7. +1 −3 timer.h
  8. +40 −41 u-array.cc
  9. +1 −1 u-powi.cc
@@ -45,7 +45,7 @@ absolutes of compared values (1st and 2nd argument). But in chain of calculatio
value can be different. For example in: `x=1000.1; y=x-1000.` characteristic
value of `y` is `1000` even though it is approximately equal `0.1`
Type-precision is expressed as http://docs.sun.com/source/806-3568/ncg_goldberg.html[ULP]
Type-precision is expressed as http://en.wikipedia.org/wiki/Unit_in_the_last_place[ULP]
for value `1.0` (`== std::numeric_limits<T>::epsilon()`). This is only possible way to make it
invariant to type used. That is error expressed in ULP is about the same when
we change type (needed for generic programming).
@@ -61,15 +61,21 @@ For integers: If one of arguments is `unsigned` then other argument converted to
We assume that if someone compares with `unsigned` then he guarantees that other value is positive.
=== check.h
Very basic unit testing. I had to write my own unit testing because gcc44 can not
compile BOOST_CHECK. Implemented mostly in macros. Shows at execution log
evaluated expression.
=== Other
[width="80%",cols="3,3,6",frame="none",options="header"]
|==========================
| Header | Sample Use | Description
| {gh-ll}check.h[check.h]| {gh-ll}t-equal.cc[t-equal.cc] | simple unit testing.
| {gh-ll}check.h[check.h]| {gh-ll}t-equal.cc[t-equal.cc] | basic unit testing.
| {gh-ll}mmap.h[mmap.h] | {gh-ll}t-mmap.cc[t-mmap.cc] | simplified mmap files ops.
| {gh-ll}timer.h[timer.h]| {gh-ll}t-timer.cc[t-timer.cc] | interval and wall timer.
| {gh-ll}timer.h[timer.h]| {gh-ll}t-timer.cc[t-timer.cc] | interval/total for cpu/wall/tick timer.
|==========================
// vim:ft=asciidoc:
73 array.h
@@ -1,37 +1,51 @@
#ifndef LVV_ARRAY
#define LVV_ARRAY
// TODO tensor: http://www.sitmo.com/doc/A_Simple_and_Extremely_Fast_CPP_Template_for_Matrices_and_Tensors
// TODO
// tensor: http://www.sitmo.com/doc/A_Simple_and_Extremely_Fast_CPP_Template_for_Matrices_and_Tensors
// memcpy : file:///tr/boost-trunk.svn/libs/type_traits/doc/html/boost_typetraits/examples/copy.html
// According to the language definition, aggregate initialization only works
// for aggregate types. An array or class type is not an aggregate if it has
// any user-declared constructors, any private or protected nonstatic data
// members, any base classes, or any virtual functions.
#include <lvv/math.h>
#include <cassert>
#include <cmath>
using std::sqrt;
#include <lvv/math.h>
#include <cassert>
#include <iostream>
using std::ostream;
using std::cout;
using std::endl;
#include <iostream>
using std::ostream;
using std::cout;
using std::endl;
#include <iterator>
using std::ostream_iterator;
#include <iterator>
using std::ostream_iterator;
#include <numeric>
using std::accumulate;
#include <numeric>
using std::accumulate;
//#include <boost/format.hpp>
//using boost::format;
//#include <boost/format.hpp>
//using boost::format;
#include <iterator>
#include <algorithm>
using std::size_t;
#include <iterator>
#include <algorithm>
using std::size_t;
#include <cmath>
using std::sqrt;
#include <immintrin.h>
#include <lvv/meta.h>
namespace lvv {
///// spcialization for SSE/OpenMP
struct plain {};
struct sse {};
template<typename T, int N> struct select_method {typedef plain type;};
template<int N> struct select_method<float,N> {typedef typename IF< (N>128), sse, plain>::type type;};
template < class T, int N, int BEGIN=0> class array {
public:
T elems[N];
@@ -48,7 +62,10 @@ template < class T, int N, int BEGIN=0> class array {
typedef int size_type;
typedef int index_type;
// CTOR -- imposible with having aggrigate constructor
// CTOR
// n/a (imposible with having aggrigate constructor)
// index
index_type ibegin() const { return BEGIN; }
@@ -148,7 +165,6 @@ template<class T, int N, int B> bool operator>=(const array<T, N, B> &x, const a
template < class T, size_t N, int B > inline void swap(array < T, N, B > &x, array < T, N, B > &y) { x.swap(y); }
// array op= scallar ( conflict with google sparsehash if we not spell out type)
template<typename T,int N, int B, typename D> array<T,N,B>& operator+=(array<T,N,B>& A, const D d) { for(typename array<T,N,B>::iterator it = A.begin(); it != A.end(); it++) *it += d; return A; }
template<typename T,int N, int B, typename D> array<T,N,B>& operator-=(array<T,N,B>& A, const D d) { for(typename array<T,N,B>::iterator it = A.begin(); it != A.end(); it++) *it -= d; return A; }
@@ -162,22 +178,6 @@ template<typename T,int N, int B> array<T,N,B>& operator-=(array<T,N,B>& LA, con
template<typename T,int N, int B> array<T,N,B>& operator*=(array<T,N,B>& LA, const array<T,N,B>& RA) { typename array<T,N,B>::iterator lit = LA.begin(); typename array<T,N,B>::const_iterator rit = RA.begin(); for(; lit != LA.end();) *lit++ *= *rit++; return LA; }
template<typename T,int N, int B> array<T,N,B>& operator/=(array<T,N,B>& LA, const array<T,N,B>& RA) { typename array<T,N,B>::iterator lit = LA.begin(); typename array<T,N,B>::const_iterator rit = RA.begin(); for(; lit != LA.end();) *lit++ /= *rit++; return LA; }
/*
// array op array
template<typename T,int N, int B>
const array<T,N,B>&
operator+ (const array<T,N,B>& LA, const array<T,N,B>& RA) {
//shared_array<array<T,N,B> > Rp((array<T,N,B>*) new T[N]);
//shared_array<array<T,N,B> > Rp(new array<T,N,B>);
//shared_ptr<array<T,N,B> > Rp(new const array<T,N,B> );
//shared_ptr<array<T,N,B> > Rp(const shared_ptr<array<T,N,B>>(new array<T,N,B> ));
//shared_ptr<array<T,N,B> > Rp((array<T,N,B>*) new char[sizeof(T)*N]);
//shared_ptr<array<T,N,B> > Rp = new array<T,N,B>;
shared_ptr<const array<T,N,B> > Rp(new const array<T,N,B>);
//for(int i=B; i<B+N; i++) (*(array<T,N,B>*) Rp.get())[i] = LA[i]+RA[i];
for(int i=B; i<B+N; i++) (*const_cast<T*>(Rp))[i] = LA[i]+RA[i];
return Rp;
}*/
template<typename T,int N, int B> T
dot_prod (const array<T,N,B>& LA, const array<T,N,B>& RA) {
@@ -211,7 +211,6 @@ distance_norm2 (const array<T,N,B>& LA, const array<T,N,B>& RA) {
return sqrt(sum);
}
template <typename T, int N, int B>
std::ostream&
operator<< (ostream& os, array<T,N,B> A) {
16 check.h
@@ -1,20 +1,22 @@
#include <iostream>
///////////////////////////////////////////////////////////////////////////////////// TEST MACROS
static __attribute__((unused)) bool all_pass=true;
static __attribute__((unused)) bool result=false;
//static __attribute__((unused)) bool result=false;
static bool result=false;
#define PASS " pass "
#define FAIL ">>> FAIL <<<"
#define RESULT cout << (result ? PASS : FAIL) << " " << __LINE__ << " ";
#define RESULT std::cout << (result ? PASS : FAIL) << " " << __LINE__ << " ";
#define CHECK(e) result=(e); all_pass = (all_pass && result); RESULT; cout << "check: " #e << endl;
#define CHECK(e) result=(e); all_pass = (all_pass && result); RESULT; std::cout << "check: " #e << std::endl;
#define CHECK_ARE_EQUAL(e1,e2) result=((e1)==(e2)); all_pass = (all_pass && result); RESULT; cout << "are equal: " << result << \
#define CHECK_ARE_EQUAL(e1,e2) result=((e1)==(e2)); all_pass = (all_pass && result); RESULT; std::cout << "are equal: " << result << \
" " #e1 " = " << (e1) << \
" " #e2 " = " << (e2) << endl;
" " #e2 " = " << (e2) << std::endl;
#define CHECK_NOT_EQUAL(e1,e2) result=((e1)!=(e2)); all_pass = (all_pass && result); RESULT; cout << "not equal: " << result << \
#define CHECK_NOT_EQUAL(e1,e2) result=((e1)!=(e2)); all_pass = (all_pass && result); RESULT; std::cout << "not equal: " << result << \
" " #e1 " = " << (e1) << \
" " #e2 " = " << (e2) << endl;
" " #e2 " = " << (e2) << std::endl;
@@ -3,15 +3,17 @@
# to set speed run as: make s=o
CXX ?= g++
VPATH := ../lvv/
FC = gfortran
TMPDIR ?=/v
########################################################################################
#SPEED := $(s:o=OPTIMZE)
SPEED := $(s:d=DEBUG)
#SPEED := $(c:d=CHECK)
#SPEED = $($($(s:d=DEBUG):c=CHECK):o=OPTIMIZE)
SPEED ?= DEBUG
####################################################################################### COMPILE SPECIFIC
g++FLAGS := -pipe -Wno-reorder -Wno-sign-compare # -Wmissing-braces
@@ -49,7 +51,7 @@ iccFLAGS_DEBUG := -debug all
#for icc PATH=/usr/x86_64-pc-linux-gnu/gcc-bin/4.2.4:$(PATH)
####################################################################################### NOT COMPILE SPECIFIC
CXXFLAGS_COMMON = -Wall -DID='"$(ID)"' -I . -I .. -I ../.. -I /usr/local/include
CXXFLAGS_COMMON = -Wall -DID='"$(ID)"' -I ~/p/ -I /usr/local/include
#-frecord-gcc-switches
CXXFLAGS_OPTIMIZE := -DNDEBUG -DGSL_RANGE_CHECK_OFF -DNOCHECK
#CXXFLAGS_DEBUG := -DDEBUG -lgzstream -lz -lmudflap
@@ -59,7 +61,6 @@ CXXFLAGS_CHECK := -DDEBUG -lgzstream -lz -DDOCHECK -DNOSTATS -D_GLIBCXX_DEB
####################################################################################### EVALUATE CXXFLAGS
CXXFLAGS += $(CXXFLAGS_COMMON) $(CXXFLAGS_$(SPEED)) $($(CXX)FLAGS) $($(CXX)FLAGS_$(SPEED)) $(CF) $(CFLAGS)
#*: ../lvv/include.mk ../lvv/lvv.h
.SUFFIXES: .cc -r -c -g -gp
.PHONY = %-r %-g %-gr %-gp
@@ -2,7 +2,7 @@
#include <iostream>
using namespace std;
#include <boost/foreach.hpp>
//#include <boost/foreach.hpp>
#include <lvv/array.h>
#include <lvv/lvv.h>
@@ -22,6 +22,7 @@ main() {
cout << std::boolalpha;
CHECK(1 == 1);
CHECK(!equal(f1,f2));
CHECK( equal(f1,f1));
CHECK(!equal(f0,f1));
@@ -9,9 +9,7 @@
#include <sys/resource.h>
#include <stdlib.h>
//#include <unistd.h>
//#include <stdint.h>
//typedef unsigned long long int uint64_t;
#include <stdint.h>
#include <iostream>
#include <iomanip>
@@ -1,38 +1,36 @@
#include <iostream>
using namespace std;
//#include <boost/foreach.hpp>
//#include <iostream>
#include <lvv/math.h>
using lvv::eq;
#include <lvv/array.h>
#include <lvv/lvv.h>
//#include <lvv/lvv.h>
using lvv::array;
#include <lopti/convert-gsl.h>
#define BOOST_TEST_MODULE lvv_array
#include <boost/test/included/unit_test.hpp>
#include <lvv/check.h>
//#include <lopti/convert-gsl.h>
using namespace std;
using namespace lvv;
BOOST_AUTO_TEST_CASE( lvv_array ) {
int
main() {
typedef array<int,5> a5_t;
// CTOR
array <int, 5 > a0 = {{0,1,2,3,4}}; // index starts from 0
BOOST_CHECK( a0.ibegin()==0);
BOOST_CHECK( a0.iend()==5);
BOOST_CHECK( a0.size()==5);
CHECK(a0.ibegin()==0);
CHECK( a0.iend()==5);
CHECK( a0.size()==5);
array <int, 5, 1> a1 = {{1,2,3,4,5}}; // index starts from 1
BOOST_CHECK( a1.ibegin()==1);
BOOST_CHECK( a1.iend()==6);
BOOST_CHECK( a1.size()==5);
CHECK( a1.ibegin()==1);
CHECK( a1.iend()==6);
CHECK( a1.size()==5);
array <int, 5, -2> an = {{-2,-1,0,1,2}}; // index starts from -2
BOOST_CHECK( an.ibegin()==-2);
BOOST_CHECK( an.iend()==3);
BOOST_CHECK( an.size()==5);
CHECK( an.ibegin()==-2);
CHECK( an.iend()==3);
CHECK( an.size()==5);
array <int, 5, 1> const b1 = {{10,20,30,40,50}}; // index starts from 1
@@ -43,65 +41,66 @@ BOOST_AUTO_TEST_CASE( lvv_array ) {
array<int,5,0> b0;
b0 = 0;
b0 = 2;
BOOST_CHECK( b0[0] == 2 );
BOOST_CHECK( b0[3] == 2 );
CHECK( b0[0] == 2 );
CHECK( b0[3] == 2 );
// = diffrent type vector
array<long,5,0> c0;
c0 = a0;
BOOST_CHECK( c0[0] == 0 );
BOOST_CHECK( c0[3] == 3 );
CHECK( c0[0] == 0 );
CHECK( c0[3] == 3 );
//////////////////////////////////////////////////// vector ops
// array op= scalar : an+10
an += 10;
BOOST_CHECK( *an.begin() == -2+10 );
BOOST_CHECK( an[-1] == -1+10 );
BOOST_CHECK( an[an.iend()-1] == 2+10 );
CHECK( *an.begin() == -2+10 );
CHECK( an[-1] == -1+10 );
CHECK( an[an.iend()-1] == 2+10 );
// array op= array
a1 += b1;
BOOST_CHECK( a1[1] == 1+10 );
BOOST_CHECK( a1[5] == 5+50 );
CHECK( a1[1] == 1+10 );
CHECK( a1[5] == 5+50 );
// vector ops
array<float,2> c1={{1,2}};
array<float,2> c2={{2,2}};
// dot prod: {1,2} x {2,2} = "
BOOST_CHECK( dot_prod(c1,c2) == 6 );
CHECK( dot_prod(c1,c2) == 6 );
// norm2: : |{2,2}|
BOOST_CHECK( eq(norm2(c2), 2.82843f) );
CHECK( eq(norm2(c2), 2.82843f) );
//distance_norm2: : |{1,2}-{2,2}| =
array<double,2> v1 = {{3., 0.}};
array<double,2> v2 = {{0., 4.}};
BOOST_CHECK( eq(distance_norm2(v1,v2), 5.));
CHECK( eq(distance_norm2(v1,v2), 5.));
//////////////////////////////////////////////////// gsl convertion
#ifdef CONVERT_GSl_H
gsl_vector* gV; // 1st index == 0
gV = gsl_vector_alloc(a0.size());
gV <<= a0;
BOOST_CHECK( gsl_vector_get(gV,0) == a0[0]);
BOOST_CHECK( gsl_vector_get(gV,2) == a0[2]);
CHECK( gsl_vector_get(gV,0) == a0[0]);
CHECK( gsl_vector_get(gV,2) == a0[2]);
b0 <<= gV;
BOOST_CHECK( b0[2]== a0[2]);
BOOST_CHECK( b0 == a0);
CHECK( b0[2]== a0[2]);
CHECK( b0 == a0);
gV << a1;
BOOST_CHECK( gsl_vector_get(gV,0) == a1[1]);
BOOST_CHECK( gsl_vector_get(gV,2) == a1[3]);
BOOST_CHECK( gsl_vector_get(gV,4) == a1[5]);
CHECK( gsl_vector_get(gV,0) == a1[1]);
CHECK( gsl_vector_get(gV,2) == a1[3]);
CHECK( gsl_vector_get(gV,4) == a1[5]);
array<int,5,-2> b_m2;
b_m2 << gV;
BOOST_CHECK( b_m2[-2]== a1[1]);
BOOST_CHECK( b_m2[2] == a1[5]);
CHECK( b_m2[-2]== a1[1]);
CHECK( b_m2[2] == a1[5]);
#endif
cout << (all_pass ? "\n------------ all pass ------------\n" : "\n!!!!!!!!! SOME FAILED !!!!!!!!\n");
exit(all_pass ? 0 : 1);
}
@@ -1,5 +1,5 @@
#include <limits>
//#include <limits>
#include <lvv/lvv.h>
#include <lvv/math.h>
#include <lvv/check.h>

0 comments on commit 9a29127

Please sign in to comment.