14#include "arcane/utils/IProcessorAffinityService.h"
15#include "arcane/utils/ITraceMng.h"
16#include "arcane/utils/OStringStream.h"
18#include "arcane/core/FactoryService.h"
19#include "arcane/core/AbstractService.h"
21#include "arccore/base/internal/DependencyInjection.h"
36class HWLocProcessorAffinityService
46 explicit HWLocProcessorAffinityService(
ITraceMng* tm)
52 ~HWLocProcessorAffinityService()
override
55 hwloc_topology_destroy(m_topology);
60 void build()
override {}
75 bool m_is_init =
false;
76 hwloc_topology_t m_topology =
nullptr;
81 void _outputTopology(hwloc_obj_t l, hwloc_obj_t parent,
int i,
OStringStream& ostr);
82 int _numberOf(
const hwloc_obj_type_t);
91_internal_hwloc_obj_snprintf(
char*
string,
size_t size,
92 hwloc_obj* l,
const char* _indexprefix,
int verbose)
94 const char* indexprefix = _indexprefix ? _indexprefix :
"#";
95 char os_index[12] =
"";
100 if (l->os_index != (
unsigned)-1) {
101 std::snprintf(os_index, 12,
"%s%u", indexprefix, l->os_index);
104 hwloc_obj_type_snprintf(type,
sizeof(type), l, verbose);
105 attrlen = hwloc_obj_attr_snprintf(attr,
sizeof(attr), l,
" ", verbose);
108 return std::snprintf(
string, size,
"%s%s(%s)", type, os_index, attr);
110 return std::snprintf(
string, size,
"%s%s", type, os_index);
117void HWLocProcessorAffinityService::
118_outputTopology(hwloc_obj_t l, hwloc_obj_t parent,
int i,
OStringStream& ostr)
120 const char* indexprefix =
"#";
122 if (parent && parent->arity == 1 && hwloc_bitmap_isequal(l->cpuset, parent->cpuset)) {
127 info() << ostr.str();
130 for (
int z = 0; z < 2 * i; ++z)
134 _internal_hwloc_obj_snprintf(line,
sizeof(line) - 1, l, indexprefix, 0);
136 unsigned int arity = l->arity;
137 if (arity != 0 || (!i && !arity)) {
138 for (
unsigned int x = 0; x < arity; ++x) {
139 _outputTopology(l->children[x], l, i, ostr);
147void HWLocProcessorAffinityService::
154 info() <<
"Getting hardware architecture hwloc_version=" << HWLOC_VERSION;
155 int err = hwloc_topology_init(&m_topology);
157 info() <<
"Error in hwloc_topology_init r=" << err;
160 unsigned long flags = 0;
161 hwloc_topology_set_flags(m_topology, flags);
163 err = hwloc_topology_load(m_topology);
165 info() <<
"Error in hwloc_topology_load r=" << err;
176 hwloc_bitmap_t new_cpuset = hwloc_bitmap_alloc();
177 hwloc_get_cpubind(m_topology, new_cpuset, 0 | HWLOC_CPUBIND_THREAD);
179 hwloc_bitmap_snprintf(result_s,
sizeof(result_s) - 1, new_cpuset);
182 hwloc_bitmap_free(new_cpuset);
194 _outputTopology(hwloc_get_root_obj(m_topology),
nullptr, 0, ostrf);
195 info() << ostrf.str();
206 hwloc_bitmap_t new_cpuset = hwloc_bitmap_alloc();
207 hwloc_get_cpubind(m_topology, new_cpuset, 0 | HWLOC_CPUBIND_THREAD);
211 unsigned int cpu_iter = 0;
212 hwloc_bitmap_foreach_begin(cpu_iter, new_cpuset)
216 if (cpu_index == cpu)
217 hwloc_bitmap_only(new_cpuset, cpu_iter);
220 hwloc_bitmap_foreach_end();
223 hwloc_set_cpubind(m_topology, new_cpuset, flags | HWLOC_CPUBIND_THREAD);
226 hwloc_get_cpubind(m_topology, new_cpuset, 0 | HWLOC_CPUBIND_THREAD);
228 hwloc_bitmap_snprintf(result_s,
sizeof(result_s) - 1, new_cpuset);
230 hwloc_bitmap_free(new_cpuset);
236Int32 HWLocProcessorAffinityService::
237_numberOf(
const hwloc_obj_type_t that)
240 int depth = hwloc_get_type_depth(m_topology, that);
241 if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
243 int width = hwloc_get_nbobjs_by_depth(m_topology, depth);
253 return _numberOf(HWLOC_OBJ_CORE);
262 return _numberOf(HWLOC_OBJ_SOCKET);
271 return _numberOf(HWLOC_OBJ_PU);
285 DependencyInjection::ProviderProperty(
"HWLoc"),
#define ARCANE_REGISTER_APPLICATION_FACTORY(aclass, ainterface, aname)
Registers a factory service for the class aclass.
Int32 numberOfProcessingUnit() override
Number of logical cores (-1 if unknown).
void bindThread(Int32 cpu) override
Constrains the current thread to stay on the core with index cpu.
void printInfos() override
Displays complete topology information via info().
Int32 numberOfCore() override
Number of CPU cores (-1 if unknown).
String cpuSetString() override
Returns the cpuset for the current thread.
Int32 numberOfSocket() override
Number of sockets (-1 if unknown).
virtual ITraceMng * traceMng() const =0
Trace manager.
Interface of a CPU core affinity management service.
Output stream linked to a String.
IApplication * application() const
Access to the associated IApplication.
Structure containing the information to create a service.
View of a UTF-8 character string.
Unicode character string.
TraceAccessor(ITraceMng *m)
Constructs an accessor via the trace manager m.
TraceMessage info() const
Flow for an information message.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
std::int32_t Int32
Signed integer type of 32 bits.