1 // Copyright (C) 2018-2019 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
5 #include "lin_omp_manager.h"
12 namespace MKLDNNPlugin {
17 Processor::Processor() {
24 loadContentFromFile("/proc/cpuinfo");
27 void CpuInfo::loadContentFromFile(const char *fileName) {
28 std::ifstream file(fileName);
30 (std::istreambuf_iterator<char>(file)),
31 (std::istreambuf_iterator<char>()));
33 loadContent(content.c_str());
36 void CpuInfo::loadContent(const char *content) {
37 size_t contentLength = strlen(content);
38 char *contentCopy = new char[contentLength + 1];
39 snprintf(contentCopy, contentLength + 1, "%s", content);
41 parseLines(contentCopy);
43 fileContentBegin = contentCopy;
44 fileContentEnd = &contentCopy[contentLength];
49 delete[] fileContentBegin;
52 void CpuInfo::parseLines(char *content) {
53 for (; *content; content++) {
54 if (*content == '\n') {
60 const char *CpuInfo::getFirstLine() {
61 currentLine = fileContentBegin < fileContentEnd ? fileContentBegin : NULL;
65 const char *CpuInfo::getNextLine() {
70 const char *savedCurrentLine = currentLine;
71 while (*(currentLine++)) {
74 if (currentLine >= fileContentEnd) {
78 return savedCurrentLine;
81 Collection::Collection(CpuInfoInterface *cpuInfo) : cpuInfo(*cpuInfo) {
82 totalNumberOfSockets = 0;
83 totalNumberOfCpuCores = 0;
84 currentProcessor = NULL;
86 processors.reserve(96);
89 collectBasicCpuInformation();
92 unsigned Collection::getTotalNumberOfSockets() {
93 return totalNumberOfSockets;
96 unsigned Collection::getTotalNumberOfCpuCores() {
97 return totalNumberOfCpuCores;
100 unsigned Collection::getNumberOfProcessors() {
101 return processors.size();
104 void Collection::parseCpuInfo() {
105 const char *cpuInfoLine = cpuInfo.getFirstLine();
106 for (; cpuInfoLine; cpuInfoLine = cpuInfo.getNextLine()) {
107 parseCpuInfoLine(cpuInfoLine);
111 void Collection::parseCpuInfoLine(const char *cpuInfoLine) {
112 int delimiterPosition = strcspn(cpuInfoLine, ":");
114 if (cpuInfoLine[delimiterPosition] == '\0') {
115 currentProcessor = NULL;
117 parseValue(cpuInfoLine, &cpuInfoLine[delimiterPosition + 2]);
121 void Collection::parseValue(const char *fieldName, const char *valueString) {
122 if (!currentProcessor) {
123 appendNewProcessor();
126 if (beginsWith(fieldName, "processor")) {
127 currentProcessor->processor = parseInteger(valueString);
130 if (beginsWith(fieldName, "physical id")) {
131 currentProcessor->physicalId = parseInteger(valueString);
134 if (beginsWith(fieldName, "cpu cores")) {
135 currentProcessor->cpuCores = parseInteger(valueString);
139 void Collection::appendNewProcessor() {
140 processors.push_back(Processor());
141 currentProcessor = &processors.back();
144 bool Collection::beginsWith(const char *lineBuffer, const char *text) const {
146 if (*(lineBuffer++) != *(text++)) {
154 unsigned Collection::parseInteger(const char *text) const {
158 void Collection::collectBasicCpuInformation() {
159 std::set<unsigned> uniquePhysicalId;
160 std::vector<Processor>::iterator processor = processors.begin();
161 for (; processor != processors.end(); processor++) {
162 uniquePhysicalId.insert(processor->physicalId);
163 updateCpuInformation(*processor, uniquePhysicalId.size());
167 void Collection::updateCpuInformation(const Processor &processor,
168 unsigned numberOfUniquePhysicalId) {
169 if (totalNumberOfSockets == numberOfUniquePhysicalId) {
173 totalNumberOfSockets = numberOfUniquePhysicalId;
174 totalNumberOfCpuCores += processor.cpuCores;
179 int getNumberOfCPUSockets() {
180 static CpuInfo cpuInfo;
181 static Collection collection(&cpuInfo);
182 return collection.getTotalNumberOfSockets();
185 int getNumberOfCPUCores() {
186 static CpuInfo cpuInfo;
187 static Collection collection(&cpuInfo);
188 unsigned numberOfProcessors = collection.getNumberOfProcessors();
189 unsigned totalNumberOfCpuCores = collection.getTotalNumberOfCpuCores();
191 cpu_set_t usedCoreSet, currentCoreSet, currentCpuSet;
192 CPU_ZERO(¤tCpuSet);
193 CPU_ZERO(&usedCoreSet);
194 CPU_ZERO(¤tCoreSet);
196 sched_getaffinity(0, sizeof(currentCpuSet), ¤tCpuSet);
198 for (int processorId = 0; processorId < numberOfProcessors; processorId++) {
199 if (CPU_ISSET(processorId, ¤tCpuSet)) {
200 unsigned coreId = processorId % totalNumberOfCpuCores;
201 if (!CPU_ISSET(coreId, &usedCoreSet)) {
202 CPU_SET(coreId, &usedCoreSet);
203 CPU_SET(processorId, ¤tCoreSet);
207 return CPU_COUNT(¤tCoreSet);
210 #endif // #ifndef APPLE
212 } // namespace MKLDNNPlugin