//-*- Mode: C++ -*- //* This file is property of and copyright by the ALICE HLT Project * //* ALICE Experiment at CERN, All rights reserved. * //* See cxx source for full Copyright notice * #ifndef ALIHLTTPCCADEF_H #define ALIHLTTPCCADEF_H /** * Definitions needed for AliHLTTPCCATracker * */ #if defined(HLTCA_STANDALONE) typedef unsigned char UChar_t; typedef UChar_t Byte_t; typedef int Int_t; typedef double Double_t; #else #include "Rtypes.h" #endif #ifdef NDEBUG #define ASSERT(v, msg) #else #define ASSERT(v, msg) \ if (v) {} else { \ std::cerr << __FILE__ << ":" << __LINE__ << " assertion failed: " \ << #v << " = " << (v) << "\n" << msg << std::endl; \ abort(); \ } #endif struct float2 { float x; float y; }; /* * Helper for compile-time verification of correct API usage */ namespace { template struct HLTTPCCA_STATIC_ASSERT_FAILURE; template<> struct HLTTPCCA_STATIC_ASSERT_FAILURE {}; } #define HLTTPCCA_STATIC_ASSERT_CONCAT_HELPER(a, b) a##b #define HLTTPCCA_STATIC_ASSERT_CONCAT(a, b) HLTTPCCA_STATIC_ASSERT_CONCAT_HELPER(a, b) #define STATIC_ASSERT(cond, msg) \ typedef HLTTPCCA_STATIC_ASSERT_FAILURE HLTTPCCA_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__); \ HLTTPCCA_STATIC_ASSERT_CONCAT(_STATIC_ASSERTION_FAILED_##msg, __LINE__) Error_##msg; \ (void) Error_##msg namespace { template void UNUSED_PARAM1( const T1 & ) {} template void UNUSED_PARAM2( const T1 &, const T2 & ) {} template void UNUSED_PARAM3( const T1 &, const T2 &, const T3 & ) {} template void UNUSED_PARAM4( const T1 &, const T2 &, const T3 &, const T4 & ) {} template void UNUSED_PARAM5( const T1 &, const T2 &, const T3 &, const T4 &, const T5 & ) {} template void UNUSED_PARAM6( const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 & ) {} template void UNUSED_PARAM7( const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 & ) {} template void UNUSED_PARAM8( const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &, const T8 & ) {} template void UNUSED_PARAM9( const T1 &, const T2 &, const T3 &, const T4 &, const T5 &, const T6 &, const T7 &, const T8 &, const T9 & ) {} } #define unrolled_loop4( _type_, _it_, _start_, _end_, _code_ ) \ if (_start_ + 0 < _end_) { enum { _it_ = (_start_ + 0) < _end_ ? (_start_ + 0) : _start_ }; _code_ } \ if (_start_ + 1 < _end_) { enum { _it_ = (_start_ + 1) < _end_ ? (_start_ + 1) : _start_ }; _code_ } \ if (_start_ + 2 < _end_) { enum { _it_ = (_start_ + 2) < _end_ ? (_start_ + 2) : _start_ }; _code_ } \ if (_start_ + 3 < _end_) { enum { _it_ = (_start_ + 3) < _end_ ? (_start_ + 3) : _start_ }; _code_ } \ do {} while ( false ) #ifdef __GNUC__ #define MAY_ALIAS __attribute__((__may_alias__)) #else #define MAY_ALIAS #endif #if defined( __GNUC__ ) && __GNUC__ - 0 >= 3 # define ISLIKELY( x ) __builtin_expect( !!( x ),1 ) # define ISUNLIKELY( x ) __builtin_expect( !!( x ),0 ) #else # define ISLIKELY( x ) ( x ) # define ISUNLIKELY( x ) ( x ) #endif #include typedef arbb::i16 THitI_ArBB; // type of index of hit on row\sector typedef arbb::u16 TRowI_ArBB; // type of index of row in sector // TODO u8 typedef arbb::i16 TRowI2_ArBB; // type of index of row in sector // additional to arbb functions, which should be usefull ingiven package //namespace arbb{ // using namespace arbb; using arbb::array; using arbb::dense; using arbb::nested; using arbb::usize; using arbb::f32; using arbb::i32; //using arbb::boolean; using arbb::indices; using arbb::fill; arbb::boolean finite_arbb(const f32 s); ARBB_ELTWISE_FUNCTION_1( arbb::boolean, finite_arbb, f32 ); template // TODO THitI_ArBB -> usize dense gather(const dense& source, const dense& index, const T& value, const dense& defaults, const dense& mask) { const dense tmp = gather(source, index, value); return select(mask, tmp, defaults); } template dense scatter(const dense& source, const dense& index, const dense& defaults, const dense& mask) { const usize taskSize = defaults.length(); #if 0 // TODO - no bounds problem const dense indexInBounds = select(mask, index, 0); // FIXME const dense scatteredMask = scatter( mask, indexInBounds, fill(false, taskSize) ); const dense scatteredSource = scatter( source, indexInBounds, defaults ); return select( scatteredMask, scatteredSource, defaults); // const dense scatteredMask = scatter( mask, index, fill(false, taskSize) ); // const dense scatteredSource = scatter( source, index, defaults ); // return select( scatteredMask, scatteredSource, defaults); #else // bounds problem // FIXME const dense indexInBounds = select( mask, index, fill(static_cast(taskSize), mask.length() ) ); const dense scatteredMask_long = scatter( mask, indexInBounds, fill(false, taskSize+1) ); const dense defaults_long = cat( defaults, fill( 0, 1 ) ); const dense scatteredSource_long = scatter( source, indexInBounds, defaults_long ); const dense result_long = select( scatteredMask_long, scatteredSource_long, defaults_long); return section( result_long, 0, taskSize ); #endif // problem } /// Returns a three-dimensional dense container with @p nrows rows, /// where result[x,y,z] = sourse[x,z], y = 0 .. nrows-1 source. template dense repeat_row(const dense& source, const usize& nrows) { const usize NCols = source.num_cols(); const usize NRows = nrows; const usize NPages = source.num_rows(); dense result = dense( NCols, NRows, NPages ); _for (usize i = 0, i < source.num_rows(), ++i) { const dense sourceRow = source.row(i); const dense result_tmp = repeat_row(sourceRow, NRows); result = replace_page( result, i, result_tmp); } _end_for; return result; } /// Computes the minimum of @p source along @p level1 and @p level2, and stores the /// locations of these minima in @p loc. template dense min_reduce_my(const dense& source, // TODO generalize dense& loc1, dense& loc2) { const usize NCols = source.num_cols(); dense bestIndicesAtPages; const dense source_reduced1 = min_reduce(source, bestIndicesAtPages, 2); dense bestIndicesAtColumns; const dense source_reduced2 = min_reduce(source_reduced1, bestIndicesAtColumns, 1); const dense, 1> bestIndicesAtColumns_ziped = bestIndicesAtColumns.zip( arbb::indices(0,NCols,1) ); const dense, 2> bestIndicesAtColumns_2D = repeat_row( bestIndicesAtColumns_ziped, 1 ); dense bestIndices = gather( bestIndicesAtPages, bestIndicesAtColumns_2D, -1 ).row(0); loc1 = bestIndicesAtColumns; loc2 = bestIndices; return source_reduced2; } #define ARBB_PRINT( name, p ) {{{{ \ std::cout << name << value(p) << std::endl; \ }}}} #define ARBB_PRINT_2( name, p, p2 ) {{{{ \ std::cout << name << value(p) << " " << value(p2) << std::endl; \ }}}} /// print all entries in container template< typename T> void ARBB_PRINT_ALL( std::string name, const dense& p ) { std::cout << name; _for ( usize i = 0, i < (p).length(), i++ ) { std::cout << value((p)[i]) << " "; } _end_for; std::cout << std::endl; } /// print all entries in container with mask[i] = true template< typename T> void ARBB_PRINT_ALL( std::string name, const dense& p, const dense& m ) { _if ( any(m) ) { std::cout << name; } _end_if; _for ( usize i = 0, i < (p).length(), i++ ) { _if( (m)[i] ) { std::cout << value((p)[i]) << " "; } _end_if; } _end_for; _if ( any(m) ) { std::cout << std::endl; } _end_if; } /// print all indices - i such that mask[i] = true void ARBB_PRINT_INDICES( std::string name, const dense& m ); /// the class has to be like: /// class className /// { /// public: /// template< size_t D > /// class TDense; /// friend class TDense<1>; /// /// someFunctions /// private: /// someTypes someDataMembers; /// /// typedef someType TArtKey; /// TArtKey ArtKey(); /// }; /// ARBB_ELTWISE_METHOD_0(someType, className, ArtKey); // template // class nested_my: public nested { // template // typename nested get() const { // }; // template // void set(const nested, 1>& val) { // }; // } #define ARBB_UDT_DENSE_HELPER_INTRO(className) \ template \ class className::TDense: public dense \ { \ public: \ typedef dense TDenseBase; \ TDense():TDenseBase(){}; \ TDense(const TDenseBase& src):TDenseBase(src){}; \ TDense(const usize& length):TDenseBase(length){}; \ #define ARBB_UDT_DENSE_HELPER_SORT_INTRO(className) \ void Sort( arbb::sort_direction dir = arbb::sort_ascending ) { \ const dense artKey = className().ArtKey(*reinterpret_cast(this)); \ dense rank; \ sort(artKey, rank, dir); \ #define ARBB_UDT_DENSE_HELPER_SORT(type, n) \ { \ const dense member = this->template get(); \ this->template set( gather( member, rank ) ); \ } #define ARBB_UDT_DENSE_HELPER_ACCESSORS(type, name, n) \ dense name() const { return this->template get(); }; \ void Set##name ( const dense& source ) { this->template set( source ); }; #define ARBB_UDT_DENSE_1(className, type0, name0) \ ARBB_UDT_DENSE_HELPER_INTRO(className); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type0, name0, 0); \ ARBB_UDT_DENSE_HELPER_SORT_INTRO(className); \ ARBB_UDT_DENSE_HELPER_SORT(type0, 0) \ }; \ }; #define ARBB_UDT_DENSE_2(className, type0, name0, type1, name1) \ ARBB_UDT_DENSE_HELPER_INTRO(className); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type0, name0, 0); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type1, name1, 1); \ ARBB_UDT_DENSE_HELPER_SORT_INTRO(className); \ ARBB_UDT_DENSE_HELPER_SORT(type0, 0) \ ARBB_UDT_DENSE_HELPER_SORT(type1, 1) \ }; \ }; #define ARBB_UDT_DENSE_3(className, type0, name0, type1, name1, type2, name2) \ ARBB_UDT_DENSE_HELPER_INTRO(className); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type0, name0, 0); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type1, name1, 1); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type2, name2, 2); \ ARBB_UDT_DENSE_HELPER_SORT_INTRO(className); \ ARBB_UDT_DENSE_HELPER_SORT(type0, 0) \ ARBB_UDT_DENSE_HELPER_SORT(type1, 1) \ ARBB_UDT_DENSE_HELPER_SORT(type2, 2) \ }; \ }; #define ARBB_UDT_DENSE_4(className, type0, name0, type1, name1, type2, name2, type3, name3) \ ARBB_UDT_DENSE_HELPER_INTRO(className); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type0, name0, 0); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type1, name1, 1); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type2, name2, 2); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type3, name3, 3); \ ARBB_UDT_DENSE_HELPER_SORT_INTRO(className); \ ARBB_UDT_DENSE_HELPER_SORT(type0, 0) \ ARBB_UDT_DENSE_HELPER_SORT(type1, 1) \ ARBB_UDT_DENSE_HELPER_SORT(type2, 2) \ ARBB_UDT_DENSE_HELPER_SORT(type3, 3) \ }; \ }; #define ARBB_UDT_DENSE_5(className, type0, name0, type1, name1, type2, name2, type3, name3, type4, name4) \ ARBB_UDT_DENSE_HELPER_INTRO(className); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type0, name0, 0); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type1, name1, 1); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type2, name2, 2); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type3, name3, 3); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type4, name4, 4); \ ARBB_UDT_DENSE_HELPER_SORT_INTRO(className); \ ARBB_UDT_DENSE_HELPER_SORT(type0, 0) \ ARBB_UDT_DENSE_HELPER_SORT(type1, 1) \ ARBB_UDT_DENSE_HELPER_SORT(type2, 2) \ ARBB_UDT_DENSE_HELPER_SORT(type3, 3) \ ARBB_UDT_DENSE_HELPER_SORT(type4, 4) \ }; \ }; #define ARBB_UDT_DENSE_6(className, type0, name0, type1, name1, type2, name2, type3, name3, type4, name4, type5, name5) \ ARBB_UDT_DENSE_HELPER_INTRO(className); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type0, name0, 0); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type1, name1, 1); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type2, name2, 2); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type3, name3, 3); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type4, name4, 4); \ ARBB_UDT_DENSE_HELPER_ACCESSORS(type5, name5, 5); \ ARBB_UDT_DENSE_HELPER_SORT_INTRO(className); \ ARBB_UDT_DENSE_HELPER_SORT(type0, 0) \ ARBB_UDT_DENSE_HELPER_SORT(type1, 1) \ ARBB_UDT_DENSE_HELPER_SORT(type2, 2) \ ARBB_UDT_DENSE_HELPER_SORT(type3, 3) \ ARBB_UDT_DENSE_HELPER_SORT(type4, 4) \ ARBB_UDT_DENSE_HELPER_SORT(type5, 5) \ }; \ }; template< typename T > class nested_my { public: nested_my():fData(),fLengths(),fStartIndices(){}; /// Returns a flattened 1D dense container with the data from each /// segment in order. dense flatten() const{ return fData; }; /// Returns a dense container comprised of the lengths of the segments. dense lengths() const { return fLengths; }; /// Returns a copy of the segment at index @p i. dense segment(const usize& index) const { dense r; _if( fLengths[index] > 0 ) { // FIXME empty container r = section( fData, fStartIndices[index], fLengths[index] ); } _end_if; return r; }; // new functions nested_my( const dense& data, const dense& lengths ):fData(data){ fLengths = lengths; fStartIndices = add_scan( lengths ); }; void replace_segment( const usize& index, const dense& value ) { _if( value.length() == fLengths[index] ) { fData = replace( fData, fStartIndices[index], fLengths[index], 1, value ); } _else { std::cout << " replace_segment has invalid parameters " << std::endl; } _end_if; }; // end new functions protected: dense fData; dense fLengths; dense fStartIndices; }; /// Returns a nested container with its elements drawn from @p data, /// partitioned into segments with lengths are provided by @p lengths. template nested_my reshape_nested_lengths_my(const dense& data, const dense& lengths){ return nested_my( data, lengths ); }; /// Returns a nested container with the same segments as @p src, but /// the segment at index @p i replaced by @p value. template nested_my replace_segment(const nested_my& src, const usize& i, const dense& value){ nested_my r = src; r.replace_segment(i,value); return r; }; /// Returns the concatenation of @p source1 followed by @p source2. template // FIXME empty container dense cat_my(const dense& source1, const dense& source2) { dense result; _if( source1.length() > 0 ) { result = cat( source1, source2 ); } _else { result = source2; } _end_if; return result; } #endif