|
Sierra Toolkit
Version of the Day
|
00001 /*------------------------------------------------------------------------*/ 00002 /* Copyright 2010 Sandia Corporation. */ 00003 /* Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive */ 00004 /* license for use of this work by or on behalf of the U.S. Government. */ 00005 /* Export of this program may require a license from the */ 00006 /* United States Government. */ 00007 /*------------------------------------------------------------------------*/ 00008 00009 00010 #include <stddef.h> 00011 #include <stdexcept> 00012 #include <sstream> 00013 00014 #include <stk_util/parallel/Parallel.hpp> 00015 00016 #include <stk_mesh/base/DataTraits.hpp> 00017 #include <stk_mesh/base/DataTraitsEnum.hpp> 00018 #include <stk_mesh/base/DataTraitsClass.hpp> 00019 00020 #include <stk_util/unit_test_support/stk_utest_macros.hpp> 00021 00022 using stk_classic::mesh::DataTraits; 00023 using stk_classic::mesh::data_traits; 00024 using stk_classic::CommAll; 00025 00026 //---------------------------------------------------------------------- 00027 00028 namespace { 00029 00030 STKUNIT_UNIT_TEST(TestDataTraits, testVoid) 00031 { 00032 // Test the DataTrait for void 00033 00034 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00035 MPI_Barrier( pm ); 00036 00037 const DataTraits & traits = data_traits<void>(); 00038 00039 STKUNIT_ASSERT( traits.type_info == typeid(void) ); 00040 STKUNIT_ASSERT_EQUAL( traits.size_of , size_t(0) ); 00041 STKUNIT_ASSERT_EQUAL( traits.alignment_of , size_t(0) ); 00042 STKUNIT_ASSERT_EQUAL( traits.stride_of , size_t(0) ); 00043 STKUNIT_ASSERT_EQUAL( traits.is_void , true ); 00044 STKUNIT_ASSERT_EQUAL( traits.is_integral , false ); 00045 STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false ); 00046 STKUNIT_ASSERT_EQUAL( traits.is_array , false ); 00047 STKUNIT_ASSERT_EQUAL( traits.is_pointer , false ); 00048 STKUNIT_ASSERT_EQUAL( traits.is_enum , false ); 00049 STKUNIT_ASSERT_EQUAL( traits.is_class , false ); 00050 STKUNIT_ASSERT_EQUAL( traits.is_pod , false ); 00051 STKUNIT_ASSERT_EQUAL( traits.is_signed , false ); 00052 STKUNIT_ASSERT_EQUAL( traits.is_unsigned , false ); 00053 00054 STKUNIT_ASSERT( ! traits.remove_pointer ); 00055 STKUNIT_ASSERT( traits.enum_info.empty() ); 00056 STKUNIT_ASSERT( traits.class_info.empty() ); 00057 00058 STKUNIT_ASSERT_THROW( traits.construct( NULL , 0 ) , std::runtime_error ); 00059 STKUNIT_ASSERT_THROW( traits.destroy( NULL , 0 ) , std::runtime_error ); 00060 STKUNIT_ASSERT_THROW( traits.copy( NULL , NULL , 0 ) , std::runtime_error ); 00061 STKUNIT_ASSERT_THROW( traits.sum( NULL , NULL , 0 ) , std::runtime_error ); 00062 STKUNIT_ASSERT_THROW( traits.max( NULL , NULL , 0 ) , std::runtime_error ); 00063 STKUNIT_ASSERT_THROW( traits.min( NULL , NULL , 0 ) , std::runtime_error ); 00064 STKUNIT_ASSERT_THROW( traits.bit_and( NULL, NULL, 0 ), std::runtime_error ); 00065 STKUNIT_ASSERT_THROW( traits.bit_or( NULL , NULL, 0 ), std::runtime_error ); 00066 STKUNIT_ASSERT_THROW( traits.bit_xor( NULL, NULL, 0 ), std::runtime_error ); 00067 STKUNIT_ASSERT_THROW( traits.print( std::cout, NULL, 0), std::runtime_error); 00068 00069 CommAll comm( pm ); 00070 STKUNIT_ASSERT_THROW( traits.pack( comm.send_buffer(0) , NULL , 0 ), std::runtime_error ); 00071 comm.allocate_buffers( 0 ); 00072 comm.communicate(); 00073 STKUNIT_ASSERT_THROW( traits.unpack( comm.recv_buffer(0) , NULL , 0 ), std::runtime_error ); 00074 } 00075 00076 //---------------------------------------------------------------------- 00077 00078 template< typename T , bool is_integral , bool is_signed > 00079 void test_fundamental_type() 00080 { 00081 // Test DataTrait for fundamental type T 00082 00083 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00084 int p_rank = stk_classic::parallel_machine_rank( pm ); 00085 int p_size = stk_classic::parallel_machine_size( pm ); 00086 MPI_Barrier( pm ); 00087 00088 // Test data trait properties of type T 00089 const DataTraits & traits = data_traits<T>(); 00090 STKUNIT_ASSERT( traits.type_info == typeid(T) ); 00091 STKUNIT_ASSERT_EQUAL( traits.size_of , sizeof(T) ); 00092 STKUNIT_ASSERT_EQUAL( traits.alignment_of , sizeof(T) ); 00093 STKUNIT_ASSERT_EQUAL( traits.stride_of , sizeof(T) ); 00094 STKUNIT_ASSERT_EQUAL( traits.is_void , false ); 00095 STKUNIT_ASSERT_EQUAL( traits.is_integral , is_integral ); 00096 STKUNIT_ASSERT_EQUAL( traits.is_floating_point , ! is_integral ); 00097 STKUNIT_ASSERT_EQUAL( traits.is_array , false ); 00098 STKUNIT_ASSERT_EQUAL( traits.is_pointer , false ); 00099 STKUNIT_ASSERT_EQUAL( traits.is_enum , false ); 00100 STKUNIT_ASSERT_EQUAL( traits.is_class , false ); 00101 STKUNIT_ASSERT_EQUAL( traits.is_pod , true ); 00102 STKUNIT_ASSERT_EQUAL( traits.is_signed , is_signed ); 00103 STKUNIT_ASSERT_EQUAL( traits.is_unsigned , is_integral && ! is_signed); 00104 00105 STKUNIT_ASSERT( ! traits.remove_pointer ); 00106 STKUNIT_ASSERT( traits.enum_info.empty() ); 00107 STKUNIT_ASSERT( traits.class_info.empty() ); 00108 00109 const unsigned array_size = 3; 00110 const T a[array_size] = { T(1) , T(2) , T(4) }; 00111 T b[array_size] ; 00112 00113 // Test data trait basic operations on type T 00114 traits.construct( b , array_size ); 00115 STKUNIT_ASSERT_EQUAL( T(0) , b[0] ); 00116 STKUNIT_ASSERT_EQUAL( T(0) , b[1] ); 00117 STKUNIT_ASSERT_EQUAL( T(0) , b[2] ); 00118 00119 traits.copy( b , a , array_size ); 00120 STKUNIT_ASSERT_EQUAL( T(1) , b[0] ); 00121 STKUNIT_ASSERT_EQUAL( T(2) , b[1] ); 00122 STKUNIT_ASSERT_EQUAL( T(4) , b[2] ); 00123 00124 traits.sum( b , a , array_size ); 00125 STKUNIT_ASSERT_EQUAL( T(2) , b[0] ); 00126 STKUNIT_ASSERT_EQUAL( T(4) , b[1] ); 00127 STKUNIT_ASSERT_EQUAL( T(8) , b[2] ); 00128 00129 traits.min( b , a , array_size ); 00130 STKUNIT_ASSERT_EQUAL( T(1) , b[0] ); 00131 STKUNIT_ASSERT_EQUAL( T(2) , b[1] ); 00132 STKUNIT_ASSERT_EQUAL( T(4) , b[2] ); 00133 00134 traits.sum( b , a , array_size ); 00135 traits.max( b , a , array_size ); 00136 STKUNIT_ASSERT_EQUAL( T(2) , b[0] ); 00137 STKUNIT_ASSERT_EQUAL( T(4) , b[1] ); 00138 STKUNIT_ASSERT_EQUAL( T(8) , b[2] ); 00139 00140 if ( is_integral ) { 00141 // Test integral-specific operations 00142 traits.bit_or( b , a , array_size ); 00143 STKUNIT_ASSERT_EQUAL( T(3) , b[0] ); 00144 STKUNIT_ASSERT_EQUAL( T(6) , b[1] ); 00145 STKUNIT_ASSERT_EQUAL( T(12) , b[2] ); 00146 00147 traits.bit_and( b , a , array_size ); 00148 STKUNIT_ASSERT_EQUAL( T(1) , b[0] ); 00149 STKUNIT_ASSERT_EQUAL( T(2) , b[1] ); 00150 STKUNIT_ASSERT_EQUAL( T(4) , b[2] ); 00151 00152 traits.bit_xor( b , a , array_size ); 00153 STKUNIT_ASSERT_EQUAL( T(0) , b[0] ); 00154 STKUNIT_ASSERT_EQUAL( T(0) , b[1] ); 00155 STKUNIT_ASSERT_EQUAL( T(0) , b[2] ); 00156 } 00157 else { 00158 // Test unsupported operations 00159 STKUNIT_ASSERT_THROW(traits.bit_or (b, a, array_size), std::runtime_error); 00160 STKUNIT_ASSERT_THROW(traits.bit_and(b, a, array_size), std::runtime_error); 00161 STKUNIT_ASSERT_THROW(traits.bit_xor(b, a, array_size), std::runtime_error); 00162 } 00163 00164 // Test data trait pack/unpack (communication) of type T 00165 traits.construct( b , array_size ); 00166 CommAll comm( pm ); 00167 traits.pack( comm.send_buffer(0) , a , array_size ); 00168 comm.allocate_buffers( 0 ); 00169 traits.pack( comm.send_buffer(0) , a , array_size ); 00170 comm.communicate(); 00171 if (p_rank == 0) { 00172 for (int proc_id = 0; proc_id < p_size; ++proc_id) { 00173 traits.unpack( comm.recv_buffer(proc_id) , b , array_size ); 00174 STKUNIT_ASSERT_EQUAL( T(1) , b[0] ); 00175 STKUNIT_ASSERT_EQUAL( T(2) , b[1] ); 00176 STKUNIT_ASSERT_EQUAL( T(4) , b[2] ); 00177 } 00178 } 00179 00180 // Test data trait print of type T 00181 std::ostringstream oss; 00182 oss << traits.name << " " ; 00183 traits.print( oss , a , array_size ); 00184 oss << std::endl ; 00185 00186 // Test data trait destruction (no-op in this case) 00187 traits.destroy( b , array_size ); 00188 } 00189 00190 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_bool) 00191 { 00192 test_fundamental_type<char, true, true>(); 00193 } 00194 00195 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedchar) 00196 { 00197 test_fundamental_type<unsigned char, true, false>(); 00198 } 00199 00200 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_short) 00201 { 00202 test_fundamental_type<short, true, true>(); 00203 } 00204 00205 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedshort) 00206 { 00207 test_fundamental_type<unsigned short, true, false>(); 00208 } 00209 00210 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_int) 00211 { 00212 test_fundamental_type<int, true, true>(); 00213 } 00214 00215 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedint) 00216 { 00217 test_fundamental_type<unsigned int, true, false>(); 00218 } 00219 00220 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_long) 00221 { 00222 test_fundamental_type<long, true, true>(); 00223 } 00224 00225 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedlong) 00226 { 00227 test_fundamental_type<unsigned long, true, false>(); 00228 } 00229 00230 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_float) 00231 { 00232 test_fundamental_type<float, false, false>(); 00233 } 00234 00235 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_double) 00236 { 00237 test_fundamental_type<double, false, false>(); 00238 } 00239 00240 //---------------------------------------------------------------------- 00241 00242 template< typename T > 00243 void test_fundamental_pointer() 00244 { 00245 // Test DataTrait for fundamenter pointer type T* 00246 00247 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00248 MPI_Barrier( pm ); 00249 00250 // Test data trait properties of type T* 00251 const DataTraits & traits = data_traits<T*>(); 00252 STKUNIT_ASSERT( traits.type_info == typeid(T*) ); 00253 STKUNIT_ASSERT_EQUAL( traits.size_of , sizeof(T*) ); 00254 STKUNIT_ASSERT_EQUAL( traits.alignment_of , sizeof(T*) ); 00255 STKUNIT_ASSERT_EQUAL( traits.stride_of , sizeof(T*) ); 00256 STKUNIT_ASSERT_EQUAL( traits.is_void , false ); 00257 STKUNIT_ASSERT_EQUAL( traits.is_integral , false ); 00258 STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false ); 00259 STKUNIT_ASSERT_EQUAL( traits.is_array , false ); 00260 STKUNIT_ASSERT_EQUAL( traits.is_pointer , true ); 00261 STKUNIT_ASSERT_EQUAL( traits.is_enum , false ); 00262 STKUNIT_ASSERT_EQUAL( traits.is_class , false ); 00263 STKUNIT_ASSERT_EQUAL( traits.is_pod , false ); 00264 STKUNIT_ASSERT_EQUAL( traits.is_signed , false ); 00265 STKUNIT_ASSERT_EQUAL( traits.is_unsigned , false ); 00266 00267 STKUNIT_ASSERT( traits.remove_pointer == & data_traits<T>() ); 00268 STKUNIT_ASSERT( traits.enum_info.empty() ); 00269 STKUNIT_ASSERT( traits.class_info.empty() ); 00270 00271 const unsigned array_size = 3; 00272 T val[array_size] = { T(1) , T(2) , T(4) }; 00273 T * const a[array_size] = { val , val + 1 , val + 2 }; 00274 T * b[array_size] ; 00275 00276 // Test data trait basic operations on type T* 00277 traits.construct( b , array_size ); 00278 STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[0] ); 00279 STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[1] ); 00280 STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[2] ); 00281 00282 traits.copy( b , a , array_size ); 00283 STKUNIT_ASSERT_EQUAL( val + 0 , b[0] ); 00284 STKUNIT_ASSERT_EQUAL( val + 1 , b[1] ); 00285 STKUNIT_ASSERT_EQUAL( val + 2 , b[2] ); 00286 00287 traits.destroy( b , array_size ); 00288 STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[0] ); 00289 STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[1] ); 00290 STKUNIT_ASSERT_EQUAL( static_cast<T*>(NULL) , b[2] ); 00291 00292 // Test unsupported operations 00293 STKUNIT_ASSERT_THROW(traits.sum (b, a, array_size), std::runtime_error); 00294 STKUNIT_ASSERT_THROW(traits.max (b, a, array_size), std::runtime_error); 00295 STKUNIT_ASSERT_THROW(traits.min (b, a, array_size), std::runtime_error); 00296 STKUNIT_ASSERT_THROW(traits.bit_and(b, a, array_size), std::runtime_error); 00297 STKUNIT_ASSERT_THROW(traits.bit_or( b, a, array_size), std::runtime_error); 00298 STKUNIT_ASSERT_THROW(traits.bit_xor(b, a, array_size), std::runtime_error); 00299 STKUNIT_ASSERT_THROW(traits.print (std::cout, NULL, 0), std::runtime_error); 00300 00301 CommAll comm( pm ); 00302 STKUNIT_ASSERT_THROW( traits.pack( comm.send_buffer(0) , a , array_size ), std::runtime_error ); 00303 comm.allocate_buffers( 0 ); 00304 comm.communicate(); 00305 STKUNIT_ASSERT_THROW( traits.unpack( comm.recv_buffer(0) , b , array_size ), std::runtime_error ); 00306 } 00307 00308 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_char_ptr) 00309 { 00310 test_fundamental_pointer<char>(); 00311 } 00312 00313 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedchar_ptr) 00314 { 00315 test_fundamental_pointer<unsigned char>(); 00316 } 00317 00318 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_short_ptr) 00319 { 00320 test_fundamental_pointer<short>(); 00321 } 00322 00323 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedshort_ptr) 00324 { 00325 test_fundamental_pointer<unsigned short>(); 00326 } 00327 00328 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_int_ptr) 00329 { 00330 test_fundamental_pointer<int>(); 00331 } 00332 00333 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedint_ptr) 00334 { 00335 test_fundamental_pointer<unsigned int>(); 00336 } 00337 00338 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_long_ptr) 00339 { 00340 test_fundamental_pointer<long>(); 00341 } 00342 00343 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_unsignedlong_ptr) 00344 { 00345 test_fundamental_pointer<unsigned long>(); 00346 } 00347 00348 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_float_ptr) 00349 { 00350 test_fundamental_pointer<float>(); 00351 } 00352 00353 STKUNIT_UNIT_TEST(TestDataTraits, testFundamental_double_ptr) 00354 { 00355 test_fundamental_pointer<double>(); 00356 } 00357 00358 } 00359 //---------------------------------------------------------------------- 00360 00361 #ifndef __PGI 00362 00363 enum EType { val_a = 'a' , val_b = 'b' , val_c = 'c' }; 00364 00365 namespace stk_classic { 00366 namespace mesh { 00367 00368 // This enum will only work within the stk_classic::mesh namespace 00369 DATA_TRAITS_ENUM_3( EType , val_a , val_b , val_c ) 00370 00371 } 00372 } 00373 00374 namespace { 00375 00376 STKUNIT_UNIT_TEST(TestDataTraits, testEnum) 00377 { 00378 // Test interaction of DataTraits with enums 00379 00380 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00381 int p_rank = stk_classic::parallel_machine_rank( pm ); 00382 int p_size = stk_classic::parallel_machine_size( pm ); 00383 MPI_Barrier( pm ); 00384 00385 typedef EType T ; 00386 const DataTraits & traits = data_traits<T>(); 00387 00388 // Test data trait properties of enum type 00389 STKUNIT_ASSERT( traits.type_info == typeid(T) ); 00390 STKUNIT_ASSERT_EQUAL( traits.size_of , sizeof(T) ); 00391 STKUNIT_ASSERT_EQUAL( traits.alignment_of , sizeof(T) ); 00392 STKUNIT_ASSERT_EQUAL( traits.stride_of , sizeof(T) ); 00393 STKUNIT_ASSERT_EQUAL( traits.is_integral , false ); 00394 STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false ); 00395 STKUNIT_ASSERT_EQUAL( traits.is_array , false ); 00396 STKUNIT_ASSERT_EQUAL( traits.is_pointer , false ); 00397 STKUNIT_ASSERT_EQUAL( traits.is_enum , true ); 00398 STKUNIT_ASSERT_EQUAL( traits.is_class , false ); 00399 STKUNIT_ASSERT_EQUAL( traits.is_pod , true ); 00400 STKUNIT_ASSERT_EQUAL( traits.is_signed , false ); 00401 STKUNIT_ASSERT_EQUAL( traits.is_unsigned , false ); 00402 00403 STKUNIT_ASSERT( ! traits.remove_pointer ); 00404 STKUNIT_ASSERT( traits.class_info.empty() ); 00405 00406 STKUNIT_ASSERT_EQUAL( traits.enum_info.size() , size_t(3) ); 00407 STKUNIT_ASSERT_EQUAL( (traits.enum_info[0].name == "val_a"), true ); 00408 STKUNIT_ASSERT_EQUAL( (traits.enum_info[1].name == "val_b"), true ); 00409 STKUNIT_ASSERT_EQUAL( (traits.enum_info[2].name == "val_c"), true ); 00410 STKUNIT_ASSERT_EQUAL( traits.enum_info[0].value , long(val_a) ); 00411 STKUNIT_ASSERT_EQUAL( traits.enum_info[1].value , long(val_b) ); 00412 STKUNIT_ASSERT_EQUAL( traits.enum_info[2].value , long(val_c) ); 00413 00414 const unsigned array_size = 3; 00415 EType a[array_size] = { val_a , val_b , val_c }; 00416 EType b[array_size] ; 00417 00418 // Test data trait basic operations on enum type 00419 traits.construct( b , array_size ); 00420 STKUNIT_ASSERT_EQUAL( val_a , b[0] ); 00421 STKUNIT_ASSERT_EQUAL( val_a , b[1] ); 00422 STKUNIT_ASSERT_EQUAL( val_a , b[2] ); 00423 00424 traits.copy( b , a , array_size ); 00425 STKUNIT_ASSERT_EQUAL( a[0] , b[0] ); 00426 STKUNIT_ASSERT_EQUAL( a[1] , b[1] ); 00427 STKUNIT_ASSERT_EQUAL( a[2] , b[2] ); 00428 00429 b[0] = val_b ; b[1] = val_b ; b[2] = val_b ; 00430 00431 traits.min( b , a , array_size ); 00432 STKUNIT_ASSERT_EQUAL( val_a , b[0] ); 00433 STKUNIT_ASSERT_EQUAL( val_b , b[1] ); 00434 STKUNIT_ASSERT_EQUAL( val_b , b[2] ); 00435 00436 b[0] = val_b ; b[1] = val_b ; b[2] = val_b ; 00437 00438 traits.max( b , a , array_size ); 00439 STKUNIT_ASSERT_EQUAL( val_b , b[0] ); 00440 STKUNIT_ASSERT_EQUAL( val_b , b[1] ); 00441 STKUNIT_ASSERT_EQUAL( val_c , b[2] ); 00442 00443 // Test unsupported operations 00444 STKUNIT_ASSERT_THROW(traits.sum (b, a, array_size), std::runtime_error); 00445 STKUNIT_ASSERT_THROW(traits.bit_and(b, a, array_size), std::runtime_error); 00446 STKUNIT_ASSERT_THROW(traits.bit_or (b, a, array_size), std::runtime_error); 00447 STKUNIT_ASSERT_THROW(traits.bit_xor(b, a, array_size), std::runtime_error); 00448 00449 // Test pack/unpack (communication) of enum type 00450 traits.construct( b , array_size ); 00451 CommAll comm( pm ); 00452 traits.pack( comm.send_buffer(0) , a , array_size ); 00453 comm.allocate_buffers( 0 ); 00454 traits.pack( comm.send_buffer(0) , a , array_size ); 00455 comm.communicate(); 00456 if (p_rank == 0) { 00457 for (int proc_id = 0; proc_id < p_size; ++proc_id) { 00458 traits.unpack( comm.recv_buffer(proc_id) , b , array_size ); 00459 STKUNIT_ASSERT_EQUAL( a[0] , b[0] ); 00460 STKUNIT_ASSERT_EQUAL( a[1] , b[1] ); 00461 STKUNIT_ASSERT_EQUAL( a[2] , b[2] ); 00462 } 00463 } 00464 00465 // Test printing of enum type 00466 std::ostringstream oss; 00467 b[2] = static_cast<EType>( 'd' ); 00468 oss << traits.name << " " ; 00469 traits.print( oss , b , array_size ); 00470 oss << std::endl ; 00471 00472 // Test destruction of enum type (no-op in this case) 00473 traits.destroy( b , array_size ); 00474 } 00475 00476 } 00477 00478 //---------------------------------------------------------------------- 00479 00480 struct Vec3 { double x , y , z ; }; 00481 00482 namespace stk_classic { 00483 namespace mesh { 00484 00485 // This enum will only work within the stk_classic::mesh namespace 00486 DATA_TRAITS_POD_CLASS_3( Vec3 , x , y , z ) 00487 00488 } 00489 } 00490 00491 namespace { 00492 00493 STKUNIT_UNIT_TEST(TestDataTraits, testClass) 00494 { 00495 // Test interaction of DataTraits with classes 00496 00497 stk_classic::ParallelMachine pm = MPI_COMM_WORLD; 00498 int p_rank = stk_classic::parallel_machine_rank( pm ); 00499 int p_size = stk_classic::parallel_machine_size( pm ); 00500 MPI_Barrier( pm ); 00501 00502 typedef Vec3 T ; 00503 const DataTraits & traits = data_traits<T>(); 00504 00505 // Test data trait properties of class type 00506 STKUNIT_ASSERT( traits.type_info == typeid(T) ); 00507 STKUNIT_ASSERT_EQUAL( traits.size_of , sizeof(T) ); 00508 STKUNIT_ASSERT_EQUAL( traits.alignment_of , sizeof(double) ); 00509 STKUNIT_ASSERT_EQUAL( traits.stride_of , sizeof(T) ); 00510 STKUNIT_ASSERT_EQUAL( traits.is_integral , false ); 00511 STKUNIT_ASSERT_EQUAL( traits.is_floating_point , false ); 00512 STKUNIT_ASSERT_EQUAL( traits.is_array , false ); 00513 STKUNIT_ASSERT_EQUAL( traits.is_pointer , false ); 00514 STKUNIT_ASSERT_EQUAL( traits.is_enum , false ); 00515 STKUNIT_ASSERT_EQUAL( traits.is_class , true ); 00516 STKUNIT_ASSERT_EQUAL( traits.is_pod , true ); 00517 STKUNIT_ASSERT_EQUAL( traits.is_signed , false ); 00518 STKUNIT_ASSERT_EQUAL( traits.is_unsigned , false ); 00519 00520 STKUNIT_ASSERT( ! traits.remove_pointer ); 00521 STKUNIT_ASSERT( traits.enum_info.empty() ); 00522 00523 const Vec3 a = { 1.0 , 2.0 , 3.0 }; 00524 const size_t dx = reinterpret_cast<const unsigned char *>( & a.x ) - 00525 reinterpret_cast<const unsigned char *>( & a ); 00526 const size_t dy = reinterpret_cast<const unsigned char *>( & a.y ) - 00527 reinterpret_cast<const unsigned char *>( & a ); 00528 const size_t dz = reinterpret_cast<const unsigned char *>( & a.z ) - 00529 reinterpret_cast<const unsigned char *>( & a ); 00530 00531 STKUNIT_ASSERT_EQUAL( traits.class_info.size() , size_t(3) ); 00532 STKUNIT_ASSERT_EQUAL( (traits.class_info[0].name == "x"), true ); 00533 STKUNIT_ASSERT_EQUAL( (traits.class_info[1].name == "y"), true ); 00534 STKUNIT_ASSERT_EQUAL( (traits.class_info[2].name == "z"), true ); 00535 STKUNIT_ASSERT_EQUAL( traits.class_info[0].traits, & data_traits<double>() ); 00536 STKUNIT_ASSERT_EQUAL( traits.class_info[1].traits, & data_traits<double>() ); 00537 STKUNIT_ASSERT_EQUAL( traits.class_info[2].traits, & data_traits<double>() ); 00538 STKUNIT_ASSERT_EQUAL( traits.class_info[0].offset, dx ); 00539 STKUNIT_ASSERT_EQUAL( traits.class_info[1].offset, dy ); 00540 STKUNIT_ASSERT_EQUAL( traits.class_info[2].offset, dz ); 00541 00542 // Test data trait basic operations on class type 00543 const unsigned array_size = 1; 00544 Vec3 b ; 00545 traits.construct( & b , array_size ); 00546 traits.copy( & b , & a , array_size ); 00547 STKUNIT_ASSERT_EQUAL( b.x , a.x ); 00548 STKUNIT_ASSERT_EQUAL( b.y , a.y ); 00549 STKUNIT_ASSERT_EQUAL( b.z , a.z ); 00550 00551 // Test unsupport operations on class type 00552 STKUNIT_ASSERT_THROW(traits.sum (NULL, NULL, 0 ), std::runtime_error); 00553 STKUNIT_ASSERT_THROW(traits.max (NULL, NULL, 0 ), std::runtime_error); 00554 STKUNIT_ASSERT_THROW(traits.min (NULL, NULL, 0 ), std::runtime_error); 00555 STKUNIT_ASSERT_THROW(traits.bit_and(NULL, NULL, 0 ), std::runtime_error); 00556 STKUNIT_ASSERT_THROW(traits.bit_or (NULL, NULL, 0 ), std::runtime_error); 00557 STKUNIT_ASSERT_THROW(traits.bit_xor(NULL, NULL, 0 ), std::runtime_error); 00558 STKUNIT_ASSERT_THROW(traits.print (std::cout, NULL, 0), std::runtime_error); 00559 00560 // Test data trait pack/unpack (communication) of class type 00561 traits.construct( & b , array_size ); 00562 CommAll comm( pm ); 00563 traits.pack( comm.send_buffer(0) , & a , array_size ); 00564 comm.allocate_buffers( 0 ); 00565 traits.pack( comm.send_buffer(0) , & a , array_size ); 00566 comm.communicate(); 00567 if (p_rank == 0) { 00568 for (int proc_id = 0; proc_id < p_size; ++proc_id) { 00569 traits.unpack( comm.recv_buffer(proc_id) , & b , array_size ); 00570 STKUNIT_ASSERT_EQUAL( a.x , b.x ); 00571 STKUNIT_ASSERT_EQUAL( a.y , b.y ); 00572 STKUNIT_ASSERT_EQUAL( a.z , b.z ); 00573 } 00574 } 00575 00576 traits.destroy( & b , array_size ); 00577 } 00578 00579 } 00580 00581 #endif