ENH: extend/improve broadcast handling

- split off a Pstream::genericBroadcast() which uses UOPBstream during
  serialization and UOPBstream during de-serialization.
  This function will not normally be used directly by callers, but
  provides a base layer for higher-level broadcast calls.

- low-level UPstream broadcast of string content.
  Since std::string has length and contiguous content, it is possible
  to handle directly by the following:
     1. broadcast size
     2. resize
     3. broadcast content when size != 0

  Although this is a similar amount of communication as the generic
  streaming version (min 1, max 2 broadcasts) it is more efficient
  by avoiding serialization/de-serialization overhead.

- handle broadcast of List content distinctly.
  Allows an optimized path for contiguous data, similar to how
  std::string is handled (broadcast size, resize container, broadcast
  content when size != 0), but can revert to genericBroadcast (streamed)
  for non-contiguous data.

- make various scatter variants simple aliases for broadcast, since
  that is what they are doing behind the scenes anyhow:

    * scatter()
    * combineScatter()
    * listCombineScatter()
    * mapCombineScatter()

  Except scatterList() which remains somewhat different.
  Beyond the additional (size == nProcs) check, the only difference to
  using broadcast(List<T>&) or a regular scatter(List<T>&) is that
  processor-local data is skipped. So leave this variant as-is.

STYLE: rename/prefix implementation code with 'Pstream'

- better association with its purpose and provides a unique name
This commit is contained in:
Mark Olesen
2022-02-25 17:42:57 +01:00
committed by Andrew Heather
parent f3674eee36
commit c086f22298
16 changed files with 660 additions and 441 deletions

View File

@ -42,45 +42,38 @@ Description
using namespace Foam;
// This is what our new scatter will look like inside
template<class Type>
void testBroadcastStream
(
Type& value,
const label comm = UPstream::worldComm
)
template<class T>
void printPre(const T& value)
{
Info<< nl << "is_contiguous:" << is_contiguous<Type>::value << endl;
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
Pout<< "pre-broadcast: " << value << endl;
}
if (is_contiguous<Type>::value)
{
UPstream::broadcast
(
reinterpret_cast<char*>(&value),
sizeof(Type),
comm,
UPstream::masterNo()
);
}
else
{
if (UPstream::master())
{
OPBstream toAll(UPstream::masterNo(), comm);
toAll << value;
}
else
{
IPBstream fromMaster(UPstream::masterNo(), comm);
fromMaster >> value;
}
}
template<class T>
void printPost(const T& value)
{
Pout<< "post-broadcast: " << value << endl;
}
template<class T>
void testBroadcast(T& value)
{
printPre(value);
Pstream::broadcast(value);
printPost(value);
}
template<class T>
void testBroadcast(List<T>& values)
{
Info<< nl << "is_contiguous:" << is_contiguous<T>::value << endl;
Pout<< "pre-broadcast: " << flatOutput(values) << endl;
Pstream::broadcast(values);
Pout<< "post-broadcast: " << flatOutput(values) << endl;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
int main(int argc, char *argv[])
@ -95,7 +88,7 @@ int main(int argc, char *argv[])
{
value = UPstream::nProcs();
}
testBroadcastStream(value);
testBroadcast(value);
}
{
@ -104,7 +97,18 @@ int main(int argc, char *argv[])
{
values = identity(UPstream::nProcs());
}
testBroadcastStream(values);
testBroadcast(values);
}
{
word value;
if (Pstream::master())
{
value = args.executable();
}
printPre(value);
UPstream::broadcast(value); // Low-level UPstream broadcast
printPost(value);
}
{
@ -117,7 +121,7 @@ int main(int argc, char *argv[])
values[i] = "value_" + Foam::name(i);
}
}
testBroadcastStream(values);
testBroadcast(values);
}
{
@ -126,7 +130,7 @@ int main(int argc, char *argv[])
{
values = vector(1,2,3);
}
testBroadcastStream(values);
testBroadcast(values);
}
{
@ -134,8 +138,15 @@ int main(int argc, char *argv[])
if (Pstream::master())
{
values = vector(1,2,3);
scalar mult = 1;
for (auto& v : values)
{
v *= mult;
mult += 1;
}
}
testBroadcastStream(values);
testBroadcast(values);
}
Info<< "End\n" << endl;