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
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
;
27 expected_total
= nsockets
;
28 expected_per_place
= ncores_per_socket
* nthreads_per_core
;
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
);
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
);
48 static int check_places() {
50 topology_obj_type_t type
;
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");
63 value
= getenv("OMP_PLACES");
66 "error: OMP_PLACES must be set to one of threads,cores,sockets!\n");
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
;
77 "error: OMP_PLACES must be one of threads,cores,sockets!\n");
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
);
85 } else if (sockets
->num_places
<= 0) {
86 printf("Invalid number of sockets (%d). Skipping test.\n",
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");
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;
107 if (getenv("RUN_OUT_OF_ORDER")) {
108 snprintf(buf
, sizeof(buf
), "%dt,%ds,%dc", nthreads_per_core
, nsockets
,
111 snprintf(buf
, sizeof(buf
), "%ds,%dc,%dt", nsockets
, ncores_per_socket
,
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
);
127 if (!topology_using_full_mask()) {
128 printf("Thread does not have access to all logical processors. Skipping "
132 return check_places();