X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2Fcml%2Fmatrix%2Fmatrix_unroller.h;fp=src%2FMoof%2Fcml%2Fmatrix%2Fmatrix_unroller.h;h=0000000000000000000000000000000000000000;hp=ab85945285a67a7bcc70f08956dea156e586c94d;hb=831f04d4bc19a390415ac0bbac4331c7a65509bc;hpb=299af4f2047e767e5d79501c26444473bda64c64 diff --git a/src/Moof/cml/matrix/matrix_unroller.h b/src/Moof/cml/matrix/matrix_unroller.h deleted file mode 100644 index ab85945..0000000 --- a/src/Moof/cml/matrix/matrix_unroller.h +++ /dev/null @@ -1,293 +0,0 @@ -/* -*- C++ -*- ------------------------------------------------------------ - -Copyright (c) 2007 Jesse Anders and Demian Nave http://cmldev.net/ - -The Configurable Math Library (CML) is distributed under the terms of the -Boost Software License, v1.0 (see cml/LICENSE for details). - - *-----------------------------------------------------------------------*/ -/** @file - * @brief - * - * @todo Need to implement unrolling for efficient col-major array access. - * - * @todo Does it make sense to unroll an assignment if either side of the - * assignment has a fixed size, or just when the target matrix is fixed - * size? - */ - -#ifndef matrix_unroller_h -#define matrix_unroller_h - -#include -#include -#include - -#if !defined(CML_2D_UNROLLER) && !defined(CML_NO_2D_UNROLLER) -#error "The matrix unroller has not been defined." -#endif - -#if defined(CML_2D_UNROLLER) && !defined(CML_MATRIX_UNROLL_LIMIT) -#error "CML_MATRIX_UNROLL_LIMIT is undefined." -#endif - -namespace cml { -namespace et { -namespace detail { - -/** Unroll a binary assignment operator on a fixed-size matrix. - * - * This uses a forward iteration to make better use of the cache. - * - * @sa cml::matrix - * @sa cml::et::OpAssign - * - * @bug Need to verify that OpT is actually an assignment operator. - * @bug The 2D unroller needs to be specified for efficient col-major - * access. - */ -template -class MatrixAssignmentUnroller -{ - protected: - - /* The matrix type being assigned to: */ - typedef cml::matrix matrix_type; - - /* Record traits for the arguments: */ - typedef ExprTraits dest_traits; - typedef ExprTraits src_traits; - -#if defined(CML_2D_UNROLLER) - - /* Forward declare: */ - template - struct Eval; - - /* XXX This needs to be specified for efficient col-major access also! */ - - /** Evaluate the binary operator at element R,C. */ - template - struct Eval { - void operator()(matrix_type& dest, const SrcT& src) const { - - /* Apply to current R,C: */ - OpT().apply(dest(R,C), src_traits().get(src,R,C)); - - /* Evaluate at R,C+1: */ - Eval()(dest,src); - } - }; - - /** Evaluate the binary operator at element R,LastCol. */ - template - struct Eval { - void operator()(matrix_type& dest, const SrcT& src) const { - - /* Apply to R,LastCol: */ - OpT().apply(dest(R,LastCol), src_traits().get(src,R,LastCol)); - - /* Evaluate at R+1,0; i.e. move to next row and start the - * col iteration from 0: - */ - Eval()(dest,src); - } - }; - - /** Evaluate the binary operator at element LastRow,C. */ - template - struct Eval { - void operator()(matrix_type& dest, const SrcT& src) const { - - /* Apply to LastRow,C: */ - OpT().apply(dest(LastRow,C), src_traits().get(src,LastRow,C)); - - /* Evaluate at LastRow,C+1: */ - Eval()(dest,src); - } - }; - - /** Evaluate the binary operator at element LastRow,LastCol. */ - template - struct Eval { - void operator()(matrix_type& dest, const SrcT& src) const { - - /* Apply to LastRow,LastCol: */ - OpT().apply( - dest(LastRow,LastCol), - src_traits().get(src,LastRow,LastCol)); - } - }; - - - /** Evaluate operators on large matrices using a loop. */ - template - struct Eval { - void operator()(matrix_type& dest, const SrcT& src) const { - for(size_t i = 0; i <= LastRow; ++i) { - for(size_t j = 0; j <= LastCol; ++j) { - OpT().apply(dest(i,j), src_traits().get(src,i,j)); - } - } - } - }; - -#endif // CML_2D_UNROLLER - -#if defined(CML_NO_2D_UNROLLER) - - /** Evaluate the binary operator using a loop. */ - template struct Eval { - void operator()(matrix_type& dest, const SrcT& src) const { - for(size_t i = 0; i <= LastRow; ++i) { - for(size_t j = 0; j <= LastCol; ++j) { - OpT().apply(dest(i,j), src_traits().get(src,i,j)); - } - } - } - }; - -#endif // CML_NO_2D_UNROLLER - - - public: - - /** Unroll assignment for a fixed-sized matrix. */ - void operator()( - cml::matrix& dest, const SrcT& src, cml::fixed_size_tag) - { - typedef cml::matrix matrix_type; - enum { - LastRow = matrix_type::array_rows-1, - LastCol = matrix_type::array_cols-1, - Max = (LastRow+1)*(LastCol+1) - }; - -#if defined(CML_2D_UNROLLER) - typedef typename MatrixAssignmentUnroller - ::template Eval<0, 0, LastRow, LastCol, - (Max <= CML_MATRIX_UNROLL_LIMIT)> Unroller; -#endif - -#if defined(CML_NO_2D_UNROLLER) - /* Use a loop: */ - typedef typename MatrixAssignmentUnroller - ::template Eval<0, 0, LastRow, LastCol> Unroller; -#endif - - /* Use a run-time check if src is a run-time sized expression: */ - typedef typename ExprTraits::size_tag src_size; - typedef typename select_if< - same_type::is_true, - dynamic_size_tag, fixed_size_tag>::result size_tag; - - /* Check the expression size (the returned size isn't needed): */ - CheckedSize(dest,src,size_tag()); - /* Note: for two fixed-size expressions, the if-statements and - * comparisons should be completely eliminated as dead code. If - * src is a dynamic-sized expression, the check will still happen. - */ - - Unroller()(dest,src); - } - - - private: - /* XXX Blah, a temp. hack to fix the auto-resizing stuff below. */ - matrix_size hack_actual_size( - matrix_type& dest, const SrcT& /*src*/, scalar_result_tag - ) - { - typedef ExprTraits dest_traits; - return dest_traits().size(dest); - } - - matrix_size hack_actual_size( - matrix_type& /*dest*/, const SrcT& src, matrix_result_tag - ) - { - typedef ExprTraits src_traits; - return src_traits().size(src); - } - - matrix_size CheckOrResize( - matrix_type& dest, const SrcT& src, cml::resizable_tag) - { -#if defined(CML_AUTOMATIC_MATRIX_RESIZE_ON_ASSIGNMENT) - /* Get the size of src. This also causes src to check its size: */ - matrix_size N = hack_actual_size( - dest, src, typename src_traits::result_tag()); - - /* Set the destination matrix's size: */ - dest.resize(N.first,N.second); -#else - matrix_size N = CheckedSize(dest,src,dynamic_size_tag()); -#endif - return N; - } - - matrix_size CheckOrResize( - matrix_type& dest, const SrcT& src, cml::not_resizable_tag) - { - return CheckedSize(dest,src,dynamic_size_tag()); - } - - - public: - - - /** Use a loop for dynamic-sized matrix assignment. - * - * @note The target matrix must already have the correct size. - * - * @todo This needs to be specialized for efficient row-major or col-major - * layout access. - */ - void operator()(matrix_type& dest, const SrcT& src, cml::dynamic_size_tag) - { - typedef ExprTraits src_traits; - matrix_size N = this->CheckOrResize( - dest,src,typename matrix_type::resizing_tag()); - for(size_t i = 0; i < N.first; ++i) { - for(size_t j = 0; j < N.second; ++j) { - OpT().apply(dest(i,j), src_traits().get(src,i,j)); - /* Note: we don't need get(), since dest is a matrix. */ - } - } - } -}; - -} - -/** This constructs an assignment unroller for fixed-size arrays. - * - * The operator must be an assignment op (otherwise, this doesn't make any - * sense). Also, automatic unrolling is only performed for fixed-size - * matrices; a loop is used for dynamic-sized matrices. - * - * @sa cml::matrix - * @sa cml::et::OpAssign - * - * @bug Need to verify that OpT is actually an assignment operator. - */ -template -inline void UnrollAssignment(cml::matrix& dest, const SrcT& src) -{ - /* Record the destination matrix type, and the expression traits: */ - typedef cml::matrix matrix_type; - - /* Record the type of the unroller: */ - typedef detail::MatrixAssignmentUnroller unroller; - - /* Finally, do the unroll call: */ - unroller()(dest, src, typename matrix_type::size_tag()); - /* XXX It may make sense to unroll if either side is a fixed size. */ -} - -} // namespace et -} // namespace cml - -#endif - -// ------------------------------------------------------------------------- -// vim:ft=cpp