/* //@HEADER // ************************************************************************ // // Kokkos v. 2.0 // Copyright (2014) Sandia Corporation // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // 3. Neither the name of the Corporation nor the names of the // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov) // // ************************************************************************ //@HEADER */ #include namespace TestCXX11 { template struct FunctorAddTest{ typedef Kokkos::View view_type; view_type a_, b_; typedef DeviceType execution_space; FunctorAddTest(view_type & a, view_type &b):a_(a),b_(b) {} void operator() (const int& i) const { b_(i,0) = a_(i,1) + a_(i,2); b_(i,1) = a_(i,0) - a_(i,3); b_(i,2) = a_(i,4) + a_(i,0); b_(i,3) = a_(i,2) - a_(i,1); b_(i,4) = a_(i,3) + a_(i,4); } typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ; void operator() (const team_member & dev) const { int i = dev.league_rank()*dev.team_size() + dev.team_rank(); b_(i,0) = a_(i,1) + a_(i,2); b_(i,1) = a_(i,0) - a_(i,3); b_(i,2) = a_(i,4) + a_(i,0); b_(i,3) = a_(i,2) - a_(i,1); b_(i,4) = a_(i,3) + a_(i,4); } }; template double AddTestFunctor() { typedef Kokkos::TeamPolicy policy_type ; Kokkos::View a("A",100,5); Kokkos::View b("B",100,5); typename Kokkos::View::HostMirror h_a = Kokkos::create_mirror_view(a); typename Kokkos::View::HostMirror h_b = Kokkos::create_mirror_view(b); for(int i=0;i<100;i++) { for(int j=0;j<5;j++) h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j; } Kokkos::deep_copy(a,h_a); if(PWRTest==false) Kokkos::parallel_for(100,FunctorAddTest(a,b)); else Kokkos::parallel_for(policy_type(25,4),FunctorAddTest(a,b)); Kokkos::deep_copy(h_b,b); double result = 0; for(int i=0;i<100;i++) { for(int j=0;j<5;j++) result += h_b(i,j); } return result; } #if defined (KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA) template double AddTestLambda() { typedef Kokkos::TeamPolicy policy_type ; Kokkos::View a("A",100,5); Kokkos::View b("B",100,5); typename Kokkos::View::HostMirror h_a = Kokkos::create_mirror_view(a); typename Kokkos::View::HostMirror h_b = Kokkos::create_mirror_view(b); for(int i=0;i<100;i++) { for(int j=0;j<5;j++) h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j; } Kokkos::deep_copy(a,h_a); if(PWRTest==false) { Kokkos::parallel_for(100,[=](const int& i) { b(i,0) = a(i,1) + a(i,2); b(i,1) = a(i,0) - a(i,3); b(i,2) = a(i,4) + a(i,0); b(i,3) = a(i,2) - a(i,1); b(i,4) = a(i,3) + a(i,4); }); } else { typedef typename policy_type::member_type team_member ; Kokkos::parallel_for(policy_type(25,4),[=](const team_member & dev) { int i = dev.league_rank()*dev.team_size() + dev.team_rank(); b(i,0) = a(i,1) + a(i,2); b(i,1) = a(i,0) - a(i,3); b(i,2) = a(i,4) + a(i,0); b(i,3) = a(i,2) - a(i,1); b(i,4) = a(i,3) + a(i,4); }); } Kokkos::deep_copy(h_b,b); double result = 0; for(int i=0;i<100;i++) { for(int j=0;j<5;j++) result += h_b(i,j); } return result; } #else template double AddTestLambda() { return AddTestFunctor(); } #endif template struct FunctorReduceTest{ typedef Kokkos::View view_type; view_type a_; typedef DeviceType execution_space; typedef double value_type; FunctorReduceTest(view_type & a):a_(a) {} KOKKOS_INLINE_FUNCTION void operator() (const int& i, value_type& sum) const { sum += a_(i,1) + a_(i,2); sum += a_(i,0) - a_(i,3); sum += a_(i,4) + a_(i,0); sum += a_(i,2) - a_(i,1); sum += a_(i,3) + a_(i,4); } typedef typename Kokkos::TeamPolicy< execution_space >::member_type team_member ; KOKKOS_INLINE_FUNCTION void operator() (const team_member & dev, value_type& sum) const { int i = dev.league_rank()*dev.team_size() + dev.team_rank(); sum += a_(i,1) + a_(i,2); sum += a_(i,0) - a_(i,3); sum += a_(i,4) + a_(i,0); sum += a_(i,2) - a_(i,1); sum += a_(i,3) + a_(i,4); } KOKKOS_INLINE_FUNCTION void init(value_type& update) const {update = 0.0;} KOKKOS_INLINE_FUNCTION void join(volatile value_type& update, volatile value_type const& input) const {update += input;} }; template double ReduceTestFunctor() { typedef Kokkos::TeamPolicy policy_type ; typedef Kokkos::View view_type ; typedef Kokkos::View unmanaged_result ; view_type a("A",100,5); typename view_type::HostMirror h_a = Kokkos::create_mirror_view(a); for(int i=0;i<100;i++) { for(int j=0;j<5;j++) h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j; } Kokkos::deep_copy(a,h_a); double result = 0.0; if(PWRTest==false) Kokkos::parallel_reduce(100,FunctorReduceTest(a), unmanaged_result( & result )); else Kokkos::parallel_reduce(policy_type(25,4),FunctorReduceTest(a), unmanaged_result( & result )); return result; } #if defined (KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA) template double ReduceTestLambda() { typedef Kokkos::TeamPolicy policy_type ; typedef Kokkos::View view_type ; typedef Kokkos::View unmanaged_result ; view_type a("A",100,5); typename view_type::HostMirror h_a = Kokkos::create_mirror_view(a); for(int i=0;i<100;i++) { for(int j=0;j<5;j++) h_a(i,j) = 0.1*i/(1.1*j+1.0) + 0.5*j; } Kokkos::deep_copy(a,h_a); double result = 0.0; if(PWRTest==false) { Kokkos::parallel_reduce(100,[=](const int& i, double& sum) { sum += a(i,1) + a(i,2); sum += a(i,0) - a(i,3); sum += a(i,4) + a(i,0); sum += a(i,2) - a(i,1); sum += a(i,3) + a(i,4); }, unmanaged_result( & result ) ); } else { typedef typename policy_type::member_type team_member ; Kokkos::parallel_reduce(policy_type(25,4),[=](const team_member & dev, double& sum) { int i = dev.league_rank()*dev.team_size() + dev.team_rank(); sum += a(i,1) + a(i,2); sum += a(i,0) - a(i,3); sum += a(i,4) + a(i,0); sum += a(i,2) - a(i,1); sum += a(i,3) + a(i,4); }, unmanaged_result( & result ) ); } return result; } #else template double ReduceTestLambda() { return ReduceTestFunctor(); } #endif template double TestVariantLambda(int test) { switch (test) { case 1: return AddTestLambda(); case 2: return AddTestLambda(); case 3: return ReduceTestLambda(); case 4: return ReduceTestLambda(); } return 0; } template double TestVariantFunctor(int test) { switch (test) { case 1: return AddTestFunctor(); case 2: return AddTestFunctor(); case 3: return ReduceTestFunctor(); case 4: return ReduceTestFunctor(); } return 0; } template bool Test(int test) { #ifdef KOKKOS_HAVE_CXX11_DISPATCH_LAMBDA double res_functor = TestVariantFunctor(test); double res_lambda = TestVariantLambda(test); char testnames[5][256] = {" " ,"AddTest","AddTest TeamPolicy" ,"ReduceTest","ReduceTest TeamPolicy" }; bool passed = true; if ( res_functor != res_lambda ) { passed = false; std::cout << "CXX11 ( test = '" << testnames[test] << "' FAILED : " << res_functor << " != " << res_lambda << std::endl ; } return passed ; #else return true; #endif } }