... | ... | @@ -4,8 +4,6 @@ |
|
|
[![upgrade](/icons/chevrons-up.svg "upgrade guide")][upgrade-guide]
|
|
|
[![code](/icons/code.svg "coding patterns")][code-patterns]
|
|
|
|
|
|
***Preview information, subject to change at any time !!!***
|
|
|
|
|
|
[[_TOC_]]
|
|
|
|
|
|
<!-- ## Deprecation and Removal -->
|
... | ... | @@ -75,7 +73,195 @@ without any compatibility (alias) handling: |
|
|
|
|
|
<!-- ## Changes in behaviour -->
|
|
|
|
|
|
<!-- ## Namespace changes -->
|
|
|
|
|
|
## New List Methods
|
|
|
|
|
|
### SubList Access
|
|
|
|
|
|
A SubList or SubField is frequently used to view or operate on a
|
|
|
sub-section of a List or Field. The new `slice` method for List and
|
|
|
Field uses a syntax more similar to `substr` and returns a
|
|
|
SubList/SubField. Here the offset is first, and the size is second.
|
|
|
For example,
|
|
|
```
|
|
|
auto data1 = allData.slice(0, 10); // The first 10 elements
|
|
|
auto data2 = allData.slice(10); // Remaining elements
|
|
|
```
|
|
|
An unspecified length is equivalent to "all remaining elements".
|
|
|
|
|
|
The sliced portion can also be selected with the usual `labelRange`
|
|
|
(which represents a start/size pair). For example,
|
|
|
```
|
|
|
labelRange range(...);
|
|
|
|
|
|
fullList.slice(range) = identity(range.size());
|
|
|
|
|
|
// And
|
|
|
fullList.slice(range) = UIndirectList<T>(other, addr);
|
|
|
```
|
|
|
|
|
|
### No-copy resizing
|
|
|
|
|
|
The size of a List often requires adjustment prior to an operation,
|
|
|
but old values (if any) may not be of any interest and always be
|
|
|
overwritten with new values. For these cases the regular `resize` or
|
|
|
`setSize` methods are wasteful and the `resize_nocopy` and
|
|
|
`reserve_nocopy` versions can be used. These will avoid the overhead
|
|
|
of the intermediate list and the copy/move overhead of retaining the
|
|
|
old values (which would be subsequently discarded anyhow).
|
|
|
```
|
|
|
//OLD: field.resize(newLength);
|
|
|
|
|
|
field.resize_nocopy(newLength);
|
|
|
```
|
|
|
|
|
|
### Contiguous data access methods
|
|
|
|
|
|
Especially when interfacing with external codes or for MPI
|
|
|
communications it is common to handle the contiguous data directly.
|
|
|
The new List methods `data_bytes()` and `cdata_bytes()` complement the
|
|
|
`size_bytes()` methods for passing contiguous data pointers and sizes.
|
|
|
For example,
|
|
|
```
|
|
|
UOPstream::write
|
|
|
(
|
|
|
UPstream::commsTypes::nonBlocking,
|
|
|
proci,
|
|
|
sendBufs[proci].cdata_bytes(),
|
|
|
sendBufs[proci].size_bytes(),
|
|
|
tag,
|
|
|
comm
|
|
|
)
|
|
|
```
|
|
|
|
|
|
## Parallel gather/scatter routines
|
|
|
|
|
|
Additional MPI gather/scatter routines, globalIndex gather methods
|
|
|
|
|
|
- UPstream::mpiGather (MPI_Gather) - used by Pstream::listGatherValues
|
|
|
- UPstream::mpiScatter (MPI_Scatter) - used by Pstream::listScatterValues
|
|
|
|
|
|
These are much simpler forms for gather/scatter of fixed-sized
|
|
|
contiguous types data types (eg, primitives, simple pairs etc).
|
|
|
|
|
|
In the gather form, creates a list of gathered values on the master
|
|
|
process. The subranks have a list size of zero.
|
|
|
|
|
|
Similarly, scatter will distribute a list of values to single values
|
|
|
on each process.
|
|
|
|
|
|
Instead of
|
|
|
```
|
|
|
labelList sendSizes(Pstream::nProcs());
|
|
|
sendSizes[Pstream::myProcNo()] = sendData.size();
|
|
|
Pstream::gatherList(sendSizes);
|
|
|
```
|
|
|
Can write
|
|
|
```
|
|
|
const labelList sendSizes
|
|
|
(
|
|
|
UPstream::listGatherValues<label>(sendData.size())
|
|
|
);
|
|
|
|
|
|
// Less code, lower overhead and list can be const.
|
|
|
```
|
|
|
|
|
|
For scattering an individual value only.
|
|
|
Instead of
|
|
|
```
|
|
|
labelList someValues;
|
|
|
if (Pstream::master()) someValues = ...;
|
|
|
|
|
|
Pstream::gatherList(sendSizes);
|
|
|
const label localValue
|
|
|
(
|
|
|
someValues[Pstream::myProcNo()]
|
|
|
);
|
|
|
```
|
|
|
Can write
|
|
|
```
|
|
|
labelList someValues;
|
|
|
if (Pstream::master()) someValues = ...;
|
|
|
|
|
|
Pstream::gatherList(sendSizes);
|
|
|
const label localValue
|
|
|
(
|
|
|
UPstream::listScatterValues<label>(someValues)
|
|
|
);
|
|
|
```
|
|
|
Can also mix listGatherValues to assemble a list on master and use
|
|
|
Pstream::scatterList to distribute.
|
|
|
|
|
|
|
|
|
## Improved flexibilty of globalIndex
|
|
|
|
|
|
- When gathering data, the local size is properly respected, which
|
|
|
allows support for gathering with 0 master elements.
|
|
|
|
|
|
- Additional creation from local sizes. It is generally
|
|
|
easier and safer to assemble sizes and let globalIndex determine the
|
|
|
corresponding offsets, when working with raw values.
|
|
|
|
|
|
- Add globalIndex const_iterator to iterate across the access ranges.
|
|
|
This is makes it simpler to use with the List slice() method to
|
|
|
access or operate on a sub-section of list.
|
|
|
|
|
|
For example,
|
|
|
```
|
|
|
scalarField allValues = ...;
|
|
|
globalIndex procAccess = ...;
|
|
|
|
|
|
for (const labelRange& range : procAccess)
|
|
|
{
|
|
|
someOutput(allValues.slice(range));
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
## Memory handling
|
|
|
|
|
|
Improved consistency in the `refPtr` and `tmp` classes, support for
|
|
|
shallow copying of references and improved checks. The shallow copying
|
|
|
enables building HashTables with shadowed variables (similar idea to
|
|
|
shared pointer semantics).
|
|
|
|
|
|
The methods `good()` and `valid()` as well as a direct bool test work
|
|
|
identically in the memory classes.
|
|
|
|
|
|
Explicit `is_const()` checking methods for `refPtr` and `tmp`. These
|
|
|
can be used in combination with `is_pointer()` or `movable()` checks to
|
|
|
narrow down handling and memory reuse.
|
|
|
|
|
|
Added `release()` method to `refPtr` for consistency with `autoPtr`
|
|
|
and `std::unique_ptr`.
|
|
|
|
|
|
The precision adaptors are modifiable, which allows reuse (similar to
|
|
|
the refPtr container) when wrapping different conents. To support this,
|
|
|
there are additional control for when contents are copied back,
|
|
|
instead of waiting for the adaptor to go out of scope.
|
|
|
For example,
|
|
|
```
|
|
|
if (adaptor.active())
|
|
|
{
|
|
|
adaptor.commit();
|
|
|
adaptor.clear();
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
### Streams etc.
|
|
|
|
|
|
Added various methods to return object/stream names relative to the
|
|
|
current case, which produces compacter, more readable output.
|
|
|
|
|
|
- IOobject : objectRelPath()
|
|
|
- IOstream : relativeName()
|
|
|
- dictionary : relativeName()
|
|
|
|
|
|
For the occasion functions that are isolated from the Time or other
|
|
|
case-specific reference the `argList::envRelativePath()` static method
|
|
|
is available.
|
|
|
|
|
|
|
|
|
----
|
|
|
|
... | ... | |