Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /trunk/src/lib/parallel-target/cpu.c
ViewVC logotype

View of /trunk/src/lib/parallel-target/cpu.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1301 - (download) (as text) (annotate)
Thu Jun 9 23:58:40 2011 UTC (8 years, 1 month ago) by jhr
File size: 3457 byte(s)
  Added support for hest-based command-line arguments to trunk.  Also switched
  output filename to prog.txt (from mip.txt)
/*! \file cpu.c
 *
 * \author John Reppy
 */

/*
 * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
 * All rights reserved.
 */

#include "Diderot/diderot.h"
#if defined (__APPLE__)
#  include <sys/sysctl.h>
#endif
#ifdef HAVE_LIBNUMA
#  include <numa.h>
#endif
#include <errno.h>

/*! \brief determine the number of CPUs */
bool GetNumCPUs (CPUInfo_t *info)
{
#if defined(HAVE__PROC_CPUINFO)
  /* Get information from /proc/cpuinfo.  The interesting
   * fields are:
   *
   *    processor       : <id>          # logical processor id
   *    physical id     : <id>          # node id
   *    core id         : <id>          # core id (per node)
   *    cpu cores       : <n>           # number of cores per node
   */
    FILE *cpuinfo = fopen("/proc/cpuinfo", "r");
    char buf[1024];
    if (cpuinfo != NULL) {
        int maxProcId = 0, maxNodeId = 0, maxCoreId = 0, nCores = 0;
        while (fgets(buf, sizeof(buf), cpuinfo) != 0) {
            int tmp;
            if (sscanf(buf, "processor : %d", &tmp) == 1) {
                maxProcId = (tmp > maxProcId) ? tmp : maxProcId;
            }
            else if (sscanf(buf, "physical id : %d", &tmp) == 1) {
                maxNodeId = (tmp > maxNodeId) ? tmp : maxNodeId;
            }
            else if (sscanf(buf, "core id : %d", &tmp) == 1) {
                maxCoreId = (tmp > maxCoreId) ? tmp : maxCoreId;
            }
            else if (sscanf(buf, "cpu cores : %d", &tmp) == 1) {
                nCores = (tmp > nCores) ? tmp : nCores;
            }
        }
        fclose (cpuinfo);

#ifdef HAVE_LIBNUMA
        info->numHWThreads = info->numHWCores = maxProcId + 1;
        info->numHWNodes  = numa_max_node()+1;
        info->numThdsPerCore = 1;
        info->numCoresPerNode = info->numHWThreads / info->numHWNodes;
#else
        info->numHWNodes = maxNodeId + 1;
        info->numHWCores = info->numHWNodes * nCores;
        info->numHWThreads = maxProcId + 1;
        info->numCoresPerNode = nCores;
        info->numThdsPerCore = info->numHWThreads / info->numHWCores;
#endif

        return true;
    }
    else {
        fprintf(stderr, "unable to determine the number of processors\n");
        return false;
    }
#elif defined(__APPLE__)
    size_t      len = sizeof(int);

  /* the number of nodes */
    if (sysctlbyname("hw.packages", &(info->numHWNodes), &len, 0, 0) < 0) {
        if (errno == ENOENT) {
          // "hw.packages" is not known
            info->numHWNodes = 1;
        }
        else {
            fprintf(stderr, "unable to determine the number of nodes\n");
            return false;
        }
    }

  /* the number of cores */
    if (sysctlbyname("hw.physicalcpu", &(info->numHWCores), &len, 0, 0) < 0) {
        fprintf(stderr, "unable to determine the number of physical CPUs\n");
        return false;
    }

  /* the number of hardware threads */
    if (sysctlbyname("hw.logicalcpu", &(info->numHWThreads), &len, 0, 0) < 0) {
        if (errno == ENOENT) {
          // "hw.packages" is not known
            info->numHWThreads = info->numHWCores;
        }
        else {
            fprintf(stderr, "unable to determine the number of logical CPUs\n");
            return false;
        }
    }

    info->numCoresPerNode = info->numHWCores / info->numHWNodes;
    info->numThdsPerCore = info->numHWThreads / info->numHWCores;

    return true;
#else
    return false;
#endif

} /* end of GetNumCPUs */

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0