Skip to content

Commit

Permalink
made compatible with gcc44, started to work on array, SSE specialization
Browse files Browse the repository at this point in the history
  • Loading branch information
lvv committed Dec 9, 2008
1 parent 0858e10 commit 9a29127
Show file tree
Hide file tree
Showing 9 changed files with 102 additions and 96 deletions.
12 changes: 9 additions & 3 deletions README.txt
Expand Up @@ -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).
Expand All @@ -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 changes: 36 additions & 37 deletions 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];
Expand All @@ -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; }
Expand Down Expand Up @@ -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; }
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down
16 changes: 9 additions & 7 deletions 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;


7 changes: 4 additions & 3 deletions include.mk
Expand Up @@ -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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion t-array.cc
Expand Up @@ -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>
Expand Down
1 change: 1 addition & 0 deletions t-check.cc
Expand Up @@ -22,6 +22,7 @@ main() {

cout << std::boolalpha;

CHECK(1 == 1);
CHECK(!equal(f1,f2));
CHECK( equal(f1,f1));
CHECK(!equal(f0,f1));
Expand Down
4 changes: 1 addition & 3 deletions timer.h
Expand Up @@ -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>

Expand Down
81 changes: 40 additions & 41 deletions u-array.cc
@@ -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

Expand All @@ -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);

}
2 changes: 1 addition & 1 deletion u-powi.cc
@@ -1,5 +1,5 @@

#include <limits>
//#include <limits>
#include <lvv/lvv.h>
#include <lvv/math.h>
#include <lvv/check.h>
Expand Down

0 comments on commit 9a29127

Please sign in to comment.