/************************************************************************************* Grid physics library, www.github.com/paboyle/Grid Source file: ./lib/lattice/Lattice_comparison_utils.h Copyright (C) 2015 Author: Azusa Yamaguchi Author: Peter Boyle This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. See the full license in the file "LICENSE" in the top level distribution directory *************************************************************************************/ /* END LEGAL */ #ifndef GRID_COMPARISON_H #define GRID_COMPARISON_H NAMESPACE_BEGIN(Grid); ///////////////////////////////////////// // This implementation is a bit poor. // // Only support relational logical operations (<, > etc) // on scalar objects. Therefore can strip any tensor structures. // // Should guard this with isGridTensor<> enable if? ///////////////////////////////////////// // // Generic list of functors // template class veq { public: accelerator vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) == (rhs); } }; template class vne { public: accelerator vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) != (rhs); } }; template class vlt { public: accelerator vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) < (rhs); } }; template class vle { public: accelerator vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) <= (rhs); } }; template class vgt { public: accelerator vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) > (rhs); } }; template class vge { public: accelerator vInteger operator()(const lobj &lhs, const robj &rhs) { return (lhs) >= (rhs); } }; // Generic list of functors template class seq { public: accelerator Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) == (rhs); } }; template class sne { public: accelerator Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) != (rhs); } }; template class slt { public: accelerator Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) < (rhs); } }; template class sle { public: accelerator Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) <= (rhs); } }; template class sgt { public: accelerator Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) > (rhs); } }; template class sge { public: accelerator Integer operator()(const lobj &lhs, const robj &rhs) { return (lhs) >= (rhs); } }; ////////////////////////////////////////////////////////////////////////////////////////////////////// // Integer and real get extra relational functions. ////////////////////////////////////////////////////////////////////////////////////////////////////// template = 0> accelerator_inline vInteger Comparison(sfunctor sop,const vsimd & lhs, const vsimd & rhs) { typedef typename vsimd::scalar_type scalar; ExtractBuffer vlhs(vsimd::Nsimd()); // Use functors to reduce this to single implementation ExtractBuffer vrhs(vsimd::Nsimd()); ExtractBuffer vpred(vsimd::Nsimd()); vInteger ret; extract(lhs,vlhs); extract(rhs,vrhs); for(int s=0;s(ret,vpred); return ret; } template = 0> accelerator_inline vInteger Comparison(sfunctor sop,const vsimd & lhs, const typename vsimd::scalar_type & rhs) { typedef typename vsimd::scalar_type scalar; ExtractBuffer vlhs(vsimd::Nsimd()); // Use functors to reduce this to single implementation ExtractBuffer vpred(vsimd::Nsimd()); vInteger ret; extract(lhs,vlhs); for(int s=0;s(ret,vpred); return ret; } template = 0> accelerator_inline vInteger Comparison(sfunctor sop,const typename vsimd::scalar_type & lhs, const vsimd & rhs) { typedef typename vsimd::scalar_type scalar; ExtractBuffer vrhs(vsimd::Nsimd()); // Use functors to reduce this to single implementation ExtractBuffer vpred(vsimd::Nsimd()); vInteger ret; extract(rhs,vrhs); for(int s=0;s(ret,vpred); return ret; } #define DECLARE_RELATIONAL(op,functor) \ template = 0> \ accelerator_inline vInteger operator op (const vsimd & lhs, const vsimd & rhs) \ { \ typedef typename vsimd::scalar_type scalar; \ return Comparison(functor(),lhs,rhs); \ } \ template = 0> \ accelerator_inline vInteger operator op (const vsimd & lhs, const typename vsimd::scalar_type & rhs) \ { \ typedef typename vsimd::scalar_type scalar; \ return Comparison(functor(),lhs,rhs); \ } \ template = 0> \ accelerator_inline vInteger operator op (const typename vsimd::scalar_type & lhs, const vsimd & rhs) \ { \ typedef typename vsimd::scalar_type scalar; \ return Comparison(functor(),lhs,rhs); \ } \ template \ accelerator_inline vInteger operator op(const iScalar &lhs,const iScalar &rhs) \ { \ return lhs._internal op rhs._internal; \ } \ template \ accelerator_inline vInteger operator op(const iScalar &lhs,const typename vsimd::scalar_type &rhs) \ { \ return lhs._internal op rhs; \ } \ template \ accelerator_inline vInteger operator op(const typename vsimd::scalar_type &lhs,const iScalar &rhs) \ { \ return lhs op rhs._internal; \ } DECLARE_RELATIONAL(<,slt); DECLARE_RELATIONAL(<=,sle); DECLARE_RELATIONAL(>,sgt); DECLARE_RELATIONAL(>=,sge); DECLARE_RELATIONAL(==,seq); DECLARE_RELATIONAL(!=,sne); #undef DECLARE_RELATIONAL NAMESPACE_END(Grid); #endif