-
Notifications
You must be signed in to change notification settings - Fork 900
Topic/sentinel proc name conversion #1345
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,7 +13,7 @@ | |
* Copyright (c) 2007-2012 Los Alamos National Security, LLC. All rights | ||
* reserved. | ||
* Copyright (c) 2013-2014 Intel, Inc. All rights reserved | ||
* Copyright (c) 2015 Research Organization for Information Science | ||
* Copyright (c) 2015-2016 Research Organization for Information Science | ||
* and Technology (RIST). All rights reserved. | ||
* $COPYRIGHT$ | ||
* | ||
|
@@ -369,17 +369,66 @@ static inline bool ompi_proc_is_sentinel (ompi_proc_t *proc) | |
return (intptr_t) proc & 0x1; | ||
} | ||
|
||
static inline intptr_t ompi_proc_name_to_sentinel (opal_process_name_t name) | ||
#if OPAL_SIZEOF_PROCESS_NAME_T == SIZEOF_VOID_P | ||
/* | ||
* we assume an ompi_proc_t is at least aligned on two bytes, | ||
* so if the LSB of a pointer to an ompi_proc_t is 1, we have to handle | ||
* this pointer as a sentinel instead of a pointer. | ||
* a sentinel can be seen as an uint64_t with the following format : | ||
* - bit 0 : 1 | ||
* - bits 1-15 : local jobid | ||
* - bits 16-31 : job family | ||
* - bits 32-63 : vpid | ||
*/ | ||
static inline uintptr_t ompi_proc_name_to_sentinel (opal_process_name_t name) | ||
{ | ||
uintptr_t tmp, sentinel = 0; | ||
/* local jobid must fit in 15 bits */ | ||
assert(! (OMPI_LOCAL_JOBID(name.jobid) & 0x8000)); | ||
sentinel |= 0x1; | ||
tmp = (uintptr_t)OMPI_LOCAL_JOBID(name.jobid); | ||
sentinel |= ((tmp << 1) & 0xfffe); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been trying to understand this logic, and I'm not sure I believe that the "1" you want to set for the sentinel is winding up in the correct place. Isn't it supposed to be in the MSB position? |
||
tmp = (uintptr_t)OMPI_JOB_FAMILY(name.jobid); | ||
sentinel |= ((tmp << 16) & 0xffff0000); | ||
tmp = (uintptr_t)name.vpid; | ||
sentinel |= ((tmp << 32) & 0xffffffff00000000); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this still assume that uintptr_t is 64-bits? |
||
return sentinel; | ||
} | ||
|
||
static inline opal_process_name_t ompi_proc_sentinel_to_name (uintptr_t sentinel) | ||
{ | ||
opal_process_name_t name; | ||
uint32_t local, family; | ||
uint32_t vpid; | ||
assert(sentinel & 0x1); | ||
local = (sentinel >> 1) & 0x7fff; | ||
family = (sentinel >> 16) & 0xffff; | ||
vpid = (sentinel >> 32) & 0xffffffff; | ||
name.jobid = OMPI_CONSTRUCT_JOBID(family,local); | ||
name.vpid = vpid; | ||
return name; | ||
} | ||
#elif 4 == SIZEOF_VOID_P | ||
/* | ||
* currently, a sentinel is only made from the current jobid aka OMPI_PROC_MY_NAME->jobid | ||
* so we only store the first 31 bits of the vpid | ||
*/ | ||
static inline uintptr_t ompi_proc_name_to_sentinel (opal_process_name_t name) | ||
{ | ||
return (*((intptr_t *) &name) << 1) | 0x1; | ||
assert(OMPI_PROC_MY_NAME->jobid == name.jobid); | ||
return (uintptr_t)((name.vpid <<1) | 0x1); | ||
} | ||
|
||
static inline opal_process_name_t ompi_proc_sentinel_to_name (intptr_t sentinel) | ||
static inline opal_process_name_t ompi_proc_sentinel_to_name (uintptr_t sentinel) | ||
{ | ||
sentinel >>= 1; | ||
sentinel &= 0x7FFFFFFFFFFFFFFF; | ||
return *((opal_process_name_t *) &sentinel); | ||
opal_process_name_t name; | ||
name.jobid = OMPI_PROC_MY_NAME->jobid; | ||
name.vpid = sentinel >> 1; | ||
return name; | ||
} | ||
#else | ||
#error unsupported pointer size | ||
#endif | ||
|
||
END_C_DECLS | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -97,6 +97,9 @@ ORTE_DECLSPEC char *orte_pretty_print_timing(int64_t secs, int64_t usecs); | |
#define ORTE_CONSTRUCT_LOCAL_JOBID(local, job) \ | ||
( ((local) & 0xffff0000) | ((job) & 0x0000ffff) ) | ||
|
||
#define ORTE_CONSTRUCT_JOBID(family, local) \ | ||
ORTE_CONSTRUCT_LOCAL_JOBID(ORTE_CONSTRUCT_JOB_FAMILY(family), local) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this really work if family and local are just 16-bit values? My macros assumed they were 32-bit. |
||
/* a macro for identifying that a proc is a daemon */ | ||
#define ORTE_JOBID_IS_DAEMON(n) \ | ||
!((n) & 0x0000ffff) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW: that memory map isn't quite correct. I'm not sure how you are numbering bits, but assuming that they go from 0 as the LSB to 63 as the MSB, then the layout is:
So you want to set your sentinel in bit 47, not bit 0. Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sentinel bit is the LSB, aka bit zero.
see my comment in the code above
an ompi_proc_t* can either be a genuine pointer, or a sentinel.
that would require 65 bits.
the trick is pointer are always aligned on two bytes, so the LSB of a pointer is always zero, and we can use this bit as the sentinel bit.
if it is one, it means this is not a pointer but a sentinel.
that still means we have to "pack" the opal_process_name_t into the remaining 63 bits, and we decided to drop the MSB of the local jobid.
note that cannot work "as is" 32 bits.
my best bet is to simply disable cutoff at runtime on 32 bits arch
an other option to keep memory usage low is to use the sentinel bit as an opal_process_name_t* instead of a "packed" opal_process_name_t, but I am not sure it is worth it.
I will likely use jobid and family as uint32_t as you mentionned, and fix the abstraction
makes more sense now ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fwiw, @hjelmn initially used the MSB as the sentinel bit, assuming the MSB of an ompi_proc_t address was always zero. this assumption was proven wrong on a linux/sparc Fujitsu cluster.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with using the MSB of the local jobid. What I'm confused by is that your documented bitmap is incorrect. The local jobid is in the middle of the object, not at the edge as you show.
Nathan mistakenly used the MSB of the entire structure instead of the local jobid. Your bitmap moves it to the LSB of the entire structure, which is the LSB of the vpid, not the local jobid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am confused too ...
I guess the way we number bits differ
where does the local jobid end into ?
and btw, is this endian dependent ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rhc54 Ok, just making sure. I agree we need to update ompi_group_t. I have some ideas I can start implementing in the next month. Can target 2.1.x or 2.2.x for the changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hjelmn Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we use the LSB of the uint64_t, and shift the vpid to the correct place (so that we logically use the MSB of the jobid), I dont see why this will be an issue if we decide to make the orte_process_name_t a 32 bits value. Why are we trying to increase the opportunities for cache pollution by moving to a design that will require at least 2 extra indirections (the array of arrays solution).
There is a much simpler solution: dissociate the opal_process_name_t from the orte_process_name_t (in a mechanism similar to the lazy naming resolution for shared libraries). Make opal_process_name_t a simple int (32 to start with) that will be the index to an internal array that we alter every time the process known universe changes. This solution might be a little confusing as the index does not represent a global unique naming, but the ORTE name it points to does, but it has the benefit to let us (OPAL and OMPI) be totally independent on how ORTE wants to name it's processes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I said, I'm not advocating any particular solution - I'm only pointing out that hinging the scheme on a particular size of the process name struct, or on the idea that we can arbitrarily throw away one of its bits without repercussions, is fragile. If you have a better scheme than the one I suggested, that's fine with me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has at least the advantage of making OPAL + OMPI totally independent on how the RTE names processes...