Open MPI logo

PLPA Users' Mailing List Archives

  |   Home   |   Support   |   FAQ   |   all PLPA Users mailing list

From: Jeff Squyres (jsquyres_at_[hidden])
Date: 2007-04-27 09:04:00


On Apr 24, 2007, at 2:11 PM, Bert Wesarg wrote:

>> Hmm. Is that really a good idea? I'd think it was safer to say "I
>> don't know" rather than "here's a fallback which may or may not be
>> true."
> Loud thinking:
>
> What is the worst case that could happen, if we have no thread
> information, aka the file thread_siblings is missing:
> There are threads, so for two cpu ids cpu_i, cpu_j there should be two
> tuple with (x, y, a) and (x, y, b) where a != b. So we end up with a
> mapping from cpu_i and cpu_j to (x, y, 0).
>
> So the best way is here to return topo unsupported. the best thing
> is to
> catch this thing in the cache building.

According to your prior post, we should always have the hmt
information if we have the socket/core information, right? If so I
think that this is a moot point.

Here's the matrix of possible information in the kernel, assembled
from a few prior posts:

- number of linux virtual processors: always available
- socket/core mappings: available in >=2.6.16
- hmt mappings: available >=2.6.16
- node mappings: available ?for a long time?

------

I think I'm finally understanding what you mean by adding a 3rd
member to the (socket,core) tuple (for the [hardware] thread ID).

So I think the question is: how do we want to expose the [hardware]
thread information and node in the API?

I think looking at the data relationships will help here:

- one-to-one: (socket,core) -> processor ID
- one-to-one: (socket,core) -> node ID
- one-to-many: (socket,core) -> thread IDs
- one-to-one: processor ID -> (socket,core)
- one-to-one: processor ID -> node ID
- one-to-one: processor ID -> thread ID
- one-to-many: node ID -> (socket,core)
- one-to-many: node ID -> processor IDs
- one-to-many: node ID -> thread IDs (potentially not unique)
- one-to-many: thread ID -> (socket,core)
- one-to-many: thread ID -> processor IDs
- one-to-many: thread ID -> node ID

Looking at this list, I can imagine wanting to do lookups on any of
them (looking up <foo> given a specific thread ID is probably
somewhat dubious, but I can imagine *some* application may want to do
it...?).

If it really *is* useful to lookup based on any of these items,
perhaps we're looking at this the wrong way -- what if there was a
single function that did all lookups, and search terms and result
information was expressed in terms of a struct? Perhaps something
like this:

-----
#define PLPA_CPU_INFO_WILDCARD -1
#define PLPA_CPU_INFO_UNKNOWN -2
typedef struct _plpa_cpu_info_t {
   int socket, core, processor_id, thread_id, node_id;
} plpa_cpu_info_t;

int plpa_lookup(plpa_cpu_info_t *search_term, plpa_cpu_info_t **results,
                 int *result_count);

/* Example usage */

void foo() {
     plpa_cpu_info_t search, *results;
     int result_count;

     /* Search on a (socket,core) tuple */
     search.socket = desired_socket_id;
     search.core = desired_core_id;
     search.processor_id = search.thread_id = search.node_id =
PLPA_CPU_INFO_WILDCARD;
     if (0 == plpa_lookup(&search, &results, &result_count)) {
         /* can look through results[0] - results[result_count -1] */
         free(results);
     }

     /* Search on a node ID */
     search.node_id = desired_node_id;
     search.processor_id = search.thread_id = search.core =
search.socket = PLPA_CPU_INFO_WILDCARD;
     if (0 == plpa_lookup(&search, &results, &result_count)) {
         /* can look through results[0] - results[result_count -1] */
         free(results);
      }

/* ...and so on */
-----

Hence, you get get an array of struct's back that you can examine for
whatever you want, and you can eventually release in a single call to
free(). This seems simple and straightforward.

Thoughts?

-- 
Jeff Squyres
Cisco Systems