Page MenuHomec4science

Main.cpp
No OneTemporary

File Metadata

Created
Thu, Nov 7, 20:01

Main.cpp

//@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 <utility>
#include <iostream>
#include <Kokkos_Core.hpp>
#include <BoxElemPart.hpp>
namespace Kokkos {
namespace Example {
template< class > void test_fixture();
}
}
int test_box( const size_t global_size
, const size_t global_box[][2]
, const bool print_verbose )
{
size_t global_count = 0 ;
size_t global_max = 0 ;
size_t global_min = Kokkos::Example::box_count( global_box );
size_t global_box_max[3][2] = { { 0 , 0 } , { 0 , 0 } , { 0 , 0 } };
size_t global_box_min[3][2] = { { 0 , global_box[0][1] } , { 0 , global_box[1][1] } , { 0 , global_box[2][1] } };
size_t intersect_error = 0 ;
size_t neighbor_max = 0 ;
for ( size_t global_rank = 0 ; global_rank < global_size ; ++global_rank ) {
size_t box[3][2] = { { 0 , global_box[0][1] } , { 0 , global_box[1][1] } , { 0 , global_box[2][1] } };
size_t ghost_box[3][2] ;
size_t neighbor_count = 0 ;
Kokkos::Example::box_partition( global_size , global_rank , global_box , box );
Kokkos::Example::box_ghost_layer( global_box , box , 1 , ghost_box );
{
const size_t n = Kokkos::Example::box_count( box );
for ( int i = 0 ; i < 3 ; ++i ) {
if ( ( box[i][1] - box[i][0] ) < ( global_box_min[i][1] - global_box_min[i][0] ) ) {
global_box_min[i][0] = box[i][0] ;
global_box_min[i][1] = box[i][1] ;
}
if ( ( box[i][1] - box[i][0] ) > ( global_box_max[i][1] - global_box_max[i][0] ) ) {
global_box_max[i][0] = box[i][0] ;
global_box_max[i][1] = box[i][1] ;
}
}
global_max = std::max( global_max , n );
global_min = std::min( global_min , n );
global_count += n ;
}
for ( size_t other_rank = 0 ; other_rank < global_size ; ++other_rank ) {
if ( other_rank == global_rank ) continue ;
size_t other_box[3][2] = { { 0 , global_box[0][1] } , { 0 , global_box[1][1] } , { 0 , global_box[2][1] } };
size_t intersect_box[3][2] ;
Kokkos::Example::box_partition( global_size , other_rank , global_box , other_box );
Kokkos::Example::box_intersect( intersect_box , box , other_box );
const size_t n = Kokkos::Example::box_count( intersect_box );
intersect_error += n ;
Kokkos::Example::box_intersect( intersect_box , ghost_box , other_box );
neighbor_count += Kokkos::Example::box_count( intersect_box ) ? 1 : 0 ;
if ( n ) {
std::cout << "box partition intersection error" << std::endl ;
std::cout << "box = {"
<< " [ " << box[0][0] << " , " << box[0][1] << " )"
<< " [ " << box[1][0] << " , " << box[1][1] << " )"
<< " [ " << box[2][0] << " , " << box[2][1] << " )"
<< " }" << std::endl ;
std::cout << "other_box = {"
<< " [ " << other_box[0][0] << " , " << other_box[0][1] << " )"
<< " [ " << other_box[1][0] << " , " << other_box[1][1] << " )"
<< " [ " << other_box[2][0] << " , " << other_box[2][1] << " )"
<< " }" << std::endl ;
return 0 ;
}
}
neighbor_max = std::max( neighbor_max , neighbor_count );
}
if ( print_verbose ) {
std::cout << "global_part = " << global_size << std::endl ;
std::cout << "global_box = { "
<< " [ " << global_box[0][0] << " .. " << global_box[0][1] << " ) X"
<< " [ " << global_box[1][0] << " .. " << global_box[1][1] << " ) X"
<< " [ " << global_box[2][0] << " .. " << global_box[2][1] << " )"
<< " }" << std::endl ;
std::cout << "count( global_box ) = " << Kokkos::Example::box_count( global_box ) << std::endl ;
std::cout << "sum partition( global_box ) = " << global_count << std::endl ;
std::cout << "avg partition( global_box ) = " << size_t( double(global_count) / double(global_size)) << std::endl ;
std::cout << "min partition( global_box ) = " << global_min << std::endl ;
std::cout << "min part X ( global_box ) = [ " << global_box_min[0][0] << " .. " << global_box_min[0][1] << " )" << std::endl ;
std::cout << "min part Y ( global_box ) = [ " << global_box_min[1][0] << " .. " << global_box_min[1][1] << " )" << std::endl ;
std::cout << "min part Z ( global_box ) = [ " << global_box_min[2][0] << " .. " << global_box_min[2][1] << " )" << std::endl ;
std::cout << "max partition( global_box ) = " << global_max << std::endl ;
std::cout << "max part X ( global_box ) = [ " << global_box_max[0][0] << " .. " << global_box_max[0][1] << " )" << std::endl ;
std::cout << "max part Y ( global_box ) = [ " << global_box_max[1][0] << " .. " << global_box_max[1][1] << " )" << std::endl ;
std::cout << "max part Z ( global_box ) = [ " << global_box_max[2][0] << " .. " << global_box_max[2][1] << " )" << std::endl ;
std::cout << "sum intersect( global_box ) = " << intersect_error << std::endl ;
std::cout << "max neighbor = " << neighbor_max << std::endl ;
}
return neighbor_max ;
}
void test_elem()
{
const Kokkos::Example::BoxElemPart::Decompose
decompose = Kokkos::Example::BoxElemPart:: DecomposeElem ; // DecomposeElem | DecomposeNode ;
const size_t global_size = 256 ;
const size_t global_nx = 100 ;
const size_t global_ny = 120 ;
const size_t global_nz = 140 ;
double node_count_avg = 0 ;
size_t node_count_max = 0 ;
size_t node_count_min = ( global_nx + 1 ) * ( global_ny + 1 ) * ( global_nz + 1 );
double elem_count_avg = 0 ;
size_t elem_count_max = 0 ;
size_t elem_count_min = global_nx * global_ny * global_nz ;
double recv_count_avg = 0 ;
size_t recv_count_max = 0 ;
size_t recv_count_min = global_size ;
double send_count_avg = 0 ;
size_t send_count_max = 0 ;
size_t send_count_min = global_size ;
for ( size_t r = 0 ; r < global_size ; ++r ) {
const Kokkos::Example::BoxElemPart
fixture( Kokkos::Example::BoxElemPart::ElemLinear ,
decompose , global_size , r , global_nx , global_ny , global_nz );
// Print a sample:
// if ( r == global_size * 2 / 3 ) fixture.print( std::cout );
// Verify recv/send alignment:
{
size_t recv_lid = fixture.owns_node_count();
for ( size_t i = 0 ; i < fixture.recv_node_msg_count() ; ++i ) {
const size_t recv_rank = fixture.recv_node_rank( i );
const size_t recv_count = fixture.recv_node_count( i );
const Kokkos::Example::BoxElemPart other_fixture(
Kokkos::Example::BoxElemPart::ElemLinear ,
decompose , global_size , recv_rank , global_nx , global_ny , global_nz );
size_t send_item = 0 ;
size_t j = 0 ;
while ( j < other_fixture.send_node_msg_count() && other_fixture.send_node_rank(j) != r ) {
send_item += other_fixture.send_node_count( j );
++j ;
}
if ( recv_count != other_fixture.send_node_count(j) ) {
std::cout << "Error P[" << r << "].recv(" << recv_count << ") != "
<< "P[" << recv_rank << "].send(" << other_fixture.send_node_count(j) << ")"
<< std::endl ;
}
else {
for ( size_t k = 0 ; k < recv_count ; ++k , ++send_item , ++recv_lid ) {
const size_t send_lid = other_fixture.send_node_id( send_item );
size_t recv_coord[3] , send_coord[3] ;
fixture.local_node_coord( recv_lid , recv_coord );
other_fixture.local_node_coord( send_lid , send_coord );
if ( recv_coord[0] != send_coord[0] ||
recv_coord[1] != send_coord[1] ||
recv_coord[2] != send_coord[2] ) {
std::cout << "Error P[" << r << "].recv[" << recv_lid << "]{ "
<< recv_coord[0] << " , "
<< recv_coord[1] << " , "
<< recv_coord[2] << " } != "
<< "P[" << recv_rank << "].send[" << send_lid << "]{ "
<< send_coord[0] << " , "
<< send_coord[1] << " , "
<< send_coord[2] << " }"
<< std::endl ;
}
}
}
}
}
node_count_avg += fixture.owns_node_count();
elem_count_avg += fixture.uses_elem_count();
recv_count_avg += fixture.recv_node_msg_count();
send_count_avg += fixture.send_node_msg_count();
elem_count_min = std::min( (size_t) fixture.uses_elem_count() , elem_count_min );
elem_count_max = std::max( (size_t) fixture.uses_elem_count() , elem_count_max );
node_count_min = std::min( (size_t) fixture.owns_node_count() , node_count_min );
node_count_max = std::max( (size_t) fixture.owns_node_count() , node_count_max );
recv_count_max = std::max( (size_t) fixture.recv_node_msg_count() , recv_count_max );
recv_count_min = std::min( (size_t) fixture.recv_node_msg_count() , recv_count_min );
send_count_max = std::max( (size_t) fixture.send_node_msg_count() , send_count_max );
send_count_min = std::min( (size_t) fixture.send_node_msg_count() , send_count_min );
}
node_count_avg /= double(global_size);
elem_count_avg /= double(global_size);
recv_count_avg /= double(global_size);
send_count_avg /= double(global_size);
std::cout << "Elem min(" << elem_count_min << ") avg(" << elem_count_avg << ") max(" << elem_count_max << ") " << std::endl
<< "Node min(" << node_count_min << ") avg(" << node_count_avg << ") max(" << node_count_max << ") " << std::endl
<< "Recv min(" << recv_count_min << ") avg(" << recv_count_avg << ") max(" << recv_count_max << ") " << std::endl
<< "Send min(" << send_count_min << ") avg(" << send_count_avg << ") max(" << send_count_max << ") " << std::endl
;
}
int main()
{
for ( int i = 1 ; i <= 32 ; ++i ) {
const size_t global_size = 16 * i ;
const size_t global_box[3][2] = { { 0 , 65 } , { 0 , 65 } , { 0 , 65 } };
if ( 30 < test_box( global_size , global_box , false ) ) {
test_box( global_size , global_box , true );
}
}
// test_elem();
{
std::cout << "test_fixture< Host >" << std::endl ;
Kokkos::HostSpace::execution_space::initialize( 1 );
Kokkos::Example::test_fixture< Kokkos::HostSpace::execution_space >();
Kokkos::HostSpace::execution_space::finalize();
}
#if defined( KOKKOS_HAVE_CUDA )
{
std::cout << "test_fixture< Cuda >" << std::endl ;
Kokkos::HostSpace::execution_space::initialize();
Kokkos::Cuda::initialize( Kokkos::Cuda::SelectDevice(0) );
Kokkos::Example::test_fixture< Kokkos::Cuda >();
Kokkos::Cuda::finalize();
Kokkos::HostSpace::execution_space::finalize();
}
#endif
}

Event Timeline