12#include "gadgetconfig.h"
14#include <gsl/gsl_rng.h>
21#include "../system/pinning.h"
28 cpuset = hwloc_bitmap_alloc();
29 hwloc_get_proc_cpubind(topology, getpid(), cpuset, 0);
37 hwloc_topology_init(&topology);
40 hwloc_topology_load(topology);
44 topodepth = hwloc_topology_get_depth(topology);
46 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_SOCKET);
48 if(depth == HWLOC_TYPE_DEPTH_UNKNOWN)
51 sockets = hwloc_get_nbobjs_by_depth(topology, depth);
53 depth = hwloc_get_type_depth(topology, HWLOC_OBJ_CORE);
55 if(depth == HWLOC_TYPE_DEPTH_UNKNOWN)
58 cores = hwloc_get_nbobjs_by_depth(topology, depth);
60 depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU);
62 if(depth == HWLOC_TYPE_DEPTH_UNKNOWN)
65 pus = hwloc_get_nbobjs_by_depth(topology, depth);
72 sc->
mpi_printf(
"PINNING: We have %d sockets, %d physical cores and %d logical cores on the first MPI-task's node.\n", sockets, cores,
74 if(cores <= 0 || sockets <= 0 || pus <= 0)
76 sc->
mpi_printf(
"PINNING: The topology cannot be recognized. We refrain from any pinning attempt.\n");
77 flag_pinning_error = 1;
81 hyperthreads_per_core = pus / cores;
83 if(hyperthreads_per_core < 1)
84 Terminate(
"Need at least one logical thread per physical core\n");
87 sc->
mpi_printf(
"PINNING: Looks like %d hyperthreads per physical core are in principle possible.\n", hyperthreads_per_core);
89 cpuset_after_MPI_init = hwloc_bitmap_alloc();
90 hwloc_get_proc_cpubind(topology, getpid(), cpuset_after_MPI_init, 0);
92 if(!hwloc_bitmap_isequal(cpuset, cpuset_after_MPI_init))
93 sc->
mpi_printf(
"PINNING: Apparently, the MPI library set some pinning itself. We'll override this.\n");
95 int available_pus = 0;
97 for(
int id = hwloc_bitmap_first(cpuset);
id != -1;
id = hwloc_bitmap_next(cpuset,
id))
100 sc->
mpi_printf(
"PINNING: Looks like %d logical cores are available.\n", available_pus);
102 if(available_pus == pus)
104 sc->
mpi_printf(
"PINNING: Looks like all available logical cores are at our disposal.\n");
108 if(available_pus >= 1)
110 sc->
mpi_printf(
"PINNING: Looks like already before start of the code, a tight binding was imposed.\n");
111#ifdef IMPOSE_PINNING_OVERRIDE_MODE
112 for(
int id = 0;
id < pus;
id++)
113 hwloc_bitmap_set(cpuset,
id);
115 sc->
mpi_printf(
"PINNING: We are overriding this and make all %d available to us.\n", available_pus);
118 "PINNING: We refrain from any pinning attempt ourselves. (This can be changed by setting the compile flag "
119 "IMPOSE_PINNING_OVERRIDE_MODE.)\n");
120 flag_pinning_error = 1;
128 for(
int i = 0; i < pus && i <
MAX_CORES; i++)
129 if(hwloc_bitmap_isset(cpuset, i))
135 sc->
mpi_printf(
"PINNING: Available logical cores on first node: %s\n", buf);
139 sc->
mpi_printf(
"PINNING: %d logical cores are available per MPI Task.\n", pus_per_task);
141 if(pus_per_task <= 0)
142 Terminate(
"Need at least one logical core per MPI task for pinning to make sense.\n");
145 int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_PU);
146 int cores_before = 0;
149 for(cid = 0; cores_before < sc->
RankInThisNode * pus_per_task && cid < pus; cid++)
151 hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, cid);
153 hwloc_cpuset_t cpuset_core = hwloc_bitmap_dup(obj->cpuset);
154 if(hwloc_bitmap_isincluded(cpuset_core, cpuset))
158 hwloc_bitmap_free(cpuset_core);
163 hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, cid);
164 hwloc_cpuset_t current_cpu = hwloc_bitmap_dup(obj->cpuset);
166 hwloc_set_proc_cpubind(topology, getpid(), current_cpu, HWLOC_CPUBIND_PROCESS);
173 if(flag_pinning_error)
176 hwloc_get_cpubind(topology, cpuset, 0);
180 for(
int i = 0; i < pus && i <
MAX_CORES; i++)
181 if(hwloc_bitmap_isset(cpuset, i))
187 for(
int i = 0; i < sc->
NTask; i++)
190 printf(
"PINNING: Node=%4d: Task=%04d: %s\n", sc->
ThisNode, sc->
ThisTask, buf);
void report_pinning(setcomm *sc)
void detect_topology(void)
void pin_to_core_set(setcomm *sc)
void mpi_printf(const char *fmt,...)