reduce(f,sumOp<scalarField>) ambiguous conversion with clang
hi!
I have a scalarField that has to contain some global averaging. when I do the reduce operation to make it work in parallel, clang raises the following error Code:
OpenFOAM-3.0.x/src/OpenFOAM/lnInclude/ops.H:162:9: error: conversion from 'tmp<Field<typename typeOfSum<double, double>::type> >' thanks |
Hi,
Since ambiguity is between constructor from tmp and operator returning reference, you can suppress constructor from tmp using NoConstructFromTmp symbol definition before including Field.H header. For example compilation of this: Code:
#include "Field.H" Code:
#define NoConstructFromTmp |
Hi,
I looked at modified dynamicMesh code (zoneVelocityLaplacianFvMotionSolver) that developed from refVelocityLaplacianFvMotionSolver. This code developed by Dr. Stefan Hoerner a long ago, applied dynamicMesh to specific pointZone. This code work in serial running but for parallel is not work. I try to check line by line and think the problem comes from here Quote:
Quote:
May I think true? or any hint for this problem. Thanks |
Quote:
Thank you for this. Unfortunately, the "NoConstructFromTmp" variable has been removed since at least OpenFOAM-7. Do you have any other suggested solutions? For example, if I add the following line to any OpenFOAM code (e.g. laplacianFoam): Code:
surfaceVectorField n = mesh.Sf()/mesh.magSf(); Code:
laplacianFoam.C:52:24: error: conversion from 'tmp<GeometricField<Foam::Vector<double>, fvsPatchField, Foam::surfaceMesh>>' to 'Foam::surfaceVectorField' (aka 'GeometricField<Vector<double>, fvsPatchField, Foam::surfaceMesh>') is ambiguous Code:
surfaceVectorField n(mesh.Sf()/mesh.magSf()); By the way, I am using Apple clang version 12.0.5 (clang-1205.0.22.9) on a m1 Mac. |
Quote:
Code:
scalarField fld(1+2*Pstream::nProcs()); |
Quote:
Hi Phil, They are almost, but not quite the same. With the assignment version, the compiler is spoiled for choice. Code:
surfaceVectorField lhs = (mesh.Sf()/mesh.magSf()); I'm not really sure what gcc does here. In the cast operation (tmp.H) it is using a const reference, whereas Field.H one is stealing content. Would be interesting to try and report the data addresses to see which compilation branch it is taking: if it is creating the intermediate and copying the contents or actually steals the contents. FWIW we've been addressing clang pickiness for a long-time, so most of OpenFOAM itself should compile cleanly with clang. Occasionally we do have some things with template specialization in the wrong namespace that newer clang and gcc accepts but older gcc rejects. We try to cover the range from gcc-4.8.5 -> gcc-11.2 and some version of clang up to clang-13 (most recent on linux). Occasionally also do see some oddness with clang optimization though. You'll see some things marked as "volatile" in the EtoHthermo.H (for example), also recently hit a weird branching optimization with vtk parallel output (sigh). |
Hi Mark,
Thanks for your insightful reply! My adventure into the world of clang only started earlier this year when I got an Apple M1 machine (GCC is not supported as far as I can see). I am trying to get solids4foam compiling with clang but have many errors like the ones above (n = ... but also reduce statements). Out of curiosity I will now also try clang-12 on ubuntu just in case there are some differences. However, from what you are saying it seems like clang is just being more strict than gcc with these ambiguous statements and so I probably just need to fix them! Philip Edit: I tried on Ubuntu 20.04 using clang-12 and I see the same behaviour as on macOS (which is good to see but expected). So I will start to "de-ambiguify" (it should be a word if it's not) my code. |
Quote:
If I wanted to perform an element by element sum, such that fld is exactly the same on each core, how would you suggest that is done? To be more explicit, consider the following trivial example: Code:
scalarField fld(3); Edit: This post https://www.cfd-online.com/Forums/op...tml#post316767 suggests that above works, which it does with gcc, but it does not compile with clang. However, I understand the ambiguity in this case that clang has an issue with. |
Quote:
Yes, I meant to illustrate that sumOp with different size fields doesn't make much sense. If you do however have identical field sizes, you should be able to define your own operator. For example, Code:
template<class T> |
Great, thanks for this. I will come back and post the code that works in this case.
|
The definition below seems to work. You can save it as a file called FieldSumOp.H (although the name is a bit ambiguous), and then include it as you need (and make sure to include the GPL header).
Code:
#ifndef FieldSumOp_H Code:
scalarField fld(3); |
What about something as simple as this?
Code:
template<class Type> If you are only doing this once, a lambda should also be OK. For example, Code:
reduce If you are doing the same thing several times locally, can pack the lamda into a variable Code:
auto fieldReducer = |
Nice options, thanks!
I have yet to use a lambda in C++; I often don't think of it but they are clearly convenient. In my case, I perform a field reduce operation like this across many files and classes and so defining it in a header files is easiest. But your suggestion is certainly tidier (no need to explicitly specify the forAll loop). I guess using a tmp may be a good idea if the fields may not be small. Sure, I will use a struct. For reference, I use this approach in solids4foam for syncing "global" interface fields in FSI; a more elegant/efficient parallelisation strategy would avoid the need for these synced global fields, so I probably/hopefully won't need it in the future. Edit: example struct definition using tmp and without the need for #ifdef Code:
#ifndef FieldSumOp_H |
Quote:
There are still other places and reasons for "tmp" (or my new favourite "refPtr"), but I don't think that this is one of them. |
Quote:
Thanks again! |
All times are GMT -4. The time now is 17:20. |