Re: itaps-parallel Two options from today's iMeshP phone conference
On 10-07-16 04:21 PM, Devine, Karen D wrote:
Today's attendees: Carl, Seegyoung, Misbah, Jason, Tim, Vitus, Karen, Mark Beall, Saurabh
In today's iMeshP phone conference, we discussed options that would associate entities with parts during the entities' creation. This association is desirable to provide consistency of the data base for parallel applications and for efficiency in some implementations. And, indeed, for parallel operations to make sense, entities must belong to some part. In addition, we'd like to allow serial iMesh services to be applied to all entities in a part; having a mechanism to add entities to a part during the creation process allows the serial service to be used.
We discussed services that one might like to use in serial within a part. Mesh smoothing was one example; however, because it does not create entities, it is not relevant to this discussion. Other options, like mesh generation and edge swapping, need to have some parallel awareness when they are used in parallel. We envisioned that some serial kernels could be used under a parallel-aware wrapper for these types of services, provided that the serial kernels could add entities to the desired part.
Note that below, I refer to "serial" and "parallel" services. Serial services are those that do not use iMeshP; they view the root set as the entire mesh, with no concept of partitions, part boundaries or ghosts. Parallel services use iMeshP and recognize that the mesh is distributed across one or more processors.
We identified two options:
A. Change the iMesh_createEnt function to include an entity set handle argument PH. For serial applications, PH would be the root set; that is, entities are added only to the root set. For parallel applications, PH would be a part handle; the created entity would be added to the part identified by the part handle. Since iMesh_createEnt is an iMesh function (not an iMeshP function), we would use entity set handle as the argument type, so that serial users would not have to include iMeshP.h nor link with iMeshP. This option was generally accepted by Carl, Simmetrix, Sandia and RPI. Tim is in favor of adding the argument, but does not like the restriction of the handle to be either the root set or a part handle. My fear in allowing arbitrary entity set handles to be used is as follows: if a service uses the entity set handle to, say, add entities to a boundary condition set, that service could not be used in parallel, as its iMesh_createEnt calls would not add the entities to a part.
B. Add a new iMeshP function iMeshP_createEnt that takes as input a part handle. Parallel services would need to use iMeshP_createEnt to add entities, include iMeshP.h, and link with an iMeshP library; iMesh_createEnt would return an error. Serial services would continue to use iMesh_createEnt. This option is more explicit than option A, but requires more work on the user's part if the user wants code to work both with and without iMeshP.
I think this is a pretty accurate description.
One point we didn't discuss but, perhaps, should have was when and how entity ownership should be assigned. The proposed changes add entities to parts, but do not address determining the ownership or copy-status of an entity. I am not sure where these issues should most appropriately be resolved; can they be postponed until iMeshP_syncPartitionAll?
I had assumed that we were talking about setting ownership, since that's the real sticking point: entities that don't have an owner can't be modified (as I interpret the current spec). Carl -- ------------------------------------------------------------------------ Dr. Carl Ollivier-Gooch, P.Eng. Voice: +1-604-822-1854 Professor Fax: +1-604-822-2403 Department of Mechanical Engineering email: [email protected] University of British Columbia http://www.mech.ubc.ca/~cfog Vancouver, BC V6T 1Z4 http://tetra.mech.ubc.ca/ANSLab/ ------------------------------------------------------------------------
On 07/16/10 20:00, Carl Ollivier-Gooch wrote:
On 10-07-16 04:21 PM, Devine, Karen D wrote:
A. Change the iMesh_createEnt function to include an entity set handle argument PH. For serial applications, PH would be the root set; that is, entities are added only to the root set. For parallel applications, PH would be a part handle; the created entity would be added to the part identified by the part handle. Since iMesh_createEnt is an iMesh function (not an iMeshP function), we would use entity set handle as the argument type, so that serial users would not have to include iMeshP.h nor link with iMeshP. This option was generally accepted by Carl, Simmetrix, Sandia and RPI. Tim is in favor of adding the argument, but does not like the restriction of the handle to be either the root set or a part handle. My fear in allowing arbitrary entity set handles to be used is as follows: if a service uses the entity set handle to, say, add entities to a boundary condition set, that service could not be used in parallel, as its iMesh_createEnt calls would not add the entities to a part.
B. Add a new iMeshP function iMeshP_createEnt that takes as input a part handle. Parallel services would need to use iMeshP_createEnt to add entities, include iMeshP.h, and link with an iMeshP library; iMesh_createEnt would return an error. Serial services would continue to use iMesh_createEnt. This option is more explicit than option A, but requires more work on the user's part if the user wants code to work both with and without iMeshP.
I think for A, we proposed that the argument be NULL in case of serial. If we want no restriction in iMesh, then maybe we can instead pass an array of entity sets to iMesh_createEnt, and then in iMeshP stipulate that one of them has to be a part.
One point we didn't discuss but, perhaps, should have was when and how entity ownership should be assigned. The proposed changes add entities to parts, but do not address determining the ownership or copy-status of an entity. I am not sure where these issues should most appropriately be resolved; can they be postponed until iMeshP_syncPartitionAll?
I had assumed that we were talking about setting ownership, since that's the real sticking point: entities that don't have an owner can't be modified (as I interpret the current spec).
Carl
Actually, no, we create different entities (ie. pointers) on different parts on the part boundary but only one part has the right to modify. The part is not modifying the entity in the _create function. saurabh
Saurabh Tendulkar wrote:
On 07/16/10 20:00, Carl Ollivier-Gooch wrote:
On 10-07-16 04:21 PM, Devine, Karen D wrote:
A. Change the iMesh_createEnt function to include an entity set handle argument PH. For serial applications, PH would be the root set; that is, entities are added only to the root set. For parallel applications, PH would be a part handle; the created entity would be added to the part identified by the part handle. Since iMesh_createEnt is an iMesh function (not an iMeshP function), we would use entity set handle as the argument type, so that serial users would not have to include iMeshP.h nor link with iMeshP. This option was generally accepted by Carl, Simmetrix, Sandia and RPI. Tim is in favor of adding the argument, but does not like the restriction of the handle to be either the root set or a part handle. My fear in allowing arbitrary entity set handles to be used is as follows: if a service uses the entity set handle to, say, add entities to a boundary condition set, that service could not be used in parallel, as its iMesh_createEnt calls would not add the entities to a part.
[snip]
I think for A, we proposed that the argument be NULL in case of serial. If we want no restriction in iMesh, then maybe we can instead pass an array of entity sets to iMesh_createEnt, and then in iMeshP stipulate that one of them has to be a part.
Logically null. Not literally 'NULL' (a bit-wise zero value). Not all implementations use pointer-based handles, and therefore zero is not an invalid handle value for all implementations. The closest thing we have to a logical null is the root set (as everything goes into the root set anyway.) - jason
I think for A, we proposed that the argument be NULL in case of serial. If we want no restriction in iMesh, then maybe we can instead pass an array of entity sets to iMesh_createEnt, and then in iMeshP stipulate that one of them has to be a part.
Logically null. Not literally 'NULL' (a bit-wise zero value). Not all implementations use pointer-based handles, and therefore zero is not an invalid handle value for all implementations. The closest thing we have to a logical null is the root set (as everything goes into the root set anyway.)
- jason
Don't they have to use pointer-based handles, since iBase_EntitySetHandle is typedef'd as: typedef struct iBase_EntitySetHandle_Private* iBase_EntitySetHandle; in iBase.h? saurabh
Saurabh Tendulkar wrote:
I think for A, we proposed that the argument be NULL in case of serial. If we want no restriction in iMesh, then maybe we can instead pass an array of entity sets to iMesh_createEnt, and then in iMeshP stipulate that one of them has to be a part.
Logically null. Not literally 'NULL' (a bit-wise zero value). Not all implementations use pointer-based handles, and therefore zero is not an invalid handle value for all implementations. The closest thing we have to a logical null is the root set (as everything goes into the root set anyway.)
- jason
Don't they have to use pointer-based handles,
No.
since iBase_EntitySetHandle is typedef'd as: typedef struct iBase_EntitySetHandle_Private* iBase_EntitySetHandle; in iBase.h?
The fact that a pointer is used in the typedef for a set handle does not in any way restrict implementations to using pointers, nor is it intended to.
On Jul 19, 2010, at 12:21 PM, Jason Kraftcheck wrote:
Saurabh Tendulkar wrote:
On 07/16/10 20:00, Carl Ollivier-Gooch wrote:
On 10-07-16 04:21 PM, Devine, Karen D wrote:
A. Change the iMesh_createEnt function to include an entity set handle argument PH. For serial applications, PH would be the root set; that is, entities are added only to the root set. For parallel applications, PH would be a part handle; the created entity would be added to the part identified by the part handle. Since iMesh_createEnt is an iMesh function (not an iMeshP function), we would use entity set handle as the argument type, so that serial users would not have to include iMeshP.h nor link with iMeshP. This option was generally accepted by Carl, Simmetrix, Sandia and RPI. Tim is in favor of adding the argument, but does not like the restriction of the handle to be either the root set or a part handle. My fear in allowing arbitrary entity set handles to be used is as follows: if a service uses the entity set handle to, say, add entities to a boundary condition set, that service could not be used in parallel, as its iMesh_createEnt calls would not add the entities to a part.
[snip]
I think for A, we proposed that the argument be NULL in case of serial. If we want no restriction in iMesh, then maybe we can instead pass an array of entity sets to iMesh_createEnt, and then in iMeshP stipulate that one of them has to be a part.
I don't really like the array idea, since I think that obscures the intent here. If there is a single argument that must be a part, then it is very simple to explain why its there and when and when not to pass something.
Logically null. Not literally 'NULL' (a bit-wise zero value). Not all implementations use pointer-based handles, and therefore zero is not an invalid handle value for all implementations. The closest thing we have to a logical null is the root set (as everything goes into the root set anyway.)
- jason
Would it make sense for an implementation to define a value that means NULL (for here and other places that it could be of use)? Passing the root set here could be confusing ("ah I see, everything is always added to the root set since I always have to pass it here. Oh wait, sometimes I don't have to pass it here, does that mean that this entity won't be added to the root set?") mark
Mark Beall wrote:
Would it make sense for an implementation to define a value that means NULL (for here and other places that it could be of use)?
Well, what value would you choose and how would you guarantee that it wouldn't be problematic for any existing implementation? Zero would clearly be troubling for an implementation that was array-based and simply used array indices as handles.
Passing the root set here could be confusing ("ah I see, everything is always added to the root set since I always have to pass it here. Oh wait, sometimes I don't have to pass it here, does that mean that this entity won't be added to the root set?")
I think this was one of the reasons that Tim argued that the function accept any set in the serial case. It would be less confusing than documenting a special case where an app need always pass the same redundant value (when working in serial.) I suppose we could pass a pointer to the handle, such that the pointer could be NULL. I'm not sure that that would be any less confusing than using the root set, through. And we already use the root set handle in exactly the same way in iMesh_loadMesh. - jason
On Jul 19, 2010, at 1:06 PM, Jason Kraftcheck wrote:
Mark Beall wrote:
Would it make sense for an implementation to define a value that means NULL (for here and other places that it could be of use)?
Well, what value would you choose and how would you guarantee that it wouldn't be problematic for any existing implementation? Zero would clearly be troubling for an implementation that was array-based and simply used array indices as handles.
There could be a function that returns that value (iMesh_getNullSet) or a global that the implementation must initialize to that value.
Passing the root set here could be confusing ("ah I see, everything is always added to the root set since I always have to pass it here. Oh wait, sometimes I don't have to pass it here, does that mean that this entity won't be added to the root set?")
I think this was one of the reasons that Tim argued that the function accept any set in the serial case. It would be less confusing than documenting a special case where an app need always pass the same redundant value (when working in serial.)
The problem with accepting any set is that you don't want people to use it for some other purpose in serial and then find they have to change their code to do the right thing in parallel.
I suppose we could pass a pointer to the handle, such that the pointer could be NULL. I'm not sure that that would be any less confusing than using the root set, through. And we already use the root set handle in exactly the same way in iMesh_loadMesh.
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic. mark
Mark Beall wrote:
On Jul 19, 2010, at 1:06 PM, Jason Kraftcheck wrote:
Mark Beall wrote:
Would it make sense for an implementation to define a value that means NULL (for here and other places that it could be of use)?
Well, what value would you choose and how would you guarantee that it wouldn't be problematic for any existing implementation? Zero would clearly be troubling for an implementation that was array-based and simply used array indices as handles.
There could be a function that returns that value (iMesh_getNullSet) or
We could do that. But it seems a lot simpler to use the existing iMesh_getRootSEt.
a global that the implementation must initialize to that value.
This would definitely eliminate the possibility of ever using multiple implementations at the same time.
Passing the root set here could be confusing ("ah I see, everything is always added to the root set since I always have to pass it here. Oh wait, sometimes I don't have to pass it here, does that mean that this entity won't be added to the root set?")
I think this was one of the reasons that Tim argued that the function accept any set in the serial case. It would be less confusing than documenting a special case where an app need always pass the same redundant value (when working in serial.)
The problem with accepting any set is that you don't want people to use it for some other purpose in serial and then find they have to change their code to do the right thing in parallel.
I suppose we could pass a pointer to the handle, such that the pointer could be NULL. I'm not sure that that would be any less confusing than using the root set, through. And we already use the root set handle in exactly the same way in iMesh_loadMesh.
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic.
How does it mean 'the set that contains everything' in the *load*Mesh case? -jason
On Jul 19, 2010, at 1:32 PM, Jason Kraftcheck wrote:
Passing the root set here could be confusing ("ah I see, everything is always added to the root set since I always have to pass it here. Oh wait, sometimes I don't have to pass it here, does that mean that this entity won't be added to the root set?")
I think this was one of the reasons that Tim argued that the function accept any set in the serial case. It would be less confusing than documenting a special case where an app need always pass the same redundant value (when working in serial.)
The problem with accepting any set is that you don't want people to use it for some other purpose in serial and then find they have to change their code to do the right thing in parallel.
I suppose we could pass a pointer to the handle, such that the pointer could be NULL. I'm not sure that that would be any less confusing than using the root set, through. And we already use the root set handle in exactly the same way in iMesh_loadMesh.
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic.
How does it mean 'the set that contains everything' in the *load*Mesh case?
Since the root set does contain everything and that's the set you're passing, thus you did add the entities into the set you passed in. Yes, the mesh entities get added to the root set anyhow, but it's at least a little consistent (although I do think that passing a NULL set here would be more clear). mark
Mark Beall wrote:
On Jul 19, 2010, at 1:32 PM, Jason Kraftcheck wrote:
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic.
How does it mean 'the set that contains everything' in the *load*Mesh case?
Since the root set does contain everything and that's the set you're passing, thus you did add the entities into the set you passed in. Yes, the mesh entities get added to the root set anyhow, but it's at least a little consistent (although I do think that passing a NULL set here would be more clear).
And how is this different than the createEnt case? - jason
On Jul 19, 2010, at 1:50 PM, Jason Kraftcheck wrote:
Mark Beall wrote:
On Jul 19, 2010, at 1:32 PM, Jason Kraftcheck wrote:
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic.
How does it mean 'the set that contains everything' in the *load*Mesh case?
Since the root set does contain everything and that's the set you're passing, thus you did add the entities into the set you passed in. Yes, the mesh entities get added to the root set anyhow, but it's at least a little consistent (although I do think that passing a NULL set here would be more clear).
And how is this different than the createEnt case?
Since we're trying to specify the part that the entity goes into in parallel. It's been pretty clearly established in the past that in iMesh/iMeshP parts are not entity sets (even though they may be in some implementations) even though there are a few entity set functions that are currently "overloaded" to also be able to take in parts (changing that was brought up at one point, I don't recall whether that ever was discussed) Really this function should take in a part handle, not an entity set. The definition for iMeshP_PartHandle could easily be moved into iMesh.h. Should also at that time, changing it so that's it's not typedefed to iBase_EntitySetHandle. mark
Mark Beall wrote:
On Jul 19, 2010, at 1:50 PM, Jason Kraftcheck wrote:
Mark Beall wrote:
On Jul 19, 2010, at 1:32 PM, Jason Kraftcheck wrote:
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic.
How does it mean 'the set that contains everything' in the *load*Mesh case?
Since the root set does contain everything and that's the set you're passing, thus you did add the entities into the set you passed in. Yes, the mesh entities get added to the root set anyhow, but it's at least a little consistent (although I do think that passing a NULL set here would be more clear).
And how is this different than the createEnt case?
Since we're trying to specify the part that the entity goes into in parallel. It's been pretty clearly established in the past that in iMesh/iMeshP parts are not entity sets (even though they may be in some implementations) even though there are a few entity set functions that are currently "overloaded" to also be able to take in parts (changing that was brought up at one point, I don't recall whether that ever was discussed)
Really this function should take in a part handle, not an entity set. The definition for iMeshP_PartHandle could easily be moved into iMesh.h. Should also at that time, changing it so that's it's not typedefed to iBase_EntitySetHandle.
But in the specific case of passing the root set as a 'null' handle to createEnt, how is the behavior different then when the root set is used in that way for loadMesh? In both cases the mesh is 'added' to the root set, which is essentially a no-op because everything is in the root set anyway. - jason
On Jul 19, 2010, at 2:14 PM, Jason Kraftcheck wrote:
Mark Beall wrote:
On Jul 19, 2010, at 1:50 PM, Jason Kraftcheck wrote:
Mark Beall wrote:
On Jul 19, 2010, at 1:32 PM, Jason Kraftcheck wrote:
I'd say that using the root set to mean both "no set" and "the set that contains everything" is confusing. In iMesh_loadMesh (and most other places I saw when I looked quickly) you can say that it means "everything in the instance", which is the same as the root set. However if there are places (now or in the future) where there is a meaningful difference between the two things, that usage could become problematic.
How does it mean 'the set that contains everything' in the *load*Mesh case?
Since the root set does contain everything and that's the set you're passing, thus you did add the entities into the set you passed in. Yes, the mesh entities get added to the root set anyhow, but it's at least a little consistent (although I do think that passing a NULL set here would be more clear).
And how is this different than the createEnt case?
Since we're trying to specify the part that the entity goes into in parallel. It's been pretty clearly established in the past that in iMesh/iMeshP parts are not entity sets (even though they may be in some implementations) even though there are a few entity set functions that are currently "overloaded" to also be able to take in parts (changing that was brought up at one point, I don't recall whether that ever was discussed)
Really this function should take in a part handle, not an entity set. The definition for iMeshP_PartHandle could easily be moved into iMesh.h. Should also at that time, changing it so that's it's not typedefed to iBase_EntitySetHandle.
But in the specific case of passing the root set as a 'null' handle to createEnt, how is the behavior different then when the root set is used in that way for loadMesh? In both cases the mesh is 'added' to the root set, which is essentially a no-op because everything is in the root set anyway.
I'll agree that it's the same in that it's misleading in both cases and will eventually cause an issue when the distinction between the root set and no set comes up to be meaningful in some situation (There could be such a case right now, I didn't look that hard) The fact that one can argue that it isn't completely illogical in the iMesh_load case doesn't mean that it's also a consistent expression of intent in that case. mark
participants (4)
-
Carl Ollivier-Gooch -
Jason Kraftcheck -
Mark Beall -
Saurabh Tendulkar