Commit fe3b244e authored by Peyton, Jonathan L's avatar Peyton, Jonathan L
Browse files

[OpenMP] Fix norespect affinity bug for Windows

KMP_AFFINITY=norespect was triggering an error because the underlying
process affinity mask was not updated to include the entire machine.
The Windows documentation states that the thread affinities must be
subsets of the process affinity. This patch also moves the printing
(for KMP_AFFINITY=verbose) of whether the initial mask was respected
out of each topology detection function and to one location where the
initial affinity mask is read.

Differential Revision: https://reviews.llvm.org/D92587
parent 9b7d6a6b
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -694,6 +694,9 @@ public:
    virtual int begin() const { return 0; }
    virtual int end() const { return 0; }
    virtual int next(int previous) const { return 0; }
#if KMP_OS_WINDOWS
    virtual int set_process_affinity(bool abort_on_error) const { return -1; }
#endif
    // Set the system's affinity to this affinity mask's value
    virtual int set_system_affinity(bool abort_on_error) const { return -1; }
    // Set this affinity mask to the current system affinity
+19 −82
Original line number Diff line number Diff line
@@ -729,15 +729,7 @@ static int __kmp_affinity_create_hwloc_map(AddrUnsPair **address2os,
    __kmp_ncores = nPackages = 1;
    __kmp_nThreadsPerCore = nCoresPerPkg = 1;
    if (__kmp_affinity_verbose) {
      char buf[KMP_AFFIN_MASK_PRINT_LEN];
      __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN, oldMask);

      KMP_INFORM(AffUsingHwloc, "KMP_AFFINITY");
      if (__kmp_affinity_respect_mask) {
        KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
      } else {
        KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
      }
      KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
      KMP_INFORM(Uniform, "KMP_AFFINITY");
      KMP_INFORM(Topology, "KMP_AFFINITY", nPackages, nCoresPerPkg,
@@ -791,13 +783,6 @@ static int __kmp_affinity_create_hwloc_map(AddrUnsPair **address2os,

  // Print the machine topology summary.
  if (__kmp_affinity_verbose) {
    char mask[KMP_AFFIN_MASK_PRINT_LEN];
    __kmp_affinity_print_mask(mask, KMP_AFFIN_MASK_PRINT_LEN, oldMask);
    if (__kmp_affinity_respect_mask) {
      KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", mask);
    } else {
      KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", mask);
    }
    KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
    if (uniform) {
      KMP_INFORM(Uniform, "KMP_AFFINITY");
@@ -898,16 +883,7 @@ static int __kmp_affinity_create_flat_map(AddrUnsPair **address2os,
  __kmp_ncores = nPackages = __kmp_avail_proc;
  __kmp_nThreadsPerCore = nCoresPerPkg = 1;
  if (__kmp_affinity_verbose) {
    char buf[KMP_AFFIN_MASK_PRINT_LEN];
    __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN,
                              __kmp_affin_fullMask);

    KMP_INFORM(AffCapableUseFlat, "KMP_AFFINITY");
    if (__kmp_affinity_respect_mask) {
      KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
    } else {
      KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
    }
    KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
    KMP_INFORM(Uniform, "KMP_AFFINITY");
    KMP_INFORM(Topology, "KMP_AFFINITY", nPackages, nCoresPerPkg,
@@ -1273,15 +1249,7 @@ static int __kmp_affinity_create_apicid_map(AddrUnsPair **address2os,
    __kmp_ncores = nPackages = 1;
    __kmp_nThreadsPerCore = nCoresPerPkg = 1;
    if (__kmp_affinity_verbose) {
      char buf[KMP_AFFIN_MASK_PRINT_LEN];
      __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN, oldMask);

      KMP_INFORM(AffUseGlobCpuid, "KMP_AFFINITY");
      if (__kmp_affinity_respect_mask) {
        KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
      } else {
        KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
      }
      KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
      KMP_INFORM(Uniform, "KMP_AFFINITY");
      KMP_INFORM(Topology, "KMP_AFFINITY", nPackages, nCoresPerPkg,
@@ -1406,15 +1374,7 @@ static int __kmp_affinity_create_apicid_map(AddrUnsPair **address2os,
  // not enabled.
  __kmp_ncores = nCores;
  if (__kmp_affinity_verbose) {
    char buf[KMP_AFFIN_MASK_PRINT_LEN];
    __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN, oldMask);

    KMP_INFORM(AffUseGlobCpuid, "KMP_AFFINITY");
    if (__kmp_affinity_respect_mask) {
      KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
    } else {
      KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
    }
    KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
    if (__kmp_affinity_uniform_topology()) {
      KMP_INFORM(Uniform, "KMP_AFFINITY");
@@ -1689,15 +1649,7 @@ static int __kmp_affinity_create_x2apicid_map(AddrUnsPair **address2os,
    __kmp_ncores = nPackages = 1;
    __kmp_nThreadsPerCore = nCoresPerPkg = 1;
    if (__kmp_affinity_verbose) {
      char buf[KMP_AFFIN_MASK_PRINT_LEN];
      __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN, oldMask);

      KMP_INFORM(AffUseGlobCpuidL11, "KMP_AFFINITY");
      if (__kmp_affinity_respect_mask) {
        KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
      } else {
        KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
      }
      KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
      KMP_INFORM(Uniform, "KMP_AFFINITY");
      KMP_INFORM(Topology, "KMP_AFFINITY", nPackages, nCoresPerPkg,
@@ -1813,15 +1765,7 @@ static int __kmp_affinity_create_x2apicid_map(AddrUnsPair **address2os,

  // Print the machine topology summary.
  if (__kmp_affinity_verbose) {
    char mask[KMP_AFFIN_MASK_PRINT_LEN];
    __kmp_affinity_print_mask(mask, KMP_AFFIN_MASK_PRINT_LEN, oldMask);

    KMP_INFORM(AffUseGlobCpuidL11, "KMP_AFFINITY");
    if (__kmp_affinity_respect_mask) {
      KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", mask);
    } else {
      KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", mask);
    }
    KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
    if (uniform) {
      KMP_INFORM(Uniform, "KMP_AFFINITY");
@@ -2332,15 +2276,7 @@ static int __kmp_affinity_create_cpuinfo_map(AddrUnsPair **address2os,
        KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
        KMP_INFORM(Uniform, "KMP_AFFINITY");
      } else {
        char buf[KMP_AFFIN_MASK_PRINT_LEN];
        __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN,
                                  __kmp_affin_fullMask);
        KMP_INFORM(AffCapableUseCpuinfo, "KMP_AFFINITY");
        if (__kmp_affinity_respect_mask) {
          KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
        } else {
          KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
        }
        KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
        KMP_INFORM(Uniform, "KMP_AFFINITY");
      }
@@ -2541,15 +2477,7 @@ restart_radix_check:
        KMP_INFORM(NonUniform, "KMP_AFFINITY");
      }
    } else {
      char buf[KMP_AFFIN_MASK_PRINT_LEN];
      __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN,
                                __kmp_affin_fullMask);
      KMP_INFORM(AffCapableUseCpuinfo, "KMP_AFFINITY");
      if (__kmp_affinity_respect_mask) {
        KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
      } else {
        KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
      }
      KMP_INFORM(AvailableOSProc, "KMP_AFFINITY", __kmp_avail_proc);
      if (uniform) {
        KMP_INFORM(Uniform, "KMP_AFFINITY");
@@ -3987,14 +3915,6 @@ static void __kmp_apply_thread_places(AddrUnsPair **pAddr, int depth) {
    *pAddr = newAddr; // replace old topology with new one
  }
  if (__kmp_affinity_verbose) {
    char m[KMP_AFFIN_MASK_PRINT_LEN];
    __kmp_affinity_print_mask(m, KMP_AFFIN_MASK_PRINT_LEN,
                              __kmp_affin_fullMask);
    if (__kmp_affinity_respect_mask) {
      KMP_INFORM(InitOSProcSetRespect, "KMP_HW_SUBSET", m);
    } else {
      KMP_INFORM(InitOSProcSetNotRespect, "KMP_HW_SUBSET", m);
    }
    KMP_INFORM(AvailableOSProc, "KMP_HW_SUBSET", __kmp_avail_proc);
    kmp_str_buf_t buf;
    __kmp_str_buf_init(&buf);
@@ -4156,9 +4076,8 @@ static void __kmp_aux_affinity_initialize(void) {
    KMP_CPU_ALLOC(__kmp_affin_fullMask);
  }
  if (KMP_AFFINITY_CAPABLE()) {
    if (__kmp_affinity_respect_mask) {
    __kmp_get_system_affinity(__kmp_affin_fullMask, TRUE);

    if (__kmp_affinity_respect_mask) {
      // Count the number of available processors.
      unsigned i;
      __kmp_avail_proc = 0;
@@ -4178,9 +4097,27 @@ static void __kmp_aux_affinity_initialize(void) {
        KMP_AFFINITY_DISABLE();
        return;
      }

      if (__kmp_affinity_verbose) {
        char buf[KMP_AFFIN_MASK_PRINT_LEN];
        __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN,
                                  __kmp_affin_fullMask);
        KMP_INFORM(InitOSProcSetRespect, "KMP_AFFINITY", buf);
      }
    } else {
      if (__kmp_affinity_verbose) {
        char buf[KMP_AFFIN_MASK_PRINT_LEN];
        __kmp_affinity_print_mask(buf, KMP_AFFIN_MASK_PRINT_LEN,
                                  __kmp_affin_fullMask);
        KMP_INFORM(InitOSProcSetNotRespect, "KMP_AFFINITY", buf);
      }
      __kmp_affinity_entire_machine_mask(__kmp_affin_fullMask);
      __kmp_avail_proc = __kmp_xproc;
#if KMP_OS_WINDOWS
      // Set the process affinity mask since threads' affinity
      // masks must be subset of process mask in Windows* OS
      __kmp_affin_fullMask->set_process_affinity(true);
#endif
    }
  }

+35 −2
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public:
    }
    int set_system_affinity(bool abort_on_error) const override {
      KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
                  "Illegal get affinity operation when not capable");
                  "Illegal set affinity operation when not capable");
      int retval =
          hwloc_set_cpubind(__kmp_hwloc_topology, mask, HWLOC_CPUBIND_THREAD);
      if (retval >= 0) {
@@ -79,6 +79,26 @@ public:
      }
      return error;
    }
#if KMP_OS_WINDOWS
    int set_process_affinity(bool abort_on_error) const override {
      KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
                  "Illegal set process affinity operation when not capable");
      int error = 0;
      const hwloc_topology_support *support =
          hwloc_topology_get_support(__kmp_hwloc_topology);
      if (support->cpubind->set_proc_cpubind) {
        int retval;
        retval = hwloc_set_cpubind(__kmp_hwloc_topology, mask,
                                   HWLOC_CPUBIND_PROCESS);
        if (retval >= 0)
          return 0;
        error = errno;
        if (abort_on_error)
          __kmp_fatal(KMP_MSG(FatalSysError), KMP_ERR(error), __kmp_msg_null);
      }
      return error;
    }
#endif
    int get_proc_group() const override {
      int group = -1;
#if KMP_OS_WINDOWS
@@ -318,7 +338,7 @@ class KMPNativeAffinity : public KMPAffinity {
    }
    int set_system_affinity(bool abort_on_error) const override {
      KMP_ASSERT2(KMP_AFFINITY_CAPABLE(),
                  "Illegal get affinity operation when not capable");
                  "Illegal set affinity operation when not capable");
#if KMP_OS_LINUX
      int retval =
          syscall(__NR_sched_setaffinity, 0, __kmp_affin_mask_size, mask);
@@ -426,6 +446,19 @@ class KMPNativeAffinity : public KMPAffinity {
        ++retval;
      return retval;
    }
    int set_process_affinity(bool abort_on_error) const override {
      if (__kmp_num_proc_groups <= 1) {
        if (!SetProcessAffinityMask(GetCurrentProcess(), *mask)) {
          DWORD error = GetLastError();
          if (abort_on_error) {
            __kmp_fatal(KMP_MSG(CantSetThreadAffMask), KMP_ERR(error),
                        __kmp_msg_null);
          }
          return error;
        }
      }
      return 0;
    }
    int set_system_affinity(bool abort_on_error) const override {
      if (__kmp_num_proc_groups > 1) {
        // Check for a valid mask.