134 lines · c
1// RUN: %libomp-compile -D_GNU_SOURCE2// RUN: env OMP_PLACES=threads %libomp-run3// RUN: env OMP_PLACES=cores %libomp-run4// RUN: env OMP_PLACES=sockets %libomp-run5// RUN: env OMP_PLACES=cores RUN_OUT_OF_ORDER=1 %libomp-run6// REQUIRES: linux7 8#include <stdio.h>9#include <stdlib.h>10#include <string.h>11#include "libomp_test_affinity.h"12#include "libomp_test_topology.h"13 14// Check openmp place list to make sure it follow KMP_HW_SUBSET restriction15static 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 * nthreads_per_core;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];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);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)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;79 }80 81 // Calculate of num threads per core, num cores per socket, & num sockets82 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 level100 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);120 topology_free_places(cores);121 topology_free_places(sockets);122 topology_free_places(openmp_places);123 return status;124}125 126int 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;131 }132 return check_places();133}134