[llvm] Stop including unordered_map (NFC)
[llvm-project.git] / openmp / runtime / test / affinity / kmp-hw-subset.c
blob606fcdfbada95a3a4f596bd120b8581e2d6e81ca
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
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include "libomp_test_affinity.h"
12 #include "libomp_test_topology.h"
14 // Check openmp place list to make sure it follow KMP_HW_SUBSET restriction
15 static 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;
20 if (type == TOPOLOGY_OBJ_THREAD) {
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;
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;
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;
45 return EXIT_SUCCESS;
48 static int check_places() {
49 char buf[100];
50 topology_obj_type_t type;
51 const char *value;
52 int status = EXIT_SUCCESS;
53 place_list_t *threads, *cores, *sockets, *openmp_places;
54 threads = topology_alloc_type_places(TOPOLOGY_OBJ_THREAD);
55 cores = topology_alloc_type_places(TOPOLOGY_OBJ_CORE);
56 sockets = topology_alloc_type_places(TOPOLOGY_OBJ_SOCKET);
58 if (threads->num_places <= 1) {
59 printf("Only one hardware thread to execute on. Skipping test.\n");
60 return status;
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;
69 if (strcmp(value, "threads") == 0)
70 type = TOPOLOGY_OBJ_THREAD;
71 else if (strcmp(value, "cores") == 0)
72 type = TOPOLOGY_OBJ_CORE;
73 else if (strcmp(value, "sockets") == 0)
74 type = TOPOLOGY_OBJ_SOCKET;
75 else {
76 fprintf(stderr,
77 "error: OMP_PLACES must be one of threads,cores,sockets!\n");
78 return EXIT_FAILURE;
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;
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;
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;
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;
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);
114 setenv("KMP_HW_SUBSET", buf, 1);
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);
120 topology_free_places(cores);
121 topology_free_places(sockets);
122 topology_free_places(openmp_places);
123 return status;
126 int main() {
127 if (!topology_using_full_mask()) {
128 printf("Thread does not have access to all logical processors. Skipping "
129 "test.\n");
130 return EXIT_SUCCESS;
132 return check_places();