[llvm-branch-commits] [openmp] release/18x: [OpenMP][AIX] Affinity implementation for AIX (#84984) (PR #86695)
https://github.com/brad0 approved this pull request. https://github.com/llvm/llvm-project/pull/86695 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [openmp] release/18x: [OpenMP][AIX] Affinity implementation for AIX (#84984) (PR #86695)
https://github.com/xingxue-ibm updated https://github.com/llvm/llvm-project/pull/86695 >From 47aac495c89554bb61ee13a3a32823feec4bf5b4 Mon Sep 17 00:00:00 2001 From: Xing Xue Date: Fri, 22 Mar 2024 15:25:08 -0400 Subject: [PATCH] [OpenMP][AIX] Affinity implementation for AIX (#84984) This patch implements `affinity` for AIX, which is quite different from platforms such as Linux. - Setting CPU affinity through masks and related functions are not supported. System call `bindprocessor()` is used to bind a thread to one CPU per call. - There are no system routines to get the affinity info of a thread. The implementation of `get_system_affinity()` for AIX gets the mask of all available CPUs, to be used as the full mask only. - Topology is not available from the file system. It is obtained through system SRAD (Scheduler Resource Allocation Domain). This patch has run through the libomp LIT tests successfully with `affinity` enabled. (cherry picked from commit d394f3a162b871668d0c8e8bf6a94922fa8698ae) --- openmp/runtime/src/kmp.h| 4 +- openmp/runtime/src/kmp_affinity.cpp | 129 ++-- openmp/runtime/src/kmp_affinity.h | 73 +++- openmp/runtime/src/kmp_os.h | 3 +- openmp/runtime/src/z_Linux_util.cpp | 37 ++-- openmp/runtime/test/lit.cfg | 2 +- 6 files changed, 229 insertions(+), 19 deletions(-) diff --git a/openmp/runtime/src/kmp.h b/openmp/runtime/src/kmp.h index e3a1e20731bbe0..46ee4c9fba7109 100644 --- a/openmp/runtime/src/kmp.h +++ b/openmp/runtime/src/kmp.h @@ -818,6 +818,7 @@ class KMPAffinity { typedef KMPAffinity::Mask kmp_affin_mask_t; extern KMPAffinity *__kmp_affinity_dispatch; +#ifndef KMP_OS_AIX class kmp_affinity_raii_t { kmp_affin_mask_t *mask; bool restored; @@ -842,6 +843,7 @@ class kmp_affinity_raii_t { } ~kmp_affinity_raii_t() { restore(); } }; +#endif // !KMP_OS_AIX // Declare local char buffers with this size for printing debug and info // messages, using __kmp_affinity_print_mask(). @@ -3911,7 +3913,7 @@ extern void __kmp_balanced_affinity(kmp_info_t *th, int team_size); #if KMP_WEIGHTED_ITERATIONS_SUPPORTED extern int __kmp_get_first_osid_with_ecore(void); #endif -#if KMP_OS_LINUX || KMP_OS_FREEBSD +#if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_AIX extern int kmp_set_thread_affinity_mask_initial(void); #endif static inline void __kmp_assign_root_init_mask() { diff --git a/openmp/runtime/src/kmp_affinity.cpp b/openmp/runtime/src/kmp_affinity.cpp index 6a41d34b023729..1ac541fbcaa707 100644 --- a/openmp/runtime/src/kmp_affinity.cpp +++ b/openmp/runtime/src/kmp_affinity.cpp @@ -2906,12 +2906,17 @@ static inline const char *__kmp_cpuinfo_get_envvar() { } // Parse /proc/cpuinfo (or an alternate file in the same format) to obtain the -// affinity map. +// affinity map. On AIX, the map is obtained through system SRAD (Scheduler +// Resource Allocation Domain). static bool __kmp_affinity_create_cpuinfo_map(int *line, kmp_i18n_id_t *const msg_id) { + *msg_id = kmp_i18n_null; + +#if KMP_OS_AIX + unsigned num_records = __kmp_xproc; +#else const char *filename = __kmp_cpuinfo_get_filename(); const char *envvar = __kmp_cpuinfo_get_envvar(); - *msg_id = kmp_i18n_null; if (__kmp_affinity.flags.verbose) { KMP_INFORM(AffParseFilename, "KMP_AFFINITY", filename); @@ -2970,6 +2975,7 @@ static bool __kmp_affinity_create_cpuinfo_map(int *line, *msg_id = kmp_i18n_str_CantRewindCpuinfo; return false; } +#endif // KMP_OS_AIX // Allocate the array of records to store the proc info in. The dummy // element at the end makes the logic in filling them out easier to code. @@ -2999,6 +3005,99 @@ static bool __kmp_affinity_create_cpuinfo_map(int *line, INIT_PROC_INFO(threadInfo[i]); } +#if KMP_OS_AIX + int smt_threads; + lpar_info_format1_t cpuinfo; + unsigned num_avail = __kmp_xproc; + + if (__kmp_affinity.flags.verbose) +KMP_INFORM(AffParseFilename, "KMP_AFFINITY", "system info for topology"); + + // Get the number of SMT threads per core. + int retval = + lpar_get_info(LPAR_INFO_FORMAT1, &cpuinfo, sizeof(lpar_info_format1_t)); + if (!retval) +smt_threads = cpuinfo.smt_threads; + else { +CLEANUP_THREAD_INFO; +*msg_id = kmp_i18n_str_UnknownTopology; +return false; + } + + // Allocate a resource set containing available system resourses. + rsethandle_t sys_rset = rs_alloc(RS_SYSTEM); + if (sys_rset == NULL) { +CLEANUP_THREAD_INFO; +*msg_id = kmp_i18n_str_UnknownTopology; +return false; + } + // Allocate a resource set for the SRAD info. + rsethandle_t srad = rs_alloc(RS_EMPTY); + if (srad == NULL) { +rs_free(sys_rset); +CLEANUP_THREAD_INFO; +*msg_id = kmp_i18n_str_UnknownTopology; +return false; + } + + // Get the SRAD system detail level. + int sradsdl = rs_getinfo(NULL, R_SRADSDL, 0); + if (sradsdl < 0) { +rs_free(sys_rset); +r
[llvm-branch-commits] [openmp] release/18x: [OpenMP][AIX] Affinity implementation for AIX (#84984) (PR #86695)
xingxue-ibm wrote: Thanks so much, @shiltian and @brad0! Appreciate it! @kkwli is on vacation and we were discussing the option to build libomp off a downstream branch, which is not ideal. https://github.com/llvm/llvm-project/pull/86695 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Add binary introspection/JIT manager (PR #81346)
aaupov wrote: I split out `createBinaryContext` change into https://github.com/llvm/llvm-project/pull/87172 to facilitate this review. https://github.com/llvm/llvm-project/pull/81346 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Add binary introspection/JIT manager (PR #81346)
@@ -0,0 +1,367 @@ +//===- bolt/Rewrite/JITRewriteInstance.cpp - JIT rewriter -===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// + +#include "bolt/Rewrite/JITRewriteInstance.h" +#include "bolt/Core/BinaryContext.h" +#include "bolt/Core/BinaryEmitter.h" +#include "bolt/Core/BinaryFunction.h" +#include "bolt/Core/JumpTable.h" +#include "bolt/Core/MCPlusBuilder.h" +#include "bolt/Profile/DataAggregator.h" +#include "bolt/Rewrite/BinaryPassManager.h" +#include "bolt/Rewrite/RewriteInstance.h" +#include "bolt/Utils/Utils.h" +#include "llvm/MC/MCAsmLayout.h" +#include "llvm/MC/MCObjectStreamer.h" +#include "llvm/Object/SymbolSize.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/FileSystem.h" +#include + +namespace opts { + +using namespace llvm; +extern cl::opt AlignText; +extern cl::opt PrintSections; +extern cl::opt PrintDisasm; +extern cl::opt PrintCFG; +extern cl::opt Verbosity; +} // namespace opts + +namespace llvm { +namespace bolt { + +#define DEBUG_TYPE "bolt" + +Expected> +JITRewriteInstance::createJITRewriteInstance(JournalingStreams Logger, + bool IsPIC) { + Error Err = Error::success(); + std::unique_ptr JITRI( + new JITRewriteInstance(Logger, IsPIC, Err)); + if (Err) +return std::move(Err); + return std::move(JITRI); +} + +JITRewriteInstance::JITRewriteInstance(JournalingStreams Logger, bool IsPIC, + Error &Err) +: StrPool(StrAllocator) { + ErrorAsOutParameter EAO(&Err); + Triple TheTriple(sys::getDefaultTargetTriple().c_str()); + + auto BCOrErr = BinaryContext::createBinaryContext( + TheTriple, StringRef("JIT input file"), nullptr, IsPIC, nullptr, Logger); + if (Error E = BCOrErr.takeError()) { +Err = std::move(E); +return; + } + BC = std::move(BCOrErr.get()); + BC->initializeTarget(std::unique_ptr( + createMCPlusBuilder(BC->TheTriple->getArch(), BC->MIA.get(), + BC->MII.get(), BC->MRI.get(), BC->STI.get(; + BC->FirstAllocAddress = 0; + BC->LayoutStartAddress = 0x; +} + +JITRewriteInstance::~JITRewriteInstance() {} + +void JITRewriteInstance::adjustCommandLineOptions() { + if (!opts::AlignText.getNumOccurrences()) +opts::AlignText = BC->PageAlign; +} + +Error JITRewriteInstance::preprocessProfileData() { + if (!ProfileReader) +return Error::success(); + if (Error E = ProfileReader->preprocessProfile(*BC.get())) +return Error(std::move(E)); + return Error::success(); +} + +Error JITRewriteInstance::processProfileDataPreCFG() { + if (!ProfileReader) +return Error::success(); + if (Error E = ProfileReader->readProfilePreCFG(*BC.get())) +return Error(std::move(E)); + return Error::success(); +} + +Error JITRewriteInstance::processProfileData() { + if (!ProfileReader) +return Error::success(); + if (Error E = ProfileReader->readProfile(*BC.get())) +return Error(std::move(E)); + return Error::success(); +} + +Error JITRewriteInstance::disassembleFunctions() { aaupov wrote: I believe that this and other functions are common across *RewriteInstance classes. Is it worth defining a BaseRewriteInstance class and providing them there? https://github.com/llvm/llvm-project/pull/81346 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] [BOLT] Add binary introspection/JIT manager (PR #81346)
https://github.com/aaupov edited https://github.com/llvm/llvm-project/pull/81346 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits