1
1

Merge pull request #5213 from rhc54/topic/rte

Enable the PMIx ompi/rte component
Этот коммит содержится в:
Ralph Castain 2018-06-03 10:23:40 -07:00 коммит произвёл GitHub
родитель a1737ca3eb 55ac526a67
Коммит 3020b699f3
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
135 изменённых файлов: 13858 добавлений и 10986 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -216,6 +216,7 @@ ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-interfaces.h
ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-file-interfaces.h ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-file-interfaces.h
ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-sizeof.f90 ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-sizeof.f90
ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-sizeof.h ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-sizeof.h
ompi/mpi/fortran/use-mpi-ignore-tkr/mpi-ignore-tkr-removed-interfaces.h
ompi/mpi/fortran/use-mpi-tkr/fortran_kinds.sh ompi/mpi/fortran/use-mpi-tkr/fortran_kinds.sh
ompi/mpi/fortran/use-mpi-tkr/fortran_sizes.h ompi/mpi/fortran/use-mpi-tkr/fortran_sizes.h

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2012-2013 Los Alamos National Security, LLC. * Copyright (c) 2012-2013 Los Alamos National Security, LLC.
* All rights reserved. * All rights reserved.
* Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2013-2018 Intel, Inc. All rights reserved.
* Copyright (c) 2014 Cisco Systems, Inc. All rights reserved. * Copyright (c) 2014 Cisco Systems, Inc. All rights reserved.
* Copyright (c) 2014-2016 Research Organization for Information Science * Copyright (c) 2014-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved. * and Technology (RIST). All rights reserved.
@ -49,10 +49,9 @@ typedef uint32_t ompi_vpid_t;
/* some local storage */ /* some local storage */
OMPI_DECLSPEC extern opal_process_name_t pmix_name_wildcard; OMPI_DECLSPEC extern opal_process_name_t pmix_name_wildcard;
OMPI_DECLSPEC extern opal_process_name_t pmix_proc_my_name;
OMPI_DECLSPEC extern hwloc_cpuset_t ompi_proc_applied_binding; OMPI_DECLSPEC extern hwloc_cpuset_t ompi_proc_applied_binding;
#define OMPI_PROC_MY_NAME (&pmix_proc_my_name) #define OMPI_PROC_MY_NAME (&pmix_process_info.my_name)
#define OMPI_NAME_WILDCARD (&pmix_name_wildcard) #define OMPI_NAME_WILDCARD (&pmix_name_wildcard)
typedef uint8_t ompi_rte_cmp_bitmask_t; typedef uint8_t ompi_rte_cmp_bitmask_t;
@ -62,7 +61,9 @@ typedef uint8_t ompi_rte_cmp_bitmask_t;
#define OMPI_RTE_CMP_ALL 0x04 #define OMPI_RTE_CMP_ALL 0x04
#define OMPI_RTE_CMP_WILD 0x10 #define OMPI_RTE_CMP_WILD 0x10
#define OMPI_NAME_PRINT(a) OPAL_NAME_PRINT((*(a))) OMPI_DECLSPEC char* ompi_pmix_print_name(const ompi_process_name_t *name);
#define OMPI_NAME_PRINT(a) ompi_pmix_print_name(a)
OMPI_DECLSPEC int ompi_rte_compare_name_fields(ompi_rte_cmp_bitmask_t mask, OMPI_DECLSPEC int ompi_rte_compare_name_fields(ompi_rte_cmp_bitmask_t mask,
const opal_process_name_t* name1, const opal_process_name_t* name1,
const opal_process_name_t* name2); const opal_process_name_t* name2);
@ -71,11 +72,17 @@ OMPI_DECLSPEC int ompi_rte_convert_string_to_process_name(opal_process_name_t *n
OMPI_DECLSPEC int ompi_rte_convert_process_name_to_string(char** name_string, OMPI_DECLSPEC int ompi_rte_convert_process_name_to_string(char** name_string,
const opal_process_name_t *name); const opal_process_name_t *name);
#define OMPI_LOCAL_JOBID(jobid) jobid #define OMPI_LOCAL_JOBID(n) \
#define OMPI_JOB_FAMILY(jobid) 0 ( (n) & 0x0000ffff)
/* do a little with the "family" param to avoid compiler warnings */ #define OMPI_JOB_FAMILY(n) \
#define OMPI_CONSTRUCT_JOBID(family,local) \ (((n) >> 16) & 0x0000ffff)
((family & 0x0000) | local) #define OMPI_CONSTRUCT_LOCAL_JOBID(local, job) \
( ((local) & 0xffff0000) | ((job) & 0x0000ffff) )
#define OMPI_CONSTRUCT_JOB_FAMILY(n) \
( ((n) << 16) & 0xffff0000)
#define OMPI_CONSTRUCT_JOBID(family, local) \
OMPI_CONSTRUCT_LOCAL_JOBID(OMPI_CONSTRUCT_JOB_FAMILY(family), local)
/* This is the DSS tag to serialize a proc name */ /* This is the DSS tag to serialize a proc name */
#define OMPI_NAME OPAL_NAME #define OMPI_NAME OPAL_NAME

Просмотреть файл

@ -1,7 +1,7 @@
/* /*
* Copyright (c) 2012-2013 Los Alamos National Security, LLC. * Copyright (c) 2012-2013 Los Alamos National Security, LLC.
* All rights reserved. * All rights reserved.
* Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2013-2018 Intel, Inc. All rights reserved.
* Copyright (c) 2012-2014 The University of Tennessee and The University * Copyright (c) 2012-2014 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights * of Tennessee Research Foundation. All rights
* reserved. * reserved.
@ -34,11 +34,13 @@
#include "opal/util/opal_getcwd.h" #include "opal/util/opal_getcwd.h"
#include "opal/util/os_path.h" #include "opal/util/os_path.h"
#include "opal/util/os_dirpath.h" #include "opal/util/os_dirpath.h"
#include "opal/util/printf.h"
#include "opal/util/proc.h" #include "opal/util/proc.h"
#include "opal/util/show_help.h" #include "opal/util/show_help.h"
#include "opal/mca/hwloc/base/base.h" #include "opal/mca/hwloc/base/base.h"
#include "opal/mca/pmix/base/base.h" #include "opal/mca/pmix/base/base.h"
#include "opal/threads/threads.h" #include "opal/threads/threads.h"
#include "opal/threads/tsd.h"
#include "opal/class/opal_list.h" #include "opal/class/opal_list.h"
#include "opal/dss/dss.h" #include "opal/dss/dss.h"
@ -57,7 +59,6 @@ extern ompi_rte_component_t mca_rte_pmix_component;
/* storage to support OMPI */ /* storage to support OMPI */
opal_process_name_t pmix_name_wildcard = {UINT32_MAX-1, UINT32_MAX-1}; opal_process_name_t pmix_name_wildcard = {UINT32_MAX-1, UINT32_MAX-1};
opal_process_name_t pmix_name_invalid = {UINT32_MAX, UINT32_MAX}; opal_process_name_t pmix_name_invalid = {UINT32_MAX, UINT32_MAX};
opal_process_name_t pmix_proc_my_name = {0, 0};
hwloc_cpuset_t ompi_proc_applied_binding = NULL; hwloc_cpuset_t ompi_proc_applied_binding = NULL;
pmix_process_info_t pmix_process_info = {0}; pmix_process_info_t pmix_process_info = {0};
bool pmix_proc_is_bound = false; bool pmix_proc_is_bound = false;
@ -69,11 +70,175 @@ static bool added_app_ctx = false;
static char* pre_condition_transports_print(uint64_t *unique_key); static char* pre_condition_transports_print(uint64_t *unique_key);
static int _setup_job_session_dir(char **sdir); static int _setup_job_session_dir(char **sdir);
#define ORTE_SCHEMA_DELIMITER_CHAR '.' #define OPAL_SCHEMA_DELIMITER_CHAR '.'
#define ORTE_SCHEMA_WILDCARD_CHAR '*' #define OPAL_SCHEMA_WILDCARD_CHAR '*'
#define ORTE_SCHEMA_WILDCARD_STRING "*" #define OPAL_SCHEMA_WILDCARD_STRING "*"
#define ORTE_SCHEMA_INVALID_CHAR '$' #define OPAL_SCHEMA_INVALID_CHAR '$'
#define ORTE_SCHEMA_INVALID_STRING "$" #define OPAL_SCHEMA_INVALID_STRING "$"
#define OPAL_PRINT_NAME_ARGS_MAX_SIZE 50
#define OPAL_PRINT_NAME_ARG_NUM_BUFS 16
static bool fns_init=false;
static opal_tsd_key_t print_args_tsd_key;
static char* opal_print_args_null = "NULL";
typedef struct {
char *buffers[OPAL_PRINT_NAME_ARG_NUM_BUFS];
int cntr;
} opal_print_args_buffers_t;
static void
buffer_cleanup(void *value)
{
int i;
opal_print_args_buffers_t *ptr;
if (NULL != value) {
ptr = (opal_print_args_buffers_t*)value;
for (i=0; i < OPAL_PRINT_NAME_ARG_NUM_BUFS; i++) {
free(ptr->buffers[i]);
}
free (ptr);
}
}
static opal_print_args_buffers_t*
get_print_name_buffer(void)
{
opal_print_args_buffers_t *ptr;
int ret, i;
if (!fns_init) {
/* setup the print_args function */
if (OPAL_SUCCESS != (ret = opal_tsd_key_create(&print_args_tsd_key, buffer_cleanup))) {
OPAL_ERROR_LOG(ret);
return NULL;
}
fns_init = true;
}
ret = opal_tsd_getspecific(print_args_tsd_key, (void**)&ptr);
if (OPAL_SUCCESS != ret) return NULL;
if (NULL == ptr) {
ptr = (opal_print_args_buffers_t*)malloc(sizeof(opal_print_args_buffers_t));
for (i=0; i < OPAL_PRINT_NAME_ARG_NUM_BUFS; i++) {
ptr->buffers[i] = (char *) malloc((OPAL_PRINT_NAME_ARGS_MAX_SIZE+1) * sizeof(char));
}
ptr->cntr = 0;
ret = opal_tsd_setspecific(print_args_tsd_key, (void*)ptr);
}
return (opal_print_args_buffers_t*) ptr;
}
static char* ompi_pmix_print_jobids(const opal_jobid_t job)
{
opal_print_args_buffers_t *ptr;
unsigned long tmp1, tmp2;
ptr = get_print_name_buffer();
if (NULL == ptr) {
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE);
return opal_print_args_null;
}
/* cycle around the ring */
if (OPAL_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
if (OPAL_JOBID_INVALID == job) {
snprintf(ptr->buffers[ptr->cntr++], OPAL_PRINT_NAME_ARGS_MAX_SIZE, "[INVALID]");
} else if (OPAL_JOBID_WILDCARD == job) {
snprintf(ptr->buffers[ptr->cntr++], OPAL_PRINT_NAME_ARGS_MAX_SIZE, "[WILDCARD]");
} else {
tmp1 = OMPI_JOB_FAMILY((unsigned long)job);
tmp2 = OMPI_LOCAL_JOBID((unsigned long)job);
snprintf(ptr->buffers[ptr->cntr++],
OPAL_PRINT_NAME_ARGS_MAX_SIZE,
"[%lu,%lu]", tmp1, tmp2);
}
return ptr->buffers[ptr->cntr-1];
}
static char* ompi_pmix_print_vpids(const opal_vpid_t vpid)
{
opal_print_args_buffers_t *ptr;
ptr = get_print_name_buffer();
if (NULL == ptr) {
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE);
return opal_print_args_null;
}
/* cycle around the ring */
if (OPAL_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
if (OPAL_VPID_INVALID == vpid) {
snprintf(ptr->buffers[ptr->cntr++], OPAL_PRINT_NAME_ARGS_MAX_SIZE, "INVALID");
} else if (OPAL_VPID_WILDCARD == vpid) {
snprintf(ptr->buffers[ptr->cntr++], OPAL_PRINT_NAME_ARGS_MAX_SIZE, "WILDCARD");
} else {
snprintf(ptr->buffers[ptr->cntr++],
OPAL_PRINT_NAME_ARGS_MAX_SIZE,
"%ld", (long)vpid);
}
return ptr->buffers[ptr->cntr-1];
}
char* ompi_pmix_print_name(const ompi_process_name_t *name)
{
opal_print_args_buffers_t *ptr;
char *job, *vpid;
/* protect against NULL names */
if (NULL == name) {
/* get the next buffer */
ptr = get_print_name_buffer();
if (NULL == ptr) {
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE);
return opal_print_args_null;
}
/* cycle around the ring */
if (OPAL_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
snprintf(ptr->buffers[ptr->cntr++], OPAL_PRINT_NAME_ARGS_MAX_SIZE, "[NO-NAME]");
return ptr->buffers[ptr->cntr-1];
}
/* get the jobid, vpid strings first - this will protect us from
* stepping on each other's buffer. This also guarantees
* that the print_args function has been initialized, so
* we don't need to duplicate that here
*/
job = ompi_pmix_print_jobids(name->jobid);
vpid = ompi_pmix_print_vpids(name->vpid);
/* get the next buffer */
ptr = get_print_name_buffer();
if (NULL == ptr) {
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE);
return opal_print_args_null;
}
/* cycle around the ring */
if (OPAL_PRINT_NAME_ARG_NUM_BUFS == ptr->cntr) {
ptr->cntr = 0;
}
snprintf(ptr->buffers[ptr->cntr++],
OPAL_PRINT_NAME_ARGS_MAX_SIZE,
"[%s,%s]", job, vpid);
return ptr->buffers[ptr->cntr-1];
}
int ompi_rte_compare_name_fields(ompi_rte_cmp_bitmask_t fields, int ompi_rte_compare_name_fields(ompi_rte_cmp_bitmask_t fields,
const opal_process_name_t* name1, const opal_process_name_t* name1,
@ -154,7 +319,7 @@ int ompi_rte_convert_string_to_process_name(opal_process_name_t *name,
} }
temp = strdup(name_string); /** copy input string as the strtok process is destructive */ temp = strdup(name_string); /** copy input string as the strtok process is destructive */
token = strchr(temp, ORTE_SCHEMA_DELIMITER_CHAR); /** get first field -> jobid */ token = strchr(temp, OPAL_SCHEMA_DELIMITER_CHAR); /** get first field -> jobid */
/* check for error */ /* check for error */
if (NULL == token) { if (NULL == token) {
@ -168,9 +333,9 @@ int ompi_rte_convert_string_to_process_name(opal_process_name_t *name,
/* check for WILDCARD character - assign /* check for WILDCARD character - assign
* value accordingly, if found * value accordingly, if found
*/ */
if (0 == strcmp(temp, ORTE_SCHEMA_WILDCARD_STRING)) { if (0 == strcmp(temp, OPAL_SCHEMA_WILDCARD_STRING)) {
job = pmix_name_wildcard.jobid; job = pmix_name_wildcard.jobid;
} else if (0 == strcmp(temp, ORTE_SCHEMA_INVALID_STRING)) { } else if (0 == strcmp(temp, OPAL_SCHEMA_INVALID_STRING)) {
job = pmix_name_invalid.jobid; job = pmix_name_invalid.jobid;
} else { } else {
job = strtoul(temp, NULL, 10); job = strtoul(temp, NULL, 10);
@ -179,9 +344,9 @@ int ompi_rte_convert_string_to_process_name(opal_process_name_t *name,
/* check for WILDCARD character - assign /* check for WILDCARD character - assign
* value accordingly, if found * value accordingly, if found
*/ */
if (0 == strcmp(token, ORTE_SCHEMA_WILDCARD_STRING)) { if (0 == strcmp(token, OPAL_SCHEMA_WILDCARD_STRING)) {
vpid = pmix_name_wildcard.vpid; vpid = pmix_name_wildcard.vpid;
} else if (0 == strcmp(token, ORTE_SCHEMA_INVALID_STRING)) { } else if (0 == strcmp(token, OPAL_SCHEMA_INVALID_STRING)) {
vpid = pmix_name_invalid.vpid; vpid = pmix_name_invalid.vpid;
} else { } else {
vpid = strtoul(token, NULL, 10); vpid = strtoul(token, NULL, 10);
@ -210,19 +375,19 @@ int ompi_rte_convert_process_name_to_string(char** name_string,
* it is passed back to us later * it is passed back to us later
*/ */
if (pmix_name_wildcard.jobid == name->jobid) { if (pmix_name_wildcard.jobid == name->jobid) {
asprintf(&tmp, "%s", ORTE_SCHEMA_WILDCARD_STRING); asprintf(&tmp, "%s", OPAL_SCHEMA_WILDCARD_STRING);
} else if (pmix_name_invalid.jobid == name->jobid) { } else if (pmix_name_invalid.jobid == name->jobid) {
asprintf(&tmp, "%s", ORTE_SCHEMA_INVALID_STRING); asprintf(&tmp, "%s", OPAL_SCHEMA_INVALID_STRING);
} else { } else {
asprintf(&tmp, "%lu", (unsigned long)name->jobid); asprintf(&tmp, "%lu", (unsigned long)name->jobid);
} }
if (pmix_name_wildcard.vpid == name->vpid) { if (pmix_name_wildcard.vpid == name->vpid) {
asprintf(&tmp2, "%s%c%s", tmp, ORTE_SCHEMA_DELIMITER_CHAR, ORTE_SCHEMA_WILDCARD_STRING); asprintf(&tmp2, "%s%c%s", tmp, OPAL_SCHEMA_DELIMITER_CHAR, OPAL_SCHEMA_WILDCARD_STRING);
} else if (pmix_name_invalid.vpid == name->vpid) { } else if (pmix_name_invalid.vpid == name->vpid) {
asprintf(&tmp2, "%s%c%s", tmp, ORTE_SCHEMA_DELIMITER_CHAR, ORTE_SCHEMA_INVALID_STRING); asprintf(&tmp2, "%s%c%s", tmp, OPAL_SCHEMA_DELIMITER_CHAR, OPAL_SCHEMA_INVALID_STRING);
} else { } else {
asprintf(&tmp2, "%s%c%lu", tmp, ORTE_SCHEMA_DELIMITER_CHAR, (unsigned long)name->vpid); asprintf(&tmp2, "%s%c%lu", tmp, OPAL_SCHEMA_DELIMITER_CHAR, (unsigned long)name->vpid);
} }
asprintf(name_string, "%s", tmp2); asprintf(name_string, "%s", tmp2);
@ -233,12 +398,103 @@ int ompi_rte_convert_process_name_to_string(char** name_string,
return OPAL_SUCCESS; return OPAL_SUCCESS;
} }
static int ompi_pmix_convert_string_to_jobid(opal_jobid_t *jobid, const char* jobidstring)
{
if (NULL == jobidstring) { /* got an error */
OPAL_ERROR_LOG(OPAL_ERR_BAD_PARAM);
*jobid = OPAL_JOBID_INVALID;
return OPAL_ERR_BAD_PARAM;
}
/** check for wildcard character - handle appropriately */
if (0 == strcmp(OPAL_SCHEMA_WILDCARD_STRING, jobidstring)) {
*jobid = OPAL_JOBID_WILDCARD;
return OPAL_SUCCESS;
}
/* check for invalid value */
if (0 == strcmp(OPAL_SCHEMA_INVALID_STRING, jobidstring)) {
*jobid = OPAL_JOBID_INVALID;
return OPAL_SUCCESS;
}
*jobid = strtoul(jobidstring, NULL, 10);
return OPAL_SUCCESS;
}
static int ompi_pmix_snprintf_jobid(char *jobid_string, size_t size, const opal_jobid_t jobid)
{
int rc;
/* check for wildcard value - handle appropriately */
if (OPAL_JOBID_WILDCARD == jobid) {
(void)strncpy(jobid_string, OPAL_SCHEMA_WILDCARD_STRING, size);
} else {
rc = snprintf(jobid_string, size, "%ld", (long) jobid);
if (0 > rc) {
return OPAL_ERROR;
}
}
return OPAL_SUCCESS;
}
/**
* Static functions used to configure the interactions between the OPAL and
* the runtime.
*/
static char*
_process_name_print_for_opal(const opal_process_name_t procname)
{
ompi_process_name_t* rte_name = (ompi_process_name_t*)&procname;
return ompi_pmix_print_name(rte_name);
}
static char*
_jobid_print_for_opal(const opal_jobid_t jobid)
{
return ompi_pmix_print_jobids(jobid);
}
static char*
_vpid_print_for_opal(const opal_vpid_t vpid)
{
return ompi_pmix_print_vpids(vpid);
}
static int
_process_name_compare(const opal_process_name_t p1, const opal_process_name_t p2)
{
return ompi_rte_compare_name_fields(OMPI_RTE_CMP_ALL, &p1, &p2);
}
static int _convert_string_to_process_name(opal_process_name_t *name,
const char* name_string)
{
return ompi_rte_convert_string_to_process_name(name, name_string);
}
static int _convert_process_name_to_string(char** name_string,
const opal_process_name_t *name)
{
return ompi_rte_convert_process_name_to_string(name_string, name);
}
static int
_convert_string_to_jobid(opal_jobid_t *jobid, const char *jobid_string)
{
return ompi_pmix_convert_string_to_jobid(jobid, jobid_string);
}
int ompi_rte_init(int *pargc, char ***pargv) int ompi_rte_init(int *pargc, char ***pargv)
{ {
int ret; int ret;
char *error = NULL; char *error = NULL;
opal_process_name_t pname; opal_process_name_t pname;
opal_proc_t *myname; opal_proc_t *myproc;
int u32, *u32ptr; int u32, *u32ptr;
uint16_t u16, *u16ptr; uint16_t u16, *u16ptr;
char **peers=NULL, *mycpuset; char **peers=NULL, *mycpuset;
@ -253,6 +509,16 @@ int ompi_rte_init(int *pargc, char ***pargv)
u16ptr = &u16; u16ptr = &u16;
memset(&pmix_process_info, 0, sizeof(pmix_process_info)); memset(&pmix_process_info, 0, sizeof(pmix_process_info));
/* Convince OPAL to use our naming scheme */
opal_process_name_print = _process_name_print_for_opal;
opal_vpid_print = _vpid_print_for_opal;
opal_jobid_print = _jobid_print_for_opal;
opal_compare_proc = _process_name_compare;
opal_convert_string_to_process_name = _convert_string_to_process_name;
opal_convert_process_name_to_string = _convert_process_name_to_string;
opal_snprintf_jobid = ompi_pmix_snprintf_jobid;
opal_convert_string_to_jobid = _convert_string_to_jobid;
/* initialize the opal layer */ /* initialize the opal layer */
if (OPAL_SUCCESS != (ret = opal_init(pargc, pargv))) { if (OPAL_SUCCESS != (ret = opal_init(pargc, pargv))) {
error = "opal_init"; error = "opal_init";
@ -284,14 +550,15 @@ int ompi_rte_init(int *pargc, char ***pargv)
} }
/* opal_pmix.init will have filled in proc name fields in /* opal_pmix.init will have filled in proc name fields in
* OPAL, so transfer them here */ * OPAL, so transfer them here */
myname = opal_proc_local_get(); pmix_process_info.my_name.jobid = OPAL_PROC_MY_NAME.jobid;
pmix_proc_my_name = myname->proc_name; pmix_process_info.my_name.vpid = OPAL_PROC_MY_NAME.vpid;
/* get our hostname */ /* get our hostname */
pmix_process_info.nodename = opal_get_proc_hostname(myname); myproc = opal_proc_local_get();
pmix_process_info.nodename = opal_get_proc_hostname(myproc);
/* get our local rank from PMI */ /* get our local rank from PMI */
OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_RANK, OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_RANK,
&pmix_proc_my_name, &u16ptr, OPAL_UINT16); &pmix_process_info.my_name, &u16ptr, OPAL_UINT16);
if (OPAL_SUCCESS != ret) { if (OPAL_SUCCESS != ret) {
error = "getting local rank"; error = "getting local rank";
goto error; goto error;
@ -300,7 +567,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* get our node rank from PMI */ /* get our node rank from PMI */
OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_NODE_RANK, OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_NODE_RANK,
&pmix_proc_my_name, &u16ptr, OPAL_UINT16); &pmix_process_info.my_name, &u16ptr, OPAL_UINT16);
if (OPAL_SUCCESS != ret) { if (OPAL_SUCCESS != ret) {
error = "getting node rank"; error = "getting node rank";
goto error; goto error;
@ -308,8 +575,10 @@ int ompi_rte_init(int *pargc, char ***pargv)
pmix_process_info.my_node_rank = u16; pmix_process_info.my_node_rank = u16;
/* get job size */ /* get job size */
pname.jobid = pmix_process_info.my_name.jobid;
pname.vpid = OPAL_VPID_WILDCARD;
OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_JOB_SIZE, OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_JOB_SIZE,
&pmix_name_wildcard, &u32ptr, OPAL_UINT32); &pname, &u32ptr, OPAL_UINT32);
if (OPAL_SUCCESS != ret) { if (OPAL_SUCCESS != ret) {
error = "getting job size"; error = "getting job size";
goto error; goto error;
@ -319,8 +588,8 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* push into the environ for pickup in MPI layer for /* push into the environ for pickup in MPI layer for
* MPI-3 required info key * MPI-3 required info key
*/ */
if (NULL == getenv(OPAL_MCA_PREFIX"orte_ess_num_procs")) { if (NULL == getenv(OPAL_MCA_PREFIX"opal_ess_num_procs")) {
asprintf(&ev1, OPAL_MCA_PREFIX"orte_ess_num_procs=%d", pmix_process_info.num_procs); asprintf(&ev1, OPAL_MCA_PREFIX"opal_ess_num_procs=%d", pmix_process_info.num_procs);
putenv(ev1); putenv(ev1);
added_num_procs = true; added_num_procs = true;
} }
@ -332,7 +601,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* get our app number from PMI - ok if not found */ /* get our app number from PMI - ok if not found */
OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_APPNUM, OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_APPNUM,
&pmix_proc_my_name, &u32ptr, OPAL_UINT32); &pmix_process_info.my_name, &u32ptr, OPAL_UINT32);
if (OPAL_SUCCESS == ret) { if (OPAL_SUCCESS == ret) {
pmix_process_info.app_num = u32; pmix_process_info.app_num = u32;
} else { } else {
@ -342,7 +611,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* get the number of local peers - required for wireup of /* get the number of local peers - required for wireup of
* shared memory BTL */ * shared memory BTL */
OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_SIZE, OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_SIZE,
&pmix_name_wildcard, &u32ptr, OPAL_UINT32); &pname, &u32ptr, OPAL_UINT32);
if (OPAL_SUCCESS == ret) { if (OPAL_SUCCESS == ret) {
pmix_process_info.num_local_peers = u32 - 1; // want number besides ourselves pmix_process_info.num_local_peers = u32 - 1; // want number besides ourselves
} else { } else {
@ -353,17 +622,17 @@ int ompi_rte_init(int *pargc, char ***pargv)
* we can use the jobfam and stepid as unique keys * we can use the jobfam and stepid as unique keys
* because they are unique values assigned by the RM * because they are unique values assigned by the RM
*/ */
if (NULL == getenv(OPAL_MCA_PREFIX"orte_precondition_transports")) { if (NULL == getenv(OPAL_MCA_PREFIX"opal_precondition_transports")) {
unique_key[0] = (pmix_proc_my_name.jobid & 0xff00) >> 16; unique_key[0] = (pmix_process_info.my_name.jobid & 0xff00) >> 16;
unique_key[1] = pmix_proc_my_name.jobid & 0x00ff; unique_key[1] = pmix_process_info.my_name.jobid & 0x00ff;
if (NULL == (string_key = pre_condition_transports_print(unique_key))) { if (NULL == (string_key = pre_condition_transports_print(unique_key))) {
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE); OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE);
return OPAL_ERR_OUT_OF_RESOURCE; return OPAL_ERR_OUT_OF_RESOURCE;
} }
opal_output_verbose(2, ompi_rte_base_framework.framework_output, opal_output_verbose(2, ompi_rte_base_framework.framework_output,
"%s transport key %s", "%s transport key %s",
OPAL_NAME_PRINT(pmix_proc_my_name), string_key); OPAL_NAME_PRINT(pmix_process_info.my_name), string_key);
asprintf(&envar, OPAL_MCA_PREFIX"orte_precondition_transports=%s", string_key); asprintf(&envar, OPAL_MCA_PREFIX"opal_precondition_transports=%s", string_key);
putenv(envar); putenv(envar);
added_transport_keys = true; added_transport_keys = true;
/* cannot free the envar as that messes up our environ */ /* cannot free the envar as that messes up our environ */
@ -371,7 +640,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
} }
/* retrieve temp directories info */ /* retrieve temp directories info */
OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_NSDIR, &pmix_name_wildcard, &val, OPAL_STRING); OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_NSDIR, &pname, &val, OPAL_STRING);
if (OPAL_SUCCESS == ret && NULL != val) { if (OPAL_SUCCESS == ret && NULL != val) {
pmix_process_info.job_session_dir = val; pmix_process_info.job_session_dir = val;
val = NULL; val = NULL;
@ -394,7 +663,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
} }
/* retrieve the local peers */ /* retrieve the local peers */
OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_PEERS, OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_PEERS,
&pmix_name_wildcard, &val, OPAL_STRING); &pname, &val, OPAL_STRING);
if (OPAL_SUCCESS == ret && NULL != val) { if (OPAL_SUCCESS == ret && NULL != val) {
peers = opal_argv_split(val, ','); peers = opal_argv_split(val, ',');
free(val); free(val);
@ -410,16 +679,16 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* identify our location */ /* identify our location */
val = NULL; val = NULL;
OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_LOCALITY_STRING, OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_LOCALITY_STRING,
&pmix_proc_my_name, &val, OPAL_STRING); &pmix_process_info.my_name, &val, OPAL_STRING);
if (OPAL_SUCCESS == ret && NULL != val) { if (OPAL_SUCCESS == ret && NULL != val) {
mycpuset = val; mycpuset = val;
} else { } else {
mycpuset = NULL; mycpuset = NULL;
} }
pname.jobid = pmix_proc_my_name.jobid; pname.jobid = pmix_process_info.my_name.jobid;
for (i=0; NULL != peers[i]; i++) { for (i=0; NULL != peers[i]; i++) {
pname.vpid = strtoul(peers[i], NULL, 10); pname.vpid = strtoul(peers[i], NULL, 10);
if (pname.vpid == pmix_proc_my_name.vpid) { if (pname.vpid == pmix_process_info.my_name.vpid) {
/* we are fully local to ourselves */ /* we are fully local to ourselves */
u16 = OPAL_PROC_ALL_LOCAL; u16 = OPAL_PROC_ALL_LOCAL;
} else { } else {
@ -439,7 +708,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
kv->type = OPAL_UINT16; kv->type = OPAL_UINT16;
OPAL_OUTPUT_VERBOSE((1, ompi_rte_base_framework.framework_output, OPAL_OUTPUT_VERBOSE((1, ompi_rte_base_framework.framework_output,
"%s locality: proc %s locality %s", "%s locality: proc %s locality %s",
OPAL_NAME_PRINT(pmix_proc_my_name), OPAL_NAME_PRINT(pmix_process_info.my_name),
OPAL_NAME_PRINT(pname), opal_hwloc_base_print_locality(u16))); OPAL_NAME_PRINT(pname), opal_hwloc_base_print_locality(u16)));
kv->data.uint16 = u16; kv->data.uint16 = u16;
ret = opal_pmix.store_local(&pname, kv); ret = opal_pmix.store_local(&pname, kv);
@ -514,10 +783,10 @@ int ompi_rte_finalize(void)
* so we leave that structure intact * so we leave that structure intact
*/ */
if (added_transport_keys) { if (added_transport_keys) {
unsetenv(OPAL_MCA_PREFIX"orte_precondition_transports"); unsetenv(OPAL_MCA_PREFIX"opal_precondition_transports");
} }
if (added_num_procs) { if (added_num_procs) {
unsetenv(OPAL_MCA_PREFIX"orte_ess_num_procs"); unsetenv(OPAL_MCA_PREFIX"opal_ess_num_procs");
} }
if (added_app_ctx) { if (added_app_ctx) {
unsetenv("OMPI_APP_CTX_NUM_PROCS"); unsetenv("OMPI_APP_CTX_NUM_PROCS");
@ -750,7 +1019,7 @@ static int _setup_job_session_dir(char **sdir)
"%s/ompi.%s.%lu/jf.0/%u", tmpdir, "%s/ompi.%s.%lu/jf.0/%u", tmpdir,
pmix_process_info.nodename, pmix_process_info.nodename,
(unsigned long)uid, (unsigned long)uid,
pmix_proc_my_name.jobid)) { pmix_process_info.my_name.jobid)) {
pmix_process_info.job_session_dir = NULL; pmix_process_info.job_session_dir = NULL;
return OPAL_ERR_OUT_OF_RESOURCE; return OPAL_ERR_OUT_OF_RESOURCE;
} }

Просмотреть файл

@ -10,7 +10,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2006-2017 Cisco Systems, Inc. All rights reserved * Copyright (c) 2006-2018 Cisco Systems, Inc. All rights reserved
* Copyright (c) 2006-2015 Mellanox Technologies. All rights reserved. * Copyright (c) 2006-2015 Mellanox Technologies. All rights reserved.
* Copyright (c) 2006-2015 Los Alamos National Security, LLC. All rights * Copyright (c) 2006-2015 Los Alamos National Security, LLC. All rights
* reserved. * reserved.
@ -1524,7 +1524,11 @@ static uint64_t calculate_total_mem (void)
if (NULL == machine) { if (NULL == machine) {
return 0; return 0;
} }
#if HWLOC_API_VERSION < 0x20000
return machine->memory.total_memory; return machine->memory.total_memory;
#else
return machine->total_memory;
#endif
} }
/* couldn't find it */ /* couldn't find it */

Просмотреть файл

@ -175,10 +175,6 @@ OPAL_DECLSPEC unsigned int opal_hwloc_base_get_nbobjs_by_type(hwloc_topology_t t
hwloc_obj_type_t target, hwloc_obj_type_t target,
unsigned cache_level, unsigned cache_level,
opal_hwloc_resource_type_t rtype); opal_hwloc_resource_type_t rtype);
OPAL_DECLSPEC hwloc_obj_t opal_hwloc_base_find_min_bound_target_under_obj(hwloc_topology_t topo,
hwloc_obj_t obj,
hwloc_obj_type_t target,
unsigned cache_leve);
OPAL_DECLSPEC void opal_hwloc_base_clear_usage(hwloc_topology_t topo); OPAL_DECLSPEC void opal_hwloc_base_clear_usage(hwloc_topology_t topo);
OPAL_DECLSPEC hwloc_obj_t opal_hwloc_base_get_obj_by_type(hwloc_topology_t topo, OPAL_DECLSPEC hwloc_obj_t opal_hwloc_base_get_obj_by_type(hwloc_topology_t topo,

Просмотреть файл

@ -415,21 +415,14 @@ char* opal_hwloc_base_print_locality(opal_hwloc_locality_t locality)
static void obj_data_const(opal_hwloc_obj_data_t *ptr) static void obj_data_const(opal_hwloc_obj_data_t *ptr)
{ {
ptr->available = NULL;
ptr->npus_calculated = false; ptr->npus_calculated = false;
ptr->npus = 0; ptr->npus = 0;
ptr->idx = UINT_MAX; ptr->idx = UINT_MAX;
ptr->num_bound = 0; ptr->num_bound = 0;
} }
static void obj_data_dest(opal_hwloc_obj_data_t *ptr)
{
if (NULL != ptr->available) {
hwloc_bitmap_free(ptr->available);
}
}
OBJ_CLASS_INSTANCE(opal_hwloc_obj_data_t, OBJ_CLASS_INSTANCE(opal_hwloc_obj_data_t,
opal_object_t, opal_object_t,
obj_data_const, obj_data_dest); obj_data_const, NULL);
static void sum_const(opal_hwloc_summary_t *ptr) static void sum_const(opal_hwloc_summary_t *ptr)
{ {

Просмотреть файл

@ -10,7 +10,7 @@
* University of Stuttgart. All rights reserved. * University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California. * Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved. * All rights reserved.
* Copyright (c) 2011-2017 Cisco Systems, Inc. All rights reserved * Copyright (c) 2011-2018 Cisco Systems, Inc. All rights reserved
* Copyright (c) 2012-2017 Los Alamos National Security, LLC. * Copyright (c) 2012-2017 Los Alamos National Security, LLC.
* All rights reserved. * All rights reserved.
* Copyright (c) 2013-2017 Intel, Inc. All rights reserved. * Copyright (c) 2013-2017 Intel, Inc. All rights reserved.
@ -23,6 +23,7 @@
* $HEADER$ * $HEADER$
*/ */
#define OPAL_HWLOC_WANT_SHMEM 1
#include "opal_config.h" #include "opal_config.h"
@ -149,7 +150,7 @@ int opal_hwloc_base_filter_cpus(hwloc_topology_t topo)
avail = hwloc_bitmap_alloc(); avail = hwloc_bitmap_alloc();
hwloc_bitmap_and(avail, root->online_cpuset, root->allowed_cpuset); hwloc_bitmap_and(avail, root->online_cpuset, root->allowed_cpuset);
#else #else
avail = hwloc_bitmap_dup(root->allowed_cpuset); avail = hwloc_bitmap_dup(root->cpuset);
#endif #endif
OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output, OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
"hwloc:base: no cpus specified - using root available cpuset")); "hwloc:base: no cpus specified - using root available cpuset"));
@ -173,7 +174,7 @@ int opal_hwloc_base_filter_cpus(hwloc_topology_t topo)
hwloc_bitmap_and(pucpus, pu->online_cpuset, pu->allowed_cpuset); hwloc_bitmap_and(pucpus, pu->online_cpuset, pu->allowed_cpuset);
#else #else
hwloc_bitmap_free(pucpus); hwloc_bitmap_free(pucpus);
pucpus = hwloc_bitmap_dup(pu->allowed_cpuset); pucpus = hwloc_bitmap_dup(pu->cpuset);
#endif #endif
hwloc_bitmap_or(res, avail, pucpus); hwloc_bitmap_or(res, avail, pucpus);
hwloc_bitmap_copy(avail, res); hwloc_bitmap_copy(avail, res);
@ -195,7 +196,7 @@ int opal_hwloc_base_filter_cpus(hwloc_topology_t topo)
hwloc_bitmap_and(pucpus, pu->online_cpuset, pu->allowed_cpuset); hwloc_bitmap_and(pucpus, pu->online_cpuset, pu->allowed_cpuset);
#else #else
hwloc_bitmap_free(pucpus); hwloc_bitmap_free(pucpus);
pucpus = hwloc_bitmap_dup(pu->allowed_cpuset); pucpus = hwloc_bitmap_dup(pu->cpuset);
#endif #endif
hwloc_bitmap_or(res, avail, pucpus); hwloc_bitmap_or(res, avail, pucpus);
hwloc_bitmap_copy(avail, res); hwloc_bitmap_copy(avail, res);
@ -560,30 +561,6 @@ int opal_hwloc_base_report_bind_failure(const char *file,
return OPAL_SUCCESS; return OPAL_SUCCESS;
} }
static void df_search_cores(hwloc_obj_t obj, unsigned int *cnt)
{
unsigned k;
opal_hwloc_obj_data_t *data;
if (HWLOC_OBJ_CORE == obj->type) {
data = (opal_hwloc_obj_data_t*)obj->userdata;
if (NULL == data) {
data = OBJ_NEW(opal_hwloc_obj_data_t);
obj->userdata = (void*)data;
}
if (NULL == opal_hwloc_base_cpu_list) {
data->npus = 1;
}
*cnt += data->npus;
return;
}
for (k=0; k < obj->arity; k++) {
df_search_cores(obj->children[k], cnt);
}
return;
}
/* determine if there is a single cpu in a bitmap */ /* determine if there is a single cpu in a bitmap */
bool opal_hwloc_base_single_cpu(hwloc_cpuset_t cpuset) bool opal_hwloc_base_single_cpu(hwloc_cpuset_t cpuset)
{ {
@ -628,18 +605,8 @@ unsigned int opal_hwloc_base_get_npus(hwloc_topology_t topo,
* count bits in this case as there may be more than * count bits in this case as there may be more than
* one hwthread/core. Instead, find the number of cores * one hwthread/core. Instead, find the number of cores
* in the system * in the system
*
* NOTE: remember, hwloc can't find "cores" in all
* environments. So first check to see if it found
* "core" at all.
*/ */
if (NULL != hwloc_get_obj_by_type(topo, HWLOC_OBJ_CORE, 0)) { cnt = hwloc_get_nbobjs_inside_cpuset_by_type(topo, obj->cpuset, HWLOC_OBJ_CORE);
/* starting at the incoming obj, do a down-first search
* and count the number of cores under it
*/
cnt = 0;
df_search_cores(obj, &cnt);
}
} else { } else {
hwloc_cpuset_t cpuset; hwloc_cpuset_t cpuset;
@ -732,14 +699,6 @@ unsigned int opal_hwloc_base_get_obj_idx(hwloc_topology_t topo,
* there is a single cache object type, and the level is encoded * there is a single cache object type, and the level is encoded
* in an attribute union. So looking for cache objects involves * in an attribute union. So looking for cache objects involves
* a multi-step test :-( * a multi-step test :-(
*
* And, of course, we make things even worse because we don't
* always care about what is physically or logically present,
* but rather what is available to us. For example, we don't
* want to map or bind to a cpu that is offline, or one that
* we aren't allowed by use by the OS. So we have to also filter
* the search to avoid those objects that don't have any cpus
* we can use :-((
*/ */
static hwloc_obj_t df_search(hwloc_topology_t topo, static hwloc_obj_t df_search(hwloc_topology_t topo,
hwloc_obj_t start, hwloc_obj_t start,
@ -747,100 +706,68 @@ static hwloc_obj_t df_search(hwloc_topology_t topo,
unsigned cache_level, unsigned cache_level,
unsigned int nobj, unsigned int nobj,
opal_hwloc_resource_type_t rtype, opal_hwloc_resource_type_t rtype,
unsigned int *idx,
unsigned int *num_objs) unsigned int *num_objs)
{ {
unsigned k; unsigned k;
hwloc_obj_t obj; hwloc_obj_t obj;
opal_hwloc_obj_data_t *data; opal_hwloc_obj_data_t *data;
int search_depth;
if (target == start->type) { search_depth = hwloc_get_type_depth(topo, target);
#if HWLOC_API_VERSION < 0x20000 if (HWLOC_TYPE_DEPTH_MULTIPLE == search_depth) {
if (HWLOC_OBJ_CACHE == start->type && cache_level != start->attr->cache.depth) { /* either v1.x Cache, or Groups */
goto notfound; #if HWLOC_API_VERSION >= 0x20000
} return NULL;
#else
if (cache_level != HWLOC_OBJ_CACHE)
return NULL;
search_depth = hwloc_get_cache_type_depth(topo, cache_level, (hwloc_obj_cache_type_t) -1);
#endif #endif
if (OPAL_HWLOC_LOGICAL == rtype) { }
/* the hwloc tree is composed of LOGICAL objects, so the only if (HWLOC_TYPE_DEPTH_UNKNOWN == search_depth)
* time we come here is when we are looking for logical caches return NULL;
*/
if (NULL != num_objs) { if (OPAL_HWLOC_LOGICAL == rtype) {
/* we are counting the number of caches at this level */ if (num_objs)
*num_objs += 1; *num_objs = hwloc_get_nbobjs_by_depth(topo, search_depth);
} else if (*idx == nobj) { return hwloc_get_obj_by_depth(topo, search_depth, nobj);
/* found the specific instance of the cache level being sought */ }
return start; if (OPAL_HWLOC_PHYSICAL == rtype) {
} /* the PHYSICAL object number is stored as the os_index. When
*idx += 1; * counting physical objects, we can't just count the number
return NULL; * that are in the hwloc tree as the only entries in the tree
* are LOGICAL objects - i.e., any physical gaps won't show. So
* we instead return the MAX os_index, as this is the best we
* can do to tell you how many PHYSICAL objects are in the system.
*
* NOTE: if the last PHYSICAL object is not present (e.g., the last
* socket on the node is empty), then the count we return will
* be wrong!
*/
hwloc_obj_t found = NULL;
obj = NULL;
if (num_objs)
*num_objs = 0;
while ((obj = hwloc_get_next_obj_by_depth(topo, search_depth, obj)) != NULL) {
if (num_objs && obj->os_index > *num_objs)
*num_objs = obj->os_index;
if (obj->os_index == nobj)
found = obj;
} }
if (OPAL_HWLOC_PHYSICAL == rtype) { return found;
/* the PHYSICAL object number is stored as the os_index. When }
* counting physical objects, we can't just count the number if (OPAL_HWLOC_AVAILABLE == rtype) {
* that are in the hwloc tree as the only entries in the tree int idx = 0;
* are LOGICAL objects - i.e., any physical gaps won't show. So if (num_objs)
* we instead return the MAX os_index, as this is the best we *num_objs = hwloc_get_nbobjs_inside_cpuset_by_depth(topo, start->cpuset, search_depth);
* can do to tell you how many PHYSICAL objects are in the system. obj = NULL;
* while ((obj = hwloc_get_next_obj_inside_cpuset_by_depth(topo, start->cpuset, search_depth, obj)) != NULL) {
* NOTE: if the last PHYSICAL object is not present (e.g., the last if (idx == nobj)
* socket on the node is empty), then the count we return will return obj;
* be wrong! idx++;
*/
if (NULL != num_objs) {
/* we are counting the number of these objects */
if (*num_objs < (unsigned int)start->os_index) {
*num_objs = (unsigned int)start->os_index;
}
} else if (*idx == nobj) {
/* found the specific instance of the cache level being sought */
return start;
}
*idx += 1;
return NULL;
} }
if (OPAL_HWLOC_AVAILABLE == rtype) {
/* check - do we already know the index of this object */
data = (opal_hwloc_obj_data_t*)start->userdata;
if (NULL == data) {
data = OBJ_NEW(opal_hwloc_obj_data_t);
start->userdata = (void*)data;
}
/* if we already know our location and it matches,
* then we are good
*/
if (UINT_MAX != data->idx && data->idx == nobj) {
return start;
}
/* see if we already know our available cpuset */
if (NULL == data->available) {
data->available = hwloc_bitmap_dup(start->cpuset);
}
if (NULL != data->available && !hwloc_bitmap_iszero(data->available)) {
if (NULL != num_objs) {
*num_objs += 1;
} else if (*idx == nobj) {
/* cache the location */
data->idx = *idx;
return start;
}
*idx += 1;
}
return NULL;
}
/* if it wasn't one of the above, then we are lost */
return NULL; return NULL;
} }
#if HWLOC_API_VERSION < 0x20000
notfound:
#endif
for (k=0; k < start->arity; k++) {
obj = df_search(topo, start->children[k], target, cache_level, nobj, rtype, idx, num_objs);
if (NULL != obj) {
return obj;
}
}
return NULL; return NULL;
} }
@ -849,7 +776,7 @@ unsigned int opal_hwloc_base_get_nbobjs_by_type(hwloc_topology_t topo,
unsigned cache_level, unsigned cache_level,
opal_hwloc_resource_type_t rtype) opal_hwloc_resource_type_t rtype)
{ {
unsigned int num_objs, idx; unsigned int num_objs;
hwloc_obj_t obj; hwloc_obj_t obj;
opal_hwloc_summary_t *sum; opal_hwloc_summary_t *sum;
opal_hwloc_topo_data_t *data; opal_hwloc_topo_data_t *data;
@ -881,7 +808,6 @@ unsigned int opal_hwloc_base_get_nbobjs_by_type(hwloc_topology_t topo,
/* for everything else, we have to do some work */ /* for everything else, we have to do some work */
num_objs = 0; num_objs = 0;
idx = 0;
obj = hwloc_get_root_obj(topo); obj = hwloc_get_root_obj(topo);
/* first see if the topology already has this summary */ /* first see if the topology already has this summary */
@ -904,7 +830,7 @@ unsigned int opal_hwloc_base_get_nbobjs_by_type(hwloc_topology_t topo,
} }
/* don't already know it - go get it */ /* don't already know it - go get it */
df_search(topo, obj, target, cache_level, 0, rtype, &idx, &num_objs); df_search(topo, obj, target, cache_level, 0, rtype, &num_objs);
/* cache the results for later */ /* cache the results for later */
sum = OBJ_NEW(opal_hwloc_summary_t); sum = OBJ_NEW(opal_hwloc_summary_t);
@ -921,124 +847,6 @@ unsigned int opal_hwloc_base_get_nbobjs_by_type(hwloc_topology_t topo,
return num_objs; return num_objs;
} }
static hwloc_obj_t df_search_min_bound(hwloc_topology_t topo,
hwloc_obj_t start,
hwloc_obj_type_t target,
unsigned cache_level,
unsigned int *min_bound)
{
unsigned k;
hwloc_obj_t obj, save=NULL;
opal_hwloc_obj_data_t *data;
if (target == start->type) {
/* only consider procs that are allowed */
if (0 == (k = opal_hwloc_base_get_npus(topo, start))) {
goto notfound;
}
#if HWLOC_API_VERSION < 0x20000
if (HWLOC_OBJ_CACHE == start->type && cache_level != start->attr->cache.depth) {
goto notfound;
}
#endif
/* see how many procs are bound to us */
data = (opal_hwloc_obj_data_t*)start->userdata;
if (NULL == data) {
data = OBJ_NEW(opal_hwloc_obj_data_t);
start->userdata = data;
}
OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
"hwloc:base:min_bound_under_obj object %s:%u nbound %u min %u",
hwloc_obj_type_string(target), start->logical_index,
data->num_bound, *min_bound));
if (data->num_bound < *min_bound) {
*min_bound = data->num_bound;
return start;
}
/* if we have more procs bound to us than the min, return NULL */
return NULL;
}
notfound:
for (k=0; k < start->arity; k++) {
obj = df_search_min_bound(topo, start->children[k], target, cache_level, min_bound);
if (NULL != obj) {
save = obj;
}
/* if the target level is HWTHREAD and we are NOT treating
* hwthreads as separate cpus, then we can only consider
* the 0th hwthread on a core
*/
if (HWLOC_OBJ_CORE == start->type && HWLOC_OBJ_PU == target &&
!opal_hwloc_use_hwthreads_as_cpus) {
break;
}
}
return save;
}
hwloc_obj_t opal_hwloc_base_find_min_bound_target_under_obj(hwloc_topology_t topo,
hwloc_obj_t obj,
hwloc_obj_type_t target,
unsigned cache_level)
{
unsigned int min_bound;
hwloc_obj_t loc;
/* bozo check */
if (NULL == topo || NULL == obj) {
OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
"hwloc:base:find_min_bound_under_obj NULL %s",
(NULL == topo) ? "topology" : "object"));
return NULL;
}
/* if the object and target is the same type, then there is
* nothing under it, so just return itself
*/
if (target == obj->type) {
/* again, we have to treat caches differently as
* the levels distinguish them
*/
#if HWLOC_API_VERSION < 0x20000
if (HWLOC_OBJ_CACHE == target &&
cache_level < obj->attr->cache.depth) {
goto moveon;
}
#endif
return obj;
}
#if HWLOC_API_VERSION < 0x20000
moveon:
#endif
/* the hwloc accessors all report at the topo level,
* so we have to do some work
*/
min_bound = UINT_MAX;
loc = df_search_min_bound(topo, obj, target, cache_level, &min_bound);
if (NULL != loc) {
#if HWLOC_API_VERSION < 0x20000
if (HWLOC_OBJ_CACHE == target) {
OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
"hwloc:base:min_bound_under_obj found min bound of %u on %s:%u:%u",
min_bound, hwloc_obj_type_string(target),
cache_level, loc->logical_index));
} else
#endif
OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
"hwloc:base:min_bound_under_obj found min bound of %u on %s:%u",
min_bound, hwloc_obj_type_string(target), loc->logical_index));
}
return loc;
}
/* as above, only return the Nth instance of the specified object /* as above, only return the Nth instance of the specified object
* type from inside the topology * type from inside the topology
*/ */
@ -1048,7 +856,6 @@ hwloc_obj_t opal_hwloc_base_get_obj_by_type(hwloc_topology_t topo,
unsigned int instance, unsigned int instance,
opal_hwloc_resource_type_t rtype) opal_hwloc_resource_type_t rtype)
{ {
unsigned int idx;
hwloc_obj_t obj; hwloc_obj_t obj;
/* bozo check */ /* bozo check */
@ -1069,9 +876,8 @@ hwloc_obj_t opal_hwloc_base_get_obj_by_type(hwloc_topology_t topo,
} }
/* for everything else, we have to do some work */ /* for everything else, we have to do some work */
idx = 0;
obj = hwloc_get_root_obj(topo); obj = hwloc_get_root_obj(topo);
return df_search(topo, obj, target, cache_level, instance, rtype, &idx, NULL); return df_search(topo, obj, target, cache_level, instance, rtype, NULL);
} }
static void df_clear(hwloc_topology_t topo, static void df_clear(hwloc_topology_t topo,
@ -1179,7 +985,6 @@ static int socket_core_to_cpu_set(char *socket_core_list,
int lower_range, upper_range; int lower_range, upper_range;
int socket_id, core_id; int socket_id, core_id;
hwloc_obj_t socket, core; hwloc_obj_t socket, core;
unsigned int idx;
hwloc_obj_type_t obj_type = HWLOC_OBJ_CORE; hwloc_obj_type_t obj_type = HWLOC_OBJ_CORE;
socket_core = opal_argv_split(socket_core_list, ':'); socket_core = opal_argv_split(socket_core_list, ':');
@ -1223,10 +1028,9 @@ static int socket_core_to_cpu_set(char *socket_core_list,
for (j=0; NULL != list[j]; j++) { for (j=0; NULL != list[j]; j++) {
core_id = atoi(list[j]); core_id = atoi(list[j]);
/* get that object */ /* get that object */
idx = 0;
if (NULL == (core = df_search(topo, socket, obj_type, 0, if (NULL == (core = df_search(topo, socket, obj_type, 0,
core_id, OPAL_HWLOC_AVAILABLE, core_id, OPAL_HWLOC_AVAILABLE,
&idx, NULL))) { NULL))) {
opal_argv_free(list); opal_argv_free(list);
opal_argv_free(range); opal_argv_free(range);
opal_argv_free(socket_core); opal_argv_free(socket_core);
@ -1246,10 +1050,9 @@ static int socket_core_to_cpu_set(char *socket_core_list,
upper_range = atoi(range[1]); upper_range = atoi(range[1]);
for (core_id=lower_range; core_id <= upper_range; core_id++) { for (core_id=lower_range; core_id <= upper_range; core_id++) {
/* get that object */ /* get that object */
idx = 0;
if (NULL == (core = df_search(topo, socket, obj_type, 0, if (NULL == (core = df_search(topo, socket, obj_type, 0,
core_id, OPAL_HWLOC_AVAILABLE, core_id, OPAL_HWLOC_AVAILABLE,
&idx, NULL))) { NULL))) {
opal_argv_free(range); opal_argv_free(range);
opal_argv_free(socket_core); opal_argv_free(socket_core);
return OPAL_ERR_NOT_FOUND; return OPAL_ERR_NOT_FOUND;

5
opal/mca/hwloc/external/configure.m4 поставляемый
Просмотреть файл

@ -63,12 +63,17 @@ AC_DEFUN([MCA_opal_hwloc_external_POST_CONFIG],[
# the MCA_hwloc_external_openfabrics_helper define). # the MCA_hwloc_external_openfabrics_helper define).
AS_IF([test "$opal_hwloc_dir" != ""], AS_IF([test "$opal_hwloc_dir" != ""],
[opal_hwloc_include="$opal_hwloc_dir/include/hwloc.h" [opal_hwloc_include="$opal_hwloc_dir/include/hwloc.h"
opal_hwloc_shmem_include="$opal_hwloc_dir/include/hwloc/shmem.h",
opal_hwloc_openfabrics_include="$opal_hwloc_dir/include/hwloc/openfabrics-verbs.h"], opal_hwloc_openfabrics_include="$opal_hwloc_dir/include/hwloc/openfabrics-verbs.h"],
[opal_hwloc_include="hwloc.h" [opal_hwloc_include="hwloc.h"
opal_hwloc_shmem_include="hwloc/shmem.h"
opal_hwloc_openfabrics_include="hwloc/openfabrics-verbs.h"]) opal_hwloc_openfabrics_include="hwloc/openfabrics-verbs.h"])
AC_DEFINE_UNQUOTED(MCA_hwloc_external_header, AC_DEFINE_UNQUOTED(MCA_hwloc_external_header,
["$opal_hwloc_include"], ["$opal_hwloc_include"],
[Location of external hwloc header]) [Location of external hwloc header])
AC_DEFINE_UNQUOTED(MCA_hwloc_external_shmem_header,
["$opal_hwloc_shmem_include"],
[Location of external hwloc shmem header])
AC_DEFINE_UNQUOTED(MCA_hwloc_external_openfabrics_header, AC_DEFINE_UNQUOTED(MCA_hwloc_external_openfabrics_header,
["$opal_hwloc_openfabrics_include"], ["$opal_hwloc_openfabrics_include"],
[Location of external hwloc OpenFabrics header]) [Location of external hwloc OpenFabrics header])

9
opal/mca/hwloc/external/external.h поставляемый
Просмотреть файл

@ -43,6 +43,15 @@ BEGIN_C_DECLS
# endif # endif
#endif #endif
#if defined(OPAL_HWLOC_WANT_SHMEM) && OPAL_HWLOC_WANT_SHMEM
# if HWLOC_API_VERSION >= 0x20000
# include MCA_hwloc_external_shmem_header
# endif
/* Do nothing in the 1.x case because the caller doesn't know HWLOC_API_VERSION when it sets OPAL_HWLOC_WANT_SHMEM.
* Calls to hwloc/shmem.h are protected by HWLOC_API_VERSION >= 0x20000 in the actual code.
*/
#endif
#if HWLOC_API_VERSION < 0x00010b00 #if HWLOC_API_VERSION < 0x00010b00
#define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE #define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE
#define HWLOC_OBJ_PACKAGE HWLOC_OBJ_SOCKET #define HWLOC_OBJ_PACKAGE HWLOC_OBJ_SOCKET

Просмотреть файл

@ -139,7 +139,6 @@ typedef uint8_t opal_hwloc_resource_type_t;
/* structs for storing info on objects */ /* structs for storing info on objects */
typedef struct { typedef struct {
opal_object_t super; opal_object_t super;
hwloc_cpuset_t available;
bool npus_calculated; bool npus_calculated;
unsigned int npus; unsigned int npus;
unsigned int idx; unsigned int idx;

Просмотреть файл

@ -30,16 +30,16 @@ EXTRA_DIST = \
SUBDIRS = hwloc SUBDIRS = hwloc
# Headers and sources # Headers and sources
headers = hwloc2a.h headers = hwloc201.h
sources = hwloc2a_component.c sources = hwloc201_component.c
# We only ever build this component statically # We only ever build this component statically
noinst_LTLIBRARIES = libmca_hwloc_hwloc2a.la noinst_LTLIBRARIES = libmca_hwloc_hwloc201.la
libmca_hwloc_hwloc2a_la_SOURCES = $(headers) $(sources) libmca_hwloc_hwloc201_la_SOURCES = $(headers) $(sources)
nodist_libmca_hwloc_hwloc2a_la_SOURCES = $(nodist_headers) nodist_libmca_hwloc_hwloc201_la_SOURCES = $(nodist_headers)
libmca_hwloc_hwloc2a_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc2a_LDFLAGS) libmca_hwloc_hwloc201_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc201_LDFLAGS)
libmca_hwloc_hwloc2a_la_LIBADD = $(opal_hwloc_hwloc2a_LIBS) libmca_hwloc_hwloc201_la_LIBADD = $(opal_hwloc_hwloc201_LIBS)
libmca_hwloc_hwloc2a_la_DEPENDENCIES = \ libmca_hwloc_hwloc201_la_DEPENDENCIES = \
$(HWLOC_top_builddir)/hwloc/libhwloc_embedded.la $(HWLOC_top_builddir)/hwloc/libhwloc_embedded.la
# Since the rest of the code base includes the underlying hwloc.h, we # Since the rest of the code base includes the underlying hwloc.h, we
@ -60,7 +60,6 @@ headers += \
hwloc/include/hwloc/helper.h \ hwloc/include/hwloc/helper.h \
hwloc/include/hwloc/inlines.h \ hwloc/include/hwloc/inlines.h \
hwloc/include/hwloc/intel-mic.h \ hwloc/include/hwloc/intel-mic.h \
hwloc/include/hwloc/myriexpress.h \
hwloc/include/hwloc/nvml.h \ hwloc/include/hwloc/nvml.h \
hwloc/include/hwloc/opencl.h \ hwloc/include/hwloc/opencl.h \
hwloc/include/hwloc/openfabrics-verbs.h \ hwloc/include/hwloc/openfabrics-verbs.h \

1
opal/mca/hwloc/hwloc201/README-ompi.txt Обычный файл
Просмотреть файл

@ -0,0 +1 @@
Cherry-picked commits after 2.0.1:

Просмотреть файл

@ -17,43 +17,43 @@
# #
# Priority # Priority
# #
AC_DEFUN([MCA_opal_hwloc_hwloc2a_PRIORITY], [90]) AC_DEFUN([MCA_opal_hwloc_hwloc201_PRIORITY], [90])
# #
# Force this component to compile in static-only mode # Force this component to compile in static-only mode
# #
AC_DEFUN([MCA_opal_hwloc_hwloc2a_COMPILE_MODE], [ AC_DEFUN([MCA_opal_hwloc_hwloc201_COMPILE_MODE], [
AC_MSG_CHECKING([for MCA component $2:$3 compile mode]) AC_MSG_CHECKING([for MCA component $2:$3 compile mode])
$4="static" $4="static"
AC_MSG_RESULT([$$4]) AC_MSG_RESULT([$$4])
]) ])
# Include hwloc m4 files # Include hwloc m4 files
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_pkg.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_pkg.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_check_attributes.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_check_attributes.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_check_visibility.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_check_visibility.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_check_vendor.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_check_vendor.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_components.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_components.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_internal.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_internal.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/netloc.m4) m4_include(opal/mca/hwloc/hwloc201/hwloc/config/netloc.m4)
# MCA_hwloc_hwloc2a_POST_CONFIG() # MCA_hwloc_hwloc201_POST_CONFIG()
# --------------------------------- # ---------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc2a_POST_CONFIG],[ AC_DEFUN([MCA_opal_hwloc_hwloc201_POST_CONFIG],[
OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc2a_basedir]) OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc201_basedir])
# If we won, then do all the rest of the setup # If we won, then do all the rest of the setup
AS_IF([test "$1" = "1" && test "$opal_hwloc_hwloc2a_support" = "yes"], AS_IF([test "$1" = "1" && test "$opal_hwloc_hwloc201_support" = "yes"],
[ [
# Set this variable so that the framework m4 knows what # Set this variable so that the framework m4 knows what
# file to include in opal/mca/hwloc/hwloc-internal.h # file to include in opal/mca/hwloc/hwloc-internal.h
opal_hwloc_hwloc2a_basedir=opal/mca/hwloc/hwloc2a opal_hwloc_hwloc201_basedir=opal/mca/hwloc/hwloc201
opal_hwloc_base_include="$opal_hwloc_hwloc2a_basedir/hwloc2a.h" opal_hwloc_base_include="$opal_hwloc_hwloc201_basedir/hwloc201.h"
# Add some stuff to CPPFLAGS so that the rest of the source # Add some stuff to CPPFLAGS so that the rest of the source
# tree can be built # tree can be built
file=$opal_hwloc_hwloc2a_basedir/hwloc file=$opal_hwloc_hwloc201_basedir/hwloc
CPPFLAGS="-I$OPAL_TOP_SRCDIR/$file/include $CPPFLAGS" CPPFLAGS="-I$OPAL_TOP_SRCDIR/$file/include $CPPFLAGS"
AS_IF([test "$OPAL_TOP_BUILDDIR" != "$OPAL_TOP_SRCDIR"], AS_IF([test "$OPAL_TOP_BUILDDIR" != "$OPAL_TOP_SRCDIR"],
[CPPFLAGS="-I$OPAL_TOP_BUILDDIR/$file/include $CPPFLAGS"]) [CPPFLAGS="-I$OPAL_TOP_BUILDDIR/$file/include $CPPFLAGS"])
@ -66,41 +66,41 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_POST_CONFIG],[
])dnl ])dnl
# MCA_hwloc_hwloc2a_CONFIG([action-if-found], [action-if-not-found]) # MCA_hwloc_hwloc201_CONFIG([action-if-found], [action-if-not-found])
# -------------------------------------------------------------------- # --------------------------------------------------------------------
AC_DEFUN([MCA_opal_hwloc_hwloc2a_CONFIG],[ AC_DEFUN([MCA_opal_hwloc_hwloc201_CONFIG],[
# Hwloc needs to know if we have Verbs support # Hwloc needs to know if we have Verbs support
AC_REQUIRE([OPAL_CHECK_VERBS_DIR]) AC_REQUIRE([OPAL_CHECK_VERBS_DIR])
AC_CONFIG_FILES([opal/mca/hwloc/hwloc2a/Makefile]) AC_CONFIG_FILES([opal/mca/hwloc/hwloc201/Makefile])
OPAL_VAR_SCOPE_PUSH([HWLOC_VERSION opal_hwloc_hwloc2a_save_CPPFLAGS opal_hwloc_hwloc2a_save_LDFLAGS opal_hwloc_hwloc2a_save_LIBS opal_hwloc_hwloc2a_save_cairo opal_hwloc_hwloc2a_save_xml opal_hwloc_hwloc2a_save_mode opal_hwloc_hwloc2a_basedir opal_hwloc_hwloc2a_file opal_hwloc_hwloc2a_save_cflags CPPFLAGS_save LIBS_save opal_hwloc_external]) OPAL_VAR_SCOPE_PUSH([HWLOC_VERSION opal_hwloc_hwloc201_save_CPPFLAGS opal_hwloc_hwloc201_save_LDFLAGS opal_hwloc_hwloc201_save_LIBS opal_hwloc_hwloc201_save_cairo opal_hwloc_hwloc201_save_xml opal_hwloc_hwloc201_save_mode opal_hwloc_hwloc201_basedir opal_hwloc_hwloc201_file opal_hwloc_hwloc201_save_cflags CPPFLAGS_save LIBS_save opal_hwloc_external])
# default to this component not providing support # default to this component not providing support
opal_hwloc_hwloc2a_basedir=opal/mca/hwloc/hwloc2a opal_hwloc_hwloc201_basedir=opal/mca/hwloc/hwloc201
opal_hwloc_hwloc2a_support=no opal_hwloc_hwloc201_support=no
AS_IF([test "$with_hwloc" = "internal" || test -z "$with_hwloc" || test "$with_hwloc" = "yes"], AS_IF([test "$with_hwloc" = "internal" || test -z "$with_hwloc" || test "$with_hwloc" = "yes"],
[opal_hwloc_external="no"], [opal_hwloc_external="no"],
[opal_hwloc_external="yes"]) [opal_hwloc_external="yes"])
opal_hwloc_hwloc2a_save_CPPFLAGS=$CPPFLAGS opal_hwloc_hwloc201_save_CPPFLAGS=$CPPFLAGS
opal_hwloc_hwloc2a_save_LDFLAGS=$LDFLAGS opal_hwloc_hwloc201_save_LDFLAGS=$LDFLAGS
opal_hwloc_hwloc2a_save_LIBS=$LIBS opal_hwloc_hwloc201_save_LIBS=$LIBS
# Run the hwloc configuration - if no external hwloc, then set the prefixi # Run the hwloc configuration - if no external hwloc, then set the prefixi
# to minimize the chance that someone will use the internal symbols # to minimize the chance that someone will use the internal symbols
AS_IF([test "$opal_hwloc_external" = "no" && AS_IF([test "$opal_hwloc_external" = "no" &&
test "$with_hwloc" != "future"], test "$with_hwloc" != "future"],
[HWLOC_SET_SYMBOL_PREFIX([opal_hwloc2a_])]) [HWLOC_SET_SYMBOL_PREFIX([opal_hwloc201_])])
# save XML or graphical options # save XML or graphical options
opal_hwloc_hwloc2a_save_cairo=$enable_cairo opal_hwloc_hwloc201_save_cairo=$enable_cairo
opal_hwloc_hwloc2a_save_xml=$enable_xml opal_hwloc_hwloc201_save_xml=$enable_xml
opal_hwloc_hwloc2a_save_static=$enable_static opal_hwloc_hwloc201_save_static=$enable_static
opal_hwloc_hwloc2a_save_shared=$enable_shared opal_hwloc_hwloc201_save_shared=$enable_shared
opal_hwloc_hwloc2a_save_plugins=$enable_plugins opal_hwloc_hwloc201_save_plugins=$enable_plugins
opal_hwloc_hwloc2a_save_mode=$hwloc_mode opal_hwloc_hwloc201_save_mode=$hwloc_mode
# never enable hwloc's graphical option # never enable hwloc's graphical option
enable_cairo=no enable_cairo=no
@ -131,22 +131,22 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_CONFIG],[
# hwloc checks for compiler visibility, and its needs to do # hwloc checks for compiler visibility, and its needs to do
# this without "picky" flags. # this without "picky" flags.
opal_hwloc_hwloc2a_save_cflags=$CFLAGS opal_hwloc_hwloc201_save_cflags=$CFLAGS
CFLAGS=$OPAL_CFLAGS_BEFORE_PICKY CFLAGS=$OPAL_CFLAGS_BEFORE_PICKY
AS_IF([test -n "$opal_datatype_cuda_CPPFLAGS"], AS_IF([test -n "$opal_datatype_cuda_CPPFLAGS"],
[CPPFLAGS="$CPPFLAGS $opal_datatype_cuda_CPPFLAGS"]) [CPPFLAGS="$CPPFLAGS $opal_datatype_cuda_CPPFLAGS"])
HWLOC_SETUP_CORE([opal/mca/hwloc/hwloc2a/hwloc], HWLOC_SETUP_CORE([opal/mca/hwloc/hwloc201/hwloc],
[AC_MSG_CHECKING([whether hwloc configure succeeded]) [AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([yes]) AC_MSG_RESULT([yes])
HWLOC_VERSION="internal v`$srcdir/$opal_hwloc_hwloc2a_basedir/hwloc/config/hwloc_get_version.sh $srcdir/$opal_hwloc_hwloc2a_basedir/hwloc/VERSION`" HWLOC_VERSION="internal v`$srcdir/$opal_hwloc_hwloc201_basedir/hwloc/config/hwloc_get_version.sh $srcdir/$opal_hwloc_hwloc201_basedir/hwloc/VERSION`"
# Build flags for our Makefile.am # Build flags for our Makefile.am
opal_hwloc_hwloc2a_LDFLAGS='$(HWLOC_EMBEDDED_LDFLAGS)' opal_hwloc_hwloc201_LDFLAGS='$(HWLOC_EMBEDDED_LDFLAGS)'
opal_hwloc_hwloc2a_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_hwloc_hwloc2a_basedir"'/hwloc/hwloc/libhwloc_embedded.la $(HWLOC_EMBEDDED_LIBS)' opal_hwloc_hwloc201_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_hwloc_hwloc201_basedir"'/hwloc/hwloc/libhwloc_embedded.la $(HWLOC_EMBEDDED_LIBS)'
opal_hwloc_hwloc2a_support=yes opal_hwloc_hwloc201_support=yes
AC_DEFINE_UNQUOTED([HWLOC_HWLOC2a_HWLOC_VERSION], AC_DEFINE_UNQUOTED([HWLOC_HWLOC201_HWLOC_VERSION],
["$HWLOC_VERSION"], ["$HWLOC_VERSION"],
[Version of hwloc]) [Version of hwloc])
@ -159,35 +159,35 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_CONFIG],[
], ],
[AC_MSG_CHECKING([whether hwloc configure succeeded]) [AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([no]) AC_MSG_RESULT([no])
opal_hwloc_hwloc2a_support=no]) opal_hwloc_hwloc201_support=no])
CFLAGS=$opal_hwloc_hwloc2a_save_cflags CFLAGS=$opal_hwloc_hwloc201_save_cflags
# Restore some env variables, if necessary # Restore some env variables, if necessary
AS_IF([test -n "$opal_hwloc_hwloc2a_save_cairo"], AS_IF([test -n "$opal_hwloc_hwloc201_save_cairo"],
[enable_cairo=$opal_hwloc_hwloc2a_save_cairo]) [enable_cairo=$opal_hwloc_hwloc201_save_cairo])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_xml"], AS_IF([test -n "$opal_hwloc_hwloc201_save_xml"],
[enable_xml=$opal_hwloc_hwloc2a_save_xml]) [enable_xml=$opal_hwloc_hwloc201_save_xml])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_static"], AS_IF([test -n "$opal_hwloc_hwloc201_save_static"],
[enable_static=$opal_hwloc_hwloc2a_save_static]) [enable_static=$opal_hwloc_hwloc201_save_static])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_shared"], AS_IF([test -n "$opal_hwloc_hwloc201_save_shared"],
[enable_shared=$opal_hwloc_hwloc2a_save_shared]) [enable_shared=$opal_hwloc_hwloc201_save_shared])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_plugins"], AS_IF([test -n "$opal_hwloc_hwloc201_save_plugins"],
[enable_plugins=$opal_hwloc_hwloc2a_save_shared]) [enable_plugins=$opal_hwloc_hwloc201_save_shared])
CPPFLAGS=$opal_hwloc_hwloc2a_save_CPPFLAGS CPPFLAGS=$opal_hwloc_hwloc201_save_CPPFLAGS
LDFLAGS=$opal_hwloc_hwloc2a_save_LDFLAGS LDFLAGS=$opal_hwloc_hwloc201_save_LDFLAGS
LIBS=$opal_hwloc_hwloc2a_save_LIBS LIBS=$opal_hwloc_hwloc201_save_LIBS
AC_SUBST([opal_hwloc_hwloc2a_CFLAGS]) AC_SUBST([opal_hwloc_hwloc201_CFLAGS])
AC_SUBST([opal_hwloc_hwloc2a_CPPFLAGS]) AC_SUBST([opal_hwloc_hwloc201_CPPFLAGS])
AC_SUBST([opal_hwloc_hwloc2a_LDFLAGS]) AC_SUBST([opal_hwloc_hwloc201_LDFLAGS])
AC_SUBST([opal_hwloc_hwloc2a_LIBS]) AC_SUBST([opal_hwloc_hwloc201_LIBS])
# Finally, add some flags to the wrapper compiler so that our # Finally, add some flags to the wrapper compiler so that our
# headers can be found. # headers can be found.
hwloc_hwloc2a_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS" hwloc_hwloc201_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS"
hwloc_hwloc2a_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS" hwloc_hwloc201_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS"
hwloc_hwloc2a_WRAPPER_EXTRA_CPPFLAGS='-I${pkgincludedir}/'"$opal_hwloc_hwloc2a_basedir/hwloc/include" hwloc_hwloc201_WRAPPER_EXTRA_CPPFLAGS='-I${pkgincludedir}/'"$opal_hwloc_hwloc201_basedir/hwloc/include"
# If we are not building the internal hwloc, then indicate that # If we are not building the internal hwloc, then indicate that
# this component should not be built. NOTE: we still did all the # this component should not be built. NOTE: we still did all the
@ -197,12 +197,12 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_CONFIG],[
# distclean" infrastructure to work properly). # distclean" infrastructure to work properly).
AS_IF([test "$opal_hwloc_external" = "yes"], AS_IF([test "$opal_hwloc_external" = "yes"],
[AC_MSG_WARN([using an external hwloc; disqualifying this component]) [AC_MSG_WARN([using an external hwloc; disqualifying this component])
opal_hwloc_hwloc2a_support=no], opal_hwloc_hwloc201_support=no],
[AC_DEFINE([HAVE_DECL_HWLOC_OBJ_OSDEV_COPROC], [1]) [AC_DEFINE([HAVE_DECL_HWLOC_OBJ_OSDEV_COPROC], [1])
AC_DEFINE([HAVE_HWLOC_TOPOLOGY_DUP], [1])]) AC_DEFINE([HAVE_HWLOC_TOPOLOGY_DUP], [1])])
# Done! # Done!
AS_IF([test "$opal_hwloc_hwloc2a_support" = "yes"], AS_IF([test "$opal_hwloc_hwloc201_support" = "yes"],
[$1], [$1],
[$2]) [$2])

Просмотреть файл

@ -1,29 +1,44 @@
netloc Authors hwloc Authors
============== =============
The following cumulative list contains the names of most individuals who The following cumulative list contains the names of most individuals
have committed code to the hwloc repository. who have committed code to the hwloc repository
(either directly or through a third party).
Name Affiliation(s) Name Affiliation(s)
--------------------------- -------------------- --------------------------- --------------------
Grzegorz Andrejczuk Intel
Cédric Augonnet University of Bordeaux Cédric Augonnet University of Bordeaux
Guillaume Beauchamp Inria Guillaume Beauchamp Inria
Ahmad Boissetri Binzagr Inria Ahmad Boissetri Binzagr Inria
Cyril Bordage Inria Cyril Bordage Inria
Nicholas Buroker UWL Nicholas Buroker UWL
Christopher M. Cantalupo Intel
Jérôme Clet-Ortega University of Bordeaux Jérôme Clet-Ortega University of Bordeaux
Ludovic Courtès Inria Ludovic Courtès Inria
Clément Foyer Inria
Nathalie Furmento CNRS Nathalie Furmento CNRS
Bryon Gloden
Brice Goglin Inria Brice Goglin Inria
Gilles Gouaillardet RIST
Joshua Hursey UWL Joshua Hursey UWL
Alexey Kardashevskiy IBM Alexey Kardashevskiy IBM
Rob Latham ANL
Douglas MacFarland UWL Douglas MacFarland UWL
Marc Marí BSC
Jonathan L Peyton Intel
Piotr Luc Intel
Antoine Rougier intern from University of Bordeaux Antoine Rougier intern from University of Bordeaux
Jeff Squyres Cisco Jeff Squyres Cisco
Samuel Thibault University of Bordeaux Samuel Thibault University of Bordeaux
Jean-Yves VET DDN
Benjamin Worpitz
Jeff Zhao Zhaoxin
Affiliaion abbreviations: Affiliaion abbreviations:
------------------------- -------------------------
ANL = Argonne National Lab
BSC = Barcelona Supercomputing Center
Cisco = Cisco Systems, Inc. Cisco = Cisco Systems, Inc.
CNRS = Centre national de la recherche scientifique (France) CNRS = Centre national de la recherche scientifique (France)
UWL = University of Wisconsin-La Crosse UWL = University of Wisconsin-La Crosse

93
opal/mca/hwloc/hwloc201/hwloc/Makefile.am Обычный файл
Просмотреть файл

@ -0,0 +1,93 @@
# Copyright © 2009-2018 Inria. All rights reserved.
# Copyright © 2009 Université Bordeaux
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# See COPYING in top-level directory.
# Note that the -I directory must *exactly* match what was specified
# via AC_CONFIG_MACRO_DIR in configure.ac.
ACLOCAL_AMFLAGS = -I ./config
#
# "make distcheck" requires that tarballs are able to be able to "make
# dist", so we have to include config/distscript.sh.
#
EXTRA_DIST = \
README VERSION COPYING AUTHORS \
config/hwloc_get_version.sh \
config/distscript.sh
SUBDIRS = include hwloc
if HWLOC_BUILD_STANDALONE
if BUILD_NETLOC
SUBDIRS += netloc
endif
SUBDIRS += utils tests contrib/systemd contrib/misc
# We need doc/ if HWLOC_BUILD_DOXYGEN, or during make install if HWLOC_INSTALL_DOXYGEN.
# There's no INSTALL_SUBDIRS, so always enter doc/ and check HWLOC_BUILD/INSTALL_DOXYGEN there
SUBDIRS += doc
endif
# Do not let automake automatically add the non-standalone dirs to the
# distribution tarball if we're building in embedded mode.
DIST_SUBDIRS = $(SUBDIRS)
if HWLOC_BUILD_STANDALONE
if !BUILD_NETLOC
DIST_SUBDIRS += netloc
endif
endif
# Only install the pkg file if we're building in standalone mode (and not on Windows)
if HWLOC_BUILD_STANDALONE
hwlocpkgconfigdir = $(libdir)/pkgconfig
hwlocpkgconfig_DATA = hwloc.pc
if BUILD_NETLOC
# JMS Need to compare hwloc.pc and netloc.pc -- I think netloc.pc is
# missing some things.
# pkgconfig_DATA += netloc.pc Disabled until the netloc API is public
EXTRA_DIST += netloc.pc
if BUILD_NETLOCSCOTCH
hwlocpkgconfig_DATA += netlocscotch.pc
endif BUILD_NETLOCSCOTCH
endif BUILD_NETLOC
endif HWLOC_BUILD_STANDALONE
# Only install the valgrind suppressions file if we're building in
# standalone mode
if HWLOC_BUILD_STANDALONE
dist_pkgdata_DATA = contrib/hwloc-valgrind.supp
endif
# Only install entire visual studio subdirectory if we're building in
# standalone mode
if HWLOC_BUILD_STANDALONE
EXTRA_DIST += contrib/windows
endif
if HWLOC_BUILD_STANDALONE
dist-hook:
sh "$(top_srcdir)/config/distscript.sh" "$(top_srcdir)" "$(distdir)" "$(HWLOC_VERSION)"
endif HWLOC_BUILD_STANDALONE
if HWLOC_BUILD_STANDALONE
if HWLOC_HAVE_WINDOWS
#
# Winball specific rules
#
install-data-local:
sed -e 's/$$/'$$'\015'/ < $(srcdir)/README > $(DESTDIR)$(prefix)/README.txt
sed -e 's/$$/'$$'\015'/ < $(srcdir)/NEWS > $(DESTDIR)$(prefix)/NEWS.txt
sed -e 's/$$/'$$'\015'/ < $(srcdir)/COPYING > $(DESTDIR)$(prefix)/COPYING.txt
uninstall-local:
rm -f $(DESTDIR)$(prefix)/README.txt $(DESTDIR)$(prefix)/NEWS.txt $(DESTDIR)$(prefix)/COPYING.txt
endif HWLOC_HAVE_WINDOWS
endif HWLOC_BUILD_STANDALONE
#
# Build the documenation and top-level README file
#
if HWLOC_BUILD_STANDALONE
.PHONY: doc readme
doc readme:
$(MAKE) -C doc
endif HWLOC_BUILD_STANDALONE

Просмотреть файл

@ -1,5 +1,5 @@
Copyright © 2009 CNRS Copyright © 2009 CNRS
Copyright © 2009-2017 Inria. All rights reserved. Copyright © 2009-2018 Inria. All rights reserved.
Copyright © 2009-2013 Université Bordeaux Copyright © 2009-2013 Université Bordeaux
Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
@ -17,116 +17,196 @@ bug fixes (and other actions) for each version of hwloc since version
in v0.9.1). in v0.9.1).
Version 2.0.1 (also included in 1.11.10 when relevant)
-------------
* Bump the library soname to 15:0:0 to avoid conflicts with hwloc 1.11.x
releases. The hwloc 2.0.0 soname was buggy (12:0:0), applications will
have to be recompiled.
* Serialize pciaccess discovery to fix concurrent topology loads in
multiple threads.
* Fix hwloc-dump-hwdata to only process SMBIOS information that correspond
to the KNL and KNM configuration.
* Add a heuristic for guessing KNL/KNM memory and cluster modes when
hwloc-dump-hwdata could not run as root earlier.
* Add --no-text lstopo option to remove text from some boxes in the
graphical output. Mostly useful for removing Group labels.
* Some minor fixes to memory binding.
Version 2.0.0 Version 2.0.0
------------- -------------
* The ABI of the library has changed. For instance some hwloc_obj fields *** The ABI of the library has changed. ***
were reordered. For instance some hwloc_obj fields were reordered, added or removed, see below.
- HWLOC_API_VERSION and hwloc_get_api_version() now give 0x00020000. + HWLOC_API_VERSION and hwloc_get_api_version() now give 0x00020000.
- See "How do I handle ABI breaks and API upgrades ?" in the FAQ + See "How do I handle ABI breaks and API upgrades ?" in the FAQ
and https://github.com/open-mpi/hwloc/wiki/Upgrading-to-v2.0-API and "Upgrading to hwloc 2.0 API" in the documentation.
* Major changes * Major API changes
+ Memory, I/O and Misc objects are now stored in dedicated children lists,
not in the usual children list that is now only used for CPU-side objects.
- hwloc_get_next_child() may still be used to iterate over these 4 lists
of children at once.
- hwloc_obj_type_is_normal(), _memory() and _io() may be used to check
the kind of a given object type.
+ Topologies always have at least one NUMA object. On non-NUMA machines, + Topologies always have at least one NUMA object. On non-NUMA machines,
a single NUMA object is added to describe the entire machine memory. a single NUMA object is added to describe the entire machine memory.
The NUMA level cannot be ignored anymore. The NUMA level cannot be ignored anymore.
+ The NUMA level is special since NUMA nodes are not in the main hierarchy
of objects anymore. Its depth is a fake negative depth that should not be
compared with normal levels.
- If all memory objects are attached to parents at the same depth,
it may be retrieved with hwloc_get_memory_parents_depth().
+ The HWLOC_OBJ_CACHE type is replaced with 8 types HWLOC_OBJ_L[1-5]CACHE + The HWLOC_OBJ_CACHE type is replaced with 8 types HWLOC_OBJ_L[1-5]CACHE
and HWLOC_OBJ_L[1-3]ICACHE that remove the need to disambiguate levels and HWLOC_OBJ_L[1-3]ICACHE that remove the need to disambiguate levels
when looking for caches with _by_type() functions. when looking for caches with _by_type() functions.
- New hwloc_obj_type_is_{,d,i}cache() functions may be used to check whether - New hwloc_obj_type_is_{,d,i}cache() functions may be used to check whether
a given type is a cache. a given type is a cache.
+ Replace hwloc_topology_ignore*() functions with hwloc_topology_set_type_filter() + Reworked ignoring/filtering API
and hwloc_topology_set_all_types_filter(). - Replace hwloc_topology_ignore*() functions with hwloc_topology_set_type_filter()
- Contrary to hwloc_topology_ignore_{type,all}_keep_structure() which and hwloc_topology_set_all_types_filter().
removed individual objects, HWLOC_TYPE_FILTER_KEEP_STRUCTURE only removes . Contrary to hwloc_topology_ignore_{type,all}_keep_structure() which
entire levels (so that topology do not become too asymmetric). removed individual objects, HWLOC_TYPE_FILTER_KEEP_STRUCTURE only removes
+ Remove HWLOC_TOPOLOGY_FLAG_ICACHES in favor of hwloc_topology_set_icache_types_filter() entire levels (so that topology do not become too asymmetric).
with HWLOC_TYPE_FILTER_KEEP_ALL. - Remove HWLOC_TOPOLOGY_FLAG_ICACHES in favor of hwloc_topology_set_icache_types_filter()
+ Remove HWLOC_TOPOLOGY_FLAG_IO_DEVICES, _IO_BRIDGES and _WHOLE_IO in favor of with HWLOC_TYPE_FILTER_KEEP_ALL.
hwloc_topology_set_io_types_filter() with HWLOC_TYPE_FILTER_KEEP_ALL or - Remove HWLOC_TOPOLOGY_FLAG_IO_DEVICES, _IO_BRIDGES and _WHOLE_IO in favor of
HWLOC_TYPE_FILTER_KEEP_IMPORTANT. hwloc_topology_set_io_types_filter() with HWLOC_TYPE_FILTER_KEEP_ALL or
HWLOC_TYPE_FILTER_KEEP_IMPORTANT.
+ The distance API has been completely reworked. It is now described
in hwloc/distances.h.
+ Return values
- Most functions in hwloc/bitmap.h now return an int that may be negative
in case of failure to realloc/extend the internal storage of a bitmap.
- hwloc_obj_add_info() also returns an int in case allocations fail.
* Minor API changes
+ Object attributes
- obj->memory is removed.
. local_memory and page_types attributes are now in obj->attr->numanode
. total_memory moves obj->total_memory.
- Objects do not have allowed_cpuset and allowed_nodeset anymore.
They are only available for the entire topology using
hwloc_topology_get_allowed_cpuset() and hwloc_topology_get_allowed_nodeset().
- Objects now have a "subtype" field that supersedes former "Type" and
"CoProcType" info attributes.
+ Object and level depths are now signed ints.
+ Object string printing and parsing
- hwloc_type_sscanf() deprecates the old hwloc_obj_type_sscanf().
- hwloc_type_sscanf_as_depth() is added to convert a type name into
a level depth.
- hwloc_obj_cpuset_snprintf() is deprecated in favor of hwloc_bitmap_snprintf().
+ Misc objects
- Replace hwloc_topology_insert_misc_object_by_cpuset() with
hwloc_topology_insert_group_object() to precisely specify the location
of an additional hierarchy level in the topology.
- Misc objects have their own level and depth to iterate over all of them.
- Misc objects may now only be inserted as a leaf object with
hwloc_topology_insert_misc_object() which deprecates
hwloc_topology_insert_misc_object_by_parent().
+ hwloc_topology_restrict() doesn't remove objects that contain memory + hwloc_topology_restrict() doesn't remove objects that contain memory
by default anymore. by default anymore.
- The list of existing restrict flags was modified. - The list of existing restrict flags was modified.
+ The discovery support array now contains some NUMA specific bits.
+ XML export functions take an additional flags argument, + XML export functions take an additional flags argument,
for instance for exporting XMLs that are compatible with hwloc 1.x. for instance for exporting XMLs that are compatible with hwloc 1.x.
+ The distance API has been completely reworked. It is now described
in hwloc/distances.h.
+ Add hwloc/shmem.h for sharing topologies between processes running on
the same machine (for reducing the memory footprint).
+ Add the experimental netloc subproject. It is enabled by default when
supported and can be disabled with --disable-netloc.
It currently brings command-line tools to gather and visualize the
topology of InfiniBand fabrics, and an API to convert such topologies
into Scotch architectures for process mapping.
See the documentation for details.
+ Remove the online_cpuset from struct hwloc_obj. Offline PUs get unknown
topologies on Linux nowadays, and wrong topology on Solaris. Other OS
do not support them. And one cannot do much about them anyway. Just keep
them in complete_cpuset.
+ Remove the custom interface for assembling the topologies of different
nodes as well as the hwloc-assembler tools.
+ Remove Kerrighed support from the Linux backend.
+ Remove Tru64 (OSF/1) support.
- Remove HWLOC_MEMBIND_REPLICATE which wasn't available anywhere else.
* API
+ Objects now have a "subtype" field that supersedes former "Type" and
"CoProcType" info attributes.
+ The almost-unused "os_level" attribute has been removed from the
hwloc_obj structure.
+ I/O and Misc objects are now stored in a dedicated children list, only
normal children with non-NULL cpusets and nodesets are in the main
children list.
- hwloc_get_next_child() may still be used to iterate over these 3 lists
of children at once.
+ Replace hwloc_topology_insert_misc_object_by_cpuset() with
hwloc_topology_insert_group_object() to precisely specify the location
of an additional hierarchy level in the topology.
+ Misc objects have their own level and depth to iterate over all of them.
+ Misc objects may now only be inserted as a leaf object with
hwloc_topology_insert_misc_object() which deprecates
hwloc_topology_insert_misc_object_by_parent().
+ hwloc_topology_set_fsroot() is removed, the environment variable
HWLOC_FSROOT may be used for the same remote testing/debugging purpose.
+ hwloc_type_sscanf() deprecates the old hwloc_obj_type_sscanf().
+ hwloc_type_sscanf_as_depth() is added to convert a type name into
a level depth.
+ hwloc_type_name() deprecates the old hwloc_obj_type_string().
+ Remove the deprecated hwloc_obj_snprintf(), hwloc_obj_type_of_string(),
hwloc_distribute[v]().
+ hwloc_obj_cpuset_snprintf() is deprecated in favor of hwloc_bitmap_snprintf().
+ Functions diff_load_xml*(), diff_export_xml*() and diff_destroy() in + Functions diff_load_xml*(), diff_export_xml*() and diff_destroy() in
hwloc/diff.h do not need a topology as first parameter anymore. hwloc/diff.h do not need a topology as first parameter anymore.
+ hwloc_parse_cpumap_file () superseded by hwloc_linux_read_path_as_cpumask() + hwloc_parse_cpumap_file () superseded by hwloc_linux_read_path_as_cpumask()
in hwloc/linux.h. in hwloc/linux.h.
+ HWLOC_MEMBIND_DEFAULT and HWLOC_MEMBIND_FIRSTTOUCH were clarified.
* New APIs and Features
+ Add hwloc/shmem.h for sharing topologies between processes running on
the same machine (for reducing the memory footprint).
+ Add the experimental netloc subproject. It is disabled by default
and can be enabled with --enable-netloc.
It currently brings command-line tools to gather and visualize the
topology of InfiniBand fabrics, and an API to convert such topologies
into Scotch architectures for process mapping.
See the documentation for details.
* Removed APIs and features
+ Remove the online_cpuset from struct hwloc_obj. Offline PUs get unknown
topologies on Linux nowadays, and wrong topology on Solaris. Other OS
do not support them. And one cannot do much about them anyway. Just keep
them in complete_cpuset.
+ Remove the now-unused "System" object type HWLOC_OBJ_SYSTEM,
defined to MACHINE for backward compatibility.
+ The almost-unused "os_level" attribute has been removed from the
hwloc_obj structure.
+ Remove the custom interface for assembling the topologies of different
nodes as well as the hwloc-assembler tools.
+ hwloc_topology_set_fsroot() is removed, the environment variable
HWLOC_FSROOT may be used for the same remote testing/debugging purpose.
+ Remove the deprecated hwloc_obj_snprintf(), hwloc_obj_type_of_string(),
hwloc_distribute[v]().
* Remove Myrinet Express interoperability (hwloc/myriexpress.h).
+ Remove Kerrighed support from the Linux backend.
+ Remove Tru64 (OSF/1) support.
- Remove HWLOC_MEMBIND_REPLICATE which wasn't available anywhere else.
* Backend improvements
+ Linux
- OS devices do not have to be attached through PCI anymore,
for instance enabling the discovery of NVDIMM block devices.
- Remove the dependency on libnuma.
- Add a SectorSize attribute to block OS devices.
+ Mac OS X
- Fix detection of cores and hyperthreads.
- Add CPUVendor, Model, ... attributes.
+ Windows
- Add get_area_memlocation().
* Tools * Tools
- lstopo and hwloc-info have a new --filter option matching the new filtering API. + lstopo and hwloc-info have a new --filter option matching the new filtering API.
- hwloc-distances was removed and replaced with lstopo --distances. + lstopo can be given --children-layout=plain to force a basic displaying
* Plugin API of memory and normal children together below their parent.
+ hwloc_fill_object_sets() is renamed into hwloc_obj_add_children_sets(). + hwloc-distances was removed and replaced with lstopo --distances.
* Misc * Misc
+ Linux OS devices do not have to be attached through PCI anymore, + Exports
for instance enabling the discovery of NVDIMM block devices. - Exporting to synthetic now ignores I/O and Misc objects.
+ Add a SectorSize attribute to block OS devices on Linux. + PCI discovery
+ Misc MemoryModule objects are only added when full I/O discovery is enabled - Separate OS device discovery from PCI discovery. Only the latter is disabled
(WHOLE_IO topology flag). with --disable-pci at configure time. Both may be disabled with --disable-io.
+ Do not set PCI devices and bridges name automatically. Vendor and device - The `linuxpci' component is now renamed into `linuxio'.
names are already in info attributes. - The old `libpci' component name from hwloc 1.6 is not supported anymore,
+ Exporting to synthetic now ignores I/O and Misc objects. only the `pci' name from hwloc 1.7 is now recognized.
+ XML and Synthetic export functions have moved to hwloc/export.h, - The HWLOC_PCI_<domain>_<bus>_LOCALCPUS environment variables are superseded
automatically included from hwloc.h. with a single HWLOC_PCI_LOCALITY where bus ranges may be specified.
+ Separate OS device discovery from PCI discovery. Only the latter is disabled - Do not set PCI devices and bridges name automatically. Vendor and device
with --disable-pci at configure time. Both may be disabled with --disable-io. names are already in info attributes.
+ The old `libpci' component name from hwloc 1.6 is not supported anymore, + Components and discovery
only the `pci' name from hwloc 1.7 is now recognized. - Add HWLOC_SYNTHETIC environment variable to enforce a synthetic topology
+ The `linuxpci' component is now renamed into `linuxio'. as if hwloc_topology_set_synthetic() had been called.
+ The HWLOC_PCI_<domain>_<bus>_LOCALCPUS environment variables are superseded - HWLOC_COMPONENTS doesn't support xml or synthetic component attributes
with a single HWLOC_PCI_LOCALITY where bus ranges may be specified. anymore, they should be passed in HWLOC_XMLFILE or HWLOC_SYNTHETIC instead.
+ Add HWLOC_SYNTHETIC environment variable to enforce a synthetic topology - HWLOC_COMPONENTS takes precedence over other environment variables
as if hwloc_topology_set_synthetic() had been called. for selecting components.
+ HWLOC_COMPONENTS doesn't support xml or synthetic component attributes + hwloc now requires a C99 compliant compiler.
anymore, they should be passed in HWLOC_XMLFILE or HWLOC_SYNTHETIC instead.
+ HWLOC_COMPONENTS takes precedence over other environment variables
for selecting components. Version 1.11.9
+ Remove the dependency on libnuma on Linux. --------------
* Add support for Zhaoxin ZX-C and ZX-D processors in the x86 backend,
thanks to Jeff Zhao for the patch.
* Fix AMD Epyc 24-core L3 cache locality in the x86 backend.
* Don't crash in the x86 backend when the CPUID vendor string is unknown.
* Fix the missing pu discovery support bit on some OS.
* Fix the management of the lstopoStyle info attribute for custom colors.
* Add verbose warnings when failing to load hwloc v2.0+ XMLs.
Version 1.11.8
--------------
* Multiple Solaris improvements, thanks to Maureen Chew for the help:
+ Detect caches on Sparc.
+ Properly detect allowed/disallowed PUs and NUMA nodes with processor sets.
+ Add hwloc_get_last_cpu_location() support for the current thread.
* Add support for CUDA compute capability 7.0 and fix support for 6.[12].
* Tools improvements
+ Fix search for objects by physical index in command-line tools.
+ Add missing "cpubind:get_thisthread_last_cpu_location" in the output
of hwloc-info --support.
+ Add --pid and --name to specify target processes in hwloc-ps.
+ Display thread names in lstopo and hwloc-ps on Linux.
* Doc improvements
+ Add a FAQ entry about building on Windows.
+ Install missing sub-manpage for hwloc_obj_add_info() and
hwloc_obj_get_info_by_name().
Version 1.11.7 Version 1.11.7

Просмотреть файл

@ -11,12 +11,15 @@ platforms.
hwloc is actually made of two subprojects distributed together: hwloc is actually made of two subprojects distributed together:
* The original hwloc project for describing the internals of computing nodes. * The original hwloc project for describing the internals of computing nodes.
It is described in details between sections Hardware Locality (hwloc) It is described in details starting at section Hardware Locality (hwloc)
Introduction and Network Locality (netloc). Introduction.
* The network-oriented companion called netloc (Network Locality), described * The network-oriented companion called netloc (Network Locality), described
in details starting at section Network Locality (netloc). Netloc may be in details starting with section Network Locality (netloc).
disabled, but the original hwloc cannot. Both hwloc and netloc APIs are
documented after these sections. See also the Related pages tab above for links to other sections.
Netloc may be disabled, but the original hwloc cannot. Both hwloc and netloc
APIs are documented after these sections.
Installation Installation
@ -26,17 +29,9 @@ www.open-mpi.org/). Note that hwloc does not require any functionality from
Open MPI -- it is a wholly separate (and much smaller!) project and code base. Open MPI -- it is a wholly separate (and much smaller!) project and code base.
It just happens to be hosted as part of the overall Open MPI project. It just happens to be hosted as part of the overall Open MPI project.
Nightly development snapshots are available on the web site. Additionally, the Basic Installation
code can be directly cloned from Git:
shell$ git clone https://github.com/open-mpi/hwloc.git Installation is the fairly common GNU-based process:
shell$ cd hwloc
shell$ ./autogen.sh
Note that GNU Autoconf >=2.63, Automake >=1.11 and Libtool >=2.2.6 are required
when building from a Git clone.
Installation by itself is the fairly common GNU-based process:
shell$ ./configure --prefix=... shell$ ./configure --prefix=...
shell$ make shell$ make
@ -60,6 +55,31 @@ Running the "lstopo" tool is a good way to check as a graphical output whether
hwloc properly detected the architecture of your node. Netloc command-line hwloc properly detected the architecture of your node. Netloc command-line
tools can be used to display the network topology interconnecting your nodes. tools can be used to display the network topology interconnecting your nodes.
Installing from a Git clone
Additionally, the code can be directly cloned from Git:
shell$ git clone https://github.com/open-mpi/hwloc.git
shell$ cd hwloc
shell$ ./autogen.sh
Note that GNU Autoconf >=2.63, Automake >=1.11 and Libtool >=2.2.6 are required
when building from a Git clone.
Nightly development snapshots are available on the web site, they can be
configured and built without any need for Git or GNU Autotools.
Questions and Bugs
Bugs should be reported in the tracker (https://github.com/open-mpi/hwloc/
issues). Opening a new issue automatically displays lots of hints about how to
debug and report issues.
Questions may be sent to the users or developers mailing lists (http://
www.open-mpi.org/community/lists/hwloc.php).
There is also a #hwloc IRC channel on Freenode (irc.freenode.net).
See https://www.open-mpi.org/projects/hwloc/doc/ for more hwloc documentation. See https://www.open-mpi.org/projects/hwloc/doc/ for more hwloc documentation.

Просмотреть файл

@ -9,7 +9,7 @@
major=2 major=2
minor=0 minor=0
release=0 release=2
# greek is used for alpha or beta release tags. If it is non-empty, # greek is used for alpha or beta release tags. If it is non-empty,
# it will be appended to the version number. It does not have to be # it will be appended to the version number. It does not have to be
@ -18,7 +18,7 @@ release=0
# requirement is that it must be entirely printable ASCII characters # requirement is that it must be entirely printable ASCII characters
# and have no white space. # and have no white space.
greek=a1 greek=rc1
# The date when this release was created # The date when this release was created
@ -28,7 +28,7 @@ date="Unreleased developer copy"
# entire hwloc version (i.e., ignore major, minor, release, and # entire hwloc version (i.e., ignore major, minor, release, and
# greek). This is only set to 1 when making snapshot tarballs. # greek). This is only set to 1 when making snapshot tarballs.
snapshot=1 snapshot=1
snapshot_version=shmem-20170815.1857.git2478ce8 snapshot_version=${major}.${minor}.${release}${greek}-git
# The shared library version of hwloc's public library. This version # The shared library version of hwloc's public library. This version
# is maintained in accordance with the "Library Interface Versions" # is maintained in accordance with the "Library Interface Versions"
@ -41,7 +41,7 @@ snapshot_version=shmem-20170815.1857.git2478ce8
# 2. Version numbers are described in the Libtool current:revision:age # 2. Version numbers are described in the Libtool current:revision:age
# format. # format.
libhwloc_so_version=0:0:0 libhwloc_so_version=15:0:0
libnetloc_so_version=0:0:0 libnetloc_so_version=0:0:0
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj # Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj

Просмотреть файл

@ -1,6 +1,6 @@
dnl -*- Autoconf -*- dnl -*- Autoconf -*-
dnl dnl
dnl Copyright © 2009-2016 Inria. All rights reserved. dnl Copyright © 2009-2018 Inria. All rights reserved.
dnl Copyright © 2009-2012, 2015-2017 Université Bordeaux dnl Copyright © 2009-2012, 2015-2017 Université Bordeaux
dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology dnl University Research and Technology
@ -12,6 +12,7 @@ dnl University of Stuttgart. All rights reserved.
dnl Copyright © 2006-2017 Cisco Systems, Inc. All rights reserved. dnl Copyright © 2006-2017 Cisco Systems, Inc. All rights reserved.
dnl Copyright © 2012 Blue Brain Project, BBP/EPFL. All rights reserved. dnl Copyright © 2012 Blue Brain Project, BBP/EPFL. All rights reserved.
dnl Copyright © 2012 Oracle and/or its affiliates. All rights reserved. dnl Copyright © 2012 Oracle and/or its affiliates. All rights reserved.
dnl Copyright © 2012 Los Alamos National Security, LLC. All rights reserved.
dnl See COPYING in top-level directory. dnl See COPYING in top-level directory.
# Main hwloc m4 macro, to be invoked by the user # Main hwloc m4 macro, to be invoked by the user
@ -150,6 +151,14 @@ EOF])
[AC_DEFINE([HWLOC_SYM_TRANSFORM], [0])], [AC_DEFINE([HWLOC_SYM_TRANSFORM], [0])],
[AC_DEFINE([HWLOC_SYM_TRANSFORM], [1])]) [AC_DEFINE([HWLOC_SYM_TRANSFORM], [1])])
# hwloc 2.0+ requires a C99 compliant compiler
AC_PROG_CC_C99
# The result of AC_PROG_CC_C99 is stored in ac_cv_prog_cc_c99
if test "x$ac_cv_prog_cc_c99" = xno ; then
AC_MSG_WARN([hwloc requires a C99 compiler])
AC_MSG_ERROR([Aborting.])
fi
# GCC specifics. # GCC specifics.
if test "x$GCC" = "xyes"; then if test "x$GCC" = "xyes"; then
HWLOC_GCC_CFLAGS="-Wall -Wmissing-prototypes -Wundef" HWLOC_GCC_CFLAGS="-Wall -Wmissing-prototypes -Wundef"
@ -433,12 +442,12 @@ EOF])
[HWLOC_LIBS="-lpicl $HWLOC_LIBS"])]) [HWLOC_LIBS="-lpicl $HWLOC_LIBS"])])
AC_CHECK_DECLS([_SC_NPROCESSORS_ONLN, AC_CHECK_DECLS([_SC_NPROCESSORS_ONLN,
_SC_NPROCESSORS_CONF, _SC_NPROCESSORS_CONF,
_SC_NPROC_ONLN, _SC_NPROC_ONLN,
_SC_NPROC_CONF, _SC_NPROC_CONF,
_SC_PAGESIZE, _SC_PAGESIZE,
_SC_PAGE_SIZE, _SC_PAGE_SIZE,
_SC_LARGE_PAGESIZE],,[:],[[#include <unistd.h>]]) _SC_LARGE_PAGESIZE],,[:],[[#include <unistd.h>]])
AC_HAVE_HEADERS([mach/mach_host.h]) AC_HAVE_HEADERS([mach/mach_host.h])
AC_HAVE_HEADERS([mach/mach_init.h], [ AC_HAVE_HEADERS([mach/mach_init.h], [
@ -471,27 +480,39 @@ EOF])
AC_CHECK_DECLS([_putenv], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS([_putenv], [], [], [AC_INCLUDES_DEFAULT])
# Could add mkdir and access for hwloc-gather-cpuid.c on Windows # Could add mkdir and access for hwloc-gather-cpuid.c on Windows
# Do a full link test instead of just using AC_CHECK_FUNCS, which if test "x$hwloc_linux" != "xyes" ; then
# just checks to see if the symbol exists or not. For example, # Don't detect sysctl* on Linux because its sysctl() syscall is
# the prototype of sysctl uses u_int, which on some platforms # long deprecated and unneeded. Some libc still expose the symbol
# (such as FreeBSD) is only defined under __BSD_VISIBLE, __USE_BSD # and raise a big warning at link time.
# or other similar definitions. So while the symbols "sysctl" and
# "sysctlbyname" might still be available in libc (which autoconf # Do a full link test instead of just using AC_CHECK_FUNCS, which
# checks for), they might not be actually usable. # just checks to see if the symbol exists or not. For example,
AC_TRY_LINK([ # the prototype of sysctl uses u_int, which on some platforms
#include <stdio.h> # (such as FreeBSD) is only defined under __BSD_VISIBLE, __USE_BSD
#include <sys/types.h> # or other similar definitions. So while the symbols "sysctl" and
#include <sys/sysctl.h> # "sysctlbyname" might still be available in libc (which autoconf
], # checks for), they might not be actually usable.
[return sysctl(NULL,0,NULL,NULL,NULL,0);], AC_MSG_CHECKING([for sysctl])
AC_DEFINE([HAVE_SYSCTL],[1],[Define to '1' if sysctl is present and usable])) AC_TRY_LINK([
AC_TRY_LINK([ #include <stdio.h>
#include <stdio.h> #include <sys/types.h>
#include <sys/types.h> #include <sys/sysctl.h>
#include <sys/sysctl.h> ],
], [return sysctl(NULL,0,NULL,NULL,NULL,0);],
[return sysctlbyname(NULL,NULL,NULL,NULL,0);], [AC_DEFINE([HAVE_SYSCTL],[1],[Define to '1' if sysctl is present and usable])
AC_DEFINE([HAVE_SYSCTLBYNAME],[1],[Define to '1' if sysctlbyname is present and usable])) AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
AC_MSG_CHECKING([for sysctlbyname])
AC_TRY_LINK([
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
],
[return sysctlbyname(NULL,NULL,NULL,NULL,0);],
[AC_DEFINE([HAVE_SYSCTLBYNAME],[1],[Define to '1' if sysctlbyname is present and usable])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
fi
AC_CHECK_DECLS([getprogname], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS([getprogname], [], [], [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([getexecname], [], [], [AC_INCLUDES_DEFAULT]) AC_CHECK_DECLS([getexecname], [], [], [AC_INCLUDES_DEFAULT])
@ -537,6 +558,13 @@ EOF])
AC_DEFINE_UNQUOTED(hwloc_thread_t, $hwloc_thread_t, [Define this to the thread ID type]) AC_DEFINE_UNQUOTED(hwloc_thread_t, $hwloc_thread_t, [Define this to the thread ID type])
fi fi
AC_CHECK_DECLS([sched_getcpu],,[:],[[
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <sched.h>
]])
_HWLOC_CHECK_DECL([sched_setaffinity], [ _HWLOC_CHECK_DECL([sched_setaffinity], [
AC_DEFINE([HWLOC_HAVE_SCHED_SETAFFINITY], [1], [Define to 1 if glibc provides a prototype of sched_setaffinity()]) AC_DEFINE([HWLOC_HAVE_SCHED_SETAFFINITY], [1], [Define to 1 if glibc provides a prototype of sched_setaffinity()])
AS_IF([test "$HWLOC_STRICT_ARGS_CFLAGS" = "FAIL"],[ AS_IF([test "$HWLOC_STRICT_ARGS_CFLAGS" = "FAIL"],[
@ -748,24 +776,38 @@ EOF])
# OpenCL support # OpenCL support
hwloc_opencl_happy=no hwloc_opencl_happy=no
if test "x$enable_io" != xno && test "x$enable_opencl" != "xno"; then if test "x$enable_io" != xno && test "x$enable_opencl" != "xno"; then
hwloc_opencl_happy=yes hwloc_opencl_happy=yes
case ${target} in
*-*-darwin*)
# On Darwin, only use the OpenCL framework
AC_CHECK_HEADERS([OpenCL/cl_ext.h], [
AC_MSG_CHECKING([for the OpenCL framework])
tmp_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -framework OpenCL"
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
#include <OpenCL/opencl.h>
]], [[
return clGetDeviceIDs(0, 0, 0, NULL, NULL);
]])],
[AC_MSG_RESULT(yes)
HWLOC_OPENCL_LDFLAGS="-framework OpenCL"],
[AC_MSG_RESULT(no)
hwloc_opencl_happy=no])
LDFLAGS="$tmp_save_LDFLAGS"
], [hwloc_opencl_happy=no])
;;
*)
# On Others, look for OpenCL at normal locations
AC_CHECK_HEADERS([CL/cl_ext.h], [ AC_CHECK_HEADERS([CL/cl_ext.h], [
AC_CHECK_LIB([OpenCL], [clGetDeviceIDs], [HWLOC_OPENCL_LIBS="-lOpenCL"], [hwloc_opencl_happy=no]) AC_CHECK_LIB([OpenCL], [clGetDeviceIDs], [HWLOC_OPENCL_LIBS="-lOpenCL"], [hwloc_opencl_happy=no])
], [hwloc_opencl_happy=no]) ], [hwloc_opencl_happy=no])
;;
esac
fi fi
AC_SUBST(HWLOC_OPENCL_CFLAGS)
AC_SUBST(HWLOC_OPENCL_LIBS) AC_SUBST(HWLOC_OPENCL_LIBS)
# Check if required extensions are available AC_SUBST(HWLOC_OPENCL_LDFLAGS)
if test "x$hwloc_opencl_happy" = "xyes"; then
tmp_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $HWLOC_OPENCL_CFLAGS"
tmp_save_LIBS="$LIBS"
LIBS="$LIBS $HWLOC_OPENCL_LIBS"
AC_CHECK_DECLS([CL_DEVICE_TOPOLOGY_AMD],[hwloc_opencl_amd_happy=yes],[:],[[#include <CL/cl_ext.h>]])
CFLAGS="$tmp_save_CFLAGS"
LIBS="$tmp_save_LIBS"
# We can't do anything without CL_DEVICE_TOPOLOGY_AMD so far, so disable OpenCL entirely if not found
test "x$hwloc_opencl_amd_happy" != "xyes" && hwloc_opencl_happy=no
fi
# If we asked for opencl support but couldn't deliver, fail # If we asked for opencl support but couldn't deliver, fail
AS_IF([test "$enable_opencl" = "yes" -a "$hwloc_opencl_happy" = "no"], AS_IF([test "$enable_opencl" = "yes" -a "$hwloc_opencl_happy" = "no"],
[AC_MSG_WARN([Specified --enable-opencl switch, but could not]) [AC_MSG_WARN([Specified --enable-opencl switch, but could not])
@ -1085,6 +1127,7 @@ EOF])
HWLOC_REQUIRES="$HWLOC_PCIACCESS_REQUIRES $HWLOC_REQUIRES"]) HWLOC_REQUIRES="$HWLOC_PCIACCESS_REQUIRES $HWLOC_REQUIRES"])
AS_IF([test "$hwloc_opencl_component" = "static"], AS_IF([test "$hwloc_opencl_component" = "static"],
[HWLOC_LIBS="$HWLOC_LIBS $HWLOC_OPENCL_LIBS" [HWLOC_LIBS="$HWLOC_LIBS $HWLOC_OPENCL_LIBS"
HWLOC_LDFLAGS="$HWLOC_LDFLAGS $HWLOC_OPENCL_LDFLAGS"
HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_OPENCL_CFLAGS" HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_OPENCL_CFLAGS"
HWLOC_REQUIRES="$HWLOC_OPENCL_REQUIRES $HWLOC_REQUIRES"]) HWLOC_REQUIRES="$HWLOC_OPENCL_REQUIRES $HWLOC_REQUIRES"])
AS_IF([test "$hwloc_cuda_component" = "static"], AS_IF([test "$hwloc_cuda_component" = "static"],
@ -1138,7 +1181,7 @@ EOF])
AC_CONFIG_FILES( AC_CONFIG_FILES(
hwloc_config_prefix[Makefile] hwloc_config_prefix[Makefile]
hwloc_config_prefix[include/Makefile] hwloc_config_prefix[include/Makefile]
hwloc_config_prefix[hwloc/Makefile ] hwloc_config_prefix[hwloc/Makefile]
) )
# Cleanup # Cleanup
@ -1178,8 +1221,6 @@ AC_DEFUN([HWLOC_DO_AM_CONDITIONALS],[
[test "x$hwloc_have_cuda" = "xyes"]) [test "x$hwloc_have_cuda" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_GL], AM_CONDITIONAL([HWLOC_HAVE_GL],
[test "x$hwloc_have_gl" = "xyes"]) [test "x$hwloc_have_gl" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_MYRIEXPRESS],
[test "x$hwloc_have_myriexpress" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_CUDART], AM_CONDITIONAL([HWLOC_HAVE_CUDART],
[test "x$hwloc_have_cudart" = "xyes"]) [test "x$hwloc_have_cudart" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_LIBXML2], [test "$hwloc_libxml2_happy" = "yes"]) AM_CONDITIONAL([HWLOC_HAVE_LIBXML2], [test "$hwloc_libxml2_happy" = "yes"])

Просмотреть файл

@ -531,3 +531,4 @@ AC_DEFUN([_HWLOC_CHECK_ATTRIBUTES], [
AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS, [$hwloc_cv___attribute__weak_alias], AC_DEFINE_UNQUOTED(HWLOC_HAVE_ATTRIBUTE_WEAK_ALIAS, [$hwloc_cv___attribute__weak_alias],
[Whether your compiler has __attribute__ weak alias or not]) [Whether your compiler has __attribute__ weak alias or not])
]) ])

Просмотреть файл

@ -29,24 +29,24 @@ else
if test -f "$srcfile"; then if test -f "$srcfile"; then
ompi_vers=`sed -n " ompi_vers=`sed -n "
t clear t clear
: clear : clear
s/^major/HWLOC_MAJOR_VERSION/ s/^major/HWLOC_MAJOR_VERSION/
s/^minor/HWLOC_MINOR_VERSION/ s/^minor/HWLOC_MINOR_VERSION/
s/^release/HWLOC_RELEASE_VERSION/ s/^release/HWLOC_RELEASE_VERSION/
s/^greek/HWLOC_GREEK_VERSION/ s/^greek/HWLOC_GREEK_VERSION/
s/\\\${major}/\\\${HWLOC_MAJOR_VERSION}/ s/\\\${major}/\\\${HWLOC_MAJOR_VERSION}/
s/\\\${minor}/\\\${HWLOC_MINOR_VERSION}/ s/\\\${minor}/\\\${HWLOC_MINOR_VERSION}/
s/\\\${release}/\\\${HWLOC_RELEASE_VERSION}/ s/\\\${release}/\\\${HWLOC_RELEASE_VERSION}/
s/\\\${greek}/\\\${HWLOC_GREEK_VERSION}/ s/\\\${greek}/\\\${HWLOC_GREEK_VERSION}/
s/^date/HWLOC_RELEASE_DATE/ s/^date/HWLOC_RELEASE_DATE/
s/^snapshot_version/HWLOC_SNAPSHOT_VERSION/ s/^snapshot_version/HWLOC_SNAPSHOT_VERSION/
s/^snapshot/HWLOC_SNAPSHOT/ s/^snapshot/HWLOC_SNAPSHOT/
t print t print
b b
: print : print
p" < "$srcfile"` p" < "$srcfile"`
eval "$ompi_vers" eval "$ompi_vers"
HWLOC_VERSION="$HWLOC_MAJOR_VERSION.$HWLOC_MINOR_VERSION.$HWLOC_RELEASE_VERSION${HWLOC_GREEK_VERSION}" HWLOC_VERSION="$HWLOC_MAJOR_VERSION.$HWLOC_MINOR_VERSION.$HWLOC_RELEASE_VERSION${HWLOC_GREEK_VERSION}"
@ -62,14 +62,14 @@ else
fi fi
if test "$option" = ""; then if test "$option" = ""; then
option="--version" option="--version"
fi fi
fi fi
case "$option" in case "$option" in
--version) --version)
echo $HWLOC_VERSION echo $HWLOC_VERSION
;; ;;
--release-date) --release-date)
echo $HWLOC_RELEASE_DATE echo $HWLOC_RELEASE_DATE
;; ;;
@ -77,7 +77,7 @@ case "$option" in
echo $HWLOC_SNAPSHOT echo $HWLOC_SNAPSHOT
;; ;;
-h|--help) -h|--help)
cat <<EOF cat <<EOF
$0 <srcfile> <option> $0 <srcfile> <option>
<srcfile> - Text version file <srcfile> - Text version file

Просмотреть файл

@ -1,6 +1,6 @@
dnl -*- Autoconf -*- dnl -*- Autoconf -*-
dnl dnl
dnl Copyright © 2010-2017 Inria. All rights reserved. dnl Copyright © 2010-2018 Inria. All rights reserved.
dnl Copyright © 2009, 2011 Université Bordeaux dnl Copyright © 2009, 2011 Université Bordeaux
dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana dnl Copyright © 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology dnl University Research and Technology
@ -122,7 +122,7 @@ AC_DEFUN([HWLOC_SETUP_DOCS],[
EOF EOF
AC_MSG_CHECKING([if this is a developer build]) AC_MSG_CHECKING([if this is a developer build])
AS_IF([test ! -d "$srcdir/.hg" -a ! -d "$srcdir/.git"], AS_IF([test ! -e "$srcdir/.git"],
[AC_MSG_RESULT([no (doxygen generation is optional)]) [AC_MSG_RESULT([no (doxygen generation is optional)])
test "x$enable_doxygen" = x && enable_doxygen=no], test "x$enable_doxygen" = x && enable_doxygen=no],
[AC_MSG_RESULT([yes]) [AC_MSG_RESULT([yes])
@ -185,8 +185,8 @@ EOF
AC_MSG_CHECKING([if will install doxygen docs]) AC_MSG_CHECKING([if will install doxygen docs])
AS_IF([test "x$hwloc_generate_doxs" = "xyes" -o \ AS_IF([test "x$hwloc_generate_doxs" = "xyes" -o \
-f "$srcdir/doc/doxygen-doc/man/man3/hwloc_distrib.3" -a \ -f "$srcdir/doc/doxygen-doc/man/man3/hwloc_distrib.3" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-a4.pdf" -a \ -f "$srcdir/doc/doxygen-doc/hwloc-a4.pdf" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-letter.pdf"], -f "$srcdir/doc/doxygen-doc/hwloc-letter.pdf"],
[hwloc_install_doxs=yes], [hwloc_install_doxs=yes],
[hwloc_install_doxs=no]) [hwloc_install_doxs=no])
AC_MSG_RESULT([$hwloc_install_doxs]) AC_MSG_RESULT([$hwloc_install_doxs])
@ -322,12 +322,15 @@ EOF
]) ])
# Only generate this if we're building the utilities # Only generate this if we're building the utilities
# Even the netloc library Makefile is here because
# we don't embed libnetloc yet, it's useless without tools
AC_CONFIG_FILES( AC_CONFIG_FILES(
hwloc_config_prefix[utils/Makefile] hwloc_config_prefix[utils/Makefile]
hwloc_config_prefix[utils/hwloc/Makefile] hwloc_config_prefix[utils/hwloc/Makefile]
hwloc_config_prefix[utils/lstopo/Makefile] hwloc_config_prefix[utils/lstopo/Makefile]
hwloc_config_prefix[hwloc.pc] hwloc_config_prefix[hwloc.pc]
hwloc_config_prefix[netloc/Makefile]
hwloc_config_prefix[utils/netloc/infiniband/Makefile] hwloc_config_prefix[utils/netloc/infiniband/Makefile]
hwloc_config_prefix[utils/netloc/draw/Makefile] hwloc_config_prefix[utils/netloc/draw/Makefile]
hwloc_config_prefix[utils/netloc/scotch/Makefile] hwloc_config_prefix[utils/netloc/scotch/Makefile]
@ -353,7 +356,7 @@ EOF
# linux-libnuma.h testing requires libnuma with numa_bitmask_alloc() # linux-libnuma.h testing requires libnuma with numa_bitmask_alloc()
AC_CHECK_LIB([numa], [numa_available], [ AC_CHECK_LIB([numa], [numa_available], [
AC_CHECK_DECL([numa_bitmask_alloc], [hwloc_have_linux_libnuma=yes], [], AC_CHECK_DECL([numa_bitmask_alloc], [hwloc_have_linux_libnuma=yes], [],
[#include <numa.h>]) [#include <numa.h>])
]) ])
AC_CHECK_HEADERS([stdlib.h], [ AC_CHECK_HEADERS([stdlib.h], [
@ -366,16 +369,6 @@ EOF
hwloc_have_libibverbs=yes]) hwloc_have_libibverbs=yes])
]) ])
AC_CHECK_HEADERS([myriexpress.h], [
AC_MSG_CHECKING(if MX_NUMA_NODE exists)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <myriexpress.h>]],
[[int a = MX_NUMA_NODE;]])],
[AC_MSG_RESULT(yes)
AC_CHECK_LIB([myriexpress], [mx_get_info],
[AC_DEFINE([HAVE_MYRIEXPRESS], 1, [Define to 1 if we have -lmyriexpress])
hwloc_have_myriexpress=yes])],
[AC_MSG_RESULT(no)])])
AC_CHECK_PROGS(XMLLINT, [xmllint]) AC_CHECK_PROGS(XMLLINT, [xmllint])
AC_CHECK_PROGS(BUNZIPP, bunzip2, false) AC_CHECK_PROGS(BUNZIPP, bunzip2, false)
@ -424,6 +417,7 @@ int foo(void) {
hwloc_config_prefix[utils/hwloc/test-hwloc-dump-hwdata/Makefile] hwloc_config_prefix[utils/hwloc/test-hwloc-dump-hwdata/Makefile]
hwloc_config_prefix[utils/hwloc/test-hwloc-dump-hwdata/test-hwloc-dump-hwdata.sh] hwloc_config_prefix[utils/hwloc/test-hwloc-dump-hwdata/test-hwloc-dump-hwdata.sh]
hwloc_config_prefix[utils/lstopo/test-lstopo.sh] hwloc_config_prefix[utils/lstopo/test-lstopo.sh]
hwloc_config_prefix[utils/netloc/infiniband/netloc_ib_gather_raw]
hwloc_config_prefix[contrib/systemd/Makefile] hwloc_config_prefix[contrib/systemd/Makefile]
hwloc_config_prefix[contrib/misc/Makefile] hwloc_config_prefix[contrib/misc/Makefile]
hwloc_config_prefix[tests/netloc/Makefile] hwloc_config_prefix[tests/netloc/Makefile]
@ -448,6 +442,7 @@ chmod +x ]hwloc_config_prefix[tests/hwloc/linux/test-topology.sh \
]hwloc_config_prefix[utils/hwloc/test-fake-plugin.sh \ ]hwloc_config_prefix[utils/hwloc/test-fake-plugin.sh \
]hwloc_config_prefix[utils/hwloc/test-hwloc-dump-hwdata/test-hwloc-dump-hwdata.sh \ ]hwloc_config_prefix[utils/hwloc/test-hwloc-dump-hwdata/test-hwloc-dump-hwdata.sh \
]hwloc_config_prefix[utils/lstopo/test-lstopo.sh \ ]hwloc_config_prefix[utils/lstopo/test-lstopo.sh \
]hwloc_config_prefix[utils/netloc/infiniband/netloc_ib_gather_raw \
]hwloc_config_prefix[tests/netloc/tests.sh]) ]hwloc_config_prefix[tests/netloc/tests.sh])
# These links are only needed in standalone mode. It would # These links are only needed in standalone mode. It would

Просмотреть файл

@ -2,7 +2,7 @@ dnl -*- Autoconf -*-
dnl dnl
dnl Copyright © 2014 Cisco Systems, Inc. All rights reserved. dnl Copyright © 2014 Cisco Systems, Inc. All rights reserved.
dnl dnl
dnl Copyright © 2014-2017 Inria. All rights reserved. dnl Copyright © 2014-2018 Inria. All rights reserved.
dnl See COPYING in top-level directory. dnl See COPYING in top-level directory.
# Main hwloc m4 macro, to be invoked by the user # Main hwloc m4 macro, to be invoked by the user
@ -25,11 +25,6 @@ AC_DEFUN([NETLOC_SETUP_CORE],[
### ###
EOF]) EOF])
# If no prefix was defined, set a good value
m4_ifval([$1],
[m4_define([netloc_config_prefix],[$1/])],
[m4_define([netloc_config_prefix], [])])
# These flags are specific to netloc, and should not be redundant # These flags are specific to netloc, and should not be redundant
# with hwloc. I.e., if the flag already exists in hwloc, there's # with hwloc. I.e., if the flag already exists in hwloc, there's
# no need to put it here. # no need to put it here.
@ -63,21 +58,12 @@ EOF])
NETLOC_EMBEDDED_CPPFLAGS=$NETLOC_CPPFLAGS NETLOC_EMBEDDED_CPPFLAGS=$NETLOC_CPPFLAGS
NETLOC_EMBEDDED_LDADD='$(HWLOC_top_builddir)/netloc/libnetloc_embedded.la' NETLOC_EMBEDDED_LDADD='$(HWLOC_top_builddir)/netloc/libnetloc_embedded.la'
NETLOC_EMBEDDED_LIBS=$NETLOC_LIBS NETLOC_EMBEDDED_LIBS=$NETLOC_LIBS
NETLOC_LIBS=], NETLOC_LIBS=])
[AC_CONFIG_FILES(netloc_config_prefix[utils/netloc/infiniband/netloc_ib_gather_raw])
AC_CONFIG_COMMANDS([chmoding-netloc-scripts], [
chmod +x ]hwloc_config_prefix[utils/netloc/infiniband/netloc_ib_gather_raw
])
])
AC_SUBST(NETLOC_EMBEDDED_CFLAGS) AC_SUBST(NETLOC_EMBEDDED_CFLAGS)
AC_SUBST(NETLOC_EMBEDDED_CPPFLAGS) AC_SUBST(NETLOC_EMBEDDED_CPPFLAGS)
AC_SUBST(NETLOC_EMBEDDED_LDADD) AC_SUBST(NETLOC_EMBEDDED_LDADD)
AC_SUBST(NETLOC_EMBEDDED_LIBS) AC_SUBST(NETLOC_EMBEDDED_LIBS)
AC_CONFIG_FILES(
netloc_config_prefix[netloc/Makefile]
)
AS_IF([test "$netloc_happy" = "yes"], AS_IF([test "$netloc_happy" = "yes"],
[$2], [$2],
[$3]) [$3])

Просмотреть файл

@ -1,7 +1,7 @@
# -*- shell-script -*- # -*- shell-script -*-
# #
# Copyright © 2009 CNRS # Copyright © 2009 CNRS
# Copyright © 2009-2016 Inria. All rights reserved. # Copyright © 2009-2018 Inria. All rights reserved.
# Copyright © 2009, 2011-2012 Université Bordeaux # Copyright © 2009, 2011-2012 Université Bordeaux
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# #
@ -18,7 +18,7 @@
AC_INIT([hwloc], AC_INIT([hwloc],
[m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --version]))], [m4_normalize(esyscmd([config/hwloc_get_version.sh VERSION --version]))],
[http://www.open-mpi.org/projects/hwloc/], [hwloc]) [http://github.com/open-mpi/hwloc/issues], [hwloc])
AC_PREREQ(2.63) AC_PREREQ(2.63)
AC_CONFIG_AUX_DIR(./config) AC_CONFIG_AUX_DIR(./config)
# Note that this directory must *exactly* match what was specified via # Note that this directory must *exactly* match what was specified via
@ -143,10 +143,10 @@ AC_SUBST([libnetloc_so_version])
AC_ARG_ENABLE([netloc], AC_ARG_ENABLE([netloc],
[AC_HELP_STRING([--enable-netloc], [AC_HELP_STRING([--enable-netloc],
[The Netloc functionality is enabled by default, but will be silently skipped it if cannot be built (e.g., not supported on your platform). Using --enable-netloc will cause configure to abort if Netloc cannot be build. Using --disable-netloc will cause configure to skip attempting to build netloc at all.]) [The Netloc functionality is disabled by default. Using --enable-netloc will cause configure to abort if Netloc cannot be build (e.g., not supported on your platform).])
]) ])
AS_IF([test "$enable_netloc" != "no"], AS_IF([test "$enable_netloc" = "yes" -a "$hwloc_mode" = "standalone"],
[NETLOC_SETUP_CORE([], [], [NETLOC_SETUP_CORE([], [],
[AS_IF([test "$enable_netloc" = "yes"], [AS_IF([test "$enable_netloc" = "yes"],
[AC_MSG_ERROR([Cannot build netloc core])]) [AC_MSG_ERROR([Cannot build netloc core])])
@ -225,9 +225,11 @@ fi
hwloc_xml_status=basic hwloc_xml_status=basic
AS_IF([test "$hwloc_libxml2_happy" = "yes"], [hwloc_xml_status=full]) AS_IF([test "$hwloc_libxml2_happy" = "yes"], [hwloc_xml_status=full])
netloc_status=no netloc_status=no
AS_IF([test "$netloc_happy" = "yes"], [netloc_status=yes]) AS_IF([test "$netloc_happy" = "yes"], [
netlocscotch_status=no netlocscotch_status=without
AS_IF([test "$scotch_found_headers" = "yes"], [netlocscotch_status=yes]) AS_IF([test "$scotch_found_headers" = "yes"], [netlocscotch_status=with])
netloc_status="yes ($netlocscotch_status scotch)"
])
# Prepare the I/O summary # Prepare the I/O summary
hwloc_probeio_list= hwloc_probeio_list=
@ -254,7 +256,7 @@ Hwloc optional build support status (more details can be found above):
Probe / display I/O devices:$hwloc_probeio_list Probe / display I/O devices:$hwloc_probeio_list
Graphical output (Cairo): $hwloc_cairo_happy Graphical output (Cairo): $hwloc_cairo_happy
XML input / output: $hwloc_xml_status XML input / output: $hwloc_xml_status
Netloc functionality: $netloc_status (with scotch: $netlocscotch_status) Netloc functionality: $netloc_status
EOF EOF
# Plugin support # Plugin support

Просмотреть файл

@ -126,7 +126,7 @@
obj:*libatiadl* obj:*libatiadl*
} }
# #
{ {
libpciaccess_device_name_leak libpciaccess_device_name_leak
Memcheck:Leak Memcheck:Leak
@ -158,3 +158,4 @@
... ...
fun:udev_device_new_from_subsystem_sysname fun:udev_device_new_from_subsystem_sysname
} }

Просмотреть файл

@ -1,4 +1,4 @@
# Copyright © 2009-2017 Inria. All rights reserved. # Copyright © 2009-2018 Inria. All rights reserved.
# Copyright © 2009-2012 Université Bordeaux # Copyright © 2009-2012 Université Bordeaux
# Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved. # Copyright © 2009-2014 Cisco Systems, Inc. All rights reserved.
# Copyright © 2011-2012 Oracle and/or its affiliates. All rights reserved. # Copyright © 2011-2012 Oracle and/or its affiliates. All rights reserved.
@ -76,7 +76,7 @@ else
plugins_LTLIBRARIES += hwloc_opencl.la plugins_LTLIBRARIES += hwloc_opencl.la
hwloc_opencl_la_SOURCES = topology-opencl.c hwloc_opencl_la_SOURCES = topology-opencl.c
hwloc_opencl_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_OPENCL_CFLAGS) -DHWLOC_INSIDE_PLUGIN hwloc_opencl_la_CFLAGS = $(AM_CFLAGS) $(HWLOC_OPENCL_CFLAGS) -DHWLOC_INSIDE_PLUGIN
hwloc_opencl_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_OPENCL_LIBS) hwloc_opencl_la_LDFLAGS = $(plugins_ldflags) $(HWLOC_OPENCL_LIBS) $(HWLOC_OPENCL_LDFLAGS)
endif endif
endif HWLOC_HAVE_OPENCL endif HWLOC_HAVE_OPENCL
@ -199,7 +199,7 @@ endif HWLOC_HAVE_WINDOWS
# Installable library # Installable library
libhwloc_la_SOURCES = $(sources) libhwloc_la_SOURCES = $(sources)
libhwloc_la_LDFLAGS = $(ldflags) -version-info $(libhwloc_so_version) $(HWLOC_LIBS) libhwloc_la_LDFLAGS = $(ldflags) -version-info $(libhwloc_so_version) $(HWLOC_LIBS) $(HWLOC_LDFLAGS)
if HWLOC_HAVE_PLUGINS if HWLOC_HAVE_PLUGINS
AM_CPPFLAGS += $(LTDLINCL) AM_CPPFLAGS += $(LTDLINCL)
@ -217,9 +217,9 @@ libhwloc_embedded_la_SOURCES = $(sources)
# XML data (only install if we're building in standalone mode) # XML data (only install if we're building in standalone mode)
if HWLOC_BUILD_STANDALONE if HWLOC_BUILD_STANDALONE
xml_DATA = $(srcdir)/hwloc.dtd xml_DATA = $(srcdir)/hwloc.dtd $(srcdir)/hwloc2.dtd $(srcdir)/hwloc2-diff.dtd
xmldir = $(pkgdatadir) xmldir = $(pkgdatadir)
EXTRA_DIST += hwloc.dtd EXTRA_DIST += hwloc.dtd hwloc2.dtd hwloc2-diff.dtd
endif endif
DISTCLEANFILES = static-components.h DISTCLEANFILES = static-components.h

309
opal/mca/hwloc/hwloc201/hwloc/hwloc/base64.c Обычный файл
Просмотреть файл

@ -0,0 +1,309 @@
/*
* Copyright © 2012-2018 Inria. All rights reserved.
* See COPYING in top-level directory.
*
* Modifications after import:
* - removed all #if
* - updated prototypes
* - updated #include
*/
/* include hwloc's config before anything else
* so that extensions and features are properly enabled
*/
#include <private/private.h>
/* $OpenBSD: base64.c,v 1.5 2006/10/21 09:55:03 otto Exp $ */
/*
* Copyright (c) 1996 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
/*
* Portions Copyright (c) 1995 by International Business Machines, Inc.
*
* International Business Machines, Inc. (hereinafter called IBM) grants
* permission under its copyrights to use, copy, modify, and distribute this
* Software with or without fee, provided that the above copyright notice and
* all paragraphs of this notice appear in all copies, and that the name of IBM
* not be used in connection with the marketing of any product incorporating
* the Software or modifications thereof, without specific, written prior
* permission.
*
* To the extent it has a right to do so, IBM grants an immunity from suit
* under its patents, if any, for the use, sale or manufacture of products to
* the extent that such products are used for performing Domain Name System
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
* granted for any product per se or for any other function of any product.
*
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
/* OPENBSD ORIGINAL: lib/libc/net/base64.c */
static const char Base64[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char Pad64 = '=';
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
The following encoding technique is taken from RFC 1521 by Borenstein
and Freed. It is reproduced here in a slightly edited form for
convenience.
A 65-character subset of US-ASCII is used, enabling 6 bits to be
represented per printable character. (The extra 65th character, "=",
is used to signify a special processing function.)
The encoding process represents 24-bit groups of input bits as output
strings of 4 encoded characters. Proceeding from left to right, a
24-bit input group is formed by concatenating 3 8-bit input groups.
These 24 bits are then treated as 4 concatenated 6-bit groups, each
of which is translated into a single digit in the base64 alphabet.
Each 6-bit group is used as an index into an array of 64 printable
characters. The character referenced by the index is placed in the
output string.
Table 1: The Base64 Alphabet
Value Encoding Value Encoding Value Encoding Value Encoding
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
Special processing is performed if fewer than 24 bits are available
at the end of the data being encoded. A full encoding quantum is
always completed at the end of a quantity. When fewer than 24 input
bits are available in an input group, zero bits are added (on the
right) to form an integral number of 6-bit groups. Padding at the
end of the data is performed using the '=' character.
Since all base64 input is an integral number of octets, only the
-------------------------------------------------
following cases can arise:
(1) the final quantum of encoding input is an integral
multiple of 24 bits; here, the final unit of encoded
output will be an integral multiple of 4 characters
with no "=" padding,
(2) the final quantum of encoding input is exactly 8 bits;
here, the final unit of encoded output will be two
characters followed by two "=" padding characters, or
(3) the final quantum of encoding input is exactly 16 bits;
here, the final unit of encoded output will be three
characters followed by one "=" padding character.
*/
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int
hwloc_encode_to_base64(const char *src, size_t srclength, char *target, size_t targsize)
{
size_t datalength = 0;
unsigned char input[3];
unsigned char output[4];
unsigned int i;
while (2 < srclength) {
input[0] = *src++;
input[1] = *src++;
input[2] = *src++;
srclength -= 3;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
output[3] = input[2] & 0x3f;
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
target[datalength++] = Base64[output[2]];
target[datalength++] = Base64[output[3]];
}
/* Now we worry about padding. */
if (0 != srclength) {
/* Get what's left. */
input[0] = input[1] = input[2] = '\0';
for (i = 0; i < srclength; i++)
input[i] = *src++;
output[0] = input[0] >> 2;
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
if (datalength + 4 > targsize)
return (-1);
target[datalength++] = Base64[output[0]];
target[datalength++] = Base64[output[1]];
if (srclength == 1)
target[datalength++] = Pad64;
else
target[datalength++] = Base64[output[2]];
target[datalength++] = Pad64;
}
if (datalength >= targsize)
return (-1);
target[datalength] = '\0'; /* Returned value doesn't count \0. */
return (int)(datalength);
}
/* skips all whitespace anywhere.
converts characters, four at a time, starting at (or after)
src from base - 64 numbers into three 8 bit bytes in the target area.
it returns the number of data bytes stored at the target, or -1 on error.
*/
int
hwloc_decode_from_base64(char const *src, char *target, size_t targsize)
{
unsigned int tarindex, state;
int ch;
char *pos;
state = 0;
tarindex = 0;
while ((ch = *src++) != '\0') {
if (isspace(ch)) /* Skip whitespace anywhere. */
continue;
if (ch == Pad64)
break;
pos = strchr(Base64, ch);
if (pos == 0) /* A non-base64 character. */
return (-1);
switch (state) {
case 0:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] = (char)(pos - Base64) << 2;
}
state = 1;
break;
case 1:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 4;
target[tarindex+1] = ((pos - Base64) & 0x0f)
<< 4 ;
}
tarindex++;
state = 2;
break;
case 2:
if (target) {
if (tarindex + 1 >= targsize)
return (-1);
target[tarindex] |= (pos - Base64) >> 2;
target[tarindex+1] = ((pos - Base64) & 0x03)
<< 6;
}
tarindex++;
state = 3;
break;
case 3:
if (target) {
if (tarindex >= targsize)
return (-1);
target[tarindex] |= (pos - Base64);
}
tarindex++;
state = 0;
break;
}
}
/*
* We are done decoding Base-64 chars. Let's see if we ended
* on a byte boundary, and/or with erroneous trailing characters.
*/
if (ch == Pad64) { /* We got a pad char. */
ch = *src++; /* Skip it, get next. */
switch (state) {
case 0: /* Invalid = in first position */
case 1: /* Invalid = in second position */
return (-1);
case 2: /* Valid, means one byte of info */
/* Skip any number of spaces. */
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
break;
/* Make sure there is another trailing = sign. */
if (ch != Pad64)
return (-1);
ch = *src++; /* Skip the = */
/* Fall through to "single trailing =" case. */
/* FALLTHROUGH */
case 3: /* Valid, means two bytes of info */
/*
* We know this char is an =. Is there anything but
* whitespace after it?
*/
for (; ch != '\0'; ch = *src++)
if (!isspace(ch))
return (-1);
/*
* Now make sure for cases 2 and 3 that the "extra"
* bits that slopped past the last full byte were
* zeros. If we don't check them, they become a
* subliminal channel.
*/
if (target && target[tarindex] != 0)
return (-1);
}
} else {
/*
* We ended by seeing the end of the string. Make sure we
* have no partial bytes lying around.
*/
if (state != 0)
return (-1);
}
return (tarindex);
}

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux * Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011-2015 Cisco Systems, Inc. All rights reserved. * Copyright © 2011-2015 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -38,12 +38,6 @@ hwloc_fix_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_t set)
hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology); hwloc_const_bitmap_t topology_set = hwloc_topology_get_topology_cpuset(topology);
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology); hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
if (!topology_set) {
/* The topology is composed of several systems, the cpuset is ambiguous. */
errno = EXDEV;
return NULL;
}
if (hwloc_bitmap_iszero(set)) { if (hwloc_bitmap_iszero(set)) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
@ -244,19 +238,6 @@ hwloc_fix_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset)
hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology); hwloc_const_bitmap_t topology_nodeset = hwloc_topology_get_topology_nodeset(topology);
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology); hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
if (!hwloc_topology_get_topology_cpuset(topology)) {
/* The topology is composed of several systems, the nodeset is thus
* ambiguous. */
errno = EXDEV;
return NULL;
}
if (!complete_nodeset) {
/* There is no NUMA node */
errno = ENODEV;
return NULL;
}
if (hwloc_bitmap_iszero(nodeset)) { if (hwloc_bitmap_iszero(nodeset)) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
@ -280,19 +261,6 @@ hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwl
hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology); hwloc_const_bitmap_t complete_set = hwloc_topology_get_complete_cpuset(topology);
hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology); hwloc_const_bitmap_t complete_nodeset = hwloc_topology_get_complete_nodeset(topology);
if (!topology_set) {
/* The topology is composed of several systems, the cpuset is thus
* ambiguous. */
errno = EXDEV;
return -1;
}
if (!complete_nodeset) {
/* There is no NUMA node */
errno = ENODEV;
return -1;
}
if (hwloc_bitmap_iszero(cpuset)) { if (hwloc_bitmap_iszero(cpuset)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
@ -312,10 +280,21 @@ hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwl
return 0; return 0;
} }
static __hwloc_inline int hwloc__check_membind_policy(hwloc_membind_policy_t policy)
{
if (policy == HWLOC_MEMBIND_DEFAULT
|| policy == HWLOC_MEMBIND_FIRSTTOUCH
|| policy == HWLOC_MEMBIND_BIND
|| policy == HWLOC_MEMBIND_INTERLEAVE
|| policy == HWLOC_MEMBIND_NEXTTOUCH)
return 0;
return -1;
}
static int static int
hwloc_set_membind_by_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_set_membind_by_nodeset(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{ {
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) { if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -413,7 +392,7 @@ hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_p
static int static int
hwloc_set_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_set_proc_membind_by_nodeset(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{ {
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) { if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -485,7 +464,7 @@ hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_
static int static int
hwloc_set_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_set_area_membind_by_nodeset(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{ {
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) { if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -655,7 +634,7 @@ hwloc_alloc_membind_by_nodeset(hwloc_topology_t topology, size_t len, hwloc_cons
{ {
void *p; void *p;
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) { if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
@ -704,9 +683,9 @@ hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc(); hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
if (hwloc_fix_membind_cpuset(topology, nodeset, set)) { if (hwloc_fix_membind_cpuset(topology, nodeset, set)) {
if (flags & HWLOC_MEMBIND_STRICT) if (flags & HWLOC_MEMBIND_STRICT)
ret = NULL; ret = NULL;
else else
ret = hwloc_alloc(topology, len); ret = hwloc_alloc(topology, len);
} else } else
ret = hwloc_alloc_membind_by_nodeset(topology, len, nodeset, policy, flags); ret = hwloc_alloc_membind_by_nodeset(topology, len, nodeset, policy, flags);
hwloc_bitmap_free(nodeset); hwloc_bitmap_free(nodeset);
@ -729,12 +708,8 @@ hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set) static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set)
{ {
hwloc_const_cpuset_t cpuset = hwloc_topology_get_complete_cpuset(topology); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
if (cpuset) { return 0;
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
} else
return -1;
} }
static int dontset_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused) static int dontset_thisthread_cpubind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
@ -774,13 +749,9 @@ static int dontget_thread_cpubind(hwloc_topology_t topology __hwloc_attribute_un
static int dontset_return_complete_nodeset(hwloc_topology_t topology, hwloc_nodeset_t set, hwloc_membind_policy_t *policy) static int dontset_return_complete_nodeset(hwloc_topology_t topology, hwloc_nodeset_t set, hwloc_membind_policy_t *policy)
{ {
hwloc_const_nodeset_t nodeset = hwloc_topology_get_complete_nodeset(topology); hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
if (nodeset) { *policy = HWLOC_MEMBIND_MIXED;
hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology)); return 0;
*policy = HWLOC_MEMBIND_DEFAULT;
return 0;
} else
return -1;
} }
static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused) static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
@ -835,7 +806,7 @@ static int dontfree_membind(hwloc_topology_t topology __hwloc_attribute_unused,
} }
static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks, static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused) struct hwloc_topology_support *support __hwloc_attribute_unused)
{ {
hooks->set_thisproc_cpubind = dontset_thisproc_cpubind; hooks->set_thisproc_cpubind = dontset_thisproc_cpubind;
hooks->get_thisproc_cpubind = dontget_thisproc_cpubind; hooks->get_thisproc_cpubind = dontget_thisproc_cpubind;

1676
opal/mca/hwloc/hwloc201/hwloc/hwloc/bitmap.c Обычный файл

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -39,13 +39,13 @@ static const char * hwloc_plugins_blacklist = NULL;
* Far from perfect, but easy to maintain, and way enough given that this code will never be needed for real. */ * Far from perfect, but easy to maintain, and way enough given that this code will never be needed for real. */
#include <windows.h> #include <windows.h>
static LONG hwloc_components_mutex = 0; static LONG hwloc_components_mutex = 0;
#define HWLOC_COMPONENTS_LOCK() do { \ #define HWLOC_COMPONENTS_LOCK() do { \
while (InterlockedCompareExchange(&hwloc_components_mutex, 1, 0) != 0) \ while (InterlockedCompareExchange(&hwloc_components_mutex, 1, 0) != 0) \
SwitchToThread(); \ SwitchToThread(); \
} while (0) } while (0)
#define HWLOC_COMPONENTS_UNLOCK() do { \ #define HWLOC_COMPONENTS_UNLOCK() do { \
assert(hwloc_components_mutex == 1); \ assert(hwloc_components_mutex == 1); \
hwloc_components_mutex = 0; \ hwloc_components_mutex = 0; \
} while (0) } while (0)
#elif defined HWLOC_HAVE_PTHREAD_MUTEX #elif defined HWLOC_HAVE_PTHREAD_MUTEX
@ -78,7 +78,6 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
{ {
const char *basename; const char *basename;
lt_dlhandle handle; lt_dlhandle handle;
char *componentsymbolname = NULL;
struct hwloc_component *component; struct hwloc_component *component;
struct hwloc__plugin_desc *desc, **prevdesc; struct hwloc__plugin_desc *desc, **prevdesc;
@ -104,43 +103,44 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror()); fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror());
goto out; goto out;
} }
componentsymbolname = malloc(strlen(basename)+10+1);
{
char componentsymbolname[strlen(basename)+10+1];
sprintf(componentsymbolname, "%s_component", basename); sprintf(componentsymbolname, "%s_component", basename);
component = lt_dlsym(handle, componentsymbolname); component = lt_dlsym(handle, componentsymbolname);
if (!component) { if (!component) {
if (hwloc_plugins_verbose) if (hwloc_plugins_verbose)
fprintf(stderr, "Failed to find component symbol `%s'\n", fprintf(stderr, "Failed to find component symbol `%s'\n",
componentsymbolname); componentsymbolname);
goto out_with_handle; goto out_with_handle;
} }
if (component->abi != HWLOC_COMPONENT_ABI) { if (component->abi != HWLOC_COMPONENT_ABI) {
if (hwloc_plugins_verbose) if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin symbol ABI %u instead of %d\n", fprintf(stderr, "Plugin symbol ABI %u instead of %d\n",
component->abi, HWLOC_COMPONENT_ABI); component->abi, HWLOC_COMPONENT_ABI);
goto out_with_handle; goto out_with_handle;
} }
if (hwloc_plugins_verbose) if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin contains expected symbol `%s'\n", fprintf(stderr, "Plugin contains expected symbol `%s'\n",
componentsymbolname); componentsymbolname);
free(componentsymbolname); }
componentsymbolname = NULL;
if (HWLOC_COMPONENT_TYPE_DISC == component->type) { if (HWLOC_COMPONENT_TYPE_DISC == component->type) {
if (strncmp(basename, "hwloc_", 6)) { if (strncmp(basename, "hwloc_", 6)) {
if (hwloc_plugins_verbose) if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin name `%s' doesn't match its type DISCOVERY\n", basename); fprintf(stderr, "Plugin name `%s' doesn't match its type DISCOVERY\n", basename);
goto out_with_handle; goto out_with_handle;
} }
} else if (HWLOC_COMPONENT_TYPE_XML == component->type) { } else if (HWLOC_COMPONENT_TYPE_XML == component->type) {
if (strncmp(basename, "hwloc_xml_", 10)) { if (strncmp(basename, "hwloc_xml_", 10)) {
if (hwloc_plugins_verbose) if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin name `%s' doesn't match its type XML\n", basename); fprintf(stderr, "Plugin name `%s' doesn't match its type XML\n", basename);
goto out_with_handle; goto out_with_handle;
} }
} else { } else {
if (hwloc_plugins_verbose) if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin name `%s' has invalid type %u\n", fprintf(stderr, "Plugin name `%s' has invalid type %u\n",
basename, (unsigned) component->type); basename, (unsigned) component->type);
goto out_with_handle; goto out_with_handle;
} }
@ -167,7 +167,6 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
out_with_handle: out_with_handle:
lt_dlclose(handle); lt_dlclose(handle);
free(componentsymbolname); /* NULL if already freed */
out: out:
return 0; return 0;
} }
@ -246,7 +245,7 @@ hwloc_disc_component_type_string(hwloc_disc_component_type_t type)
static int static int
hwloc_disc_component_register(struct hwloc_disc_component *component, hwloc_disc_component_register(struct hwloc_disc_component *component,
const char *filename) const char *filename)
{ {
struct hwloc_disc_component **prev; struct hwloc_disc_component **prev;
@ -260,7 +259,7 @@ hwloc_disc_component_register(struct hwloc_disc_component *component,
|| strcspn(component->name, HWLOC_COMPONENT_SEPS) != strlen(component->name)) { || strcspn(component->name, HWLOC_COMPONENT_SEPS) != strlen(component->name)) {
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Cannot register discovery component with name `%s' containing reserved characters `%c" HWLOC_COMPONENT_SEPS "'\n", fprintf(stderr, "Cannot register discovery component with name `%s' containing reserved characters `%c" HWLOC_COMPONENT_SEPS "'\n",
component->name, HWLOC_COMPONENT_EXCLUDE_CHAR); component->name, HWLOC_COMPONENT_EXCLUDE_CHAR);
return -1; return -1;
} }
/* check that the component type is valid */ /* check that the component type is valid */
@ -271,7 +270,7 @@ hwloc_disc_component_register(struct hwloc_disc_component *component,
break; break;
default: default:
fprintf(stderr, "Cannot register discovery component `%s' with unknown type %u\n", fprintf(stderr, "Cannot register discovery component `%s' with unknown type %u\n",
component->name, (unsigned) component->type); component->name, (unsigned) component->type);
return -1; return -1;
} }
@ -280,25 +279,25 @@ hwloc_disc_component_register(struct hwloc_disc_component *component,
if (!strcmp((*prev)->name, component->name)) { if (!strcmp((*prev)->name, component->name)) {
/* if two components have the same name, only keep the highest priority one */ /* if two components have the same name, only keep the highest priority one */
if ((*prev)->priority < component->priority) { if ((*prev)->priority < component->priority) {
/* drop the existing component */ /* drop the existing component */
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Dropping previously registered discovery component `%s', priority %u lower than new one %u\n", fprintf(stderr, "Dropping previously registered discovery component `%s', priority %u lower than new one %u\n",
(*prev)->name, (*prev)->priority, component->priority); (*prev)->name, (*prev)->priority, component->priority);
*prev = (*prev)->next; *prev = (*prev)->next;
} else { } else {
/* drop the new one */ /* drop the new one */
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Ignoring new discovery component `%s', priority %u lower than previously registered one %u\n", fprintf(stderr, "Ignoring new discovery component `%s', priority %u lower than previously registered one %u\n",
component->name, component->priority, (*prev)->priority); component->name, component->priority, (*prev)->priority);
return -1; return -1;
} }
} }
prev = &((*prev)->next); prev = &((*prev)->next);
} }
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Registered %s discovery component `%s' with priority %u (%s%s)\n", fprintf(stderr, "Registered %s discovery component `%s' with priority %u (%s%s)\n",
hwloc_disc_component_type_string(component->type), component->name, component->priority, hwloc_disc_component_type_string(component->type), component->name, component->priority,
filename ? "from plugin " : "statically build", filename ? filename : ""); filename ? "from plugin " : "statically build", filename ? filename : "");
prev = &hwloc_disc_components; prev = &hwloc_disc_components;
while (NULL != *prev) { while (NULL != *prev) {
@ -350,7 +349,7 @@ hwloc_components_init(void)
#endif #endif
if (hwloc_component_finalize_cb_count) { if (hwloc_component_finalize_cb_count) {
hwloc_component_finalize_cbs = calloc(hwloc_component_finalize_cb_count, hwloc_component_finalize_cbs = calloc(hwloc_component_finalize_cb_count,
sizeof(*hwloc_component_finalize_cbs)); sizeof(*hwloc_component_finalize_cbs));
assert(hwloc_component_finalize_cbs); assert(hwloc_component_finalize_cbs);
/* forget that max number and recompute the real one below */ /* forget that max number and recompute the real one below */
hwloc_component_finalize_cb_count = 0; hwloc_component_finalize_cb_count = 0;
@ -360,14 +359,14 @@ hwloc_components_init(void)
for(i=0; NULL != hwloc_static_components[i]; i++) { for(i=0; NULL != hwloc_static_components[i]; i++) {
if (hwloc_static_components[i]->flags) { if (hwloc_static_components[i]->flags) {
fprintf(stderr, "Ignoring static component with invalid flags %lx\n", fprintf(stderr, "Ignoring static component with invalid flags %lx\n",
hwloc_static_components[i]->flags); hwloc_static_components[i]->flags);
continue; continue;
} }
/* initialize the component */ /* initialize the component */
if (hwloc_static_components[i]->init && hwloc_static_components[i]->init(0) < 0) { if (hwloc_static_components[i]->init && hwloc_static_components[i]->init(0) < 0) {
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Ignoring static component, failed to initialize\n"); fprintf(stderr, "Ignoring static component, failed to initialize\n");
continue; continue;
} }
/* queue ->finalize() callback if any */ /* queue ->finalize() callback if any */
@ -388,14 +387,14 @@ hwloc_components_init(void)
for(desc = hwloc_plugins; NULL != desc; desc = desc->next) { for(desc = hwloc_plugins; NULL != desc; desc = desc->next) {
if (desc->component->flags) { if (desc->component->flags) {
fprintf(stderr, "Ignoring plugin `%s' component with invalid flags %lx\n", fprintf(stderr, "Ignoring plugin `%s' component with invalid flags %lx\n",
desc->name, desc->component->flags); desc->name, desc->component->flags);
continue; continue;
} }
/* initialize the component */ /* initialize the component */
if (desc->component->init && desc->component->init(0) < 0) { if (desc->component->init && desc->component->init(0) < 0) {
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Ignoring plugin `%s', failed to initialize\n", desc->name); fprintf(stderr, "Ignoring plugin `%s', failed to initialize\n", desc->name);
continue; continue;
} }
/* queue ->finalize() callback if any */ /* queue ->finalize() callback if any */
@ -424,7 +423,7 @@ hwloc_backends_init(struct hwloc_topology *topology)
static struct hwloc_disc_component * static struct hwloc_disc_component *
hwloc_disc_component_find(int type /* hwloc_disc_component_type_t or -1 if any */, hwloc_disc_component_find(int type /* hwloc_disc_component_type_t or -1 if any */,
const char *name /* name of NULL if any */) const char *name /* name of NULL if any */)
{ {
struct hwloc_disc_component *comp = hwloc_disc_components; struct hwloc_disc_component *comp = hwloc_disc_components;
while (NULL != comp) { while (NULL != comp) {
@ -439,9 +438,9 @@ hwloc_disc_component_find(int type /* hwloc_disc_component_type_t or -1 if any *
/* used by set_xml(), set_synthetic(), ... environment variables, ... to force the first backend */ /* used by set_xml(), set_synthetic(), ... environment variables, ... to force the first backend */
int int
hwloc_disc_component_force_enable(struct hwloc_topology *topology, hwloc_disc_component_force_enable(struct hwloc_topology *topology,
int envvar_forced, int envvar_forced,
int type, const char *name, int type, const char *name,
const void *data1, const void *data2, const void *data3) const void *data1, const void *data2, const void *data3)
{ {
struct hwloc_disc_component *comp; struct hwloc_disc_component *comp;
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -469,9 +468,9 @@ hwloc_disc_component_force_enable(struct hwloc_topology *topology,
static int static int
hwloc_disc_component_try_enable(struct hwloc_topology *topology, hwloc_disc_component_try_enable(struct hwloc_topology *topology,
struct hwloc_disc_component *comp, struct hwloc_disc_component *comp,
const char *comparg, const char *comparg,
int envvar_forced) int envvar_forced)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -480,7 +479,7 @@ hwloc_disc_component_try_enable(struct hwloc_topology *topology,
/* do not warn if envvar_forced since system-wide HWLOC_COMPONENTS must be silently ignored after set_xml() etc. /* do not warn if envvar_forced since system-wide HWLOC_COMPONENTS must be silently ignored after set_xml() etc.
*/ */
fprintf(stderr, "Excluding %s discovery component `%s', conflicts with excludes 0x%x\n", fprintf(stderr, "Excluding %s discovery component `%s', conflicts with excludes 0x%x\n",
hwloc_disc_component_type_string(comp->type), comp->name, topology->backend_excludes); hwloc_disc_component_type_string(comp->type), comp->name, topology->backend_excludes);
return -1; return -1;
} }
@ -515,49 +514,49 @@ hwloc_disc_components_enable_others(struct hwloc_topology *topology)
while (*curenv) { while (*curenv) {
s = strcspn(curenv, HWLOC_COMPONENT_SEPS); s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
if (s) { if (s) {
char c; char c;
/* replace linuxpci with linuxio for backward compatibility with pre-v2.0 */ /* replace linuxpci with linuxio for backward compatibility with pre-v2.0 */
if (!strncmp(curenv, "linuxpci", 8) && s == 8) { if (!strncmp(curenv, "linuxpci", 8) && s == 8) {
curenv[5] = 'i'; curenv[5] = 'i';
curenv[6] = 'o'; curenv[6] = 'o';
curenv[7] = *HWLOC_COMPONENT_SEPS; curenv[7] = *HWLOC_COMPONENT_SEPS;
} else if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, "linuxpci", 8) && s == 9) { } else if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, "linuxpci", 8) && s == 9) {
curenv[6] = 'i'; curenv[6] = 'i';
curenv[7] = 'o'; curenv[7] = 'o';
curenv[8] = *HWLOC_COMPONENT_SEPS; curenv[8] = *HWLOC_COMPONENT_SEPS;
/* skip this name, it's a negated one */ /* skip this name, it's a negated one */
goto nextname; goto nextname;
} }
if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR) if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR)
goto nextname; goto nextname;
if (!strncmp(curenv, HWLOC_COMPONENT_STOP_NAME, s)) { if (!strncmp(curenv, HWLOC_COMPONENT_STOP_NAME, s)) {
tryall = 0; tryall = 0;
break; break;
} }
/* save the last char and replace with \0 */ /* save the last char and replace with \0 */
c = curenv[s]; c = curenv[s];
curenv[s] = '\0'; curenv[s] = '\0';
comp = hwloc_disc_component_find(-1, curenv); comp = hwloc_disc_component_find(-1, curenv);
if (comp) { if (comp) {
hwloc_disc_component_try_enable(topology, comp, NULL, 1 /* envvar forced */); hwloc_disc_component_try_enable(topology, comp, NULL, 1 /* envvar forced */);
} else { } else {
fprintf(stderr, "Cannot find discovery component `%s'\n", curenv); fprintf(stderr, "Cannot find discovery component `%s'\n", curenv);
} }
/* restore chars (the second loop below needs env to be unmodified) */ /* restore chars (the second loop below needs env to be unmodified) */
curenv[s] = c; curenv[s] = c;
} }
nextname: nextname:
curenv += s; curenv += s;
if (*curenv) if (*curenv)
/* Skip comma */ /* Skip comma */
curenv++; curenv++;
} }
} }
@ -567,22 +566,24 @@ nextname:
if (tryall) { if (tryall) {
comp = hwloc_disc_components; comp = hwloc_disc_components;
while (NULL != comp) { while (NULL != comp) {
if (!comp->enabled_by_default)
goto nextcomp;
/* check if this component was explicitly excluded in env */ /* check if this component was explicitly excluded in env */
if (env) { if (env) {
char *curenv = env; char *curenv = env;
while (*curenv) { while (*curenv) {
size_t s = strcspn(curenv, HWLOC_COMPONENT_SEPS); size_t s = strcspn(curenv, HWLOC_COMPONENT_SEPS);
if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, comp->name, s-1) && strlen(comp->name) == s-1) { if (curenv[0] == HWLOC_COMPONENT_EXCLUDE_CHAR && !strncmp(curenv+1, comp->name, s-1) && strlen(comp->name) == s-1) {
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Excluding %s discovery component `%s' because of HWLOC_COMPONENTS environment variable\n", fprintf(stderr, "Excluding %s discovery component `%s' because of HWLOC_COMPONENTS environment variable\n",
hwloc_disc_component_type_string(comp->type), comp->name); hwloc_disc_component_type_string(comp->type), comp->name);
goto nextcomp; goto nextcomp;
} }
curenv += s; curenv += s;
if (*curenv) if (*curenv)
/* Skip comma */ /* Skip comma */
curenv++; curenv++;
} }
} }
hwloc_disc_component_try_enable(topology, comp, NULL, 0 /* defaults, not envvar forced */); hwloc_disc_component_try_enable(topology, comp, NULL, 0 /* defaults, not envvar forced */);
nextcomp: nextcomp:
@ -671,7 +672,7 @@ hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *back
/* check backend flags */ /* check backend flags */
if (backend->flags) { if (backend->flags) {
fprintf(stderr, "Cannot enable %s discovery component `%s' with unknown flags %lx\n", fprintf(stderr, "Cannot enable %s discovery component `%s' with unknown flags %lx\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name, backend->flags); hwloc_disc_component_type_string(backend->component->type), backend->component->name, backend->flags);
return -1; return -1;
} }
@ -680,8 +681,8 @@ hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *back
while (NULL != *pprev) { while (NULL != *pprev) {
if ((*pprev)->component == backend->component) { if ((*pprev)->component == backend->component) {
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Cannot enable %s discovery component `%s' twice\n", fprintf(stderr, "Cannot enable %s discovery component `%s' twice\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name); hwloc_disc_component_type_string(backend->component->type), backend->component->name);
hwloc_backend_disable(backend); hwloc_backend_disable(backend);
errno = EBUSY; errno = EBUSY;
return -1; return -1;
@ -691,7 +692,7 @@ hwloc_backend_enable(struct hwloc_topology *topology, struct hwloc_backend *back
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Enabling %s discovery component `%s'\n", fprintf(stderr, "Enabling %s discovery component `%s'\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name); hwloc_disc_component_type_string(backend->component->type), backend->component->name);
/* enqueue at the end */ /* enqueue at the end */
pprev = &topology->backends; pprev = &topology->backends;
@ -775,7 +776,7 @@ hwloc_backends_disable_all(struct hwloc_topology *topology)
struct hwloc_backend *next = backend->next; struct hwloc_backend *next = backend->next;
if (hwloc_components_verbose) if (hwloc_components_verbose)
fprintf(stderr, "Disabling %s discovery component `%s'\n", fprintf(stderr, "Disabling %s discovery component `%s'\n",
hwloc_disc_component_type_string(backend->component->type), backend->component->name); hwloc_disc_component_type_string(backend->component->type), backend->component->name);
hwloc_backend_disable(backend); hwloc_backend_disable(backend);
topology->backends = next; topology->backends = next;
} }

492
opal/mca/hwloc/hwloc201/hwloc/hwloc/diff.c Обычный файл
Просмотреть файл

@ -0,0 +1,492 @@
/*
* Copyright © 2013-2018 Inria. All rights reserved.
* See COPYING in top-level directory.
*/
#include <private/autogen/config.h>
#include <private/private.h>
#include <private/misc.h>
int hwloc_topology_diff_destroy(hwloc_topology_diff_t diff)
{
hwloc_topology_diff_t next;
while (diff) {
next = diff->generic.next;
switch (diff->generic.type) {
default:
break;
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR:
switch (diff->obj_attr.diff.generic.type) {
default:
break;
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME:
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO:
free(diff->obj_attr.diff.string.name);
free(diff->obj_attr.diff.string.oldvalue);
free(diff->obj_attr.diff.string.newvalue);
break;
}
break;
}
free(diff);
diff = next;
}
return 0;
}
/************************
* Computing diffs
*/
static void hwloc_append_diff(hwloc_topology_diff_t newdiff,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
if (*firstdiffp)
(*lastdiffp)->generic.next = newdiff;
else
*firstdiffp = newdiff;
*lastdiffp = newdiff;
newdiff->generic.next = NULL;
}
static int hwloc_append_diff_too_complex(hwloc_obj_t obj1,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->too_complex.type = HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX;
newdiff->too_complex.obj_depth = obj1->depth;
newdiff->too_complex.obj_index = obj1->logical_index;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int hwloc_append_diff_obj_attr_string(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type,
const char *name,
const char *oldvalue,
const char *newvalue,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.string.type = type;
newdiff->obj_attr.diff.string.name = name ? strdup(name) : NULL;
newdiff->obj_attr.diff.string.oldvalue = oldvalue ? strdup(oldvalue) : NULL;
newdiff->obj_attr.diff.string.newvalue = newvalue ? strdup(newvalue) : NULL;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int hwloc_append_diff_obj_attr_uint64(hwloc_obj_t obj,
hwloc_topology_diff_obj_attr_type_t type,
hwloc_uint64_t idx,
hwloc_uint64_t oldvalue,
hwloc_uint64_t newvalue,
hwloc_topology_diff_t *firstdiffp,
hwloc_topology_diff_t *lastdiffp)
{
hwloc_topology_diff_t newdiff;
newdiff = malloc(sizeof(*newdiff));
if (!newdiff)
return -1;
newdiff->obj_attr.type = HWLOC_TOPOLOGY_DIFF_OBJ_ATTR;
newdiff->obj_attr.obj_depth = obj->depth;
newdiff->obj_attr.obj_index = obj->logical_index;
newdiff->obj_attr.diff.uint64.type = type;
newdiff->obj_attr.diff.uint64.index = idx;
newdiff->obj_attr.diff.uint64.oldvalue = oldvalue;
newdiff->obj_attr.diff.uint64.newvalue = newvalue;
hwloc_append_diff(newdiff, firstdiffp, lastdiffp);
return 0;
}
static int
hwloc_diff_trees(hwloc_topology_t topo1, hwloc_obj_t obj1,
hwloc_topology_t topo2, hwloc_obj_t obj2,
unsigned flags,
hwloc_topology_diff_t *firstdiffp, hwloc_topology_diff_t *lastdiffp)
{
unsigned i;
int err;
hwloc_obj_t child1, child2;
if (obj1->depth != obj2->depth)
goto out_too_complex;
if (obj1->type != obj2->type)
goto out_too_complex;
if ((!obj1->subtype) != (!obj2->subtype)
|| (obj1->subtype && strcmp(obj1->subtype, obj2->subtype)))
goto out_too_complex;
if (obj1->os_index != obj2->os_index)
/* we could allow different os_index for non-PU non-NUMAnode objects
* but it's likely useless anyway */
goto out_too_complex;
#define _SETS_DIFFERENT(_set1, _set2) \
( ( !(_set1) != !(_set2) ) \
|| ( (_set1) && !hwloc_bitmap_isequal(_set1, _set2) ) )
#define SETS_DIFFERENT(_set, _obj1, _obj2) _SETS_DIFFERENT((_obj1)->_set, (_obj2)->_set)
if (SETS_DIFFERENT(cpuset, obj1, obj2)
|| SETS_DIFFERENT(complete_cpuset, obj1, obj2)
|| SETS_DIFFERENT(nodeset, obj1, obj2)
|| SETS_DIFFERENT(complete_nodeset, obj1, obj2))
goto out_too_complex;
/* no need to check logical_index, sibling_rank, symmetric_subtree,
* the parents did it */
/* gp_index don't have to be strictly identical */
if ((!obj1->name) != (!obj2->name)
|| (obj1->name && strcmp(obj1->name, obj2->name))) {
err = hwloc_append_diff_obj_attr_string(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME,
NULL,
obj1->name,
obj2->name,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
/* type-specific attrs */
switch (obj1->type) {
default:
break;
case HWLOC_OBJ_NUMANODE:
if (obj1->attr->numanode.local_memory != obj2->attr->numanode.local_memory) {
err = hwloc_append_diff_obj_attr_uint64(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE,
0,
obj1->attr->numanode.local_memory,
obj2->attr->numanode.local_memory,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
/* ignore memory page_types */
break;
case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE:
case HWLOC_OBJ_L4CACHE:
case HWLOC_OBJ_L5CACHE:
case HWLOC_OBJ_L1ICACHE:
case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->cache)))
goto out_too_complex;
break;
case HWLOC_OBJ_GROUP:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->group)))
goto out_too_complex;
break;
case HWLOC_OBJ_PCI_DEVICE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->pcidev)))
goto out_too_complex;
break;
case HWLOC_OBJ_BRIDGE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->bridge)))
goto out_too_complex;
break;
case HWLOC_OBJ_OS_DEVICE:
if (memcmp(obj1->attr, obj2->attr, sizeof(obj1->attr->osdev)))
goto out_too_complex;
break;
}
/* infos */
if (obj1->infos_count != obj2->infos_count)
goto out_too_complex;
for(i=0; i<obj1->infos_count; i++) {
struct hwloc_info_s *info1 = &obj1->infos[i], *info2 = &obj2->infos[i];
if (strcmp(info1->name, info2->name))
goto out_too_complex;
if (strcmp(obj1->infos[i].value, obj2->infos[i].value)) {
err = hwloc_append_diff_obj_attr_string(obj1,
HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO,
info1->name,
info1->value,
info2->value,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
}
/* ignore userdata */
/* children */
for(child1 = obj1->first_child, child2 = obj2->first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
/* memory children */
for(child1 = obj1->memory_first_child, child2 = obj2->memory_first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
/* I/O children */
for(child1 = obj1->io_first_child, child2 = obj2->io_first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
/* misc children */
for(child1 = obj1->misc_first_child, child2 = obj2->misc_first_child;
child1 != NULL && child2 != NULL;
child1 = child1->next_sibling, child2 = child2->next_sibling) {
err = hwloc_diff_trees(topo1, child1,
topo2, child2,
flags,
firstdiffp, lastdiffp);
if (err < 0)
return err;
}
if (child1 || child2)
goto out_too_complex;
return 0;
out_too_complex:
hwloc_append_diff_too_complex(obj1, firstdiffp, lastdiffp);
return 0;
}
int hwloc_topology_diff_build(hwloc_topology_t topo1,
hwloc_topology_t topo2,
unsigned long flags,
hwloc_topology_diff_t *diffp)
{
hwloc_topology_diff_t lastdiff, tmpdiff;
struct hwloc_internal_distances_s *dist1, *dist2;
unsigned i;
int err;
if (!topo1->is_loaded || !topo2->is_loaded) {
errno = EINVAL;
return -1;
}
if (flags != 0) {
errno = EINVAL;
return -1;
}
*diffp = NULL;
err = hwloc_diff_trees(topo1, hwloc_get_root_obj(topo1),
topo2, hwloc_get_root_obj(topo2),
flags,
diffp, &lastdiff);
if (!err) {
tmpdiff = *diffp;
while (tmpdiff) {
if (tmpdiff->generic.type == HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX) {
err = 1;
break;
}
tmpdiff = tmpdiff->generic.next;
}
}
if (!err) {
if (SETS_DIFFERENT(allowed_cpuset, topo1, topo2)
|| SETS_DIFFERENT(allowed_nodeset, topo1, topo2)) {
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
err = 1;
}
}
if (!err) {
/* distances */
hwloc_internal_distances_refresh(topo1);
hwloc_internal_distances_refresh(topo2);
dist1 = topo1->first_dist;
dist2 = topo2->first_dist;
while (dist1 || dist2) {
if (!!dist1 != !!dist2) {
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
err = 1;
break;
}
if (dist1->type != dist2->type
|| dist1->nbobjs != dist2->nbobjs
|| dist1->kind != dist2->kind
|| memcmp(dist1->values, dist2->values, dist1->nbobjs * dist1->nbobjs * sizeof(*dist1->values))) {
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
err = 1;
break;
}
for(i=0; i<dist1->nbobjs; i++)
/* gp_index isn't enforced above. so compare logical_index instead, which is enforced. requires distances refresh() above */
if (dist1->objs[i]->logical_index != dist2->objs[i]->logical_index) {
hwloc_append_diff_too_complex(hwloc_get_root_obj(topo1), diffp, &lastdiff);
err = 1;
break;
}
dist1 = dist1->next;
dist2 = dist2->next;
}
}
return err;
}
/********************
* Applying diffs
*/
static int
hwloc_apply_diff_one(hwloc_topology_t topology,
hwloc_topology_diff_t diff,
unsigned long flags)
{
int reverse = !!(flags & HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
switch (diff->generic.type) {
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR: {
struct hwloc_topology_diff_obj_attr_s *obj_attr = &diff->obj_attr;
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, obj_attr->obj_depth, obj_attr->obj_index);
if (!obj)
return -1;
switch (obj_attr->diff.generic.type) {
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_SIZE: {
hwloc_obj_t tmpobj;
hwloc_uint64_t oldvalue = reverse ? obj_attr->diff.uint64.newvalue : obj_attr->diff.uint64.oldvalue;
hwloc_uint64_t newvalue = reverse ? obj_attr->diff.uint64.oldvalue : obj_attr->diff.uint64.newvalue;
hwloc_uint64_t valuediff = newvalue - oldvalue;
if (obj->type != HWLOC_OBJ_NUMANODE)
return -1;
if (obj->attr->numanode.local_memory != oldvalue)
return -1;
obj->attr->numanode.local_memory = newvalue;
tmpobj = obj;
while (tmpobj) {
tmpobj->total_memory += valuediff;
tmpobj = tmpobj->parent;
}
break;
}
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_NAME: {
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
if (!obj->name || strcmp(obj->name, oldvalue))
return -1;
free(obj->name);
obj->name = strdup(newvalue);
break;
}
case HWLOC_TOPOLOGY_DIFF_OBJ_ATTR_INFO: {
const char *name = obj_attr->diff.string.name;
const char *oldvalue = reverse ? obj_attr->diff.string.newvalue : obj_attr->diff.string.oldvalue;
const char *newvalue = reverse ? obj_attr->diff.string.oldvalue : obj_attr->diff.string.newvalue;
unsigned i;
int found = 0;
for(i=0; i<obj->infos_count; i++) {
struct hwloc_info_s *info = &obj->infos[i];
if (!strcmp(info->name, name)
&& !strcmp(info->value, oldvalue)) {
free(info->value);
info->value = strdup(newvalue);
found = 1;
break;
}
}
if (!found)
return -1;
break;
}
default:
return -1;
}
break;
}
default:
return -1;
}
return 0;
}
int hwloc_topology_diff_apply(hwloc_topology_t topology,
hwloc_topology_diff_t diff,
unsigned long flags)
{
hwloc_topology_diff_t tmpdiff, tmpdiff2;
int err, nr;
if (!topology->is_loaded) {
errno = EINVAL;
return -1;
}
if (flags & ~HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE) {
errno = EINVAL;
return -1;
}
tmpdiff = diff;
nr = 0;
while (tmpdiff) {
nr++;
err = hwloc_apply_diff_one(topology, tmpdiff, flags);
if (err < 0)
goto cancel;
tmpdiff = tmpdiff->generic.next;
}
return 0;
cancel:
tmpdiff2 = tmpdiff;
tmpdiff = diff;
while (tmpdiff != tmpdiff2) {
hwloc_apply_diff_one(topology, tmpdiff, flags ^ HWLOC_TOPOLOGY_DIFF_APPLY_REVERSE);
tmpdiff = tmpdiff->generic.next;
}
errno = EINVAL;
return -nr; /* return the index (starting at 1) of the first element that couldn't be applied */
}

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2010-2017 Inria. All rights reserved. * Copyright © 2010-2018 Inria. All rights reserved.
* Copyright © 2011-2012 Université Bordeaux * Copyright © 2011-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -22,6 +22,7 @@
void hwloc_internal_distances_init(struct hwloc_topology *topology) void hwloc_internal_distances_init(struct hwloc_topology *topology)
{ {
topology->first_dist = topology->last_dist = NULL; topology->first_dist = topology->last_dist = NULL;
topology->next_dist_id = 0;
} }
/* called at the beginning of load() */ /* called at the beginning of load() */
@ -99,6 +100,7 @@ static int hwloc_internal_distances_dup_one(struct hwloc_topology *new, struct h
newdist->type = olddist->type; newdist->type = olddist->type;
newdist->nbobjs = nbobjs; newdist->nbobjs = nbobjs;
newdist->kind = olddist->kind; newdist->kind = olddist->kind;
newdist->id = olddist->id;
newdist->indexes = hwloc_tma_malloc(tma, nbobjs * sizeof(*newdist->indexes)); newdist->indexes = hwloc_tma_malloc(tma, nbobjs * sizeof(*newdist->indexes));
newdist->objs = hwloc_tma_calloc(tma, nbobjs * sizeof(*newdist->objs)); newdist->objs = hwloc_tma_calloc(tma, nbobjs * sizeof(*newdist->objs));
@ -129,6 +131,7 @@ int hwloc_internal_distances_dup(struct hwloc_topology *new, struct hwloc_topolo
{ {
struct hwloc_internal_distances_s *olddist; struct hwloc_internal_distances_s *olddist;
int err; int err;
new->next_dist_id = old->next_dist_id;
for(olddist = old->first_dist; olddist; olddist = olddist->next) { for(olddist = old->first_dist; olddist; olddist = olddist->next) {
err = hwloc_internal_distances_dup_one(new, olddist); err = hwloc_internal_distances_dup_one(new, olddist);
if (err < 0) if (err < 0)
@ -151,7 +154,7 @@ int hwloc_distances_remove(hwloc_topology_t topology)
return 0; return 0;
} }
int hwloc_distances_remove_by_depth(hwloc_topology_t topology, unsigned depth) int hwloc_distances_remove_by_depth(hwloc_topology_t topology, int depth)
{ {
struct hwloc_internal_distances_s *dist, *next; struct hwloc_internal_distances_s *dist, *next;
hwloc_obj_type_t type; hwloc_obj_type_t type;
@ -173,13 +176,13 @@ int hwloc_distances_remove_by_depth(hwloc_topology_t topology, unsigned depth)
next = dist->next; next = dist->next;
if (dist->type == type) { if (dist->type == type) {
if (next) if (next)
next->prev = dist->prev; next->prev = dist->prev;
else else
topology->last_dist = dist->prev; topology->last_dist = dist->prev;
if (dist->prev) if (dist->prev)
dist->prev->next = dist->next; dist->prev->next = dist->next;
else else
topology->first_dist = dist->next; topology->first_dist = dist->next;
hwloc_internal_distances_free(dist); hwloc_internal_distances_free(dist);
} }
} }
@ -199,8 +202,8 @@ hwloc__groups_by_distances(struct hwloc_topology *topology, unsigned nbobjs, str
*/ */
static int static int
hwloc_internal_distances__add(hwloc_topology_t topology, hwloc_internal_distances__add(hwloc_topology_t topology,
hwloc_obj_type_t type, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *indexes, uint64_t *values, hwloc_obj_type_t type, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *indexes, uint64_t *values,
unsigned long kind) unsigned long kind)
{ {
struct hwloc_internal_distances_s *dist = calloc(1, sizeof(*dist)); struct hwloc_internal_distances_s *dist = calloc(1, sizeof(*dist));
if (!dist) if (!dist)
@ -230,15 +233,17 @@ hwloc_internal_distances__add(hwloc_topology_t topology,
goto err_with_dist; goto err_with_dist;
if (dist->type == HWLOC_OBJ_PU || dist->type == HWLOC_OBJ_NUMANODE) { if (dist->type == HWLOC_OBJ_PU || dist->type == HWLOC_OBJ_NUMANODE) {
for(i=0; i<nbobjs; i++) for(i=0; i<nbobjs; i++)
dist->indexes[i] = objs[i]->os_index; dist->indexes[i] = objs[i]->os_index;
} else { } else {
for(i=0; i<nbobjs; i++) for(i=0; i<nbobjs; i++)
dist->indexes[i] = objs[i]->gp_index; dist->indexes[i] = objs[i]->gp_index;
} }
} }
dist->values = values; dist->values = values;
dist->id = topology->next_dist_id++;
if (topology->last_dist) if (topology->last_dist)
topology->last_dist->next = dist; topology->last_dist->next = dist;
else else
@ -258,8 +263,8 @@ hwloc_internal_distances__add(hwloc_topology_t topology,
} }
int hwloc_internal_distances_add_by_index(hwloc_topology_t topology, int hwloc_internal_distances_add_by_index(hwloc_topology_t topology,
hwloc_obj_type_t type, unsigned nbobjs, uint64_t *indexes, uint64_t *values, hwloc_obj_type_t type, unsigned nbobjs, uint64_t *indexes, uint64_t *values,
unsigned long kind, unsigned long flags) unsigned long kind, unsigned long flags)
{ {
if (nbobjs < 2) { if (nbobjs < 2) {
errno = EINVAL; errno = EINVAL;
@ -283,8 +288,8 @@ int hwloc_internal_distances_add_by_index(hwloc_topology_t topology,
} }
int hwloc_internal_distances_add(hwloc_topology_t topology, int hwloc_internal_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values,
unsigned long kind, unsigned long flags) unsigned long kind, unsigned long flags)
{ {
if (nbobjs < 2) { if (nbobjs < 2) {
errno = EINVAL; errno = EINVAL;
@ -310,18 +315,18 @@ int hwloc_internal_distances_add(hwloc_topology_t topology,
fprintf(stderr, "Trying to group objects using distance matrix:\n"); fprintf(stderr, "Trying to group objects using distance matrix:\n");
fprintf(stderr, "%s", gp ? "gp_index" : "os_index"); fprintf(stderr, "%s", gp ? "gp_index" : "os_index");
for(j=0; j<nbobjs; j++) for(j=0; j<nbobjs; j++)
fprintf(stderr, " % 5d", (int)(gp ? objs[j]->gp_index : objs[j]->os_index)); fprintf(stderr, " % 5d", (int)(gp ? objs[j]->gp_index : objs[j]->os_index));
fprintf(stderr, "\n"); fprintf(stderr, "\n");
for(i=0; i<nbobjs; i++) { for(i=0; i<nbobjs; i++) {
fprintf(stderr, " % 5d", (int)(gp ? objs[i]->gp_index : objs[i]->os_index)); fprintf(stderr, " % 5d", (int)(gp ? objs[i]->gp_index : objs[i]->os_index));
for(j=0; j<nbobjs; j++) for(j=0; j<nbobjs; j++)
fprintf(stderr, " % 5lld", (long long) values[i*nbobjs + j]); fprintf(stderr, " % 5lld", (long long) values[i*nbobjs + j]);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
} }
hwloc__groups_by_distances(topology, nbobjs, objs, values, hwloc__groups_by_distances(topology, nbobjs, objs, values,
kind, nbaccuracies, accuracies, 1 /* check the first matrice */); kind, nbaccuracies, accuracies, 1 /* check the first matrice */);
} }
return hwloc_internal_distances__add(topology, objs[0]->type, nbobjs, objs, NULL, values, kind); return hwloc_internal_distances__add(topology, objs[0]->type, nbobjs, objs, NULL, values, kind);
@ -340,8 +345,8 @@ int hwloc_internal_distances_add(hwloc_topology_t topology,
/* The actual function exported to the user /* The actual function exported to the user
*/ */
int hwloc_distances_add(hwloc_topology_t topology, int hwloc_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values,
unsigned long kind, unsigned long flags) unsigned long kind, unsigned long flags)
{ {
hwloc_obj_type_t type; hwloc_obj_type_t type;
unsigned i; unsigned i;
@ -417,8 +422,8 @@ static hwloc_obj_t hwloc_find_obj_by_type_and_gp_index(hwloc_topology_t topology
static void static void
hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist, hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist,
hwloc_obj_t *objs, hwloc_obj_t *objs,
unsigned disappeared) unsigned disappeared)
{ {
unsigned nbobjs = dist->nbobjs; unsigned nbobjs = dist->nbobjs;
unsigned i, newi; unsigned i, newi;
@ -427,10 +432,10 @@ hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist,
for(i=0, newi=0; i<nbobjs; i++) for(i=0, newi=0; i<nbobjs; i++)
if (objs[i]) { if (objs[i]) {
for(j=0, newj=0; j<nbobjs; j++) for(j=0, newj=0; j<nbobjs; j++)
if (objs[j]) { if (objs[j]) {
dist->values[newi*(nbobjs-disappeared)+newj] = dist->values[i*nbobjs+j]; dist->values[newi*(nbobjs-disappeared)+newj] = dist->values[i*nbobjs+j];
newj++; newj++;
} }
newi++; newi++;
} }
@ -446,7 +451,7 @@ hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist,
static int static int
hwloc_internal_distances_refresh_one(hwloc_topology_t topology, hwloc_internal_distances_refresh_one(hwloc_topology_t topology,
struct hwloc_internal_distances_s *dist) struct hwloc_internal_distances_s *dist)
{ {
hwloc_obj_type_t type = dist->type; hwloc_obj_type_t type = dist->type;
unsigned nbobjs = dist->nbobjs; unsigned nbobjs = dist->nbobjs;
@ -497,13 +502,13 @@ hwloc_internal_distances_refresh(hwloc_topology_t topology)
if (hwloc_internal_distances_refresh_one(topology, dist) < 0) { if (hwloc_internal_distances_refresh_one(topology, dist) < 0) {
assert(!topology->tma || !topology->tma->dontfree); /* this tma cannot fail to allocate */ assert(!topology->tma || !topology->tma->dontfree); /* this tma cannot fail to allocate */
if (dist->prev) if (dist->prev)
dist->prev->next = next; dist->prev->next = next;
else else
topology->first_dist = next; topology->first_dist = next;
if (next) if (next)
next->prev = dist->prev; next->prev = dist->prev;
else else
topology->last_dist = dist->prev; topology->last_dist = dist->prev;
hwloc_internal_distances_free(dist); hwloc_internal_distances_free(dist);
continue; continue;
} }
@ -524,7 +529,7 @@ hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology)
void void
hwloc_distances_release(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_distances_release(hwloc_topology_t topology __hwloc_attribute_unused,
struct hwloc_distances_s *distances) struct hwloc_distances_s *distances)
{ {
free(distances->values); free(distances->values);
free(distances->objs); free(distances->objs);
@ -533,7 +538,7 @@ hwloc_distances_release(hwloc_topology_t topology __hwloc_attribute_unused,
static struct hwloc_distances_s * static struct hwloc_distances_s *
hwloc_distances_get_one(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_distances_get_one(hwloc_topology_t topology __hwloc_attribute_unused,
struct hwloc_internal_distances_s *dist) struct hwloc_internal_distances_s *dist)
{ {
struct hwloc_distances_s *distances; struct hwloc_distances_s *distances;
unsigned nbobjs; unsigned nbobjs;
@ -566,9 +571,9 @@ hwloc_distances_get_one(hwloc_topology_t topology __hwloc_attribute_unused,
static int static int
hwloc__distances_get(hwloc_topology_t topology, hwloc__distances_get(hwloc_topology_t topology,
hwloc_obj_type_t type, hwloc_obj_type_t type,
unsigned *nrp, struct hwloc_distances_s **distancesp, unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags __hwloc_attribute_unused) unsigned long kind, unsigned long flags __hwloc_attribute_unused)
{ {
struct hwloc_internal_distances_s *dist; struct hwloc_internal_distances_s *dist;
unsigned nr = 0, i; unsigned nr = 0, i;
@ -585,6 +590,11 @@ hwloc__distances_get(hwloc_topology_t topology,
/* we could refresh only the distances that match, but we won't have many distances anyway, /* we could refresh only the distances that match, but we won't have many distances anyway,
* so performance is totally negligible. * so performance is totally negligible.
*
* This is also useful in multithreaded apps that modify the topology.
* They can call any valid hwloc_distances_get() to force a refresh after
* changing the topology, so that future concurrent get() won't cause
* concurrent refresh().
*/ */
hwloc_internal_distances_refresh(topology); hwloc_internal_distances_refresh(topology);
@ -603,7 +613,7 @@ hwloc__distances_get(hwloc_topology_t topology,
if (nr < *nrp) { if (nr < *nrp) {
struct hwloc_distances_s *distances = hwloc_distances_get_one(topology, dist); struct hwloc_distances_s *distances = hwloc_distances_get_one(topology, dist);
if (!distances) if (!distances)
goto error; goto error;
distancesp[nr] = distances; distancesp[nr] = distances;
} }
nr++; nr++;
@ -622,8 +632,8 @@ hwloc__distances_get(hwloc_topology_t topology,
int int
hwloc_distances_get(hwloc_topology_t topology, hwloc_distances_get(hwloc_topology_t topology,
unsigned *nrp, struct hwloc_distances_s **distancesp, unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags) unsigned long kind, unsigned long flags)
{ {
if (flags || !topology->is_loaded) { if (flags || !topology->is_loaded) {
errno = EINVAL; errno = EINVAL;
@ -634,9 +644,9 @@ hwloc_distances_get(hwloc_topology_t topology,
} }
int int
hwloc_distances_get_by_depth(hwloc_topology_t topology, unsigned depth, hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth,
unsigned *nrp, struct hwloc_distances_s **distancesp, unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags) unsigned long kind, unsigned long flags)
{ {
hwloc_obj_type_t type; hwloc_obj_type_t type;
@ -690,10 +700,10 @@ static int hwloc_compare_values(uint64_t a, uint64_t b, float accuracy)
*/ */
static unsigned static unsigned
hwloc__find_groups_by_min_distance(unsigned nbobjs, hwloc__find_groups_by_min_distance(unsigned nbobjs,
uint64_t *_values, uint64_t *_values,
float accuracy, float accuracy,
unsigned *groupids, unsigned *groupids,
int verbose) int verbose)
{ {
uint64_t min_distance = UINT64_MAX; uint64_t min_distance = UINT64_MAX;
unsigned groupid = 1; unsigned groupid = 1;
@ -717,7 +727,7 @@ hwloc__find_groups_by_min_distance(unsigned nbobjs,
/* build groups of objects connected with this distance */ /* build groups of objects connected with this distance */
for(i=0; i<nbobjs; i++) { for(i=0; i<nbobjs; i++) {
unsigned size; unsigned size;
int firstfound; unsigned firstfound;
/* if already grouped, skip */ /* if already grouped, skip */
if (groupids[i]) if (groupids[i])
@ -728,25 +738,25 @@ hwloc__find_groups_by_min_distance(unsigned nbobjs,
size = 1; size = 1;
firstfound = i; firstfound = i;
while (firstfound != -1) { while (firstfound != (unsigned)-1) {
/* we added new objects to the group, the first one was firstfound. /* we added new objects to the group, the first one was firstfound.
* rescan all connections from these new objects (starting at first found) to any other objects, * rescan all connections from these new objects (starting at first found) to any other objects,
* so as to find new objects minimally-connected by transivity. * so as to find new objects minimally-connected by transivity.
*/ */
int newfirstfound = -1; unsigned newfirstfound = (unsigned)-1;
for(j=firstfound; j<nbobjs; j++) for(j=firstfound; j<nbobjs; j++)
if (groupids[j] == groupid) if (groupids[j] == groupid)
for(k=0; k<nbobjs; k++) for(k=0; k<nbobjs; k++)
if (!groupids[k] && !hwloc_compare_values(VALUE(j, k), min_distance, accuracy)) { if (!groupids[k] && !hwloc_compare_values(VALUE(j, k), min_distance, accuracy)) {
groupids[k] = groupid; groupids[k] = groupid;
size++; size++;
if (newfirstfound == -1) if (newfirstfound == (unsigned)-1)
newfirstfound = k; newfirstfound = k;
if (i == j) if (i == j)
hwloc_debug(" object %u is minimally connected to %u\n", k, i); hwloc_debug(" object %u is minimally connected to %u\n", k, i);
else else
hwloc_debug(" object %u is minimally connected to %u through %u\n", k, i, j); hwloc_debug(" object %u is minimally connected to %u through %u\n", k, i, j);
} }
firstfound = newfirstfound; firstfound = newfirstfound;
} }
@ -761,7 +771,7 @@ hwloc__find_groups_by_min_distance(unsigned nbobjs,
groupid++; groupid++;
if (verbose) if (verbose)
fprintf(stderr, " Found transitive graph with %u objects with minimal distance %llu accuracy %f\n", fprintf(stderr, " Found transitive graph with %u objects with minimal distance %llu accuracy %f\n",
size, (unsigned long long) min_distance, accuracy); size, (unsigned long long) min_distance, accuracy);
} }
if (groupid == 2 && !skipped) if (groupid == 2 && !skipped)
@ -781,17 +791,17 @@ hwloc__check_grouping_matrix(unsigned nbobjs, uint64_t *_values, float accuracy,
for(j=i+1; j<nbobjs; j++) { for(j=i+1; j<nbobjs; j++) {
/* should be symmetric */ /* should be symmetric */
if (hwloc_compare_values(VALUE(i, j), VALUE(j, i), accuracy)) { if (hwloc_compare_values(VALUE(i, j), VALUE(j, i), accuracy)) {
if (verbose) if (verbose)
fprintf(stderr, " Distance matrix asymmetric ([%u,%u]=%llu != [%u,%u]=%llu), aborting\n", fprintf(stderr, " Distance matrix asymmetric ([%u,%u]=%llu != [%u,%u]=%llu), aborting\n",
i, j, (unsigned long long) VALUE(i, j), j, i, (unsigned long long) VALUE(j, i)); i, j, (unsigned long long) VALUE(i, j), j, i, (unsigned long long) VALUE(j, i));
return -1; return -1;
} }
/* diagonal is smaller than everything else */ /* diagonal is smaller than everything else */
if (hwloc_compare_values(VALUE(i, j), VALUE(i, i), accuracy) <= 0) { if (hwloc_compare_values(VALUE(i, j), VALUE(i, i), accuracy) <= 0) {
if (verbose) if (verbose)
fprintf(stderr, " Distance to self not strictly minimal ([%u,%u]=%llu <= [%u,%u]=%llu), aborting\n", fprintf(stderr, " Distance to self not strictly minimal ([%u,%u]=%llu <= [%u,%u]=%llu), aborting\n",
i, j, (unsigned long long) VALUE(i, j), i, i, (unsigned long long) VALUE(i, i)); i, j, (unsigned long long) VALUE(i, j), i, i, (unsigned long long) VALUE(i, i));
return -1; return -1;
} }
} }
} }
@ -803,15 +813,15 @@ hwloc__check_grouping_matrix(unsigned nbobjs, uint64_t *_values, float accuracy,
*/ */
static void static void
hwloc__groups_by_distances(struct hwloc_topology *topology, hwloc__groups_by_distances(struct hwloc_topology *topology,
unsigned nbobjs, unsigned nbobjs,
struct hwloc_obj **objs, struct hwloc_obj **objs,
uint64_t *_values, uint64_t *_values,
unsigned long kind, unsigned long kind,
unsigned nbaccuracies, unsigned nbaccuracies,
float *accuracies, float *accuracies,
int needcheck) int needcheck)
{ {
unsigned *groupids = NULL; HWLOC_VLA(unsigned, groupids, nbobjs);
unsigned nbgroups = 0; unsigned nbgroups = 0;
unsigned i,j; unsigned i,j;
int verbose = topology->grouping_verbose; int verbose = topology->grouping_verbose;
@ -824,15 +834,10 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
/* TODO hwloc__find_groups_by_max_distance() for bandwidth */ /* TODO hwloc__find_groups_by_max_distance() for bandwidth */
return; return;
groupids = malloc(sizeof(unsigned) * nbobjs);
if (NULL == groupids) {
return;
}
for(i=0; i<nbaccuracies; i++) { for(i=0; i<nbaccuracies; i++) {
if (verbose) if (verbose)
fprintf(stderr, "Trying to group %u %s objects according to physical distances with accuracy %f\n", fprintf(stderr, "Trying to group %u %s objects according to physical distances with accuracy %f\n",
nbobjs, hwloc_type_name(objs[0]->type), accuracies[i]); nbobjs, hwloc_obj_type_string(objs[0]->type), accuracies[i]);
if (needcheck && hwloc__check_grouping_matrix(nbobjs, _values, accuracies[i], verbose) < 0) if (needcheck && hwloc__check_grouping_matrix(nbobjs, _values, accuracies[i], verbose) < 0)
continue; continue;
nbgroups = hwloc__find_groups_by_min_distance(nbobjs, _values, accuracies[i], groupids, verbose); nbgroups = hwloc__find_groups_by_min_distance(nbobjs, _values, accuracies[i], groupids, verbose);
@ -840,53 +845,44 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
break; break;
} }
if (!nbgroups) if (!nbgroups)
goto outter_free; return;
/* For convenience, put these declarations inside a block. It's a
crying shame we can't use C99 syntax here, and have to do a bunch
of mallocs. :-( */
{ {
hwloc_obj_t *groupobjs = NULL; HWLOC_VLA(hwloc_obj_t, groupobjs, nbgroups);
unsigned *groupsizes = NULL; HWLOC_VLA(unsigned, groupsizes, nbgroups);
uint64_t *groupvalues = NULL; HWLOC_VLA(uint64_t, groupvalues, nbgroups*nbgroups);
unsigned failed = 0; unsigned failed = 0;
groupobjs = malloc(sizeof(hwloc_obj_t) * nbgroups);
groupsizes = malloc(sizeof(unsigned) * nbgroups);
groupvalues = malloc(sizeof(uint64_t) * nbgroups * nbgroups);
if (NULL == groupobjs || NULL == groupsizes || NULL == groupvalues) {
goto inner_free;
}
/* create new Group objects and record their size */ /* create new Group objects and record their size */
memset(&(groupsizes[0]), 0, sizeof(groupsizes[0]) * nbgroups); memset(&(groupsizes[0]), 0, sizeof(groupsizes[0]) * nbgroups);
for(i=0; i<nbgroups; i++) { for(i=0; i<nbgroups; i++) {
/* create the Group object */ /* create the Group object */
hwloc_obj_t group_obj, res_obj; hwloc_obj_t group_obj, res_obj;
group_obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, -1); group_obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, HWLOC_UNKNOWN_INDEX);
group_obj->cpuset = hwloc_bitmap_alloc(); group_obj->cpuset = hwloc_bitmap_alloc();
group_obj->attr->group.kind = HWLOC_GROUP_KIND_DISTANCE; group_obj->attr->group.kind = HWLOC_GROUP_KIND_DISTANCE;
group_obj->attr->group.subkind = topology->grouping_next_subkind; group_obj->attr->group.subkind = topology->grouping_next_subkind;
for (j=0; j<nbobjs; j++) for (j=0; j<nbobjs; j++)
if (groupids[j] == i+1) { if (groupids[j] == i+1) {
/* assemble the group sets */ /* assemble the group sets */
hwloc_obj_add_other_obj_sets(group_obj, objs[j]); hwloc_obj_add_other_obj_sets(group_obj, objs[j]);
groupsizes[i]++; groupsizes[i]++;
} }
hwloc_debug_1arg_bitmap("adding Group object with %u objects and cpuset %s\n", hwloc_debug_1arg_bitmap("adding Group object with %u objects and cpuset %s\n",
groupsizes[i], group_obj->cpuset); groupsizes[i], group_obj->cpuset);
res_obj = hwloc__insert_object_by_cpuset(topology, group_obj, res_obj = hwloc__insert_object_by_cpuset(topology, NULL, group_obj,
(kind & HWLOC_DISTANCES_KIND_FROM_USER) ? hwloc_report_user_distance_error : hwloc_report_os_error); (kind & HWLOC_DISTANCES_KIND_FROM_USER) ? hwloc_report_user_distance_error : hwloc_report_os_error);
/* res_obj may be NULL on failure to insert. */ /* res_obj may be NULL on failure to insert. */
if (!res_obj) if (!res_obj)
failed++; failed++;
/* or it may be different from groupobjs if we got groups from XML import before grouping */ /* or it may be different from groupobjs if we got groups from XML import before grouping */
groupobjs[i] = res_obj; groupobjs[i] = res_obj;
} }
topology->grouping_next_subkind++; topology->grouping_next_subkind++;
if (failed) if (failed)
/* don't try to group above if we got a NULL group here, just keep this incomplete level */ /* don't try to group above if we got a NULL group here, just keep this incomplete level */
goto inner_free; return;
/* factorize values */ /* factorize values */
memset(&(groupvalues[0]), 0, sizeof(groupvalues[0]) * nbgroups * nbgroups); memset(&(groupvalues[0]), 0, sizeof(groupvalues[0]) * nbgroups * nbgroups);
@ -894,9 +890,9 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
#define VALUE(i, j) _values[(i) * nbobjs + (j)] #define VALUE(i, j) _values[(i) * nbobjs + (j)]
#define GROUP_VALUE(i, j) groupvalues[(i) * nbgroups + (j)] #define GROUP_VALUE(i, j) groupvalues[(i) * nbgroups + (j)]
for(i=0; i<nbobjs; i++) for(i=0; i<nbobjs; i++)
if (groupids[i]) if (groupids[i])
for(j=0; j<nbobjs; j++) for(j=0; j<nbobjs; j++)
if (groupids[j]) if (groupids[j])
GROUP_VALUE(groupids[i]-1, groupids[j]-1) += VALUE(i, j); GROUP_VALUE(groupids[i]-1, groupids[j]-1) += VALUE(i, j);
for(i=0; i<nbgroups; i++) for(i=0; i<nbgroups; i++)
for(j=0; j<nbgroups; j++) { for(j=0; j<nbgroups; j++) {
@ -907,25 +903,16 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
hwloc_debug("%s", "generated new distance matrix between groups:\n"); hwloc_debug("%s", "generated new distance matrix between groups:\n");
hwloc_debug("%s", " index"); hwloc_debug("%s", " index");
for(j=0; j<nbgroups; j++) for(j=0; j<nbgroups; j++)
hwloc_debug(" % 5d", (int) j); /* print index because os_index is -1 for Groups */ hwloc_debug(" % 5d", (int) j); /* print index because os_index is -1 for Groups */
hwloc_debug("%s", "\n"); hwloc_debug("%s", "\n");
for(i=0; i<nbgroups; i++) { for(i=0; i<nbgroups; i++) {
hwloc_debug(" % 5d", (int) i); hwloc_debug(" % 5d", (int) i);
for(j=0; j<nbgroups; j++) for(j=0; j<nbgroups; j++)
hwloc_debug(" %llu", (unsigned long long) GROUP_VALUE(i, j)); hwloc_debug(" %llu", (unsigned long long) GROUP_VALUE(i, j));
hwloc_debug("%s", "\n"); hwloc_debug("%s", "\n");
} }
#endif #endif
hwloc__groups_by_distances(topology, nbgroups, groupobjs, groupvalues, kind, nbaccuracies, accuracies, 0 /* no need to check generated matrix */); hwloc__groups_by_distances(topology, nbgroups, groupobjs, groupvalues, kind, nbaccuracies, accuracies, 0 /* no need to check generated matrix */);
inner_free:
/* Safely free everything */
free(groupobjs);
free(groupsizes);
free(groupvalues);
} }
outter_free:
free(groupids);
} }

Просмотреть файл

@ -1,18 +1,19 @@
<!-- <!--
Copyright © 2009 CNRS Copyright © 2009 CNRS
Copyright © 2009-2016 Inria. All rights reserved. Copyright © 2009-2017 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux. Copyright © 2009-2011 Université Bordeaux.
See COPYING in top-level directory. See COPYING in top-level directory.
This is the old DTD for hwloc v1.x XMLs and diff XMLs.
--> -->
<!ELEMENT topology (object+,distances2*)> <!ELEMENT topology (object)+>
<!ELEMENT root (object)+> <!ELEMENT root (object)+>
<!ELEMENT object (page_type*,info*,userdata*,object*,distances*)> <!ELEMENT object (page_type*,info*,distances*,userdata*,object*)>
<!ATTLIST object type (System | Machine | Misc | Group | NUMANode | Package | L1Cache | L2Cache | L3Cache | L4Cache | L5Cache | L1iCache | L2iCache | L3iCache | Core | PU | Bridge | PCIDev | OSDev) #REQUIRED> <!ATTLIST object type (System | Machine | Misc | Group | NUMANode | Socket | Package | Cache | Core | PU | Bridge | PCIDev | OSDev) #REQUIRED>
<!ATTLIST object subtype CDATA "" > <!ATTLIST object os_level CDATA "-1" >
<!ATTLIST object os_index CDATA "-1" > <!ATTLIST object os_index CDATA "-1" >
<!ATTLIST object gp_index CDATA "-1" >
<!ATTLIST object name CDATA "" > <!ATTLIST object name CDATA "" >
<!ATTLIST object local_memory CDATA "0" > <!ATTLIST object local_memory CDATA "0" >
<!ATTLIST object cache_size CDATA "0" > <!ATTLIST object cache_size CDATA "0" >
@ -21,15 +22,14 @@
<!ATTLIST object cache_type CDATA "0" > <!ATTLIST object cache_type CDATA "0" >
<!ATTLIST object huge_page_size_kB CDATA "0" > <!ATTLIST object huge_page_size_kB CDATA "0" >
<!ATTLIST object huge_page_free CDATA "0" > <!ATTLIST object huge_page_free CDATA "0" >
<!ATTLIST object depth CDATA "-1" >
<!ATTLIST object cpuset CDATA "0" > <!ATTLIST object cpuset CDATA "0" >
<!ATTLIST object complete_cpuset CDATA "" > <!ATTLIST object complete_cpuset CDATA "" >
<!ATTLIST object online_cpuset CDATA "" >
<!ATTLIST object allowed_cpuset CDATA "" > <!ATTLIST object allowed_cpuset CDATA "" >
<!ATTLIST object nodeset CDATA "" > <!ATTLIST object nodeset CDATA "" >
<!ATTLIST object complete_nodeset CDATA "" > <!ATTLIST object complete_nodeset CDATA "" >
<!ATTLIST object allowed_nodeset CDATA "" > <!ATTLIST object allowed_nodeset CDATA "" >
<!ATTLIST object depth CDATA "-1" >
<!ATTLIST object kind CDATA "0" >
<!ATTLIST object subkind CDATA "0" >
<!ATTLIST object bridge_type CDATA "" > <!ATTLIST object bridge_type CDATA "" >
<!ATTLIST object bridge_pci CDATA "" > <!ATTLIST object bridge_pci CDATA "" >
<!ATTLIST object pci_busid CDATA "" > <!ATTLIST object pci_busid CDATA "" >
@ -45,17 +45,13 @@
<!ATTLIST info name CDATA #REQUIRED> <!ATTLIST info name CDATA #REQUIRED>
<!ATTLIST info value CDATA #REQUIRED> <!ATTLIST info value CDATA #REQUIRED>
<!ELEMENT distances2 (indexes+,u64values+)> <!ELEMENT distances (latency*)>
<!ATTLIST distances2 type CDATA #REQUIRED> <!ATTLIST distances nbobjs CDATA #REQUIRED>
<!ATTLIST distances2 nbobjs CDATA #REQUIRED> <!ATTLIST distances relative_depth CDATA #REQUIRED>
<!ATTLIST distances2 indexing CDATA #REQUIRED> <!ATTLIST distances latency_base CDATA #REQUIRED>
<!ATTLIST distances2 kind CDATA #REQUIRED>
<!ELEMENT indexes (#PCDATA)> <!ELEMENT latency EMPTY>
<!ATTLIST indexes length CDATA #REQUIRED> <!ATTLIST latency value CDATA #REQUIRED>
<!ELEMENT u64values (#PCDATA)>
<!ATTLIST u64values length CDATA #REQUIRED>
<!ELEMENT userdata (#PCDATA)> <!ELEMENT userdata (#PCDATA)>
<!ATTLIST userdata name CDATA "" > <!ATTLIST userdata name CDATA "" >
@ -75,13 +71,3 @@
<!ATTLIST diff obj_attr_name CDATA "" > <!ATTLIST diff obj_attr_name CDATA "" >
<!ATTLIST diff obj_attr_newvalue CDATA "" > <!ATTLIST diff obj_attr_newvalue CDATA "" >
<!ATTLIST diff obj_attr_oldvalue CDATA "" > <!ATTLIST diff obj_attr_oldvalue CDATA "" >
<!-- Deprecated in 2.0+ -->
<!ELEMENT distances (latency*)>
<!ATTLIST distances nbobjs CDATA #REQUIRED>
<!ATTLIST distances relative_depth CDATA #REQUIRED>
<!ATTLIST distances latency_base CDATA #REQUIRED>
<!ELEMENT latency EMPTY>
<!ATTLIST latency value CDATA #REQUIRED>

Просмотреть файл

@ -0,0 +1,21 @@
<!--
Copyright © 2009 CNRS
Copyright © 2009-2017 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux.
See COPYING in top-level directory.
This is the DTD for hwloc v2.x diff XMLs.
-->
<!ELEMENT topologydiff (diff)*>
<!ATTLIST topologydiff refname CDATA "">
<!ELEMENT diff EMPTY>
<!ATTLIST diff type CDATA #REQUIRED>
<!ATTLIST diff obj_depth CDATA "-1" >
<!ATTLIST diff obj_index CDATA "-1" >
<!ATTLIST diff obj_attr_type CDATA "-1" >
<!ATTLIST diff obj_attr_index CDATA "-1" >
<!ATTLIST diff obj_attr_name CDATA "" >
<!ATTLIST diff obj_attr_newvalue CDATA "" >
<!ATTLIST diff obj_attr_oldvalue CDATA "" >

Просмотреть файл

@ -0,0 +1,63 @@
<!--
Copyright © 2009 CNRS
Copyright © 2009-2017 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux.
See COPYING in top-level directory.
This is the DTD for hwloc v2.x XMLs.
-->
<!ELEMENT topology (object+,distances2*)>
<!ATTLIST topology version CDATA "">
<!ELEMENT object (page_type*,info*,userdata*,object*)>
<!ATTLIST object type (Machine | Misc | Group | NUMANode | Package | L1Cache | L2Cache | L3Cache | L4Cache | L5Cache | L1iCache | L2iCache | L3iCache | Core | PU | Bridge | PCIDev | OSDev) #REQUIRED>
<!ATTLIST object subtype CDATA "" >
<!ATTLIST object os_index CDATA "-1" >
<!ATTLIST object gp_index CDATA "-1" >
<!ATTLIST object name CDATA "" >
<!ATTLIST object local_memory CDATA "0" >
<!ATTLIST object cache_size CDATA "0" >
<!ATTLIST object cache_linesize CDATA "0" >
<!ATTLIST object cache_associativity CDATA "0" >
<!ATTLIST object cache_type CDATA "0" >
<!ATTLIST object cpuset CDATA "0" >
<!ATTLIST object complete_cpuset CDATA "" >
<!ATTLIST object allowed_cpuset CDATA "" >
<!ATTLIST object nodeset CDATA "" >
<!ATTLIST object complete_nodeset CDATA "" >
<!ATTLIST object allowed_nodeset CDATA "" >
<!ATTLIST object depth CDATA "-1" >
<!ATTLIST object kind CDATA "0" >
<!ATTLIST object subkind CDATA "0" >
<!ATTLIST object bridge_type CDATA "" >
<!ATTLIST object bridge_pci CDATA "" >
<!ATTLIST object pci_busid CDATA "" >
<!ATTLIST object pci_type CDATA "" >
<!ATTLIST object pci_link_speed CDATA "0." >
<!ATTLIST object osdev_type CDATA "" >
<!ELEMENT page_type EMPTY>
<!ATTLIST page_type size CDATA #REQUIRED>
<!ATTLIST page_type count CDATA #REQUIRED>
<!ELEMENT info EMPTY>
<!ATTLIST info name CDATA #REQUIRED>
<!ATTLIST info value CDATA #REQUIRED>
<!ELEMENT distances2 (indexes+,u64values+)>
<!ATTLIST distances2 type CDATA #REQUIRED>
<!ATTLIST distances2 nbobjs CDATA #REQUIRED>
<!ATTLIST distances2 indexing CDATA #REQUIRED>
<!ATTLIST distances2 kind CDATA #REQUIRED>
<!ELEMENT indexes (#PCDATA)>
<!ATTLIST indexes length CDATA #REQUIRED>
<!ELEMENT u64values (#PCDATA)>
<!ATTLIST u64values length CDATA #REQUIRED>
<!ELEMENT userdata (#PCDATA)>
<!ATTLIST userdata name CDATA "" >
<!ATTLIST userdata length CDATA "0" >
<!ATTLIST userdata encoding CDATA "" >

Просмотреть файл

@ -94,7 +94,7 @@ int hwloc_namecoloncmp(const char *haystack, const char *needle, size_t n)
} }
void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused, void hwloc_add_uname_info(struct hwloc_topology *topology __hwloc_attribute_unused,
void *cached_uname __hwloc_attribute_unused) void *cached_uname __hwloc_attribute_unused)
{ {
#ifdef HAVE_UNAME #ifdef HAVE_UNAME
struct utsname _utsname, *utsname; struct utsname _utsname, *utsname;

Просмотреть файл

@ -25,8 +25,8 @@
static void static void
hwloc_pci_forced_locality_parse_one(struct hwloc_topology *topology, hwloc_pci_forced_locality_parse_one(struct hwloc_topology *topology,
const char *string /* must contain a ' ' */, const char *string /* must contain a ' ' */,
unsigned *allocated) unsigned *allocated)
{ {
unsigned nr = topology->pci_forced_locality_nr; unsigned nr = topology->pci_forced_locality_nr;
unsigned domain, bus_first, bus_last, dummy; unsigned domain, bus_first, bus_last, dummy;
@ -59,7 +59,7 @@ hwloc_pci_forced_locality_parse_one(struct hwloc_topology *topology,
} else if (nr >= *allocated) { } else if (nr >= *allocated) {
struct hwloc_pci_forced_locality_s *tmplocs; struct hwloc_pci_forced_locality_s *tmplocs;
tmplocs = realloc(topology->pci_forced_locality, tmplocs = realloc(topology->pci_forced_locality,
2 * *allocated * sizeof(*topology->pci_forced_locality)); 2 * *allocated * sizeof(*topology->pci_forced_locality));
if (!tmplocs) if (!tmplocs)
goto out_with_set; /* failed to allocate, ignore this forced locality */ goto out_with_set; /* failed to allocate, ignore this forced locality */
topology->pci_forced_locality = tmplocs; topology->pci_forced_locality = tmplocs;
@ -92,7 +92,7 @@ hwloc_pci_forced_locality_parse(struct hwloc_topology *topology, const char *_en
if (tmp[len] != '\0') { if (tmp[len] != '\0') {
tmp[len] = '\0'; tmp[len] = '\0';
if (tmp[len+1] != '\0') if (tmp[len+1] != '\0')
next = &tmp[len]+1; next = &tmp[len]+1;
} }
hwloc_pci_forced_locality_parse_one(topology, tmp, &allocated); hwloc_pci_forced_locality_parse_one(topology, tmp, &allocated);
@ -109,7 +109,6 @@ hwloc_pci_forced_locality_parse(struct hwloc_topology *topology, const char *_en
void void
hwloc_pci_discovery_init(struct hwloc_topology *topology) hwloc_pci_discovery_init(struct hwloc_topology *topology)
{ {
topology->pci_nonzero_domains = 0;
topology->need_pci_belowroot_apply_locality = 0; topology->need_pci_belowroot_apply_locality = 0;
topology->pci_has_forced_locality = 0; topology->pci_has_forced_locality = 0;
@ -134,17 +133,17 @@ hwloc_pci_discovery_prepare(struct hwloc_topology *topology)
char *buffer; char *buffer;
int err = fstat(fd, &st); int err = fstat(fd, &st);
if (!err) { if (!err) {
if (st.st_size <= 64*1024) { /* random limit large enough to store multiple cpusets for thousands of PUs */ if (st.st_size <= 64*1024) { /* random limit large enough to store multiple cpusets for thousands of PUs */
buffer = malloc(st.st_size+1); buffer = malloc(st.st_size+1);
if (read(fd, buffer, st.st_size) == st.st_size) { if (read(fd, buffer, st.st_size) == st.st_size) {
buffer[st.st_size] = '\0'; buffer[st.st_size] = '\0';
hwloc_pci_forced_locality_parse(topology, buffer); hwloc_pci_forced_locality_parse(topology, buffer);
} }
free(buffer); free(buffer);
} else { } else {
fprintf(stderr, "Ignoring HWLOC_PCI_LOCALITY file `%s' too large (%lu bytes)\n", fprintf(stderr, "Ignoring HWLOC_PCI_LOCALITY file `%s' too large (%lu bytes)\n",
env, (unsigned long) st.st_size); env, (unsigned long) st.st_size);
} }
} }
close(fd); close(fd);
} else } else
@ -166,7 +165,7 @@ hwloc_pci_discovery_exit(struct hwloc_topology *topology __hwloc_attribute_unuse
#ifdef HWLOC_DEBUG #ifdef HWLOC_DEBUG
static void static void
hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused, hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused,
struct hwloc_obj *pcidev) struct hwloc_obj *pcidev)
{ {
char busid[14]; char busid[14];
hwloc_obj_t parent; hwloc_obj_t parent;
@ -186,34 +185,26 @@ hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused,
hwloc_debug("HostBridge"); hwloc_debug("HostBridge");
else else
hwloc_debug("%s Bridge [%04x:%04x]", busid, hwloc_debug("%s Bridge [%04x:%04x]", busid,
pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id); pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id);
hwloc_debug(" to %04x:[%02x:%02x]\n", hwloc_debug(" to %04x:[%02x:%02x]\n",
pcidev->attr->bridge.downstream.pci.domain, pcidev->attr->bridge.downstream.pci.secondary_bus, pcidev->attr->bridge.downstream.pci.subordinate_bus); pcidev->attr->bridge.downstream.pci.domain, pcidev->attr->bridge.downstream.pci.secondary_bus, pcidev->attr->bridge.downstream.pci.subordinate_bus);
} else } else
hwloc_debug("%s Device [%04x:%04x (%04x:%04x) rev=%02x class=%04x]\n", busid, hwloc_debug("%s Device [%04x:%04x (%04x:%04x) rev=%02x class=%04x]\n", busid,
pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id, pcidev->attr->pcidev.vendor_id, pcidev->attr->pcidev.device_id,
pcidev->attr->pcidev.subvendor_id, pcidev->attr->pcidev.subdevice_id, pcidev->attr->pcidev.subvendor_id, pcidev->attr->pcidev.subdevice_id,
pcidev->attr->pcidev.revision, pcidev->attr->pcidev.class_id); pcidev->attr->pcidev.revision, pcidev->attr->pcidev.class_id);
}
static void
hwloc_pci__traverse(void * cbdata, struct hwloc_obj *tree,
void (*cb)(void * cbdata, struct hwloc_obj *))
{
struct hwloc_obj *child = tree;
while (child) {
cb(cbdata, child);
if (child->type == HWLOC_OBJ_BRIDGE && child->io_first_child)
hwloc_pci__traverse(cbdata, child->io_first_child, cb);
child = child->next_sibling;
}
} }
static void static void
hwloc_pci_traverse(void * cbdata, struct hwloc_obj *tree, hwloc_pci_traverse(void * cbdata, struct hwloc_obj *tree,
void (*cb)(void * cbdata, struct hwloc_obj *)) void (*cb)(void * cbdata, struct hwloc_obj *))
{ {
hwloc_pci__traverse(cbdata, tree, cb); hwloc_obj_t child;
cb(cbdata, tree);
for_each_io_child(child, tree) {
if (child->type == HWLOC_OBJ_BRIDGE)
hwloc_pci_traverse(cbdata, child, cb);
}
} }
#endif /* HWLOC_DEBUG */ #endif /* HWLOC_DEBUG */
@ -294,27 +285,27 @@ hwloc_pci_add_object(struct hwloc_obj *parent, struct hwloc_obj **parent_io_firs
*curp = new; *curp = new;
new->parent = parent; new->parent = parent;
if (new->type == HWLOC_OBJ_BRIDGE) { if (new->type == HWLOC_OBJ_BRIDGE) {
/* look at remaining siblings and move some below new */ /* look at remaining siblings and move some below new */
childp = &new->io_first_child; childp = &new->io_first_child;
curp = &new->next_sibling; curp = &new->next_sibling;
while (*curp) { while (*curp) {
hwloc_obj_t cur = *curp; hwloc_obj_t cur = *curp;
if (hwloc_pci_compare_busids(new, cur) == HWLOC_PCI_BUSID_LOWER) { if (hwloc_pci_compare_busids(new, cur) == HWLOC_PCI_BUSID_LOWER) {
/* this sibling remains under root, after new. */ /* this sibling remains under root, after new. */
if (cur->attr->pcidev.domain > new->attr->pcidev.domain if (cur->attr->pcidev.domain > new->attr->pcidev.domain
|| cur->attr->pcidev.bus > new->attr->bridge.downstream.pci.subordinate_bus) || cur->attr->pcidev.bus > new->attr->bridge.downstream.pci.subordinate_bus)
/* this sibling is even above new's subordinate bus, no other sibling could go below new */ /* this sibling is even above new's subordinate bus, no other sibling could go below new */
return; return;
curp = &cur->next_sibling; curp = &cur->next_sibling;
} else { } else {
/* this sibling goes under new */ /* this sibling goes under new */
*childp = cur; *childp = cur;
*curp = cur->next_sibling; *curp = cur->next_sibling;
(*childp)->parent = new; (*childp)->parent = new;
(*childp)->next_sibling = NULL; (*childp)->next_sibling = NULL;
childp = &(*childp)->next_sibling; childp = &(*childp)->next_sibling;
} }
} }
} }
return; return;
} }
@ -328,7 +319,7 @@ hwloc_pci_add_object(struct hwloc_obj *parent, struct hwloc_obj **parent_io_firs
void void
hwloc_pcidisc_tree_insert_by_busid(struct hwloc_obj **treep, hwloc_pcidisc_tree_insert_by_busid(struct hwloc_obj **treep,
struct hwloc_obj *obj) struct hwloc_obj *obj)
{ {
hwloc_pci_add_object(NULL /* no parent on top of tree */, treep, obj); hwloc_pci_add_object(NULL /* no parent on top of tree */, treep, obj);
} }
@ -367,7 +358,7 @@ hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *old
*/ */
while (old_tree) { while (old_tree) {
/* start a new host bridge */ /* start a new host bridge */
struct hwloc_obj *hostbridge = hwloc_alloc_setup_object(topology, HWLOC_OBJ_BRIDGE, -1); struct hwloc_obj *hostbridge = hwloc_alloc_setup_object(topology, HWLOC_OBJ_BRIDGE, HWLOC_UNKNOWN_INDEX);
struct hwloc_obj **dstnextp = &hostbridge->io_first_child; struct hwloc_obj **dstnextp = &hostbridge->io_first_child;
struct hwloc_obj **srcnextp = &old_tree; struct hwloc_obj **srcnextp = &old_tree;
struct hwloc_obj *child = *srcnextp; struct hwloc_obj *child = *srcnextp;
@ -388,14 +379,14 @@ hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *old
/* compute hostbridge secondary/subordinate buses */ /* compute hostbridge secondary/subordinate buses */
if (child->type == HWLOC_OBJ_BRIDGE if (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.downstream.pci.subordinate_bus > current_subordinate) && child->attr->bridge.downstream.pci.subordinate_bus > current_subordinate)
current_subordinate = child->attr->bridge.downstream.pci.subordinate_bus; current_subordinate = child->attr->bridge.downstream.pci.subordinate_bus;
/* use next child if it has the same domains/bus */ /* use next child if it has the same domains/bus */
child = *srcnextp; child = *srcnextp;
if (child if (child
&& child->attr->pcidev.domain == current_domain && child->attr->pcidev.domain == current_domain
&& child->attr->pcidev.bus == current_bus) && child->attr->pcidev.bus == current_bus)
goto next_child; goto next_child;
/* finish setting up this hostbridge */ /* finish setting up this hostbridge */
@ -405,16 +396,13 @@ hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *old
hostbridge->attr->bridge.downstream.pci.secondary_bus = current_bus; hostbridge->attr->bridge.downstream.pci.secondary_bus = current_bus;
hostbridge->attr->bridge.downstream.pci.subordinate_bus = current_subordinate; hostbridge->attr->bridge.downstream.pci.subordinate_bus = current_subordinate;
hwloc_debug("New PCI hostbridge %04x:[%02x-%02x]\n", hwloc_debug("New PCI hostbridge %04x:[%02x-%02x]\n",
current_domain, current_bus, current_subordinate); current_domain, current_bus, current_subordinate);
if (current_domain)
topology->pci_nonzero_domains = 1;
*next_hb_p = hostbridge; *next_hb_p = hostbridge;
next_hb_p = &hostbridge->next_sibling; next_hb_p = &hostbridge->next_sibling;
topology->modified = 1; /* needed in case somebody reconnects levels before the core calls hwloc_pci_belowroot_apply_locality() topology->modified = 1; /* needed in case somebody reconnects levels before the core calls hwloc_pci_belowroot_apply_locality()
* or if hwloc_pci_belowroot_apply_locality() keeps hostbridges below root. * or if hwloc_pci_belowroot_apply_locality() keeps hostbridges below root.
*/ */
} }
done: done:
@ -424,8 +412,8 @@ hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *old
static struct hwloc_obj * static struct hwloc_obj *
hwloc_pci_fixup_busid_parent(struct hwloc_topology *topology __hwloc_attribute_unused, hwloc_pci_fixup_busid_parent(struct hwloc_topology *topology __hwloc_attribute_unused,
struct hwloc_pcidev_attr_s *busid, struct hwloc_pcidev_attr_s *busid,
struct hwloc_obj *parent) struct hwloc_obj *parent)
{ {
/* Xeon E5v3 in cluster-on-die mode only have PCI on the first NUMA node of each package. /* Xeon E5v3 in cluster-on-die mode only have PCI on the first NUMA node of each package.
* but many dual-processor host report the second PCI hierarchy on 2nd NUMA of first package. * but many dual-processor host report the second PCI hierarchy on 2nd NUMA of first package.
@ -438,20 +426,20 @@ hwloc_pci_fixup_busid_parent(struct hwloc_topology *topology __hwloc_attribute_u
const char *cpumodel = hwloc_obj_get_info_by_name(parent->parent, "CPUModel"); const char *cpumodel = hwloc_obj_get_info_by_name(parent->parent, "CPUModel");
if (cpumodel && strstr(cpumodel, "Xeon")) { if (cpumodel && strstr(cpumodel, "Xeon")) {
if (!hwloc_hide_errors()) { if (!hwloc_hide_errors()) {
fprintf(stderr, "****************************************************************************\n"); fprintf(stderr, "****************************************************************************\n");
fprintf(stderr, "* hwloc %s has encountered an incorrect PCI locality information.\n", HWLOC_VERSION); fprintf(stderr, "* hwloc %s has encountered an incorrect PCI locality information.\n", HWLOC_VERSION);
fprintf(stderr, "* PCI bus %04x:%02x is supposedly close to 2nd NUMA node of 1st package,\n", fprintf(stderr, "* PCI bus %04x:%02x is supposedly close to 2nd NUMA node of 1st package,\n",
busid->domain, busid->bus); busid->domain, busid->bus);
fprintf(stderr, "* however hwloc believes this is impossible on this architecture.\n"); fprintf(stderr, "* however hwloc believes this is impossible on this architecture.\n");
fprintf(stderr, "* Therefore the PCI bus will be moved to 1st NUMA node of 2nd package.\n"); fprintf(stderr, "* Therefore the PCI bus will be moved to 1st NUMA node of 2nd package.\n");
fprintf(stderr, "*\n"); fprintf(stderr, "*\n");
fprintf(stderr, "* If you feel this fixup is wrong, disable it by setting in your environment\n"); fprintf(stderr, "* If you feel this fixup is wrong, disable it by setting in your environment\n");
fprintf(stderr, "* HWLOC_PCI_%04x_%02x_LOCALCPUS= (empty value), and report the problem\n", fprintf(stderr, "* HWLOC_PCI_%04x_%02x_LOCALCPUS= (empty value), and report the problem\n",
busid->domain, busid->bus); busid->domain, busid->bus);
fprintf(stderr, "* to the hwloc's user mailing list together with the XML output of lstopo.\n"); fprintf(stderr, "* to the hwloc's user mailing list together with the XML output of lstopo.\n");
fprintf(stderr, "*\n"); fprintf(stderr, "*\n");
fprintf(stderr, "* You may silence this message by setting HWLOC_HIDE_ERRORS=1 in your environment.\n"); fprintf(stderr, "* You may silence this message by setting HWLOC_HIDE_ERRORS=1 in your environment.\n");
fprintf(stderr, "****************************************************************************\n"); fprintf(stderr, "****************************************************************************\n");
} }
return parent->parent->next_sibling->first_child; return parent->parent->next_sibling->first_child;
} }
@ -474,11 +462,11 @@ hwloc__pci_find_busid_parent(struct hwloc_topology *topology, struct hwloc_pcide
if (topology->pci_has_forced_locality) { if (topology->pci_has_forced_locality) {
for(i=0; i<topology->pci_forced_locality_nr; i++) { for(i=0; i<topology->pci_forced_locality_nr; i++) {
if (busid->domain == topology->pci_forced_locality[i].domain if (busid->domain == topology->pci_forced_locality[i].domain
&& busid->bus >= topology->pci_forced_locality[i].bus_first && busid->bus >= topology->pci_forced_locality[i].bus_first
&& busid->bus <= topology->pci_forced_locality[i].bus_last) { && busid->bus <= topology->pci_forced_locality[i].bus_last) {
hwloc_bitmap_copy(cpuset, topology->pci_forced_locality[i].cpuset); hwloc_bitmap_copy(cpuset, topology->pci_forced_locality[i].cpuset);
forced = 1; forced = 1;
break; break;
} }
} }
/* if pci locality was forced, even empty, don't let quirks change what the OS reports */ /* if pci locality was forced, even empty, don't let quirks change what the OS reports */
@ -491,19 +479,19 @@ hwloc__pci_find_busid_parent(struct hwloc_topology *topology, struct hwloc_pcide
char envname[256]; char envname[256];
/* override the cpuset with the environment if given */ /* override the cpuset with the environment if given */
snprintf(envname, sizeof(envname), "HWLOC_PCI_%04x_%02x_LOCALCPUS", snprintf(envname, sizeof(envname), "HWLOC_PCI_%04x_%02x_LOCALCPUS",
busid->domain, busid->bus); busid->domain, busid->bus);
env = getenv(envname); env = getenv(envname);
if (env) { if (env) {
static int reported = 0; static int reported = 0;
if (!topology->pci_has_forced_locality && !reported) { if (!topology->pci_has_forced_locality && !reported) {
fprintf(stderr, "Environment variable %s is deprecated, please use HWLOC_PCI_LOCALITY instead.\n", env); fprintf(stderr, "Environment variable %s is deprecated, please use HWLOC_PCI_LOCALITY instead.\n", env);
reported = 1; reported = 1;
} }
if (*env) { if (*env) {
/* force the cpuset */ /* force the cpuset */
hwloc_debug("Overriding localcpus using %s in the environment\n", envname); hwloc_debug("Overriding localcpus using %s in the environment\n", envname);
hwloc_bitmap_sscanf(cpuset, env); hwloc_bitmap_sscanf(cpuset, env);
forced = 1; forced = 1;
} }
/* if env exists, even empty, don't let quirks change what the OS reports */ /* if env exists, even empty, don't let quirks change what the OS reports */
noquirks = 1; noquirks = 1;
@ -540,7 +528,7 @@ hwloc__pci_find_busid_parent(struct hwloc_topology *topology, struct hwloc_pcide
struct hwloc_obj * struct hwloc_obj *
hwloc_pcidisc_find_busid_parent(struct hwloc_topology *topology, hwloc_pcidisc_find_busid_parent(struct hwloc_topology *topology,
unsigned domain, unsigned bus, unsigned dev, unsigned func) unsigned domain, unsigned bus, unsigned dev, unsigned func)
{ {
struct hwloc_pcidev_attr_s busid; struct hwloc_pcidev_attr_s busid;
busid.domain = domain; busid.domain = domain;
@ -570,25 +558,25 @@ hwloc_pci_belowroot_apply_locality(struct hwloc_topology *topology)
/* skip non-PCI objects */ /* skip non-PCI objects */
if (obj->type != HWLOC_OBJ_PCI_DEVICE if (obj->type != HWLOC_OBJ_PCI_DEVICE
&& !(obj->type == HWLOC_OBJ_BRIDGE && obj->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI) && !(obj->type == HWLOC_OBJ_BRIDGE && obj->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI)
&& !(obj->type == HWLOC_OBJ_BRIDGE && obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)) { && !(obj->type == HWLOC_OBJ_BRIDGE && obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)) {
listp = &obj->next_sibling; listp = &obj->next_sibling;
continue; continue;
} }
if (obj->type == HWLOC_OBJ_PCI_DEVICE if (obj->type == HWLOC_OBJ_PCI_DEVICE
|| (obj->type == HWLOC_OBJ_BRIDGE || (obj->type == HWLOC_OBJ_BRIDGE
&& obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)) && obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI))
busid = &obj->attr->pcidev; busid = &obj->attr->pcidev;
else { else {
/* hostbridges don't have a PCI busid for looking up locality, use their first child if PCI */ /* hostbridges don't have a PCI busid for looking up locality, use their first child if PCI */
hwloc_obj_t child = obj->io_first_child; hwloc_obj_t child = obj->io_first_child;
if (child && (child->type == HWLOC_OBJ_PCI_DEVICE if (child && (child->type == HWLOC_OBJ_PCI_DEVICE
|| (child->type == HWLOC_OBJ_BRIDGE || (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI))) && child->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)))
busid = &obj->io_first_child->attr->pcidev; busid = &obj->io_first_child->attr->pcidev;
else else
continue; continue;
} }
/* attach the object (and children) where it belongs */ /* attach the object (and children) where it belongs */
@ -609,40 +597,40 @@ hwloc_pci_belowroot_apply_locality(struct hwloc_topology *topology)
static struct hwloc_obj * static struct hwloc_obj *
hwloc__pci_belowroot_find_by_busid(hwloc_obj_t parent, hwloc__pci_belowroot_find_by_busid(hwloc_obj_t parent,
unsigned domain, unsigned bus, unsigned dev, unsigned func) unsigned domain, unsigned bus, unsigned dev, unsigned func)
{ {
hwloc_obj_t child = parent->io_first_child; hwloc_obj_t child;
for ( ; child; child = child->next_sibling) { for_each_io_child(child, parent) {
if (child->type == HWLOC_OBJ_PCI_DEVICE if (child->type == HWLOC_OBJ_PCI_DEVICE
|| (child->type == HWLOC_OBJ_BRIDGE || (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)) { && child->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)) {
if (child->attr->pcidev.domain == domain if (child->attr->pcidev.domain == domain
&& child->attr->pcidev.bus == bus && child->attr->pcidev.bus == bus
&& child->attr->pcidev.dev == dev && child->attr->pcidev.dev == dev
&& child->attr->pcidev.func == func) && child->attr->pcidev.func == func)
/* that's the right bus id */ /* that's the right bus id */
return child; return child;
if (child->attr->pcidev.domain > domain if (child->attr->pcidev.domain > domain
|| (child->attr->pcidev.domain == domain || (child->attr->pcidev.domain == domain
&& child->attr->pcidev.bus > bus)) && child->attr->pcidev.bus > bus))
/* bus id too high, won't find anything later, return parent */ /* bus id too high, won't find anything later, return parent */
return parent; return parent;
if (child->type == HWLOC_OBJ_BRIDGE if (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI && child->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
&& child->attr->bridge.downstream.pci.domain == domain && child->attr->bridge.downstream.pci.domain == domain
&& child->attr->bridge.downstream.pci.secondary_bus <= bus && child->attr->bridge.downstream.pci.secondary_bus <= bus
&& child->attr->bridge.downstream.pci.subordinate_bus >= bus) && child->attr->bridge.downstream.pci.subordinate_bus >= bus)
/* not the right bus id, but it's included in the bus below that bridge */ /* not the right bus id, but it's included in the bus below that bridge */
return hwloc__pci_belowroot_find_by_busid(child, domain, bus, dev, func); return hwloc__pci_belowroot_find_by_busid(child, domain, bus, dev, func);
} else if (child->type == HWLOC_OBJ_BRIDGE } else if (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.upstream_type != HWLOC_OBJ_BRIDGE_PCI && child->attr->bridge.upstream_type != HWLOC_OBJ_BRIDGE_PCI
&& child->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI && child->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI
/* non-PCI to PCI bridge, just look at the subordinate bus */ /* non-PCI to PCI bridge, just look at the subordinate bus */
&& child->attr->bridge.downstream.pci.domain == domain && child->attr->bridge.downstream.pci.domain == domain
&& child->attr->bridge.downstream.pci.secondary_bus <= bus && child->attr->bridge.downstream.pci.secondary_bus <= bus
&& child->attr->bridge.downstream.pci.subordinate_bus >= bus) { && child->attr->bridge.downstream.pci.subordinate_bus >= bus) {
/* contains our bus, recurse */ /* contains our bus, recurse */
return hwloc__pci_belowroot_find_by_busid(child, domain, bus, dev, func); return hwloc__pci_belowroot_find_by_busid(child, domain, bus, dev, func);
} }
@ -653,7 +641,7 @@ hwloc__pci_belowroot_find_by_busid(hwloc_obj_t parent,
struct hwloc_obj * struct hwloc_obj *
hwloc_pcidisc_find_by_busid(struct hwloc_topology *topology, hwloc_pcidisc_find_by_busid(struct hwloc_topology *topology,
unsigned domain, unsigned bus, unsigned dev, unsigned func) unsigned domain, unsigned bus, unsigned dev, unsigned func)
{ {
hwloc_obj_t root = hwloc_get_root_obj(topology); hwloc_obj_t root = hwloc_get_root_obj(topology);
hwloc_obj_t parent = hwloc__pci_belowroot_find_by_busid(root, domain, bus, dev, func); hwloc_obj_t parent = hwloc__pci_belowroot_find_by_busid(root, domain, bus, dev, func);
@ -703,7 +691,7 @@ hwloc_pcidisc_find_cap(const unsigned char *config, unsigned cap)
int int
hwloc_pcidisc_find_linkspeed(const unsigned char *config, hwloc_pcidisc_find_linkspeed(const unsigned char *config,
unsigned offset, float *linkspeed) unsigned offset, float *linkspeed)
{ {
unsigned linksta, speed, width; unsigned linksta, speed, width;
float lanespeed; float lanespeed;
@ -751,7 +739,7 @@ hwloc_pcidisc_check_bridge_type(unsigned device_class, const unsigned char *conf
int int
hwloc_pcidisc_setup_bridge_attr(hwloc_obj_t obj, hwloc_pcidisc_setup_bridge_attr(hwloc_obj_t obj,
const unsigned char *config) const unsigned char *config)
{ {
struct hwloc_bridge_attr_s *battr = &obj->attr->bridge; struct hwloc_bridge_attr_s *battr = &obj->attr->bridge;
struct hwloc_pcidev_attr_s *pattr = &battr->upstream.pci; struct hwloc_pcidev_attr_s *pattr = &battr->upstream.pci;
@ -762,7 +750,7 @@ hwloc_pcidisc_setup_bridge_attr(hwloc_obj_t obj,
* to workaround such problems (e.g. ACPI information about PCI parent/children). * to workaround such problems (e.g. ACPI information about PCI parent/children).
*/ */
hwloc_debug(" %04x:%02x:%02x.%01x bridge with (ignored) invalid PCI_PRIMARY_BUS %02x\n", hwloc_debug(" %04x:%02x:%02x.%01x bridge with (ignored) invalid PCI_PRIMARY_BUS %02x\n",
pattr->domain, pattr->bus, pattr->dev, pattr->func, config[HWLOC_PCI_PRIMARY_BUS]); pattr->domain, pattr->bus, pattr->dev, pattr->func, config[HWLOC_PCI_PRIMARY_BUS]);
} }
obj->type = HWLOC_OBJ_BRIDGE; obj->type = HWLOC_OBJ_BRIDGE;
@ -782,8 +770,8 @@ hwloc_pcidisc_setup_bridge_attr(hwloc_obj_t obj,
* because objects may be discovered out of order (especially in the fsroot case). * because objects may be discovered out of order (especially in the fsroot case).
*/ */
hwloc_debug(" %04x:%02x:%02x.%01x bridge has invalid secondary-subordinate buses [%02x-%02x]\n", hwloc_debug(" %04x:%02x:%02x.%01x bridge has invalid secondary-subordinate buses [%02x-%02x]\n",
pattr->domain, pattr->bus, pattr->dev, pattr->func, pattr->domain, pattr->bus, pattr->dev, pattr->func,
battr->downstream.pci.secondary_bus, battr->downstream.pci.subordinate_bus); battr->downstream.pci.secondary_bus, battr->downstream.pci.subordinate_bus);
hwloc_free_unlinked_object(obj); hwloc_free_unlinked_object(obj);
return -1; return -1;
} }
@ -798,143 +786,143 @@ hwloc_pci_class_string(unsigned short class_id)
switch ((class_id & 0xff00) >> 8) { switch ((class_id & 0xff00) >> 8) {
case 0x00: case 0x00:
switch (class_id) { switch (class_id) {
case 0x0001: return "VGA"; case 0x0001: return "VGA";
} }
break; break;
case 0x01: case 0x01:
switch (class_id) { switch (class_id) {
case 0x0100: return "SCSI"; case 0x0100: return "SCSI";
case 0x0101: return "IDE"; case 0x0101: return "IDE";
case 0x0102: return "Floppy"; case 0x0102: return "Floppy";
case 0x0103: return "IPI"; case 0x0103: return "IPI";
case 0x0104: return "RAID"; case 0x0104: return "RAID";
case 0x0105: return "ATA"; case 0x0105: return "ATA";
case 0x0106: return "SATA"; case 0x0106: return "SATA";
case 0x0107: return "SAS"; case 0x0107: return "SAS";
case 0x0108: return "NVMExp"; case 0x0108: return "NVMExp";
} }
return "Storage"; return "Storage";
case 0x02: case 0x02:
switch (class_id) { switch (class_id) {
case 0x0200: return "Ethernet"; case 0x0200: return "Ethernet";
case 0x0201: return "TokenRing"; case 0x0201: return "TokenRing";
case 0x0202: return "FDDI"; case 0x0202: return "FDDI";
case 0x0203: return "ATM"; case 0x0203: return "ATM";
case 0x0204: return "ISDN"; case 0x0204: return "ISDN";
case 0x0205: return "WorldFip"; case 0x0205: return "WorldFip";
case 0x0206: return "PICMG"; case 0x0206: return "PICMG";
case 0x0207: return "InfiniBand"; case 0x0207: return "InfiniBand";
case 0x0208: return "Fabric"; case 0x0208: return "Fabric";
} }
return "Network"; return "Network";
case 0x03: case 0x03:
switch (class_id) { switch (class_id) {
case 0x0300: return "VGA"; case 0x0300: return "VGA";
case 0x0301: return "XGA"; case 0x0301: return "XGA";
case 0x0302: return "3D"; case 0x0302: return "3D";
} }
return "Display"; return "Display";
case 0x04: case 0x04:
switch (class_id) { switch (class_id) {
case 0x0400: return "MultimediaVideo"; case 0x0400: return "MultimediaVideo";
case 0x0401: return "MultimediaAudio"; case 0x0401: return "MultimediaAudio";
case 0x0402: return "Telephony"; case 0x0402: return "Telephony";
case 0x0403: return "AudioDevice"; case 0x0403: return "AudioDevice";
} }
return "Multimedia"; return "Multimedia";
case 0x05: case 0x05:
switch (class_id) { switch (class_id) {
case 0x0500: return "RAM"; case 0x0500: return "RAM";
case 0x0501: return "Flash"; case 0x0501: return "Flash";
} }
return "Memory"; return "Memory";
case 0x06: case 0x06:
switch (class_id) { switch (class_id) {
case 0x0600: return "HostBridge"; case 0x0600: return "HostBridge";
case 0x0601: return "ISABridge"; case 0x0601: return "ISABridge";
case 0x0602: return "EISABridge"; case 0x0602: return "EISABridge";
case 0x0603: return "MicroChannelBridge"; case 0x0603: return "MicroChannelBridge";
case 0x0604: return "PCIBridge"; case 0x0604: return "PCIBridge";
case 0x0605: return "PCMCIABridge"; case 0x0605: return "PCMCIABridge";
case 0x0606: return "NubusBridge"; case 0x0606: return "NubusBridge";
case 0x0607: return "CardBusBridge"; case 0x0607: return "CardBusBridge";
case 0x0608: return "RACEwayBridge"; case 0x0608: return "RACEwayBridge";
case 0x0609: return "SemiTransparentPCIBridge"; case 0x0609: return "SemiTransparentPCIBridge";
case 0x060a: return "InfiniBandPCIHostBridge"; case 0x060a: return "InfiniBandPCIHostBridge";
} }
return "Bridge"; return "Bridge";
case 0x07: case 0x07:
switch (class_id) { switch (class_id) {
case 0x0700: return "Serial"; case 0x0700: return "Serial";
case 0x0701: return "Parallel"; case 0x0701: return "Parallel";
case 0x0702: return "MultiportSerial"; case 0x0702: return "MultiportSerial";
case 0x0703: return "Model"; case 0x0703: return "Model";
case 0x0704: return "GPIB"; case 0x0704: return "GPIB";
case 0x0705: return "SmartCard"; case 0x0705: return "SmartCard";
} }
return "Communication"; return "Communication";
case 0x08: case 0x08:
switch (class_id) { switch (class_id) {
case 0x0800: return "PIC"; case 0x0800: return "PIC";
case 0x0801: return "DMA"; case 0x0801: return "DMA";
case 0x0802: return "Timer"; case 0x0802: return "Timer";
case 0x0803: return "RTC"; case 0x0803: return "RTC";
case 0x0804: return "PCIHotPlug"; case 0x0804: return "PCIHotPlug";
case 0x0805: return "SDHost"; case 0x0805: return "SDHost";
case 0x0806: return "IOMMU"; case 0x0806: return "IOMMU";
} }
return "SystemPeripheral"; return "SystemPeripheral";
case 0x09: case 0x09:
switch (class_id) { switch (class_id) {
case 0x0900: return "Keyboard"; case 0x0900: return "Keyboard";
case 0x0901: return "DigitizerPen"; case 0x0901: return "DigitizerPen";
case 0x0902: return "Mouse"; case 0x0902: return "Mouse";
case 0x0903: return "Scanern"; case 0x0903: return "Scanern";
case 0x0904: return "Gameport"; case 0x0904: return "Gameport";
} }
return "Input"; return "Input";
case 0x0a: case 0x0a:
return "DockingStation"; return "DockingStation";
case 0x0b: case 0x0b:
switch (class_id) { switch (class_id) {
case 0x0b00: return "386"; case 0x0b00: return "386";
case 0x0b01: return "486"; case 0x0b01: return "486";
case 0x0b02: return "Pentium"; case 0x0b02: return "Pentium";
/* 0x0b03 and 0x0b04 might be Pentium and P6 ? */ /* 0x0b03 and 0x0b04 might be Pentium and P6 ? */
case 0x0b10: return "Alpha"; case 0x0b10: return "Alpha";
case 0x0b20: return "PowerPC"; case 0x0b20: return "PowerPC";
case 0x0b30: return "MIPS"; case 0x0b30: return "MIPS";
case 0x0b40: return "Co-Processor"; case 0x0b40: return "Co-Processor";
} }
return "Processor"; return "Processor";
case 0x0c: case 0x0c:
switch (class_id) { switch (class_id) {
case 0x0c00: return "FireWire"; case 0x0c00: return "FireWire";
case 0x0c01: return "ACCESS"; case 0x0c01: return "ACCESS";
case 0x0c02: return "SSA"; case 0x0c02: return "SSA";
case 0x0c03: return "USB"; case 0x0c03: return "USB";
case 0x0c04: return "FibreChannel"; case 0x0c04: return "FibreChannel";
case 0x0c05: return "SMBus"; case 0x0c05: return "SMBus";
case 0x0c06: return "InfiniBand"; case 0x0c06: return "InfiniBand";
case 0x0c07: return "IPMI-SMIC"; case 0x0c07: return "IPMI-SMIC";
case 0x0c08: return "SERCOS"; case 0x0c08: return "SERCOS";
case 0x0c09: return "CANBUS"; case 0x0c09: return "CANBUS";
} }
return "SerialBus"; return "SerialBus";
case 0x0d: case 0x0d:
switch (class_id) { switch (class_id) {
case 0x0d00: return "IRDA"; case 0x0d00: return "IRDA";
case 0x0d01: return "ConsumerIR"; case 0x0d01: return "ConsumerIR";
case 0x0d10: return "RF"; case 0x0d10: return "RF";
case 0x0d11: return "Bluetooth"; case 0x0d11: return "Bluetooth";
case 0x0d12: return "Broadband"; case 0x0d12: return "Broadband";
case 0x0d20: return "802.1a"; case 0x0d20: return "802.1a";
case 0x0d21: return "802.1b"; case 0x0d21: return "802.1b";
} }
return "Wireless"; return "Wireless";
case 0x0e: case 0x0e:
switch (class_id) { switch (class_id) {
case 0x0e00: return "I2O"; case 0x0e00: return "I2O";
} }
return "Intelligent"; return "Intelligent";
case 0x0f: case 0x0f:

Просмотреть файл

@ -27,7 +27,7 @@ struct hwloc_shmem_header {
static void * static void *
tma_shmem_malloc(struct hwloc_tma * tma, tma_shmem_malloc(struct hwloc_tma * tma,
size_t length) size_t length)
{ {
void *current = tma->data; void *current = tma->data;
tma->data = (char*)tma->data + ((length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1)); tma->data = (char*)tma->data + ((length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1));
@ -37,7 +37,7 @@ tma_shmem_malloc(struct hwloc_tma * tma,
static void * static void *
tma_get_length_malloc(struct hwloc_tma * tma, tma_get_length_malloc(struct hwloc_tma * tma,
size_t length) size_t length)
{ {
size_t *tma_length = tma->data; size_t *tma_length = tma->data;
*tma_length += (length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1); *tma_length += (length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1);
@ -47,8 +47,8 @@ tma_get_length_malloc(struct hwloc_tma * tma,
int int
hwloc_shmem_topology_get_length(hwloc_topology_t topology, hwloc_shmem_topology_get_length(hwloc_topology_t topology,
size_t *lengthp, size_t *lengthp,
unsigned long flags) unsigned long flags)
{ {
hwloc_topology_t new; hwloc_topology_t new;
struct hwloc_tma tma; struct hwloc_tma tma;
@ -76,9 +76,9 @@ hwloc_shmem_topology_get_length(hwloc_topology_t topology,
int int
hwloc_shmem_topology_write(hwloc_topology_t topology, hwloc_shmem_topology_write(hwloc_topology_t topology,
int fd, uint64_t fileoffset, int fd, uint64_t fileoffset,
void *mmap_address, size_t length, void *mmap_address, size_t length,
unsigned long flags) unsigned long flags)
{ {
hwloc_topology_t new; hwloc_topology_t new;
struct hwloc_tma tma; struct hwloc_tma tma;
@ -144,9 +144,9 @@ hwloc_shmem_topology_write(hwloc_topology_t topology,
int int
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp, hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
int fd, uint64_t fileoffset, int fd, uint64_t fileoffset,
void *mmap_address, size_t length, void *mmap_address, size_t length,
unsigned long flags) unsigned long flags)
{ {
hwloc_topology_t new, old; hwloc_topology_t new, old;
struct hwloc_shmem_header header; struct hwloc_shmem_header header;
@ -178,12 +178,17 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
if (mmap_res == MAP_FAILED) if (mmap_res == MAP_FAILED)
return -1; return -1;
if (mmap_res != mmap_address) { if (mmap_res != mmap_address) {
munmap(mmap_res, length);
errno = EBUSY; errno = EBUSY;
return -1; goto out_with_mmap;
} }
old = (hwloc_topology_t)((char*)mmap_address + sizeof(header)); old = (hwloc_topology_t)((char*)mmap_address + sizeof(header));
if (hwloc_topology_abi_check(old) < 0) {
errno = EINVAL;
goto out_with_mmap;
}
/* enforced by dup() inside shmem_topology_write() */
assert(old->is_loaded); assert(old->is_loaded);
assert(old->backends == NULL); assert(old->backends == NULL);
assert(old->get_pci_busid_cpuset_backend == NULL); assert(old->get_pci_busid_cpuset_backend == NULL);
@ -200,6 +205,7 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
new->tma = NULL; new->tma = NULL;
new->adopted_shmem_addr = mmap_address; new->adopted_shmem_addr = mmap_address;
new->adopted_shmem_length = length; new->adopted_shmem_length = length;
new->topology_abi = HWLOC_TOPOLOGY_ABI;
/* setting binding hooks will touch support arrays, so duplicate them too. /* setting binding hooks will touch support arrays, so duplicate them too.
* could avoid that by requesting a R/W mmap * could avoid that by requesting a R/W mmap
*/ */
@ -210,6 +216,9 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
memcpy(new->support.cpubind, old->support.cpubind, sizeof(*new->support.cpubind)); memcpy(new->support.cpubind, old->support.cpubind, sizeof(*new->support.cpubind));
memcpy(new->support.membind, old->support.membind, sizeof(*new->support.membind)); memcpy(new->support.membind, old->support.membind, sizeof(*new->support.membind));
hwloc_set_binding_hooks(new); hwloc_set_binding_hooks(new);
/* clear userdata callbacks pointing to the writer process' functions */
new->userdata_export_cb = NULL;
new->userdata_import_cb = NULL;
#ifndef HWLOC_DEBUG #ifndef HWLOC_DEBUG
if (getenv("HWLOC_DEBUG_CHECK")) if (getenv("HWLOC_DEBUG_CHECK"))
@ -221,7 +230,8 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
out_with_components: out_with_components:
hwloc_components_fini(); hwloc_components_fini();
munmap(mmap_address, length); out_with_mmap:
munmap(mmap_res, length);
return -1; return -1;
} }
@ -240,8 +250,8 @@ hwloc__topology_disadopt(hwloc_topology_t topology)
int int
hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unused,
size_t *lengthp __hwloc_attribute_unused, size_t *lengthp __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused) unsigned long flags __hwloc_attribute_unused)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
@ -249,9 +259,9 @@ hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unus
int int
hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused,
int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused, int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused, void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused) unsigned long flags __hwloc_attribute_unused)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;
@ -259,9 +269,9 @@ hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused,
int int
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp __hwloc_attribute_unused, hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp __hwloc_attribute_unused,
int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused, int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused, void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused) unsigned long flags __hwloc_attribute_unused)
{ {
errno = ENOSYS; errno = ENOSYS;
return -1; return -1;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux * Copyright © 2009-2011, 2013 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -173,9 +173,9 @@ hwloc_aix_get_tid_getthrds_cpubind(hwloc_topology_t topology __hwloc_attribute_u
#endif #endif
if (thread_info.ti_tid == tid) { if (thread_info.ti_tid == tid) {
if (PROCESSOR_CLASS_ANY != thread_info.ti_cpuid) if (PROCESSOR_CLASS_ANY != thread_info.ti_cpuid)
hwloc_bitmap_set(hwloc_set, thread_info.ti_cpuid); hwloc_bitmap_set(hwloc_set, thread_info.ti_cpuid);
else else
hwloc_bitmap_fill(hwloc_set); hwloc_bitmap_fill(hwloc_set);
break; break;
} }
} }
@ -359,8 +359,9 @@ hwloc_aix_prepare_membind(hwloc_topology_t topology, rsethandle_t *rad, hwloc_co
} }
static int static int
hwloc_aix_set_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who, pid_t pid, hwloc_const_bitmap_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_aix_set_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who, pid_t pid, hwloc_const_bitmap_t _nodeset, hwloc_membind_policy_t policy, int flags)
{ {
hwloc_const_nodeset_t nodeset;
rsethandle_t rad; rsethandle_t rad;
int res; int res;
@ -369,6 +370,11 @@ hwloc_aix_set_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who,
return -1; return -1;
} }
if (policy == HWLOC_MEMBIND_DEFAULT)
nodeset = hwloc_topology_get_complete_nodeset(topology);
else
nodeset = _nodeset;
switch (policy) { switch (policy) {
case HWLOC_MEMBIND_DEFAULT: case HWLOC_MEMBIND_DEFAULT:
case HWLOC_MEMBIND_BIND: case HWLOC_MEMBIND_BIND:
@ -402,11 +408,9 @@ hwloc_aix_get_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who,
rsethandle_t rset; rsethandle_t rset;
unsigned cpu, maxcpus; unsigned cpu, maxcpus;
int res = -1; int res = -1;
int depth, n, i; int n, i;
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); n = hwloc_get_nbobjs_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE);
assert(depth >= 0);
n = hwloc_get_nbobjs_by_depth(topology, depth);
rset = rs_alloc(RS_EMPTY); rset = rs_alloc(RS_EMPTY);
@ -423,7 +427,7 @@ hwloc_aix_get_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who,
hwloc_bitmap_zero(nodeset); hwloc_bitmap_zero(nodeset);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, depth, i); hwloc_obj_t obj = hwloc_get_obj_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE, i);
if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set)) if (hwloc_bitmap_isincluded(obj->cpuset, hwloc_set))
hwloc_bitmap_set(nodeset, obj->os_index); hwloc_bitmap_set(nodeset, obj->os_index);
} }
@ -524,8 +528,9 @@ hwloc_aix_get_thread_membind(hwloc_topology_t topology, hwloc_thread_t pthread,
/* TODO: seems to be right, but doesn't seem to be working (EINVAL), even after /* TODO: seems to be right, but doesn't seem to be working (EINVAL), even after
* aligning the range on 64K... */ * aligning the range on 64K... */
static int static int
hwloc_aix_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_aix_set_area_membind(hwloc_topology_t topology, const void *addr, size_t len, hwloc_const_nodeset_t _nodeset, hwloc_membind_policy_t policy, int flags)
{ {
hwloc_const_nodeset_t nodeset;
subrange_t subrange; subrange_t subrange;
rsid_t rsid = { .at_subrange = &subrange }; rsid_t rsid = { .at_subrange = &subrange };
uint_t aix_policy; uint_t aix_policy;
@ -538,6 +543,11 @@ hwloc_aix_set_area_membind(hwloc_topology_t topology, const void *addr, size_t l
return -1; return -1;
} }
if (policy == HWLOC_MEMBIND_DEFAULT)
nodeset = hwloc_topology_get_complete_nodeset(topology);
else
nodeset = _nodeset;
subrange.su_offset = (uintptr_t) addr; subrange.su_offset = (uintptr_t) addr;
subrange.su_length = len; subrange.su_length = len;
subrange.su_rstype = R_RSET; subrange.su_rstype = R_RSET;
@ -567,12 +577,18 @@ hwloc_aix_set_area_membind(hwloc_topology_t topology, const void *addr, size_t l
#endif #endif
static void * static void *
hwloc_aix_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_aix_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t _nodeset, hwloc_membind_policy_t policy, int flags)
{ {
hwloc_const_nodeset_t nodeset;
void *ret; void *ret;
rsid_t rsid; rsid_t rsid;
uint_t aix_policy; uint_t aix_policy;
if (policy == HWLOC_MEMBIND_DEFAULT)
nodeset = hwloc_topology_get_complete_nodeset(topology);
else
nodeset = _nodeset;
if (hwloc_aix_membind_policy_from_hwloc(&aix_policy, policy)) if (hwloc_aix_membind_policy_from_hwloc(&aix_policy, policy))
return hwloc_alloc_or_fail(topology, len, flags); return hwloc_alloc_or_fail(topology, len, flags);
@ -607,7 +623,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
for (i = 0; i < nbnodes; i++) { for (i = 0; i < nbnodes; i++) {
hwloc_bitmap_t cpuset; hwloc_bitmap_t cpuset;
unsigned os_index = (unsigned) -1; /* no os_index except for PU and NUMANODE below */ unsigned os_index = HWLOC_UNKNOWN_INDEX; /* no os_index except for PU and NUMANODE below */
if (rs_getrad(rset, rad, sdl, i, 0)) { if (rs_getrad(rset, rad, sdl, i, 0)) {
fprintf(stderr,"rs_getrad(%d) failed: %s\n", i, strerror(errno)); fprintf(stderr,"rs_getrad(%d) failed: %s\n", i, strerror(errno));
@ -620,7 +636,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
cpuset = hwloc_bitmap_alloc(); cpuset = hwloc_bitmap_alloc();
for (j = 0; j < maxcpus; j++) { for (j = 0; j < maxcpus; j++) {
if (rs_op(RS_TESTRESOURCE, rad, NULL, R_PROCS, j)) if (rs_op(RS_TESTRESOURCE, rad, NULL, R_PROCS, j))
hwloc_bitmap_set(cpuset, j); hwloc_bitmap_set(cpuset, j);
} }
if (type == HWLOC_OBJ_PU) { if (type == HWLOC_OBJ_PU) {
@ -639,76 +655,76 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
switch(type) { switch(type) {
case HWLOC_OBJ_NUMANODE: case HWLOC_OBJ_NUMANODE:
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, i); hwloc_bitmap_set(obj->nodeset, i);
obj->memory.local_memory = 0; /* TODO: odd, rs_getinfo(rad, R_MEMSIZE, 0) << 10 returns the total memory ... */ obj->attr->numanode.local_memory = 0; /* TODO: odd, rs_getinfo(rad, R_MEMSIZE, 0) << 10 returns the total memory ... */
obj->memory.page_types_len = 2; obj->attr->numanode.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types)); obj->attr->numanode.page_types = malloc(2*sizeof(*obj->attr->numanode.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types)); memset(obj->attr->numanode.page_types, 0, 2*sizeof(*obj->attr->numanode.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize(); obj->attr->numanode.page_types[0].size = hwloc_getpagesize();
#if HAVE_DECL__SC_LARGE_PAGESIZE #if HAVE_DECL__SC_LARGE_PAGESIZE
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif #endif
/* TODO: obj->memory.page_types[1].count = rs_getinfo(rset, R_LGPGFREE, 0) / hugepagesize */ /* TODO: obj->attr->numanode.page_types[1].count = rs_getinfo(rset, R_LGPGFREE, 0) / hugepagesize */
break; break;
case HWLOC_OBJ_L2CACHE: case HWLOC_OBJ_L2CACHE:
obj->attr->cache.size = _system_configuration.L2_cache_size; obj->attr->cache.size = _system_configuration.L2_cache_size;
obj->attr->cache.associativity = _system_configuration.L2_cache_asc; obj->attr->cache.associativity = _system_configuration.L2_cache_asc;
obj->attr->cache.linesize = 0; /* unknown by default */ obj->attr->cache.linesize = 0; /* unknown by default */
if (__power_pc()) if (__power_pc())
if (__power_4() || __power_5() || __power_6() || __power_7()) if (__power_4() || __power_5() || __power_6() || __power_7())
obj->attr->cache.linesize = 128; obj->attr->cache.linesize = 128;
obj->attr->cache.depth = 2; obj->attr->cache.depth = 2;
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; /* OK for power[4567], unknown for others */ obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; /* OK for power[4567], unknown for others */
break; break;
case HWLOC_OBJ_GROUP: case HWLOC_OBJ_GROUP:
obj->attr->group.kind = HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN; obj->attr->group.kind = HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN;
obj->attr->group.subkind = level; obj->attr->group.subkind = level;
break; break;
case HWLOC_OBJ_CORE: case HWLOC_OBJ_CORE:
{ {
hwloc_obj_t obj2, obj3; hwloc_obj_t obj2, obj3;
obj2 = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, -1); obj2 = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, HWLOC_UNKNOWN_INDEX);
obj2->cpuset = hwloc_bitmap_dup(obj->cpuset); obj2->cpuset = hwloc_bitmap_dup(obj->cpuset);
obj2->attr->cache.size = _system_configuration.dcache_size; obj2->attr->cache.size = _system_configuration.dcache_size;
obj2->attr->cache.associativity = _system_configuration.dcache_asc; obj2->attr->cache.associativity = _system_configuration.dcache_asc;
obj2->attr->cache.linesize = _system_configuration.dcache_line; obj2->attr->cache.linesize = _system_configuration.dcache_line;
obj2->attr->cache.depth = 1; obj2->attr->cache.depth = 1;
if (_system_configuration.cache_attrib & (1<<30)) { if (_system_configuration.cache_attrib & (1<<30)) {
/* Unified cache */ /* Unified cache */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; obj2->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
hwloc_debug("Adding an L1u cache for core %d\n", i); hwloc_debug("Adding an L1u cache for core %d\n", i);
} else { } else {
/* Separate Instruction and Data caches */ /* Separate Instruction and Data caches */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj2->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
hwloc_debug("Adding an L1d cache for core %d\n", i); hwloc_debug("Adding an L1d cache for core %d\n", i);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
obj3 = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, -1); obj3 = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, HWLOC_UNKNOWN_INDEX);
obj3->cpuset = hwloc_bitmap_dup(obj->cpuset); obj3->cpuset = hwloc_bitmap_dup(obj->cpuset);
obj3->attr->cache.size = _system_configuration.icache_size; obj3->attr->cache.size = _system_configuration.icache_size;
obj3->attr->cache.associativity = _system_configuration.icache_asc; obj3->attr->cache.associativity = _system_configuration.icache_asc;
obj3->attr->cache.linesize = _system_configuration.icache_line; obj3->attr->cache.linesize = _system_configuration.icache_line;
obj3->attr->cache.depth = 1; obj3->attr->cache.depth = 1;
obj3->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj3->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
hwloc_debug("Adding an L1i cache for core %d\n", i); hwloc_debug("Adding an L1i cache for core %d\n", i);
hwloc_insert_object_by_cpuset(topology, obj3); hwloc_insert_object_by_cpuset(topology, obj3);
} }
} }
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE))
hwloc_insert_object_by_cpuset(topology, obj2); hwloc_insert_object_by_cpuset(topology, obj2);
else else
hwloc_free_unlinked_object(obj2); /* FIXME: don't built at all, just build the cpuset in case l1/l1i needs it */ hwloc_free_unlinked_object(obj2); /* FIXME: don't built at all, just build the cpuset in case l1/l1i needs it */
break; break;
} }
default: default:
break; break;
} }
hwloc_debug_2args_bitmap("%s %d has cpuset %s\n", hwloc_debug_2args_bitmap("%s %d has cpuset %s\n",
hwloc_type_name(type), hwloc_obj_type_string(type),
i, obj->cpuset); i, obj->cpuset);
if (hwloc_filter_check_keep_object_type(topology, obj->type)) if (hwloc_filter_check_keep_object_type(topology, obj->type))
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
else else
@ -729,7 +745,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
/* somebody discovered things */ /* somebody discovered things */
return -1; return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]); hwloc_alloc_root_sets(topology->levels[0][0]);
/* TODO: R_LGPGDEF/R_LGPGFREE for large pages */ /* TODO: R_LGPGDEF/R_LGPGFREE for large pages */
@ -743,52 +759,53 @@ hwloc_look_aix(struct hwloc_backend *backend)
int known = 0; int known = 0;
#if 0 #if 0
if (i == rs_getinfo(NULL, R_SMPSDL, 0)) if (i == rs_getinfo(NULL, R_SMPSDL, 0))
/* Not enabled for now because I'm not sure what it corresponds to. On /* Not enabled for now because I'm not sure what it corresponds to. On
* decrypthon it contains all the cpus. Is it a "machine" or a "system" * decrypthon it contains all the cpus. Is it a "machine" or a "system"
* level ? * level ?
*/ */
{ {
hwloc_debug("looking AIX \"SMP\" sdl %d\n", i); hwloc_debug("looking AIX \"SMP\" sdl %d\n", i);
look_rset(i, HWLOC_OBJ_MACHINE, topology, i); look_rset(i, HWLOC_OBJ_MACHINE, topology, i);
known = 1; known = 1;
} }
#endif #endif
if (i == rs_getinfo(NULL, R_MCMSDL, 0)) if (i == rs_getinfo(NULL, R_MCMSDL, 0))
{ {
hwloc_debug("looking AIX node sdl %d\n", i); hwloc_debug("looking AIX node sdl %d\n", i);
look_rset(i, HWLOC_OBJ_NUMANODE, topology, i); look_rset(i, HWLOC_OBJ_NUMANODE, topology, i);
known = 1; known = 1;
} topology->support.discovery->numa = 1;
}
# ifdef R_L2CSDL # ifdef R_L2CSDL
if (i == rs_getinfo(NULL, R_L2CSDL, 0)) if (i == rs_getinfo(NULL, R_L2CSDL, 0))
{ {
hwloc_debug("looking AIX L2 sdl %d\n", i); hwloc_debug("looking AIX L2 sdl %d\n", i);
look_rset(i, HWLOC_OBJ_L2CACHE, topology, i); look_rset(i, HWLOC_OBJ_L2CACHE, topology, i);
known = 1; known = 1;
} }
# endif # endif
# ifdef R_PCORESDL # ifdef R_PCORESDL
if (i == rs_getinfo(NULL, R_PCORESDL, 0)) if (i == rs_getinfo(NULL, R_PCORESDL, 0))
{ {
hwloc_debug("looking AIX core sdl %d\n", i); hwloc_debug("looking AIX core sdl %d\n", i);
look_rset(i, HWLOC_OBJ_CORE, topology, i); look_rset(i, HWLOC_OBJ_CORE, topology, i);
known = 1; known = 1;
} }
# endif # endif
if (i == rs_getinfo(NULL, R_MAXSDL, 0)) if (i == rs_getinfo(NULL, R_MAXSDL, 0))
{ {
hwloc_debug("looking AIX max sdl %d\n", i); hwloc_debug("looking AIX max sdl %d\n", i);
look_rset(i, HWLOC_OBJ_PU, topology, i); look_rset(i, HWLOC_OBJ_PU, topology, i);
known = 1; known = 1;
topology->support.discovery->pu = 1; topology->support.discovery->pu = 1;
} }
/* Don't know how it should be rendered, make a misc object for it. */ /* Don't know how it should be rendered, make a misc object for it. */
if (!known) if (!known)
{ {
hwloc_debug("looking AIX unknown sdl %d\n", i); hwloc_debug("looking AIX unknown sdl %d\n", i);
look_rset(i, HWLOC_OBJ_GROUP, topology, i); look_rset(i, HWLOC_OBJ_GROUP, topology, i);
} }
} }
hwloc_obj_add_info(topology->levels[0][0], "Backend", "AIX"); hwloc_obj_add_info(topology->levels[0][0], "Backend", "AIX");
@ -798,7 +815,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
void void
hwloc_set_aix_hooks(struct hwloc_binding_hooks *hooks, hwloc_set_aix_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused) struct hwloc_topology_support *support __hwloc_attribute_unused)
{ {
hooks->set_proc_cpubind = hwloc_aix_set_proc_cpubind; hooks->set_proc_cpubind = hwloc_aix_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_aix_get_proc_cpubind; hooks->get_proc_cpubind = hwloc_aix_get_proc_cpubind;
@ -845,9 +862,9 @@ hwloc_set_aix_hooks(struct hwloc_binding_hooks *hooks,
static struct hwloc_backend * static struct hwloc_backend *
hwloc_aix_component_instantiate(struct hwloc_disc_component *component, hwloc_aix_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -863,6 +880,7 @@ static struct hwloc_disc_component hwloc_aix_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_aix_component_instantiate, hwloc_aix_component_instantiate,
50, 50,
1,
NULL NULL
}; };

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2013-2017 Inria. All rights reserved. * Copyright © 2013-2018 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -26,7 +26,7 @@ hwloc_bgq__get_allowed_resources(struct hwloc_topology *topology)
unsigned i; unsigned i;
/* mark the 17th core (OS-reserved) as disallowed */ /* mark the 17th core (OS-reserved) as disallowed */
hwloc_bitmap_clr_range(topology->levels[0][0]->allowed_cpuset, (HWLOC_BGQ_CORES-1)*4, HWLOC_BGQ_CORES*4-1); hwloc_bitmap_clr_range(topology->allowed_cpuset, (HWLOC_BGQ_CORES-1)*4, HWLOC_BGQ_CORES*4-1);
if (topology->is_thissystem) { /* don't call CNK unless thissystem */ if (topology->is_thissystem) { /* don't call CNK unless thissystem */
env = getenv("BG_THREADMODEL"); env = getenv("BG_THREADMODEL");
@ -34,9 +34,9 @@ hwloc_bgq__get_allowed_resources(struct hwloc_topology *topology)
/* process cannot use cores/threads outside of its Kernel_ThreadMask() unless BG_THREADMODEL=2 */ /* process cannot use cores/threads outside of its Kernel_ThreadMask() unless BG_THREADMODEL=2 */
uint64_t bgmask = Kernel_ThreadMask(Kernel_MyTcoord()); uint64_t bgmask = Kernel_ThreadMask(Kernel_MyTcoord());
/* the mask is reversed, manually reverse it */ /* the mask is reversed, manually reverse it */
for(i=0; i<64; i++) for(i=0; i<64; i++)
if (((bgmask >> i) & 1) == 0) if (((bgmask >> i) & 1) == 0)
hwloc_bitmap_clr(topology->levels[0][0]->allowed_cpuset, 63-i); hwloc_bitmap_clr(topology->allowed_cpuset, 63-i);
} }
} }
return 0; return 0;
@ -54,7 +54,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
/* somebody discovered things */ /* somebody discovered things */
return -1; return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]); hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_bgq__get_allowed_resources(topology); hwloc_bgq__get_allowed_resources(topology);
@ -66,15 +66,17 @@ hwloc_look_bgq(struct hwloc_backend *backend)
set = hwloc_bitmap_alloc(); set = hwloc_bitmap_alloc();
hwloc_bitmap_set(set, 0); hwloc_bitmap_set(set, 0);
obj->nodeset = set; obj->nodeset = set;
obj->memory.local_memory = 16ULL*1024*1024*1024ULL; obj->attr->numanode.local_memory = 16ULL*1024*1024*1024ULL;
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
topology->support.discovery->numa = 1;
topology->support.discovery->numa_memory = 1;
set = hwloc_bitmap_alloc(); set = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(set, 0, HWLOC_BGQ_CORES*4-1); hwloc_bitmap_set_range(set, 0, HWLOC_BGQ_CORES*4-1);
/* shared L2 */ /* shared L2 */
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2; obj->attr->cache.depth = 2;
@ -100,7 +102,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
/* L1d */ /* L1d */
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -111,7 +113,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
} }
/* L1i */ /* L1i */
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -132,6 +134,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
} }
/* PUs */ /* PUs */
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, HWLOC_BGQ_CORES*4); hwloc_setup_pu_level(topology, HWLOC_BGQ_CORES*4);
/* Add BGQ specific information */ /* Add BGQ specific information */
@ -231,7 +234,7 @@ hwloc_bgq_get_allowed_resources(struct hwloc_topology *topology)
void void
hwloc_set_bgq_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused, hwloc_set_bgq_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused) struct hwloc_topology_support *support __hwloc_attribute_unused)
{ {
hooks->set_thisthread_cpubind = hwloc_bgq_set_thisthread_cpubind; hooks->set_thisthread_cpubind = hwloc_bgq_set_thisthread_cpubind;
hooks->set_thread_cpubind = hwloc_bgq_set_thread_cpubind; hooks->set_thread_cpubind = hwloc_bgq_set_thread_cpubind;
@ -246,9 +249,9 @@ hwloc_set_bgq_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
static struct hwloc_backend * static struct hwloc_backend *
hwloc_bgq_component_instantiate(struct hwloc_disc_component *component, hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct utsname utsname; struct utsname utsname;
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -261,11 +264,11 @@ hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
if (!env || !atoi(env)) { if (!env || !atoi(env)) {
fprintf(stderr, "*** Found unexpected uname sysname `%s' machine `%s'.\n", utsname.sysname, utsname.machine); fprintf(stderr, "*** Found unexpected uname sysname `%s' machine `%s'.\n", utsname.sysname, utsname.machine);
fprintf(stderr, "*** The BlueGene/Q backend (bgq) is only enabled by default on compute nodes\n" fprintf(stderr, "*** The BlueGene/Q backend (bgq) is only enabled by default on compute nodes\n"
"*** (where uname returns sysname=CNK and machine=BGQ).\n" "*** (where uname returns sysname=CNK and machine=BGQ).\n"
"*** If you know you *really* want to run the bgq backend on this non-compute node,\n" "*** If you know you *really* want to run the bgq backend on this non-compute node,\n"
"*** set HWLOC_FORCE_BGQ=1 in the environment.\n" "*** set HWLOC_FORCE_BGQ=1 in the environment.\n"
"*** If you just want to discover the native topology of this non-compute node,\n" "*** If you just want to discover the native topology of this non-compute node,\n"
"*** do not pass any BlueGene/Q-specific options on the configure command-line.\n"); "*** do not pass any BlueGene/Q-specific options on the configure command-line.\n");
return NULL; return NULL;
} else { } else {
forced_nonbgq = 1; forced_nonbgq = 1;
@ -287,6 +290,7 @@ static struct hwloc_disc_component hwloc_bgq_disc_component = {
~0, ~0,
hwloc_bgq_component_instantiate, hwloc_bgq_component_instantiate,
50, 50,
1,
NULL NULL
}; };

Просмотреть файл

@ -75,10 +75,10 @@ hwloc_cuda_discover(struct hwloc_backend *backend)
hwloc_obj_t cuda_device, parent; hwloc_obj_t cuda_device, parent;
unsigned cores; unsigned cores;
cuda_device = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, -1); cuda_device = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_UNKNOWN_INDEX);
snprintf(cuda_name, sizeof(cuda_name), "cuda%d", i); snprintf(cuda_name, sizeof(cuda_name), "cuda%d", i);
cuda_device->name = strdup(cuda_name); cuda_device->name = strdup(cuda_name);
cuda_device->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN; cuda_device->depth = HWLOC_TYPE_DEPTH_UNKNOWN;
cuda_device->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC; cuda_device->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC;
cuda_device->subtype = strdup("CUDA"); cuda_device->subtype = strdup("CUDA");
@ -86,7 +86,7 @@ hwloc_cuda_discover(struct hwloc_backend *backend)
hwloc_obj_add_info(cuda_device, "GPUVendor", "NVIDIA Corporation"); hwloc_obj_add_info(cuda_device, "GPUVendor", "NVIDIA Corporation");
cures = cudaGetDeviceProperties(&prop, i); cures = cudaGetDeviceProperties(&prop, i);
if (!cures) if (!cures && prop.name[0] != '\0')
hwloc_obj_add_info(cuda_device, "GPUModel", prop.name); hwloc_obj_add_info(cuda_device, "GPUModel", prop.name);
snprintf(number, sizeof(number), "%llu", ((unsigned long long) prop.totalGlobalMem) >> 10); snprintf(number, sizeof(number), "%llu", ((unsigned long long) prop.totalGlobalMem) >> 10);
@ -111,7 +111,7 @@ hwloc_cuda_discover(struct hwloc_backend *backend)
if (hwloc_cudart_get_device_pci_ids(NULL /* topology unused */, i, &domain, &bus, &dev) == 0) { if (hwloc_cudart_get_device_pci_ids(NULL /* topology unused */, i, &domain, &bus, &dev) == 0) {
parent = hwloc_pcidisc_find_by_busid(topology, domain, bus, dev, 0); parent = hwloc_pcidisc_find_by_busid(topology, domain, bus, dev, 0);
if (!parent) if (!parent)
parent = hwloc_pcidisc_find_busid_parent(topology, domain, bus, dev, 0); parent = hwloc_pcidisc_find_busid_parent(topology, domain, bus, dev, 0);
} }
if (!parent) if (!parent)
parent = hwloc_get_root_obj(topology); parent = hwloc_get_root_obj(topology);
@ -144,6 +144,7 @@ static struct hwloc_disc_component hwloc_cuda_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_cuda_component_instantiate, hwloc_cuda_component_instantiate,
10, /* after pci */ 10, /* after pci */
1,
NULL NULL
}; };

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2013 Université Bordeaux * Copyright © 2009-2013 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -35,36 +35,77 @@ hwloc_look_darwin(struct hwloc_backend *backend)
int64_t l1dcachesize, l1icachesize; int64_t l1dcachesize, l1icachesize;
int64_t cacheways[2]; int64_t cacheways[2];
int64_t l2cachesize; int64_t l2cachesize;
int64_t l3cachesize;
int64_t cachelinesize; int64_t cachelinesize;
int64_t memsize; int64_t memsize;
int64_t _tmp;
char cpumodel[64]; char cpumodel[64];
char cpuvendor[64];
char cpufamilynumber[20], cpumodelnumber[20], cpustepping[20];
int gotnuma = 0;
int gotnumamemory = 0;
if (topology->levels[0][0]->cpuset) if (topology->levels[0][0]->cpuset)
/* somebody discovered things */ /* somebody discovered things */
return -1; return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]); hwloc_alloc_root_sets(topology->levels[0][0]);
/* Don't use hwloc_fallback_nbprocessors() because it would return online cpus only,
* while we need all cpus when computing logical_per_package, etc below.
* We don't know which CPUs are offline, but Darwin doesn't support binding anyway.
*
* TODO: try hw.logicalcpu_max
*/
if (hwloc_get_sysctlbyname("hw.logicalcpu", &_nprocs) || _nprocs <= 0)
/* fallback to deprecated way */
if (hwloc_get_sysctlbyname("hw.ncpu", &_nprocs) || _nprocs <= 0)
return -1;
if (hwloc_get_sysctlbyname("hw.ncpu", &_nprocs) || _nprocs <= 0)
return -1;
nprocs = _nprocs; nprocs = _nprocs;
topology->support.discovery->pu = 1; topology->support.discovery->pu = 1;
hwloc_debug("%u procs\n", nprocs); hwloc_debug("%u procs\n", nprocs);
size = sizeof(cpuvendor);
if (sysctlbyname("machdep.cpu.vendor", cpuvendor, &size, NULL, 0))
cpuvendor[0] = '\0';
size = sizeof(cpumodel); size = sizeof(cpumodel);
if (sysctlbyname("machdep.cpu.brand_string", cpumodel, &size, NULL, 0)) if (sysctlbyname("machdep.cpu.brand_string", cpumodel, &size, NULL, 0))
cpumodel[0] = '\0'; cpumodel[0] = '\0';
if (hwloc_get_sysctlbyname("machdep.cpu.family", &_tmp))
cpufamilynumber[0] = '\0';
else
snprintf(cpufamilynumber, sizeof(cpufamilynumber), "%lld", (long long) _tmp);
if (hwloc_get_sysctlbyname("machdep.cpu.model", &_tmp))
cpumodelnumber[0] = '\0';
else
snprintf(cpumodelnumber, sizeof(cpumodelnumber), "%lld", (long long) _tmp);
/* .extfamily and .extmodel are already added to .family and .model */
if (hwloc_get_sysctlbyname("machdep.cpu.stepping", &_tmp))
cpustepping[0] = '\0';
else
snprintf(cpustepping, sizeof(cpustepping), "%lld", (long long) _tmp);
if (!hwloc_get_sysctlbyname("hw.packages", &_npackages) && _npackages > 0) { if (!hwloc_get_sysctlbyname("hw.packages", &_npackages) && _npackages > 0) {
unsigned npackages = _npackages; unsigned npackages = _npackages;
int64_t _cores_per_package; int64_t _cores_per_package;
unsigned cores_per_package;
int64_t _logical_per_package; int64_t _logical_per_package;
unsigned logical_per_package; unsigned logical_per_package;
hwloc_debug("%u packages\n", npackages); hwloc_debug("%u packages\n", npackages);
if (!hwloc_get_sysctlbyname("machdep.cpu.logical_per_package", &_logical_per_package) && _logical_per_package > 0) if (!hwloc_get_sysctlbyname("machdep.cpu.thread_count", &_logical_per_package) && _logical_per_package > 0)
/* official/modern way */
logical_per_package = _logical_per_package;
else if (!hwloc_get_sysctlbyname("machdep.cpu.logical_per_package", &_logical_per_package) && _logical_per_package > 0)
/* old way, gives the max supported by this "kind" of processor,
* can be larger than the actual number for this model.
*/
logical_per_package = _logical_per_package; logical_per_package = _logical_per_package;
else else
/* Assume the trivia. */ /* Assume the trivia. */
@ -73,7 +114,7 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_debug("%u threads per package\n", logical_per_package); hwloc_debug("%u threads per package\n", logical_per_package);
if (nprocs == npackages * logical_per_package if (nprocs == npackages * logical_per_package
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_PACKAGE)) && hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_PACKAGE))
for (i = 0; i < npackages; i++) { for (i = 0; i < npackages; i++) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PACKAGE, i); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PACKAGE, i);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
@ -83,17 +124,46 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_debug_1arg_bitmap("package %u has cpuset %s\n", hwloc_debug_1arg_bitmap("package %u has cpuset %s\n",
i, obj->cpuset); i, obj->cpuset);
if (cpuvendor[0] != '\0')
hwloc_obj_add_info(obj, "CPUVendor", cpuvendor);
if (cpumodel[0] != '\0') if (cpumodel[0] != '\0')
hwloc_obj_add_info(obj, "CPUModel", cpumodel); hwloc_obj_add_info(obj, "CPUModel", cpumodel);
if (cpufamilynumber[0] != '\0')
hwloc_obj_add_info(obj, "CPUFamilyNumber", cpufamilynumber);
if (cpumodelnumber[0] != '\0')
hwloc_obj_add_info(obj, "CPUModelNumber", cpumodelnumber);
if (cpustepping[0] != '\0')
hwloc_obj_add_info(obj, "CPUStepping", cpustepping);
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
else else {
if (cpuvendor[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUVendor", cpuvendor);
if (cpumodel[0] != '\0') if (cpumodel[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUModel", cpumodel); hwloc_obj_add_info(topology->levels[0][0], "CPUModel", cpumodel);
if (cpufamilynumber[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUFamilyNumber", cpufamilynumber);
if (cpumodelnumber[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUModelNumber", cpumodelnumber);
if (cpustepping[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUStepping", cpustepping);
}
if (!hwloc_get_sysctlbyname("machdep.cpu.cores_per_package", &_cores_per_package) && _cores_per_package > 0 if (!hwloc_get_sysctlbyname("machdep.cpu.core_count", &_cores_per_package) && _cores_per_package > 0)
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_CORE)) { /* official/modern way */
unsigned cores_per_package = _cores_per_package; cores_per_package = _cores_per_package;
else if (!hwloc_get_sysctlbyname("machdep.cpu.cores_per_package", &_cores_per_package) && _cores_per_package > 0)
/* old way, gives the max supported by this "kind" of processor,
* can be larger than the actual number for this model.
*/
cores_per_package = _cores_per_package;
else
/* no idea */
cores_per_package = 0;
if (cores_per_package > 0
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_CORE)) {
hwloc_debug("%u cores per package\n", cores_per_package); hwloc_debug("%u cores per package\n", cores_per_package);
if (!(logical_per_package % cores_per_package)) if (!(logical_per_package % cores_per_package))
@ -110,9 +180,18 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
} }
} else } else {
if (cpuvendor[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUVendor", cpuvendor);
if (cpumodel[0] != '\0') if (cpumodel[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUModel", cpumodel); hwloc_obj_add_info(topology->levels[0][0], "CPUModel", cpumodel);
if (cpufamilynumber[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUFamilyNumber", cpufamilynumber);
if (cpumodelnumber[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUModelNumber", cpumodelnumber);
if (cpustepping[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUStepping", cpustepping);
}
if (hwloc_get_sysctlbyname("hw.l1dcachesize", &l1dcachesize)) if (hwloc_get_sysctlbyname("hw.l1dcachesize", &l1dcachesize))
l1dcachesize = 0; l1dcachesize = 0;
@ -123,6 +202,9 @@ hwloc_look_darwin(struct hwloc_backend *backend)
if (hwloc_get_sysctlbyname("hw.l2cachesize", &l2cachesize)) if (hwloc_get_sysctlbyname("hw.l2cachesize", &l2cachesize))
l2cachesize = 0; l2cachesize = 0;
if (hwloc_get_sysctlbyname("hw.l3cachesize", &l3cachesize))
l3cachesize = 0;
if (hwloc_get_sysctlbyname("machdep.cpu.cache.L1_associativity", &cacheways[0])) if (hwloc_get_sysctlbyname("machdep.cpu.cache.L1_associativity", &cacheways[0]))
cacheways[0] = 0; cacheways[0] = 0;
else if (cacheways[0] == 0xff) else if (cacheways[0] == 0xff)
@ -141,22 +223,9 @@ hwloc_look_darwin(struct hwloc_backend *backend)
if (!sysctlbyname("hw.cacheconfig", NULL, &size, NULL, 0)) { if (!sysctlbyname("hw.cacheconfig", NULL, &size, NULL, 0)) {
unsigned n = size / sizeof(uint32_t); unsigned n = size / sizeof(uint32_t);
uint64_t *cacheconfig = NULL; uint64_t cacheconfig[n];
uint64_t *cachesize = NULL; uint64_t cachesize[n];
uint32_t *cacheconfig32 = NULL; uint32_t cacheconfig32[n];
cacheconfig = malloc(sizeof(uint64_t) * n);
if (NULL == cacheconfig) {
goto out;
}
cachesize = malloc(sizeof(uint64_t) * n);
if (NULL == cachesize) {
goto out;
}
cacheconfig32 = malloc(sizeof(uint32_t) * n);
if (NULL == cacheconfig32) {
goto out;
}
if ((!sysctlbyname("hw.cacheconfig", cacheconfig, &size, NULL, 0))) { if ((!sysctlbyname("hw.cacheconfig", cacheconfig, &size, NULL, 0))) {
/* Yeech. Darwin seemingly has changed from 32bit to 64bit integers for /* Yeech. Darwin seemingly has changed from 32bit to 64bit integers for
@ -177,6 +246,8 @@ hwloc_look_darwin(struct hwloc_backend *backend)
cachesize[1] = l1dcachesize; cachesize[1] = l1dcachesize;
if (n > 2) if (n > 2)
cachesize[2] = l2cachesize; cachesize[2] = l2cachesize;
if (n > 3)
cachesize[3] = l3cachesize;
} }
hwloc_debug("%s", "caches"); hwloc_debug("%s", "caches");
@ -191,13 +262,14 @@ hwloc_look_darwin(struct hwloc_backend *backend)
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
/* cacheconfig tells us how many cpus share it, let's iterate on each cache */ /* cacheconfig tells us how many cpus share it, let's iterate on each cache */
for (j = 0; j < (nprocs / cacheconfig[i]); j++) { for (j = 0; j < (nprocs / cacheconfig[i]); j++) {
if (!i) { if (!i) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, j); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, j);
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, j); hwloc_bitmap_set(obj->nodeset, j);
gotnuma++;
} else { } else {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE+i-1, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE+i-1, HWLOC_UNKNOWN_INDEX);
} }
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
for (cpu = j*cacheconfig[i]; for (cpu = j*cacheconfig[i];
cpu < ((j+1)*cacheconfig[i]); cpu < ((j+1)*cacheconfig[i]);
@ -205,10 +277,10 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_bitmap_set(obj->cpuset, cpu); hwloc_bitmap_set(obj->cpuset, cpu);
if (i == 1 && l1icachesize if (i == 1 && l1icachesize
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) { && hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
/* FIXME assuming that L1i and L1d are shared the same way. Darwin /* FIXME assuming that L1i and L1d are shared the same way. Darwin
* does not yet provide a way to know. */ * does not yet provide a way to know. */
hwloc_obj_t l1i = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, -1); hwloc_obj_t l1i = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, HWLOC_UNKNOWN_INDEX);
l1i->cpuset = hwloc_bitmap_dup(obj->cpuset); l1i->cpuset = hwloc_bitmap_dup(obj->cpuset);
hwloc_debug_1arg_bitmap("L1icache %u has cpuset %s\n", hwloc_debug_1arg_bitmap("L1icache %u has cpuset %s\n",
j, l1i->cpuset); j, l1i->cpuset);
@ -237,29 +309,32 @@ hwloc_look_darwin(struct hwloc_backend *backend)
} else { } else {
hwloc_debug_1arg_bitmap("node %u has cpuset %s\n", hwloc_debug_1arg_bitmap("node %u has cpuset %s\n",
j, obj->cpuset); j, obj->cpuset);
obj->memory.local_memory = cachesize[i]; if (cachesize[i]) {
obj->memory.page_types_len = 2; obj->attr->numanode.local_memory = cachesize[i];
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types)); gotnumamemory++;
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types)); }
obj->memory.page_types[0].size = hwloc_getpagesize(); obj->attr->numanode.page_types_len = 2;
obj->attr->numanode.page_types = malloc(2*sizeof(*obj->attr->numanode.page_types));
memset(obj->attr->numanode.page_types, 0, 2*sizeof(*obj->attr->numanode.page_types));
obj->attr->numanode.page_types[0].size = hwloc_getpagesize();
#if HAVE_DECL__SC_LARGE_PAGESIZE #if HAVE_DECL__SC_LARGE_PAGESIZE
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif #endif
} }
if (hwloc_filter_check_keep_object_type(topology, obj->type)) if (hwloc_filter_check_keep_object_type(topology, obj->type))
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
else else
hwloc_free_unlinked_object(obj); /* FIXME: don't built at all, just build the cpuset in case l1i needs it */ hwloc_free_unlinked_object(obj); /* FIXME: don't built at all, just build the cpuset in case l1i needs it */
} }
} }
} }
out:
free(cacheconfig);
free(cachesize);
free(cacheconfig32);
} }
if (gotnuma)
topology->support.discovery->numa = 1;
if (gotnumamemory)
topology->support.discovery->numa = 1;
/* add PU objects */ /* add PU objects */
hwloc_setup_pu_level(topology, nprocs); hwloc_setup_pu_level(topology, nprocs);
@ -271,15 +346,15 @@ hwloc_look_darwin(struct hwloc_backend *backend)
void void
hwloc_set_darwin_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused, hwloc_set_darwin_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused) struct hwloc_topology_support *support __hwloc_attribute_unused)
{ {
} }
static struct hwloc_backend * static struct hwloc_backend *
hwloc_darwin_component_instantiate(struct hwloc_disc_component *component, hwloc_darwin_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -295,6 +370,7 @@ static struct hwloc_disc_component hwloc_darwin_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_darwin_component_instantiate, hwloc_darwin_component_instantiate,
50, 50,
1,
NULL NULL
}; };

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2012-2014 Inria. All rights reserved. * Copyright © 2012-2017 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -11,9 +11,9 @@
static struct hwloc_backend * static struct hwloc_backend *
hwloc_fake_component_instantiate(struct hwloc_disc_component *component __hwloc_attribute_unused, hwloc_fake_component_instantiate(struct hwloc_disc_component *component __hwloc_attribute_unused,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT")) if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component instantiated\n"); printf("fake component instantiated\n");
@ -26,6 +26,7 @@ static struct hwloc_disc_component hwloc_fake_disc_component = {
0, /* nothing to exclude */ 0, /* nothing to exclude */
hwloc_fake_component_instantiate, hwloc_fake_component_instantiate,
100, /* make sure it's loaded before anything conflicting excludes it */ 100, /* make sure it's loaded before anything conflicting excludes it */
1,
NULL NULL
}; };

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2015 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux * Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -172,7 +172,7 @@ hwloc_freebsd_node_meminfo_info(struct hwloc_topology *topology)
unsigned long physmem; unsigned long physmem;
size_t len = sizeof(physmem); size_t len = sizeof(physmem);
sysctl(mib, 2, &physmem, &len, NULL, 0); sysctl(mib, 2, &physmem, &len, NULL, 0);
topology->levels[0][0]->memory.local_memory = physmem; topology->machine_memory.local_memory = physmem;
/* we don't know anything about NUMA nodes in this backend. /* we don't know anything about NUMA nodes in this backend.
* let another backend or the core move that memory to the right NUMA node */ * let another backend or the core move that memory to the right NUMA node */
} }
@ -182,11 +182,15 @@ static int
hwloc_look_freebsd(struct hwloc_backend *backend) hwloc_look_freebsd(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->levels[0][0]->cpuset) { if (!topology->levels[0][0]->cpuset) {
/* Nobody (even the x86 backend) created objects yet, setup basic objects */ /* Nobody (even the x86 backend) created objects yet, setup basic objects */
hwloc_alloc_obj_cpusets(topology->levels[0][0]); int nbprocs = hwloc_fallback_nbprocessors(topology);
if (nbprocs >= 1)
topology->support.discovery->pu = 1;
else
nbprocs = 1;
hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs); hwloc_setup_pu_level(topology, nbprocs);
} }
@ -201,7 +205,7 @@ hwloc_look_freebsd(struct hwloc_backend *backend)
void void
hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused, hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused) struct hwloc_topology_support *support __hwloc_attribute_unused)
{ {
#if defined(HAVE_SYS_CPUSET_H) && defined(HAVE_CPUSET_SETAFFINITY) #if defined(HAVE_SYS_CPUSET_H) && defined(HAVE_CPUSET_SETAFFINITY)
hooks->set_thisproc_cpubind = hwloc_freebsd_set_thisproc_cpubind; hooks->set_thisproc_cpubind = hwloc_freebsd_set_thisproc_cpubind;
@ -224,9 +228,9 @@ hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unus
static struct hwloc_backend * static struct hwloc_backend *
hwloc_freebsd_component_instantiate(struct hwloc_disc_component *component, hwloc_freebsd_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -242,6 +246,7 @@ static struct hwloc_disc_component hwloc_freebsd_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_freebsd_component_instantiate, hwloc_freebsd_component_instantiate,
50, 50,
1,
NULL NULL
}; };

Просмотреть файл

@ -53,7 +53,7 @@ hwloc_gl_discover(struct hwloc_backend *backend)
for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) { for (j = 0; j < (unsigned) ScreenCount(display) && j < HWLOC_GL_SCREEN_MAX; j++) {
hwloc_obj_t osdev, parent; hwloc_obj_t osdev, parent;
const int screen = j; const int screen = (int)j;
unsigned int *ptr_binary_data; unsigned int *ptr_binary_data;
int data_length; int data_length;
int gpu_number; int gpu_number;
@ -76,7 +76,7 @@ hwloc_gl_discover(struct hwloc_backend *backend)
if (!err) if (!err)
continue; continue;
gpu_number = ptr_binary_data[1]; gpu_number = (int)ptr_binary_data[1];
free(ptr_binary_data); free(ptr_binary_data);
#ifdef NV_CTRL_PCI_DOMAIN #ifdef NV_CTRL_PCI_DOMAIN
@ -111,26 +111,25 @@ hwloc_gl_discover(struct hwloc_backend *backend)
snprintf(name, sizeof(name), ":%u.%u", i, j); snprintf(name, sizeof(name), ":%u.%u", i, j);
osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, -1); osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_UNKNOWN_INDEX);
osdev->name = strdup(name); osdev->name = strdup(name);
osdev->logical_index = -1;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU; osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
hwloc_obj_add_info(osdev, "Backend", "GL"); hwloc_obj_add_info(osdev, "Backend", "GL");
hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation"); hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
if (productname) if (productname)
hwloc_obj_add_info(osdev, "GPUModel", productname); hwloc_obj_add_info(osdev, "GPUModel", productname);
parent = hwloc_pcidisc_find_by_busid(topology, nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func); parent = hwloc_pcidisc_find_by_busid(topology, (unsigned)nv_ctrl_pci_domain, (unsigned)nv_ctrl_pci_bus, (unsigned)nv_ctrl_pci_device, (unsigned)nv_ctrl_pci_func);
if (!parent) if (!parent)
parent = hwloc_pcidisc_find_busid_parent(topology, nv_ctrl_pci_domain, nv_ctrl_pci_bus, nv_ctrl_pci_device, nv_ctrl_pci_func); parent = hwloc_pcidisc_find_busid_parent(topology, (unsigned)nv_ctrl_pci_domain, (unsigned)nv_ctrl_pci_bus, (unsigned)nv_ctrl_pci_device, (unsigned)nv_ctrl_pci_func);
if (!parent) if (!parent)
parent = hwloc_get_root_obj(topology); parent = hwloc_get_root_obj(topology);
hwloc_insert_object_by_parent(topology, parent, osdev); hwloc_insert_object_by_parent(topology, parent, osdev);
hwloc_debug("GL device %s (product %s) on PCI %04x:%02x:%02x.%01x\n", hwloc_debug("GL device %s (product %s) on PCI %04x:%02x:%02x.%01x\n",
name, productname, name, productname,
(unsigned) nv_ctrl_pci_domain, (unsigned) nv_ctrl_pci_bus, (unsigned) nv_ctrl_pci_device, (unsigned) nv_ctrl_pci_func); (unsigned) nv_ctrl_pci_domain, (unsigned) nv_ctrl_pci_bus, (unsigned) nv_ctrl_pci_device, (unsigned) nv_ctrl_pci_func);
} }
XCloseDisplay(display); XCloseDisplay(display);
} }
@ -140,9 +139,9 @@ hwloc_gl_discover(struct hwloc_backend *backend)
static struct hwloc_backend * static struct hwloc_backend *
hwloc_gl_component_instantiate(struct hwloc_disc_component *component, hwloc_gl_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -159,6 +158,7 @@ static struct hwloc_disc_component hwloc_gl_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_gl_component_instantiate, hwloc_gl_component_instantiate,
10, /* after pci */ 10, /* after pci */
1,
NULL NULL
}; };

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2015-2016 Inria. All rights reserved. * Copyright © 2015-2017 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -22,7 +22,7 @@ int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology)
hwloc_bitmap_set(set, i); hwloc_bitmap_set(set, i);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -32,7 +32,7 @@ int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology)
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -53,7 +53,7 @@ int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology)
hwloc_bitmap_set_range(set, 0, 7); hwloc_bitmap_set_range(set, 0, 7);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2; obj->attr->cache.depth = 2;
@ -71,6 +71,7 @@ int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology)
} else } else
hwloc_bitmap_free(set); hwloc_bitmap_free(set);
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, 8); hwloc_setup_pu_level(topology, 8);
return 0; return 0;
@ -90,7 +91,7 @@ int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology)
hwloc_bitmap_set(set, i); hwloc_bitmap_set(set, i);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -100,7 +101,7 @@ int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology)
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -121,7 +122,7 @@ int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology)
hwloc_bitmap_set_range(set, 0, 15); hwloc_bitmap_set_range(set, 0, 15);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2; obj->attr->cache.depth = 2;
@ -139,6 +140,7 @@ int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology)
} else } else
hwloc_bitmap_free(set); hwloc_bitmap_free(set);
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, 16); hwloc_setup_pu_level(topology, 16);
return 0; return 0;
@ -158,7 +160,7 @@ int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology)
hwloc_bitmap_set(set, i); hwloc_bitmap_set(set, i);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1ICACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -168,7 +170,7 @@ int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology)
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_dup(set); obj->cpuset = hwloc_bitmap_dup(set);
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
obj->attr->cache.depth = 1; obj->attr->cache.depth = 1;
@ -186,7 +188,7 @@ int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology)
} }
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L2CACHE)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(obj->cpuset, 0, 15); hwloc_bitmap_set_range(obj->cpuset, 0, 15);
hwloc_bitmap_set(obj->cpuset, 32); hwloc_bitmap_set(obj->cpuset, 32);
@ -197,7 +199,7 @@ int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology)
obj->attr->cache.associativity = 24; obj->attr->cache.associativity = 24;
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, -1); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L2CACHE, HWLOC_UNKNOWN_INDEX);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(obj->cpuset, 16, 31); hwloc_bitmap_set_range(obj->cpuset, 16, 31);
hwloc_bitmap_set(obj->cpuset, 33); hwloc_bitmap_set(obj->cpuset, 33);
@ -217,6 +219,7 @@ int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology)
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, 34); hwloc_setup_pu_level(topology, 34);
return 0; return 0;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2010, 2013 Université Bordeaux * Copyright © 2009-2010, 2013 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -50,8 +50,8 @@ hwloc_hpux_find_ldom(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set)
while (obj->type != HWLOC_OBJ_NUMANODE) { while (obj->type != HWLOC_OBJ_NUMANODE) {
/* try the first child, in case it has the same cpuset */ /* try the first child, in case it has the same cpuset */
if (!obj->first_child if (!obj->first_child
|| !obj->first_child->cpuset || !obj->first_child->cpuset
|| !hwloc_bitmap_isequal(obj->cpuset, obj->first_child->cpuset)) || !hwloc_bitmap_isequal(obj->cpuset, obj->first_child->cpuset))
return -1; return -1;
obj = obj->first_child; obj = obj->first_child;
} }
@ -139,13 +139,16 @@ hwloc_hpux_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_
#ifdef MAP_MEM_FIRST_TOUCH #ifdef MAP_MEM_FIRST_TOUCH
static void* static void*
hwloc_hpux_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_hpux_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_nodeset_t _nodeset, hwloc_membind_policy_t policy, int flags)
{ {
hwloc_const_nodeset_t nodeset;
int mmap_flags; int mmap_flags;
void *p; void *p;
/* Can not give a set of nodes. */ /* Can not give a set of nodes. */
if (!hwloc_bitmap_isequal(nodeset, hwloc_topology_get_complete_nodeset(topology))) { nodeset = hwloc_topology_get_complete_nodeset(topology);
if (policy != HWLOC_MEMBIND_DEFAULT
&& !hwloc_bitmap_isequal(nodeset, _nodeset)) {
errno = EXDEV; errno = EXDEV;
return hwloc_alloc_or_fail(topology, len, flags); return hwloc_alloc_or_fail(topology, len, flags);
} }
@ -176,7 +179,6 @@ hwloc_look_hpux(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1; int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1;
hwloc_obj_t *nodes = NULL, obj;
spu_t currentcpu; spu_t currentcpu;
ldom_t currentnode; ldom_t currentnode;
int i, nbnodes = 0; int i, nbnodes = 0;
@ -185,22 +187,23 @@ hwloc_look_hpux(struct hwloc_backend *backend)
/* somebody discovered things */ /* somebody discovered things */
return -1; return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]); hwloc_alloc_root_sets(topology->levels[0][0]);
if (has_numa) { if (has_numa) {
nbnodes = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ? nbnodes = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
MPC_GETNUMLDOMS_SYS : MPC_GETNUMLDOMS, 0, 0); MPC_GETNUMLDOMS_SYS : MPC_GETNUMLDOMS, 0, 0);
}
hwloc_debug("%d nodes\n", nbnodes);
hwloc_debug("%d nodes\n", nbnodes); hwloc_obj_t nodes[nbnodes], obj;
nodes = malloc(nbnodes * sizeof(*nodes));
if (has_numa) {
i = 0; i = 0;
currentnode = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ? currentnode = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0); MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0);
while (currentnode != -1 && i < nbnodes) { while (currentnode != -1 && i < nbnodes) {
hwloc_debug("node %d is %d\n", i, currentnode); hwloc_debug("node %d is %d\n", i, currentnode);
nodes[i] = obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, currentnode); nodes[i] = obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, (unsigned) currentnode);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, currentnode); hwloc_bitmap_set(obj->nodeset, currentnode);
@ -217,13 +220,13 @@ hwloc_look_hpux(struct hwloc_backend *backend)
currentcpu = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ? currentcpu = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
MPC_GETFIRSTSPU_SYS : MPC_GETFIRSTSPU, 0,0); MPC_GETFIRSTSPU_SYS : MPC_GETFIRSTSPU, 0,0);
while (currentcpu != -1) { while (currentcpu != -1) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, currentcpu); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, (unsigned) currentcpu);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->cpuset, currentcpu); hwloc_bitmap_set(obj->cpuset, currentcpu);
hwloc_debug("cpu %d\n", currentcpu); hwloc_debug("cpu %d\n", currentcpu);
if (nodes) { if (has_numa) {
/* Add this cpu to its node */ /* Add this cpu to its node */
currentnode = mpctl(MPC_SPUTOLDOM, currentcpu, 0); currentnode = mpctl(MPC_SPUTOLDOM, currentcpu, 0);
/* Hopefully it's just the same as previous cpu */ /* Hopefully it's just the same as previous cpu */
@ -246,14 +249,15 @@ hwloc_look_hpux(struct hwloc_backend *backend)
MPC_GETNEXTSPU_SYS : MPC_GETNEXTSPU, currentcpu, 0); MPC_GETNEXTSPU_SYS : MPC_GETNEXTSPU, currentcpu, 0);
} }
if (nodes) { if (has_numa) {
/* Add nodes */ /* Add nodes */
for (i = 0 ; i < nbnodes ; i++) for (i = 0 ; i < nbnodes ; i++)
hwloc_insert_object_by_cpuset(topology, nodes[i]); hwloc_insert_object_by_cpuset(topology, nodes[i]);
free(nodes);
} }
topology->support.discovery->pu = 1; topology->support.discovery->pu = 1;
if (has_numa)
topology->support.discovery->numa = 1;
hwloc_obj_add_info(topology->levels[0][0], "Backend", "HP-UX"); hwloc_obj_add_info(topology->levels[0][0], "Backend", "HP-UX");
hwloc_add_uname_info(topology, NULL); hwloc_add_uname_info(topology, NULL);
@ -262,7 +266,7 @@ hwloc_look_hpux(struct hwloc_backend *backend)
void void
hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks, hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused) struct hwloc_topology_support *support __hwloc_attribute_unused)
{ {
hooks->set_proc_cpubind = hwloc_hpux_set_proc_cpubind; hooks->set_proc_cpubind = hwloc_hpux_set_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_hpux_set_thisproc_cpubind; hooks->set_thisproc_cpubind = hwloc_hpux_set_thisproc_cpubind;
@ -282,9 +286,9 @@ hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks,
static struct hwloc_backend * static struct hwloc_backend *
hwloc_hpux_component_instantiate(struct hwloc_disc_component *component, hwloc_hpux_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -300,6 +304,7 @@ static struct hwloc_disc_component hwloc_hpux_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_hpux_component_instantiate, hwloc_hpux_component_instantiate,
50, 50,
1,
NULL NULL
}; };

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2012 Aleksej Saushev, The NetBSD Foundation * Copyright © 2012 Aleksej Saushev, The NetBSD Foundation
* Copyright © 2009-2015 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux * Copyright © 2009-2010 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -141,7 +141,7 @@ hwloc_netbsd_node_meminfo_info(struct hwloc_topology *topology)
unsigned long physmem; unsigned long physmem;
size_t len = sizeof(physmem); size_t len = sizeof(physmem);
sysctl(mib, 2, &physmem, &len, NULL, 0); sysctl(mib, 2, &physmem, &len, NULL, 0);
topology->levels[0][0]->memory.local_memory = physmem; topology->machine_memory.local_memory = physmem;
} }
#endif #endif
@ -149,11 +149,15 @@ static int
hwloc_look_netbsd(struct hwloc_backend *backend) hwloc_look_netbsd(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->levels[0][0]->cpuset) { if (!topology->levels[0][0]->cpuset) {
/* Nobody (even the x86 backend) created objects yet, setup basic objects */ /* Nobody (even the x86 backend) created objects yet, setup basic objects */
hwloc_alloc_obj_cpusets(topology->levels[0][0]); int nbprocs = hwloc_fallback_nbprocessors(topology);
if (nbprocs >= 1)
topology->support.discovery->pu = 1;
else
nbprocs = 1;
hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs); hwloc_setup_pu_level(topology, nbprocs);
} }
@ -183,9 +187,9 @@ hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unuse
static struct hwloc_backend * static struct hwloc_backend *
hwloc_netbsd_component_instantiate(struct hwloc_disc_component *component, hwloc_netbsd_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -201,6 +205,7 @@ static struct hwloc_disc_component hwloc_netbsd_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_netbsd_component_instantiate, hwloc_netbsd_component_instantiate,
50, 50,
1,
NULL NULL
}; };

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2015 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -14,22 +14,29 @@ static int
hwloc_look_noos(struct hwloc_backend *backend) hwloc_look_noos(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
int nbprocs;
if (topology->levels[0][0]->cpuset) if (topology->levels[0][0]->cpuset)
/* somebody discovered things */ /* somebody discovered things */
return -1; return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]); nbprocs = hwloc_fallback_nbprocessors(topology);
hwloc_setup_pu_level(topology, hwloc_fallback_nbprocessors(topology)); if (nbprocs >= 1)
topology->support.discovery->pu = 1;
else
nbprocs = 1;
hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, nbprocs);
hwloc_add_uname_info(topology, NULL); hwloc_add_uname_info(topology, NULL);
return 0; return 0;
} }
static struct hwloc_backend * static struct hwloc_backend *
hwloc_noos_component_instantiate(struct hwloc_disc_component *component, hwloc_noos_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -45,6 +52,7 @@ static struct hwloc_disc_component hwloc_noos_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_noos_component_instantiate, hwloc_noos_component_instantiate,
40, /* lower than native OS component, higher than globals */ 40, /* lower than native OS component, higher than globals */
1,
NULL NULL
}; };

Просмотреть файл

@ -43,10 +43,10 @@ hwloc_nvml_discover(struct hwloc_backend *backend)
ret = nvmlDeviceGetHandleByIndex(i, &device); ret = nvmlDeviceGetHandleByIndex(i, &device);
assert(ret == NVML_SUCCESS); assert(ret == NVML_SUCCESS);
osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, -1); osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_UNKNOWN_INDEX);
snprintf(buffer, sizeof(buffer), "nvml%u", i); snprintf(buffer, sizeof(buffer), "nvml%u", i);
osdev->name = strdup(buffer); osdev->name = strdup(buffer);
osdev->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN; osdev->depth = HWLOC_TYPE_DEPTH_UNKNOWN;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU; osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
hwloc_obj_add_info(osdev, "Backend", "NVML"); hwloc_obj_add_info(osdev, "Backend", "NVML");
@ -71,21 +71,21 @@ hwloc_nvml_discover(struct hwloc_backend *backend)
if (NVML_SUCCESS == nvmlDeviceGetPciInfo(device, &pci)) { if (NVML_SUCCESS == nvmlDeviceGetPciInfo(device, &pci)) {
parent = hwloc_pcidisc_find_by_busid(topology, pci.domain, pci.bus, pci.device, 0); parent = hwloc_pcidisc_find_by_busid(topology, pci.domain, pci.bus, pci.device, 0);
if (!parent) if (!parent)
parent = hwloc_pcidisc_find_busid_parent(topology, pci.domain, pci.bus, pci.device, 0); parent = hwloc_pcidisc_find_busid_parent(topology, pci.domain, pci.bus, pci.device, 0);
#if HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION #if HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION
if (parent && parent->type == HWLOC_OBJ_PCI_DEVICE) { if (parent && parent->type == HWLOC_OBJ_PCI_DEVICE) {
unsigned maxwidth = 0, maxgen = 0; unsigned maxwidth = 0, maxgen = 0;
float lanespeed; float lanespeed;
nvmlDeviceGetMaxPcieLinkWidth(device, &maxwidth); nvmlDeviceGetMaxPcieLinkWidth(device, &maxwidth);
nvmlDeviceGetMaxPcieLinkGeneration(device, &maxgen); nvmlDeviceGetMaxPcieLinkGeneration(device, &maxgen);
/* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane /* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane
* PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane * PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane
* PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane * PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane
*/ */
lanespeed = maxgen <= 2 ? 2.5 * maxgen * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */ lanespeed = maxgen <= 2 ? 2.5 * maxgen * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */
if (lanespeed * maxwidth != 0.) if (lanespeed * maxwidth != 0.)
/* we found the max link speed, replace the current link speed found by pci (or none) */ /* we found the max link speed, replace the current link speed found by pci (or none) */
parent->attr->pcidev.linkspeed = lanespeed * maxwidth / 8; /* GB/s */ parent->attr->pcidev.linkspeed = lanespeed * maxwidth / 8; /* GB/s */
} }
#endif #endif
} }
@ -101,9 +101,9 @@ hwloc_nvml_discover(struct hwloc_backend *backend)
static struct hwloc_backend * static struct hwloc_backend *
hwloc_nvml_component_instantiate(struct hwloc_disc_component *component, hwloc_nvml_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -120,6 +120,7 @@ static struct hwloc_disc_component hwloc_nvml_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_nvml_component_instantiate, hwloc_nvml_component_instantiate,
5, /* after pci, and after cuda since likely less useful */ 5, /* after pci, and after cuda since likely less useful */
1,
NULL NULL
}; };

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2012-2017 Inria. All rights reserved. * Copyright © 2012-2018 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux. All right reserved. * Copyright © 2013, 2018 Université Bordeaux. All right reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -12,14 +12,17 @@
#include <private/misc.h> #include <private/misc.h>
#include <private/debug.h> #include <private/debug.h>
#ifdef __APPLE__
#include <OpenCL/cl_ext.h>
#else
#include <CL/cl_ext.h> #include <CL/cl_ext.h>
#endif
static int static int
hwloc_opencl_discover(struct hwloc_backend *backend) hwloc_opencl_discover(struct hwloc_backend *backend)
{ {
struct hwloc_topology *topology = backend->topology; struct hwloc_topology *topology = backend->topology;
enum hwloc_type_filter_e filter; enum hwloc_type_filter_e filter;
cl_platform_id *platform_ids = NULL;
cl_uint nr_platforms; cl_uint nr_platforms;
cl_int clret; cl_int clret;
unsigned j; unsigned j;
@ -32,29 +35,24 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
if (CL_SUCCESS != clret || !nr_platforms) if (CL_SUCCESS != clret || !nr_platforms)
return -1; return -1;
hwloc_debug("%u OpenCL platforms\n", nr_platforms); hwloc_debug("%u OpenCL platforms\n", nr_platforms);
platform_ids = malloc(nr_platforms * sizeof(*platform_ids));
if (!platform_ids) cl_platform_id platform_ids[nr_platforms];
return -1;
clret = clGetPlatformIDs(nr_platforms, platform_ids, &nr_platforms); clret = clGetPlatformIDs(nr_platforms, platform_ids, &nr_platforms);
if (CL_SUCCESS != clret || !nr_platforms) { if (CL_SUCCESS != clret || !nr_platforms)
free(platform_ids);
return -1; return -1;
}
for(j=0; j<nr_platforms; j++) { for(j=0; j<nr_platforms; j++) {
cl_device_id *device_ids = NULL;
cl_uint nr_devices; cl_uint nr_devices;
unsigned i; unsigned i;
clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, 0, NULL, &nr_devices); clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, 0, NULL, &nr_devices);
if (CL_SUCCESS != clret) if (CL_SUCCESS != clret)
continue; continue;
device_ids = malloc(nr_devices * sizeof(*device_ids));
cl_device_id device_ids[nr_devices];
clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, nr_devices, device_ids, &nr_devices); clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, nr_devices, device_ids, &nr_devices);
if (CL_SUCCESS != clret) { if (CL_SUCCESS != clret)
free(device_ids);
continue; continue;
}
for(i=0; i<nr_devices; i++) { for(i=0; i<nr_devices; i++) {
cl_platform_id platform_id = 0; cl_platform_id platform_id = 0;
@ -69,53 +67,42 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
hwloc_debug("This is opencl%ud%u\n", j, i); hwloc_debug("This is opencl%ud%u\n", j, i);
#ifdef CL_DEVICE_TOPOLOGY_AMD clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL); if (type == CL_DEVICE_TYPE_CPU)
if (CL_SUCCESS != clret) { /* we don't want CPU opencl devices */
hwloc_debug("no AMD-specific device information: %d\n", clret); continue;
continue;
} else if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_debug("AMD-specific device topology reports non-PCIe device type: %u\n", amdtopo.raw.type);
continue;
}
#else
continue;
#endif
osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, -1); osdev = hwloc_alloc_setup_object(topology, HWLOC_OBJ_OS_DEVICE, HWLOC_UNKNOWN_INDEX);
snprintf(buffer, sizeof(buffer), "opencl%ud%u", j, i); snprintf(buffer, sizeof(buffer), "opencl%ud%u", j, i);
osdev->name = strdup(buffer); osdev->name = strdup(buffer);
osdev->depth = (unsigned) HWLOC_TYPE_DEPTH_UNKNOWN; osdev->depth = HWLOC_TYPE_DEPTH_UNKNOWN;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC; osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_COPROC;
osdev->subtype = strdup("OpenCL"); osdev->subtype = strdup("OpenCL");
hwloc_obj_add_info(osdev, "Backend", "OpenCL"); hwloc_obj_add_info(osdev, "Backend", "OpenCL");
clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
if (type == CL_DEVICE_TYPE_GPU) if (type == CL_DEVICE_TYPE_GPU)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "GPU"); hwloc_obj_add_info(osdev, "OpenCLDeviceType", "GPU");
else if (type == CL_DEVICE_TYPE_ACCELERATOR) else if (type == CL_DEVICE_TYPE_ACCELERATOR)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Accelerator"); hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Accelerator");
else if (type == CL_DEVICE_TYPE_CPU)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "CPU");
else if (type == CL_DEVICE_TYPE_CUSTOM) else if (type == CL_DEVICE_TYPE_CUSTOM)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Custom"); hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Custom");
else else
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Unknown"); hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Unknown");
buffer[0] = '\0'; buffer[0] = '\0';
clGetDeviceInfo(device_ids[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL); clGetDeviceInfo(device_ids[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0') if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "GPUVendor", buffer); hwloc_obj_add_info(osdev, "GPUVendor", buffer);
buffer[0] = '\0'; buffer[0] = '\0';
#ifdef CL_DEVICE_BOARD_NAME_AMD #ifdef CL_DEVICE_BOARD_NAME_AMD
clGetDeviceInfo(device_ids[i], CL_DEVICE_BOARD_NAME_AMD, sizeof(buffer), buffer, NULL); clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_BOARD_NAME_AMD, sizeof(buffer), buffer, NULL);
#else if (CL_SUCCESS != clret || buffer[0] == '\0')
clGetDeviceInfo(device_ids[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
#endif #endif
clGetDeviceInfo(device_ids[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0') if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "GPUModel", buffer); hwloc_obj_add_info(osdev, "GPUModel", buffer);
snprintf(buffer, sizeof(buffer), "%u", j); snprintf(buffer, sizeof(buffer), "%u", j);
hwloc_obj_add_info(osdev, "OpenCLPlatformIndex", buffer); hwloc_obj_add_info(osdev, "OpenCLPlatformIndex", buffer);
@ -123,9 +110,9 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
buffer[0] = '\0'; buffer[0] = '\0';
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, NULL); clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, NULL);
if (CL_SUCCESS == clret) { if (CL_SUCCESS == clret) {
clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL); clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0') if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "OpenCLPlatformName", buffer); hwloc_obj_add_info(osdev, "OpenCLPlatformName", buffer);
} }
snprintf(buffer, sizeof(buffer), "%u", i); snprintf(buffer, sizeof(buffer), "%u", i);
@ -141,26 +128,33 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
parent = NULL; parent = NULL;
#ifdef CL_DEVICE_TOPOLOGY_AMD #ifdef CL_DEVICE_TOPOLOGY_AMD
parent = hwloc_pcidisc_find_by_busid(topology, 0, amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function); clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (!parent) if (CL_SUCCESS != clret) {
parent = hwloc_pcidisc_find_busid_parent(topology, 0, amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function); hwloc_debug("no AMD-specific device information: %d\n", clret);
} else if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_debug("AMD-specific device topology reports non-PCIe device type: %u\n", amdtopo.raw.type);
} else {
parent = hwloc_pcidisc_find_by_busid(topology, 0, (unsigned)amdtopo.pcie.bus, (unsigned)amdtopo.pcie.device, (unsigned)amdtopo.pcie.function);
if (!parent)
parent = hwloc_pcidisc_find_busid_parent(topology, 0, (unsigned)amdtopo.pcie.bus, (unsigned)amdtopo.pcie.device, (unsigned)amdtopo.pcie.function);
}
#else
hwloc_debug("No locality information found.\n");
#endif #endif
if (!parent) if (!parent)
parent = hwloc_get_root_obj(topology); parent = hwloc_get_root_obj(topology);
hwloc_insert_object_by_parent(topology, parent, osdev); hwloc_insert_object_by_parent(topology, parent, osdev);
} }
free(device_ids);
} }
free(platform_ids);
return 0; return 0;
} }
static struct hwloc_backend * static struct hwloc_backend *
hwloc_opencl_component_instantiate(struct hwloc_disc_component *component, hwloc_opencl_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -177,6 +171,7 @@ static struct hwloc_disc_component hwloc_opencl_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_opencl_component_instantiate, hwloc_opencl_component_instantiate,
10, /* after pci */ 10, /* after pci */
1,
NULL NULL
}; };

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux * Copyright © 2009-2011, 2013 Université Bordeaux
* Copyright © 2014 Cisco Systems, Inc. All rights reserved. * Copyright © 2014 Cisco Systems, Inc. All rights reserved.
* Copyright © 2015 Research Organization for Information Science * Copyright © 2015 Research Organization for Information Science
@ -73,6 +73,19 @@
#define CONFIG_SPACE_CACHESIZE 256 #define CONFIG_SPACE_CACHESIZE 256
#ifdef HWLOC_WIN_SYS
#error pciaccess locking currently not implemented on Windows
#elif defined HWLOC_HAVE_PTHREAD_MUTEX
/* pthread mutex if available (except on windows) */
#include <pthread.h>
static pthread_mutex_t hwloc_pciaccess_mutex = PTHREAD_MUTEX_INITIALIZER;
#define HWLOC_PCIACCESS_LOCK() pthread_mutex_lock(&hwloc_pciaccess_mutex)
#define HWLOC_PCIACCESS_UNLOCK() pthread_mutex_unlock(&hwloc_pciaccess_mutex)
#else /* HWLOC_WIN_SYS || HWLOC_HAVE_PTHREAD_MUTEX */
#error No mutex implementation available
#endif
static int static int
hwloc_look_pci(struct hwloc_backend *backend) hwloc_look_pci(struct hwloc_backend *backend)
@ -96,7 +109,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
tmp = hwloc_get_root_obj(topology)->io_first_child; tmp = hwloc_get_root_obj(topology)->io_first_child;
while (tmp) { while (tmp) {
if (tmp->type == HWLOC_OBJ_PCI_DEVICE if (tmp->type == HWLOC_OBJ_PCI_DEVICE
|| (tmp->type == HWLOC_OBJ_BRIDGE && tmp->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI)) { || (tmp->type == HWLOC_OBJ_BRIDGE && tmp->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI)) {
hwloc_debug("%s", "PCI objects already added, ignoring linuxpci backend.\n"); hwloc_debug("%s", "PCI objects already added, ignoring linuxpci backend.\n");
return 0; return 0;
} }
@ -105,9 +118,15 @@ hwloc_look_pci(struct hwloc_backend *backend)
hwloc_debug("%s", "\nScanning PCI buses...\n"); hwloc_debug("%s", "\nScanning PCI buses...\n");
/* pciaccess isn't thread-safe. it uses a single global variable that doesn't have
* refcounting, and is dynamically reallocated when vendor/device names are needed, etc.
*/
HWLOC_PCIACCESS_LOCK();
/* initialize PCI scanning */ /* initialize PCI scanning */
ret = pci_system_init(); ret = pci_system_init();
if (ret) { if (ret) {
HWLOC_PCIACCESS_UNLOCK();
hwloc_debug("%s", "Can not initialize libpciaccess\n"); hwloc_debug("%s", "Can not initialize libpciaccess\n");
return -1; return -1;
} }
@ -147,15 +166,15 @@ hwloc_look_pci(struct hwloc_backend *backend)
enum hwloc_type_filter_e filter; enum hwloc_type_filter_e filter;
hwloc_topology_get_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, &filter); hwloc_topology_get_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, &filter);
if (filter == HWLOC_TYPE_FILTER_KEEP_NONE) if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
continue; continue;
if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT
&& !hwloc_filter_check_pcidev_subtype_important(device_class)) && !hwloc_filter_check_pcidev_subtype_important(device_class))
continue; continue;
} else if (type == HWLOC_OBJ_BRIDGE) { } else if (type == HWLOC_OBJ_BRIDGE) {
enum hwloc_type_filter_e filter; enum hwloc_type_filter_e filter;
hwloc_topology_get_type_filter(topology, HWLOC_OBJ_BRIDGE, &filter); hwloc_topology_get_type_filter(topology, HWLOC_OBJ_BRIDGE, &filter);
if (filter == HWLOC_TYPE_FILTER_KEEP_NONE) if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
continue; continue;
/* HWLOC_TYPE_FILTER_KEEP_IMPORTANT filtered later in the core */ /* HWLOC_TYPE_FILTER_KEEP_IMPORTANT filtered later in the core */
} }
@ -188,30 +207,30 @@ hwloc_look_pci(struct hwloc_backend *backend)
size_t read; size_t read;
snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/vendor", snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/vendor",
domain, pcidev->bus, pcidev->dev, pcidev->func); domain, pcidev->bus, pcidev->dev, pcidev->func);
file = fopen(path, "r"); file = fopen(path, "r");
if (file) { if (file) {
read = fread(value, 1, sizeof(value), file); read = fread(value, 1, sizeof(value), file);
fclose(file); fclose(file);
if (read) if (read)
/* fixup the pciaccess struct so that pci_device_get_vendor_name() is correct later. */ /* fixup the pciaccess struct so that pci_device_get_vendor_name() is correct later. */
pcidev->vendor_id = strtoul(value, NULL, 16); pcidev->vendor_id = strtoul(value, NULL, 16);
} }
snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/device", snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/device",
domain, pcidev->bus, pcidev->dev, pcidev->func); domain, pcidev->bus, pcidev->dev, pcidev->func);
file = fopen(path, "r"); file = fopen(path, "r");
if (file) { if (file) {
read = fread(value, 1, sizeof(value), file); read = fread(value, 1, sizeof(value), file);
fclose(file); fclose(file);
if (read) if (read)
/* fixup the pciaccess struct so that pci_device_get_device_name() is correct later. */ /* fixup the pciaccess struct so that pci_device_get_device_name() is correct later. */
pcidev->device_id = strtoul(value, NULL, 16); pcidev->device_id = strtoul(value, NULL, 16);
} }
#endif #endif
} }
obj = hwloc_alloc_setup_object(topology, type, -1); obj = hwloc_alloc_setup_object(topology, type, HWLOC_UNKNOWN_INDEX);
obj->attr->pcidev.domain = domain; obj->attr->pcidev.domain = domain;
obj->attr->pcidev.bus = pcidev->bus; obj->attr->pcidev.bus = pcidev->bus;
obj->attr->pcidev.dev = pcidev->dev; obj->attr->pcidev.dev = pcidev->dev;
@ -229,7 +248,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
if (type == HWLOC_OBJ_BRIDGE) { if (type == HWLOC_OBJ_BRIDGE) {
if (hwloc_pcidisc_setup_bridge_attr(obj, config_space_cache) < 0) if (hwloc_pcidisc_setup_bridge_attr(obj, config_space_cache) < 0)
continue; continue;
} }
if (obj->type == HWLOC_OBJ_PCI_DEVICE) { if (obj->type == HWLOC_OBJ_PCI_DEVICE) {
@ -255,10 +274,10 @@ hwloc_look_pci(struct hwloc_backend *backend)
hwloc_obj_add_info(obj, "PCIDevice", devicename); hwloc_obj_add_info(obj, "PCIDevice", devicename);
hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s %s\n", hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s %s\n",
domain, pcidev->bus, pcidev->dev, pcidev->func, domain, pcidev->bus, pcidev->dev, pcidev->func,
device_class, pcidev->vendor_id, pcidev->device_id, device_class, pcidev->vendor_id, pcidev->device_id,
vendorname && *vendorname ? vendorname : "??", vendorname && *vendorname ? vendorname : "??",
devicename && *devicename ? devicename : "??"); devicename && *devicename ? devicename : "??");
hwloc_pcidisc_tree_insert_by_busid(&tree, obj); hwloc_pcidisc_tree_insert_by_busid(&tree, obj);
} }
@ -266,6 +285,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
/* finalize device scanning */ /* finalize device scanning */
pci_iterator_destroy(iter); pci_iterator_destroy(iter);
pci_system_cleanup(); pci_system_cleanup();
HWLOC_PCIACCESS_UNLOCK();
hwloc_pcidisc_tree_attach(topology, tree); hwloc_pcidisc_tree_attach(topology, tree);
return 0; return 0;
@ -273,9 +293,9 @@ hwloc_look_pci(struct hwloc_backend *backend)
static struct hwloc_backend * static struct hwloc_backend *
hwloc_pci_component_instantiate(struct hwloc_disc_component *component, hwloc_pci_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
@ -297,6 +317,7 @@ static struct hwloc_disc_component hwloc_pci_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_pci_component_instantiate, hwloc_pci_component_instantiate,
20, 20,
1,
NULL NULL
}; };

Просмотреть файл

@ -0,0 +1,510 @@
/*
* Copyright © 2009-2010 Oracle and/or its affiliates. All rights reserved.
* Copyright © 2013 Université Bordeaux. All rights reserved.
* Copyright © 2016-2017 Inria. All rights reserved.
*
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include <private/autogen/config.h>
#include <hwloc.h>
#include <private/solaris-chiptype.h>
#include <private/misc.h>
#include <private/debug.h>
#include <stdlib.h>
#include <strings.h>
#ifdef HAVE_PICL_H
#include <sys/systeminfo.h>
#include <picl.h>
/* SPARC Chip Implementations. */
#define IMPL_SPARC64_VI 0x6
#define IMPL_SPARC64_VII 0x7
#define IMPL_SPITFIRE 0x10
#define IMPL_BLACKBIRD 0x11
#define IMPL_SABRE 0x12
#define IMPL_HUMMINGBIRD 0x13
#define IMPL_CHEETAH 0x14
#define IMPL_CHEETAHPLUS 0x15
#define IMPL_JALAPENO 0x16
#define IMPL_JAGUAR 0x18
#define IMPL_PANTHER 0x19
#define IMPL_NIAGARA 0x23
#define IMPL_NIAGARA_2 0x24
#define IMPL_ROCK 0x25
/* Default Mfg, Cache, Speed settings */
#define TI_MANUFACTURER 0x17
#define TWO_MEG_CACHE 2097152
#define SPITFIRE_SPEED 142943750
/*****************************************************************************
Order of this list is important for the assign_value and
assign_string_value routines
*****************************************************************************/
static const char* items[] = {
#define INDEX_PROCESSOR_TYPE 0
"ProcessorType",
#define INDEX_BRAND_STRING 1
"brand-string",
#define INDEX_COMPATIBLE 2
"compatible",
#define INDEX_IMPLEMENTATION 3
"implementation#",
/* the following groups must be contigous from L1I to L3 each */
#define INDEX_L1I_CACHE_SIZE 4
"l1-icache-size",
#define INDEX_L1D_CACHE_SIZE 5
"l1-dcache-size",
#define INDEX_L2I_CACHE_SIZE 6
"l2-icache-size",
#define INDEX_L2D_CACHE_SIZE 7
"l2-dcache-size",
#define INDEX_L3_CACHE_SIZE 8
"l3-cache-size",
#define INDEX_L1I_CACHE_LINESIZE 9
"l1-icache-line-size",
#define INDEX_L1D_CACHE_LINESIZE 10
"l1-dcache-line-size",
#define INDEX_L2I_CACHE_LINESIZE 11
"l2-icache-line-size",
#define INDEX_L2D_CACHE_LINESIZE 12
"l2-dcache-line-size",
#define INDEX_L3_CACHE_LINESIZE 13
"l3-cache-line-size",
#define INDEX_L1I_CACHE_ASSOCIATIVITY 14
"l1-icache-associativity",
#define INDEX_L1D_CACHE_ASSOCIATIVITY 15
"l1-dcache-associativity",
#define INDEX_L2I_CACHE_ASSOCIATIVITY 16
"l2-icache-associativity",
#define INDEX_L2D_CACHE_ASSOCIATIVITY 17
"l2-dcache-associativity",
#define INDEX_L3_CACHE_ASSOCIATIVITY 18
"l3-cache-associativity",
#define INDEX_L2U_CACHE_SIZE 19
"l2-cache-size",
#define INDEX_L2U_CACHE_LINESIZE 20
"l2-cache-line-size",
#define INDEX_L2U_CACHE_ASSOCIATIVITY 21
"l2-cache-associativity",
#define INDEX_SL2_CACHE_SIZE 22
"sectored-l2-cache-size",
#define INDEX_SL2_CACHE_LINESIZE 23
"sectored-l2-cache-line-size",
#define INDEX_SL2_CACHE_ASSOCIATIVITY 24
"sectored-l2-cache-associativity",
};
#define NUM_ITEMS (sizeof(items) / sizeof(items[0]))
/*****************************************************************************
SPARC strings for chip modes and implementation
*****************************************************************************/
static const char* sparc_modes[] = {
#define MODE_UNKNOWN 0
"UNKNOWN",
#define MODE_SPITFIRE 1
"SPITFIRE",
#define MODE_BLACKBIRD 2
"BLACKBIRD",
#define MODE_CHEETAH 3
"CHEETAH",
#define MODE_SPARC64_VI 4
"SPARC64_VI",
#define MODE_T1 5
"T1",
#define MODE_T2 6
"T2",
/* needs T4, T3 and T2+ ? */
#define MODE_SPARC64_VII 7
"SPARC64_VII",
#define MODE_ROCK 8
"ROCK",
#define MODE_T5 9
"T5",
#define MODE_T6 10
"T6",
#define MODE_M7 11
"M7",
#define MODE_S7 12
"S7",
#define MODE_M8 13
"M8"
};
/*****************************************************************************
Default values are for Unknown so we can build up from there.
*****************************************************************************/
static int called_cpu_probe = 0;
static char dss_chip_type[PICL_PROPNAMELEN_MAX];
static char dss_chip_model[PICL_PROPNAMELEN_MAX];
static long dss_chip_mode = MODE_UNKNOWN;
struct hwloc_solaris_chip_info_s chip_info;
/*****************************************************************************
Assigns values based on the value of index. For this reason, the order of
the items array is important.
*****************************************************************************/
static void assign_value(int index, long long val) {
if (index == INDEX_IMPLEMENTATION) {
/* implementation# T1, T2, and Rock do not have this, see RFE 6615268 */
long dss_chip_impl = val;
if (dss_chip_impl == IMPL_SPITFIRE) {
dss_chip_mode = MODE_SPITFIRE;
}
else if ((dss_chip_impl >= IMPL_BLACKBIRD) &&
(dss_chip_impl <= IMPL_HUMMINGBIRD)) {
dss_chip_mode = MODE_BLACKBIRD;
}
else if ((dss_chip_impl >= IMPL_CHEETAH) &&
(dss_chip_impl <= IMPL_PANTHER)) {
dss_chip_mode = MODE_CHEETAH;
}
else if (dss_chip_impl == IMPL_SPARC64_VI) {
dss_chip_mode = MODE_SPARC64_VI;
}
else if (dss_chip_impl == IMPL_NIAGARA) {
dss_chip_mode = MODE_T1;
}
else if (dss_chip_impl == IMPL_NIAGARA_2) {
dss_chip_mode = MODE_T2;
}
else if (dss_chip_impl == IMPL_SPARC64_VII) {
dss_chip_mode = MODE_SPARC64_VII;
}
else if (dss_chip_impl == IMPL_ROCK) {
dss_chip_mode = MODE_ROCK;
}
}
else if ((index >= INDEX_L1I_CACHE_SIZE) && (index <= INDEX_L3_CACHE_SIZE)) {
/* make sure our indexes and the target structure are ordered the same */
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_SIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_SIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_SIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_SIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_SIZE+HWLOC_SOLARIS_CHIP_INFO_L3 == INDEX_L3_CACHE_SIZE);
chip_info.cache_size[index-INDEX_L1I_CACHE_SIZE] = val;
}
else if ((index >= INDEX_L1I_CACHE_LINESIZE) && (index <= INDEX_L3_CACHE_LINESIZE)) {
/* make sure our indexes and the target structure are ordered the same */
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_LINESIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_LINESIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_LINESIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_LINESIZE);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_LINESIZE+HWLOC_SOLARIS_CHIP_INFO_L3 == INDEX_L3_CACHE_LINESIZE);
chip_info.cache_linesize[index-INDEX_L1I_CACHE_LINESIZE] = val;
}
else if ((index >= INDEX_L1I_CACHE_ASSOCIATIVITY) && (index <= INDEX_L3_CACHE_ASSOCIATIVITY)) {
/* make sure our indexes and the target structure are ordered the same */
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L1I == INDEX_L1I_CACHE_ASSOCIATIVITY);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L1D == INDEX_L1D_CACHE_ASSOCIATIVITY);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L2I == INDEX_L2I_CACHE_ASSOCIATIVITY);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L2D == INDEX_L2D_CACHE_ASSOCIATIVITY);
HWLOC_BUILD_ASSERT(INDEX_L1I_CACHE_ASSOCIATIVITY+HWLOC_SOLARIS_CHIP_INFO_L3 == INDEX_L3_CACHE_ASSOCIATIVITY);
chip_info.cache_associativity[index-INDEX_L1I_CACHE_ASSOCIATIVITY] = val;
}
/* store L2U info in L2D with l2_unified flag */
else if (index == INDEX_L2U_CACHE_SIZE) {
chip_info.cache_size[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
chip_info.l2_unified = 1;
}
else if (index == INDEX_L2U_CACHE_LINESIZE) {
chip_info.cache_linesize[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
chip_info.l2_unified = 1;
}
else if (index == INDEX_L2U_CACHE_ASSOCIATIVITY) {
chip_info.cache_associativity[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
chip_info.l2_unified = 1;
}
/* assume sectored L2 is identical to L2u for size/linesize/associativity */
else if (index == INDEX_SL2_CACHE_SIZE) {
chip_info.cache_size[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
chip_info.l2_unified = 1;
}
else if (index == INDEX_SL2_CACHE_LINESIZE) {
chip_info.cache_linesize[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
chip_info.l2_unified = 1;
}
else if (index == INDEX_SL2_CACHE_ASSOCIATIVITY) {
chip_info.cache_associativity[HWLOC_SOLARIS_CHIP_INFO_L2D] = val;
chip_info.l2_unified = 1;
}
}
/*****************************************************************************
Assigns values based on the value of index. For this reason, the order of
the items array is important.
*****************************************************************************/
static void assign_string_value(int index, char* string_val) {
if (index == INDEX_COMPATIBLE) { /* compatible */
if (strncasecmp(string_val, "FJSV,SPARC64-VI",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_SPARC64_VI;
}
else if (strncasecmp(string_val, "SUNW,UltraSPARC-T1",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_T1;
}
else if (strncasecmp(string_val, "SUNW,UltraSPARC-T2",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_T2;
}
else if (strncasecmp(string_val, "FJSV,SPARC64-VII",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_SPARC64_VII;
}
else if (strncasecmp(string_val, "SUNW,Rock",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_ROCK;
}
else if (strncasecmp(string_val, "SPARC-T5",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_T5;
}
else if (strncasecmp(string_val, "SPARC-T6", /* not actually tested */
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_T6;
}
else if (strncasecmp(string_val, "SPARC-M7",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_M7;
}
else if (strncasecmp(string_val, "SPARC-S7",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_S7;
}
else if (strncasecmp(string_val, "SPARC-M8",
PICL_PROPNAMELEN_MAX) == 0) {
dss_chip_mode = MODE_M8;
}
} else if (index == INDEX_PROCESSOR_TYPE) { /* ProcessorType */
strncpy(&dss_chip_type[0], string_val, PICL_PROPNAMELEN_MAX);
} else if (index == INDEX_BRAND_STRING) { /* brand-string */
strncpy(&dss_chip_model[0], string_val, PICL_PROPNAMELEN_MAX);
}
}
/*****************************************************************************
Gets called by probe_cpu. Cycles through the table values until we find
what we are looking for.
*****************************************************************************/
static void search_table(int index, picl_prophdl_t table_hdl) {
picl_prophdl_t col_hdl;
picl_prophdl_t row_hdl;
picl_propinfo_t p_info;
int val;
char string_val[PICL_PROPNAMELEN_MAX];
for (val = picl_get_next_by_col(table_hdl, &row_hdl); val != PICL_ENDOFLIST;
val = picl_get_next_by_col(row_hdl, &row_hdl)) {
if (val == PICL_SUCCESS) {
for (col_hdl = row_hdl; val != PICL_ENDOFLIST;
val = picl_get_next_by_row(col_hdl, &col_hdl)) {
if (val == PICL_SUCCESS) {
val = picl_get_propinfo(col_hdl, &p_info);
if (val == PICL_SUCCESS) {
if (p_info.type == PICL_PTYPE_CHARSTRING) {
val = picl_get_propval(col_hdl, &string_val, sizeof(string_val));
if (val == PICL_SUCCESS) {
assign_string_value(index, string_val);
}
}
}
}
}
}
}
}
/*****************************************************************************
Gets called by picl_walk_tree_by_class. Then it cycles through the properties
until we find what we are looking for. Once we are done, we return
PICL_WALK_TERMINATE to stop picl_walk_tree_by_class from traversing the tree.
Note that PICL_PTYPE_UNSIGNED_INT and PICL_PTYPE_INT can either be 4-bytes
or 8-bytes.
*****************************************************************************/
static int probe_cpu(picl_nodehdl_t node_hdl, void* dummy_arg __hwloc_attribute_unused) {
picl_prophdl_t p_hdl;
picl_prophdl_t table_hdl;
picl_propinfo_t p_info;
long long long_long_val;
unsigned int uint_val;
unsigned int index;
int int_val;
int val;
char string_val[PICL_PROPNAMELEN_MAX];
val = picl_get_first_prop(node_hdl, &p_hdl);
while (val == PICL_SUCCESS) {
called_cpu_probe = 1;
val = picl_get_propinfo(p_hdl, &p_info);
if (val == PICL_SUCCESS) {
for (index = 0; index < NUM_ITEMS; index++) {
if (strcasecmp(p_info.name, items[index]) == 0) {
if (p_info.type == PICL_PTYPE_UNSIGNED_INT) {
if (p_info.size == sizeof(uint_val)) {
val = picl_get_propval(p_hdl, &uint_val, sizeof(uint_val));
if (val == PICL_SUCCESS) {
long_long_val = uint_val;
assign_value(index, long_long_val);
}
}
else if (p_info.size == sizeof(long_long_val)) {
val = picl_get_propval(p_hdl, &long_long_val,
sizeof(long_long_val));
if (val == PICL_SUCCESS) {
assign_value(index, long_long_val);
}
}
}
else if (p_info.type == PICL_PTYPE_INT) {
if (p_info.size == sizeof(int_val)) {
val = picl_get_propval(p_hdl, &int_val, sizeof(int_val));
if (val == PICL_SUCCESS) {
long_long_val = int_val;
assign_value(index, long_long_val);
}
}
else if (p_info.size == sizeof(long_long_val)) {
val = picl_get_propval(p_hdl, &long_long_val,
sizeof(long_long_val));
if (val == PICL_SUCCESS) {
assign_value(index, long_long_val);
}
}
}
else if (p_info.type == PICL_PTYPE_CHARSTRING) {
val = picl_get_propval(p_hdl, &string_val, sizeof(string_val));
if (val == PICL_SUCCESS) {
assign_string_value(index, string_val);
}
}
else if (p_info.type == PICL_PTYPE_TABLE) {
val = picl_get_propval(p_hdl, &table_hdl, p_info.size);
if (val == PICL_SUCCESS) {
search_table(index, table_hdl);
}
}
break;
}
}
}
val = picl_get_next_prop(p_hdl, &p_hdl);
}
return PICL_WALK_TERMINATE;
}
/*****************************************************************************
Initializes, gets the root, then walks the picl tree looking for information
Currently, the "core" class is only needed for OPL systems
*****************************************************************************/
static void probe_picl(void)
{
char *env;
int ret;
memset(&chip_info, 0, sizeof(chip_info));
/* if we ever see a heterogeneous platform, we'll need to parse PICL attributes for each CPU
* (which means returning PICL_WALK_CONTINUE instead of PICL_WALK_TERMINATE above)
* instead of using the first CPU PICL attributes for the entire machine.
*
* Use this env var to disable the PICL homogeneous-only parsing in the meantime.
*/
env = getenv("HWLOC_PICL_HETEROGENEOUS");
if (env && atoi(env))
return;
ret = picl_initialize();
if (ret == PICL_SUCCESS) {
picl_nodehdl_t root;
ret = picl_get_root(&root);
if (ret == PICL_SUCCESS) {
ret = picl_walk_tree_by_class(root, "cpu", (void *)NULL, probe_cpu);
ret = picl_walk_tree_by_class(root, "core", (void *)NULL, probe_cpu);
}
picl_shutdown();
}
if (called_cpu_probe) {
#if (defined HWLOC_X86_64_ARCH) || (defined HWLOC_X86_32_ARCH)
/* PICL returns some corrupted chip_type strings on x86,
* and CPUType only used on Sparc anyway, at least for now.
* So we just ignore this attribute on x86. */
dss_chip_type[0] = '\0';
#endif
if (dss_chip_mode != MODE_UNKNOWN) { /* SPARC chip */
strncpy(dss_chip_model, sparc_modes[dss_chip_mode],
PICL_PROPNAMELEN_MAX);
}
} else {
/* no picl information on machine available */
sysinfo(SI_HW_PROVIDER, dss_chip_type, PICL_PROPNAMELEN_MAX);
sysinfo(SI_PLATFORM, dss_chip_model, PICL_PROPNAMELEN_MAX);
}
#ifdef HWLOC_DEBUG
{
unsigned i;
for(i=0; i<sizeof(chip_info.cache_size)/sizeof(*chip_info.cache_size); i++)
hwloc_debug("PICL gave cache #%u size %lu line %u associativity %u\n",
i, chip_info.cache_size[i], chip_info.cache_linesize[i], chip_info.cache_associativity[i]);
}
#endif
/* make sure strings are null-terminated */
dss_chip_type[sizeof(dss_chip_type)-1] = '\0';
dss_chip_model[sizeof(dss_chip_model)-1] = '\0';
/* setup the info struct */
if (dss_chip_type[0])
chip_info.type = dss_chip_type;
if (dss_chip_model[0])
chip_info.model = dss_chip_model;
}
void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info)
{
static int probe_done = 0;
if (!probe_done) {
probe_picl();
probe_done = 1;
}
memcpy(info, &chip_info, sizeof(*info));
}
#else /* !HAVE_PICL_H */
void hwloc_solaris_get_chip_info(struct hwloc_solaris_chip_info_s *info)
{
memset(info, 0, sizeof(*info));
}
#endif /* !HAVE_PICL_H */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -190,6 +190,7 @@ typedef WORD (WINAPI *PFN_GETACTIVEPROCESSORGROUPCOUNT)(void);
static PFN_GETACTIVEPROCESSORGROUPCOUNT GetActiveProcessorGroupCountProc; static PFN_GETACTIVEPROCESSORGROUPCOUNT GetActiveProcessorGroupCountProc;
static unsigned long nr_processor_groups = 1; static unsigned long nr_processor_groups = 1;
static unsigned long max_numanode_index = 0;
typedef WORD (WINAPI *PFN_GETACTIVEPROCESSORCOUNT)(WORD); typedef WORD (WINAPI *PFN_GETACTIVEPROCESSORCOUNT)(WORD);
static PFN_GETACTIVEPROCESSORCOUNT GetActiveProcessorCountProc; static PFN_GETACTIVEPROCESSORCOUNT GetActiveProcessorCountProc;
@ -234,40 +235,40 @@ static void hwloc_win_get_function_ptrs(void)
kernel32 = LoadLibrary("kernel32.dll"); kernel32 = LoadLibrary("kernel32.dll");
if (kernel32) { if (kernel32) {
GetActiveProcessorGroupCountProc = GetActiveProcessorGroupCountProc =
(PFN_GETACTIVEPROCESSORGROUPCOUNT) GetProcAddress(kernel32, "GetActiveProcessorGroupCount"); (PFN_GETACTIVEPROCESSORGROUPCOUNT) GetProcAddress(kernel32, "GetActiveProcessorGroupCount");
GetActiveProcessorCountProc = GetActiveProcessorCountProc =
(PFN_GETACTIVEPROCESSORCOUNT) GetProcAddress(kernel32, "GetActiveProcessorCount"); (PFN_GETACTIVEPROCESSORCOUNT) GetProcAddress(kernel32, "GetActiveProcessorCount");
GetLogicalProcessorInformationProc = GetLogicalProcessorInformationProc =
(PFN_GETLOGICALPROCESSORINFORMATION) GetProcAddress(kernel32, "GetLogicalProcessorInformation"); (PFN_GETLOGICALPROCESSORINFORMATION) GetProcAddress(kernel32, "GetLogicalProcessorInformation");
GetCurrentProcessorNumberProc = GetCurrentProcessorNumberProc =
(PFN_GETCURRENTPROCESSORNUMBER) GetProcAddress(kernel32, "GetCurrentProcessorNumber"); (PFN_GETCURRENTPROCESSORNUMBER) GetProcAddress(kernel32, "GetCurrentProcessorNumber");
GetCurrentProcessorNumberExProc = GetCurrentProcessorNumberExProc =
(PFN_GETCURRENTPROCESSORNUMBEREX) GetProcAddress(kernel32, "GetCurrentProcessorNumberEx"); (PFN_GETCURRENTPROCESSORNUMBEREX) GetProcAddress(kernel32, "GetCurrentProcessorNumberEx");
SetThreadGroupAffinityProc = SetThreadGroupAffinityProc =
(PFN_SETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "SetThreadGroupAffinity"); (PFN_SETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "SetThreadGroupAffinity");
GetThreadGroupAffinityProc = GetThreadGroupAffinityProc =
(PFN_GETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "GetThreadGroupAffinity"); (PFN_GETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "GetThreadGroupAffinity");
GetNumaAvailableMemoryNodeProc = GetNumaAvailableMemoryNodeProc =
(PFN_GETNUMAAVAILABLEMEMORYNODE) GetProcAddress(kernel32, "GetNumaAvailableMemoryNode"); (PFN_GETNUMAAVAILABLEMEMORYNODE) GetProcAddress(kernel32, "GetNumaAvailableMemoryNode");
GetNumaAvailableMemoryNodeExProc = GetNumaAvailableMemoryNodeExProc =
(PFN_GETNUMAAVAILABLEMEMORYNODEEX) GetProcAddress(kernel32, "GetNumaAvailableMemoryNodeEx"); (PFN_GETNUMAAVAILABLEMEMORYNODEEX) GetProcAddress(kernel32, "GetNumaAvailableMemoryNodeEx");
GetLogicalProcessorInformationExProc = GetLogicalProcessorInformationExProc =
(PFN_GETLOGICALPROCESSORINFORMATIONEX)GetProcAddress(kernel32, "GetLogicalProcessorInformationEx"); (PFN_GETLOGICALPROCESSORINFORMATIONEX)GetProcAddress(kernel32, "GetLogicalProcessorInformationEx");
QueryWorkingSetExProc =
(PFN_QUERYWORKINGSETEX) GetProcAddress(kernel32, "K32QueryWorkingSetEx");
VirtualAllocExNumaProc = VirtualAllocExNumaProc =
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "K32QueryWorkingSetEx"); (PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "VirtualAllocExNuma");
VirtualAllocExNumaProc =*
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "VirtualAllocExNuma");
VirtualFreeExProc = VirtualFreeExProc =
(PFN_VIRTUALFREEEX) GetProcAddress(kernel32, "VirtualFreeEx"); (PFN_VIRTUALFREEEX) GetProcAddress(kernel32, "VirtualFreeEx");
} }
if (GetActiveProcessorGroupCountProc) if (GetActiveProcessorGroupCountProc)
nr_processor_groups = GetActiveProcessorGroupCountProc(); nr_processor_groups = GetActiveProcessorGroupCountProc();
if (!VirtualAllocExNumaProc) { if (!QueryWorkingSetExProc) {
HMODULE psapi = LoadLibrary("psapi.dll"); HMODULE psapi = LoadLibrary("psapi.dll");
if (psapi) if (psapi)
VirtualAllocExNumaProc = (PFN_VIRTUALALLOCEXNUMA) GetProcAddress(psapi, "QueryWorkingSetEx"); QueryWorkingSetExProc = (PFN_QUERYWORKINGSETEX) GetProcAddress(psapi, "QueryWorkingSetEx");
} }
} }
@ -437,7 +438,8 @@ static int
hwloc_win_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_win_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{ {
int ret; int ret;
hwloc_cpuset_t cpuset; hwloc_const_cpuset_t cpuset;
hwloc_cpuset_t _cpuset = NULL;
if ((policy != HWLOC_MEMBIND_DEFAULT && policy != HWLOC_MEMBIND_BIND) if ((policy != HWLOC_MEMBIND_DEFAULT && policy != HWLOC_MEMBIND_BIND)
|| flags & HWLOC_MEMBIND_NOCPUBIND) { || flags & HWLOC_MEMBIND_NOCPUBIND) {
@ -445,11 +447,16 @@ hwloc_win_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_
return -1; return -1;
} }
cpuset = hwloc_bitmap_alloc(); if (policy == HWLOC_MEMBIND_DEFAULT) {
hwloc_cpuset_from_nodeset(topology, cpuset, nodeset); cpuset = hwloc_topology_get_complete_cpuset(topology);
} else {
cpuset = _cpuset = hwloc_bitmap_alloc();
hwloc_cpuset_from_nodeset(topology, _cpuset, nodeset);
}
ret = hwloc_win_set_thisthread_cpubind(topology, cpuset, ret = hwloc_win_set_thisthread_cpubind(topology, cpuset,
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0); (flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
hwloc_bitmap_free(cpuset); hwloc_bitmap_free(_cpuset);
return ret; return ret;
} }
@ -535,7 +542,8 @@ static int
hwloc_win_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags) hwloc_win_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_const_nodeset_t nodeset, hwloc_membind_policy_t policy, int flags)
{ {
int ret; int ret;
hwloc_cpuset_t cpuset; hwloc_const_cpuset_t cpuset;
hwloc_cpuset_t _cpuset = NULL;
if ((policy != HWLOC_MEMBIND_DEFAULT && policy != HWLOC_MEMBIND_BIND) if ((policy != HWLOC_MEMBIND_DEFAULT && policy != HWLOC_MEMBIND_BIND)
|| flags & HWLOC_MEMBIND_NOCPUBIND) { || flags & HWLOC_MEMBIND_NOCPUBIND) {
@ -543,11 +551,16 @@ hwloc_win_set_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_con
return -1; return -1;
} }
cpuset = hwloc_bitmap_alloc(); if (policy == HWLOC_MEMBIND_DEFAULT) {
hwloc_cpuset_from_nodeset(topology, cpuset, nodeset); cpuset = hwloc_topology_get_complete_cpuset(topology);
} else {
cpuset = _cpuset = hwloc_bitmap_alloc();
hwloc_cpuset_from_nodeset(topology, _cpuset, nodeset);
}
ret = hwloc_win_set_proc_cpubind(topology, pid, cpuset, ret = hwloc_win_set_proc_cpubind(topology, pid, cpuset,
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0); (flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
hwloc_bitmap_free(cpuset); hwloc_bitmap_free(_cpuset);
return ret; return ret;
} }
@ -596,7 +609,7 @@ hwloc_win_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nod
int ret; int ret;
hwloc_cpuset_t cpuset = hwloc_bitmap_alloc(); hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
ret = hwloc_win_get_proc_cpubind(topology, pid, cpuset, ret = hwloc_win_get_proc_cpubind(topology, pid, cpuset,
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0); (flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
if (!ret) { if (!ret) {
*policy = HWLOC_MEMBIND_BIND; *policy = HWLOC_MEMBIND_BIND;
hwloc_cpuset_to_nodeset(topology, cpuset, nodeset); hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
@ -645,6 +658,10 @@ hwloc_win_alloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size
return NULL; return NULL;
} }
if (policy == HWLOC_MEMBIND_DEFAULT
|| hwloc_bitmap_isequal(nodeset, hwloc_topology_get_complete_nodeset(topology)))
return hwloc_win_alloc(topology, len);
if (hwloc_bitmap_weight(nodeset) != 1) { if (hwloc_bitmap_weight(nodeset) != 1) {
/* Not a single node, can't do this */ /* Not a single node, can't do this */
errno = EXDEV; errno = EXDEV;
@ -670,12 +687,14 @@ hwloc_win_free_membind(hwloc_topology_t topology __hwloc_attribute_unused, void
*/ */
static int static int
hwloc_win_get_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr, size_t len, hwloc_nodeset_t nodeset, hwloc_membind_policy_t * policy, int flags) hwloc_win_get_area_memlocation(hwloc_topology_t topology __hwloc_attribute_unused, const void *addr, size_t len, hwloc_nodeset_t nodeset, int flags __hwloc_attribute_unused)
{ {
SYSTEM_INFO SystemInfo; SYSTEM_INFO SystemInfo;
DWORD page_size; DWORD page_size;
uintptr_t start; uintptr_t start;
unsigned nb; unsigned nb;
PSAPI_WORKING_SET_EX_INFORMATION *pv;
unsigned i;
GetSystemInfo(&SystemInfo); GetSystemInfo(&SystemInfo);
page_size = SystemInfo.dwPageSize; page_size = SystemInfo.dwPageSize;
@ -686,38 +705,24 @@ hwloc_win_get_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, c
if (!nb) if (!nb)
nb = 1; nb = 1;
{ pv = calloc(nb, sizeof(*pv));
PSAPI_WORKING_SET_EX_INFORMATION *pv; if (!pv)
unsigned i; return -1;
pv = calloc(nb, sizeof(*pv)); for (i = 0; i < nb; i++)
pv[i].VirtualAddress = (void*) (start + i * page_size);
for (i = 0; i < nb; i++) if (!QueryWorkingSetExProc(GetCurrentProcess(), pv, nb * sizeof(*pv))) {
pv[i].VirtualAddress = (void*) (start + i * page_size);
if (!QueryWorkingSetExProc(GetCurrentProcess(), pv, nb * sizeof(*pv))) {
free(pv);
return -1;
}
*policy = HWLOC_MEMBIND_BIND;
if (flags & HWLOC_MEMBIND_STRICT) {
unsigned node = pv[0].VirtualAttributes.Node;
for (i = 1; i < nb; i++) {
if (pv[i].VirtualAttributes.Node != node) {
errno = EXDEV;
free(pv);
return -1;
}
}
hwloc_bitmap_only(nodeset, node);
free(pv);
return 0;
}
hwloc_bitmap_zero(nodeset);
for (i = 0; i < nb; i++)
hwloc_bitmap_set(nodeset, pv[i].VirtualAttributes.Node);
free(pv); free(pv);
return 0; return -1;
} }
for (i = 0; i < nb; i++) {
if (pv[i].VirtualAttributes.Valid)
hwloc_bitmap_set(nodeset, pv[i].VirtualAttributes.Node);
}
free(pv);
return 0;
} }
@ -732,12 +737,14 @@ hwloc_look_windows(struct hwloc_backend *backend)
hwloc_bitmap_t groups_pu_set = NULL; hwloc_bitmap_t groups_pu_set = NULL;
SYSTEM_INFO SystemInfo; SYSTEM_INFO SystemInfo;
DWORD length; DWORD length;
int gotnuma = 0;
int gotnumamemory = 0;
if (topology->levels[0][0]->cpuset) if (topology->levels[0][0]->cpuset)
/* somebody discovered things */ /* somebody discovered things */
return -1; return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]); hwloc_alloc_root_sets(topology->levels[0][0]);
GetSystemInfo(&SystemInfo); GetSystemInfo(&SystemInfo);
@ -752,16 +759,16 @@ hwloc_look_windows(struct hwloc_backend *backend)
procInfo = NULL; procInfo = NULL;
while (1) { while (1) {
if (GetLogicalProcessorInformationProc(procInfo, &length)) if (GetLogicalProcessorInformationProc(procInfo, &length))
break; break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1; return -1;
tmpprocInfo = realloc(procInfo, length); tmpprocInfo = realloc(procInfo, length);
if (!tmpprocInfo) { if (!tmpprocInfo) {
free(procInfo); free(procInfo);
goto out; goto out;
} }
procInfo = tmpprocInfo; procInfo = tmpprocInfo;
} }
assert(!length || procInfo); assert(!length || procInfo);
@ -769,97 +776,102 @@ hwloc_look_windows(struct hwloc_backend *backend)
for (i = 0; i < length / sizeof(*procInfo); i++) { for (i = 0; i < length / sizeof(*procInfo); i++) {
/* Ignore unknown caches */ /* Ignore unknown caches */
if (procInfo->Relationship == RelationCache if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified && procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData && procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction) && procInfo->Cache.Type != CacheInstruction)
continue; continue;
id = -1; id = HWLOC_UNKNOWN_INDEX;
switch (procInfo[i].Relationship) { switch (procInfo[i].Relationship) {
case RelationNumaNode: case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE; type = HWLOC_OBJ_NUMANODE;
id = procInfo[i].NumaNode.NodeNumber; id = procInfo[i].NumaNode.NodeNumber;
break; gotnuma++;
case RelationProcessorPackage: if (id > max_numanode_index)
type = HWLOC_OBJ_PACKAGE; max_numanode_index = id;
break; break;
case RelationCache: case RelationProcessorPackage:
type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1; type = HWLOC_OBJ_PACKAGE;
break; break;
case RelationProcessorCore: case RelationCache:
type = HWLOC_OBJ_CORE; type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1;
break; break;
case RelationGroup: case RelationProcessorCore:
default: type = HWLOC_OBJ_CORE;
type = HWLOC_OBJ_GROUP; break;
break; case RelationGroup:
} default:
type = HWLOC_OBJ_GROUP;
break;
}
if (!hwloc_filter_check_keep_object_type(topology, type)) if (!hwloc_filter_check_keep_object_type(topology, type))
continue; continue;
obj = hwloc_alloc_setup_object(topology, type, id); obj = hwloc_alloc_setup_object(topology, type, id);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
hwloc_debug("%s#%u mask %lx\n", hwloc_type_name(type), id, procInfo[i].ProcessorMask); hwloc_debug("%s#%u mask %lx\n", hwloc_obj_type_string(type), id, procInfo[i].ProcessorMask);
/* ProcessorMask is a ULONG_PTR */ /* ProcessorMask is a ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, 0, procInfo[i].ProcessorMask); hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, 0, procInfo[i].ProcessorMask);
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_type_name(type), id, obj->cpuset); hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) { switch (type) {
case HWLOC_OBJ_NUMANODE: case HWLOC_OBJ_NUMANODE:
{ {
ULONGLONG avail; ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id); hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail)) if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) || (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) {
obj->memory.local_memory = avail; obj->attr->numanode.local_memory = avail;
obj->memory.page_types_len = 2; gotnumamemory++;
obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types)); }
memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types)); obj->attr->numanode.page_types_len = 2;
obj->memory.page_types_len = 1; obj->attr->numanode.page_types = malloc(2 * sizeof(*obj->attr->numanode.page_types));
obj->memory.page_types[0].size = SystemInfo.dwPageSize; memset(obj->attr->numanode.page_types, 0, 2 * sizeof(*obj->attr->numanode.page_types));
obj->attr->numanode.page_types_len = 1;
obj->attr->numanode.page_types[0].size = SystemInfo.dwPageSize;
#if HAVE_DECL__SC_LARGE_PAGESIZE #if HAVE_DECL__SC_LARGE_PAGESIZE
obj->memory.page_types_len++; obj->attr->numanode.page_types_len++;
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif #endif
break; break;
} }
case HWLOC_OBJ_L1CACHE: case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE: case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE: case HWLOC_OBJ_L3CACHE:
case HWLOC_OBJ_L4CACHE: case HWLOC_OBJ_L4CACHE:
case HWLOC_OBJ_L5CACHE: case HWLOC_OBJ_L5CACHE:
case HWLOC_OBJ_L1ICACHE: case HWLOC_OBJ_L1ICACHE:
case HWLOC_OBJ_L2ICACHE: case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE: case HWLOC_OBJ_L3ICACHE:
obj->attr->cache.size = procInfo[i].Cache.Size; obj->attr->cache.size = procInfo[i].Cache.Size;
obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ; obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ;
obj->attr->cache.linesize = procInfo[i].Cache.LineSize; obj->attr->cache.linesize = procInfo[i].Cache.LineSize;
obj->attr->cache.depth = procInfo[i].Cache.Level; obj->attr->cache.depth = procInfo[i].Cache.Level;
switch (procInfo->Cache.Type) { switch (procInfo->Cache.Type) {
case CacheUnified: case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break; break;
case CacheData: case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break; break;
case CacheInstruction: case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break; break;
default: default:
hwloc_free_unlinked_object(obj); hwloc_free_unlinked_object(obj);
continue; continue;
} }
break; break;
case HWLOC_OBJ_GROUP: case HWLOC_OBJ_GROUP:
obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN; obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN;
break; break;
default: default:
break; break;
} }
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
free(procInfo); free(procInfo);
@ -875,158 +887,167 @@ hwloc_look_windows(struct hwloc_backend *backend)
procInfoTotal = NULL; procInfoTotal = NULL;
while (1) { while (1) {
if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length)) if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length))
break; break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1; return -1;
tmpprocInfoTotal = realloc(procInfoTotal, length); tmpprocInfoTotal = realloc(procInfoTotal, length);
if (!tmpprocInfoTotal) { if (!tmpprocInfoTotal) {
free(procInfoTotal); free(procInfoTotal);
goto out; goto out;
} }
procInfoTotal = tmpprocInfoTotal; procInfoTotal = tmpprocInfoTotal;
} }
for (procInfo = procInfoTotal; for (procInfo = procInfoTotal;
(void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length); (void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length);
procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) { procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) {
unsigned num, i; unsigned num, i;
GROUP_AFFINITY *GroupMask; GROUP_AFFINITY *GroupMask;
/* Ignore unknown caches */ /* Ignore unknown caches */
if (procInfo->Relationship == RelationCache if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified && procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData && procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction) && procInfo->Cache.Type != CacheInstruction)
continue; continue;
id = -1; id = HWLOC_UNKNOWN_INDEX;
switch (procInfo->Relationship) { switch (procInfo->Relationship) {
case RelationNumaNode: case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE; type = HWLOC_OBJ_NUMANODE;
num = 1; num = 1;
GroupMask = &procInfo->NumaNode.GroupMask; GroupMask = &procInfo->NumaNode.GroupMask;
id = procInfo->NumaNode.NodeNumber; id = procInfo->NumaNode.NodeNumber;
break; gotnuma++;
case RelationProcessorPackage: if (id > max_numanode_index)
type = HWLOC_OBJ_PACKAGE; max_numanode_index = id;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
num = procInfo->Processor.GroupCount; num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask; GroupMask = procInfo->Processor.GroupMask;
break; break;
case RelationCache: case RelationCache:
type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1; type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1;
num = 1; num = 1;
GroupMask = &procInfo->Cache.GroupMask; GroupMask = &procInfo->Cache.GroupMask;
break; break;
case RelationProcessorCore: case RelationProcessorCore:
type = HWLOC_OBJ_CORE; type = HWLOC_OBJ_CORE;
num = procInfo->Processor.GroupCount; num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask; GroupMask = procInfo->Processor.GroupMask;
break; break;
case RelationGroup: case RelationGroup:
/* So strange an interface... */ /* So strange an interface... */
for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) { for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) {
KAFFINITY mask; KAFFINITY mask;
hwloc_bitmap_t set; hwloc_bitmap_t set;
set = hwloc_bitmap_alloc(); set = hwloc_bitmap_alloc();
mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask; mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask;
hwloc_debug("group %u %d cpus mask %lx\n", id, hwloc_debug("group %u %d cpus mask %lx\n", id,
procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask); procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask);
/* KAFFINITY is ULONG_PTR */ /* KAFFINITY is ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask); hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask);
/* FIXME: what if running 32bits on a 64bits windows with 64-processor groups? /* FIXME: what if running 32bits on a 64bits windows with 64-processor groups?
* ULONG_PTR is 32bits, so half the group is invisible? * ULONG_PTR is 32bits, so half the group is invisible?
* maybe scale id to id*8/sizeof(ULONG_PTR) so that groups are 64-PU aligned? * maybe scale id to id*8/sizeof(ULONG_PTR) so that groups are 64-PU aligned?
*/ */
hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, set); hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, set);
/* save the set of PUs so that we can create them at the end */ /* save the set of PUs so that we can create them at the end */
if (!groups_pu_set) if (!groups_pu_set)
groups_pu_set = hwloc_bitmap_alloc(); groups_pu_set = hwloc_bitmap_alloc();
hwloc_bitmap_or(groups_pu_set, groups_pu_set, set); hwloc_bitmap_or(groups_pu_set, groups_pu_set, set);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) { if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id);
obj->cpuset = set; obj->cpuset = set;
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP; obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} else } else
hwloc_bitmap_free(set); hwloc_bitmap_free(set);
} }
continue; continue;
default: default:
/* Don't know how to get the mask. */ /* Don't know how to get the mask. */
hwloc_debug("unknown relation %d\n", procInfo->Relationship); hwloc_debug("unknown relation %d\n", procInfo->Relationship);
continue; continue;
} }
if (!hwloc_filter_check_keep_object_type(topology, type)) if (!hwloc_filter_check_keep_object_type(topology, type))
continue; continue;
obj = hwloc_alloc_setup_object(topology, type, id); obj = hwloc_alloc_setup_object(topology, type, id);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
hwloc_debug("%s#%u %d: mask %d:%lx\n", hwloc_type_name(type), id, i, GroupMask[i].Group, GroupMask[i].Mask); hwloc_debug("%s#%u %d: mask %d:%lx\n", hwloc_obj_type_string(type), id, i, GroupMask[i].Group, GroupMask[i].Mask);
/* GROUP_AFFINITY.Mask is KAFFINITY, which is ULONG_PTR */ /* GROUP_AFFINITY.Mask is KAFFINITY, which is ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, GroupMask[i].Group, GroupMask[i].Mask); hwloc_bitmap_set_ith_ULONG_PTR(obj->cpuset, GroupMask[i].Group, GroupMask[i].Mask);
/* FIXME: scale id to id*8/sizeof(ULONG_PTR) as above? */ /* FIXME: scale id to id*8/sizeof(ULONG_PTR) as above? */
} }
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_type_name(type), id, obj->cpuset); hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) { switch (type) {
case HWLOC_OBJ_NUMANODE: case HWLOC_OBJ_NUMANODE:
{ {
ULONGLONG avail; ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc(); obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id); hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail)) if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) || (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) {
obj->memory.local_memory = avail; obj->attr->numanode.local_memory = avail;
obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types)); gotnumamemory++;
memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types)); }
obj->memory.page_types_len = 1; obj->attr->numanode.page_types = malloc(2 * sizeof(*obj->attr->numanode.page_types));
obj->memory.page_types[0].size = SystemInfo.dwPageSize; memset(obj->attr->numanode.page_types, 0, 2 * sizeof(*obj->attr->numanode.page_types));
obj->attr->numanode.page_types_len = 1;
obj->attr->numanode.page_types[0].size = SystemInfo.dwPageSize;
#if HAVE_DECL__SC_LARGE_PAGESIZE #if HAVE_DECL__SC_LARGE_PAGESIZE
obj->memory.page_types_len++; obj->attr->numanode.page_types_len++;
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE); obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif #endif
break; break;
} }
case HWLOC_OBJ_L1CACHE: case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE: case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE: case HWLOC_OBJ_L3CACHE:
case HWLOC_OBJ_L4CACHE: case HWLOC_OBJ_L4CACHE:
case HWLOC_OBJ_L5CACHE: case HWLOC_OBJ_L5CACHE:
case HWLOC_OBJ_L1ICACHE: case HWLOC_OBJ_L1ICACHE:
case HWLOC_OBJ_L2ICACHE: case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE: case HWLOC_OBJ_L3ICACHE:
obj->attr->cache.size = procInfo->Cache.CacheSize; obj->attr->cache.size = procInfo->Cache.CacheSize;
obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ; obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ;
obj->attr->cache.linesize = procInfo->Cache.LineSize; obj->attr->cache.linesize = procInfo->Cache.LineSize;
obj->attr->cache.depth = procInfo->Cache.Level; obj->attr->cache.depth = procInfo->Cache.Level;
switch (procInfo->Cache.Type) { switch (procInfo->Cache.Type) {
case CacheUnified: case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break; break;
case CacheData: case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA; obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break; break;
case CacheInstruction: case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION; obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break; break;
default: default:
hwloc_free_unlinked_object(obj); hwloc_free_unlinked_object(obj);
continue; continue;
} }
break; break;
default: default:
break; break;
} }
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
free(procInfoTotal); free(procInfoTotal);
} }
topology->support.discovery->pu = 1;
topology->support.discovery->numa = gotnuma;
topology->support.discovery->numa_memory = gotnumamemory;
if (groups_pu_set) { if (groups_pu_set) {
/* the system supports multiple Groups. /* the system supports multiple Groups.
* PU indexes may be discontiguous, especially if Groups contain less than 64 procs. * PU indexes may be discontiguous, especially if Groups contain less than 64 procs.
@ -1038,7 +1059,7 @@ hwloc_look_windows(struct hwloc_backend *backend)
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_only(obj->cpuset, idx); hwloc_bitmap_only(obj->cpuset, idx);
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n", hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
idx, obj->cpuset); idx, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} hwloc_bitmap_foreach_end(); } hwloc_bitmap_foreach_end();
hwloc_bitmap_free(groups_pu_set); hwloc_bitmap_free(groups_pu_set);
@ -1050,12 +1071,12 @@ hwloc_look_windows(struct hwloc_backend *backend)
GetSystemInfo(&sysinfo); GetSystemInfo(&sysinfo);
for(idx=0; idx<32; idx++) for(idx=0; idx<32; idx++)
if (sysinfo.dwActiveProcessorMask & (((DWORD_PTR)1)<<idx)) { if (sysinfo.dwActiveProcessorMask & (((DWORD_PTR)1)<<idx)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx); obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx);
obj->cpuset = hwloc_bitmap_alloc(); obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_only(obj->cpuset, idx); hwloc_bitmap_only(obj->cpuset, idx);
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n", hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
idx, obj->cpuset); idx, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj); hwloc_insert_object_by_cpuset(topology, obj);
} }
} }
@ -1067,7 +1088,7 @@ hwloc_look_windows(struct hwloc_backend *backend)
void void
hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks, hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support) struct hwloc_topology_support *support)
{ {
if (GetCurrentProcessorNumberExProc || (GetCurrentProcessorNumberProc && nr_processor_groups == 1)) if (GetCurrentProcessorNumberExProc || (GetCurrentProcessorNumberProc && nr_processor_groups == 1))
hooks->get_thisthread_last_cpu_location = hwloc_win_get_thisthread_last_cpu_location; hooks->get_thisthread_last_cpu_location = hwloc_win_get_thisthread_last_cpu_location;
@ -1100,8 +1121,8 @@ hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks,
support->membind->bind_membind = 1; support->membind->bind_membind = 1;
} }
if (QueryWorkingSetExProc) if (QueryWorkingSetExProc && max_numanode_index <= 63 /* PSAPI_WORKING_SET_EX_BLOCK.Node is 6 bits only */)
hooks->get_area_membind = hwloc_win_get_area_membind; hooks->get_area_memlocation = hwloc_win_get_area_memlocation;
} }
static int hwloc_windows_component_init(unsigned long flags __hwloc_attribute_unused) static int hwloc_windows_component_init(unsigned long flags __hwloc_attribute_unused)
@ -1116,9 +1137,9 @@ static void hwloc_windows_component_finalize(unsigned long flags __hwloc_attribu
static struct hwloc_backend * static struct hwloc_backend *
hwloc_windows_component_instantiate(struct hwloc_disc_component *component, hwloc_windows_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused, const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused, const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused) const void *_data3 __hwloc_attribute_unused)
{ {
struct hwloc_backend *backend; struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component); backend = hwloc_backend_alloc(component);
@ -1134,6 +1155,7 @@ static struct hwloc_disc_component hwloc_windows_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL, HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_windows_component_instantiate, hwloc_windows_component_instantiate,
50, 50,
1,
NULL NULL
}; };
@ -1145,8 +1167,8 @@ const struct hwloc_component hwloc_windows_component = {
&hwloc_windows_disc_component &hwloc_windows_disc_component
}; };
unsigned int
hwloc_fallback_nbprocessors(struct hwloc_topology *topology) { hwloc_fallback_nbprocessors(struct hwloc_topology *topology __hwloc_attribute_unused) {
int n; int n;
SYSTEM_INFO sysinfo; SYSTEM_INFO sysinfo;
@ -1158,14 +1180,10 @@ hwloc_fallback_nbprocessors(struct hwloc_topology *topology) {
/* assume n-1 groups are complete, since that's how we store things in cpusets */ /* assume n-1 groups are complete, since that's how we store things in cpusets */
if (GetActiveProcessorCountProc) if (GetActiveProcessorCountProc)
n = MAXIMUM_PROC_PER_GROUP*(nr_processor_groups-1) n = MAXIMUM_PROC_PER_GROUP*(nr_processor_groups-1)
+ GetActiveProcessorCountProc((WORD)nr_processor_groups-1); + GetActiveProcessorCountProc((WORD)nr_processor_groups-1);
else else
n = MAXIMUM_PROC_PER_GROUP*nr_processor_groups; n = MAXIMUM_PROC_PER_GROUP*nr_processor_groups;
} }
if (n >= 1)
topology->support.discovery->pu = 1;
else
n = 1;
return n; return n;
} }

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -55,7 +55,7 @@ hwloc_libxml2_cleanup(void)
typedef struct hwloc__libxml_import_state_data_s { typedef struct hwloc__libxml_import_state_data_s {
xmlNode *node; /* current libxml node, always valid */ xmlNode *node; /* current libxml node, always valid */
xmlNode *child; /* last processed child, or NULL if none yet */ xmlNode *child; /* next processed child, or NULL if none yet */
xmlAttr *attr; /* last processed attribute, or NULL if none yet */ xmlAttr *attr; /* last processed attribute, or NULL if none yet */
} __hwloc_attribute_may_alias * hwloc__libxml_import_state_data_t; } __hwloc_attribute_may_alias * hwloc__libxml_import_state_data_t;
@ -75,7 +75,7 @@ hwloc__libxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, ch
xmlNode *subnode; xmlNode *subnode;
for (subnode = attr->children; subnode; subnode = subnode->next) { for (subnode = attr->children; subnode; subnode = subnode->next) {
if (subnode->type == XML_TEXT_NODE) { if (subnode->type == XML_TEXT_NODE) {
if (subnode->content && subnode->content[0] != '\0' && subnode->content[0] != '\n') { if (subnode->content) {
*namep = (char *) attr->name; *namep = (char *) attr->name;
*valuep = (char *) subnode->content; *valuep = (char *) subnode->content;
lstate->attr = attr; lstate->attr = attr;
@ -83,20 +83,22 @@ hwloc__libxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, ch
} }
} else { } else {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unexpected xml attr node type %u\n", subnode->type); fprintf(stderr, "%s: ignoring unexpected xml attr node type %u\n",
state->global->msgprefix, subnode->type);
} }
} }
} else { } else {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unexpected xml attr type %u\n", attr->type); fprintf(stderr, "%s: ignoring unexpected xml attr type %u\n",
state->global->msgprefix, attr->type);
} }
return -1; return -1;
} }
static int static int
hwloc__libxml_import_find_child(hwloc__xml_import_state_t state, hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate, hwloc__xml_import_state_t childstate,
char **tagp) char **tagp)
{ {
hwloc__libxml_import_state_data_t lstate = (void*) state->data; hwloc__libxml_import_state_data_t lstate = (void*) state->data;
hwloc__libxml_import_state_data_t lchildstate = (void*) childstate->data; hwloc__libxml_import_state_data_t lchildstate = (void*) childstate->data;
@ -104,23 +106,27 @@ hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
childstate->parent = state; childstate->parent = state;
childstate->global = state->global; childstate->global = state->global;
if (!lstate->child) if (!lstate->child)
/* All children proceeded */
return 0; return 0;
child = lstate->child->next;
for (; child; child = child->next) child = lstate->child;
if (child->type == XML_ELEMENT_NODE) { if (child->type == XML_ELEMENT_NODE) {
lstate->child = lchildstate->node = child; lstate->child = child->next;
lchildstate->child = child->children; lchildstate->node = child;
lchildstate->attr = NULL; lchildstate->child = child->children;
*tagp = (char*) child->name; lchildstate->attr = NULL;
return 1; *tagp = (char*) child->name;
} else if (child->type == XML_TEXT_NODE) { return 1;
if (child->content && child->content[0] != '\0' && child->content[0] != '\n') } else if (child->type == XML_TEXT_NODE) {
if (hwloc__xml_verbose()) if (child->content && child->content[0] != '\0' && child->content[0] != '\n')
fprintf(stderr, "ignoring object text content %s\n", (const char*) child->content);
} else if (child->type != XML_COMMENT_NODE) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring unexpected xml node type %u\n", child->type); fprintf(stderr, "%s: ignoring object text content %s\n",
} state->global->msgprefix, (const char*) child->content);
} else if (child->type != XML_COMMENT_NODE) {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: ignoring unexpected xml node type %u\n",
state->global->msgprefix, child->type);
}
return 0; return 0;
} }
@ -139,7 +145,7 @@ hwloc__libxml_import_close_child(hwloc__xml_import_state_t state __hwloc_attribu
static int static int
hwloc__libxml_import_get_content(hwloc__xml_import_state_t state, hwloc__libxml_import_get_content(hwloc__xml_import_state_t state,
char **beginp, size_t expected_length) char **beginp, size_t expected_length)
{ {
hwloc__libxml_import_state_data_t lstate = (void*) state->data; hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlNode *child; xmlNode *child;
@ -149,7 +155,7 @@ hwloc__libxml_import_get_content(hwloc__xml_import_state_t state,
if (!child || child->type != XML_TEXT_NODE) { if (!child || child->type != XML_TEXT_NODE) {
if (expected_length) if (expected_length)
return -1; return -1;
*beginp = ""; *beginp = (char *) "";
return 0; return 0;
} }
@ -168,30 +174,47 @@ hwloc__libxml_import_close_content(hwloc__xml_import_state_t state __hwloc_attri
static int static int
hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata, hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state) struct hwloc__xml_import_state_s *state)
{ {
hwloc__libxml_import_state_data_t lstate = (void*) state->data; hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlNode* root_node; xmlNodePtr root_node;
xmlDtd *dtd; xmlDtdPtr dtd;
assert(sizeof(*lstate) <= sizeof(state->data)); HWLOC_BUILD_ASSERT(sizeof(*lstate) <= sizeof(state->data));
dtd = xmlGetIntSubset((xmlDoc*) bdata->data); dtd = xmlGetIntSubset((xmlDocPtr) bdata->data);
if (!dtd) { if (!dtd) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topology without DTD\n"); fprintf(stderr, "%s: Loading XML topology without DTD\n",
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")) { state->global->msgprefix);
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")
&& strcmp((char *) dtd->SystemID, "hwloc2.dtd")) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topology with wrong DTD SystemID (%s instead of %s)\n", fprintf(stderr, "%s: Loading XML topology with wrong DTD SystemID (%s instead of %s)\n",
(char *) dtd->SystemID, "hwloc.dtd"); state->global->msgprefix, (char *) dtd->SystemID, "hwloc.dtd or hwloc2.dtd");
} }
root_node = xmlDocGetRootElement((xmlDoc*) bdata->data); root_node = xmlDocGetRootElement((xmlDocPtr) bdata->data);
if (strcmp((const char *) root_node->name, "topology") && strcmp((const char *) root_node->name, "root")) { if (!strcmp((const char *) root_node->name, "root")) {
bdata->version_major = 0;
bdata->version_minor = 9;
} else if (!strcmp((const char *) root_node->name, "topology")) {
unsigned major, minor;
xmlChar *version = xmlGetProp(root_node, (xmlChar*) "version");
if (version && sscanf((const char *)version, "%u.%u", &major, &minor) == 2) {
bdata->version_major = major;
bdata->version_minor = minor;
} else {
bdata->version_major = 1;
bdata->version_minor = 0;
}
xmlFree(version);
} else {
/* root node should be in "topology" class (or "root" if importing from < 1.0) */ /* root node should be in "topology" class (or "root" if importing from < 1.0) */
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring object of class `%s' not at the top the xml hierarchy\n", (const char *) root_node->name); fprintf(stderr, "%s: ignoring object of class `%s' not at the top the xml hierarchy\n",
state->global->msgprefix, (const char *) root_node->name);
goto failed; goto failed;
} }
@ -211,6 +234,24 @@ hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
return -1; /* failed */ return -1; /* failed */
} }
/* can be called at the end of the import (to cleanup things early),
* or by backend_exit() if load failed for other reasons.
*/
static void
hwloc_libxml_free_buffers(struct hwloc_xml_backend_data_s *bdata)
{
if (bdata->data) {
xmlFreeDoc((xmlDoc*)bdata->data);
bdata->data = NULL;
}
}
static void
hwloc_libxml_look_done(struct hwloc_xml_backend_data_s *bdata, int result __hwloc_attribute_unused)
{
hwloc_libxml_free_buffers(bdata);
}
static int static int
hwloc_libxml_import_diff(struct hwloc__xml_import_state_s *state, const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *firstdiffp, char **refnamep) hwloc_libxml_import_diff(struct hwloc__xml_import_state_s *state, const char *xmlpath, const char *xmlbuffer, int xmlbuflen, hwloc_topology_diff_t *firstdiffp, char **refnamep)
{ {
@ -221,7 +262,7 @@ hwloc_libxml_import_diff(struct hwloc__xml_import_state_s *state, const char *xm
xmlDtd *dtd; xmlDtd *dtd;
int ret; int ret;
assert(sizeof(*lstate) <= sizeof(state->data)); HWLOC_BUILD_ASSERT(sizeof(*lstate) <= sizeof(state->data));
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
hwloc_libxml2_init_once(); hwloc_libxml2_init_once();
@ -229,25 +270,27 @@ hwloc_libxml_import_diff(struct hwloc__xml_import_state_s *state, const char *xm
errno = 0; /* set to 0 so that we know if libxml2 changed it */ errno = 0; /* set to 0 so that we know if libxml2 changed it */
if (xmlpath) if (xmlpath)
doc = xmlReadFile(xmlpath, NULL, 0); doc = xmlReadFile(xmlpath, NULL, XML_PARSE_NOBLANKS);
else if (xmlbuffer) else if (xmlbuffer)
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0); doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, XML_PARSE_NOBLANKS);
if (!doc) { if (!doc) {
if (!errno) if (!errno)
/* libxml2 read the file fine, but it got an error during parsing */ /* libxml2 read the file fine, but it got an error during parsing */
errno = EINVAL; errno = EINVAL;
hwloc_libxml2_cleanup();
goto out; goto out;
} }
dtd = xmlGetIntSubset(doc); dtd = xmlGetIntSubset(doc);
if (!dtd) { if (!dtd) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topologydiff without DTD\n"); fprintf(stderr, "%s: Loading XML topologydiff without DTD\n",
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")) { state->global->msgprefix);
} else if (strcmp((char *) dtd->SystemID, "hwloc2-diff.dtd")) {
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topologydiff with wrong DTD SystemID (%s instead of %s)\n", fprintf(stderr, "%s: Loading XML topologydiff with wrong DTD SystemID (%s instead of %s)\n",
(char *) dtd->SystemID, "hwloc.dtd"); state->global->msgprefix, (char *) dtd->SystemID, "hwloc2-diff.dtd");
} }
root_node = xmlDocGetRootElement(doc); root_node = xmlDocGetRootElement(doc);
@ -255,7 +298,8 @@ hwloc_libxml_import_diff(struct hwloc__xml_import_state_s *state, const char *xm
if (strcmp((const char *) root_node->name, "topologydiff")) { if (strcmp((const char *) root_node->name, "topologydiff")) {
/* root node should be in "topologydiff" class */ /* root node should be in "topologydiff" class */
if (hwloc__xml_verbose()) if (hwloc__xml_verbose())
fprintf(stderr, "ignoring object of class `%s' not at the top the xml hierarchy\n", (const char *) root_node->name); fprintf(stderr, "%s: ignoring object of class `%s' not at the top the xml hierarchy\n",
state->global->msgprefix, (const char *) root_node->name);
goto out_with_doc; goto out_with_doc;
} }
@ -306,13 +350,13 @@ out:
static void static void
hwloc_libxml_backend_exit(struct hwloc_xml_backend_data_s *bdata) hwloc_libxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
{ {
xmlFreeDoc((xmlDoc*)bdata->data); hwloc_libxml_free_buffers(bdata);
hwloc_libxml2_cleanup(); hwloc_libxml2_cleanup();
} }
static int static int
hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata, hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen) const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{ {
xmlDoc *doc = NULL; xmlDoc *doc = NULL;
@ -322,19 +366,20 @@ hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
errno = 0; /* set to 0 so that we know if libxml2 changed it */ errno = 0; /* set to 0 so that we know if libxml2 changed it */
if (xmlpath) if (xmlpath)
doc = xmlReadFile(xmlpath, NULL, 0); doc = xmlReadFile(xmlpath, NULL, XML_PARSE_NOBLANKS);
else if (xmlbuffer) else if (xmlbuffer)
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0); doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, XML_PARSE_NOBLANKS);
if (!doc) { if (!doc) {
if (!errno) if (!errno)
/* libxml2 read the file fine, but it got an error during parsing */ /* libxml2 read the file fine, but it got an error during parsing */
errno = EINVAL; errno = EINVAL;
hwloc_libxml2_cleanup();
return -1; return -1;
} }
bdata->look_init = hwloc_libxml_look_init; bdata->look_init = hwloc_libxml_look_init;
bdata->look_failed = NULL; bdata->look_done = hwloc_libxml_look_done;
bdata->backend_exit = hwloc_libxml_backend_exit; bdata->backend_exit = hwloc_libxml_backend_exit;
bdata->data = doc; bdata->data = doc;
return 0; return 0;
@ -350,8 +395,8 @@ typedef struct hwloc__libxml_export_state_data_s {
static void static void
hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate, hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state, hwloc__xml_export_state_t state,
const char *name) const char *name)
{ {
hwloc__libxml_export_state_data_t lpdata = (void *) parentstate->data; hwloc__libxml_export_state_data_t lpdata = (void *) parentstate->data;
hwloc__libxml_export_state_data_t ldata = (void *) state->data; hwloc__libxml_export_state_data_t ldata = (void *) state->data;
@ -361,6 +406,7 @@ hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
state->new_prop = parentstate->new_prop; state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content; state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object; state->end_object = parentstate->end_object;
state->global = parentstate->global;
ldata->current_node = xmlNewChild(lpdata->current_node, NULL, BAD_CAST name, NULL); ldata->current_node = xmlNewChild(lpdata->current_node, NULL, BAD_CAST name, NULL);
} }
@ -386,14 +432,16 @@ hwloc__libxml_export_add_content(hwloc__xml_export_state_t state, const char *bu
} }
static xmlDocPtr static xmlDocPtr
hwloc__libxml2_prepare_export(hwloc_topology_t topology, unsigned long flags) hwloc__libxml2_prepare_export(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
unsigned long flags)
{ {
struct hwloc__xml_export_state_s state; struct hwloc__xml_export_state_s state;
hwloc__libxml_export_state_data_t data = (void *) state.data; hwloc__libxml_export_state_data_t data = (void *) state.data;
int v1export = flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1;
xmlDocPtr doc = NULL; /* document pointer */ xmlDocPtr doc = NULL; /* document pointer */
xmlNodePtr root_node = NULL; /* root pointer */ xmlNodePtr root_node = NULL; /* root pointer */
assert(sizeof(*data) <= sizeof(state.data)); HWLOC_BUILD_ASSERT(sizeof(*data) <= sizeof(state.data));
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
hwloc_libxml2_init_once(); hwloc_libxml2_init_once();
@ -401,15 +449,18 @@ hwloc__libxml2_prepare_export(hwloc_topology_t topology, unsigned long flags)
/* Creates a new document, a node and set it as a root node. */ /* Creates a new document, a node and set it as a root node. */
doc = xmlNewDoc(BAD_CAST "1.0"); doc = xmlNewDoc(BAD_CAST "1.0");
root_node = xmlNewNode(NULL, BAD_CAST "topology"); root_node = xmlNewNode(NULL, BAD_CAST "topology");
if (!(flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1))
xmlNewProp(root_node, BAD_CAST "version", BAD_CAST "2.0");
xmlDocSetRootElement(doc, root_node); xmlDocSetRootElement(doc, root_node);
/* Creates a DTD declaration. Isn't mandatory. */ /* Creates a DTD declaration. Isn't mandatory. */
(void) xmlCreateIntSubset(doc, BAD_CAST "topology", NULL, BAD_CAST "hwloc.dtd"); (void) xmlCreateIntSubset(doc, BAD_CAST "topology", NULL, v1export ? BAD_CAST "hwloc.dtd" : BAD_CAST "hwloc2.dtd");
state.new_child = hwloc__libxml_export_new_child; state.new_child = hwloc__libxml_export_new_child;
state.new_prop = hwloc__libxml_export_new_prop; state.new_prop = hwloc__libxml_export_new_prop;
state.add_content = hwloc__libxml_export_add_content; state.add_content = hwloc__libxml_export_add_content;
state.end_object = hwloc__libxml_export_end_object; state.end_object = hwloc__libxml_export_end_object;
state.global = edata;
data->current_node = root_node; data->current_node = root_node;
@ -419,14 +470,15 @@ hwloc__libxml2_prepare_export(hwloc_topology_t topology, unsigned long flags)
} }
static int static int
hwloc_libxml_export_file(hwloc_topology_t topology, const char *filename, unsigned long flags) hwloc_libxml_export_file(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
const char *filename, unsigned long flags)
{ {
xmlDocPtr doc; xmlDocPtr doc;
int ret; int ret;
errno = 0; /* set to 0 so that we know if libxml2 changed it */ errno = 0; /* set to 0 so that we know if libxml2 changed it */
doc = hwloc__libxml2_prepare_export(topology, flags); doc = hwloc__libxml2_prepare_export(topology, edata, flags);
ret = xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1); ret = xmlSaveFormatFileEnc(filename, doc, "UTF-8", 1);
xmlFreeDoc(doc); xmlFreeDoc(doc);
hwloc_libxml2_cleanup(); hwloc_libxml2_cleanup();
@ -441,11 +493,12 @@ hwloc_libxml_export_file(hwloc_topology_t topology, const char *filename, unsign
} }
static int static int
hwloc_libxml_export_buffer(hwloc_topology_t topology, char **xmlbuffer, int *buflen, unsigned long flags) hwloc_libxml_export_buffer(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
char **xmlbuffer, int *buflen, unsigned long flags)
{ {
xmlDocPtr doc; xmlDocPtr doc;
doc = hwloc__libxml2_prepare_export(topology, flags); doc = hwloc__libxml2_prepare_export(topology, edata, flags);
xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1); xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
xmlFreeDoc(doc); xmlFreeDoc(doc);
hwloc_libxml2_cleanup(); hwloc_libxml2_cleanup();
@ -460,7 +513,7 @@ hwloc__libxml2_prepare_export_diff(hwloc_topology_diff_t diff, const char *refna
xmlDocPtr doc = NULL; /* document pointer */ xmlDocPtr doc = NULL; /* document pointer */
xmlNodePtr root_node = NULL; /* root pointer */ xmlNodePtr root_node = NULL; /* root pointer */
assert(sizeof(*data) <= sizeof(state.data)); HWLOC_BUILD_ASSERT(sizeof(*data) <= sizeof(state.data));
LIBXML_TEST_VERSION; LIBXML_TEST_VERSION;
hwloc_libxml2_init_once(); hwloc_libxml2_init_once();
@ -473,7 +526,7 @@ hwloc__libxml2_prepare_export_diff(hwloc_topology_diff_t diff, const char *refna
xmlDocSetRootElement(doc, root_node); xmlDocSetRootElement(doc, root_node);
/* Creates a DTD declaration. Isn't mandatory. */ /* Creates a DTD declaration. Isn't mandatory. */
(void) xmlCreateIntSubset(doc, BAD_CAST "topologydiff", NULL, BAD_CAST "hwloc.dtd"); (void) xmlCreateIntSubset(doc, BAD_CAST "topologydiff", NULL, BAD_CAST "hwloc2-diff.dtd");
state.new_child = hwloc__libxml_export_new_child; state.new_child = hwloc__libxml_export_new_child;
state.new_prop = hwloc__libxml_export_new_prop; state.new_prop = hwloc__libxml_export_new_prop;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2011 Université Bordeaux * Copyright © 2009-2011 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -70,28 +70,28 @@ hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep,
while (value[len+escaped] != '\"') { while (value[len+escaped] != '\"') {
if (value[len+escaped] == '&') { if (value[len+escaped] == '&') {
if (!strncmp(&value[1+len+escaped], "#10;", 4)) { if (!strncmp(&value[1+len+escaped], "#10;", 4)) {
escaped += 4; escaped += 4;
value[len] = '\n'; value[len] = '\n';
} else if (!strncmp(&value[1+len+escaped], "#13;", 4)) { } else if (!strncmp(&value[1+len+escaped], "#13;", 4)) {
escaped += 4; escaped += 4;
value[len] = '\r'; value[len] = '\r';
} else if (!strncmp(&value[1+len+escaped], "#9;", 3)) { } else if (!strncmp(&value[1+len+escaped], "#9;", 3)) {
escaped += 3; escaped += 3;
value[len] = '\t'; value[len] = '\t';
} else if (!strncmp(&value[1+len+escaped], "quot;", 5)) { } else if (!strncmp(&value[1+len+escaped], "quot;", 5)) {
escaped += 5; escaped += 5;
value[len] = '\"'; value[len] = '\"';
} else if (!strncmp(&value[1+len+escaped], "lt;", 3)) { } else if (!strncmp(&value[1+len+escaped], "lt;", 3)) {
escaped += 3; escaped += 3;
value[len] = '<'; value[len] = '<';
} else if (!strncmp(&value[1+len+escaped], "gt;", 3)) { } else if (!strncmp(&value[1+len+escaped], "gt;", 3)) {
escaped += 3; escaped += 3;
value[len] = '>'; value[len] = '>';
} else if (!strncmp(&value[1+len+escaped], "amp;", 4)) { } else if (!strncmp(&value[1+len+escaped], "amp;", 4)) {
escaped += 4; escaped += 4;
value[len] = '&'; value[len] = '&';
} else { } else {
return -1; return -1;
} }
} else { } else {
value[len] = value[len+escaped]; value[len] = value[len+escaped];
@ -110,13 +110,14 @@ hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep,
static int static int
hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state, hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate, hwloc__xml_import_state_t childstate,
char **tagp) char **tagp)
{ {
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data; hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data; hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data;
char *buffer = nstate->tagbuffer; char *buffer = nstate->tagbuffer;
char *end; char *end;
char *tag;
size_t namelen; size_t namelen;
childstate->parent = state; childstate->parent = state;
@ -137,7 +138,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
return 0; return 0;
/* normal tag */ /* normal tag */
*tagp = nchildstate->tagname = buffer; tag = nchildstate->tagname = buffer;
/* find the end, mark it and return it */ /* find the end, mark it and return it */
end = strchr(buffer, '>'); end = strchr(buffer, '>');
@ -159,6 +160,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
if (buffer[namelen] == '\0') { if (buffer[namelen] == '\0') {
/* no attributes */ /* no attributes */
nchildstate->attrbuffer = NULL; nchildstate->attrbuffer = NULL;
*tagp = tag;
return 1; return 1;
} }
@ -168,6 +170,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
/* found a space, likely starting attributes */ /* found a space, likely starting attributes */
buffer[namelen] = '\0'; buffer[namelen] = '\0';
nchildstate->attrbuffer = buffer+namelen+1; nchildstate->attrbuffer = buffer+namelen+1;
*tagp = tag;
return 1; return 1;
} }
@ -211,7 +214,7 @@ hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state)
static int static int
hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state, hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
char **beginp, size_t expected_length) char **beginp, size_t expected_length)
{ {
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data; hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
char *buffer = nstate->tagbuffer; char *buffer = nstate->tagbuffer;
@ -222,7 +225,7 @@ hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
if (nstate->closed) { if (nstate->closed) {
if (expected_length) if (expected_length)
return -1; return -1;
*beginp = ""; *beginp = (char *) "";
return 0; return 0;
} }
@ -251,13 +254,15 @@ hwloc__nolibxml_import_close_content(hwloc__xml_import_state_t state)
static int static int
hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata, hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state) struct hwloc__xml_import_state_s *state)
{ {
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data; hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data; struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
unsigned major, minor;
char *end;
char *buffer; char *buffer;
assert(sizeof(*nstate) <= sizeof(state->data)); HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
/* use a copy in the temporary buffer, we may modify during parsing */ /* use a copy in the temporary buffer, we may modify during parsing */
buffer = nbdata->copy; buffer = nbdata->copy;
@ -272,7 +277,19 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
} }
/* find topology tag */ /* find topology tag */
if (strncmp(buffer, "<topology>", 10)) if (sscanf(buffer, "<topology version=\"%u.%u\">", &major, &minor) == 2) {
bdata->version_major = major;
bdata->version_minor = minor;
end = strchr(buffer, '>') + 1;
} else if (!strncmp(buffer, "<topology>", 10)) {
bdata->version_major = 1;
bdata->version_minor = 0;
end = buffer + 10;
} else if (!strncmp(buffer, "<root>", 6)) {
bdata->version_major = 0;
bdata->version_minor = 9;
end = buffer + 6;
} else
goto failed; goto failed;
state->global->next_attr = hwloc__nolibxml_import_next_attr; state->global->next_attr = hwloc__nolibxml_import_next_attr;
@ -283,7 +300,7 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
state->global->close_content = hwloc__nolibxml_import_close_content; state->global->close_content = hwloc__nolibxml_import_close_content;
state->parent = NULL; state->parent = NULL;
nstate->closed = 0; nstate->closed = 0;
nstate->tagbuffer = buffer+10; nstate->tagbuffer = end;
nstate->tagname = (char *) "topology"; nstate->tagname = (char *) "topology";
nstate->attrbuffer = NULL; nstate->attrbuffer = NULL;
return 0; /* success */ return 0; /* success */
@ -292,12 +309,31 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
return -1; /* failed */ return -1; /* failed */
} }
/* can be called at the end of the import (to cleanup things early),
* or by backend_exit() if load failed for other reasons.
*/
static void static void
hwloc_nolibxml_look_failed(struct hwloc_xml_backend_data_s *bdata __hwloc_attribute_unused) hwloc_nolibxml_free_buffers(struct hwloc_xml_backend_data_s *bdata)
{ {
/* not only when verbose */ struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
fprintf(stderr, "Failed to parse XML input with the minimalistic parser. If it was not\n" if (nbdata->buffer) {
"generated by hwloc, try enabling full XML support with libxml2.\n"); free(nbdata->buffer);
nbdata->buffer = NULL;
}
if (nbdata->copy) {
free(nbdata->copy);
nbdata->copy = NULL;
}
}
static void
hwloc_nolibxml_look_done(struct hwloc_xml_backend_data_s *bdata, int result)
{
hwloc_nolibxml_free_buffers(bdata);
if (result < 0 && hwloc__xml_verbose())
fprintf(stderr, "Failed to parse XML input with the minimalistic parser. If it was not\n"
"generated by hwloc, try enabling full XML support with libxml2.\n");
} }
/******************** /********************
@ -308,8 +344,7 @@ static void
hwloc_nolibxml_backend_exit(struct hwloc_xml_backend_data_s *bdata) hwloc_nolibxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
{ {
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data; struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
free(nbdata->buffer); hwloc_nolibxml_free_buffers(bdata);
free(nbdata->copy);
free(nbdata); free(nbdata);
} }
@ -372,7 +407,7 @@ hwloc_nolibxml_read_file(const char *xmlpath, char **bufferp, size_t *buflenp)
static int static int
hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata, hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen) const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{ {
struct hwloc__nolibxml_backend_data_s *nbdata = malloc(sizeof(*nbdata)); struct hwloc__nolibxml_backend_data_s *nbdata = malloc(sizeof(*nbdata));
@ -399,7 +434,7 @@ hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
goto out_with_buffer; goto out_with_buffer;
bdata->look_init = hwloc_nolibxml_look_init; bdata->look_init = hwloc_nolibxml_look_init;
bdata->look_failed = hwloc_nolibxml_look_failed; bdata->look_done = hwloc_nolibxml_look_done;
bdata->backend_exit = hwloc_nolibxml_backend_exit; bdata->backend_exit = hwloc_nolibxml_backend_exit;
return 0; return 0;
@ -413,8 +448,8 @@ out:
static int static int
hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state, hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen, const char *xmlpath, const char *xmlbuffer, int xmlbuflen,
hwloc_topology_diff_t *firstdiffp, char **refnamep) hwloc_topology_diff_t *firstdiffp, char **refnamep)
{ {
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data; hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__xml_import_state_s childstate; struct hwloc__xml_import_state_s childstate;
@ -423,7 +458,7 @@ hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
size_t buflen; size_t buflen;
int ret; int ret;
assert(sizeof(*nstate) <= sizeof(state->data)); HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
if (xmlbuffer) { if (xmlbuffer) {
buffer = malloc(xmlbuflen); buffer = malloc(xmlbuflen);
@ -562,8 +597,8 @@ hwloc__nolibxml_export_escape_string(const char *src)
static void static void
hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate, hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state, hwloc__xml_export_state_t state,
const char *name) const char *name)
{ {
hwloc__nolibxml_export_state_data_t npdata = (void *) parentstate->data; hwloc__nolibxml_export_state_data_t npdata = (void *) parentstate->data;
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data; hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
@ -581,6 +616,7 @@ hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
state->new_prop = parentstate->new_prop; state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content; state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object; state->end_object = parentstate->end_object;
state->global = parentstate->global;
ndata->buffer = npdata->buffer; ndata->buffer = npdata->buffer;
ndata->written = npdata->written; ndata->written = npdata->written;
@ -644,18 +680,21 @@ hwloc__nolibxml_export_add_content(hwloc__xml_export_state_t state, const char *
} }
static size_t static size_t
hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int buflen, unsigned long flags) hwloc___nolibxml_prepare_export(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
char *xmlbuffer, int buflen, unsigned long flags)
{ {
struct hwloc__xml_export_state_s state, childstate; struct hwloc__xml_export_state_s state, childstate;
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data; hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
int v1export = flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1;
int res; int res;
assert(sizeof(*ndata) <= sizeof(state.data)); HWLOC_BUILD_ASSERT(sizeof(*ndata) <= sizeof(state.data));
state.new_child = hwloc__nolibxml_export_new_child; state.new_child = hwloc__nolibxml_export_new_child;
state.new_prop = hwloc__nolibxml_export_new_prop; state.new_prop = hwloc__nolibxml_export_new_prop;
state.add_content = hwloc__nolibxml_export_add_content; state.add_content = hwloc__nolibxml_export_add_content;
state.end_object = hwloc__nolibxml_export_end_object; state.end_object = hwloc__nolibxml_export_end_object;
state.global = edata;
ndata->indent = 0; ndata->indent = 0;
ndata->written = 0; ndata->written = 0;
@ -666,10 +705,12 @@ hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int
ndata->has_content = 0; ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining, res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topology SYSTEM \"hwloc.dtd\">\n"); "<!DOCTYPE topology SYSTEM \"%s\">\n", v1export ? "hwloc.dtd" : "hwloc2.dtd");
hwloc__nolibxml_export_update_buffer(ndata, res); hwloc__nolibxml_export_update_buffer(ndata, res);
hwloc__nolibxml_export_new_child(&state, &childstate, "topology"); hwloc__nolibxml_export_new_child(&state, &childstate, "topology");
if (!(flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1))
hwloc__nolibxml_export_new_prop(&childstate, "version", "2.0");
hwloc__xml_export_topology (&childstate, topology, flags); hwloc__xml_export_topology (&childstate, topology, flags);
hwloc__nolibxml_export_end_object(&childstate, "topology"); hwloc__nolibxml_export_end_object(&childstate, "topology");
@ -677,7 +718,8 @@ hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int
} }
static int static int
hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buflenp, unsigned long flags) hwloc_nolibxml_export_buffer(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
char **bufferp, int *buflenp, unsigned long flags)
{ {
char *buffer; char *buffer;
size_t bufferlen, res; size_t bufferlen, res;
@ -686,7 +728,7 @@ hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buf
buffer = malloc(bufferlen); buffer = malloc(bufferlen);
if (!buffer) if (!buffer)
return -1; return -1;
res = hwloc___nolibxml_prepare_export(topology, buffer, (int)bufferlen, flags); res = hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)bufferlen, flags);
if (res > bufferlen) { if (res > bufferlen) {
char *tmp = realloc(buffer, res); char *tmp = realloc(buffer, res);
@ -695,7 +737,7 @@ hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buf
return -1; return -1;
} }
buffer = tmp; buffer = tmp;
hwloc___nolibxml_prepare_export(topology, buffer, (int)res, flags); hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)res, flags);
} }
*bufferp = buffer; *bufferp = buffer;
@ -704,14 +746,15 @@ hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buf
} }
static int static int
hwloc_nolibxml_export_file(hwloc_topology_t topology, const char *filename, unsigned long flags) hwloc_nolibxml_export_file(hwloc_topology_t topology, struct hwloc__xml_export_data_s *edata,
const char *filename, unsigned long flags)
{ {
FILE *file; FILE *file;
char *buffer; char *buffer;
int bufferlen; int bufferlen;
int ret; int ret;
ret = hwloc_nolibxml_export_buffer(topology, &buffer, &bufferlen, flags); ret = hwloc_nolibxml_export_buffer(topology, edata, &buffer, &bufferlen, flags);
if (ret < 0) if (ret < 0)
return -1; return -1;
@ -747,7 +790,7 @@ hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff, const char *ref
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data; hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
int res; int res;
assert(sizeof(*ndata) <= sizeof(state.data)); HWLOC_BUILD_ASSERT(sizeof(*ndata) <= sizeof(state.data));
state.new_child = hwloc__nolibxml_export_new_child; state.new_child = hwloc__nolibxml_export_new_child;
state.new_prop = hwloc__nolibxml_export_new_prop; state.new_prop = hwloc__nolibxml_export_new_prop;
@ -763,8 +806,8 @@ hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff, const char *ref
ndata->has_content = 0; ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining, res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topologydiff SYSTEM \"hwloc.dtd\">\n"); "<!DOCTYPE topologydiff SYSTEM \"hwloc2-diff.dtd\">\n");
hwloc__nolibxml_export_update_buffer(ndata, res); hwloc__nolibxml_export_update_buffer(ndata, res);
hwloc__nolibxml_export_new_child(&state, &childstate, "topologydiff"); hwloc__nolibxml_export_new_child(&state, &childstate, "topologydiff");
if (refname) if (refname)

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux * Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -18,14 +18,20 @@
int int
hwloc_get_type_depth (struct hwloc_topology *topology, hwloc_obj_type_t type) hwloc_get_type_depth (struct hwloc_topology *topology, hwloc_obj_type_t type)
{ {
return topology->type_depth[type]; HWLOC_BUILD_ASSERT(HWLOC_OBJ_TYPE_MIN == 0);
if ((unsigned) type >= HWLOC_OBJ_TYPE_MAX)
return HWLOC_TYPE_DEPTH_UNKNOWN;
else
return topology->type_depth[type];
} }
hwloc_obj_type_t hwloc_obj_type_t
hwloc_get_depth_type (hwloc_topology_t topology, unsigned depth) hwloc_get_depth_type (hwloc_topology_t topology, int depth)
{ {
if (depth >= topology->nb_levels) if ((unsigned)depth >= topology->nb_levels)
switch (depth) { switch (depth) {
case HWLOC_TYPE_DEPTH_NUMANODE:
return HWLOC_OBJ_NUMANODE;
case HWLOC_TYPE_DEPTH_BRIDGE: case HWLOC_TYPE_DEPTH_BRIDGE:
return HWLOC_OBJ_BRIDGE; return HWLOC_OBJ_BRIDGE;
case HWLOC_TYPE_DEPTH_PCI_DEVICE: case HWLOC_TYPE_DEPTH_PCI_DEVICE:
@ -40,10 +46,35 @@ hwloc_get_depth_type (hwloc_topology_t topology, unsigned depth)
return topology->levels[depth][0]->type; return topology->levels[depth][0]->type;
} }
unsigned int
hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, unsigned depth) hwloc_get_memory_parents_depth (hwloc_topology_t topology)
{ {
if (depth >= topology->nb_levels) { int depth = HWLOC_TYPE_DEPTH_UNKNOWN;
/* memory leaves are always NUMA nodes for now, no need to check parents of other memory types */
hwloc_obj_t numa = hwloc_get_obj_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE, 0);
assert(numa);
while (numa) {
hwloc_obj_t parent = numa->parent;
/* walk-up the memory hierarchy */
while (hwloc__obj_type_is_memory(parent->type))
parent = parent->parent;
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
depth = parent->depth;
else if (depth != parent->depth)
return HWLOC_TYPE_DEPTH_MULTIPLE;
numa = numa->next_cousin;
}
assert(depth >= 0);
return depth;
}
unsigned
hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, int depth)
{
if ((unsigned)depth >= topology->nb_levels) {
unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth); unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth);
if (l < HWLOC_NR_SLEVELS) if (l < HWLOC_NR_SLEVELS)
return topology->slevels[l].nbobjs; return topology->slevels[l].nbobjs;
@ -54,9 +85,9 @@ hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, unsigned depth)
} }
struct hwloc_obj * struct hwloc_obj *
hwloc_get_obj_by_depth (struct hwloc_topology *topology, unsigned depth, unsigned idx) hwloc_get_obj_by_depth (struct hwloc_topology *topology, int depth, unsigned idx)
{ {
if (depth >= topology->nb_levels) { if ((unsigned)depth >= topology->nb_levels) {
unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth); unsigned l = HWLOC_SLEVEL_FROM_DEPTH(depth);
if (l < HWLOC_NR_SLEVELS) if (l < HWLOC_NR_SLEVELS)
return idx < topology->slevels[l].nbobjs ? topology->slevels[l].objs[idx] : NULL; return idx < topology->slevels[l].nbobjs ? topology->slevels[l].objs[idx] : NULL;
@ -68,10 +99,46 @@ hwloc_get_obj_by_depth (struct hwloc_topology *topology, unsigned depth, unsigne
return topology->levels[depth][idx]; return topology->levels[depth][idx];
} }
int
hwloc_obj_type_is_normal(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_normal(type);
}
int
hwloc_obj_type_is_memory(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_memory(type);
}
int
hwloc_obj_type_is_io(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_io(type);
}
int
hwloc_obj_type_is_cache(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_cache(type);
}
int
hwloc_obj_type_is_dcache(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_dcache(type);
}
int
hwloc_obj_type_is_icache(hwloc_obj_type_t type)
{
return hwloc__obj_type_is_icache(type);
}
unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_obj *src, struct hwloc_obj **objs, unsigned max) unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_obj *src, struct hwloc_obj **objs, unsigned max)
{ {
struct hwloc_obj *parent, *nextparent, **src_objs; struct hwloc_obj *parent, *nextparent, **src_objs;
int i,src_nbobjects; unsigned i,src_nbobjects;
unsigned stored = 0; unsigned stored = 0;
if (!src->cpuset) if (!src->cpuset)
@ -85,19 +152,19 @@ unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_o
while (1) { while (1) {
nextparent = parent->parent; nextparent = parent->parent;
if (!nextparent) if (!nextparent)
goto out; goto out;
if (!hwloc_bitmap_isequal(parent->cpuset, nextparent->cpuset)) if (!hwloc_bitmap_isequal(parent->cpuset, nextparent->cpuset))
break; break;
parent = nextparent; parent = nextparent;
} }
/* traverse src's objects and find those that are in nextparent and were not in parent */ /* traverse src's objects and find those that are in nextparent and were not in parent */
for(i=0; i<src_nbobjects; i++) { for(i=0; i<src_nbobjects; i++) {
if (hwloc_bitmap_isincluded(src_objs[i]->cpuset, nextparent->cpuset) if (hwloc_bitmap_isincluded(src_objs[i]->cpuset, nextparent->cpuset)
&& !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) { && !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) {
objs[stored++] = src_objs[i]; objs[stored++] = src_objs[i];
if (stored == max) if (stored == max)
goto out; goto out;
} }
} }
parent = nextparent; parent = nextparent;
@ -109,7 +176,7 @@ unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_o
static int static int
hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bitmap_t set, hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bitmap_t set,
struct hwloc_obj ***res, int *max) struct hwloc_obj ***res, int *max)
{ {
int gotten = 0; int gotten = 0;
unsigned i; unsigned i;
@ -149,7 +216,7 @@ hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bi
int int
hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_const_bitmap_t set, hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_const_bitmap_t set,
struct hwloc_obj **objs, int max) struct hwloc_obj **objs, int max)
{ {
struct hwloc_obj *current = topology->levels[0][0]; struct hwloc_obj *current = topology->levels[0][0];
@ -163,11 +230,10 @@ hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_con
} }
const char * const char *
hwloc_type_name (hwloc_obj_type_t obj) hwloc_obj_type_string (hwloc_obj_type_t obj)
{ {
switch (obj) switch (obj)
{ {
case HWLOC_OBJ_SYSTEM: return "System";
case HWLOC_OBJ_MACHINE: return "Machine"; case HWLOC_OBJ_MACHINE: return "Machine";
case HWLOC_OBJ_MISC: return "Misc"; case HWLOC_OBJ_MISC: return "Misc";
case HWLOC_OBJ_GROUP: return "Group"; case HWLOC_OBJ_GROUP: return "Group";
@ -192,7 +258,7 @@ hwloc_type_name (hwloc_obj_type_t obj)
int int
hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep, hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
union hwloc_obj_attr_u *attrp, size_t attrsize) union hwloc_obj_attr_u *attrp, size_t attrsize)
{ {
hwloc_obj_type_t type = (hwloc_obj_type_t) -1; hwloc_obj_type_t type = (hwloc_obj_type_t) -1;
unsigned depthattr = (unsigned) -1; unsigned depthattr = (unsigned) -1;
@ -206,15 +272,37 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
*/ */
/* types without a custom depth */ /* types without a custom depth */
if (!hwloc_strncasecmp(string, "system", 2)) {
type = HWLOC_OBJ_SYSTEM; /* osdev subtype first to avoid conflicts coproc/core etc */
if (!hwloc_strncasecmp(string, "os", 2)) {
type = HWLOC_OBJ_OS_DEVICE;
} else if (!hwloc_strncasecmp(string, "bloc", 4)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_BLOCK;
} else if (!hwloc_strncasecmp(string, "net", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_NETWORK;
} else if (!hwloc_strncasecmp(string, "openfab", 7)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_OPENFABRICS;
} else if (!hwloc_strncasecmp(string, "dma", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_DMA;
} else if (!hwloc_strncasecmp(string, "gpu", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_GPU;
} else if (!hwloc_strncasecmp(string, "copro", 5)
|| !hwloc_strncasecmp(string, "co-pro", 6)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_COPROC;
} else if (!hwloc_strncasecmp(string, "machine", 2)) { } else if (!hwloc_strncasecmp(string, "machine", 2)) {
type = HWLOC_OBJ_MACHINE; type = HWLOC_OBJ_MACHINE;
} else if (!hwloc_strncasecmp(string, "node", 2) } else if (!hwloc_strncasecmp(string, "node", 2)
|| !hwloc_strncasecmp(string, "numa", 2)) { /* matches node and numanode */ || !hwloc_strncasecmp(string, "numa", 2)) { /* matches node and numanode */
type = HWLOC_OBJ_NUMANODE; type = HWLOC_OBJ_NUMANODE;
} else if (!hwloc_strncasecmp(string, "package", 2) } else if (!hwloc_strncasecmp(string, "package", 2)
|| !hwloc_strncasecmp(string, "socket", 2)) { /* backward compat with v1.10 */ || !hwloc_strncasecmp(string, "socket", 2)) { /* backward compat with v1.10 */
type = HWLOC_OBJ_PACKAGE; type = HWLOC_OBJ_PACKAGE;
} else if (!hwloc_strncasecmp(string, "core", 2)) { } else if (!hwloc_strncasecmp(string, "core", 2)) {
type = HWLOC_OBJ_CORE; type = HWLOC_OBJ_CORE;
@ -235,43 +323,21 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
} else if (!hwloc_strncasecmp(string, "pci", 3)) { } else if (!hwloc_strncasecmp(string, "pci", 3)) {
type = HWLOC_OBJ_PCI_DEVICE; type = HWLOC_OBJ_PCI_DEVICE;
} else if (!hwloc_strncasecmp(string, "os", 2)) {
type = HWLOC_OBJ_OS_DEVICE;
} else if (!hwloc_strncasecmp(string, "bloc", 4)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_BLOCK;
} else if (!hwloc_strncasecmp(string, "net", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_NETWORK;
} else if (!hwloc_strncasecmp(string, "openfab", 7)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_OPENFABRICS;
} else if (!hwloc_strncasecmp(string, "dma", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_DMA;
} else if (!hwloc_strncasecmp(string, "gpu", 3)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_GPU;
} else if (!hwloc_strncasecmp(string, "copro", 5)
|| !hwloc_strncasecmp(string, "co-pro", 6)) {
type = HWLOC_OBJ_OS_DEVICE;
ostype = HWLOC_OBJ_OSDEV_COPROC;
/* types with depthattr */ /* types with depthattr */
} else if ((string[0] == 'l' || string[0] == 'L') && string[1] >= '0' && string[1] <= '9') { } else if ((string[0] == 'l' || string[0] == 'L') && string[1] >= '0' && string[1] <= '9') {
depthattr = strtol(string+1, &end, 10); depthattr = strtol(string+1, &end, 10);
if (*end == 'i') { if (*end == 'i') {
if (depthattr >= 1 && depthattr <= 3) { if (depthattr >= 1 && depthattr <= 3) {
type = HWLOC_OBJ_L1ICACHE + depthattr-1; type = HWLOC_OBJ_L1ICACHE + depthattr-1;
cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION; cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION;
} else } else
return -1; return -1;
} else { } else {
if (depthattr >= 1 && depthattr <= 5) { if (depthattr >= 1 && depthattr <= 5) {
type = HWLOC_OBJ_L1CACHE + depthattr-1; type = HWLOC_OBJ_L1CACHE + depthattr-1;
cachetypeattr = *end == 'd' ? HWLOC_OBJ_CACHE_DATA : HWLOC_OBJ_CACHE_UNIFIED; cachetypeattr = *end == 'd' ? HWLOC_OBJ_CACHE_DATA : HWLOC_OBJ_CACHE_UNIFIED;
} else } else
return -1; return -1;
} }
} else if (!hwloc_strncasecmp(string, "group", 2)) { } else if (!hwloc_strncasecmp(string, "group", 2)) {
@ -279,7 +345,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
type = HWLOC_OBJ_GROUP; type = HWLOC_OBJ_GROUP;
length = strcspn(string, "0123456789"); length = strcspn(string, "0123456789");
if (length <= 5 && !hwloc_strncasecmp(string, "group", length) if (length <= 5 && !hwloc_strncasecmp(string, "group", length)
&& string[length] >= '0' && string[length] <= '9') { && string[length] >= '0' && string[length] <= '9') {
depthattr = strtol(string+length, &end, 10); depthattr = strtol(string+length, &end, 10);
} }
@ -288,7 +354,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
*typep = type; *typep = type;
if (attrp) { if (attrp) {
if (hwloc_obj_type_is_cache(type) && attrsize >= sizeof(attrp->cache)) { if (hwloc__obj_type_is_cache(type) && attrsize >= sizeof(attrp->cache)) {
attrp->cache.depth = depthattr; attrp->cache.depth = depthattr;
attrp->cache.type = cachetypeattr; attrp->cache.type = cachetypeattr;
} else if (type == HWLOC_OBJ_GROUP && attrsize >= sizeof(attrp->group)) { } else if (type == HWLOC_OBJ_GROUP && attrsize >= sizeof(attrp->group)) {
@ -305,7 +371,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
int int
hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep, hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
hwloc_topology_t topology, int *depthp) hwloc_topology_t topology, int *depthp)
{ {
union hwloc_obj_attr_u attr; union hwloc_obj_attr_u attr;
hwloc_obj_type_t type; hwloc_obj_type_t type;
@ -324,16 +390,16 @@ hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
depth = HWLOC_TYPE_DEPTH_UNKNOWN; depth = HWLOC_TYPE_DEPTH_UNKNOWN;
for(l=0; l<topology->nb_levels; l++) { for(l=0; l<topology->nb_levels; l++) {
if (topology->levels[l][0]->type == HWLOC_OBJ_GROUP if (topology->levels[l][0]->type == HWLOC_OBJ_GROUP
&& topology->levels[l][0]->attr->group.depth == attr.group.depth) { && topology->levels[l][0]->attr->group.depth == attr.group.depth) {
depth = l; depth = (int)l;
break; break;
} }
} }
} }
if (typep) if (typep)
*typep = type; *typep = type;
*depthp = (unsigned) depth; *depthp = depth;
return 0; return 0;
} }
@ -353,13 +419,12 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
hwloc_obj_type_t type = obj->type; hwloc_obj_type_t type = obj->type;
switch (type) { switch (type) {
case HWLOC_OBJ_MISC: case HWLOC_OBJ_MISC:
case HWLOC_OBJ_SYSTEM:
case HWLOC_OBJ_MACHINE: case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_NUMANODE: case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_PACKAGE: case HWLOC_OBJ_PACKAGE:
case HWLOC_OBJ_CORE: case HWLOC_OBJ_CORE:
case HWLOC_OBJ_PU: case HWLOC_OBJ_PU:
return hwloc_snprintf(string, size, "%s", hwloc_type_name(type)); return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
case HWLOC_OBJ_L1CACHE: case HWLOC_OBJ_L1CACHE:
case HWLOC_OBJ_L2CACHE: case HWLOC_OBJ_L2CACHE:
case HWLOC_OBJ_L3CACHE: case HWLOC_OBJ_L3CACHE:
@ -369,13 +434,13 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
case HWLOC_OBJ_L2ICACHE: case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE: case HWLOC_OBJ_L3ICACHE:
return hwloc_snprintf(string, size, "L%u%s%s", obj->attr->cache.depth, return hwloc_snprintf(string, size, "L%u%s%s", obj->attr->cache.depth,
hwloc_obj_cache_type_letter(obj->attr->cache.type), hwloc_obj_cache_type_letter(obj->attr->cache.type),
verbose ? "Cache" : ""); verbose ? "Cache" : "");
case HWLOC_OBJ_GROUP: case HWLOC_OBJ_GROUP:
if (obj->attr->group.depth != (unsigned) -1) if (obj->attr->group.depth != (unsigned) -1)
return hwloc_snprintf(string, size, "%s%u", hwloc_type_name(type), obj->attr->group.depth); return hwloc_snprintf(string, size, "%s%u", hwloc_obj_type_string(type), obj->attr->group.depth);
else else
return hwloc_snprintf(string, size, "%s", hwloc_type_name(type)); return hwloc_snprintf(string, size, "%s", hwloc_obj_type_string(type));
case HWLOC_OBJ_BRIDGE: case HWLOC_OBJ_BRIDGE:
return snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge"); return snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge");
case HWLOC_OBJ_PCI_DEVICE: case HWLOC_OBJ_PCI_DEVICE:
@ -390,7 +455,7 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
case HWLOC_OBJ_OSDEV_COPROC: return hwloc_snprintf(string, size, verbose ? "Co-Processor" : "CoProc"); case HWLOC_OBJ_OSDEV_COPROC: return hwloc_snprintf(string, size, verbose ? "Co-Processor" : "CoProc");
default: default:
if (size > 0) if (size > 0)
*string = '\0'; *string = '\0';
return 0; return 0;
} }
break; break;
@ -417,25 +482,25 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
/* print memory attributes */ /* print memory attributes */
res = 0; res = 0;
if (verbose) { if (verbose) {
if (obj->memory.local_memory) if (obj->type == HWLOC_OBJ_NUMANODE && obj->attr->numanode.local_memory)
res = hwloc_snprintf(tmp, tmplen, "%slocal=%lu%s%stotal=%lu%s", res = hwloc_snprintf(tmp, tmplen, "%slocal=%lu%s%stotal=%lu%s",
prefix, prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.local_memory, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose), hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose),
separator, separator,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.local_memory, verbose)); hwloc_memory_size_printf_unit(obj->total_memory, verbose));
else if (obj->memory.total_memory) else if (obj->total_memory)
res = hwloc_snprintf(tmp, tmplen, "%stotal=%lu%s", res = hwloc_snprintf(tmp, tmplen, "%stotal=%lu%s",
prefix, prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose)); hwloc_memory_size_printf_unit(obj->total_memory, verbose));
} else { } else {
if (obj->memory.local_memory) if (obj->type == HWLOC_OBJ_NUMANODE && obj->attr->numanode.local_memory)
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s", res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
prefix, prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.local_memory, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.local_memory, verbose)); hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose));
} }
if (res < 0) if (res < 0)
return -1; return -1;
@ -461,22 +526,22 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (verbose) { if (verbose) {
char assoc[32]; char assoc[32];
if (obj->attr->cache.associativity == -1) if (obj->attr->cache.associativity == -1)
snprintf(assoc, sizeof(assoc), "%sfully-associative", separator); snprintf(assoc, sizeof(assoc), "%sfully-associative", separator);
else if (obj->attr->cache.associativity == 0) else if (obj->attr->cache.associativity == 0)
*assoc = '\0'; *assoc = '\0';
else else
snprintf(assoc, sizeof(assoc), "%sways=%d", separator, obj->attr->cache.associativity); snprintf(assoc, sizeof(assoc), "%sways=%d", separator, obj->attr->cache.associativity);
res = hwloc_snprintf(tmp, tmplen, "%ssize=%lu%s%slinesize=%u%s", res = hwloc_snprintf(tmp, tmplen, "%ssize=%lu%s%slinesize=%u%s",
prefix, prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose), hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose),
separator, obj->attr->cache.linesize, separator, obj->attr->cache.linesize,
assoc); assoc);
} else } else
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s", res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
prefix, prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose), (unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose)); hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose));
break; break;
case HWLOC_OBJ_BRIDGE: case HWLOC_OBJ_BRIDGE:
if (verbose) { if (verbose) {
@ -486,19 +551,19 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
char linkspeed[64]= ""; char linkspeed[64]= "";
if (obj->attr->pcidev.linkspeed) if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed); snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
snprintf(up, sizeof(up), "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s", snprintf(up, sizeof(up), "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator, obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator, obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed); obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
} else } else
*up = '\0'; *up = '\0';
/* downstream is_PCI */ /* downstream is_PCI */
snprintf(down, sizeof(down), "buses=%04x:[%02x-%02x]", snprintf(down, sizeof(down), "buses=%04x:[%02x-%02x]",
obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus); obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus);
if (*up) if (*up)
res = snprintf(string, size, "%s%s%s", up, separator, down); res = snprintf(string, size, "%s%s%s", up, separator, down);
else else
res = snprintf(string, size, "%s", down); res = snprintf(string, size, "%s", down);
} }
break; break;
case HWLOC_OBJ_PCI_DEVICE: case HWLOC_OBJ_PCI_DEVICE:
@ -507,9 +572,9 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (obj->attr->pcidev.linkspeed) if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed); snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
res = snprintf(string, size, "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s", res = snprintf(string, size, "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator, obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator, obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed); obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
} }
break; break;
default: default:
@ -529,14 +594,12 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (verbose) { if (verbose) {
unsigned i; unsigned i;
for(i=0; i<obj->infos_count; i++) { for(i=0; i<obj->infos_count; i++) {
if (strchr(obj->infos[i].value, ' ')) struct hwloc_info_s *info = &obj->infos[i];
res = hwloc_snprintf(tmp, tmplen, "%s%s=\"%s\"", const char *quote = strchr(info->value, ' ') ? "\"" : "";
prefix, res = hwloc_snprintf(tmp, tmplen, "%s%s=%s%s%s",
obj->infos[i].name, obj->infos[i].value); prefix,
else info->name,
res = hwloc_snprintf(tmp, tmplen, "%s%s=%s", quote, info->value, quote);
prefix,
obj->infos[i].name, obj->infos[i].value);
if (res < 0) if (res < 0)
return -1; return -1;
ret += res; ret += res;

Просмотреть файл

@ -23,7 +23,6 @@ include_hwloc_HEADERS = \
hwloc/shmem.h \ hwloc/shmem.h \
hwloc/distances.h \ hwloc/distances.h \
hwloc/export.h \ hwloc/export.h \
hwloc/myriexpress.h \
hwloc/openfabrics-verbs.h \ hwloc/openfabrics-verbs.h \
hwloc/opencl.h \ hwloc/opencl.h \
hwloc/cuda.h \ hwloc/cuda.h \

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,6 +1,6 @@
/* -*- c -*- /* -*- c -*-
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -67,9 +67,16 @@
#define GCC_ABOVE_3_3 0 #define GCC_ABOVE_3_3 0
#endif #endif
#if !defined(__cplusplus) && \
(__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
#define GCC_ABOVE_3_4 1
#else
#define GCC_ABOVE_3_4 0
#endif
/* Maybe before gcc 2.95 too */ /* Maybe before gcc 2.95 too */
#ifdef HWLOC_HAVE_ATTRIBUTE_UNUSED #ifdef HWLOC_HAVE_ATTRIBUTE_UNUSED
#define __HWLOC_HAVE_ATTRIBUTE_UNUSED HWLOC_HAVE_ATTRIBUTE_UNUSED #define __HWLOC_HAVE_ATTRIBUTE_UNUSED HWLOC_HAVE_ATTRIBUTE_UNUSED
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_UNUSED (GXX_ABOVE_3_4 || GCC_ABOVE_2_95) # define __HWLOC_HAVE_ATTRIBUTE_UNUSED (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)
#else #else
@ -82,7 +89,7 @@
#endif #endif
#ifdef HWLOC_HAVE_ATTRIBUTE_MALLOC #ifdef HWLOC_HAVE_ATTRIBUTE_MALLOC
#define __HWLOC_HAVE_ATTRIBUTE_MALLOC HWLOC_HAVE_ATTRIBUTE_MALLOC #define __HWLOC_HAVE_ATTRIBUTE_MALLOC HWLOC_HAVE_ATTRIBUTE_MALLOC
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_MALLOC (GXX_ABOVE_3_4 || GCC_ABOVE_2_96) # define __HWLOC_HAVE_ATTRIBUTE_MALLOC (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)
#else #else
@ -95,7 +102,7 @@
#endif #endif
#ifdef HWLOC_HAVE_ATTRIBUTE_CONST #ifdef HWLOC_HAVE_ATTRIBUTE_CONST
#define __HWLOC_HAVE_ATTRIBUTE_CONST HWLOC_HAVE_ATTRIBUTE_CONST #define __HWLOC_HAVE_ATTRIBUTE_CONST HWLOC_HAVE_ATTRIBUTE_CONST
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_CONST (GXX_ABOVE_3_4 || GCC_ABOVE_2_95) # define __HWLOC_HAVE_ATTRIBUTE_CONST (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)
#else #else
@ -108,7 +115,7 @@
#endif #endif
#ifdef HWLOC_HAVE_ATTRIBUTE_PURE #ifdef HWLOC_HAVE_ATTRIBUTE_PURE
#define __HWLOC_HAVE_ATTRIBUTE_PURE HWLOC_HAVE_ATTRIBUTE_PURE #define __HWLOC_HAVE_ATTRIBUTE_PURE HWLOC_HAVE_ATTRIBUTE_PURE
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_PURE (GXX_ABOVE_3_4 || GCC_ABOVE_2_96) # define __HWLOC_HAVE_ATTRIBUTE_PURE (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)
#else #else
@ -121,7 +128,7 @@
#endif #endif
#ifdef HWLOC_HAVE_ATTRIBUTE_DEPRECATED #ifdef HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED #define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#elif defined(__GNUC__) #elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED (GXX_ABOVE_3_4 || GCC_ABOVE_3_3) # define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED (GXX_ABOVE_3_4 || GCC_ABOVE_3_3)
#else #else
@ -146,6 +153,19 @@
# define __hwloc_attribute_may_alias # define __hwloc_attribute_may_alias
#endif #endif
#ifdef HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT
#define __HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT (GXX_ABOVE_3_4 || GCC_ABOVE_3_4)
#else
# define __HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT 0
#endif
#if __HWLOC_HAVE_ATTRIBUTE_WARN_UNUSED_RESULT
# define __hwloc_attribute_warn_unused_result __attribute__((__warn_unused_result__))
#else
# define __hwloc_attribute_warn_unused_result
#endif
#ifdef HWLOC_C_HAVE_VISIBILITY #ifdef HWLOC_C_HAVE_VISIBILITY
# if HWLOC_C_HAVE_VISIBILITY # if HWLOC_C_HAVE_VISIBILITY
# define HWLOC_DECLSPEC __attribute__((__visibility__("default"))) # define HWLOC_DECLSPEC __attribute__((__visibility__("default")))

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -37,6 +37,10 @@ extern "C" {
* A bitmap may be of infinite size (all bits are set after some point). * A bitmap may be of infinite size (all bits are set after some point).
* A bitmap may even be full if all bits are set. * A bitmap may even be full if all bits are set.
* *
* \note Most functions below return an int that may be negative in case of
* error. The usual error case would be an internal failure to realloc/extend
* the storage of the bitmap (\p errno would be set to \c ENOMEM).
*
* \note Several examples of using the bitmap API are available under the * \note Several examples of using the bitmap API are available under the
* doc/examples/ directory in the source tree. * doc/examples/ directory in the source tree.
* Regression tests such as tests/hwloc/hwloc_bitmap*.c also make intensive use * Regression tests such as tests/hwloc/hwloc_bitmap*.c also make intensive use
@ -82,7 +86,7 @@ HWLOC_DECLSPEC void hwloc_bitmap_free(hwloc_bitmap_t bitmap);
HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc; HWLOC_DECLSPEC hwloc_bitmap_t hwloc_bitmap_dup(hwloc_const_bitmap_t bitmap) __hwloc_attribute_malloc;
/** \brief Copy the contents of bitmap \p src into the already allocated bitmap \p dst */ /** \brief Copy the contents of bitmap \p src into the already allocated bitmap \p dst */
HWLOC_DECLSPEC void hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src); HWLOC_DECLSPEC int hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t src);
/* /*
@ -101,6 +105,8 @@ HWLOC_DECLSPEC void hwloc_bitmap_copy(hwloc_bitmap_t dst, hwloc_const_bitmap_t s
HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated string. /** \brief Stringify a bitmap into a newly allocated string.
*
* \return -1 on error.
*/ */
HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
@ -124,6 +130,8 @@ HWLOC_DECLSPEC int hwloc_bitmap_sscanf(hwloc_bitmap_t bitmap, const char * __hwl
HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_list_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated list string. /** \brief Stringify a bitmap into a newly allocated list string.
*
* \return -1 on error.
*/ */
HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_list_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
@ -146,6 +154,8 @@ HWLOC_DECLSPEC int hwloc_bitmap_list_sscanf(hwloc_bitmap_t bitmap, const char *
HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_taskset_snprintf(char * __hwloc_restrict buf, size_t buflen, hwloc_const_bitmap_t bitmap);
/** \brief Stringify a bitmap into a newly allocated taskset-specific string. /** \brief Stringify a bitmap into a newly allocated taskset-specific string.
*
* \return -1 on error.
*/ */
HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_taskset_asprintf(char ** strp, hwloc_const_bitmap_t bitmap);
@ -165,16 +175,16 @@ HWLOC_DECLSPEC void hwloc_bitmap_zero(hwloc_bitmap_t bitmap);
HWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap); HWLOC_DECLSPEC void hwloc_bitmap_fill(hwloc_bitmap_t bitmap);
/** \brief Empty the bitmap \p bitmap and add bit \p id */ /** \brief Empty the bitmap \p bitmap and add bit \p id */
HWLOC_DECLSPEC void hwloc_bitmap_only(hwloc_bitmap_t bitmap, unsigned id); HWLOC_DECLSPEC int hwloc_bitmap_only(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Fill the bitmap \p and clear the index \p id */ /** \brief Fill the bitmap \p and clear the index \p id */
HWLOC_DECLSPEC void hwloc_bitmap_allbut(hwloc_bitmap_t bitmap, unsigned id); HWLOC_DECLSPEC int hwloc_bitmap_allbut(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Setup bitmap \p bitmap from unsigned long \p mask */ /** \brief Setup bitmap \p bitmap from unsigned long \p mask */
HWLOC_DECLSPEC void hwloc_bitmap_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask); HWLOC_DECLSPEC int hwloc_bitmap_from_ulong(hwloc_bitmap_t bitmap, unsigned long mask);
/** \brief Setup bitmap \p bitmap from unsigned long \p mask used as \p i -th subset */ /** \brief Setup bitmap \p bitmap from unsigned long \p mask used as \p i -th subset */
HWLOC_DECLSPEC void hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask); HWLOC_DECLSPEC int hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
/* /*
@ -182,25 +192,25 @@ HWLOC_DECLSPEC void hwloc_bitmap_from_ith_ulong(hwloc_bitmap_t bitmap, unsigned
*/ */
/** \brief Add index \p id in bitmap \p bitmap */ /** \brief Add index \p id in bitmap \p bitmap */
HWLOC_DECLSPEC void hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id); HWLOC_DECLSPEC int hwloc_bitmap_set(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Add indexes from \p begin to \p end in bitmap \p bitmap. /** \brief Add indexes from \p begin to \p end in bitmap \p bitmap.
* *
* If \p end is \c -1, the range is infinite. * If \p end is \c -1, the range is infinite.
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_set_range(hwloc_bitmap_t bitmap, unsigned begin, int end); HWLOC_DECLSPEC int hwloc_bitmap_set_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
/** \brief Replace \p i -th subset of bitmap \p bitmap with unsigned long \p mask */ /** \brief Replace \p i -th subset of bitmap \p bitmap with unsigned long \p mask */
HWLOC_DECLSPEC void hwloc_bitmap_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask); HWLOC_DECLSPEC int hwloc_bitmap_set_ith_ulong(hwloc_bitmap_t bitmap, unsigned i, unsigned long mask);
/** \brief Remove index \p id from bitmap \p bitmap */ /** \brief Remove index \p id from bitmap \p bitmap */
HWLOC_DECLSPEC void hwloc_bitmap_clr(hwloc_bitmap_t bitmap, unsigned id); HWLOC_DECLSPEC int hwloc_bitmap_clr(hwloc_bitmap_t bitmap, unsigned id);
/** \brief Remove indexes from \p begin to \p end in bitmap \p bitmap. /** \brief Remove indexes from \p begin to \p end in bitmap \p bitmap.
* *
* If \p end is \c -1, the range is infinite. * If \p end is \c -1, the range is infinite.
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin, int end); HWLOC_DECLSPEC int hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin, int end);
/** \brief Keep a single index among those set in bitmap \p bitmap /** \brief Keep a single index among those set in bitmap \p bitmap
* *
@ -208,7 +218,7 @@ HWLOC_DECLSPEC void hwloc_bitmap_clr_range(hwloc_bitmap_t bitmap, unsigned begin
* have a chance of migrating between multiple logical CPUs * have a chance of migrating between multiple logical CPUs
* in the original mask. * in the original mask.
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_singlify(hwloc_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_singlify(hwloc_bitmap_t bitmap);
/* /*
@ -262,6 +272,26 @@ HWLOC_DECLSPEC int hwloc_bitmap_last(hwloc_const_bitmap_t bitmap) __hwloc_attrib
*/ */
HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure; HWLOC_DECLSPEC int hwloc_bitmap_weight(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the first unset index (least significant bit) in bitmap \p bitmap
*
* \return -1 if no index is unset in \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_first_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Compute the next unset index in bitmap \p bitmap which is after index \p prev
*
* If \p prev is -1, the first unset index is returned.
*
* \return -1 if no index with higher index is unset in \p bitmap.
*/
HWLOC_DECLSPEC int hwloc_bitmap_next_unset(hwloc_const_bitmap_t bitmap, int prev) __hwloc_attribute_pure;
/** \brief Compute the last unset index (most significant bit) in bitmap \p bitmap
*
* \return -1 if no index is unset in \p bitmap, or if \p bitmap is infinitely set.
*/
HWLOC_DECLSPEC int hwloc_bitmap_last_unset(hwloc_const_bitmap_t bitmap) __hwloc_attribute_pure;
/** \brief Loop macro iterating on bitmap \p bitmap /** \brief Loop macro iterating on bitmap \p bitmap
* *
* The loop must start with hwloc_bitmap_foreach_begin() and end * The loop must start with hwloc_bitmap_foreach_begin() and end
@ -291,7 +321,7 @@ do { \
* \sa hwloc_bitmap_foreach_begin() * \sa hwloc_bitmap_foreach_begin()
* \hideinitializer * \hideinitializer
*/ */
#define hwloc_bitmap_foreach_end() \ #define hwloc_bitmap_foreach_end() \
} \ } \
} while (0) } while (0)
@ -304,31 +334,31 @@ do { \
* *
* \p res can be the same as \p bitmap1 or \p bitmap2 * \p res can be the same as \p bitmap1 or \p bitmap2
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_or (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2); HWLOC_DECLSPEC int hwloc_bitmap_or (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief And bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res /** \brief And bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
* *
* \p res can be the same as \p bitmap1 or \p bitmap2 * \p res can be the same as \p bitmap1 or \p bitmap2
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_and (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2); HWLOC_DECLSPEC int hwloc_bitmap_and (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief And bitmap \p bitmap1 and the negation of \p bitmap2 and store the result in bitmap \p res /** \brief And bitmap \p bitmap1 and the negation of \p bitmap2 and store the result in bitmap \p res
* *
* \p res can be the same as \p bitmap1 or \p bitmap2 * \p res can be the same as \p bitmap1 or \p bitmap2
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_andnot (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2); HWLOC_DECLSPEC int hwloc_bitmap_andnot (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief Xor bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res /** \brief Xor bitmaps \p bitmap1 and \p bitmap2 and store the result in bitmap \p res
* *
* \p res can be the same as \p bitmap1 or \p bitmap2 * \p res can be the same as \p bitmap1 or \p bitmap2
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_xor (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2); HWLOC_DECLSPEC int hwloc_bitmap_xor (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap1, hwloc_const_bitmap_t bitmap2);
/** \brief Negate bitmap \p bitmap and store the result in bitmap \p res /** \brief Negate bitmap \p bitmap and store the result in bitmap \p res
* *
* \p res can be the same as \p bitmap * \p res can be the same as \p bitmap
*/ */
HWLOC_DECLSPEC void hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap); HWLOC_DECLSPEC int hwloc_bitmap_not (hwloc_bitmap_t res, hwloc_const_bitmap_t bitmap);
/* /*

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2010-2016 Inria. All rights reserved. * Copyright © 2010-2017 Inria. All rights reserved.
* Copyright © 2010-2011 Université Bordeaux * Copyright © 2010-2011 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -45,7 +45,7 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, int *domain, int *bus, int *dev) CUdevice cudevice, int *domain, int *bus, int *dev)
{ {
CUresult cres; CUresult cres;
@ -90,7 +90,7 @@ hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, hwloc_cpuset_t set) CUdevice cudevice, hwloc_cpuset_t set)
{ {
#ifdef HWLOC_LINUX_SYS #ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */ /* If we're on Linux, use the sysfs mechanism to get the local cpus */
@ -144,7 +144,7 @@ hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
* CUDA device \p cudevice. Return NULL if there is none. * CUDA device \p cudevice. Return NULL if there is none.
* *
* Topology \p topology and device \p cudevice must match the local machine. * Topology \p topology and device \p cudevice must match the local machine.
* I/O devices detection and the NVML component must be enabled in the topology. * I/O devices detection and the CUDA component must be enabled in the topology.
* If not, the locality of the object may still be found using * If not, the locality of the object may still be found using
* hwloc_cuda_get_device_cpuset(). * hwloc_cuda_get_device_cpuset().
* *
@ -156,28 +156,28 @@ hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice) hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
int domain, bus, dev; int domain, bus, dev;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev)) if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL; return NULL;
osdev = NULL; osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent; hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "cuda", 4)) if (strncmp(osdev->name, "cuda", 4))
continue; continue;
if (pcidev if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE && pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& (int) pcidev->attr->pcidev.domain == domain && (int) pcidev->attr->pcidev.domain == domain
&& (int) pcidev->attr->pcidev.bus == bus && (int) pcidev->attr->pcidev.bus == bus
&& (int) pcidev->attr->pcidev.dev == dev && (int) pcidev->attr->pcidev.dev == dev
&& pcidev->attr->pcidev.func == 0) && pcidev->attr->pcidev.func == 0)
return osdev; return osdev;
/* if PCI are filtered out, we need a info attr to match on */ /* if PCI are filtered out, we need a info attr to match on */
} }
return NULL; return NULL;
} }
/** \brief Get the hwloc OS device object corresponding to the /** \brief Get the hwloc OS device object corresponding to the
@ -198,15 +198,15 @@ hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name && osdev->name
&& !strncmp("cuda", osdev->name, 4) && !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx) && atoi(osdev->name + 4) == (int) idx)
return osdev; return osdev;
} }
return NULL; return NULL;
} }
/** @} */ /** @} */

Просмотреть файл

@ -46,7 +46,7 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
int idx, int *domain, int *bus, int *dev) int idx, int *domain, int *bus, int *dev)
{ {
cudaError_t cerr; cudaError_t cerr;
struct cudaDeviceProp prop; struct cudaDeviceProp prop;
@ -87,7 +87,7 @@ hwloc_cudart_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unus
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_cudart_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
int idx, hwloc_cpuset_t set) int idx, hwloc_cpuset_t set)
{ {
#ifdef HWLOC_LINUX_SYS #ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */ /* If we're on Linux, use the sysfs mechanism to get the local cpus */
@ -155,15 +155,15 @@ hwloc_cudart_get_device_pcidev(hwloc_topology_t topology, int idx)
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) hwloc_cudart_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name && osdev->name
&& !strncmp("cuda", osdev->name, 4) && !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx) && atoi(osdev->name + 4) == (int) idx)
return osdev; return osdev;
} }
return NULL; return NULL;
} }
/** @} */ /** @} */

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -21,6 +21,8 @@
extern "C" { extern "C" {
#endif #endif
/* backward compat with v1.11 before System removal */
#define HWLOC_OBJ_SYSTEM HWLOC_OBJ_MACHINE
/* backward compat with v1.10 before Socket->Package renaming */ /* backward compat with v1.10 before Socket->Package renaming */
#define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE #define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE
/* backward compat with v1.10 before Node->NUMANode clarification */ /* backward compat with v1.10 before Node->NUMANode clarification */
@ -64,18 +66,6 @@ hwloc_obj_cpuset_snprintf(char *str, size_t size, size_t nobj, struct hwloc_obj
return res; return res;
} }
/** \brief Return a stringified topology object type.
*
* Deprecated by the identical hwloc_type_name()
*/
static __hwloc_inline const char *
hwloc_obj_type_string (hwloc_obj_type_t type) __hwloc_attribute_const; /* not deprecated in early 2.x releases because widely used and prototype unchanged */
static __hwloc_inline const char *
hwloc_obj_type_string (hwloc_obj_type_t type)
{
return hwloc_type_name(type);
}
/** \brief Convert a type string into a type and some attributes. /** \brief Convert a type string into a type and some attributes.
* *
* Deprecated by hwloc_type_sscanf() * Deprecated by hwloc_type_sscanf()
@ -91,12 +81,12 @@ hwloc_obj_type_sscanf(const char *string, hwloc_obj_type_t *typep, int *depthatt
return err; return err;
if (hwloc_obj_type_is_cache(*typep)) { if (hwloc_obj_type_is_cache(*typep)) {
if (depthattrp) if (depthattrp)
*depthattrp = attr.cache.depth; *depthattrp = (int) attr.cache.depth;
if (typeattrp && typeattrsize >= sizeof(hwloc_obj_cache_type_t)) if (typeattrp && typeattrsize >= sizeof(hwloc_obj_cache_type_t))
memcpy(typeattrp, &attr.cache.type, sizeof(hwloc_obj_cache_type_t)); memcpy(typeattrp, &attr.cache.type, sizeof(hwloc_obj_cache_type_t));
} else if (*typep == HWLOC_OBJ_GROUP) { } else if (*typep == HWLOC_OBJ_GROUP) {
if (depthattrp) if (depthattrp)
*depthattrp = attr.group.depth; *depthattrp = (int) attr.group.depth;
} }
return 0; return 0;
} }

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2013-2016 Inria. All rights reserved. * Copyright © 2013-2017 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -136,7 +136,7 @@ typedef union hwloc_topology_diff_u {
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */ hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
union hwloc_topology_diff_u * next; union hwloc_topology_diff_u * next;
/* List of attribute differences for a single object */ /* List of attribute differences for a single object */
unsigned obj_depth; int obj_depth;
unsigned obj_index; unsigned obj_index;
union hwloc_topology_diff_obj_attr_u diff; union hwloc_topology_diff_obj_attr_u diff;
} obj_attr; } obj_attr;
@ -146,7 +146,7 @@ typedef union hwloc_topology_diff_u {
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */ hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_TOO_COMPLEX */
union hwloc_topology_diff_u * next; union hwloc_topology_diff_u * next;
/* Where we had to stop computing the diff in the first topology */ /* Where we had to stop computing the diff in the first topology */
unsigned obj_depth; int obj_depth;
unsigned obj_index; unsigned obj_index;
} too_complex; } too_complex;
} * hwloc_topology_diff_t; } * hwloc_topology_diff_t;

Просмотреть файл

@ -39,18 +39,18 @@ extern "C" {
* possibly provided by the user, as specified in the \p kind attribute. * possibly provided by the user, as specified in the \p kind attribute.
*/ */
struct hwloc_distances_s { struct hwloc_distances_s {
unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */ unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */
hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix. hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix.
* These objects are not in any particular order, * These objects are not in any particular order,
* see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values() * see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values()
* for easy ways to find objects in this array and their corresponding values. * for easy ways to find objects in this array and their corresponding values.
*/ */
unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */ unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */
hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array. hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array.
* *
* Distance from i-th to j-th object is stored in slot i*nbobjs+j. * Distance from i-th to j-th object is stored in slot i*nbobjs+j.
* The meaning of the value depends on the \p kind attribute. * The meaning of the value depends on the \p kind attribute.
*/ */
}; };
/** \brief Kinds of distance matrices. /** \brief Kinds of distance matrices.
@ -114,17 +114,17 @@ enum hwloc_distances_kind_e {
*/ */
HWLOC_DECLSPEC int HWLOC_DECLSPEC int
hwloc_distances_get(hwloc_topology_t topology, hwloc_distances_get(hwloc_topology_t topology,
unsigned *nr, struct hwloc_distances_s **distances, unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags); unsigned long kind, unsigned long flags);
/** \brief Retrieve distance matrices for object at a specific depth in the topology. /** \brief Retrieve distance matrices for object at a specific depth in the topology.
* *
* Identical to hwloc_distances_get() with the additional \p depth filter. * Identical to hwloc_distances_get() with the additional \p depth filter.
*/ */
HWLOC_DECLSPEC int HWLOC_DECLSPEC int
hwloc_distances_get_by_depth(hwloc_topology_t topology, unsigned depth, hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth,
unsigned *nr, struct hwloc_distances_s **distances, unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags); unsigned long kind, unsigned long flags);
/** \brief Retrieve distance matrices for object of a specific type. /** \brief Retrieve distance matrices for object of a specific type.
* *
@ -132,11 +132,11 @@ hwloc_distances_get_by_depth(hwloc_topology_t topology, unsigned depth,
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type, hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
unsigned *nr, struct hwloc_distances_s **distances, unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags) unsigned long kind, unsigned long flags)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth < 0) { if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
*nr = 0; *nr = 0;
return 0; return 0;
} }
@ -178,8 +178,8 @@ hwloc_distances_obj_index(struct hwloc_distances_s *distances, hwloc_obj_t obj)
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_distances_obj_pair_values(struct hwloc_distances_s *distances, hwloc_distances_obj_pair_values(struct hwloc_distances_s *distances,
hwloc_obj_t obj1, hwloc_obj_t obj2, hwloc_obj_t obj1, hwloc_obj_t obj2,
hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1) hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1)
{ {
int i1 = hwloc_distances_obj_index(distances, obj1); int i1 = hwloc_distances_obj_index(distances, obj1);
int i2 = hwloc_distances_obj_index(distances, obj2); int i2 = hwloc_distances_obj_index(distances, obj2);
@ -227,8 +227,8 @@ enum hwloc_distances_add_flag_e {
* Objects must be of the same type. They cannot be of type Group. * Objects must be of the same type. They cannot be of type Group.
*/ */
HWLOC_DECLSPEC int hwloc_distances_add(hwloc_topology_t topology, HWLOC_DECLSPEC int hwloc_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values, unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values,
unsigned long kind, unsigned long flags); unsigned long kind, unsigned long flags);
/** \brief Remove all distance matrices from a topology. /** \brief Remove all distance matrices from a topology.
* *
@ -244,7 +244,7 @@ HWLOC_DECLSPEC int hwloc_distances_remove(hwloc_topology_t topology);
* *
* Identical to hwloc_distances_remove() but only applies to one level of the topology. * Identical to hwloc_distances_remove() but only applies to one level of the topology.
*/ */
HWLOC_DECLSPEC int hwloc_distances_remove_by_depth(hwloc_topology_t topology, unsigned depth); HWLOC_DECLSPEC int hwloc_distances_remove_by_depth(hwloc_topology_t topology, int depth);
/** \brief Remove distance matrices for objects of a specific type in the topology. /** \brief Remove distance matrices for objects of a specific type in the topology.
* *
@ -254,7 +254,7 @@ static __hwloc_inline int
hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type) hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t type)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth < 0) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return 0; return 0;
return hwloc_distances_remove_by_depth(topology, depth); return hwloc_distances_remove_by_depth(topology, depth);
} }

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -34,6 +34,7 @@ extern "C" {
*/ */
enum hwloc_topology_export_xml_flags_e { enum hwloc_topology_export_xml_flags_e {
/** \brief Export XML that is loadable by hwloc v1.x. /** \brief Export XML that is loadable by hwloc v1.x.
* However, the export may miss some details about the topology.
* \hideinitializer * \hideinitializer
*/ */
HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 = (1UL<<0) HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 = (1UL<<0)
@ -43,6 +44,15 @@ enum hwloc_topology_export_xml_flags_e {
* *
* This file may be loaded later through hwloc_topology_set_xml(). * This file may be loaded later through hwloc_topology_set_xml().
* *
* By default, the latest export format is used, which means older hwloc
* releases (e.g. v1.x) will not be able to import it.
* Exporting to v1.x specific XML format is possible using flag
* ::HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 but it may miss some details
* about the topology.
* If there is any chance that the exported file may ever be imported
* back by a process using hwloc 1.x, one should consider detecting
* it at runtime and using the corresponding export format.
*
* \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e. * \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e.
* *
* \return -1 if a failure occured. * \return -1 if a failure occured.
@ -67,6 +77,15 @@ HWLOC_DECLSPEC int hwloc_topology_export_xml(hwloc_topology_t topology, const ch
* *
* This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer(). * This memory buffer may be loaded later through hwloc_topology_set_xmlbuffer().
* *
* By default, the latest export format is used, which means older hwloc
* releases (e.g. v1.x) will not be able to import it.
* Exporting to v1.x specific XML format is possible using flag
* ::HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1 but it may miss some details
* about the topology.
* If there is any chance that the exported buffer may ever be imported
* back by a process using hwloc 1.x, one should consider detecting
* it at runtime and using the corresponding export format.
*
* \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e. * \p flags is a OR'ed set of ::hwloc_topology_export_xml_flags_e.
* *
* \return -1 if a failure occured. * \return -1 if a failure occured.
@ -104,7 +123,7 @@ HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuf
* \note The topology-specific userdata pointer is ignored when exporting to XML. * \note The topology-specific userdata pointer is ignored when exporting to XML.
*/ */
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology, HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj)); void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
/** \brief Export some object userdata to XML /** \brief Export some object userdata to XML
* *
@ -171,7 +190,7 @@ HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topolo
* \note The topology-specific userdata pointer is ignored when importing from XML. * \note The topology-specific userdata pointer is ignored when importing from XML.
*/ */
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology, HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length)); void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
/** @} */ /** @} */
@ -198,7 +217,27 @@ enum hwloc_topology_export_synthetic_flags_e {
* This is required if loading the synthetic description with hwloc < 1.10. * This is required if loading the synthetic description with hwloc < 1.10.
* \hideinitializer * \hideinitializer
*/ */
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS = (1UL<<1) HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS = (1UL<<1),
/** \brief Export the memory hierarchy as expected in hwloc 1.x.
*
* Instead of attaching memory children to levels, export single NUMA node child
* as normal intermediate levels, when possible.
* This is required if loading the synthetic description with hwloc 1.x.
* However this may fail if some objects have multiple local NUMA nodes.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1 = (1UL<<2),
/** \brief Do not export memory information.
*
* Only export the actual hierarchy of normal CPU-side objects and ignore
* where memory is attached.
* This is useful for when the hierarchy of CPUs is what really matters,
* but it behaves as if there was a single machine-wide NUMA node.
* \hideinitializer
*/
HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY = (1UL<<3)
}; };
/** \brief Export the topology as a synthetic string. /** \brief Export the topology as a synthetic string.

Просмотреть файл

@ -52,7 +52,7 @@ extern "C" {
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology, hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,
unsigned port, unsigned device) unsigned port, unsigned device)
{ {
unsigned x = (unsigned) -1, y = (unsigned) -1; unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
@ -63,7 +63,7 @@ hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,
&& port == x && device == y) && port == x && device == y)
return osdev; return osdev;
} }
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
@ -83,7 +83,7 @@ hwloc_gl_get_display_osdev_by_port_device(hwloc_topology_t topology,
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology, hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,
const char *name) const char *name)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
@ -92,7 +92,7 @@ hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,
&& !strcmp(name, osdev->name)) && !strcmp(name, osdev->name))
return osdev; return osdev;
} }
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
@ -109,18 +109,18 @@ hwloc_gl_get_display_osdev_by_name(hwloc_topology_t topology,
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
hwloc_obj_t osdev, hwloc_obj_t osdev,
unsigned *port, unsigned *device) unsigned *port, unsigned *device)
{ {
unsigned x = -1, y = -1; unsigned x = -1, y = -1;
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& sscanf(osdev->name, ":%u.%u", &x, &y) == 2) { && sscanf(osdev->name, ":%u.%u", &x, &y) == 2) {
*port = x; *port = x;
*device = y; *device = y;
return 0; return 0;
} }
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
/** @} */ /** @} */
@ -132,3 +132,4 @@ hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused
#endif /* HWLOC_GL_H */ #endif /* HWLOC_GL_H */

Просмотреть файл

@ -54,7 +54,7 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset, hwloc_cpuset_to_glibc_sched_affinity(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t hwlocset,
cpu_set_t *schedset, size_t schedsetsize) cpu_set_t *schedset, size_t schedsetsize)
{ {
#ifdef CPU_ZERO_S #ifdef CPU_ZERO_S
unsigned cpu; unsigned cpu;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -49,7 +49,7 @@ hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const
hwloc_obj_t child = obj->first_child; hwloc_obj_t child = obj->first_child;
while (child) { while (child) {
if (hwloc_bitmap_intersects(child->cpuset, set)) if (hwloc_bitmap_intersects(child->cpuset, set))
break; break;
child = child->next_sibling; child = child->next_sibling;
} }
if (!child) if (!child)
@ -67,7 +67,7 @@ hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const
* \return the number of objects returned in \p objs. * \return the number of objects returned in \p objs.
*/ */
HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set, HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_t * __hwloc_restrict objs, int max); hwloc_obj_t * __hwloc_restrict objs, int max);
/** \brief Return the next object at depth \p depth included in CPU set \p set. /** \brief Return the next object at depth \p depth included in CPU set \p set.
* *
@ -83,7 +83,7 @@ HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topolo
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
unsigned depth, hwloc_obj_t prev) int depth, hwloc_obj_t prev)
{ {
hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev); hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
if (!next) if (!next)
@ -107,7 +107,7 @@ hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_cons
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, hwloc_obj_t prev) hwloc_obj_type_t type, hwloc_obj_t prev)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -125,10 +125,10 @@ hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
unsigned depth, unsigned idx) __hwloc_attribute_pure; int depth, unsigned idx) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
unsigned depth, unsigned idx) int depth, unsigned idx)
{ {
hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0); hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
unsigned count = 0; unsigned count = 0;
@ -137,7 +137,7 @@ hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpu
while (obj) { while (obj) {
if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) { if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) {
if (count == idx) if (count == idx)
return obj; return obj;
count++; count++;
} }
obj = obj->next_cousin; obj = obj->next_cousin;
@ -159,10 +159,10 @@ hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpu
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure; hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, unsigned idx) hwloc_obj_type_t type, unsigned idx)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -180,10 +180,10 @@ hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpus
*/ */
static __hwloc_inline unsigned static __hwloc_inline unsigned
hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
unsigned depth) __hwloc_attribute_pure; int depth) __hwloc_attribute_pure;
static __hwloc_inline unsigned static __hwloc_inline unsigned
hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpuset_t set,
unsigned depth) int depth)
{ {
hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0); hwloc_obj_t obj = hwloc_get_obj_by_depth (topology, depth, 0);
unsigned count = 0; unsigned count = 0;
@ -211,17 +211,17 @@ hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type) __hwloc_attribute_pure; hwloc_obj_type_t type) __hwloc_attribute_pure;
static __hwloc_inline int static __hwloc_inline int
hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type) hwloc_obj_type_t type)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
return 0; return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return -1; /* FIXME: agregate nbobjs from different levels? */ return -1; /* FIXME: agregate nbobjs from different levels? */
return hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth); return (int) hwloc_get_nbobjs_inside_cpuset_by_depth(topology, set, depth);
} }
/** \brief Return the logical index among the objects included in CPU set \p set. /** \brief Return the logical index among the objects included in CPU set \p set.
@ -239,10 +239,10 @@ hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_c
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t obj) __hwloc_attribute_pure; hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline int static __hwloc_inline int
hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t obj) hwloc_obj_t obj)
{ {
int idx = 0; int idx = 0;
if (!hwloc_bitmap_isincluded(obj->cpuset, set)) if (!hwloc_bitmap_isincluded(obj->cpuset, set))
@ -270,10 +270,10 @@ hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_u
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t parent) __hwloc_attribute_pure; hwloc_obj_t parent) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set, hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t parent) hwloc_obj_t parent)
{ {
hwloc_obj_t child; hwloc_obj_t child;
if (hwloc_bitmap_iszero(set)) if (hwloc_bitmap_iszero(set))
@ -319,7 +319,7 @@ hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t s
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_const_cpuset_t set,
unsigned depth, hwloc_obj_t prev) int depth, hwloc_obj_t prev)
{ {
hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev); hwloc_obj_t next = hwloc_get_next_obj_by_depth(topology, depth, prev);
if (!next) if (!next)
@ -346,7 +346,7 @@ hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_con
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set, hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, hwloc_obj_t prev) hwloc_obj_type_t type, hwloc_obj_t prev)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -369,9 +369,9 @@ hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_cons
/** \brief Returns the ancestor object of \p obj at depth \p depth. */ /** \brief Returns the ancestor object of \p obj at depth \p depth. */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) __hwloc_attribute_pure; hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, unsigned depth, hwloc_obj_t obj) hwloc_get_ancestor_obj_by_depth (hwloc_topology_t topology __hwloc_attribute_unused, int depth, hwloc_obj_t obj)
{ {
hwloc_obj_t ancestor = obj; hwloc_obj_t ancestor = obj;
if (obj->depth < depth) if (obj->depth < depth)
@ -432,7 +432,8 @@ hwloc_obj_is_in_subtree (hwloc_topology_t topology __hwloc_attribute_unused, hwl
/** \brief Return the next child. /** \brief Return the next child.
* *
* Return the next child among the normal children list, then among the I/O * Return the next child among the normal children list,
* then among the memory children list, then among the I/O
* children list, then among the Misc children list. * children list, then among the Misc children list.
* *
* If \p prev is \c NULL, return the first child. * If \p prev is \c NULL, return the first child.
@ -446,21 +447,27 @@ hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_
int state = 0; int state = 0;
if (prev) { if (prev) {
if (prev->type == HWLOC_OBJ_MISC) if (prev->type == HWLOC_OBJ_MISC)
state = 2; state = 3;
else if (prev->type == HWLOC_OBJ_BRIDGE || prev->type == HWLOC_OBJ_PCI_DEVICE || prev->type == HWLOC_OBJ_OS_DEVICE) else if (prev->type == HWLOC_OBJ_BRIDGE || prev->type == HWLOC_OBJ_PCI_DEVICE || prev->type == HWLOC_OBJ_OS_DEVICE)
state = 2;
else if (prev->type == HWLOC_OBJ_NUMANODE)
state = 1; state = 1;
obj = prev->next_sibling; obj = prev->next_sibling;
} else { } else {
obj = parent->first_child; obj = parent->first_child;
} }
if (!obj && state == 0) { if (!obj && state == 0) {
obj = parent->io_first_child; obj = parent->memory_first_child;
state = 1; state = 1;
} }
if (!obj && state == 1) { if (!obj && state == 1) {
obj = parent->misc_first_child; obj = parent->io_first_child;
state = 2; state = 2;
} }
if (!obj && state == 2) {
obj = parent->misc_first_child;
state = 3;
}
return obj; return obj;
} }
@ -468,31 +475,82 @@ hwloc_get_next_child (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_
/** \defgroup hwlocality_helper_types Kinds of object Type
* @{
*
* Each object type is
* either Normal (i.e. hwloc_obj_type_is_normal() returns 1),
* or Memory (i.e. hwloc_obj_type_is_memory() returns 1)
* or I/O (i.e. hwloc_obj_type_is_io() returns 1)
* or Misc (i.e. equal to ::HWLOC_OBJ_MISC).
* It cannot be of more than one of these kinds.
*/
/** \brief Check whether an object type is Normal.
*
* Normal objects are objects of the main CPU hierarchy
* (Machine, Package, Core, PU, CPU caches, etc.),
* but they are not NUMA nodes, I/O devices or Misc objects.
*
* They are attached to parent as Normal children,
* not as Memory, I/O or Misc children.
*
* \return 1 if an object of type \p type is a Normal object, 0 otherwise.
*/
HWLOC_DECLSPEC int
hwloc_obj_type_is_normal(hwloc_obj_type_t type);
/** \brief Check whether an object type is Memory.
*
* Memory objects are objects attached to their parents
* in the Memory children list.
* This current only includes NUMA nodes.
*
* \return 1 if an object of type \p type is a Memory object, 0 otherwise.
*/
HWLOC_DECLSPEC int
hwloc_obj_type_is_io(hwloc_obj_type_t type);
/** \brief Check whether an object type is I/O.
*
* I/O objects are objects attached to their parents
* in the I/O children list.
* This current includes Bridges, PCI and OS devices.
*
* \return 1 if an object of type \p type is a I/O object, 0 otherwise.
*/
HWLOC_DECLSPEC int
hwloc_obj_type_is_memory(hwloc_obj_type_t type);
/** \brief Check whether an object type is a Cache (Data, Unified or Instruction).
*
* \return 1 if an object of type \p type is a Cache, 0 otherwise.
*/
HWLOC_DECLSPEC int
hwloc_obj_type_is_cache(hwloc_obj_type_t type);
/** \brief Check whether an object type is a Data or Unified Cache.
*
* \return 1 if an object of type \p type is a Data or Unified Cache, 0 otherwise.
*/
HWLOC_DECLSPEC int
hwloc_obj_type_is_dcache(hwloc_obj_type_t type);
/** \brief Check whether an object type is a Instruction Cache,
*
* \return 1 if an object of type \p type is a Instruction Cache, 0 otherwise.
*/
HWLOC_DECLSPEC int
hwloc_obj_type_is_icache(hwloc_obj_type_t type);
/** @} */
/** \defgroup hwlocality_helper_find_cache Looking at Cache Objects /** \defgroup hwlocality_helper_find_cache Looking at Cache Objects
* @{ * @{
*/ */
/** \brief Check whether an object is a Cache (Data, Unified or Instruction). */
static __hwloc_inline int
hwloc_obj_type_is_cache(hwloc_obj_type_t type)
{
return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L3ICACHE);
}
/** \brief Check whether an object is a Data or Unified Cache. */
static __hwloc_inline int
hwloc_obj_type_is_dcache(hwloc_obj_type_t type)
{
return (type >= HWLOC_OBJ_L1CACHE && type <= HWLOC_OBJ_L5CACHE);
}
/** \brief Check whether an object is a Instruction Cache. */
static __hwloc_inline int
hwloc_obj_type_is_icache(hwloc_obj_type_t type)
{
return (type >= HWLOC_OBJ_L1ICACHE && type <= HWLOC_OBJ_L3ICACHE);
}
/** \brief Find the depth of cache objects matching cache level and type. /** \brief Find the depth of cache objects matching cache level and type.
* *
* Return the depth of the topology level that contains cache objects * Return the depth of the topology level that contains cache objects
@ -516,7 +574,7 @@ hwloc_obj_type_is_icache(hwloc_obj_type_t type)
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_get_cache_type_depth (hwloc_topology_t topology, hwloc_get_cache_type_depth (hwloc_topology_t topology,
unsigned cachelevel, hwloc_obj_cache_type_t cachetype) unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
{ {
int depth; int depth;
int found = HWLOC_TYPE_DEPTH_UNKNOWN; int found = HWLOC_TYPE_DEPTH_UNKNOWN;
@ -529,7 +587,7 @@ hwloc_get_cache_type_depth (hwloc_topology_t topology,
continue; continue;
if (cachetype == (hwloc_obj_cache_type_t) -1) { if (cachetype == (hwloc_obj_cache_type_t) -1) {
if (found != HWLOC_TYPE_DEPTH_UNKNOWN) { if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
/* second match, return MULTIPLE */ /* second match, return MULTIPLE */
return HWLOC_TYPE_DEPTH_MULTIPLE; return HWLOC_TYPE_DEPTH_MULTIPLE;
} }
/* first match, mark it as found */ /* first match, mark it as found */
@ -666,12 +724,12 @@ HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_obj_below_by_type (hwloc_topology_t topology, hwloc_get_obj_below_by_type (hwloc_topology_t topology,
hwloc_obj_type_t type1, unsigned idx1, hwloc_obj_type_t type1, unsigned idx1,
hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure; hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_obj_below_by_type (hwloc_topology_t topology, hwloc_get_obj_below_by_type (hwloc_topology_t topology,
hwloc_obj_type_t type1, unsigned idx1, hwloc_obj_type_t type1, unsigned idx1,
hwloc_obj_type_t type2, unsigned idx2) hwloc_obj_type_t type2, unsigned idx2)
{ {
hwloc_obj_t obj; hwloc_obj_t obj;
obj = hwloc_get_obj_by_type (topology, type1, idx1); obj = hwloc_get_obj_by_type (topology, type1, idx1);
@ -755,10 +813,10 @@ enum hwloc_distrib_flags_e {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_distrib(hwloc_topology_t topology, hwloc_distrib(hwloc_topology_t topology,
hwloc_obj_t *roots, unsigned n_roots, hwloc_obj_t *roots, unsigned n_roots,
hwloc_cpuset_t *set, hwloc_cpuset_t *set,
unsigned n, unsigned n,
unsigned until, unsigned long flags) int until, unsigned long flags)
{ {
unsigned i; unsigned i;
unsigned tot_weight; unsigned tot_weight;
@ -772,13 +830,16 @@ hwloc_distrib(hwloc_topology_t topology,
tot_weight = 0; tot_weight = 0;
for (i = 0; i < n_roots; i++) for (i = 0; i < n_roots; i++)
tot_weight += hwloc_bitmap_weight(roots[i]->cpuset); tot_weight += (unsigned) hwloc_bitmap_weight(roots[i]->cpuset);
for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) { for (i = 0, given = 0, givenweight = 0; i < n_roots; i++) {
unsigned chunk, weight; unsigned chunk, weight;
hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i]; hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
hwloc_cpuset_t cpuset = root->cpuset; hwloc_cpuset_t cpuset = root->cpuset;
weight = hwloc_bitmap_weight(cpuset); if (root->type == HWLOC_OBJ_NUMANODE)
/* NUMANodes have same cpuset as their parent, but we need normal objects below */
root = root->parent;
weight = (unsigned) hwloc_bitmap_weight(cpuset);
if (!weight) if (!weight)
continue; continue;
/* Give to root a chunk proportional to its weight. /* Give to root a chunk proportional to its weight.
@ -788,17 +849,17 @@ hwloc_distrib(hwloc_topology_t topology,
if (!root->arity || chunk <= 1 || root->depth >= until) { if (!root->arity || chunk <= 1 || root->depth >= until) {
/* We can't split any more, put everything there. */ /* We can't split any more, put everything there. */
if (chunk) { if (chunk) {
/* Fill cpusets with ours */ /* Fill cpusets with ours */
unsigned j; unsigned j;
for (j=0; j < chunk; j++) for (j=0; j < chunk; j++)
cpusetp[j] = hwloc_bitmap_dup(cpuset); cpusetp[j] = hwloc_bitmap_dup(cpuset);
} else { } else {
/* We got no chunk, just merge our cpuset to a previous one /* We got no chunk, just merge our cpuset to a previous one
* (the first chunk cannot be empty) * (the first chunk cannot be empty)
* so that this root doesn't get ignored. * so that this root doesn't get ignored.
*/ */
assert(given); assert(given);
hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset); hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
} }
} else { } else {
/* Still more to distribute, recurse into children */ /* Still more to distribute, recurse into children */
@ -819,20 +880,18 @@ hwloc_distrib(hwloc_topology_t topology,
/** \defgroup hwlocality_helper_topology_sets CPU and node sets of entire topologies /** \defgroup hwlocality_helper_topology_sets CPU and node sets of entire topologies
* @{ * @{
*/ */
/** \brief Get complete CPU set /** \brief Get complete CPU set
* *
* \return the complete CPU set of logical processors of the system. * \return the complete CPU set of logical processors of the system.
* *
* \note The returned cpuset is not newly allocated and should thus not be * \note The returned cpuset is not newly allocated and should thus not be
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*
* \note This is equivalent to retrieving the root object complete CPU-set.
*/ */
static __hwloc_inline hwloc_const_cpuset_t HWLOC_DECLSPEC hwloc_const_cpuset_t
hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure; hwloc_topology_get_complete_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
{
return hwloc_get_root_obj(topology)->complete_cpuset;
}
/** \brief Get topology CPU set /** \brief Get topology CPU set
* *
@ -842,29 +901,30 @@ hwloc_topology_get_complete_cpuset(hwloc_topology_t topology)
* *
* \note The returned cpuset is not newly allocated and should thus not be * \note The returned cpuset is not newly allocated and should thus not be
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*
* \note This is equivalent to retrieving the root object complete CPU-set.
*/ */
static __hwloc_inline hwloc_const_cpuset_t HWLOC_DECLSPEC hwloc_const_cpuset_t
hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure; hwloc_topology_get_topology_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_topology_cpuset(hwloc_topology_t topology)
{
return hwloc_get_root_obj(topology)->cpuset;
}
/** \brief Get allowed CPU set /** \brief Get allowed CPU set
* *
* \return the CPU set of allowed logical processors of the system. * \return the CPU set of allowed logical processors of the system.
* *
* \note If the topology flag ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM was not set,
* this is identical to hwloc_topology_get_topology_cpuset(), which means
* all PUs are allowed.
*
* \note If ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM was set, applying
* hwloc_bitmap_intersects() on the result of this function and on an object
* cpuset checks whether there are allowed PUs inside that object.
* Applying hwloc_bitmap_and() returns the list of these allowed PUs.
*
* \note The returned cpuset is not newly allocated and should thus not be * \note The returned cpuset is not newly allocated and should thus not be
* changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy. * changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy.
*/ */
static __hwloc_inline hwloc_const_cpuset_t HWLOC_DECLSPEC hwloc_const_cpuset_t
hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure; hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_const_cpuset_t
hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
{
return hwloc_get_root_obj(topology)->allowed_cpuset;
}
/** \brief Get complete node set /** \brief Get complete node set
* *
@ -872,14 +932,11 @@ hwloc_topology_get_allowed_cpuset(hwloc_topology_t topology)
* *
* \note The returned nodeset is not newly allocated and should thus not be * \note The returned nodeset is not newly allocated and should thus not be
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*
* \note This is equivalent to retrieving the root object complete CPU-set.
*/ */
static __hwloc_inline hwloc_const_nodeset_t HWLOC_DECLSPEC hwloc_const_nodeset_t
hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure; hwloc_topology_get_complete_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_const_nodeset_t
hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
{
return hwloc_get_root_obj(topology)->complete_nodeset;
}
/** \brief Get topology node set /** \brief Get topology node set
* *
@ -889,29 +946,30 @@ hwloc_topology_get_complete_nodeset(hwloc_topology_t topology)
* *
* \note The returned nodeset is not newly allocated and should thus not be * \note The returned nodeset is not newly allocated and should thus not be
* changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy. * changed or freed; hwloc_bitmap_dup() must be used to obtain a local copy.
*
* \note This is equivalent to retrieving the root object complete CPU-set.
*/ */
static __hwloc_inline hwloc_const_nodeset_t HWLOC_DECLSPEC hwloc_const_nodeset_t
hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure; hwloc_topology_get_topology_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_const_nodeset_t
hwloc_topology_get_topology_nodeset(hwloc_topology_t topology)
{
return hwloc_get_root_obj(topology)->nodeset;
}
/** \brief Get allowed node set /** \brief Get allowed node set
* *
* \return the node set of allowed memory of the system. * \return the node set of allowed memory of the system.
* *
* \note If the topology flag ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM was not set,
* this is identical to hwloc_topology_get_topology_nodeset(), which means
* all NUMA nodes are allowed.
*
* \note If ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM was set, applying
* hwloc_bitmap_intersects() on the result of this function and on an object
* nodeset checks whether there are allowed NUMA nodes inside that object.
* Applying hwloc_bitmap_and() returns the list of these allowed NUMA nodes.
*
* \note The returned nodeset is not newly allocated and should thus not be * \note The returned nodeset is not newly allocated and should thus not be
* changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy. * changed or freed, hwloc_bitmap_dup() must be used to obtain a local copy.
*/ */
static __hwloc_inline hwloc_const_nodeset_t HWLOC_DECLSPEC hwloc_const_nodeset_t
hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure; hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology) __hwloc_attribute_pure;
static __hwloc_inline hwloc_const_nodeset_t
hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
{
return hwloc_get_root_obj(topology)->allowed_nodeset;
}
/** @} */ /** @} */
@ -932,15 +990,17 @@ hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
* If \p cpuset is empty, \p nodeset will be emptied as well. * If \p cpuset is empty, \p nodeset will be emptied as well.
* Otherwise \p nodeset will be entirely filled. * Otherwise \p nodeset will be entirely filled.
*/ */
static __hwloc_inline void static __hwloc_inline int
hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset) hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset, hwloc_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj = NULL; hwloc_obj_t obj = NULL;
assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN); assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
hwloc_bitmap_zero(nodeset); hwloc_bitmap_zero(nodeset);
while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL) while ((obj = hwloc_get_next_obj_covering_cpuset_by_depth(topology, _cpuset, depth, obj)) != NULL)
hwloc_bitmap_set(nodeset, obj->os_index); if (hwloc_bitmap_set(nodeset, obj->os_index) < 0)
return -1;
return 0;
} }
/** \brief Convert a NUMA node set into a CPU set and handle non-NUMA cases /** \brief Convert a NUMA node set into a CPU set and handle non-NUMA cases
@ -951,18 +1011,20 @@ hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset,
* Otherwise \p cpuset will be entirely filled. * Otherwise \p cpuset will be entirely filled.
* This is useful for manipulating memory binding sets. * This is useful for manipulating memory binding sets.
*/ */
static __hwloc_inline void static __hwloc_inline int
hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset) hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwloc_const_nodeset_t nodeset)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj = NULL; hwloc_obj_t obj = NULL;
assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN); assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
hwloc_bitmap_zero(_cpuset); hwloc_bitmap_zero(_cpuset);
while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) { while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
if (hwloc_bitmap_isset(nodeset, obj->os_index)) if (hwloc_bitmap_isset(nodeset, obj->os_index))
/* no need to check obj->cpuset because objects in levels always have a cpuset */ /* no need to check obj->cpuset because objects in levels always have a cpuset */
hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset); if (hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset) < 0)
} return -1;
}
return 0;
} }
/** @} */ /** @} */
@ -976,12 +1038,17 @@ hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwl
/** \brief Get the first non-I/O ancestor object. /** \brief Get the first non-I/O ancestor object.
* *
* Given the I/O object \p ioobj, find the smallest non-I/O ancestor * Given the I/O object \p ioobj, find the smallest non-I/O ancestor
* object. This regular object may then be used for binding because * object. This object (normal or memory) may then be used for binding
* its locality is the same as \p ioobj. * because it has non-NULL CPU and node sets
* and because its locality is the same as \p ioobj.
*
* \note The resulting object is usually a normal object but it could also
* be a memory object (e.g. NUMA node) in future platforms if I/O objects
* ever get attached to memory instead of CPUs.
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,
hwloc_obj_t ioobj) hwloc_obj_t ioobj)
{ {
hwloc_obj_t obj = ioobj; hwloc_obj_t obj = ioobj;
while (obj && !obj->cpuset) { while (obj && !obj->cpuset) {
@ -1005,14 +1072,14 @@ hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_pcidev_by_busid(hwloc_topology_t topology, hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
unsigned domain, unsigned bus, unsigned dev, unsigned func) unsigned domain, unsigned bus, unsigned dev, unsigned func)
{ {
hwloc_obj_t obj = NULL; hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) { while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
if (obj->attr->pcidev.domain == domain if (obj->attr->pcidev.domain == domain
&& obj->attr->pcidev.bus == bus && obj->attr->pcidev.bus == bus
&& obj->attr->pcidev.dev == dev && obj->attr->pcidev.dev == dev
&& obj->attr->pcidev.func == func) && obj->attr->pcidev.func == func)
return obj; return obj;
} }
return NULL; return NULL;
@ -1060,7 +1127,7 @@ hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_bridge_covers_pcibus(hwloc_obj_t bridge, hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
unsigned domain, unsigned bus) unsigned domain, unsigned bus)
{ {
return bridge->type == HWLOC_OBJ_BRIDGE return bridge->type == HWLOC_OBJ_BRIDGE
&& bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI && bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved. * Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux * Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
@ -38,7 +38,7 @@ hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0) if (hwloc_compare_types(hwloc_get_depth_type(topology, depth), type) < 0)
return depth+1; return depth+1;
/* Shouldn't ever happen, as there is always a SYSTEM level with lower order and known depth. */ /* Shouldn't ever happen, as there is always a Machine level with lower order and known depth. */
/* abort(); */ /* abort(); */
} }
@ -67,7 +67,7 @@ hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
return 0; return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE) if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
return -1; /* FIXME: agregate nbobjs from different levels? */ return -1; /* FIXME: agregate nbobjs from different levels? */
return hwloc_get_nbobjs_by_depth(topology, depth); return (int) hwloc_get_nbobjs_by_depth(topology, depth);
} }
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
@ -82,7 +82,7 @@ hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigne
} }
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_obj_t prev) hwloc_get_next_obj_by_depth (hwloc_topology_t topology, int depth, hwloc_obj_t prev)
{ {
if (!prev) if (!prev)
return hwloc_get_obj_by_depth (topology, depth, 0); return hwloc_get_obj_by_depth (topology, depth, 0);
@ -93,7 +93,7 @@ hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_ob
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev) hwloc_obj_t prev)
{ {
int depth = hwloc_get_type_depth(topology, type); int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -111,9 +111,11 @@ static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name) hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
{ {
unsigned i; unsigned i;
for(i=0; i<obj->infos_count; i++) for(i=0; i<obj->infos_count; i++) {
if (!strcmp(obj->infos[i].name, name)) struct hwloc_info_s *info = &obj->infos[i];
return obj->infos[i].value; if (!strcmp(info->name, name))
return info->value;
}
return NULL; return NULL;
} }
@ -123,7 +125,11 @@ hwloc_alloc_membind_policy(hwloc_topology_t topology, size_t len, hwloc_const_cp
void *p = hwloc_alloc_membind(topology, len, set, policy, flags); void *p = hwloc_alloc_membind(topology, len, set, policy, flags);
if (p) if (p)
return p; return p;
hwloc_set_membind(topology, set, policy, flags);
if (hwloc_set_membind(topology, set, policy, flags) < 0)
/* hwloc_set_membind() takes care of ignoring errors if non-STRICT */
return NULL;
p = hwloc_alloc(topology, len); p = hwloc_alloc(topology, len);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH) if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */ /* Enforce the binding by touching the data */

Просмотреть файл

@ -56,43 +56,43 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
int idx __hwloc_attribute_unused, int idx __hwloc_attribute_unused,
hwloc_cpuset_t set) hwloc_cpuset_t set)
{ {
#ifdef HWLOC_LINUX_SYS #ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */ /* If we're on Linux, use the sysfs mechanism to get the local cpus */
#define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128 #define HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX]; char path[HWLOC_INTEL_MIC_DEVICE_SYSFS_PATH_MAX];
DIR *sysdir = NULL; DIR *sysdir = NULL;
struct dirent *dirent; struct dirent *dirent;
unsigned pcibus, pcidev, pcifunc; unsigned pcibus, pcidev, pcifunc;
if (!hwloc_topology_is_thissystem(topology)) { if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
sprintf(path, "/sys/class/mic/mic%d", idx); sprintf(path, "/sys/class/mic/mic%d", idx);
sysdir = opendir(path); sysdir = opendir(path);
if (!sysdir) if (!sysdir)
return -1; return -1;
while ((dirent = readdir(sysdir)) != NULL) { while ((dirent = readdir(sysdir)) != NULL) {
if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) { if (sscanf(dirent->d_name, "pci_%02x:%02x.%02x", &pcibus, &pcidev, &pcifunc) == 3) {
sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc); sprintf(path, "/sys/class/mic/mic%d/pci_%02x:%02x.%02x/local_cpus", idx, pcibus, pcidev, pcifunc);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0 if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set)) || hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
break; break;
} }
} }
closedir(sysdir); closedir(sysdir);
#else #else
/* Non-Linux systems simply get a full cpuset */ /* Non-Linux systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif #endif
return 0; return 0;
} }
/** \brief Get the hwloc OS device object corresponding to the /** \brief Get the hwloc OS device object corresponding to the
@ -110,14 +110,14 @@ hwloc_intel_mic_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_un
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_intel_mic_get_device_osdev_by_index(hwloc_topology_t topology, hwloc_intel_mic_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned idx) unsigned idx)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name && osdev->name
&& !strncmp("mic", osdev->name, 3) && !strncmp("mic", osdev->name, 3)
&& atoi(osdev->name + 3) == (int) idx) && atoi(osdev->name + 3) == (int) idx)
return osdev; return osdev;
} }
return NULL; return NULL;

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009 CNRS * Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved. * Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux * Copyright © 2009-2010, 2012 Université Bordeaux
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -52,7 +52,7 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset, hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
unsigned long *mask, unsigned long *maxnode) unsigned long *mask, unsigned long *maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1; unsigned long outmaxnode = -1;
@ -86,7 +86,7 @@ hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpus
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset, hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
unsigned long *mask, unsigned long *maxnode) unsigned long *mask, unsigned long *maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1; unsigned long outmaxnode = -1;
@ -121,14 +121,14 @@ hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nod
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const unsigned long *mask, unsigned long maxnode) const unsigned long *mask, unsigned long maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;
hwloc_bitmap_zero(cpuset); hwloc_bitmap_zero(cpuset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8))))) && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_or(cpuset, cpuset, node->cpuset); hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
return 0; return 0;
} }
@ -144,14 +144,14 @@ hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const unsigned long *mask, unsigned long maxnode) const unsigned long *mask, unsigned long maxnode)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;
hwloc_bitmap_zero(nodeset); hwloc_bitmap_zero(nodeset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8))))) && (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_set(nodeset, node->os_index); hwloc_bitmap_set(nodeset, node->os_index);
return 0; return 0;
} }
@ -196,7 +196,7 @@ hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpu
if (!bitmask) if (!bitmask)
return NULL; return NULL;
while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL) while ((node = hwloc_get_next_obj_covering_cpuset_by_depth(topology, cpuset, depth, node)) != NULL)
if (node->memory.local_memory) if (node->attr->numanode.local_memory)
numa_bitmask_setbit(bitmask, node->os_index); numa_bitmask_setbit(bitmask, node->os_index);
return bitmask; return bitmask;
} }
@ -221,7 +221,7 @@ hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_no
if (!bitmask) if (!bitmask)
return NULL; return NULL;
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL) while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (hwloc_bitmap_isset(nodeset, node->os_index) && node->memory.local_memory) if (hwloc_bitmap_isset(nodeset, node->os_index) && node->attr->numanode.local_memory)
numa_bitmask_setbit(bitmask, node->os_index); numa_bitmask_setbit(bitmask, node->os_index);
return bitmask; return bitmask;
} }
@ -233,7 +233,7 @@ hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_no
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset, hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const struct bitmask *bitmask) const struct bitmask *bitmask)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;
@ -251,7 +251,7 @@ hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const struct bitmask *bitmask) const struct bitmask *bitmask)
{ {
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE); int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL; hwloc_obj_t node = NULL;

Просмотреть файл

@ -54,7 +54,7 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
nvmlDevice_t device, hwloc_cpuset_t set) nvmlDevice_t device, hwloc_cpuset_t set)
{ {
#ifdef HWLOC_LINUX_SYS #ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */ /* If we're on Linux, use the sysfs mechanism to get the local cpus */
@ -101,12 +101,12 @@ hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx) hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name && osdev->name
&& !strncmp("nvml", osdev->name, 4) && !strncmp("nvml", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx) && atoi(osdev->name + 4) == (int) idx)
return osdev; return osdev;
} }
return NULL; return NULL;
@ -128,46 +128,46 @@ hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device) hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
{ {
hwloc_obj_t osdev; hwloc_obj_t osdev;
nvmlReturn_t nvres; nvmlReturn_t nvres;
nvmlPciInfo_t pci; nvmlPciInfo_t pci;
char uuid[64]; char uuid[64];
if (!hwloc_topology_is_thissystem(topology)) { if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
nvres = nvmlDeviceGetPciInfo(device, &pci); nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres) if (NVML_SUCCESS != nvres)
return NULL; return NULL;
nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid)); nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
if (NVML_SUCCESS != nvres) if (NVML_SUCCESS != nvres)
uuid[0] = '\0'; uuid[0] = '\0';
osdev = NULL; osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent; hwloc_obj_t pcidev = osdev->parent;
const char *info; const char *info;
if (strncmp(osdev->name, "nvml", 4)) if (strncmp(osdev->name, "nvml", 4))
continue; continue;
if (pcidev if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE && pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.domain && pcidev->attr->pcidev.domain == pci.domain
&& pcidev->attr->pcidev.bus == pci.bus && pcidev->attr->pcidev.bus == pci.bus
&& pcidev->attr->pcidev.dev == pci.device && pcidev->attr->pcidev.dev == pci.device
&& pcidev->attr->pcidev.func == 0) && pcidev->attr->pcidev.func == 0)
return osdev; return osdev;
info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID"); info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
if (info && !strcmp(info, uuid)) if (info && !strcmp(info, uuid))
return osdev; return osdev;
} }
return NULL; return NULL;
} }
/** @} */ /** @} */

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2012-2017 Inria. All rights reserved. * Copyright © 2012-2018 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux. All right reserved. * Copyright © 2013, 2018 Université Bordeaux. All right reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -21,8 +21,13 @@
#include <hwloc/linux.h> #include <hwloc/linux.h>
#endif #endif
#ifdef __APPLE__
#include <OpenCL/cl.h>
#include <OpenCL/cl_ext.h>
#else
#include <CL/cl.h> #include <CL/cl.h>
#include <CL/cl_ext.h> #include <CL/cl_ext.h>
#endif
#include <stdio.h> #include <stdio.h>
@ -62,39 +67,39 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused, cl_device_id device __hwloc_attribute_unused,
hwloc_cpuset_t set) hwloc_cpuset_t set)
{ {
#if (defined HWLOC_LINUX_SYS) && (defined CL_DEVICE_TOPOLOGY_AMD) #if (defined HWLOC_LINUX_SYS) && (defined CL_DEVICE_TOPOLOGY_AMD)
/* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */ /* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */
#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128 #define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX]; char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
cl_device_topology_amd amdtopo; cl_device_topology_amd amdtopo;
cl_int clret; cl_int clret;
if (!hwloc_topology_is_thissystem(topology)) { if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL); clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) { if (CL_SUCCESS != clret) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0; return 0;
} }
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) { if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0; return 0;
} }
sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus", sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus",
(unsigned) amdtopo.pcie.bus, (unsigned) amdtopo.pcie.device, (unsigned) amdtopo.pcie.function); (unsigned) amdtopo.pcie.bus, (unsigned) amdtopo.pcie.device, (unsigned) amdtopo.pcie.function);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0 if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set)) || hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else #else
/* Non-Linux + AMD OpenCL systems simply get a full cpuset */ /* Non-Linux + AMD OpenCL systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif #endif
return 0; return 0;
} }
@ -116,24 +121,29 @@ hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology, hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned platform_index, unsigned device_index) unsigned platform_index, unsigned device_index)
{ {
unsigned x = (unsigned) -1, y = (unsigned) -1; unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name && osdev->name
&& sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2 && sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
&& platform_index == x && device_index == y) && platform_index == x && device_index == y)
return osdev; return osdev;
} }
return NULL; return NULL;
} }
/** \brief Get the hwloc OS device object corresponding to OpenCL device \p device. /** \brief Get the hwloc OS device object corresponding to OpenCL device \p deviceX.
* *
* Return the hwloc OS device object that describes the given * Use OpenCL device attributes to find the corresponding hwloc OS device object.
* OpenCL device \p device. Return NULL if there is none. * Return NULL if there is none or if useful attributes are not available.
*
* This function currently only works on AMD OpenCL devices that support
* the CL_DEVICE_TOPOLOGY_AMD extension. hwloc_opencl_get_device_osdev_by_index()
* should be preferred whenever possible, i.e. when platform and device index
* are known.
* *
* Topology \p topology and device \p device must match the local machine. * Topology \p topology and device \p device must match the local machine.
* I/O devices detection and the OpenCL component must be enabled in the topology. * I/O devices detection and the OpenCL component must be enabled in the topology.
@ -147,41 +157,41 @@ hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused) cl_device_id device __hwloc_attribute_unused)
{ {
#ifdef CL_DEVICE_TOPOLOGY_AMD #ifdef CL_DEVICE_TOPOLOGY_AMD
hwloc_obj_t osdev; hwloc_obj_t osdev;
cl_device_topology_amd amdtopo; cl_device_topology_amd amdtopo;
cl_int clret; cl_int clret;
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL); clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) { if (CL_SUCCESS != clret) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) { if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
osdev = NULL; osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent; hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "opencl", 6)) if (strncmp(osdev->name, "opencl", 6))
continue; continue;
if (pcidev if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE && pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == 0 && pcidev->attr->pcidev.domain == 0
&& pcidev->attr->pcidev.bus == amdtopo.pcie.bus && pcidev->attr->pcidev.bus == amdtopo.pcie.bus
&& pcidev->attr->pcidev.dev == amdtopo.pcie.device && pcidev->attr->pcidev.dev == amdtopo.pcie.device
&& pcidev->attr->pcidev.func == amdtopo.pcie.function) && pcidev->attr->pcidev.func == amdtopo.pcie.function)
return osdev; return osdev;
/* if PCI are filtered out, we need a info attr to match on */ /* if PCI are filtered out, we need a info attr to match on */
} }
return NULL; return NULL;
#else #else
return NULL; return NULL;
#endif #endif
} }

Просмотреть файл

@ -60,7 +60,7 @@ extern "C" {
*/ */
static __hwloc_inline int static __hwloc_inline int
hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
struct ibv_device *ibdev, hwloc_cpuset_t set) struct ibv_device *ibdev, hwloc_cpuset_t set)
{ {
#ifdef HWLOC_LINUX_SYS #ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the verbs-provided sysfs mechanism to /* If we're on Linux, use the verbs-provided sysfs mechanism to
@ -74,7 +74,7 @@ hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
} }
sprintf(path, "/sys/class/infiniband/%s/device/local_cpus", sprintf(path, "/sys/class/infiniband/%s/device/local_cpus",
ibv_get_device_name(ibdev)); ibv_get_device_name(ibdev));
if (hwloc_linux_read_path_as_cpumask(path, set) < 0 if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set)) || hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology)); hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
@ -103,15 +103,15 @@ hwloc_ibv_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology, hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,
const char *ibname) const char *ibname)
{ {
hwloc_obj_t osdev = NULL; hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) { while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type if (HWLOC_OBJ_OSDEV_OPENFABRICS == osdev->attr->osdev.type
&& osdev->name && !strcmp(ibname, osdev->name)) && osdev->name && !strcmp(ibname, osdev->name))
return osdev; return osdev;
} }
return NULL; return NULL;
} }
/** \brief Get the hwloc OS device object corresponding to the OpenFabrics /** \brief Get the hwloc OS device object corresponding to the OpenFabrics
@ -130,13 +130,13 @@ hwloc_ibv_get_device_osdev_by_name(hwloc_topology_t topology,
*/ */
static __hwloc_inline hwloc_obj_t static __hwloc_inline hwloc_obj_t
hwloc_ibv_get_device_osdev(hwloc_topology_t topology, hwloc_ibv_get_device_osdev(hwloc_topology_t topology,
struct ibv_device *ibdev) struct ibv_device *ibdev)
{ {
if (!hwloc_topology_is_thissystem(topology)) { if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL; errno = EINVAL;
return NULL; return NULL;
} }
return hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev)); return hwloc_ibv_get_device_osdev_by_name(topology, ibv_get_device_name(ibdev));
} }
/** @} */ /** @} */

Просмотреть файл

@ -86,6 +86,11 @@ struct hwloc_disc_component {
*/ */
unsigned priority; unsigned priority;
/** \brief Enabled by default.
* If unset, if will be disabled unless explicitly requested.
*/
unsigned enabled_by_default;
/** \private Used internally to list components by priority on topology->components /** \private Used internally to list components by priority on topology->components
* (the component structure is usually read-only, * (the component structure is usually read-only,
* the core copies it before using this field for queueing) * the core copies it before using this field for queueing)
@ -140,7 +145,8 @@ struct hwloc_backend {
/** \brief Main discovery callback. /** \brief Main discovery callback.
* returns -1 on error, either because it couldn't add its objects ot the existing topology, * returns -1 on error, either because it couldn't add its objects ot the existing topology,
* or because of an actual discovery/gathering failure. * or because of an actual discovery/gathering failure.
* May be NULL if type is ::HWLOC_DISC_COMPONENT_TYPE_MISC. */ * May be NULL.
*/
int (*discover)(struct hwloc_backend *backend); int (*discover)(struct hwloc_backend *backend);
/** \brief Callback used by the PCI backend to retrieve the locality of a PCI object from the OS/cpu backend. /** \brief Callback used by the PCI backend to retrieve the locality of a PCI object from the OS/cpu backend.
@ -269,9 +275,11 @@ HWLOC_DECLSPEC int hwloc_hide_errors(void);
/** \brief Add an object to the topology and specify which error callback to use. /** \brief Add an object to the topology and specify which error callback to use.
* *
* Aside from the error callback selection, this function is identical to hwloc_insert_object_by_cpuset() * This function is similar to hwloc_insert_object_by_cpuset() but it allows specifying
* where to start insertion from (if \p root is NULL, the topology root object is used),
* and specifying the error callback.
*/ */
HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t obj, hwloc_report_error_t report_error); HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_topology *topology, hwloc_obj_t root, hwloc_obj_t obj, hwloc_report_error_t report_error);
/** \brief Insert an object somewhere in the topology. /** \brief Insert an object somewhere in the topology.
* *
@ -291,8 +299,11 @@ HWLOC_DECLSPEC struct hwloc_obj *hwloc__insert_object_by_cpuset(struct hwloc_top
*/ */
HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj); HWLOC_DECLSPEC void hwloc_insert_object_by_parent(struct hwloc_topology *topology, hwloc_obj_t parent, hwloc_obj_t obj);
/** \brief Allocate and initialize an object of the given type and physical index */ /** \brief Allocate and initialize an object of the given type and physical index.
HWLOC_DECLSPEC hwloc_obj_t hwloc_alloc_setup_object(hwloc_topology_t topology, hwloc_obj_type_t type, signed os_index); *
* If \p os_index is unknown or irrelevant, use \c HWLOC_UNKNOWN_INDEX.
*/
HWLOC_DECLSPEC hwloc_obj_t hwloc_alloc_setup_object(hwloc_topology_t topology, hwloc_obj_type_t type, unsigned os_index);
/** \brief Setup object cpusets/nodesets by OR'ing its children. /** \brief Setup object cpusets/nodesets by OR'ing its children.
* *
@ -356,7 +367,7 @@ hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, co
} }
if (verboseenv_value) if (verboseenv_value)
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n", fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
pluginname, symbol); pluginname, symbol);
return -1; return -1;
} }
#endif /* HWLOC_INSIDE_PLUGIN */ #endif /* HWLOC_INSIDE_PLUGIN */
@ -381,12 +392,12 @@ hwloc_filter_check_pcidev_subtype_important(unsigned classid)
{ {
unsigned baseclass = classid >> 8; unsigned baseclass = classid >> 8;
return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */ return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
|| baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */ || baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
|| baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */ || baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
|| baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */ || baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */ || classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */ || classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|| baseclass == 0x12 /* Processing Accelerators */); || baseclass == 0x12 /* Processing Accelerators */);
} }
/** \brief Check whether the given OS device subtype is important. /** \brief Check whether the given OS device subtype is important.

Просмотреть файл

@ -1,6 +1,6 @@
/* /*
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved. * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* Copyright © 2010-2017 Inria. All rights reserved. * Copyright © 2010-2018 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -47,7 +47,6 @@ extern "C" {
#define hwloc_nodeset_t HWLOC_NAME(nodeset_t) #define hwloc_nodeset_t HWLOC_NAME(nodeset_t)
#define hwloc_const_nodeset_t HWLOC_NAME(const_nodeset_t) #define hwloc_const_nodeset_t HWLOC_NAME(const_nodeset_t)
#define HWLOC_OBJ_SYSTEM HWLOC_NAME_CAPS(OBJ_SYSTEM)
#define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE) #define HWLOC_OBJ_MACHINE HWLOC_NAME_CAPS(OBJ_MACHINE)
#define HWLOC_OBJ_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE) #define HWLOC_OBJ_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE)
#define HWLOC_OBJ_PACKAGE HWLOC_NAME_CAPS(OBJ_PACKAGE) #define HWLOC_OBJ_PACKAGE HWLOC_NAME_CAPS(OBJ_PACKAGE)
@ -94,15 +93,14 @@ extern "C" {
#define hwloc_compare_types_e HWLOC_NAME(compare_types_e) #define hwloc_compare_types_e HWLOC_NAME(compare_types_e)
#define HWLOC_TYPE_UNORDERED HWLOC_NAME_CAPS(TYPE_UNORDERED) #define HWLOC_TYPE_UNORDERED HWLOC_NAME_CAPS(TYPE_UNORDERED)
#define hwloc_obj_memory_s HWLOC_NAME(obj_memory_s)
#define hwloc_obj_memory_page_type_s HWLOC_NAME(obj_memory_page_type_s)
#define hwloc_obj HWLOC_NAME(obj) #define hwloc_obj HWLOC_NAME(obj)
#define hwloc_obj_t HWLOC_NAME(obj_t) #define hwloc_obj_t HWLOC_NAME(obj_t)
#define hwloc_obj_info_s HWLOC_NAME(obj_info_s) #define hwloc_info_s HWLOC_NAME(info_s)
#define hwloc_obj_attr_u HWLOC_NAME(obj_attr_u) #define hwloc_obj_attr_u HWLOC_NAME(obj_attr_u)
#define hwloc_numanode_attr_s HWLOC_NAME(numanode_attr_s)
#define hwloc_memory_page_type_s HWLOC_NAME(memory_page_type_s)
#define hwloc_cache_attr_s HWLOC_NAME(cache_attr_s) #define hwloc_cache_attr_s HWLOC_NAME(cache_attr_s)
#define hwloc_group_attr_s HWLOC_NAME(group_attr_s) #define hwloc_group_attr_s HWLOC_NAME(group_attr_s)
#define hwloc_pcidev_attr_s HWLOC_NAME(pcidev_attr_s) #define hwloc_pcidev_attr_s HWLOC_NAME(pcidev_attr_s)
@ -113,6 +111,7 @@ extern "C" {
#define hwloc_topology_load HWLOC_NAME(topology_load) #define hwloc_topology_load HWLOC_NAME(topology_load)
#define hwloc_topology_destroy HWLOC_NAME(topology_destroy) #define hwloc_topology_destroy HWLOC_NAME(topology_destroy)
#define hwloc_topology_dup HWLOC_NAME(topology_dup) #define hwloc_topology_dup HWLOC_NAME(topology_dup)
#define hwloc_topology_abi_check HWLOC_NAME(topology_abi_check)
#define hwloc_topology_check HWLOC_NAME(topology_check) #define hwloc_topology_check HWLOC_NAME(topology_check)
#define hwloc_topology_flags_e HWLOC_NAME(topology_flags_e) #define hwloc_topology_flags_e HWLOC_NAME(topology_flags_e)
@ -163,6 +162,7 @@ extern "C" {
#define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth) #define hwloc_topology_get_depth HWLOC_NAME(topology_get_depth)
#define hwloc_get_type_depth HWLOC_NAME(get_type_depth) #define hwloc_get_type_depth HWLOC_NAME(get_type_depth)
#define hwloc_get_memory_parents_depth HWLOC_NAME(get_memory_parents_depth)
#define hwloc_get_type_depth_e HWLOC_NAME(get_type_depth_e) #define hwloc_get_type_depth_e HWLOC_NAME(get_type_depth_e)
#define HWLOC_TYPE_DEPTH_UNKNOWN HWLOC_NAME_CAPS(TYPE_DEPTH_UNKNOWN) #define HWLOC_TYPE_DEPTH_UNKNOWN HWLOC_NAME_CAPS(TYPE_DEPTH_UNKNOWN)
@ -171,6 +171,7 @@ extern "C" {
#define HWLOC_TYPE_DEPTH_PCI_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_PCI_DEVICE) #define HWLOC_TYPE_DEPTH_PCI_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_PCI_DEVICE)
#define HWLOC_TYPE_DEPTH_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE) #define HWLOC_TYPE_DEPTH_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE)
#define HWLOC_TYPE_DEPTH_MISC HWLOC_NAME_CAPS(TYPE_DEPTH_MISC) #define HWLOC_TYPE_DEPTH_MISC HWLOC_NAME_CAPS(TYPE_DEPTH_MISC)
#define HWLOC_TYPE_DEPTH_NUMANODE HWLOC_NAME_CAPS(TYPE_DEPTH_NUMANODE)
#define hwloc_get_depth_type HWLOC_NAME(get_depth_type) #define hwloc_get_depth_type HWLOC_NAME(get_depth_type)
#define hwloc_get_nbobjs_by_depth HWLOC_NAME(get_nbobjs_by_depth) #define hwloc_get_nbobjs_by_depth HWLOC_NAME(get_nbobjs_by_depth)
@ -179,7 +180,7 @@ extern "C" {
#define hwloc_get_obj_by_depth HWLOC_NAME(get_obj_by_depth ) #define hwloc_get_obj_by_depth HWLOC_NAME(get_obj_by_depth )
#define hwloc_get_obj_by_type HWLOC_NAME(get_obj_by_type ) #define hwloc_get_obj_by_type HWLOC_NAME(get_obj_by_type )
#define hwloc_type_name HWLOC_NAME(type_name) #define hwloc_obj_type_string HWLOC_NAME(obj_type_string )
#define hwloc_obj_type_snprintf HWLOC_NAME(obj_type_snprintf ) #define hwloc_obj_type_snprintf HWLOC_NAME(obj_type_snprintf )
#define hwloc_obj_attr_snprintf HWLOC_NAME(obj_attr_snprintf ) #define hwloc_obj_attr_snprintf HWLOC_NAME(obj_attr_snprintf )
#define hwloc_type_sscanf HWLOC_NAME(type_sscanf) #define hwloc_type_sscanf HWLOC_NAME(type_sscanf)
@ -290,6 +291,9 @@ extern "C" {
#define hwloc_bitmap_first HWLOC_NAME(bitmap_first) #define hwloc_bitmap_first HWLOC_NAME(bitmap_first)
#define hwloc_bitmap_last HWLOC_NAME(bitmap_last) #define hwloc_bitmap_last HWLOC_NAME(bitmap_last)
#define hwloc_bitmap_next HWLOC_NAME(bitmap_next) #define hwloc_bitmap_next HWLOC_NAME(bitmap_next)
#define hwloc_bitmap_first_unset HWLOC_NAME(bitmap_first_unset)
#define hwloc_bitmap_last_unset HWLOC_NAME(bitmap_last_unset)
#define hwloc_bitmap_next_unset HWLOC_NAME(bitmap_next_unset)
#define hwloc_bitmap_singlify HWLOC_NAME(bitmap_singlify) #define hwloc_bitmap_singlify HWLOC_NAME(bitmap_singlify)
#define hwloc_bitmap_compare_first HWLOC_NAME(bitmap_compare_first) #define hwloc_bitmap_compare_first HWLOC_NAME(bitmap_compare_first)
#define hwloc_bitmap_compare HWLOC_NAME(bitmap_compare) #define hwloc_bitmap_compare HWLOC_NAME(bitmap_compare)
@ -322,6 +326,9 @@ extern "C" {
#define hwloc_get_obj_covering_cpuset HWLOC_NAME(get_obj_covering_cpuset) #define hwloc_get_obj_covering_cpuset HWLOC_NAME(get_obj_covering_cpuset)
#define hwloc_get_next_obj_covering_cpuset_by_depth HWLOC_NAME(get_next_obj_covering_cpuset_by_depth) #define hwloc_get_next_obj_covering_cpuset_by_depth HWLOC_NAME(get_next_obj_covering_cpuset_by_depth)
#define hwloc_get_next_obj_covering_cpuset_by_type HWLOC_NAME(get_next_obj_covering_cpuset_by_type) #define hwloc_get_next_obj_covering_cpuset_by_type HWLOC_NAME(get_next_obj_covering_cpuset_by_type)
#define hwloc_obj_type_is_normal HWLOC_NAME(obj_type_is_normal)
#define hwloc_obj_type_is_memory HWLOC_NAME(obj_type_is_memory)
#define hwloc_obj_type_is_io HWLOC_NAME(obj_type_is_io)
#define hwloc_obj_type_is_cache HWLOC_NAME(obj_type_is_cache) #define hwloc_obj_type_is_cache HWLOC_NAME(obj_type_is_cache)
#define hwloc_obj_type_is_dcache HWLOC_NAME(obj_type_is_dcache) #define hwloc_obj_type_is_dcache HWLOC_NAME(obj_type_is_dcache)
#define hwloc_obj_type_is_icache HWLOC_NAME(obj_type_is_icache) #define hwloc_obj_type_is_icache HWLOC_NAME(obj_type_is_icache)
@ -360,6 +367,8 @@ extern "C" {
#define hwloc_topology_export_synthetic_flags_e HWLOC_NAME(topology_export_synthetic_flags_e) #define hwloc_topology_export_synthetic_flags_e HWLOC_NAME(topology_export_synthetic_flags_e)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES) #define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_EXTENDED_TYPES)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS) #define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_NO_ATTRS)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1 HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_V1)
#define HWLOC_TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY HWLOC_NAME_CAPS(TOPOLOGY_EXPORT_SYNTHETIC_FLAG_IGNORE_MEMORY)
#define hwloc_topology_export_synthetic HWLOC_NAME(topology_export_synthetic) #define hwloc_topology_export_synthetic HWLOC_NAME(topology_export_synthetic)
/* distances.h */ /* distances.h */
@ -453,11 +462,6 @@ extern "C" {
#define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev) #define hwloc_ibv_get_device_osdev HWLOC_NAME(ibv_get_device_osdev)
#define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name) #define hwloc_ibv_get_device_osdev_by_name HWLOC_NAME(ibv_get_device_osdev_by_name)
/* myriexpress.h */
#define hwloc_mx_board_get_device_cpuset HWLOC_NAME(mx_board_get_device_cpuset)
#define hwloc_mx_endpoint_get_device_cpuset HWLOC_NAME(mx_endpoint_get_device_cpuset)
/* intel-mic.h */ /* intel-mic.h */
#define hwloc_intel_mic_get_device_cpuset HWLOC_NAME(intel_mic_get_device_cpuset) #define hwloc_intel_mic_get_device_cpuset HWLOC_NAME(intel_mic_get_device_cpuset)
@ -547,7 +551,6 @@ extern "C" {
#define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent) #define hwloc_topology_insert_misc_object_by_parent HWLOC_NAME(topology_insert_misc_object_by_parent)
#define hwloc_obj_cpuset_snprintf HWLOC_NAME(obj_cpuset_snprintf) #define hwloc_obj_cpuset_snprintf HWLOC_NAME(obj_cpuset_snprintf)
#define hwloc_obj_type_string HWLOC_NAME(obj_type_string)
#define hwloc_obj_type_sscanf HWLOC_NAME(obj_type_sscanf) #define hwloc_obj_type_sscanf HWLOC_NAME(obj_type_sscanf)
#define hwloc_set_membind_nodeset HWLOC_NAME(set_membind_nodeset) #define hwloc_set_membind_nodeset HWLOC_NAME(set_membind_nodeset)
@ -578,9 +581,20 @@ extern "C" {
#define hwloc_flsl_from_fls32 HWLOC_NAME(flsl_from_fls32) #define hwloc_flsl_from_fls32 HWLOC_NAME(flsl_from_fls32)
#define hwloc_weight_long HWLOC_NAME(weight_long) #define hwloc_weight_long HWLOC_NAME(weight_long)
#define hwloc_strncasecmp HWLOC_NAME(strncasecmp) #define hwloc_strncasecmp HWLOC_NAME(strncasecmp)
#define hwloc_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)
#define hwloc_pci_class_string HWLOC_NAME(pci_class_string)
#define hwloc_cache_type_by_depth_type HWLOC_NAME(cache_type_by_depth_type) #define hwloc_cache_type_by_depth_type HWLOC_NAME(cache_type_by_depth_type)
#define hwloc_obj_type_is_io HWLOC_NAME(obj_type_is_io) #define hwloc__obj_type_is_normal HWLOC_NAME(_obj_type_is_normal)
#define hwloc_obj_type_is_special HWLOC_NAME(obj_type_is_special) #define hwloc__obj_type_is_memory HWLOC_NAME(_obj_type_is_memory)
#define hwloc__obj_type_is_io HWLOC_NAME(_obj_type_is_io)
#define hwloc__obj_type_is_special HWLOC_NAME(_obj_type_is_special)
#define hwloc__obj_type_is_cache HWLOC_NAME(_obj_type_is_cache)
#define hwloc__obj_type_is_dcache HWLOC_NAME(_obj_type_is_dcache)
#define hwloc__obj_type_is_icache HWLOC_NAME(_obj_type_is_icache)
/* private/cpuid-x86.h */ /* private/cpuid-x86.h */
@ -597,6 +611,7 @@ extern "C" {
#define hwloc_xml_backend_data_s HWLOC_NAME(xml_backend_data_s) #define hwloc_xml_backend_data_s HWLOC_NAME(xml_backend_data_s)
#define hwloc__xml_export_state_s HWLOC_NAME(_xml_export_state_s) #define hwloc__xml_export_state_s HWLOC_NAME(_xml_export_state_s)
#define hwloc__xml_export_state_t HWLOC_NAME(_xml_export_state_t) #define hwloc__xml_export_state_t HWLOC_NAME(_xml_export_state_t)
#define hwloc__xml_export_data_s HWLOC_NAME(_xml_export_data_s)
#define hwloc__xml_export_topology HWLOC_NAME(_xml_export_topology) #define hwloc__xml_export_topology HWLOC_NAME(_xml_export_topology)
#define hwloc__xml_export_diff HWLOC_NAME(_xml_export_diff) #define hwloc__xml_export_diff HWLOC_NAME(_xml_export_diff)
@ -627,7 +642,7 @@ extern "C" {
#define hwloc_pci_forced_locality_s HWLOC_NAME(pci_forced_locality_s) #define hwloc_pci_forced_locality_s HWLOC_NAME(pci_forced_locality_s)
#define hwloc_alloc_obj_cpusets HWLOC_NAME(alloc_obj_cpusets) #define hwloc_alloc_root_sets HWLOC_NAME(alloc_root_sets)
#define hwloc_setup_pu_level HWLOC_NAME(setup_pu_level) #define hwloc_setup_pu_level HWLOC_NAME(setup_pu_level)
#define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname) #define hwloc_get_sysctlbyname HWLOC_NAME(get_sysctlbyname)
#define hwloc_get_sysctl HWLOC_NAME(get_sysctl) #define hwloc_get_sysctl HWLOC_NAME(get_sysctl)
@ -639,15 +654,16 @@ extern "C" {
#define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults) #define hwloc_topology_setup_defaults HWLOC_NAME(topology_setup_defaults)
#define hwloc_topology_clear HWLOC_NAME(topology_clear) #define hwloc_topology_clear HWLOC_NAME(topology_clear)
#define hwloc__attach_memory_object HWLOC_NAME(insert_memory_object)
#define hwloc_pci_discovery_init HWLOC_NAME(pci_discovery_init) #define hwloc_pci_discovery_init HWLOC_NAME(pci_discovery_init)
#define hwloc_pci_discovery_prepare HWLOC_NAME(pci_discovery_prepare) #define hwloc_pci_discovery_prepare HWLOC_NAME(pci_discovery_prepare)
#define hwloc_pci_discovery_exit HWLOC_NAME(pci_discovery_exit) #define hwloc_pci_discovery_exit HWLOC_NAME(pci_discovery_exit)
#define hwloc_find_insert_io_parent_by_complete_cpuset HWLOC_NAME(hwloc_find_insert_io_parent_by_complete_cpuset) #define hwloc_find_insert_io_parent_by_complete_cpuset HWLOC_NAME(hwloc_find_insert_io_parent_by_complete_cpuset)
#define hwloc_pci_belowroot_apply_locality HWLOC_NAME(pci_belowroot_apply_locality) #define hwloc_pci_belowroot_apply_locality HWLOC_NAME(pci_belowroot_apply_locality)
#define hwloc_pci_class_string HWLOC_NAME(pci_class_string)
#define hwloc__add_info HWLOC_NAME(_add_info) #define hwloc__add_info HWLOC_NAME(_add_info)
#define hwloc__find_info_slot HWLOC_NAME(_find_info_slot) #define hwloc__add_info_nodup HWLOC_NAME(_add_info_nodup)
#define hwloc__move_infos HWLOC_NAME(_move_infos) #define hwloc__move_infos HWLOC_NAME(_move_infos)
#define hwloc__free_infos HWLOC_NAME(_free_infos) #define hwloc__free_infos HWLOC_NAME(_free_infos)
@ -694,12 +710,8 @@ extern "C" {
#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64) #define hwloc_encode_to_base64 HWLOC_NAME(encode_to_base64)
#define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64) #define hwloc_decode_from_base64 HWLOC_NAME(decode_from_base64)
#define hwloc_obj_add_info_nodup HWLOC_NAME(obj_add_info_nodup)
#define hwloc_progname HWLOC_NAME(progname) #define hwloc_progname HWLOC_NAME(progname)
#define hwloc_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)
#define hwloc__topology_disadopt HWLOC_NAME(_topology_disadopt) #define hwloc__topology_disadopt HWLOC_NAME(_topology_disadopt)
#define hwloc__topology_dup HWLOC_NAME(_topology_dup) #define hwloc__topology_dup HWLOC_NAME(_topology_dup)
@ -711,8 +723,8 @@ extern "C" {
/* private/solaris-chiptype.h */ /* private/solaris-chiptype.h */
#define hwloc_solaris_get_chip_type HWLOC_NAME(solaris_get_chip_type) #define hwloc_solaris_chip_info_s HWLOC_NAME(solaris_chip_info_s)
#define hwloc_solaris_get_chip_model HWLOC_NAME(solaris_get_chip_model) #define hwloc_solaris_get_chip_info HWLOC_NAME(solaris_get_chip_info)
#endif /* HWLOC_SYM_TRANSFORM */ #endif /* HWLOC_SYM_TRANSFORM */

Просмотреть файл

@ -1,5 +1,5 @@
/* /*
* Copyright © 2013-2017 Inria. All rights reserved. * Copyright © 2013-2018 Inria. All rights reserved.
* See COPYING in top-level directory. * See COPYING in top-level directory.
*/ */
@ -29,7 +29,7 @@ extern "C" {
* *
* Then it must find a virtual memory area of that size that is available * Then it must find a virtual memory area of that size that is available
* in all processes (identical virtual addresses in all processes). * in all processes (identical virtual addresses in all processes).
* On Linux, this can be done by comparing holes found in /proc/<pid>/maps * On Linux, this can be done by comparing holes found in /proc/\<pid\>/maps
* for each process. * for each process.
* *
* Once found, it must open a destination file for storing the buffer, * Once found, it must open a destination file for storing the buffer,
@ -51,8 +51,8 @@ extern "C" {
* \note Flags \p flags are currently unused, must be 0. * \note Flags \p flags are currently unused, must be 0.
*/ */
HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology, HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology,
size_t *lengthp, size_t *lengthp,
unsigned long flags); unsigned long flags);
/** \brief Duplicate a topology to a shared memory file. /** \brief Duplicate a topology to a shared memory file.
* *
@ -80,9 +80,9 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology,
* or \p length aren't page-aligned. * or \p length aren't page-aligned.
*/ */
HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology, HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
int fd, hwloc_uint64_t fileoffset, int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length, void *mmap_address, size_t length,
unsigned long flags); unsigned long flags);
/** \brief Adopt a shared memory topology stored in a file. /** \brief Adopt a shared memory topology stored in a file.
* *
@ -110,15 +110,22 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
* that created the shared topology also placed userdata-pointed buffers * that created the shared topology also placed userdata-pointed buffers
* in shared memory. * in shared memory.
* *
* \note This function takes care of calling hwloc_topology_abi_check().
*
* \return -1 with errno set to EBUSY if the virtual memory mapping defined * \return -1 with errno set to EBUSY if the virtual memory mapping defined
* by \p mmap_address and \p length isn't available in the process. * by \p mmap_address and \p length isn't available in the process.
*
* \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address * \return -1 with errno set to EINVAL if \p fileoffset, \p mmap_address
* or \p length aren't page-aligned. * or \p length aren't page-aligned, or do not match what was given to
* hwloc_shmem_topology_write() earlier.
*
* \return -1 with errno set to EINVAL if the layout of the topology structure
* is different between the writer process and the adopter process.
*/ */
HWLOC_DECLSPEC int hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp, HWLOC_DECLSPEC int hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
int fd, hwloc_uint64_t fileoffset, int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length, void *mmap_address, size_t length,
unsigned long flags); unsigned long flags);
/** @} */ /** @} */

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше