LLVM OpenMP 19.0.0git
kmp-hw-subset.c
Go to the documentation of this file.
1// RUN: %libomp-compile -D_GNU_SOURCE
2// RUN: env OMP_PLACES=threads %libomp-run
3// RUN: env OMP_PLACES=cores %libomp-run
4// RUN: env OMP_PLACES=sockets %libomp-run
5// RUN: env OMP_PLACES=cores RUN_OUT_OF_ORDER=1 %libomp-run
6// REQUIRES: linux
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
13
14// Check openmp place list to make sure it follow KMP_HW_SUBSET restriction
15static int compare_hw_subset_places(const place_list_t *openmp_places,
16 topology_obj_type_t type, int nsockets,
17 int ncores_per_socket,
18 int nthreads_per_core) {
19 int i, j, expected_total, expected_per_place;
21 expected_total = nsockets * ncores_per_socket * nthreads_per_core;
22 expected_per_place = 1;
23 } else if (type == TOPOLOGY_OBJ_CORE) {
24 expected_total = nsockets * ncores_per_socket;
25 expected_per_place = nthreads_per_core;
26 } else {
27 expected_total = nsockets;
28 expected_per_place = ncores_per_socket;
29 }
30 if (openmp_places->num_places != expected_total) {
31 fprintf(stderr, "error: KMP_HW_SUBSET did not half each resource layer!\n");
32 printf("openmp_places places:\n");
33 topology_print_places(openmp_places);
34 printf("\n");
35 return EXIT_FAILURE;
36 }
37 for (i = 0; i < openmp_places->num_places; ++i) {
38 int count = affinity_mask_count(openmp_places->masks[i]);
39 if (count != expected_per_place) {
40 fprintf(stderr, "error: place %d has %d OS procs instead of %d\n", i,
41 count, expected_per_place);
42 return EXIT_FAILURE;
43 }
44 }
45 return EXIT_SUCCESS;
46}
47
48static int check_places() {
49 char buf[100];
51 const char *value;
52 int status = EXIT_SUCCESS;
53 place_list_t *threads, *cores, *sockets, *openmp_places;
57
58 if (threads->num_places <= 1) {
59 printf("Only one hardware thread to execute on. Skipping test.\n");
60 return status;
61 }
62
63 value = getenv("OMP_PLACES");
64 if (!value) {
65 fprintf(stderr,
66 "error: OMP_PLACES must be set to one of threads,cores,sockets!\n");
67 return EXIT_FAILURE;
68 }
69 if (strcmp(value, "threads") == 0)
71 else if (strcmp(value, "cores") == 0)
73 else if (strcmp(value, "sockets") == 0)
75 else {
76 fprintf(stderr,
77 "error: OMP_PLACES must be one of threads,cores,sockets!\n");
78 return EXIT_FAILURE;
79 }
80
81 // Calculate of num threads per core, num cores per socket, & num sockets
82 if (cores->num_places <= 0) {
83 printf("Invalid number of cores (%d). Skipping test.\n", cores->num_places);
84 return status;
85 } else if (sockets->num_places <= 0) {
86 printf("Invalid number of sockets (%d). Skipping test.\n",
87 cores->num_places);
88 return status;
89 }
90 int nthreads_per_core = threads->num_places / cores->num_places;
91 int ncores_per_socket = cores->num_places / sockets->num_places;
92 int nsockets = sockets->num_places;
93
94 if (nsockets * ncores_per_socket * nthreads_per_core != threads->num_places) {
95 printf("Only uniform topologies can be tested. Skipping test.\n");
96 return status;
97 }
98
99 // Use half the resources of every level
100 if (nthreads_per_core > 1)
101 nthreads_per_core /= 2;
102 if (ncores_per_socket > 1)
103 ncores_per_socket /= 2;
104 if (nsockets > 1)
105 nsockets /= 2;
106
107 if (getenv("RUN_OUT_OF_ORDER")) {
108 snprintf(buf, sizeof(buf), "%dt,%ds,%dc", nthreads_per_core, nsockets,
109 ncores_per_socket);
110 } else {
111 snprintf(buf, sizeof(buf), "%ds,%dc,%dt", nsockets, ncores_per_socket,
112 nthreads_per_core);
113 }
114 setenv("KMP_HW_SUBSET", buf, 1);
115
116 openmp_places = topology_alloc_openmp_places();
117 status = compare_hw_subset_places(openmp_places, type, nsockets,
118 ncores_per_socket, nthreads_per_core);
119 topology_free_places(threads);
121 topology_free_places(sockets);
122 topology_free_places(openmp_places);
123 return status;
124}
125
126int main() {
128 printf("Thread does not have access to all logical processors. Skipping "
129 "test.\n");
130 return EXIT_SUCCESS;
131 }
132 return check_places();
133}
char buf[BUFFER_SIZE]
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t count
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long value
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain __itt_id ITT_FORMAT p const __itt_domain __itt_id __itt_timestamp __itt_timestamp ITT_FORMAT lu const __itt_domain __itt_id __itt_id __itt_string_handle ITT_FORMAT p const __itt_domain ITT_FORMAT p const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_string_handle unsigned long long ITT_FORMAT lu const __itt_domain __itt_id __itt_string_handle __itt_metadata_type type
static int compare_hw_subset_places(const place_list_t *openmp_places, topology_obj_type_t type, int nsockets, int ncores_per_socket, int nthreads_per_core)
Definition: kmp-hw-subset.c:15
static int check_places()
Definition: kmp-hw-subset.c:48
int main()
static volatile kmp_i18n_cat_status_t status
Definition: kmp_i18n.cpp:48
#define i
Definition: kmp_stub.cpp:87
static int affinity_mask_count(const affinity_mask_t *mask)
static void topology_print_places(const place_list_t *p)
topology_obj_type_t
@ TOPOLOGY_OBJ_CORE
@ TOPOLOGY_OBJ_THREAD
@ TOPOLOGY_OBJ_SOCKET
static place_list_t * topology_alloc_openmp_places()
static place_list_t * topology_alloc_type_places(topology_obj_type_t type)
static int topology_using_full_mask()
static void topology_free_places(place_list_t *places)
affinity_mask_t ** masks