ARGOBOTS  140a356fc09a44696eb3487150e459266f9b5405
abtd_affinity.c
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 /*
7  * The Argobots affinity module parses the following grammar while it ignores
8  * all white spaces between tokens. Double-quoted symbols in the following are
9  * part of the syntax.
10  *
11  * <list> = <interval>
12  * | <list> "," <interval>
13  * <interval> = <es-id-list> ":" <num> ":" <stride>
14  * | <es-id-list> ":" <num>
15  * | <es-id-list>
16  * <es-id-list> = <id>
17  * | "{" <id-list> "}"
18  * <id-list> = <id-interval>
19  * | <id-list> "," <id-interval>
20  * <id-interval> = <id> ":" <num> ":" <stride>
21  * | <id> ":" <num>
22  * | <id>
23  * <id> = <integer>
24  * <stride> = <integer>
25  * <num> = <positive integer>
26  *
27  * An execution stream with rank n refers to the (n % N)th CPU ID list
28  * (<es-id-list>) of the whole list (<list>) that has N items. The execution
29  * stream will be scheduled on a core that has a CPU ID in its CPU ID list
30  * (<es-id-list>). If a CPU ID is smaller than zero or larger than the number
31  * of cores recognized by the system, a modulo of the number of cores is used.
32  *
33  * This grammar supports a pattern-based syntax. <id-interval> can represent
34  * multiple CPU IDs by specifying a base CPU ID (<id>), the number of CPU IDs
35  * (<num>), and a stride (<stride>) as follows:
36  * <id>, <id> + <stride>, ..., <id> + <stride> * (<num> - 1)
37  * <interval> also accepts a pattern-based syntax as follows:
38  * <es-id-list>,
39  * {<es-id-list>[0] + <stride>, <es-id-list>[1] + <stride>, ...}, ...
40  * {<es-id-list>[0] + <stride> * (<num> - 1),
41  * <es-id-list>[1] + <stride> * (<num> - 1), ...}
42  * Note that <num> and <stride> are set to 1 if they are omitted.
43  *
44  * Let us assume a 12-core machine (NOTE: "12-core" does not mean 12 physical
45  * cores but indicates 12 hardware threads on modern CPUs). Examples are as
46  * follows:
47  *
48  * Example 1: bind ES with rank n to a core that has CPU ID = n % 12
49  *
50  * | ES0 | ES1 | ES2 | ES3 | ES4 | ES5 | ES6 | ES7 | ES8 | ES9 | ES10| ES11|
51  * |CPU00|CPU01|CPU02|CPU03|CPU04|CPU05|CPU06|CPU07|CPU08|CPU09|CPU10|CPU11|
52  *
53  * (1.1) ABT_SET_AFFINITY="{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11}"
54  * This explicitly sets all the CPU IDs.
55  * (1.2) ABT_SET_AFFINITY="0,1,2,3,4,5,6,7,8,9,10,11"
56  * It is similar to (1.1), but it omits "{}" since "{id}" = "id".
57  * (1.3) ABT_SET_AFFINITY="{0}:12:1"
58  * This creates 12 CPU ID lists starting from {0}. The stride is specified
59  * as 1, so the created lists are {0}, {1}, {2}, ... {11}.
60  * (1.4) ABT_SET_AFFINITY="{0}:12"
61  * The default stride is 1, so it is the same as (1.3)
62  * (1.5) ABT_SET_AFFINITY="0:12"
63  * It omits "{}" in (1.4) since "{id}" = "id".
64  *
65  * Example 2: bind ES with rank n to a core that has CPU ID = (n + 6) % 12
66  *
67  * | ES6 | ES7 | ES8 | ES9 | ES10| ES11| ES0 | ES1 | ES2 | ES3 | ES4 | ES5 |
68  * |CPU00|CPU01|CPU02|CPU03|CPU04|CPU05|CPU06|CPU07|CPU08|CPU09|CPU10|CPU11|
69  *
70  * (2.1) ABT_SET_AFFINITY="{6},{7},{8},{9},{10},{11},{0},{1},{2},{3},{4},{5}"
71  * This explicitly sets all the CPU IDs.
72  * (2.2) ABT_SET_AFFINITY="6,7,8,9,10,11,0,1,2,3,4,5"
73  * It is similar to (2.1), but it omits "{}" since "{id}" = "id".
74  * (2.3) ABT_SET_AFFINITY="{6}:6:1,{0}:6:1"
75  * This first creates 6 CPU ID lists starting from {6} and then 6 lists
76  * starting from {0}. The stride is "1", so the created lists are
77  * {6}, ... {11}, {0} ... {5}.
78  * (2.4) ABT_SET_AFFINITY="{6}:6,{0}:6"
79  * The default stride is 1, so it is the same as (2.3)
80  * (2.5) ABT_SET_AFFINITY="6:6,0:6"
81  * It omits "{}" in (2.4) since "{id}" = "id".
82  * (2.6) ABT_SET_AFFINITY="6:12"
83  * Affinity setting wraps around with respect to the number of cores, so
84  * this works the same as (2.5) on a 12-core machine.
85  *
86  * Example 3: bind ES with rank n to core that has CPU ID = (n * 4) % 12
87  *
88  * | ES0 | | | | ES1 | | | | ES2 | | | |
89  * |CPU00|CPU01|CPU02|CPU03|CPU04|CPU05|CPU06|CPU07|CPU08|CPU09|CPU10|CPU11|
90  *
91  * (3.1) ABT_SET_AFFINITY="{0},{4},{8}"
92  * This explicitly sets all the CPU IDs.
93  * (3.2) ABT_SET_AFFINITY="0,4,8"
94  * It is similar to (3.1), but it omits "{}" since "{id}" = "id".
95  * (3.3) ABT_SET_AFFINITY="{0}:3:4"
96  * This creates 3 CPU ID lists starting from {0}. The stride is "4", so
97  * creates lists are {0}, {4}, {8}.
98  * (3.4) ABT_SET_AFFINITY="0:3:4"
99  * It omits "{}" in (3.3) since "{id}" = "id".
100  *
101  * Example 4: bind ES with rank n to core that has
102  * CPU ID = (n * 4 + (n % 12) / 3) % 12
103  *
104  * | ES0 | ES3 | ES6 | ES9 | ES1 | ES4 | ES7 | ES10| ES2 | ES5 | ES9 | ES11|
105  * |CPU00|CPU01|CPU02|CPU03|CPU04|CPU05|CPU06|CPU07|CPU08|CPU09|CPU10|CPU11|
106  *
107  * (4.1) ABT_SET_AFFINITY="{0},{4},{8},{1},{5},{9},{2},{6},{10},{3},{7},{11}"
108  * This explicitly sets all the CPU IDs.
109  * (4.2) ABT_SET_AFFINITY="0,4,8,1,5,9,2,6,10,3,7,11"
110  * It is similar to (4.1), but it omits "{}" since "{id}" = "id".
111  * (4.3) ABT_SET_AFFINITY="{0}:3:4,{1}:3:4,{2}:3:4,{3}:3:4"
112  * This creates 3 CPU ID lists ({0}, {4}, {8}), then ({1}, {5}, {9}),
113  * ({2}, {6}, {10}), and ({3}, {7}, {11}).
114  * (4.4) ABT_SET_AFFINITY="0:3:4,1:3:4,2:3:4,3:3:4"
115  * It omits "{}" in (4.3) since "{id}" = "id".
116  *
117  * Example 5: bind ES with rank n to cores that have
118  * (n * 4) % 12 <= CPU ID < (n * 4) % 12 + 4
119  *
120  * | ES0 | ES1 | ES2 |
121  * |CPU00|CPU01|CPU02|CPU03|CPU04|CPU05|CPU06|CPU07|CPU08|CPU09|CPU10|CPU11|
122  *
123  * (5.1) ABT_SET_AFFINITY="{0,1,2,3},{4,5,6,7},{8,9,10,11}"
124  * This explicitly sets all the CPU IDs.
125  * (5.2) ABT_SET_AFFINITY="{0,1,2,3}:3:4"
126  * This creates 3 CPU ID lists starting from {0,1,2,3}. The stride is "4",
127  * so the created lists are "{0,1,2,3}, {4,5,6,7}, {8,9,10,11}".
128  * Note that "{0,1,2,3}:3:1" (or "{0,1,2,3}:3") is wrong: they create
129  * "{0,1,2,3}, {2,3,4,5}, {3,4,5,6}" since the stride is 1.
130  * (5.3) ABT_SET_AFFINITY="{0:4:1}:3:4"
131  * "{0:4:1}" means a CPU ID list of 4 CPU IDs that starts from 0 with a
132  * stride 1, so it is the same as "{0,1,2,3}".
133  * (5.4) ABT_SET_AFFINITY="{0:4}:3:4"
134  * The default stride is 1.
135  *
136  * Example 6: bind ES with rank n to cores that have either of the following:
137  * CPU ID = (n * 2) % 6
138  * CPU ID = (n * 2) % 6 + 6
139  *
140  * | ES0 | ES1 | ES2 | ES3 | ES4 | ES5 |
141  * |CPU00|CPU06|CPU01|CPU07|CPU02|CPU08|CPU03|CPU09|CPU04|CPU10|CPU05|CPU11|
142  *
143  * (6.1) ABT_SET_AFFINITY="{0,6},{1,7},{2,8},{3,9},{4,10},{5,11}"
144  * This explicitly sets all the CPU IDs.
145  * (6.2) ABT_SET_AFFINITY="{0,6}:6:1"
146  * This creates 6 CPU ID lists starting from {0,6}. The stride is "1", so
147  * the created lists are "{0,6}, {1,7}, {2,8}, {3,9}, {4,10}, {5,11}".
148  * (6.3) ABT_SET_AFFINITY="{0,6}:6"
149  * The default stride is 1.
150  *
151  * Example 7: bind ESs to cores except for those that have CPU ID = 0 or 1
152  *
153  * | | ES0, ES1, ES2, ... |
154  * |CPU00|CPU01|CPU02|CPU03|CPU04|CPU05|CPU06|CPU07|CPU08|CPU09|CPU10|CPU11|
155  *
156  * (7.1) ABT_SET_AFFINITY="{2,3,4,5,6,7,8,9,10,11}"
157  * This explicitly sets all the CPU IDs.
158  * (7.2) ABT_SET_AFFINITY="{2:10:1}"
159  * "{2:10:1}" means a CPU ID list that has 10 CPU IDs starting from 2 with
160  * a stride 1, so it is the same as "{2,3,4,5,6,7,8,9,10,11}".
161  * (7.3) ABT_SET_AFFINITY="{2:10}"
162  * The default stride is 1.
163  */
164 
165 #include "abti.h"
166 #include <unistd.h>
167 
168 #ifdef HAVE_PTHREAD_SETAFFINITY_NP
169 #ifdef __FreeBSD__
170 
171 #include <sys/param.h>
172 #include <sys/cpuset.h>
173 #include <pthread_np.h>
174 typedef cpuset_t cpu_set_t;
175 
176 #else /* !__FreeBSD__ */
177 
178 #define _GNU_SOURCE
179 #include <sched.h>
180 
181 #endif
182 #endif /* HAVE_PTHREAD_SETAFFINITY_NP */
183 
184 typedef struct {
186  uint32_t num_cpusets;
189 
191 
192 static inline int int_rem(int a, unsigned int b)
193 {
194  /* Return x where a = n * b + x and 0 <= x < b */
195  /* Because of ambiguity in the C specification, it uses a branch to check if
196  * the result is positive. */
197  int int_b = b;
198  int ret = (a % int_b) + int_b;
199  return ret >= int_b ? (ret - int_b) : ret;
200 }
201 
202 ABTU_ret_err static int get_num_cores(pthread_t native_thread, int *p_num_cores)
203 {
204 #ifdef HAVE_PTHREAD_SETAFFINITY_NP
205  int i, num_cores = 0;
206  /* Check the number of available cores by counting set bits. */
207  cpu_set_t cpuset;
208  int ret = pthread_getaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
209  if (ret)
210  return ABT_ERR_SYS;
211  for (i = 0; i < CPU_SETSIZE; i++) {
212  if (CPU_ISSET(i, &cpuset)) {
213  num_cores++;
214  }
215  }
216  *p_num_cores = num_cores;
217  return ABT_SUCCESS;
218 #else
219  return ABT_ERR_FEATURE_NA;
220 #endif
221 }
222 
223 ABTU_ret_err static int create_cpuset(pthread_t native_thread,
224  ABTD_affinity_cpuset *p_cpuset)
225 {
226 #ifdef HAVE_PTHREAD_SETAFFINITY_NP
227  cpu_set_t cpuset;
228  int ret = pthread_getaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
229  if (ret)
230  return ABT_ERR_SYS;
231  int i, j, num_cpuids = 0;
232  for (i = 0; i < CPU_SETSIZE; i++) {
233  if (CPU_ISSET(i, &cpuset))
234  num_cpuids++;
235  }
236  p_cpuset->num_cpuids = num_cpuids;
237  ret = ABTU_malloc(sizeof(int) * num_cpuids, (void **)&p_cpuset->cpuids);
238  ABTI_CHECK_ERROR(ret);
239  for (i = 0, j = 0; i < CPU_SETSIZE; i++) {
240  if (CPU_ISSET(i, &cpuset))
241  p_cpuset->cpuids[j++] = i;
242  }
243  return ABT_SUCCESS;
244 #else
245  return ABT_ERR_FEATURE_NA;
246 #endif
247 }
248 
249 ABTU_ret_err static int read_cpuset(pthread_t native_thread, int max_cpuids,
250  int *cpuids, int *p_num_cpuids)
251 {
252 #ifdef HAVE_PTHREAD_SETAFFINITY_NP
253  cpu_set_t cpuset;
254  int ret = pthread_getaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
255  if (ret)
256  return ABT_ERR_SYS;
257  int i, num_cpuids = 0;
258  for (i = 0; i < CPU_SETSIZE; i++) {
259  if (CPU_ISSET(i, &cpuset)) {
260  if (num_cpuids < max_cpuids) {
261  cpuids[num_cpuids] = i;
262  }
263  num_cpuids++;
264  }
265  }
266  *p_num_cpuids = num_cpuids;
267  return ABT_SUCCESS;
268 #else
269  return ABT_ERR_FEATURE_NA;
270 #endif
271 }
272 
273 ABTU_ret_err static int apply_cpuset(pthread_t native_thread,
274  const ABTD_affinity_cpuset *p_cpuset)
275 {
276 #ifdef HAVE_PTHREAD_SETAFFINITY_NP
277  uint32_t i;
278  cpu_set_t cpuset;
279  CPU_ZERO(&cpuset);
280  if (p_cpuset->num_cpuids == 0) {
281  /* Use the initial one. */
282  for (i = 0; i < g_affinity.initial_cpuset.num_cpuids; i++)
283  CPU_SET(int_rem(g_affinity.initial_cpuset.cpuids[i], CPU_SETSIZE),
284  &cpuset);
285  } else {
286  for (i = 0; i < p_cpuset->num_cpuids; i++)
287  CPU_SET(int_rem(p_cpuset->cpuids[i], CPU_SETSIZE), &cpuset);
288  }
289  int ret = pthread_setaffinity_np(native_thread, sizeof(cpu_set_t), &cpuset);
290  return ret == 0 ? ABT_SUCCESS : ABT_ERR_SYS;
291 #else
292  return ABT_ERR_FEATURE_NA;
293 #endif
294 }
295 
296 void ABTD_affinity_init(const char *affinity_str)
297 {
299  g_affinity.cpusets = NULL;
301  pthread_t self_native_thread = pthread_self();
302  uint32_t i;
303  int ret;
304  ret = get_num_cores(self_native_thread, &gp_ABTI_global->num_cores);
305  if (ret != ABT_SUCCESS || gp_ABTI_global->num_cores == 0) {
307  return;
308  }
309  ret = create_cpuset(self_native_thread, &g_affinity.initial_cpuset);
310  if (ret != ABT_SUCCESS) {
312  return;
313  } else if (g_affinity.initial_cpuset.num_cpuids == 0) {
316  return;
317  }
319  ABTD_affinity_list *p_list = ABTD_affinity_list_create(affinity_str);
320  if (p_list) {
321  if (p_list->num == 0) {
322  ABTD_affinity_list_free(p_list);
323  p_list = NULL;
324  }
325  }
326  if (p_list) {
327  /* Create cpusets based on the affinity list.*/
328  g_affinity.num_cpusets = p_list->num;
330  (void **)&g_affinity.cpusets);
331  ABTI_ASSERT(ret == ABT_SUCCESS);
332  for (i = 0; i < p_list->num; i++) {
333  const ABTD_affinity_id_list *p_id_list = p_list->p_id_lists[i];
334  uint32_t j, num_cpuids = 0, len_cpuids = 8;
335  ret = ABTU_malloc(sizeof(int) * len_cpuids,
336  (void **)&g_affinity.cpusets[i].cpuids);
337  ABTI_ASSERT(ret == ABT_SUCCESS);
339  ABTD_affinity_list_free(p_list);
341  return;
342  }
343  for (j = 0; j < p_id_list->num; j++) {
344  int cpuid_i = int_rem(p_id_list->ids[j],
346  int cpuid = g_affinity.initial_cpuset.cpuids[cpuid_i];
347  /* If it is unique, add it.*/
348  uint32_t k;
349  int is_unique = 1;
350  for (k = 0; k < num_cpuids; k++) {
351  if (g_affinity.cpusets[i].cpuids[k] == cpuid) {
352  is_unique = 0;
353  break;
354  }
355  }
356  if (is_unique) {
357  if (num_cpuids == len_cpuids) {
358  ret = ABTU_realloc(sizeof(int) * len_cpuids,
359  sizeof(int) * len_cpuids * 2,
360  (void **)&g_affinity.cpusets[i]
361  .cpuids);
362  ABTI_ASSERT(ret == ABT_SUCCESS);
363  len_cpuids *= 2;
364  }
365  g_affinity.cpusets[i].cpuids[num_cpuids] = cpuid;
366  num_cpuids++;
367  }
368  }
369  /* Adjust the size of cpuids. */
370  if (num_cpuids != len_cpuids)
371  ret = ABTU_realloc(sizeof(int) * len_cpuids,
372  sizeof(int) * num_cpuids,
373  (void **)&g_affinity.cpusets[i].cpuids);
374  ABTI_ASSERT(ret == ABT_SUCCESS);
375  g_affinity.cpusets[i].num_cpuids = num_cpuids;
376  }
377  ABTD_affinity_list_free(p_list);
378  } else {
379  /* Create default cpusets. */
382  (void **)&g_affinity.cpusets);
383  ABTI_ASSERT(ret == ABT_SUCCESS);
384  for (i = 0; i < g_affinity.num_cpusets; i++) {
386  ret = ABTU_malloc(sizeof(int) * g_affinity.cpusets[i].num_cpuids,
387  (void **)&g_affinity.cpusets[i].cpuids);
388  ABTI_ASSERT(ret == ABT_SUCCESS);
389  g_affinity.cpusets[i].cpuids[0] =
391  }
392  }
393 }
394 
396 {
397  pthread_t self_native_thread = pthread_self();
399  /* Set the affinity of the main native thread to the original one. */
400  int abt_errno =
401  apply_cpuset(self_native_thread, &g_affinity.initial_cpuset);
402  /* Even if this cpuset apply fails, there is no way to handle it (e.g.,
403  * possibly the CPU affinity policy has been changed while running
404  * a user program. Let's ignore this error. */
405  (void)abt_errno;
406  }
407  /* Free g_afinity. */
409  uint32_t i;
410  for (i = 0; i < g_affinity.num_cpusets; i++) {
412  }
414  g_affinity.cpusets = NULL;
416 }
417 
419  int max_cpuids, int *cpuids,
420  int *p_num_cpuids)
421 {
422  return read_cpuset(p_ctx->native_thread, max_cpuids, cpuids, p_num_cpuids);
423 }
424 
425 ABTU_ret_err int
427  const ABTD_affinity_cpuset *p_cpuset)
428 {
429  return apply_cpuset(p_ctx->native_thread, p_cpuset);
430 }
431 
433  int rank)
434 {
436  ABTD_affinity_cpuset *p_cpuset =
438  return apply_cpuset(p_ctx->native_thread, p_cpuset);
439  }
440  return ABT_SUCCESS;
441 }
442 
444 {
445  if (p_cpuset) {
446  ABTU_free(p_cpuset->cpuids);
447  p_cpuset->cpuids = NULL;
448  }
449 }
ABTD_xstream_context::native_thread
pthread_t native_thread
Definition: abtd.h:22
ABT_ERR_SYS
#define ABT_ERR_SYS
Error code: an error related to system calls.
Definition: abt.h:385
ABTU_realloc
static ABTU_ret_err int ABTU_realloc(size_t old_size, size_t new_size, void **p_ptr)
Definition: abtu.h:240
ABTD_affinity_cpuset_apply
ABTU_ret_err int ABTD_affinity_cpuset_apply(ABTD_xstream_context *p_ctx, const ABTD_affinity_cpuset *p_cpuset)
Definition: abtd_affinity.c:426
ABTD_affinity_cpuset_read
ABTU_ret_err int ABTD_affinity_cpuset_read(ABTD_xstream_context *p_ctx, int max_cpuids, int *cpuids, int *p_num_cpuids)
Definition: abtd_affinity.c:418
ABTD_xstream_context
Definition: abtd.h:21
ABTI_CHECK_ERROR
#define ABTI_CHECK_ERROR(abt_errno)
Definition: abti_error.h:127
gp_ABTI_global
ABTI_global * gp_ABTI_global
Definition: global.c:18
get_num_cores
static ABTU_ret_err int get_num_cores(pthread_t native_thread, int *p_num_cores)
Definition: abtd_affinity.c:202
ABTI_IS_ERROR_CHECK_ENABLED
#define ABTI_IS_ERROR_CHECK_ENABLED
Definition: abti.h:20
int_rem
static int int_rem(int a, unsigned int b)
Definition: abtd_affinity.c:192
abti.h
global_affinity::num_cpusets
uint32_t num_cpusets
Definition: abtd_affinity.c:186
ABTU_malloc
static ABTU_ret_err int ABTU_malloc(size_t size, void **p_ptr)
Definition: abtu.h:218
ABTD_affinity_parser_list
Definition: abtd.h:74
ABTD_affinity_init
void ABTD_affinity_init(const char *affinity_str)
Definition: abtd_affinity.c:296
ABTI_ASSERT
#define ABTI_ASSERT(cond)
Definition: abti_error.h:12
ABTU_calloc
static ABTU_ret_err int ABTU_calloc(size_t num, size_t size, void **p_ptr)
Definition: abtu.h:227
ABT_SUCCESS
#define ABT_SUCCESS
Error code: the routine returns successfully.
Definition: abt.h:90
ABTU_ret_err
#define ABTU_ret_err
Definition: abtu.h:138
ABTD_affinity_parser_list::p_id_lists
ABTD_affinity_id_list ** p_id_lists
Definition: abtd.h:76
global_affinity
Definition: abtd_affinity.c:184
g_affinity
static global_affinity g_affinity
Definition: abtd_affinity.c:190
ABT_TRUE
#define ABT_TRUE
True constant for ABT_bool.
Definition: abt.h:735
ABTD_affinity_parser_list::num
uint32_t num
Definition: abtd.h:75
apply_cpuset
static ABTU_ret_err int apply_cpuset(pthread_t native_thread, const ABTD_affinity_cpuset *p_cpuset)
Definition: abtd_affinity.c:273
ABT_FALSE
#define ABT_FALSE
False constant for ABT_bool.
Definition: abt.h:737
ABTD_affinity_cpuset_destroy
void ABTD_affinity_cpuset_destroy(ABTD_affinity_cpuset *p_cpuset)
Definition: abtd_affinity.c:443
ABTD_affinity_cpuset::num_cpuids
size_t num_cpuids
Definition: abtd.h:36
ABTD_affinity_list_create
ABTD_affinity_list * ABTD_affinity_list_create(const char *affinity_str)
Definition: abtd_affinity_parser.c:254
ABTU_free
static void ABTU_free(void *ptr)
Definition: abtu.h:211
create_cpuset
static ABTU_ret_err int create_cpuset(pthread_t native_thread, ABTD_affinity_cpuset *p_cpuset)
Definition: abtd_affinity.c:223
ABTI_global::set_affinity
ABT_bool set_affinity
Definition: abti.h:186
ABTD_affinity_list_free
void ABTD_affinity_list_free(ABTD_affinity_list *p_list)
Definition: abtd_affinity_parser.c:259
ABTD_affinity_id_list::num
uint32_t num
Definition: abtd.h:71
ABTD_affinity_cpuset_apply_default
ABTU_ret_err int ABTD_affinity_cpuset_apply_default(ABTD_xstream_context *p_ctx, int rank)
Definition: abtd_affinity.c:432
read_cpuset
static ABTU_ret_err int read_cpuset(pthread_t native_thread, int max_cpuids, int *cpuids, int *p_num_cpuids)
Definition: abtd_affinity.c:249
ABTD_affinity_id_list
Definition: abtd.h:70
ABT_ERR_FEATURE_NA
#define ABT_ERR_FEATURE_NA
Error code: unsupported feature.
Definition: abt.h:380
global_affinity::cpusets
ABTD_affinity_cpuset * cpusets
Definition: abtd_affinity.c:187
ABTI_global::num_cores
int num_cores
Definition: abti.h:185
ABTD_affinity_cpuset
Definition: abtd.h:35
global_affinity::initial_cpuset
ABTD_affinity_cpuset initial_cpuset
Definition: abtd_affinity.c:185
ABTD_affinity_id_list::ids
int * ids
Definition: abtd.h:72
ABTD_affinity_finalize
void ABTD_affinity_finalize(void)
Definition: abtd_affinity.c:395
ABTD_affinity_cpuset::cpuids
int * cpuids
Definition: abtd.h:37