CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Sharing large scalarList among multiple processors (https://www.cfd-online.com/Forums/openfoam-programming-development/191953-sharing-large-scalarlist-among-multiple-processors.html)

hanness August 25, 2017 05:06

Sharing large scalarList among multiple processors
 
Hi All,

I'm currently looking for a solution to efficiently share data in a parallel simulation.
The problem is as follows:
In a custom (temperature) boundary condition I want to interpolate the temperature based on several parameters. The data for the interpolation (list of scalars) is read from a file during initialisation of the bc. This list is rather large (36Mio values). My current implementation works fine, but it reads and stores this list for every thread which makes it very slow in the beginning and causes trouble with memory when running on 20 or more processors.

Instead, we thought of using a pointer to the list and reading the list only on the master processor but somehow I can't make the code run properly. And here comes the problem. The relevant constructor of the BC currently looks like this:
Code:

Foam::myTemperatureFvPatchScalarField::
myTemperatureFvPatchScalarField
(
    const fvPatch& p,
    const DimensionedField<scalar, volMesh>& iF,
    const dictionary& dict
)
:
    fixedValueFvPatchScalarField(p, iF),
    phiName_(dict.lookupOrDefault<word>("phi", "phi")),
    airTempIntTblName_(dict.lookup("airTempIntTblName")),
    airTempIntTbl_
    (
            airTempIntTblName_,
            this->patch().boundaryMesh().mesh(),
            IOdictionary
            (
                IOobject
                (
                    airTempIntTblName_,
                    this->patch().boundaryMesh().mesh().time().constant(),
                    this->patch().boundaryMesh().mesh(),
                    IOobject::MUST_READ,    // must exist, otherwise failure
                    IOobject::NO_WRITE,      // dict is only read by the solver
                    false // register
                )
            ),
            true //initialise only
    ),
    dataPointer_(),
    ...

{
    Pout << " in constructor " << endl;

    ...

    if (Pstream::master())
    {

        Pout << "in master loop ... " << endl;

        uniformMatrixInterpolationTable<scalar> foo
        (
        uniformMatrixInterpolationTable<scalar>
        (
            IOobject
            (
                airTempIntTblName_,
                this->patch().boundaryMesh().mesh().time().constant(),
                this->patch().boundaryMesh().mesh(),
                IOobject::MUST_READ,    // must exist, otherwise failure
                IOobject::NO_WRITE,      // dict is only read by the solver
                true
            )
        )
        );

        scalarList tblData=scalarList(foo.size(),Zero);
        scalarList *dataPtr;
        forAll(foo,i)
        {
            tblData[i]=foo[i];
        }
        dataPtr = &tblData;
        dataPointer_.set(dataPtr);
        Pout << "dataPtr " << *dataPtr << endl;

    }
//    Pstream::scatter(dataPointer_,Pstream::blocking);
}

dataPointer_ is defined in the respective .H file as
Code:


        autoPtr<scalarList> dataPointer_;

Now, although it compiles fine, there are several problems with this code. First of all, when running on a single thread it ends with the following error (after finishing the iterations):
Code:

End

*** Error in `buoyantSimpleFoam': double free or corruption (out): 0x00007ffd10596a30 ***
Aborted (core dumped)

When running on multiple threads (here two) it crashes with the following error message during initialisation ( - for debugging purposes the table was shortened to 32 entries):
Code:

[1]  in constructor
[0]  in constructor
[0] in master loop ...
[0] dataPtr 32{800}
[1]
[1]
[1] --> FOAM FATAL IO ERROR:
[1] incorrect first token, expected <int> or '(', found on line 0 the word 'dictionary'
[1]
[1] file: IOstream at line 0.
[1]
[1]    From function Foam::Istream& Foam::operator>>(Foam::Istream&, Foam::List<T>&) [with T = int]
[1]    in file /home/ubuntu/OpenFOAM/OpenFOAM-4.1/src/OpenFOAM/lnInclude/ListIO.C at line 148.
[1]
FOAM parallel run exiting
[1]

I thought this happens because the pointer is only available on the master and that I'd have to scatter the pointer to the other processors as well. But when uncommenting the Pstream line in the above code it won't compile:
Code:

g++ -std=c++0x -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/opt/openfoam4/src/finiteVolume/lnInclude -I/opt/openfoam4/src/TurbulenceModels/incompressible/lnInclude -I/opt/openfoam4/src/TurbulenceModels/compressible/lnInclude -I/opt/openfoam4/src/turbulenceModels/compressible/lnInclude -I/opt/openfoam4/src/TurbulenceModels/turbulenceModels/lnInclude -I/opt/openfoam4/src/transportModels/compressible/lnInclude -I/opt/openfoam4/src/thermophysicalModels/basic/lnInclude  -IlnInclude -I. -I/opt/openfoam4/src/OpenFOAM/lnInclude -I/opt/openfoam4/src/OSspecific/POSIX/lnInclude  -fPIC -c myTemperatureFvPatchScalarField.C -o Make/linux64GccDPInt32Opt/myTemperatureFvPatchScalarField.o
In file included from /opt/openfoam4/src/OpenFOAM/lnInclude/Pstream.H:352:0,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/mapDistributeBase.H:75,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/Field.C:30,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/Field.H:405,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/labelField.H:39,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/primitiveFields.H:37,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/pointField.H:36,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/edge.H:40,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/edgeList.H:32,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/PrimitivePatch.H:56,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/primitivePatch.H:35,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/polyPatch.H:43,
                from /opt/openfoam4/src/finiteVolume/lnInclude/fvPatch.H:39,
                from /opt/openfoam4/src/finiteVolume/lnInclude/fvPatchField.H:47,
                from /opt/openfoam4/src/finiteVolume/lnInclude/fvPatchFields.H:29,
                from myTemperatureFvPatchScalarField.H:55,
                from myTemperatureFvPatchScalarField.C:26:
/opt/openfoam4/src/OpenFOAM/lnInclude/gatherScatter.C: In instantiation of ‘static void Foam::Pstream::scatter(const Foam::List<Foam::UPstream::commsStruct>&, T&, int, Foam::label) [with T = Foam::autoPtr<Foam::List<double> >; Foam::label = int]’:
/opt/openfoam4/src/OpenFOAM/lnInclude/gatherScatter.C:227:70:  required from ‘static void Foam::Pstream::scatter(T&, int, Foam::label) [with T = Foam::autoPtr<Foam::List<double> >; Foam::label = int]’
myTemperatureFvPatchScalarField.C:303:52:  required from here
/opt/openfoam4/src/OpenFOAM/lnInclude/gatherScatter.C:184:27: error: no match for ‘operator>>’ (operand types are ‘Foam::IPstream’ and ‘Foam::autoPtr<Foam::List<double> >’)
                fromAbove >> Value;
                          ^
/opt/openfoam4/src/OpenFOAM/lnInclude/gatherScatter.C:184:27: note: candidates are:
In file included from /opt/openfoam4/src/OpenFOAM/lnInclude/string.H:48:0,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/word.H:42,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/wordList.H:41,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/patchIdentifier.H:38,
                from /opt/openfoam4/src/OpenFOAM/lnInclude/polyPatch.H:42,
                from /opt/openfoam4/src/finiteVolume/lnInclude/fvPatch.H:39,
                from /opt/openfoam4/src/finiteVolume/lnInclude/fvPatchField.H:47,
                from /opt/openfoam4/src/finiteVolume/lnInclude/fvPatchFields.H:29,
                from myTemperatureFvPatchScalarField.H:55,
                from myTemperatureFvPatchScalarField.C:26:
/opt/openfoam4/src/OpenFOAM/lnInclude/char.H:49:10: note: Foam::Istream& Foam::operator>>(Foam::Istream&, char&)
 Istream& operator>>(Istream&, char&);
...

So, I've got a few questions.
1. Is the approach using pointers in this case reasonable or is there a better alternative?
2. Is there anything wrong in the way the pointer is used. (see the error message for a single thread run above)
3. Why doesn't it run in parallel?

I really appreciate any comments and thoughts regarding the above and thanks a lot!
Hannes

Vesposo August 28, 2017 03:51

Hi,

I'm struggeling with a similar question and would appreciate any hints on scattering a smart pointer over processors while only the master initializes it.


All times are GMT -4. The time now is 10:08.