Commit 39baad20 authored by Carter Edwards's avatar Carter Edwards
Browse files

Kokkos: Fix example/fixture incorrect array bounds check and increase...

Kokkos: Fix example/fixture incorrect array bounds check and increase fixture's upper bound from 30 to 62 processor neighbors.
parent d762b392
......@@ -508,8 +508,8 @@ private:
static
void apply( task_root_type * t )
{
range_policy const & r = * static_cast< member_type * >( static_cast< task_base_type * >( t ) ).m_policy ;
FunctorType & f = * static_cast< FunctorType * >( static_cast< task_base_type * >( t ) );
range_policy const & r = ( * static_cast< member_type * >( static_cast< task_base_type * >( t ) ) ).m_policy ;
FunctorType & f = ( * static_cast< FunctorType * >( static_cast< task_base_type * >( t ) ) );
FunctorType const & cf = f ;
const IntType e = r.end();
......
......@@ -211,6 +211,21 @@ Perf fenl(
use_elems[0] , use_elems[1] , use_elems[2] ,
bubble_x , bubble_y , bubble_z );
{
int global_error = ! fixture.ok();
#if defined( KOKKOS_HAVE_MPI )
int local_error = global_error ;
global_error = 0 ;
MPI_Allreduce( & local_error , & global_error , 1 , MPI_INT , MPI_SUM , comm );
#endif
if ( global_error ) {
throw std::runtime_error(std::string("Error generating finite element fixture"));
}
}
//------------------------------------
const ImportType comm_nodal_import(
......
......@@ -155,6 +155,8 @@ public:
typedef Kokkos::View< const size_t * [2] , Device > comm_list_type ;
typedef Kokkos::View< const size_t * , Device > send_nodeid_type ;
inline bool ok() const { return m_box_part.ok(); }
KOKKOS_INLINE_FUNCTION
size_t node_count() const { return m_node_grid.dimension_0(); }
......
......@@ -182,6 +182,8 @@ BoxElemPart::BoxElemPart(
m_owns_node_count = 0 ;
m_send_node_count = 0 ;
m_ok = true ;
//----------------------------------------
if ( ElemLinear == elem_order ) {
......@@ -212,7 +214,7 @@ BoxElemPart::BoxElemPart(
m_owns_node_count = 1 ;
m_send_node_count = 0 ;
for ( size_t rr = 1 ; rr < m_global_size ; ++rr ) {
for ( size_t rr = 1 ; rr < m_global_size && m_ok ; ++rr ) {
const size_t rank = ( m_global_rank + rr ) % m_global_size ;
......@@ -228,8 +230,10 @@ BoxElemPart::BoxElemPart(
if ( m_owns_node[ m_owns_node_count ][1] ) {
if ( PROC_NEIGH_MAX <= m_owns_node_count ) {
throw std::runtime_error("BoxElemPart exceeded maximum neighbor count");
if ( ( PROC_NEIGH_MAX - 1 ) <= m_owns_node_count ) {
std::cout << "BoxElemPart exceeded maximum neighbor count" << std::endl ;
m_ok = false ;
break ;
}
m_owns_node[ m_owns_node_count ][0] = rank ;
......@@ -244,8 +248,10 @@ BoxElemPart::BoxElemPart(
if ( m_send_node[ m_send_node_count ][1] ) {
if ( PROC_NEIGH_MAX <= m_send_node_count ) {
throw std::runtime_error("BoxElemPart exceeded maximum neighbor count");
if ( ( PROC_NEIGH_MAX - 1 ) <= m_send_node_count ) {
std::cout << "BoxElemPart exceeded maximum neighbor count" << std::endl ;
m_ok = false ;
break ;
}
m_send_node[ m_send_node_count ][0] = rank ;
......@@ -263,6 +269,7 @@ BoxElemPart::BoxElemPart(
Kokkos::Example::box_intersect( test_box , m_owns_node_box[0] , o_node_box );
if ( Kokkos::Example::box_count( test_box ) ) {
std::cout << "Box partitioning error" << std::endl ;
std::cout << "owns_node[" << m_global_rank << "]{"
<< " [" << m_owns_node_box[0][0][0] << "," << m_owns_node_box[0][0][1] << ")"
<< " [" << m_owns_node_box[0][1][0] << "," << m_owns_node_box[0][1][1] << ")"
......@@ -273,6 +280,8 @@ BoxElemPart::BoxElemPart(
<< " [" << o_node_box[1][0] << "," << o_node_box[1][1] << ")"
<< " [" << o_node_box[2][0] << "," << o_node_box[2][1] << ")"
<< "}" << std::endl ;
m_ok = false ;
break ;
}
}
......@@ -281,7 +290,7 @@ BoxElemPart::BoxElemPart(
Kokkos::Example::box_intersect( test_box , m_uses_elem_box , elem_box );
if ( Kokkos::Example::box_count( test_box ) ) {
std::cout << "Box partitioning error" << std::endl ;
std::cout << "ElemBox[" << m_global_rank << "]{"
<< " [" << m_uses_elem_box[0][0] << "," << m_uses_elem_box[0][1] << ")"
<< " [" << m_uses_elem_box[1][0] << "," << m_uses_elem_box[1][1] << ")"
......@@ -292,6 +301,8 @@ BoxElemPart::BoxElemPart(
<< " [" << elem_box[1][0] << "," << elem_box[1][1] << ")"
<< " [" << elem_box[2][0] << "," << elem_box[2][1] << ")"
<< "}" << std::endl ;
m_ok = false ;
break ;
}
}
}
......@@ -318,15 +329,29 @@ BoxElemPart::BoxElemPart(
if ( count != Kokkos::Example::box_count( m_uses_node_box ) ) {
std::cout << "Node uses count = " << Kokkos::Example::box_count( m_uses_node_box )
<< " error count = " << count << std::endl ;
m_ok = false ;
}
}
if ( global_node_count != node_count ) {
std::cout << "Node count = " << global_node_count << " overlap error count = " << node_count << std::endl ;
m_ok = false ;
}
if ( DecomposeElem == decompose && global_elem_count != elem_count ) {
std::cout << "Elem count = " << global_elem_count << " overlap error count = " << elem_count << std::endl ;
m_ok = false ;
}
if ( ! m_ok ) {
for ( int i = 0 ; i < 3 ; ++i ) { for ( int j = 0 ; j < 2 ; ++j ) {
m_global_elem_box[i][j] = 0 ;
m_global_node_box[i][j] = 0 ;
m_uses_elem_box[i][j] = 0 ;
m_uses_node_box[i][j] = 0 ;
}}
m_owns_node_count = 0 ;
m_send_node_count = 0 ;
}
}
......
......@@ -113,6 +113,8 @@ public:
enum Decompose { DecomposeNode , DecomposeElem };
enum ElemOrder { ElemLinear , ElemQuadratic };
bool ok() const { return m_ok ; }
BoxElemPart( const ElemOrder elem_order ,
const Decompose decompose ,
const size_t global_size ,
......@@ -279,7 +281,7 @@ public:
private:
// Maximum number of processes in a neighborhood, including this process
enum { PROC_NEIGH_MAX = 32 };
enum { PROC_NEIGH_MAX = 64 };
void local( const size_t rank ,
size_t uses_elem[][2] ,
......@@ -288,6 +290,7 @@ private:
size_t m_global_size ;
size_t m_global_rank ;
Decompose m_decompose ;
ElemOrder m_elem_order ;
......@@ -304,6 +307,8 @@ private:
size_t m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
size_t m_send_node[ PROC_NEIGH_MAX ][2] ;
size_t m_send_node_count ;
bool m_ok ;
};
} // namespace Example
......
......@@ -17,14 +17,15 @@ template< class > void test_fixture();
}
}
void test_box()
int test_box( const size_t global_size
, const size_t global_box[][2]
, const bool print_verbose )
{
const size_t global_size = 2500 ;
const size_t global_box[3][2] = { { 0 , 1000 } , { 0 , 1100 } , { 0 , 1200 } };
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 ;
......@@ -40,6 +41,17 @@ void test_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 ;
......@@ -65,6 +77,7 @@ void test_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] << " )"
......@@ -75,20 +88,37 @@ void test_box()
<< " [ " << other_box[1][0] << " , " << other_box[1][1] << " )"
<< " [ " << other_box[2][0] << " , " << other_box[2][1] << " )"
<< " }" << std::endl ;
return ;
return 0 ;
}
}
neighbor_max = std::max( neighbor_max , neighbor_count );
}
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 << "max partition( global_box ) = " << global_max << std::endl ;
std::cout << "sum intersect( global_box ) = " << intersect_error << std::endl ;
std::cout << "max neighbor = " << neighbor_max << std::endl ;
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()
......@@ -208,8 +238,16 @@ void test_elem()
int main()
{
// test_box();
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< HostExecSpace >" << std::endl ;
HostExecSpace::initialize( 1 );
......
......@@ -155,6 +155,8 @@ public:
typedef Kokkos::View< const size_t * [2] , Device > comm_list_type ;
typedef Kokkos::View< const size_t * , Device > send_nodeid_type ;
inline bool ok() const { return m_box_part.ok(); }
KOKKOS_INLINE_FUNCTION
size_t node_count() const { return m_node_grid.dimension_0(); }
......
......@@ -182,6 +182,8 @@ BoxElemPart::BoxElemPart(
m_owns_node_count = 0 ;
m_send_node_count = 0 ;
m_ok = true ;
//----------------------------------------
if ( ElemLinear == elem_order ) {
......@@ -212,7 +214,7 @@ BoxElemPart::BoxElemPart(
m_owns_node_count = 1 ;
m_send_node_count = 0 ;
for ( size_t rr = 1 ; rr < m_global_size ; ++rr ) {
for ( size_t rr = 1 ; rr < m_global_size && m_ok ; ++rr ) {
const size_t rank = ( m_global_rank + rr ) % m_global_size ;
......@@ -228,8 +230,10 @@ BoxElemPart::BoxElemPart(
if ( m_owns_node[ m_owns_node_count ][1] ) {
if ( PROC_NEIGH_MAX <= m_owns_node_count ) {
throw std::runtime_error("BoxElemPart exceeded maximum neighbor count");
if ( ( PROC_NEIGH_MAX - 1 ) <= m_owns_node_count ) {
std::cout << "BoxElemPart exceeded maximum neighbor count" << std::endl ;
m_ok = false ;
break ;
}
m_owns_node[ m_owns_node_count ][0] = rank ;
......@@ -244,8 +248,10 @@ BoxElemPart::BoxElemPart(
if ( m_send_node[ m_send_node_count ][1] ) {
if ( PROC_NEIGH_MAX <= m_send_node_count ) {
throw std::runtime_error("BoxElemPart exceeded maximum neighbor count");
if ( ( PROC_NEIGH_MAX - 1 ) <= m_send_node_count ) {
std::cout << "BoxElemPart exceeded maximum neighbor count" << std::endl ;
m_ok = false ;
break ;
}
m_send_node[ m_send_node_count ][0] = rank ;
......@@ -263,6 +269,7 @@ BoxElemPart::BoxElemPart(
Kokkos::Example::box_intersect( test_box , m_owns_node_box[0] , o_node_box );
if ( Kokkos::Example::box_count( test_box ) ) {
std::cout << "Box partitioning error" << std::endl ;
std::cout << "owns_node[" << m_global_rank << "]{"
<< " [" << m_owns_node_box[0][0][0] << "," << m_owns_node_box[0][0][1] << ")"
<< " [" << m_owns_node_box[0][1][0] << "," << m_owns_node_box[0][1][1] << ")"
......@@ -273,6 +280,8 @@ BoxElemPart::BoxElemPart(
<< " [" << o_node_box[1][0] << "," << o_node_box[1][1] << ")"
<< " [" << o_node_box[2][0] << "," << o_node_box[2][1] << ")"
<< "}" << std::endl ;
m_ok = false ;
break ;
}
}
......@@ -281,7 +290,7 @@ BoxElemPart::BoxElemPart(
Kokkos::Example::box_intersect( test_box , m_uses_elem_box , elem_box );
if ( Kokkos::Example::box_count( test_box ) ) {
std::cout << "Box partitioning error" << std::endl ;
std::cout << "ElemBox[" << m_global_rank << "]{"
<< " [" << m_uses_elem_box[0][0] << "," << m_uses_elem_box[0][1] << ")"
<< " [" << m_uses_elem_box[1][0] << "," << m_uses_elem_box[1][1] << ")"
......@@ -292,6 +301,8 @@ BoxElemPart::BoxElemPart(
<< " [" << elem_box[1][0] << "," << elem_box[1][1] << ")"
<< " [" << elem_box[2][0] << "," << elem_box[2][1] << ")"
<< "}" << std::endl ;
m_ok = false ;
break ;
}
}
}
......@@ -318,15 +329,29 @@ BoxElemPart::BoxElemPart(
if ( count != Kokkos::Example::box_count( m_uses_node_box ) ) {
std::cout << "Node uses count = " << Kokkos::Example::box_count( m_uses_node_box )
<< " error count = " << count << std::endl ;
m_ok = false ;
}
}
if ( global_node_count != node_count ) {
std::cout << "Node count = " << global_node_count << " overlap error count = " << node_count << std::endl ;
m_ok = false ;
}
if ( DecomposeElem == decompose && global_elem_count != elem_count ) {
std::cout << "Elem count = " << global_elem_count << " overlap error count = " << elem_count << std::endl ;
m_ok = false ;
}
if ( ! m_ok ) {
for ( int i = 0 ; i < 3 ; ++i ) { for ( int j = 0 ; j < 2 ; ++j ) {
m_global_elem_box[i][j] = 0 ;
m_global_node_box[i][j] = 0 ;
m_uses_elem_box[i][j] = 0 ;
m_uses_node_box[i][j] = 0 ;
}}
m_owns_node_count = 0 ;
m_send_node_count = 0 ;
}
}
......
......@@ -113,6 +113,8 @@ public:
enum Decompose { DecomposeNode , DecomposeElem };
enum ElemOrder { ElemLinear , ElemQuadratic };
bool ok() const { return m_ok ; }
BoxElemPart( const ElemOrder elem_order ,
const Decompose decompose ,
const size_t global_size ,
......@@ -279,7 +281,7 @@ public:
private:
// Maximum number of processes in a neighborhood, including this process
enum { PROC_NEIGH_MAX = 32 };
enum { PROC_NEIGH_MAX = 64 };
void local( const size_t rank ,
size_t uses_elem[][2] ,
......@@ -288,6 +290,7 @@ private:
size_t m_global_size ;
size_t m_global_rank ;
Decompose m_decompose ;
ElemOrder m_elem_order ;
......@@ -304,6 +307,8 @@ private:
size_t m_send_node_box[ PROC_NEIGH_MAX ][3][2] ;
size_t m_send_node[ PROC_NEIGH_MAX ][2] ;
size_t m_send_node_count ;
bool m_ok ;
};
} // namespace Example
......
......@@ -272,6 +272,10 @@ public:
, response()
, perf()
{
if ( maximum(comm, ( fixture.ok() ? 0 : 1 ) ) ) {
throw std::runtime_error(std::string("Problem fixture setup failed"));
}
perf.global_elem_count = fixture.elem_count_global();
perf.global_node_count = fixture.node_count_global();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment