88#include " Cereal_Func.h"
99#include " Cereal_Types.h"
1010#include " MPI_Wrapper.h"
11+ #include " Global_Func.h"
1112
1213#include < cereal/archives/binary.hpp>
1314#include < sstream>
2021namespace Comm
2122{
2223
24+ inline Cereal_Func::Cereal_Func ()
25+ {
26+ #if MPI_VERSION>=4
27+ using int_type = MPI_Count;
28+ #else
29+ using int_type = int ;
30+ #endif
31+
32+ // assuming MPI communication is less than max(1TB, memory availablle now) for most case,
33+ // so initialize here to avoid thread conflict in the future.
34+ const std::size_t TB = std::size_t (1 )<<12 ;
35+ const std::size_t memory_max = std::max (TB, Global_Func::memory_available ());
36+ const std::size_t times = std::ceil ( double (memory_max) / double (std::numeric_limits<int_type>::max ()) );
37+ const std::size_t exponent_align = std::ceil ( std::log (times) / std::log (2 ) );
38+ this ->char_contiguous .resize (exponent_align);
39+ }
40+
2341// every 2^exponent_align char concatenate to 1 word
2442 // <<exponent_align means *2^exponent_align
2543 // >>exponent_align means /2^exponent_align
@@ -34,7 +52,7 @@ inline std::size_t Cereal_Func::align_stringstream(std::stringstream &ss)
3452 const std::size_t size_old = ss.str ().size (); // Inefficient, should be optimized
3553 const std::size_t times = std::ceil ( double (size_old) / double (std::numeric_limits<int_type>::max ()) );
3654 const std::size_t exponent_align = std::ceil ( std::log (times) / std::log (2 ) );
37- this ->char_contiguous (exponent_align);
55+ this ->char_contiguous . resize (exponent_align);
3856 constexpr char c0 = 0 ;
3957 const std::size_t size_align = 1 <<exponent_align;
4058 if (size_old%size_align)
@@ -47,6 +65,7 @@ inline std::size_t Cereal_Func::align_stringstream(std::stringstream &ss)
4765// Send str
4866inline void Cereal_Func::mpi_send (const std::string &str, const std::size_t exponent_align, const int rank_recv, const int tag, const MPI_Comm &mpi_comm)
4967{
68+ this ->char_contiguous .resize (exponent_align);
5069 #if MPI_VERSION>=4
5170 MPI_CHECK ( MPI_Send_c ( str.c_str (), str.size ()>>exponent_align, this ->char_contiguous (exponent_align), rank_recv, tag, mpi_comm ) );
5271 #else
@@ -73,6 +92,7 @@ void Cereal_Func::mpi_send(const int rank_recv, const int tag, const MPI_Comm &m
7392// Isend str
7493inline void Cereal_Func::mpi_isend (const std::string &str, const std::size_t exponent_align, const int rank_recv, const int tag, const MPI_Comm &mpi_comm, MPI_Request &request)
7594{
95+ this ->char_contiguous .resize (exponent_align);
7696 #if MPI_VERSION>=4
7797 MPI_CHECK ( MPI_Isend_c ( str.c_str (), str.size ()>>exponent_align, this ->char_contiguous (exponent_align), rank_recv, tag, mpi_comm, &request ) );
7898 #else
@@ -102,6 +122,7 @@ inline std::vector<char> Cereal_Func::mpi_recv(const MPI_Comm &mpi_comm, MPI_Sta
102122{
103123 for (std::size_t exponent_align=0 ; ; ++exponent_align)
104124 {
125+ this ->char_contiguous .resize (exponent_align);
105126 const MPI_Datatype mpi_type = this ->char_contiguous (exponent_align);
106127 #if MPI_VERSION>=4
107128 MPI_Count size; MPI_CHECK ( MPI_Get_count_c ( &status, mpi_type, &size ) );
@@ -146,6 +167,7 @@ inline std::vector<char> Cereal_Func::mpi_mrecv(MPI_Message &message_recv, const
146167{
147168 for (std::size_t exponent_align=0 ; ; ++exponent_align)
148169 {
170+ this ->char_contiguous .resize (exponent_align);
149171 const MPI_Datatype mpi_type = this ->char_contiguous (exponent_align);
150172 #if MPI_VERSION>=4
151173 MPI_Count size; MPI_CHECK ( MPI_Get_count_c ( &status, mpi_type, &size ) );
0 commit comments