Finally getting around to working on this... but it's actually much more
complicated than I thought.
My idea was to simply use something like:
counter + (std::numeric_limits<unsigned long int>::max() / n_processors())
as the unique ID. Where "counter" is increased every time a DofObject gets
Unfortunately that doesn't work.
Here's the problem: DofObject is NOT a ParallelObject and doesn't know what
processor_id it's assigned to when it's created. Therefore we are missing
two critical pieces of information that are needed for creating a unique ID
at the time a DofObject is created:
1. How many total processors there are.
2. What processor this DofObject is assigned to in the beginning
Not only that - but with ParallelMesh you have to be careful to assign the
same ID on every processor...
So - I started looking for where the right place was to assign a unique
ID... and it's looking like a callback to Mesh from the Partitioner ( in
partition() ) might not be a bad idea. Maybe something like virtual void
In the case of SerialMesh this isn't a problem because it can just loop
over all DofObjects in the Mesh in the same order on every processor and
assign a unique ID using just a "serial" counter. If any new Elements are
added after partition() they will get the next number... etc. Easy.
However, for ParallelMesh things are not so easy. All processors can't
loop over all the objects in the very same way - so the scheme for
SerialMesh is out. The "counter" scheme (outlined at the beginning) seems
like a good idea - but there is still one problem: processor_id is assigned
to elements and nodes independently.... and in a two stage process (look in
I can definitely assign the unique_ids for the elements _just_ after
set_parent_processor_ids(mesh) in Partioner::partition(). The cool thing
is that redistribute() is called right after that which will cause that
unique_id to get packed up along with the rest of the Elem and sent
wherever it needs to go... so everything will work fine.
The bad part is that the Nodes _also_ get packed up and sent during
redistribute()... which means that if we set the unique_id on the nodes
_after_ redistribute() we'll have to go through a second phase of
renegotiation to make sure those are consistent across all processors.
However, it's not until _after_ redistribute that the processor_id() gets
set for nodes! So we can't set the unique_id for nodes before
Am I way off base here?
On Wed, Jul 10, 2013 at 11:49 PM, Roy Stogner <roystgnr@...:
> On Wed, 10 Jul 2013, Derek Gaston wrote:
> On Jul 10, 2013, at 11:05 PM, Roy Stogner <roystgnr@...>
>> I'd rather avoid adding a mandatory extra 8 bytes to every DofObject,
>>> but I don't see any insuperable obstacle to adding an optional 8
>>> bytes; this could even be run-time optional since we already have to
>>> have that variable-size _idx_buf in there. The only practical
>>> obstacle is that the _idx_buf code is *already* scary complicated.
>> At this point I would just prefer a compile time option. We are going
>> to have code connected to this thing in quite a few places in MOOSE so
>> I would really like to be able to do elem->unique_id or some such.
> Compile time option is okay with me unless others disagree. Just make
> it elem->unique_id() so that we can hide the underlying data in the
> index buffer and move to a runtime option sometime later.
> Are we at the point where I can gin something up and put in a pull
>> request and we can discuss from there?
> Fine by me. There are still issues we haven't discussed but I can't
> think of any really hairy problems.
> I really don't think it's going to be much code to get started with.
> Agreed. I also suspect your first crack is going to break my
> finally-passing-buildbot 64-bit-dof_id_type tests, but I'll fix that
> when we come to it. :-)
> You might want to strip out PackedElem and PackedNode while you're at
> it; that's been superceded by the Parallel::*packed_range stuff for a
> while now, and it's probably easier to delete the older code than to
> update it.