@@ -2910,12 +2910,17 @@ static inline const char *__kmp_cpuinfo_get_envvar() {
2910
2910
}
2911
2911
2912
2912
// Parse /proc/cpuinfo (or an alternate file in the same format) to obtain the
2913
- // affinity map.
2913
+ // affinity map. On AIX, the map is obtained through system SRAD (Scheduler
2914
+ // Resource Allocation Domain).
2914
2915
static bool __kmp_affinity_create_cpuinfo_map (int *line,
2915
2916
kmp_i18n_id_t *const msg_id) {
2917
+ *msg_id = kmp_i18n_null;
2918
+
2919
+ #if KMP_OS_AIX
2920
+ unsigned num_records = __kmp_xproc;
2921
+ #else
2916
2922
const char *filename = __kmp_cpuinfo_get_filename ();
2917
2923
const char *envvar = __kmp_cpuinfo_get_envvar ();
2918
- *msg_id = kmp_i18n_null;
2919
2924
2920
2925
if (__kmp_affinity.flags .verbose ) {
2921
2926
KMP_INFORM (AffParseFilename, " KMP_AFFINITY" , filename);
@@ -2974,6 +2979,7 @@ static bool __kmp_affinity_create_cpuinfo_map(int *line,
2974
2979
*msg_id = kmp_i18n_str_CantRewindCpuinfo;
2975
2980
return false ;
2976
2981
}
2982
+ #endif // KMP_OS_AIX
2977
2983
2978
2984
// Allocate the array of records to store the proc info in. The dummy
2979
2985
// element at the end makes the logic in filling them out easier to code.
@@ -3003,6 +3009,99 @@ static bool __kmp_affinity_create_cpuinfo_map(int *line,
3003
3009
INIT_PROC_INFO (threadInfo[i]);
3004
3010
}
3005
3011
3012
+ #if KMP_OS_AIX
3013
+ int smt_threads;
3014
+ lpar_info_format1_t cpuinfo;
3015
+ unsigned num_avail = __kmp_xproc;
3016
+
3017
+ if (__kmp_affinity.flags .verbose )
3018
+ KMP_INFORM (AffParseFilename, " KMP_AFFINITY" , " system info for topology" );
3019
+
3020
+ // Get the number of SMT threads per core.
3021
+ int retval =
3022
+ lpar_get_info (LPAR_INFO_FORMAT1, &cpuinfo, sizeof (lpar_info_format1_t ));
3023
+ if (!retval)
3024
+ smt_threads = cpuinfo.smt_threads ;
3025
+ else {
3026
+ CLEANUP_THREAD_INFO;
3027
+ *msg_id = kmp_i18n_str_UnknownTopology;
3028
+ return false ;
3029
+ }
3030
+
3031
+ // Allocate a resource set containing available system resourses.
3032
+ rsethandle_t sys_rset = rs_alloc (RS_SYSTEM);
3033
+ if (sys_rset == NULL ) {
3034
+ CLEANUP_THREAD_INFO;
3035
+ *msg_id = kmp_i18n_str_UnknownTopology;
3036
+ return false ;
3037
+ }
3038
+ // Allocate a resource set for the SRAD info.
3039
+ rsethandle_t srad = rs_alloc (RS_EMPTY);
3040
+ if (srad == NULL ) {
3041
+ rs_free (sys_rset);
3042
+ CLEANUP_THREAD_INFO;
3043
+ *msg_id = kmp_i18n_str_UnknownTopology;
3044
+ return false ;
3045
+ }
3046
+
3047
+ // Get the SRAD system detail level.
3048
+ int sradsdl = rs_getinfo (NULL , R_SRADSDL, 0 );
3049
+ if (sradsdl < 0 ) {
3050
+ rs_free (sys_rset);
3051
+ rs_free (srad);
3052
+ CLEANUP_THREAD_INFO;
3053
+ *msg_id = kmp_i18n_str_UnknownTopology;
3054
+ return false ;
3055
+ }
3056
+ // Get the number of RADs at that SRAD SDL.
3057
+ int num_rads = rs_numrads (sys_rset, sradsdl, 0 );
3058
+ if (num_rads < 0 ) {
3059
+ rs_free (sys_rset);
3060
+ rs_free (srad);
3061
+ CLEANUP_THREAD_INFO;
3062
+ *msg_id = kmp_i18n_str_UnknownTopology;
3063
+ return false ;
3064
+ }
3065
+
3066
+ // Get the maximum number of procs that may be contained in a resource set.
3067
+ int max_procs = rs_getinfo (NULL , R_MAXPROCS, 0 );
3068
+ if (max_procs < 0 ) {
3069
+ rs_free (sys_rset);
3070
+ rs_free (srad);
3071
+ CLEANUP_THREAD_INFO;
3072
+ *msg_id = kmp_i18n_str_UnknownTopology;
3073
+ return false ;
3074
+ }
3075
+
3076
+ int cur_rad = 0 ;
3077
+ int num_set = 0 ;
3078
+ for (int srad_idx = 0 ; cur_rad < num_rads && srad_idx < VMI_MAXRADS;
3079
+ ++srad_idx) {
3080
+ // Check if the SRAD is available in the RSET.
3081
+ if (rs_getrad (sys_rset, srad, sradsdl, srad_idx, 0 ) < 0 )
3082
+ continue ;
3083
+
3084
+ for (int cpu = 0 ; cpu < max_procs; cpu++) {
3085
+ // Set the info for the cpu if it is in the SRAD.
3086
+ if (rs_op (RS_TESTRESOURCE, srad, NULL , R_PROCS, cpu)) {
3087
+ threadInfo[cpu][osIdIndex] = cpu;
3088
+ threadInfo[cpu][pkgIdIndex] = cur_rad;
3089
+ threadInfo[cpu][coreIdIndex] = cpu / smt_threads;
3090
+ ++num_set;
3091
+ if (num_set >= num_avail) {
3092
+ // Done if all available CPUs have been set.
3093
+ break ;
3094
+ }
3095
+ }
3096
+ }
3097
+ ++cur_rad;
3098
+ }
3099
+ rs_free (sys_rset);
3100
+ rs_free (srad);
3101
+
3102
+ // The topology is already sorted.
3103
+
3104
+ #else // !KMP_OS_AIX
3006
3105
unsigned num_avail = 0 ;
3007
3106
*line = 0 ;
3008
3107
#if KMP_ARCH_S390X
@@ -3250,6 +3349,8 @@ static bool __kmp_affinity_create_cpuinfo_map(int *line,
3250
3349
qsort (threadInfo, num_avail, sizeof (*threadInfo),
3251
3350
__kmp_affinity_cmp_ProcCpuInfo_phys_id);
3252
3351
3352
+ #endif // KMP_OS_AIX
3353
+
3253
3354
// The table is now sorted by pkgId / coreId / threadId, but we really don't
3254
3355
// know the radix of any of the fields. pkgId's may be sparsely assigned among
3255
3356
// the chips on a system. Although coreId's are usually assigned
@@ -4445,7 +4546,7 @@ static bool __kmp_aux_affinity_initialize_topology(kmp_affinity_t &affinity) {
4445
4546
}
4446
4547
#endif /* KMP_ARCH_X86 || KMP_ARCH_X86_64 */
4447
4548
4448
- #if KMP_OS_LINUX
4549
+ #if KMP_OS_LINUX || KMP_OS_AIX
4449
4550
if (!success) {
4450
4551
int line = 0 ;
4451
4552
success = __kmp_affinity_create_cpuinfo_map (&line, &msg_id);
@@ -4841,7 +4942,12 @@ void __kmp_affinity_uninitialize(void) {
4841
4942
}
4842
4943
if (__kmp_affin_origMask != NULL ) {
4843
4944
if (KMP_AFFINITY_CAPABLE ()) {
4945
+ #if KMP_OS_AIX
4946
+ // Uninitialize by unbinding the thread.
4947
+ bindprocessor (BINDTHREAD, thread_self (), PROCESSOR_CLASS_ANY);
4948
+ #else
4844
4949
__kmp_set_system_affinity (__kmp_affin_origMask, FALSE );
4950
+ #endif
4845
4951
}
4846
4952
KMP_CPU_FREE (__kmp_affin_origMask);
4847
4953
__kmp_affin_origMask = NULL ;
@@ -5015,7 +5121,10 @@ void __kmp_affinity_bind_init_mask(int gtid) {
5015
5121
__kmp_set_system_affinity (th->th .th_affin_mask , FALSE );
5016
5122
} else
5017
5123
#endif
5124
+ #ifndef KMP_OS_AIX
5125
+ // Do not set the full mask as the init mask on AIX.
5018
5126
__kmp_set_system_affinity (th->th .th_affin_mask , TRUE );
5127
+ #endif
5019
5128
}
5020
5129
5021
5130
void __kmp_affinity_bind_place (int gtid) {
@@ -5128,15 +5237,15 @@ int __kmp_aux_set_affinity(void **mask) {
5128
5237
int __kmp_aux_get_affinity (void **mask) {
5129
5238
int gtid;
5130
5239
int retval;
5131
- #if KMP_OS_WINDOWS || KMP_DEBUG
5240
+ #if KMP_OS_WINDOWS || KMP_OS_AIX || KMP_DEBUG
5132
5241
kmp_info_t *th;
5133
5242
#endif
5134
5243
if (!KMP_AFFINITY_CAPABLE ()) {
5135
5244
return -1 ;
5136
5245
}
5137
5246
5138
5247
gtid = __kmp_entry_gtid ();
5139
- #if KMP_OS_WINDOWS || KMP_DEBUG
5248
+ #if KMP_OS_WINDOWS || KMP_OS_AIX || KMP_DEBUG
5140
5249
th = __kmp_threads[gtid];
5141
5250
#else
5142
5251
(void )gtid; // unused variable
@@ -5159,7 +5268,7 @@ int __kmp_aux_get_affinity(void **mask) {
5159
5268
}
5160
5269
}
5161
5270
5162
- #if !KMP_OS_WINDOWS
5271
+ #if !KMP_OS_WINDOWS && !KMP_OS_AIX
5163
5272
5164
5273
retval = __kmp_get_system_affinity ((kmp_affin_mask_t *)(*mask), FALSE );
5165
5274
KA_TRACE (
@@ -5179,7 +5288,7 @@ int __kmp_aux_get_affinity(void **mask) {
5179
5288
KMP_CPU_COPY ((kmp_affin_mask_t *)(*mask), th->th .th_affin_mask );
5180
5289
return 0 ;
5181
5290
5182
- #endif /* KMP_OS_WINDOWS */
5291
+ #endif /* ! KMP_OS_WINDOWS && !KMP_OS_AIX */
5183
5292
}
5184
5293
5185
5294
int __kmp_aux_get_affinity_max_proc () {
@@ -5561,7 +5670,8 @@ void __kmp_balanced_affinity(kmp_info_t *th, int nthreads) {
5561
5670
}
5562
5671
}
5563
5672
5564
- #if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD || KMP_OS_DRAGONFLY
5673
+ #if KMP_OS_LINUX || KMP_OS_FREEBSD || KMP_OS_NETBSD || KMP_OS_DRAGONFLY || \
5674
+ KMP_OS_AIX
5565
5675
// We don't need this entry for Windows because
5566
5676
// there is GetProcessAffinityMask() api
5567
5677
//
@@ -5596,7 +5706,11 @@ extern "C"
5596
5706
" set full mask for thread %d\n " ,
5597
5707
gtid));
5598
5708
KMP_DEBUG_ASSERT (__kmp_affin_fullMask != NULL );
5709
+ #if KMP_OS_AIX
5710
+ return bindprocessor (BINDTHREAD, thread_self (), PROCESSOR_CLASS_ANY);
5711
+ #else
5599
5712
return __kmp_set_system_affinity (__kmp_affin_fullMask, FALSE );
5713
+ #endif
5600
5714
}
5601
5715
#endif
5602
5716
0 commit comments