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-sizeof.f90
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_sizes.h

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

@ -1,7 +1,7 @@
/*
* Copyright (c) 2012-2013 Los Alamos National Security, LLC.
* 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-2016 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
@ -49,10 +49,9 @@ typedef uint32_t ompi_vpid_t;
/* some local storage */
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;
#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)
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_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,
const opal_process_name_t* name1,
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,
const opal_process_name_t *name);
#define OMPI_LOCAL_JOBID(jobid) jobid
#define OMPI_JOB_FAMILY(jobid) 0
/* do a little with the "family" param to avoid compiler warnings */
#define OMPI_LOCAL_JOBID(n) \
( (n) & 0x0000ffff)
#define OMPI_JOB_FAMILY(n) \
(((n) >> 16) & 0x0000ffff)
#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) \
((family & 0x0000) | local)
OMPI_CONSTRUCT_LOCAL_JOBID(OMPI_CONSTRUCT_JOB_FAMILY(family), local)
/* This is the DSS tag to serialize a proc name */
#define OMPI_NAME OPAL_NAME

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

@ -1,7 +1,7 @@
/*
* Copyright (c) 2012-2013 Los Alamos National Security, LLC.
* 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
* of Tennessee Research Foundation. All rights
* reserved.
@ -34,11 +34,13 @@
#include "opal/util/opal_getcwd.h"
#include "opal/util/os_path.h"
#include "opal/util/os_dirpath.h"
#include "opal/util/printf.h"
#include "opal/util/proc.h"
#include "opal/util/show_help.h"
#include "opal/mca/hwloc/base/base.h"
#include "opal/mca/pmix/base/base.h"
#include "opal/threads/threads.h"
#include "opal/threads/tsd.h"
#include "opal/class/opal_list.h"
#include "opal/dss/dss.h"
@ -57,7 +59,6 @@ extern ompi_rte_component_t mca_rte_pmix_component;
/* storage to support OMPI */
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_proc_my_name = {0, 0};
hwloc_cpuset_t ompi_proc_applied_binding = NULL;
pmix_process_info_t pmix_process_info = {0};
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 int _setup_job_session_dir(char **sdir);
#define ORTE_SCHEMA_DELIMITER_CHAR '.'
#define ORTE_SCHEMA_WILDCARD_CHAR '*'
#define ORTE_SCHEMA_WILDCARD_STRING "*"
#define ORTE_SCHEMA_INVALID_CHAR '$'
#define ORTE_SCHEMA_INVALID_STRING "$"
#define OPAL_SCHEMA_DELIMITER_CHAR '.'
#define OPAL_SCHEMA_WILDCARD_CHAR '*'
#define OPAL_SCHEMA_WILDCARD_STRING "*"
#define OPAL_SCHEMA_INVALID_CHAR '$'
#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,
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 */
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 */
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
* 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;
} else if (0 == strcmp(temp, ORTE_SCHEMA_INVALID_STRING)) {
} else if (0 == strcmp(temp, OPAL_SCHEMA_INVALID_STRING)) {
job = pmix_name_invalid.jobid;
} else {
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
* 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;
} else if (0 == strcmp(token, ORTE_SCHEMA_INVALID_STRING)) {
} else if (0 == strcmp(token, OPAL_SCHEMA_INVALID_STRING)) {
vpid = pmix_name_invalid.vpid;
} else {
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
*/
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) {
asprintf(&tmp, "%s", ORTE_SCHEMA_INVALID_STRING);
asprintf(&tmp, "%s", OPAL_SCHEMA_INVALID_STRING);
} else {
asprintf(&tmp, "%lu", (unsigned long)name->jobid);
}
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) {
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 {
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);
@ -233,12 +398,103 @@ int ompi_rte_convert_process_name_to_string(char** name_string,
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 ret;
char *error = NULL;
opal_process_name_t pname;
opal_proc_t *myname;
opal_proc_t *myproc;
int u32, *u32ptr;
uint16_t u16, *u16ptr;
char **peers=NULL, *mycpuset;
@ -253,6 +509,16 @@ int ompi_rte_init(int *pargc, char ***pargv)
u16ptr = &u16;
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 */
if (OPAL_SUCCESS != (ret = opal_init(pargc, pargv))) {
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, so transfer them here */
myname = opal_proc_local_get();
pmix_proc_my_name = myname->proc_name;
pmix_process_info.my_name.jobid = OPAL_PROC_MY_NAME.jobid;
pmix_process_info.my_name.vpid = OPAL_PROC_MY_NAME.vpid;
/* 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 */
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) {
error = "getting local rank";
goto error;
@ -300,7 +567,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* get our node rank from PMI */
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) {
error = "getting node rank";
goto error;
@ -308,8 +575,10 @@ int ompi_rte_init(int *pargc, char ***pargv)
pmix_process_info.my_node_rank = u16;
/* 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,
&pmix_name_wildcard, &u32ptr, OPAL_UINT32);
&pname, &u32ptr, OPAL_UINT32);
if (OPAL_SUCCESS != ret) {
error = "getting job size";
goto error;
@ -319,8 +588,8 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* push into the environ for pickup in MPI layer for
* MPI-3 required info key
*/
if (NULL == getenv(OPAL_MCA_PREFIX"orte_ess_num_procs")) {
asprintf(&ev1, OPAL_MCA_PREFIX"orte_ess_num_procs=%d", pmix_process_info.num_procs);
if (NULL == getenv(OPAL_MCA_PREFIX"opal_ess_num_procs")) {
asprintf(&ev1, OPAL_MCA_PREFIX"opal_ess_num_procs=%d", pmix_process_info.num_procs);
putenv(ev1);
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 */
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) {
pmix_process_info.app_num = u32;
} else {
@ -342,7 +611,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* get the number of local peers - required for wireup of
* shared memory BTL */
OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_SIZE,
&pmix_name_wildcard, &u32ptr, OPAL_UINT32);
&pname, &u32ptr, OPAL_UINT32);
if (OPAL_SUCCESS == ret) {
pmix_process_info.num_local_peers = u32 - 1; // want number besides ourselves
} else {
@ -353,17 +622,17 @@ int ompi_rte_init(int *pargc, char ***pargv)
* we can use the jobfam and stepid as unique keys
* because they are unique values assigned by the RM
*/
if (NULL == getenv(OPAL_MCA_PREFIX"orte_precondition_transports")) {
unique_key[0] = (pmix_proc_my_name.jobid & 0xff00) >> 16;
unique_key[1] = pmix_proc_my_name.jobid & 0x00ff;
if (NULL == getenv(OPAL_MCA_PREFIX"opal_precondition_transports")) {
unique_key[0] = (pmix_process_info.my_name.jobid & 0xff00) >> 16;
unique_key[1] = pmix_process_info.my_name.jobid & 0x00ff;
if (NULL == (string_key = pre_condition_transports_print(unique_key))) {
OPAL_ERROR_LOG(OPAL_ERR_OUT_OF_RESOURCE);
return OPAL_ERR_OUT_OF_RESOURCE;
}
opal_output_verbose(2, ompi_rte_base_framework.framework_output,
"%s transport key %s",
OPAL_NAME_PRINT(pmix_proc_my_name), string_key);
asprintf(&envar, OPAL_MCA_PREFIX"orte_precondition_transports=%s", string_key);
OPAL_NAME_PRINT(pmix_process_info.my_name), string_key);
asprintf(&envar, OPAL_MCA_PREFIX"opal_precondition_transports=%s", string_key);
putenv(envar);
added_transport_keys = true;
/* 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 */
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) {
pmix_process_info.job_session_dir = val;
val = NULL;
@ -394,7 +663,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
}
/* retrieve the 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) {
peers = opal_argv_split(val, ',');
free(val);
@ -410,16 +679,16 @@ int ompi_rte_init(int *pargc, char ***pargv)
/* identify our location */
val = NULL;
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) {
mycpuset = val;
} else {
mycpuset = NULL;
}
pname.jobid = pmix_proc_my_name.jobid;
pname.jobid = pmix_process_info.my_name.jobid;
for (i=0; NULL != peers[i]; i++) {
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 */
u16 = OPAL_PROC_ALL_LOCAL;
} else {
@ -439,7 +708,7 @@ int ompi_rte_init(int *pargc, char ***pargv)
kv->type = OPAL_UINT16;
OPAL_OUTPUT_VERBOSE((1, ompi_rte_base_framework.framework_output,
"%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)));
kv->data.uint16 = u16;
ret = opal_pmix.store_local(&pname, kv);
@ -514,10 +783,10 @@ int ompi_rte_finalize(void)
* so we leave that structure intact
*/
if (added_transport_keys) {
unsetenv(OPAL_MCA_PREFIX"orte_precondition_transports");
unsetenv(OPAL_MCA_PREFIX"opal_precondition_transports");
}
if (added_num_procs) {
unsetenv(OPAL_MCA_PREFIX"orte_ess_num_procs");
unsetenv(OPAL_MCA_PREFIX"opal_ess_num_procs");
}
if (added_app_ctx) {
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,
pmix_process_info.nodename,
(unsigned long)uid,
pmix_proc_my_name.jobid)) {
pmix_process_info.my_name.jobid)) {
pmix_process_info.job_session_dir = NULL;
return OPAL_ERR_OUT_OF_RESOURCE;
}

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

@ -10,7 +10,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* 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 Los Alamos National Security, LLC. All rights
* reserved.
@ -1524,7 +1524,11 @@ static uint64_t calculate_total_mem (void)
if (NULL == machine) {
return 0;
}
#if HWLOC_API_VERSION < 0x20000
return machine->memory.total_memory;
#else
return machine->total_memory;
#endif
}
/* 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,
unsigned cache_level,
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 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)
{
ptr->available = NULL;
ptr->npus_calculated = false;
ptr->npus = 0;
ptr->idx = UINT_MAX;
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,
opal_object_t,
obj_data_const, obj_data_dest);
obj_data_const, NULL);
static void sum_const(opal_hwloc_summary_t *ptr)
{

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

@ -10,7 +10,7 @@
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* 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.
* All rights reserved.
* Copyright (c) 2013-2017 Intel, Inc. All rights reserved.
@ -23,6 +23,7 @@
* $HEADER$
*/
#define OPAL_HWLOC_WANT_SHMEM 1
#include "opal_config.h"
@ -149,7 +150,7 @@ int opal_hwloc_base_filter_cpus(hwloc_topology_t topo)
avail = hwloc_bitmap_alloc();
hwloc_bitmap_and(avail, root->online_cpuset, root->allowed_cpuset);
#else
avail = hwloc_bitmap_dup(root->allowed_cpuset);
avail = hwloc_bitmap_dup(root->cpuset);
#endif
OPAL_OUTPUT_VERBOSE((5, opal_hwloc_base_framework.framework_output,
"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);
#else
hwloc_bitmap_free(pucpus);
pucpus = hwloc_bitmap_dup(pu->allowed_cpuset);
pucpus = hwloc_bitmap_dup(pu->cpuset);
#endif
hwloc_bitmap_or(res, avail, pucpus);
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);
#else
hwloc_bitmap_free(pucpus);
pucpus = hwloc_bitmap_dup(pu->allowed_cpuset);
pucpus = hwloc_bitmap_dup(pu->cpuset);
#endif
hwloc_bitmap_or(res, avail, pucpus);
hwloc_bitmap_copy(avail, res);
@ -560,30 +561,6 @@ int opal_hwloc_base_report_bind_failure(const char *file,
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 */
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
* one hwthread/core. Instead, find the number of cores
* 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)) {
/* 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);
}
cnt = hwloc_get_nbobjs_inside_cpuset_by_type(topo, obj->cpuset, HWLOC_OBJ_CORE);
} else {
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
* in an attribute union. So looking for cache objects involves
* 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,
hwloc_obj_t start,
@ -747,32 +706,31 @@ static hwloc_obj_t df_search(hwloc_topology_t topo,
unsigned cache_level,
unsigned int nobj,
opal_hwloc_resource_type_t rtype,
unsigned int *idx,
unsigned int *num_objs)
{
unsigned k;
hwloc_obj_t obj;
opal_hwloc_obj_data_t *data;
int search_depth;
if (target == start->type) {
#if HWLOC_API_VERSION < 0x20000
if (HWLOC_OBJ_CACHE == start->type && cache_level != start->attr->cache.depth) {
goto notfound;
}
#endif
if (OPAL_HWLOC_LOGICAL == rtype) {
/* the hwloc tree is composed of LOGICAL objects, so the only
* time we come here is when we are looking for logical caches
*/
if (NULL != num_objs) {
/* we are counting the number of caches at this level */
*num_objs += 1;
} else if (*idx == nobj) {
/* found the specific instance of the cache level being sought */
return start;
}
*idx += 1;
search_depth = hwloc_get_type_depth(topo, target);
if (HWLOC_TYPE_DEPTH_MULTIPLE == search_depth) {
/* either v1.x Cache, or Groups */
#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
}
if (HWLOC_TYPE_DEPTH_UNKNOWN == search_depth)
return NULL;
if (OPAL_HWLOC_LOGICAL == rtype) {
if (num_objs)
*num_objs = hwloc_get_nbobjs_by_depth(topo, search_depth);
return hwloc_get_obj_by_depth(topo, search_depth, nobj);
}
if (OPAL_HWLOC_PHYSICAL == rtype) {
/* the PHYSICAL object number is stored as the os_index. When
@ -786,61 +744,30 @@ static hwloc_obj_t df_search(hwloc_topology_t topo,
* socket on the node is empty), then the count we return will
* be wrong!
*/
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;
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;
}
} else if (*idx == nobj) {
/* found the specific instance of the cache level being sought */
return start;
}
*idx += 1;
return NULL;
return found;
}
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;
}
#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) {
int idx = 0;
if (num_objs)
*num_objs = hwloc_get_nbobjs_inside_cpuset_by_depth(topo, start->cpuset, search_depth);
obj = NULL;
while ((obj = hwloc_get_next_obj_inside_cpuset_by_depth(topo, start->cpuset, search_depth, obj)) != NULL) {
if (idx == nobj)
return obj;
idx++;
}
return NULL;
}
return NULL;
}
@ -849,7 +776,7 @@ unsigned int opal_hwloc_base_get_nbobjs_by_type(hwloc_topology_t topo,
unsigned cache_level,
opal_hwloc_resource_type_t rtype)
{
unsigned int num_objs, idx;
unsigned int num_objs;
hwloc_obj_t obj;
opal_hwloc_summary_t *sum;
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 */
num_objs = 0;
idx = 0;
obj = hwloc_get_root_obj(topo);
/* 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 */
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 */
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;
}
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
* 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,
opal_hwloc_resource_type_t rtype)
{
unsigned int idx;
hwloc_obj_t obj;
/* 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 */
idx = 0;
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,
@ -1179,7 +985,6 @@ static int socket_core_to_cpu_set(char *socket_core_list,
int lower_range, upper_range;
int socket_id, core_id;
hwloc_obj_t socket, core;
unsigned int idx;
hwloc_obj_type_t obj_type = HWLOC_OBJ_CORE;
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++) {
core_id = atoi(list[j]);
/* get that object */
idx = 0;
if (NULL == (core = df_search(topo, socket, obj_type, 0,
core_id, OPAL_HWLOC_AVAILABLE,
&idx, NULL))) {
NULL))) {
opal_argv_free(list);
opal_argv_free(range);
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]);
for (core_id=lower_range; core_id <= upper_range; core_id++) {
/* get that object */
idx = 0;
if (NULL == (core = df_search(topo, socket, obj_type, 0,
core_id, OPAL_HWLOC_AVAILABLE,
&idx, NULL))) {
NULL))) {
opal_argv_free(range);
opal_argv_free(socket_core);
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).
AS_IF([test "$opal_hwloc_dir" != ""],
[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_include="hwloc.h"
opal_hwloc_shmem_include="hwloc/shmem.h"
opal_hwloc_openfabrics_include="hwloc/openfabrics-verbs.h"])
AC_DEFINE_UNQUOTED(MCA_hwloc_external_header,
["$opal_hwloc_include"],
[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,
["$opal_hwloc_openfabrics_include"],
[Location of external hwloc OpenFabrics header])

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

@ -43,6 +43,15 @@ BEGIN_C_DECLS
# 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
#define HWLOC_OBJ_NUMANODE HWLOC_OBJ_NODE
#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 */
typedef struct {
opal_object_t super;
hwloc_cpuset_t available;
bool npus_calculated;
unsigned int npus;
unsigned int idx;

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

@ -30,16 +30,16 @@ EXTRA_DIST = \
SUBDIRS = hwloc
# Headers and sources
headers = hwloc2a.h
sources = hwloc2a_component.c
headers = hwloc201.h
sources = hwloc201_component.c
# We only ever build this component statically
noinst_LTLIBRARIES = libmca_hwloc_hwloc2a.la
libmca_hwloc_hwloc2a_la_SOURCES = $(headers) $(sources)
nodist_libmca_hwloc_hwloc2a_la_SOURCES = $(nodist_headers)
libmca_hwloc_hwloc2a_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc2a_LDFLAGS)
libmca_hwloc_hwloc2a_la_LIBADD = $(opal_hwloc_hwloc2a_LIBS)
libmca_hwloc_hwloc2a_la_DEPENDENCIES = \
noinst_LTLIBRARIES = libmca_hwloc_hwloc201.la
libmca_hwloc_hwloc201_la_SOURCES = $(headers) $(sources)
nodist_libmca_hwloc_hwloc201_la_SOURCES = $(nodist_headers)
libmca_hwloc_hwloc201_la_LDFLAGS = -module -avoid-version $(opal_hwloc_hwloc201_LDFLAGS)
libmca_hwloc_hwloc201_la_LIBADD = $(opal_hwloc_hwloc201_LIBS)
libmca_hwloc_hwloc201_la_DEPENDENCIES = \
$(HWLOC_top_builddir)/hwloc/libhwloc_embedded.la
# 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/inlines.h \
hwloc/include/hwloc/intel-mic.h \
hwloc/include/hwloc/myriexpress.h \
hwloc/include/hwloc/nvml.h \
hwloc/include/hwloc/opencl.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
#
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
#
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])
$4="static"
AC_MSG_RESULT([$$4])
])
# Include hwloc m4 files
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_pkg.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_check_attributes.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_check_visibility.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_check_vendor.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_components.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/hwloc_internal.m4)
m4_include(opal/mca/hwloc/hwloc2a/hwloc/config/netloc.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_pkg.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_check_attributes.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_check_visibility.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_check_vendor.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_components.m4)
m4_include(opal/mca/hwloc/hwloc201/hwloc/config/hwloc_internal.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],[
OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc2a_basedir])
AC_DEFUN([MCA_opal_hwloc_hwloc201_POST_CONFIG],[
OPAL_VAR_SCOPE_PUSH([opal_hwloc_hwloc201_basedir])
# 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
# file to include in opal/mca/hwloc/hwloc-internal.h
opal_hwloc_hwloc2a_basedir=opal/mca/hwloc/hwloc2a
opal_hwloc_base_include="$opal_hwloc_hwloc2a_basedir/hwloc2a.h"
opal_hwloc_hwloc201_basedir=opal/mca/hwloc/hwloc201
opal_hwloc_base_include="$opal_hwloc_hwloc201_basedir/hwloc201.h"
# Add some stuff to CPPFLAGS so that the rest of the source
# tree can be built
file=$opal_hwloc_hwloc2a_basedir/hwloc
file=$opal_hwloc_hwloc201_basedir/hwloc
CPPFLAGS="-I$OPAL_TOP_SRCDIR/$file/include $CPPFLAGS"
AS_IF([test "$OPAL_TOP_BUILDDIR" != "$OPAL_TOP_SRCDIR"],
[CPPFLAGS="-I$OPAL_TOP_BUILDDIR/$file/include $CPPFLAGS"])
@ -66,41 +66,41 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_POST_CONFIG],[
])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
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
opal_hwloc_hwloc2a_basedir=opal/mca/hwloc/hwloc2a
opal_hwloc_hwloc2a_support=no
opal_hwloc_hwloc201_basedir=opal/mca/hwloc/hwloc201
opal_hwloc_hwloc201_support=no
AS_IF([test "$with_hwloc" = "internal" || test -z "$with_hwloc" || test "$with_hwloc" = "yes"],
[opal_hwloc_external="no"],
[opal_hwloc_external="yes"])
opal_hwloc_hwloc2a_save_CPPFLAGS=$CPPFLAGS
opal_hwloc_hwloc2a_save_LDFLAGS=$LDFLAGS
opal_hwloc_hwloc2a_save_LIBS=$LIBS
opal_hwloc_hwloc201_save_CPPFLAGS=$CPPFLAGS
opal_hwloc_hwloc201_save_LDFLAGS=$LDFLAGS
opal_hwloc_hwloc201_save_LIBS=$LIBS
# Run the hwloc configuration - if no external hwloc, then set the prefixi
# to minimize the chance that someone will use the internal symbols
AS_IF([test "$opal_hwloc_external" = "no" &&
test "$with_hwloc" != "future"],
[HWLOC_SET_SYMBOL_PREFIX([opal_hwloc2a_])])
[HWLOC_SET_SYMBOL_PREFIX([opal_hwloc201_])])
# save XML or graphical options
opal_hwloc_hwloc2a_save_cairo=$enable_cairo
opal_hwloc_hwloc2a_save_xml=$enable_xml
opal_hwloc_hwloc2a_save_static=$enable_static
opal_hwloc_hwloc2a_save_shared=$enable_shared
opal_hwloc_hwloc2a_save_plugins=$enable_plugins
opal_hwloc_hwloc2a_save_mode=$hwloc_mode
opal_hwloc_hwloc201_save_cairo=$enable_cairo
opal_hwloc_hwloc201_save_xml=$enable_xml
opal_hwloc_hwloc201_save_static=$enable_static
opal_hwloc_hwloc201_save_shared=$enable_shared
opal_hwloc_hwloc201_save_plugins=$enable_plugins
opal_hwloc_hwloc201_save_mode=$hwloc_mode
# never enable hwloc's graphical option
enable_cairo=no
@ -131,22 +131,22 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_CONFIG],[
# hwloc checks for compiler visibility, and its needs to do
# this without "picky" flags.
opal_hwloc_hwloc2a_save_cflags=$CFLAGS
opal_hwloc_hwloc201_save_cflags=$CFLAGS
CFLAGS=$OPAL_CFLAGS_BEFORE_PICKY
AS_IF([test -n "$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_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
opal_hwloc_hwloc2a_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_hwloc2a_support=yes
opal_hwloc_hwloc201_LDFLAGS='$(HWLOC_EMBEDDED_LDFLAGS)'
opal_hwloc_hwloc201_LIBS='$(OPAL_TOP_BUILDDIR)/'"$opal_hwloc_hwloc201_basedir"'/hwloc/hwloc/libhwloc_embedded.la $(HWLOC_EMBEDDED_LIBS)'
opal_hwloc_hwloc201_support=yes
AC_DEFINE_UNQUOTED([HWLOC_HWLOC2a_HWLOC_VERSION],
AC_DEFINE_UNQUOTED([HWLOC_HWLOC201_HWLOC_VERSION],
["$HWLOC_VERSION"],
[Version of hwloc])
@ -159,35 +159,35 @@ AC_DEFUN([MCA_opal_hwloc_hwloc2a_CONFIG],[
],
[AC_MSG_CHECKING([whether hwloc configure succeeded])
AC_MSG_RESULT([no])
opal_hwloc_hwloc2a_support=no])
CFLAGS=$opal_hwloc_hwloc2a_save_cflags
opal_hwloc_hwloc201_support=no])
CFLAGS=$opal_hwloc_hwloc201_save_cflags
# Restore some env variables, if necessary
AS_IF([test -n "$opal_hwloc_hwloc2a_save_cairo"],
[enable_cairo=$opal_hwloc_hwloc2a_save_cairo])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_xml"],
[enable_xml=$opal_hwloc_hwloc2a_save_xml])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_static"],
[enable_static=$opal_hwloc_hwloc2a_save_static])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_shared"],
[enable_shared=$opal_hwloc_hwloc2a_save_shared])
AS_IF([test -n "$opal_hwloc_hwloc2a_save_plugins"],
[enable_plugins=$opal_hwloc_hwloc2a_save_shared])
AS_IF([test -n "$opal_hwloc_hwloc201_save_cairo"],
[enable_cairo=$opal_hwloc_hwloc201_save_cairo])
AS_IF([test -n "$opal_hwloc_hwloc201_save_xml"],
[enable_xml=$opal_hwloc_hwloc201_save_xml])
AS_IF([test -n "$opal_hwloc_hwloc201_save_static"],
[enable_static=$opal_hwloc_hwloc201_save_static])
AS_IF([test -n "$opal_hwloc_hwloc201_save_shared"],
[enable_shared=$opal_hwloc_hwloc201_save_shared])
AS_IF([test -n "$opal_hwloc_hwloc201_save_plugins"],
[enable_plugins=$opal_hwloc_hwloc201_save_shared])
CPPFLAGS=$opal_hwloc_hwloc2a_save_CPPFLAGS
LDFLAGS=$opal_hwloc_hwloc2a_save_LDFLAGS
LIBS=$opal_hwloc_hwloc2a_save_LIBS
CPPFLAGS=$opal_hwloc_hwloc201_save_CPPFLAGS
LDFLAGS=$opal_hwloc_hwloc201_save_LDFLAGS
LIBS=$opal_hwloc_hwloc201_save_LIBS
AC_SUBST([opal_hwloc_hwloc2a_CFLAGS])
AC_SUBST([opal_hwloc_hwloc2a_CPPFLAGS])
AC_SUBST([opal_hwloc_hwloc2a_LDFLAGS])
AC_SUBST([opal_hwloc_hwloc2a_LIBS])
AC_SUBST([opal_hwloc_hwloc201_CFLAGS])
AC_SUBST([opal_hwloc_hwloc201_CPPFLAGS])
AC_SUBST([opal_hwloc_hwloc201_LDFLAGS])
AC_SUBST([opal_hwloc_hwloc201_LIBS])
# Finally, add some flags to the wrapper compiler so that our
# headers can be found.
hwloc_hwloc2a_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS"
hwloc_hwloc2a_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS"
hwloc_hwloc2a_WRAPPER_EXTRA_CPPFLAGS='-I${pkgincludedir}/'"$opal_hwloc_hwloc2a_basedir/hwloc/include"
hwloc_hwloc201_WRAPPER_EXTRA_LDFLAGS="$HWLOC_EMBEDDED_LDFLAGS"
hwloc_hwloc201_WRAPPER_EXTRA_LIBS="$HWLOC_EMBEDDED_LIBS"
hwloc_hwloc201_WRAPPER_EXTRA_CPPFLAGS='-I${pkgincludedir}/'"$opal_hwloc_hwloc201_basedir/hwloc/include"
# If we are not building the internal hwloc, then indicate that
# 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).
AS_IF([test "$opal_hwloc_external" = "yes"],
[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_HWLOC_TOPOLOGY_DUP], [1])])
# Done!
AS_IF([test "$opal_hwloc_hwloc2a_support" = "yes"],
AS_IF([test "$opal_hwloc_hwloc201_support" = "yes"],
[$1],
[$2])

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

@ -1,29 +1,44 @@
netloc Authors
==============
hwloc Authors
=============
The following cumulative list contains the names of most individuals who
have committed code to the hwloc repository.
The following cumulative list contains the names of most individuals
who have committed code to the hwloc repository
(either directly or through a third party).
Name Affiliation(s)
--------------------------- --------------------
Grzegorz Andrejczuk Intel
Cédric Augonnet University of Bordeaux
Guillaume Beauchamp Inria
Ahmad Boissetri Binzagr Inria
Cyril Bordage Inria
Nicholas Buroker UWL
Christopher M. Cantalupo Intel
Jérôme Clet-Ortega University of Bordeaux
Ludovic Courtès Inria
Clément Foyer Inria
Nathalie Furmento CNRS
Bryon Gloden
Brice Goglin Inria
Gilles Gouaillardet RIST
Joshua Hursey UWL
Alexey Kardashevskiy IBM
Rob Latham ANL
Douglas MacFarland UWL
Marc Marí BSC
Jonathan L Peyton Intel
Piotr Luc Intel
Antoine Rougier intern from University of Bordeaux
Jeff Squyres Cisco
Samuel Thibault University of Bordeaux
Jean-Yves VET DDN
Benjamin Worpitz
Jeff Zhao Zhaoxin
Affiliaion abbreviations:
-------------------------
ANL = Argonne National Lab
BSC = Barcelona Supercomputing Center
Cisco = Cisco Systems, Inc.
CNRS = Centre national de la recherche scientifique (France)
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-2017 Inria. All rights reserved.
Copyright © 2009-2018 Inria. All rights reserved.
Copyright © 2009-2013 Université Bordeaux
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).
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
-------------
* The ABI of the library has changed. For instance some hwloc_obj fields
were reordered.
- HWLOC_API_VERSION and hwloc_get_api_version() now give 0x00020000.
- 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
* Major changes
*** The ABI of the library has changed. ***
For instance some hwloc_obj fields were reordered, added or removed, see below.
+ HWLOC_API_VERSION and hwloc_get_api_version() now give 0x00020000.
+ See "How do I handle ABI breaks and API upgrades ?" in the FAQ
and "Upgrading to hwloc 2.0 API" in the documentation.
* 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,
a single NUMA object is added to describe the entire machine memory.
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
and HWLOC_OBJ_L[1-3]ICACHE that remove the need to disambiguate levels
when looking for caches with _by_type() functions.
- New hwloc_obj_type_is_{,d,i}cache() functions may be used to check whether
a given type is a cache.
+ Replace hwloc_topology_ignore*() functions with hwloc_topology_set_type_filter()
+ Reworked ignoring/filtering API
- Replace hwloc_topology_ignore*() functions with hwloc_topology_set_type_filter()
and hwloc_topology_set_all_types_filter().
- Contrary to hwloc_topology_ignore_{type,all}_keep_structure() which
. Contrary to hwloc_topology_ignore_{type,all}_keep_structure() which
removed individual objects, HWLOC_TYPE_FILTER_KEEP_STRUCTURE only removes
entire levels (so that topology do not become too asymmetric).
+ Remove HWLOC_TOPOLOGY_FLAG_ICACHES in favor of hwloc_topology_set_icache_types_filter()
- Remove HWLOC_TOPOLOGY_FLAG_ICACHES in favor of hwloc_topology_set_icache_types_filter()
with HWLOC_TYPE_FILTER_KEEP_ALL.
+ Remove HWLOC_TOPOLOGY_FLAG_IO_DEVICES, _IO_BRIDGES and _WHOLE_IO in favor of
- Remove HWLOC_TOPOLOGY_FLAG_IO_DEVICES, _IO_BRIDGES and _WHOLE_IO in favor of
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
by default anymore.
- 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,
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
hwloc/diff.h do not need a topology as first parameter anymore.
+ hwloc_parse_cpumap_file () superseded by hwloc_linux_read_path_as_cpumask()
in hwloc/linux.h.
* Tools
- lstopo and hwloc-info have a new --filter option matching the new filtering API.
- hwloc-distances was removed and replaced with lstopo --distances.
* Plugin API
+ hwloc_fill_object_sets() is renamed into hwloc_obj_add_children_sets().
* Misc
+ Linux OS devices do not have to be attached through PCI anymore,
+ 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.
+ Add a SectorSize attribute to block OS devices on Linux.
+ Misc MemoryModule objects are only added when full I/O discovery is enabled
(WHOLE_IO topology flag).
+ Do not set PCI devices and bridges name automatically. Vendor and device
names are already in info attributes.
+ Exporting to synthetic now ignores I/O and Misc objects.
+ XML and Synthetic export functions have moved to hwloc/export.h,
automatically included from hwloc.h.
+ Separate OS device discovery from PCI discovery. Only the latter is disabled
- 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
+ lstopo and hwloc-info have a new --filter option matching the new filtering API.
+ lstopo can be given --children-layout=plain to force a basic displaying
of memory and normal children together below their parent.
+ hwloc-distances was removed and replaced with lstopo --distances.
* Misc
+ Exports
- Exporting to synthetic now ignores I/O and Misc objects.
+ PCI discovery
- Separate OS device discovery from PCI discovery. Only the latter is disabled
with --disable-pci at configure time. Both may be disabled with --disable-io.
+ The old `libpci' component name from hwloc 1.6 is not supported anymore,
- The `linuxpci' component is now renamed into `linuxio'.
- The old `libpci' component name from hwloc 1.6 is not supported anymore,
only the `pci' name from hwloc 1.7 is now recognized.
+ The `linuxpci' component is now renamed into `linuxio'.
+ The HWLOC_PCI_<domain>_<bus>_LOCALCPUS environment variables are superseded
- The HWLOC_PCI_<domain>_<bus>_LOCALCPUS environment variables are superseded
with a single HWLOC_PCI_LOCALITY where bus ranges may be specified.
+ Add HWLOC_SYNTHETIC environment variable to enforce a synthetic topology
- Do not set PCI devices and bridges name automatically. Vendor and device
names are already in info attributes.
+ Components and discovery
- Add HWLOC_SYNTHETIC environment variable to enforce a synthetic topology
as if hwloc_topology_set_synthetic() had been called.
+ HWLOC_COMPONENTS doesn't support xml or synthetic component attributes
- HWLOC_COMPONENTS doesn't support xml or synthetic component attributes
anymore, they should be passed in HWLOC_XMLFILE or HWLOC_SYNTHETIC instead.
+ HWLOC_COMPONENTS takes precedence over other environment variables
- HWLOC_COMPONENTS takes precedence over other environment variables
for selecting components.
+ Remove the dependency on libnuma on Linux.
+ hwloc now requires a C99 compliant compiler.
Version 1.11.9
--------------
* 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

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

@ -11,12 +11,15 @@ platforms.
hwloc is actually made of two subprojects distributed together:
* The original hwloc project for describing the internals of computing nodes.
It is described in details between sections Hardware Locality (hwloc)
Introduction and Network Locality (netloc).
It is described in details starting at section Hardware Locality (hwloc)
Introduction.
* The network-oriented companion called netloc (Network Locality), described
in details starting at section Network Locality (netloc). Netloc may be
disabled, but the original hwloc cannot. Both hwloc and netloc APIs are
documented after these sections.
in details starting with section Network Locality (netloc).
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
@ -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.
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
code can be directly cloned from Git:
Basic Installation
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.
Installation by itself is the fairly common GNU-based process:
Installation is the fairly common GNU-based process:
shell$ ./configure --prefix=...
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
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.

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

@ -9,7 +9,7 @@
major=2
minor=0
release=0
release=2
# 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
@ -18,7 +18,7 @@ release=0
# requirement is that it must be entirely printable ASCII characters
# and have no white space.
greek=a1
greek=rc1
# 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
# greek). This is only set to 1 when making snapshot tarballs.
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
# 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
# format.
libhwloc_so_version=0:0:0
libhwloc_so_version=15:0:0
libnetloc_so_version=0:0:0
# Please also update the <TargetName> lines in contrib/windows/libhwloc.vcxproj

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

@ -1,6 +1,6 @@
dnl -*- Autoconf -*-
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 © 2004-2005 The Trustees of Indiana University and Indiana
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 © 2012 Blue Brain Project, BBP/EPFL. 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.
# 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], [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.
if test "x$GCC" = "xyes"; then
HWLOC_GCC_CFLAGS="-Wall -Wmissing-prototypes -Wundef"
@ -471,6 +480,11 @@ EOF])
AC_CHECK_DECLS([_putenv], [], [], [AC_INCLUDES_DEFAULT])
# Could add mkdir and access for hwloc-gather-cpuid.c on Windows
if test "x$hwloc_linux" != "xyes" ; then
# Don't detect sysctl* on Linux because its sysctl() syscall is
# long deprecated and unneeded. Some libc still expose the symbol
# and raise a big warning at link time.
# Do a full link test instead of just using AC_CHECK_FUNCS, which
# just checks to see if the symbol exists or not. For example,
# the prototype of sysctl uses u_int, which on some platforms
@ -478,20 +492,27 @@ EOF])
# or other similar definitions. So while the symbols "sysctl" and
# "sysctlbyname" might still be available in libc (which autoconf
# checks for), they might not be actually usable.
AC_MSG_CHECKING([for sysctl])
AC_TRY_LINK([
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
],
[return sysctl(NULL,0,NULL,NULL,NULL,0);],
AC_DEFINE([HAVE_SYSCTL],[1],[Define to '1' if sysctl is present and usable]))
[AC_DEFINE([HAVE_SYSCTL],[1],[Define to '1' if sysctl 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_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([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])
fi
AC_CHECK_DECLS([sched_getcpu],,[:],[[
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#include <sched.h>
]])
_HWLOC_CHECK_DECL([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"],[
@ -749,23 +777,37 @@ EOF])
hwloc_opencl_happy=no
if test "x$enable_io" != xno && test "x$enable_opencl" != "xno"; then
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_LIB([OpenCL], [clGetDeviceIDs], [HWLOC_OPENCL_LIBS="-lOpenCL"], [hwloc_opencl_happy=no])
], [hwloc_opencl_happy=no])
;;
esac
fi
AC_SUBST(HWLOC_OPENCL_CFLAGS)
AC_SUBST(HWLOC_OPENCL_LIBS)
# Check if required extensions are available
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
AC_SUBST(HWLOC_OPENCL_LDFLAGS)
# If we asked for opencl support but couldn't deliver, fail
AS_IF([test "$enable_opencl" = "yes" -a "$hwloc_opencl_happy" = "no"],
[AC_MSG_WARN([Specified --enable-opencl switch, but could not])
@ -1085,6 +1127,7 @@ EOF])
HWLOC_REQUIRES="$HWLOC_PCIACCESS_REQUIRES $HWLOC_REQUIRES"])
AS_IF([test "$hwloc_opencl_component" = "static"],
[HWLOC_LIBS="$HWLOC_LIBS $HWLOC_OPENCL_LIBS"
HWLOC_LDFLAGS="$HWLOC_LDFLAGS $HWLOC_OPENCL_LDFLAGS"
HWLOC_CFLAGS="$HWLOC_CFLAGS $HWLOC_OPENCL_CFLAGS"
HWLOC_REQUIRES="$HWLOC_OPENCL_REQUIRES $HWLOC_REQUIRES"])
AS_IF([test "$hwloc_cuda_component" = "static"],
@ -1178,8 +1221,6 @@ AC_DEFUN([HWLOC_DO_AM_CONDITIONALS],[
[test "x$hwloc_have_cuda" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_GL],
[test "x$hwloc_have_gl" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_MYRIEXPRESS],
[test "x$hwloc_have_myriexpress" = "xyes"])
AM_CONDITIONAL([HWLOC_HAVE_CUDART],
[test "x$hwloc_have_cudart" = "xyes"])
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],
[Whether your compiler has __attribute__ weak alias or not])
])

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

@ -1,6 +1,6 @@
dnl -*- Autoconf -*-
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 © 2004-2005 The Trustees of Indiana University and Indiana
dnl University Research and Technology
@ -122,7 +122,7 @@ AC_DEFUN([HWLOC_SETUP_DOCS],[
EOF
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)])
test "x$enable_doxygen" = x && enable_doxygen=no],
[AC_MSG_RESULT([yes])
@ -322,12 +322,15 @@ EOF
])
# 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(
hwloc_config_prefix[utils/Makefile]
hwloc_config_prefix[utils/hwloc/Makefile]
hwloc_config_prefix[utils/lstopo/Makefile]
hwloc_config_prefix[hwloc.pc]
hwloc_config_prefix[netloc/Makefile]
hwloc_config_prefix[utils/netloc/infiniband/Makefile]
hwloc_config_prefix[utils/netloc/draw/Makefile]
hwloc_config_prefix[utils/netloc/scotch/Makefile]
@ -366,16 +369,6 @@ EOF
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(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/test-hwloc-dump-hwdata.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/misc/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-hwloc-dump-hwdata/test-hwloc-dump-hwdata.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])
# These links are only needed in standalone mode. It would

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

@ -2,7 +2,7 @@ dnl -*- Autoconf -*-
dnl
dnl Copyright © 2014 Cisco Systems, Inc. All rights reserved.
dnl
dnl Copyright © 2014-2017 Inria. All rights reserved.
dnl Copyright © 2014-2018 Inria. All rights reserved.
dnl See COPYING in top-level directory.
# Main hwloc m4 macro, to be invoked by the user
@ -25,11 +25,6 @@ AC_DEFUN([NETLOC_SETUP_CORE],[
###
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
# with hwloc. I.e., if the flag already exists in hwloc, there's
# no need to put it here.
@ -63,21 +58,12 @@ EOF])
NETLOC_EMBEDDED_CPPFLAGS=$NETLOC_CPPFLAGS
NETLOC_EMBEDDED_LDADD='$(HWLOC_top_builddir)/netloc/libnetloc_embedded.la'
NETLOC_EMBEDDED_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
])
])
NETLOC_LIBS=])
AC_SUBST(NETLOC_EMBEDDED_CFLAGS)
AC_SUBST(NETLOC_EMBEDDED_CPPFLAGS)
AC_SUBST(NETLOC_EMBEDDED_LDADD)
AC_SUBST(NETLOC_EMBEDDED_LIBS)
AC_CONFIG_FILES(
netloc_config_prefix[netloc/Makefile]
)
AS_IF([test "$netloc_happy" = "yes"],
[$2],
[$3])

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

@ -1,7 +1,7 @@
# -*- shell-script -*-
#
# 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-2014 Cisco Systems, Inc. All rights reserved.
#
@ -18,7 +18,7 @@
AC_INIT([hwloc],
[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_CONFIG_AUX_DIR(./config)
# 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_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([], [],
[AS_IF([test "$enable_netloc" = "yes"],
[AC_MSG_ERROR([Cannot build netloc core])])
@ -225,9 +225,11 @@ fi
hwloc_xml_status=basic
AS_IF([test "$hwloc_libxml2_happy" = "yes"], [hwloc_xml_status=full])
netloc_status=no
AS_IF([test "$netloc_happy" = "yes"], [netloc_status=yes])
netlocscotch_status=no
AS_IF([test "$scotch_found_headers" = "yes"], [netlocscotch_status=yes])
AS_IF([test "$netloc_happy" = "yes"], [
netlocscotch_status=without
AS_IF([test "$scotch_found_headers" = "yes"], [netlocscotch_status=with])
netloc_status="yes ($netlocscotch_status scotch)"
])
# Prepare the I/O summary
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
Graphical output (Cairo): $hwloc_cairo_happy
XML input / output: $hwloc_xml_status
Netloc functionality: $netloc_status (with scotch: $netlocscotch_status)
Netloc functionality: $netloc_status
EOF
# Plugin support

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

@ -158,3 +158,4 @@
...
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-2014 Cisco Systems, Inc. All rights reserved.
# Copyright © 2011-2012 Oracle and/or its affiliates. All rights reserved.
@ -76,7 +76,7 @@ else
plugins_LTLIBRARIES += hwloc_opencl.la
hwloc_opencl_la_SOURCES = topology-opencl.c
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 HWLOC_HAVE_OPENCL
@ -199,7 +199,7 @@ endif HWLOC_HAVE_WINDOWS
# Installable library
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
AM_CPPFLAGS += $(LTDLINCL)
@ -217,9 +217,9 @@ libhwloc_embedded_la_SOURCES = $(sources)
# XML data (only install if we're building in standalone mode)
if HWLOC_BUILD_STANDALONE
xml_DATA = $(srcdir)/hwloc.dtd
xml_DATA = $(srcdir)/hwloc.dtd $(srcdir)/hwloc2.dtd $(srcdir)/hwloc2-diff.dtd
xmldir = $(pkgdatadir)
EXTRA_DIST += hwloc.dtd
EXTRA_DIST += hwloc.dtd hwloc2.dtd hwloc2-diff.dtd
endif
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-2016 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011-2015 Cisco Systems, Inc. All rights reserved.
* 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 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)) {
errno = EINVAL;
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 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)) {
errno = EINVAL;
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_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)) {
errno = EINVAL;
return -1;
@ -312,10 +280,21 @@ hwloc_fix_membind_cpuset(hwloc_topology_t topology, hwloc_nodeset_t nodeset, hwl
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
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;
return -1;
}
@ -413,7 +392,7 @@ hwloc_get_membind(hwloc_topology_t topology, hwloc_bitmap_t set, hwloc_membind_p
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)
{
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return -1;
}
@ -485,7 +464,7 @@ hwloc_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_bitmap_
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)
{
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return -1;
}
@ -655,7 +634,7 @@ hwloc_alloc_membind_by_nodeset(hwloc_topology_t topology, size_t len, hwloc_cons
{
void *p;
if (flags & ~HWLOC_MEMBIND_ALLFLAGS) {
if ((flags & ~HWLOC_MEMBIND_ALLFLAGS) || hwloc__check_membind_policy(policy) < 0) {
errno = EINVAL;
return NULL;
}
@ -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)
{
hwloc_const_cpuset_t cpuset = hwloc_topology_get_complete_cpuset(topology);
if (cpuset) {
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)
@ -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)
{
hwloc_const_nodeset_t nodeset = hwloc_topology_get_complete_nodeset(topology);
if (nodeset) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
*policy = HWLOC_MEMBIND_DEFAULT;
*policy = HWLOC_MEMBIND_MIXED;
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)

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

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

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

@ -78,7 +78,6 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
{
const char *basename;
lt_dlhandle handle;
char *componentsymbolname = NULL;
struct hwloc_component *component;
struct hwloc__plugin_desc *desc, **prevdesc;
@ -104,7 +103,9 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
fprintf(stderr, "Failed to load plugin: %s\n", lt_dlerror());
goto out;
}
componentsymbolname = malloc(strlen(basename)+10+1);
{
char componentsymbolname[strlen(basename)+10+1];
sprintf(componentsymbolname, "%s_component", basename);
component = lt_dlsym(handle, componentsymbolname);
if (!component) {
@ -122,8 +123,7 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
if (hwloc_plugins_verbose)
fprintf(stderr, "Plugin contains expected symbol `%s'\n",
componentsymbolname);
free(componentsymbolname);
componentsymbolname = NULL;
}
if (HWLOC_COMPONENT_TYPE_DISC == component->type) {
if (strncmp(basename, "hwloc_", 6)) {
@ -167,7 +167,6 @@ hwloc__dlforeach_cb(const char *filename, void *_data __hwloc_attribute_unused)
out_with_handle:
lt_dlclose(handle);
free(componentsymbolname); /* NULL if already freed */
out:
return 0;
}
@ -567,6 +566,8 @@ nextname:
if (tryall) {
comp = hwloc_disc_components;
while (NULL != comp) {
if (!comp->enabled_by_default)
goto nextcomp;
/* check if this component was explicitly excluded in env */
if (env) {
char *curenv = env;

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 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -22,6 +22,7 @@
void hwloc_internal_distances_init(struct hwloc_topology *topology)
{
topology->first_dist = topology->last_dist = NULL;
topology->next_dist_id = 0;
}
/* 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->nbobjs = nbobjs;
newdist->kind = olddist->kind;
newdist->id = olddist->id;
newdist->indexes = hwloc_tma_malloc(tma, nbobjs * sizeof(*newdist->indexes));
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;
int err;
new->next_dist_id = old->next_dist_id;
for(olddist = old->first_dist; olddist; olddist = olddist->next) {
err = hwloc_internal_distances_dup_one(new, olddist);
if (err < 0)
@ -151,7 +154,7 @@ int hwloc_distances_remove(hwloc_topology_t topology)
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;
hwloc_obj_type_t type;
@ -239,6 +242,8 @@ hwloc_internal_distances__add(hwloc_topology_t topology,
dist->values = values;
dist->id = topology->next_dist_id++;
if (topology->last_dist)
topology->last_dist->next = dist;
else
@ -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,
* 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);
@ -634,7 +644,7 @@ hwloc_distances_get(hwloc_topology_t topology,
}
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 long kind, unsigned long flags)
{
@ -717,7 +727,7 @@ hwloc__find_groups_by_min_distance(unsigned nbobjs,
/* build groups of objects connected with this distance */
for(i=0; i<nbobjs; i++) {
unsigned size;
int firstfound;
unsigned firstfound;
/* if already grouped, skip */
if (groupids[i])
@ -728,19 +738,19 @@ hwloc__find_groups_by_min_distance(unsigned nbobjs,
size = 1;
firstfound = i;
while (firstfound != -1) {
while (firstfound != (unsigned)-1) {
/* 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,
* so as to find new objects minimally-connected by transivity.
*/
int newfirstfound = -1;
unsigned newfirstfound = (unsigned)-1;
for(j=firstfound; j<nbobjs; j++)
if (groupids[j] == groupid)
for(k=0; k<nbobjs; k++)
if (!groupids[k] && !hwloc_compare_values(VALUE(j, k), min_distance, accuracy)) {
groupids[k] = groupid;
size++;
if (newfirstfound == -1)
if (newfirstfound == (unsigned)-1)
newfirstfound = k;
if (i == j)
hwloc_debug(" object %u is minimally connected to %u\n", k, i);
@ -811,7 +821,7 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
float *accuracies,
int needcheck)
{
unsigned *groupids = NULL;
HWLOC_VLA(unsigned, groupids, nbobjs);
unsigned nbgroups = 0;
unsigned i,j;
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 */
return;
groupids = malloc(sizeof(unsigned) * nbobjs);
if (NULL == groupids) {
return;
}
for(i=0; i<nbaccuracies; i++) {
if (verbose)
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)
continue;
nbgroups = hwloc__find_groups_by_min_distance(nbobjs, _values, accuracies[i], groupids, verbose);
@ -840,29 +845,20 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
break;
}
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;
unsigned *groupsizes = NULL;
uint64_t *groupvalues = NULL;
HWLOC_VLA(hwloc_obj_t, groupobjs, nbgroups);
HWLOC_VLA(unsigned, groupsizes, nbgroups);
HWLOC_VLA(uint64_t, groupvalues, nbgroups*nbgroups);
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 */
memset(&(groupsizes[0]), 0, sizeof(groupsizes[0]) * nbgroups);
for(i=0; i<nbgroups; i++) {
/* create the Group object */
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->attr->group.kind = HWLOC_GROUP_KIND_DISTANCE;
group_obj->attr->group.subkind = topology->grouping_next_subkind;
@ -874,7 +870,7 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
}
hwloc_debug_1arg_bitmap("adding Group object with %u objects and cpuset %s\n",
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);
/* res_obj may be NULL on failure to insert. */
if (!res_obj)
@ -886,7 +882,7 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
if (failed)
/* don't try to group above if we got a NULL group here, just keep this incomplete level */
goto inner_free;
return;
/* factorize values */
memset(&(groupvalues[0]), 0, sizeof(groupvalues[0]) * nbgroups * nbgroups);
@ -918,14 +914,5 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
#endif
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-2016 Inria. All rights reserved.
Copyright © 2009-2017 Inria. All rights reserved.
Copyright © 2009-2011 Université Bordeaux.
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 object (page_type*,info*,userdata*,object*,distances*)>
<!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 subtype CDATA "" >
<!ELEMENT object (page_type*,info*,distances*,userdata*,object*)>
<!ATTLIST object type (System | Machine | Misc | Group | NUMANode | Socket | Package | Cache | Core | PU | Bridge | PCIDev | OSDev) #REQUIRED>
<!ATTLIST object os_level CDATA "-1" >
<!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" >
@ -21,15 +22,14 @@
<!ATTLIST object cache_type CDATA "0" >
<!ATTLIST object huge_page_size_kB CDATA "0" >
<!ATTLIST object huge_page_free CDATA "0" >
<!ATTLIST object depth CDATA "-1" >
<!ATTLIST object cpuset CDATA "0" >
<!ATTLIST object complete_cpuset CDATA "" >
<!ATTLIST object online_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 "" >
@ -45,17 +45,13 @@
<!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 distances (latency*)>
<!ATTLIST distances nbobjs CDATA #REQUIRED>
<!ATTLIST distances relative_depth CDATA #REQUIRED>
<!ATTLIST distances latency_base CDATA #REQUIRED>
<!ELEMENT indexes (#PCDATA)>
<!ATTLIST indexes length CDATA #REQUIRED>
<!ELEMENT u64values (#PCDATA)>
<!ATTLIST u64values length CDATA #REQUIRED>
<!ELEMENT latency EMPTY>
<!ATTLIST latency value CDATA #REQUIRED>
<!ELEMENT userdata (#PCDATA)>
<!ATTLIST userdata name CDATA "" >
@ -75,13 +71,3 @@
<!ATTLIST diff obj_attr_name CDATA "" >
<!ATTLIST diff obj_attr_newvalue 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 "" >

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

@ -109,7 +109,6 @@ hwloc_pci_forced_locality_parse(struct hwloc_topology *topology, const char *_en
void
hwloc_pci_discovery_init(struct hwloc_topology *topology)
{
topology->pci_nonzero_domains = 0;
topology->need_pci_belowroot_apply_locality = 0;
topology->pci_has_forced_locality = 0;
@ -196,24 +195,16 @@ hwloc_pci_traverse_print_cb(void * cbdata __hwloc_attribute_unused,
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
hwloc_pci_traverse(void * cbdata, struct hwloc_obj *tree,
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 */
@ -367,7 +358,7 @@ hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *old
*/
while (old_tree) {
/* 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 **srcnextp = &old_tree;
struct hwloc_obj *child = *srcnextp;
@ -407,9 +398,6 @@ hwloc_pcidisc_tree_attach(struct hwloc_topology *topology, struct hwloc_obj *old
hwloc_debug("New PCI hostbridge %04x:[%02x-%02x]\n",
current_domain, current_bus, current_subordinate);
if (current_domain)
topology->pci_nonzero_domains = 1;
*next_hb_p = hostbridge;
next_hb_p = &hostbridge->next_sibling;
topology->modified = 1; /* needed in case somebody reconnects levels before the core calls hwloc_pci_belowroot_apply_locality()
@ -611,9 +599,9 @@ static struct hwloc_obj *
hwloc__pci_belowroot_find_by_busid(hwloc_obj_t parent,
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
|| (child->type == HWLOC_OBJ_BRIDGE
&& child->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI)) {

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

@ -178,12 +178,17 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
if (mmap_res == MAP_FAILED)
return -1;
if (mmap_res != mmap_address) {
munmap(mmap_res, length);
errno = EBUSY;
return -1;
goto out_with_mmap;
}
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->backends == 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->adopted_shmem_addr = mmap_address;
new->adopted_shmem_length = length;
new->topology_abi = HWLOC_TOPOLOGY_ABI;
/* setting binding hooks will touch support arrays, so duplicate them too.
* 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.membind, old->support.membind, sizeof(*new->support.membind));
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
if (getenv("HWLOC_DEBUG_CHECK"))
@ -221,7 +230,8 @@ hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
out_with_components:
hwloc_components_fini();
munmap(mmap_address, length);
out_with_mmap:
munmap(mmap_res, length);
return -1;
}

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -359,8 +359,9 @@ hwloc_aix_prepare_membind(hwloc_topology_t topology, rsethandle_t *rad, hwloc_co
}
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;
int res;
@ -369,6 +370,11 @@ hwloc_aix_set_sth_membind(hwloc_topology_t topology, rstype_t what, rsid_t who,
return -1;
}
if (policy == HWLOC_MEMBIND_DEFAULT)
nodeset = hwloc_topology_get_complete_nodeset(topology);
else
nodeset = _nodeset;
switch (policy) {
case HWLOC_MEMBIND_DEFAULT:
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;
unsigned cpu, maxcpus;
int res = -1;
int depth, n, i;
int n, i;
depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
assert(depth >= 0);
n = hwloc_get_nbobjs_by_depth(topology, depth);
n = hwloc_get_nbobjs_by_depth(topology, HWLOC_TYPE_DEPTH_NUMANODE);
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);
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))
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
* aligning the range on 64K... */
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;
rsid_t rsid = { .at_subrange = &subrange };
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;
}
if (policy == HWLOC_MEMBIND_DEFAULT)
nodeset = hwloc_topology_get_complete_nodeset(topology);
else
nodeset = _nodeset;
subrange.su_offset = (uintptr_t) addr;
subrange.su_length = len;
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
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;
rsid_t rsid;
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))
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++) {
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)) {
fprintf(stderr,"rs_getrad(%d) failed: %s\n", i, strerror(errno));
@ -641,15 +657,15 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
case HWLOC_OBJ_NUMANODE:
obj->nodeset = hwloc_bitmap_alloc();
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->memory.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize();
obj->attr->numanode.local_memory = 0; /* TODO: odd, rs_getinfo(rad, R_MEMSIZE, 0) << 10 returns the total memory ... */
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
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#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;
case HWLOC_OBJ_L2CACHE:
obj->attr->cache.size = _system_configuration.L2_cache_size;
@ -670,7 +686,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
case HWLOC_OBJ_CORE:
{
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->attr->cache.size = _system_configuration.dcache_size;
obj2->attr->cache.associativity = _system_configuration.dcache_asc;
@ -686,7 +702,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
hwloc_debug("Adding an L1d cache for core %d\n", i);
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->attr->cache.size = _system_configuration.icache_size;
obj3->attr->cache.associativity = _system_configuration.icache_asc;
@ -707,7 +723,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
break;
}
hwloc_debug_2args_bitmap("%s %d has cpuset %s\n",
hwloc_type_name(type),
hwloc_obj_type_string(type),
i, obj->cpuset);
if (hwloc_filter_check_keep_object_type(topology, obj->type))
hwloc_insert_object_by_cpuset(topology, obj);
@ -729,7 +745,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
/* somebody discovered things */
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 */
@ -758,6 +774,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
hwloc_debug("looking AIX node sdl %d\n", i);
look_rset(i, HWLOC_OBJ_NUMANODE, topology, i);
known = 1;
topology->support.discovery->numa = 1;
}
# ifdef R_L2CSDL
if (i == rs_getinfo(NULL, R_L2CSDL, 0))
@ -863,6 +880,7 @@ static struct hwloc_disc_component hwloc_aix_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_aix_component_instantiate,
50,
1,
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.
*/
@ -26,7 +26,7 @@ hwloc_bgq__get_allowed_resources(struct hwloc_topology *topology)
unsigned i;
/* 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 */
env = getenv("BG_THREADMODEL");
@ -36,7 +36,7 @@ hwloc_bgq__get_allowed_resources(struct hwloc_topology *topology)
/* the mask is reversed, manually reverse it */
for(i=0; i<64; i++)
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;
@ -54,7 +54,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
/* somebody discovered things */
return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_alloc_root_sets(topology->levels[0][0]);
hwloc_bgq__get_allowed_resources(topology);
@ -66,15 +66,17 @@ hwloc_look_bgq(struct hwloc_backend *backend)
set = hwloc_bitmap_alloc();
hwloc_bitmap_set(set, 0);
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);
topology->support.discovery->numa = 1;
topology->support.discovery->numa_memory = 1;
set = hwloc_bitmap_alloc();
hwloc_bitmap_set_range(set, 0, HWLOC_BGQ_CORES*4-1);
/* shared L2 */
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->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2;
@ -100,7 +102,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
/* L1d */
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->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
obj->attr->cache.depth = 1;
@ -111,7 +113,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
}
/* L1i */
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->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
obj->attr->cache.depth = 1;
@ -132,6 +134,7 @@ hwloc_look_bgq(struct hwloc_backend *backend)
}
/* PUs */
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, HWLOC_BGQ_CORES*4);
/* Add BGQ specific information */
@ -287,6 +290,7 @@ static struct hwloc_disc_component hwloc_bgq_disc_component = {
~0,
hwloc_bgq_component_instantiate,
50,
1,
NULL
};

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

@ -75,10 +75,10 @@ hwloc_cuda_discover(struct hwloc_backend *backend)
hwloc_obj_t cuda_device, parent;
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);
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->subtype = strdup("CUDA");
@ -86,7 +86,7 @@ hwloc_cuda_discover(struct hwloc_backend *backend)
hwloc_obj_add_info(cuda_device, "GPUVendor", "NVIDIA Corporation");
cures = cudaGetDeviceProperties(&prop, i);
if (!cures)
if (!cures && prop.name[0] != '\0')
hwloc_obj_add_info(cuda_device, "GPUModel", prop.name);
snprintf(number, sizeof(number), "%llu", ((unsigned long long) prop.totalGlobalMem) >> 10);
@ -144,6 +144,7 @@ static struct hwloc_disc_component hwloc_cuda_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_cuda_component_instantiate,
10, /* after pci */
1,
NULL
};

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2013 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -35,36 +35,77 @@ hwloc_look_darwin(struct hwloc_backend *backend)
int64_t l1dcachesize, l1icachesize;
int64_t cacheways[2];
int64_t l2cachesize;
int64_t l3cachesize;
int64_t cachelinesize;
int64_t memsize;
int64_t _tmp;
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)
/* somebody discovered things */
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;
nprocs = _nprocs;
topology->support.discovery->pu = 1;
hwloc_debug("%u procs\n", nprocs);
size = sizeof(cpuvendor);
if (sysctlbyname("machdep.cpu.vendor", cpuvendor, &size, NULL, 0))
cpuvendor[0] = '\0';
size = sizeof(cpumodel);
if (sysctlbyname("machdep.cpu.brand_string", cpumodel, &size, NULL, 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) {
unsigned npackages = _npackages;
int64_t _cores_per_package;
unsigned cores_per_package;
int64_t _logical_per_package;
unsigned logical_per_package;
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;
else
/* Assume the trivia. */
@ -83,17 +124,46 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_debug_1arg_bitmap("package %u has cpuset %s\n",
i, obj->cpuset);
if (cpuvendor[0] != '\0')
hwloc_obj_add_info(obj, "CPUVendor", cpuvendor);
if (cpumodel[0] != '\0')
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);
}
else
else {
if (cpuvendor[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUVendor", cpuvendor);
if (cpumodel[0] != '\0')
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)
/* official/modern way */
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)) {
unsigned cores_per_package = _cores_per_package;
hwloc_debug("%u cores per package\n", 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);
}
}
} else
} else {
if (cpuvendor[0] != '\0')
hwloc_obj_add_info(topology->levels[0][0], "CPUVendor", cpuvendor);
if (cpumodel[0] != '\0')
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))
l1dcachesize = 0;
@ -123,6 +202,9 @@ hwloc_look_darwin(struct hwloc_backend *backend)
if (hwloc_get_sysctlbyname("hw.l2cachesize", &l2cachesize))
l2cachesize = 0;
if (hwloc_get_sysctlbyname("hw.l3cachesize", &l3cachesize))
l3cachesize = 0;
if (hwloc_get_sysctlbyname("machdep.cpu.cache.L1_associativity", &cacheways[0]))
cacheways[0] = 0;
else if (cacheways[0] == 0xff)
@ -141,22 +223,9 @@ hwloc_look_darwin(struct hwloc_backend *backend)
if (!sysctlbyname("hw.cacheconfig", NULL, &size, NULL, 0)) {
unsigned n = size / sizeof(uint32_t);
uint64_t *cacheconfig = NULL;
uint64_t *cachesize = NULL;
uint32_t *cacheconfig32 = NULL;
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;
}
uint64_t cacheconfig[n];
uint64_t cachesize[n];
uint32_t cacheconfig32[n];
if ((!sysctlbyname("hw.cacheconfig", cacheconfig, &size, NULL, 0))) {
/* 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;
if (n > 2)
cachesize[2] = l2cachesize;
if (n > 3)
cachesize[3] = l3cachesize;
}
hwloc_debug("%s", "caches");
@ -195,8 +266,9 @@ hwloc_look_darwin(struct hwloc_backend *backend)
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, j);
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, j);
gotnuma++;
} 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();
for (cpu = j*cacheconfig[i];
@ -208,7 +280,7 @@ hwloc_look_darwin(struct hwloc_backend *backend)
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
/* FIXME assuming that L1i and L1d are shared the same way. Darwin
* 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);
hwloc_debug_1arg_bitmap("L1icache %u has cpuset %s\n",
j, l1i->cpuset);
@ -237,13 +309,16 @@ hwloc_look_darwin(struct hwloc_backend *backend)
} else {
hwloc_debug_1arg_bitmap("node %u has cpuset %s\n",
j, obj->cpuset);
obj->memory.local_memory = cachesize[i];
obj->memory.page_types_len = 2;
obj->memory.page_types = malloc(2*sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2*sizeof(*obj->memory.page_types));
obj->memory.page_types[0].size = hwloc_getpagesize();
if (cachesize[i]) {
obj->attr->numanode.local_memory = cachesize[i];
gotnumamemory++;
}
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
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
}
@ -254,12 +329,12 @@ hwloc_look_darwin(struct hwloc_backend *backend)
}
}
}
out:
free(cacheconfig);
free(cachesize);
free(cacheconfig32);
}
if (gotnuma)
topology->support.discovery->numa = 1;
if (gotnumamemory)
topology->support.discovery->numa = 1;
/* add PU objects */
hwloc_setup_pu_level(topology, nprocs);
@ -295,6 +370,7 @@ static struct hwloc_disc_component hwloc_darwin_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_darwin_component_instantiate,
50,
1,
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.
*/
@ -26,6 +26,7 @@ static struct hwloc_disc_component hwloc_fake_disc_component = {
0, /* nothing to exclude */
hwloc_fake_component_instantiate,
100, /* make sure it's loaded before anything conflicting excludes it */
1,
NULL
};

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -172,7 +172,7 @@ hwloc_freebsd_node_meminfo_info(struct hwloc_topology *topology)
unsigned long physmem;
size_t len = sizeof(physmem);
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.
* 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)
{
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->levels[0][0]->cpuset) {
/* 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);
}
@ -242,6 +246,7 @@ static struct hwloc_disc_component hwloc_freebsd_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_freebsd_component_instantiate,
50,
1,
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++) {
hwloc_obj_t osdev, parent;
const int screen = j;
const int screen = (int)j;
unsigned int *ptr_binary_data;
int data_length;
int gpu_number;
@ -76,7 +76,7 @@ hwloc_gl_discover(struct hwloc_backend *backend)
if (!err)
continue;
gpu_number = ptr_binary_data[1];
gpu_number = (int)ptr_binary_data[1];
free(ptr_binary_data);
#ifdef NV_CTRL_PCI_DOMAIN
@ -111,18 +111,17 @@ hwloc_gl_discover(struct hwloc_backend *backend)
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->logical_index = -1;
osdev->attr->osdev.type = HWLOC_OBJ_OSDEV_GPU;
hwloc_obj_add_info(osdev, "Backend", "GL");
hwloc_obj_add_info(osdev, "GPUVendor", "NVIDIA Corporation");
if (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)
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)
parent = hwloc_get_root_obj(topology);
@ -159,6 +158,7 @@ static struct hwloc_disc_component hwloc_gl_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_gl_component_instantiate,
10, /* after pci */
1,
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.
*/
@ -22,7 +22,7 @@ int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology)
hwloc_bitmap_set(set, i);
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->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
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);
}
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->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
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);
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->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2;
@ -71,6 +71,7 @@ int hwloc_look_hardwired_fujitsu_k(struct hwloc_topology *topology)
} else
hwloc_bitmap_free(set);
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, 8);
return 0;
@ -90,7 +91,7 @@ int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology)
hwloc_bitmap_set(set, i);
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->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
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);
}
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->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
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);
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->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
obj->attr->cache.depth = 2;
@ -139,6 +140,7 @@ int hwloc_look_hardwired_fujitsu_fx10(struct hwloc_topology *topology)
} else
hwloc_bitmap_free(set);
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, 16);
return 0;
@ -158,7 +160,7 @@ int hwloc_look_hardwired_fujitsu_fx100(struct hwloc_topology *topology)
hwloc_bitmap_set(set, i);
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->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
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);
}
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->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
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)) {
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();
hwloc_bitmap_set_range(obj->cpuset, 0, 15);
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;
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();
hwloc_bitmap_set_range(obj->cpuset, 16, 31);
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);
}
topology->support.discovery->pu = 1;
hwloc_setup_pu_level(topology, 34);
return 0;

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2010, 2013 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -139,13 +139,16 @@ hwloc_hpux_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_
#ifdef MAP_MEM_FIRST_TOUCH
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;
void *p;
/* 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;
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;
int has_numa = sysconf(_SC_CCNUMA_SUPPORT) == 1;
hwloc_obj_t *nodes = NULL, obj;
spu_t currentcpu;
ldom_t currentnode;
int i, nbnodes = 0;
@ -185,22 +187,23 @@ hwloc_look_hpux(struct hwloc_backend *backend)
/* somebody discovered things */
return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_alloc_root_sets(topology->levels[0][0]);
if (has_numa) {
nbnodes = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
MPC_GETNUMLDOMS_SYS : MPC_GETNUMLDOMS, 0, 0);
}
hwloc_debug("%d nodes\n", nbnodes);
nodes = malloc(nbnodes * sizeof(*nodes));
hwloc_obj_t nodes[nbnodes], obj;
if (has_numa) {
i = 0;
currentnode = mpctl((topology->flags & HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM) ?
MPC_GETFIRSTLDOM_SYS : MPC_GETFIRSTLDOM, 0, 0);
while (currentnode != -1 && i < nbnodes) {
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->nodeset = hwloc_bitmap_alloc();
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) ?
MPC_GETFIRSTSPU_SYS : MPC_GETFIRSTSPU, 0,0);
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();
hwloc_bitmap_set(obj->cpuset, currentcpu);
hwloc_debug("cpu %d\n", currentcpu);
if (nodes) {
if (has_numa) {
/* Add this cpu to its node */
currentnode = mpctl(MPC_SPUTOLDOM, currentcpu, 0);
/* 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);
}
if (nodes) {
if (has_numa) {
/* Add nodes */
for (i = 0 ; i < nbnodes ; i++)
hwloc_insert_object_by_cpuset(topology, nodes[i]);
free(nodes);
}
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_add_uname_info(topology, NULL);
@ -300,6 +304,7 @@ static struct hwloc_disc_component hwloc_hpux_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_hpux_component_instantiate,
50,
1,
NULL
};

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

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

@ -1,6 +1,6 @@
/*
* 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 © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -141,7 +141,7 @@ hwloc_netbsd_node_meminfo_info(struct hwloc_topology *topology)
unsigned long physmem;
size_t len = sizeof(physmem);
sysctl(mib, 2, &physmem, &len, NULL, 0);
topology->levels[0][0]->memory.local_memory = physmem;
topology->machine_memory.local_memory = physmem;
}
#endif
@ -149,11 +149,15 @@ static int
hwloc_look_netbsd(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
unsigned nbprocs = hwloc_fallback_nbprocessors(topology);
if (!topology->levels[0][0]->cpuset) {
/* 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);
}
@ -201,6 +205,7 @@ static struct hwloc_disc_component hwloc_netbsd_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_netbsd_component_instantiate,
50,
1,
NULL
};

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2015 Inria. All rights reserved.
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -14,13 +14,20 @@ static int
hwloc_look_noos(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
int nbprocs;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_setup_pu_level(topology, hwloc_fallback_nbprocessors(topology));
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_add_uname_info(topology, NULL);
return 0;
}
@ -45,6 +52,7 @@ static struct hwloc_disc_component hwloc_noos_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_noos_component_instantiate,
40, /* lower than native OS component, higher than globals */
1,
NULL
};

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

@ -43,10 +43,10 @@ hwloc_nvml_discover(struct hwloc_backend *backend)
ret = nvmlDeviceGetHandleByIndex(i, &device);
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);
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;
hwloc_obj_add_info(osdev, "Backend", "NVML");
@ -120,6 +120,7 @@ static struct hwloc_disc_component hwloc_nvml_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_nvml_component_instantiate,
5, /* after pci, and after cuda since likely less useful */
1,
NULL
};

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

@ -1,6 +1,6 @@
/*
* Copyright © 2012-2017 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux. All right reserved.
* Copyright © 2012-2018 Inria. All rights reserved.
* Copyright © 2013, 2018 Université Bordeaux. All right reserved.
* See COPYING in top-level directory.
*/
@ -12,14 +12,17 @@
#include <private/misc.h>
#include <private/debug.h>
#ifdef __APPLE__
#include <OpenCL/cl_ext.h>
#else
#include <CL/cl_ext.h>
#endif
static int
hwloc_opencl_discover(struct hwloc_backend *backend)
{
struct hwloc_topology *topology = backend->topology;
enum hwloc_type_filter_e filter;
cl_platform_id *platform_ids = NULL;
cl_uint nr_platforms;
cl_int clret;
unsigned j;
@ -32,29 +35,24 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
if (CL_SUCCESS != clret || !nr_platforms)
return -1;
hwloc_debug("%u OpenCL platforms\n", nr_platforms);
platform_ids = malloc(nr_platforms * sizeof(*platform_ids));
if (!platform_ids)
return -1;
cl_platform_id platform_ids[nr_platforms];
clret = clGetPlatformIDs(nr_platforms, platform_ids, &nr_platforms);
if (CL_SUCCESS != clret || !nr_platforms) {
free(platform_ids);
if (CL_SUCCESS != clret || !nr_platforms)
return -1;
}
for(j=0; j<nr_platforms; j++) {
cl_device_id *device_ids = NULL;
cl_uint nr_devices;
unsigned i;
clret = clGetDeviceIDs(platform_ids[j], CL_DEVICE_TYPE_ALL, 0, NULL, &nr_devices);
if (CL_SUCCESS != clret)
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);
if (CL_SUCCESS != clret) {
free(device_ids);
if (CL_SUCCESS != clret)
continue;
}
for(i=0; i<nr_devices; i++) {
cl_platform_id platform_id = 0;
@ -69,35 +67,24 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
hwloc_debug("This is opencl%ud%u\n", j, i);
#ifdef CL_DEVICE_TOPOLOGY_AMD
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
hwloc_debug("no AMD-specific device information: %d\n", clret);
clGetDeviceInfo(device_ids[i], CL_DEVICE_TYPE, sizeof(type), &type, NULL);
if (type == CL_DEVICE_TYPE_CPU)
/* we don't want CPU opencl devices */
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);
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->subtype = strdup("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)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "GPU");
else if (type == CL_DEVICE_TYPE_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)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Custom");
else
@ -110,10 +97,10 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
buffer[0] = '\0';
#ifdef CL_DEVICE_BOARD_NAME_AMD
clGetDeviceInfo(device_ids[i], CL_DEVICE_BOARD_NAME_AMD, sizeof(buffer), buffer, NULL);
#else
clGetDeviceInfo(device_ids[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_BOARD_NAME_AMD, sizeof(buffer), buffer, NULL);
if (CL_SUCCESS != clret || buffer[0] == '\0')
#endif
clGetDeviceInfo(device_ids[i], CL_DEVICE_NAME, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "GPUModel", buffer);
@ -141,18 +128,25 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
parent = NULL;
#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 (CL_SUCCESS != clret) {
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, amdtopo.pcie.bus, amdtopo.pcie.device, amdtopo.pcie.function);
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
if (!parent)
parent = hwloc_get_root_obj(topology);
hwloc_insert_object_by_parent(topology, parent, osdev);
}
free(device_ids);
}
free(platform_ids);
return 0;
}
@ -177,6 +171,7 @@ static struct hwloc_disc_component hwloc_opencl_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_opencl_component_instantiate,
10, /* after pci */
1,
NULL
};

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2011, 2013 Université Bordeaux
* Copyright © 2014 Cisco Systems, Inc. All rights reserved.
* Copyright © 2015 Research Organization for Information Science
@ -73,6 +73,19 @@
#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
hwloc_look_pci(struct hwloc_backend *backend)
@ -105,9 +118,15 @@ hwloc_look_pci(struct hwloc_backend *backend)
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 */
ret = pci_system_init();
if (ret) {
HWLOC_PCIACCESS_UNLOCK();
hwloc_debug("%s", "Can not initialize libpciaccess\n");
return -1;
}
@ -211,7 +230,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
#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.bus = pcidev->bus;
obj->attr->pcidev.dev = pcidev->dev;
@ -266,6 +285,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
/* finalize device scanning */
pci_iterator_destroy(iter);
pci_system_cleanup();
HWLOC_PCIACCESS_UNLOCK();
hwloc_pcidisc_tree_attach(topology, tree);
return 0;
@ -297,6 +317,7 @@ static struct hwloc_disc_component hwloc_pci_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_pci_component_instantiate,
20,
1,
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-2017 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -190,6 +190,7 @@ typedef WORD (WINAPI *PFN_GETACTIVEPROCESSORGROUPCOUNT)(void);
static PFN_GETACTIVEPROCESSORGROUPCOUNT GetActiveProcessorGroupCountProc;
static unsigned long nr_processor_groups = 1;
static unsigned long max_numanode_index = 0;
typedef WORD (WINAPI *PFN_GETACTIVEPROCESSORCOUNT)(WORD);
static PFN_GETACTIVEPROCESSORCOUNT GetActiveProcessorCountProc;
@ -253,9 +254,9 @@ static void hwloc_win_get_function_ptrs(void)
(PFN_GETNUMAAVAILABLEMEMORYNODEEX) GetProcAddress(kernel32, "GetNumaAvailableMemoryNodeEx");
GetLogicalProcessorInformationExProc =
(PFN_GETLOGICALPROCESSORINFORMATIONEX)GetProcAddress(kernel32, "GetLogicalProcessorInformationEx");
QueryWorkingSetExProc =
(PFN_QUERYWORKINGSETEX) GetProcAddress(kernel32, "K32QueryWorkingSetEx");
VirtualAllocExNumaProc =
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "K32QueryWorkingSetEx");
VirtualAllocExNumaProc =*
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "VirtualAllocExNuma");
VirtualFreeExProc =
(PFN_VIRTUALFREEEX) GetProcAddress(kernel32, "VirtualFreeEx");
@ -264,10 +265,10 @@ static void hwloc_win_get_function_ptrs(void)
if (GetActiveProcessorGroupCountProc)
nr_processor_groups = GetActiveProcessorGroupCountProc();
if (!VirtualAllocExNumaProc) {
if (!QueryWorkingSetExProc) {
HMODULE psapi = LoadLibrary("psapi.dll");
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)
{
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)
|| flags & HWLOC_MEMBIND_NOCPUBIND) {
@ -445,11 +447,16 @@ hwloc_win_set_thisthread_membind(hwloc_topology_t topology, hwloc_const_nodeset_
return -1;
}
cpuset = hwloc_bitmap_alloc();
hwloc_cpuset_from_nodeset(topology, cpuset, nodeset);
if (policy == HWLOC_MEMBIND_DEFAULT) {
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,
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
hwloc_bitmap_free(cpuset);
hwloc_bitmap_free(_cpuset);
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)
{
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)
|| 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;
}
cpuset = hwloc_bitmap_alloc();
hwloc_cpuset_from_nodeset(topology, cpuset, nodeset);
if (policy == HWLOC_MEMBIND_DEFAULT) {
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,
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
hwloc_bitmap_free(cpuset);
hwloc_bitmap_free(_cpuset);
return ret;
}
@ -645,6 +658,10 @@ hwloc_win_alloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size
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) {
/* Not a single node, can't do this */
errno = EXDEV;
@ -670,12 +687,14 @@ hwloc_win_free_membind(hwloc_topology_t topology __hwloc_attribute_unused, void
*/
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;
DWORD page_size;
uintptr_t start;
unsigned nb;
PSAPI_WORKING_SET_EX_INFORMATION *pv;
unsigned i;
GetSystemInfo(&SystemInfo);
page_size = SystemInfo.dwPageSize;
@ -686,11 +705,9 @@ hwloc_win_get_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, c
if (!nb)
nb = 1;
{
PSAPI_WORKING_SET_EX_INFORMATION *pv;
unsigned i;
pv = calloc(nb, sizeof(*pv));
if (!pv)
return -1;
for (i = 0; i < nb; i++)
pv[i].VirtualAddress = (void*) (start + i * page_size);
@ -698,27 +715,15 @@ hwloc_win_get_area_membind(hwloc_topology_t topology __hwloc_attribute_unused, c
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++)
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;
SYSTEM_INFO SystemInfo;
DWORD length;
int gotnuma = 0;
int gotnumamemory = 0;
if (topology->levels[0][0]->cpuset)
/* somebody discovered things */
return -1;
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_alloc_root_sets(topology->levels[0][0]);
GetSystemInfo(&SystemInfo);
@ -775,11 +782,14 @@ hwloc_look_windows(struct hwloc_backend *backend)
&& procInfo->Cache.Type != CacheInstruction)
continue;
id = -1;
id = HWLOC_UNKNOWN_INDEX;
switch (procInfo[i].Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
id = procInfo[i].NumaNode.NodeNumber;
gotnuma++;
if (id > max_numanode_index)
max_numanode_index = id;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
@ -801,10 +811,10 @@ hwloc_look_windows(struct hwloc_backend *backend)
obj = hwloc_alloc_setup_object(topology, type, id);
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 */
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) {
case HWLOC_OBJ_NUMANODE:
@ -813,16 +823,18 @@ hwloc_look_windows(struct hwloc_backend *backend)
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail)))
obj->memory.local_memory = avail;
obj->memory.page_types_len = 2;
obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types));
obj->memory.page_types_len = 1;
obj->memory.page_types[0].size = SystemInfo.dwPageSize;
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) {
obj->attr->numanode.local_memory = avail;
gotnumamemory++;
}
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_len = 1;
obj->attr->numanode.page_types[0].size = SystemInfo.dwPageSize;
#if HAVE_DECL__SC_LARGE_PAGESIZE
obj->memory.page_types_len++;
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
obj->attr->numanode.page_types_len++;
obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
break;
}
@ -900,13 +912,16 @@ hwloc_look_windows(struct hwloc_backend *backend)
&& procInfo->Cache.Type != CacheInstruction)
continue;
id = -1;
id = HWLOC_UNKNOWN_INDEX;
switch (procInfo->Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
num = 1;
GroupMask = &procInfo->NumaNode.GroupMask;
id = procInfo->NumaNode.NodeNumber;
gotnuma++;
if (id > max_numanode_index)
max_numanode_index = id;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
@ -967,12 +982,12 @@ hwloc_look_windows(struct hwloc_backend *backend)
obj = hwloc_alloc_setup_object(topology, type, id);
obj->cpuset = hwloc_bitmap_alloc();
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 */
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? */
}
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) {
case HWLOC_OBJ_NUMANODE:
{
@ -980,15 +995,17 @@ hwloc_look_windows(struct hwloc_backend *backend)
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail)))
obj->memory.local_memory = avail;
obj->memory.page_types = malloc(2 * sizeof(*obj->memory.page_types));
memset(obj->memory.page_types, 0, 2 * sizeof(*obj->memory.page_types));
obj->memory.page_types_len = 1;
obj->memory.page_types[0].size = SystemInfo.dwPageSize;
|| (GetNumaAvailableMemoryNodeProc && GetNumaAvailableMemoryNodeProc(id, &avail))) {
obj->attr->numanode.local_memory = avail;
gotnumamemory++;
}
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_len = 1;
obj->attr->numanode.page_types[0].size = SystemInfo.dwPageSize;
#if HAVE_DECL__SC_LARGE_PAGESIZE
obj->memory.page_types_len++;
obj->memory.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
obj->attr->numanode.page_types_len++;
obj->attr->numanode.page_types[1].size = sysconf(_SC_LARGE_PAGESIZE);
#endif
break;
}
@ -1027,6 +1044,10 @@ hwloc_look_windows(struct hwloc_backend *backend)
free(procInfoTotal);
}
topology->support.discovery->pu = 1;
topology->support.discovery->numa = gotnuma;
topology->support.discovery->numa_memory = gotnumamemory;
if (groups_pu_set) {
/* the system supports multiple Groups.
* PU indexes may be discontiguous, especially if Groups contain less than 64 procs.
@ -1100,8 +1121,8 @@ hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks,
support->membind->bind_membind = 1;
}
if (QueryWorkingSetExProc)
hooks->get_area_membind = hwloc_win_get_area_membind;
if (QueryWorkingSetExProc && max_numanode_index <= 63 /* PSAPI_WORKING_SET_EX_BLOCK.Node is 6 bits only */)
hooks->get_area_memlocation = hwloc_win_get_area_memlocation;
}
static int hwloc_windows_component_init(unsigned long flags __hwloc_attribute_unused)
@ -1134,6 +1155,7 @@ static struct hwloc_disc_component hwloc_windows_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_windows_component_instantiate,
50,
1,
NULL
};
@ -1145,8 +1167,8 @@ const struct hwloc_component hwloc_windows_component = {
&hwloc_windows_disc_component
};
unsigned
hwloc_fallback_nbprocessors(struct hwloc_topology *topology) {
int
hwloc_fallback_nbprocessors(struct hwloc_topology *topology __hwloc_attribute_unused) {
int n;
SYSTEM_INFO sysinfo;
@ -1163,9 +1185,5 @@ hwloc_fallback_nbprocessors(struct hwloc_topology *topology) {
n = MAXIMUM_PROC_PER_GROUP*nr_processor_groups;
}
if (n >= 1)
topology->support.discovery->pu = 1;
else
n = 1;
return n;
}

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

@ -1,5 +1,5 @@
/*
* Copyright © 2010-2017 Inria. All rights reserved.
* Copyright © 2010-2018 Inria. All rights reserved.
* Copyright © 2010-2013 Université Bordeaux
* Copyright © 2010-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -70,29 +70,35 @@ cpuiddump_read(const char *dirpath, unsigned idx)
{
struct cpuiddump *cpuiddump;
struct cpuiddump_entry *cur;
char *filename;
size_t filenamelen = strlen(dirpath) + 15;
FILE *file;
char line[128];
unsigned nr;
cpuiddump = malloc(sizeof(*cpuiddump));
cpuiddump->nr = 0; /* return a cpuiddump that will raise errors because it matches nothing */
if (!cpuiddump) {
fprintf(stderr, "Failed to allocate cpuiddump for PU #%u, ignoring cpuiddump.\n", idx);
goto out;
}
filename = malloc(filenamelen);
{
size_t filenamelen = strlen(dirpath) + 15;
HWLOC_VLA(char, filename, filenamelen);
snprintf(filename, filenamelen, "%s/pu%u", dirpath, idx);
file = fopen(filename, "r");
if (!file) {
fprintf(stderr, "Could not read dumped cpuid file %s\n", filename);
free(filename);
return cpuiddump;
fprintf(stderr, "Could not read dumped cpuid file %s, ignoring cpuiddump.\n", filename);
goto out_with_dump;
}
}
free(filename);
nr = 0;
while (fgets(line, sizeof(line), file))
nr++;
cpuiddump->entries = malloc(nr * sizeof(struct cpuiddump_entry));
if (!cpuiddump->entries) {
fprintf(stderr, "Failed to allocate %u cpuiddump entries for PU #%u, ignoring cpuiddump.\n", nr, idx);
goto out_with_file;
}
fseek(file, 0, SEEK_SET);
cur = &cpuiddump->entries[0];
@ -108,9 +114,17 @@ cpuiddump_read(const char *dirpath, unsigned idx)
nr++;
}
}
cpuiddump->nr = nr;
fclose(file);
return cpuiddump;
out_with_file:
fclose(file);
out_with_dump:
free(cpuiddump);
out:
return NULL;
}
static void
@ -195,6 +209,7 @@ struct procinfo {
enum cpuid_type {
intel,
amd,
zhaoxin,
unknown
};
@ -284,7 +299,8 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
infos->cpufamilynumber = _family;
}
if ((cpuid_type == intel && (_family == 0x6 || _family == 0xf))
|| (cpuid_type == amd && _family == 0xf)) {
|| (cpuid_type == amd && _family == 0xf)
|| (cpuid_type == zhaoxin && (_family == 0x6 || _family == 0x7))) {
infos->cpumodelnumber = _model + (_extendedmodel << 4);
} else {
infos->cpumodelnumber = _model;
@ -320,7 +336,7 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
/* Get core/thread information from cpuid 0x80000008
* (not supported on Intel)
*/
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000008) {
if (cpuid_type != intel && cpuid_type != zhaoxin && highest_ext_cpuid >= 0x80000008) {
unsigned max_nbcores;
unsigned max_nbthreads;
unsigned coreidsize;
@ -356,9 +372,12 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
* and cache information from cpuid 0x8000001d
* (AMD topology extension)
*/
if (cpuid_type != intel && has_topoext(features)) {
if (cpuid_type != intel && cpuid_type != zhaoxin && has_topoext(features)) {
unsigned apic_id, node_id, nodes_per_proc;
/* the code below doesn't want any other cache yet */
assert(!infos->numcaches);
eax = 0x8000001e;
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
infos->apicid = apic_id = eax;
@ -403,7 +422,7 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
}
cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache));
if (cache) {
for (cachenum = 0; ; cachenum++) {
unsigned long linesize, linepart, ways, sets;
eax = 0x8000001d;
@ -442,18 +461,21 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
cache++;
}
} else {
infos->numcaches = 0;
}
} else {
/* If there's no topoext,
* get cache information from cpuid 0x80000005 and 0x80000006
* (not supported on Intel)
*/
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000005) {
if (cpuid_type != intel && cpuid_type != zhaoxin && highest_ext_cpuid >= 0x80000005) {
eax = 0x80000005;
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
fill_amd_cache(infos, 1, HWLOC_OBJ_CACHE_DATA, 1, ecx); /* private L1d */
fill_amd_cache(infos, 1, HWLOC_OBJ_CACHE_INSTRUCTION, 1, edx); /* private L1i */
}
if (cpuid_type != intel && highest_ext_cpuid >= 0x80000006) {
if (cpuid_type != intel && cpuid_type != zhaoxin && highest_ext_cpuid >= 0x80000006) {
eax = 0x80000006;
cpuid_or_from_dump(&eax, &ebx, &ecx, &edx, src_cpuiddump);
if (ecx & 0xf000)
@ -474,6 +496,8 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
unsigned max_nbcores;
unsigned max_nbthreads;
unsigned level;
struct cacheinfo *tmpcaches;
unsigned oldnumcaches = infos->numcaches; /* in case we got caches above */
for (cachenum = 0; ; cachenum++) {
eax = 0x04;
@ -500,7 +524,10 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
}
}
cache = infos->cache = malloc(infos->numcaches * sizeof(*infos->cache));
tmpcaches = realloc(infos->cache, infos->numcaches * sizeof(*infos->cache));
if (tmpcaches) {
infos->cache = tmpcaches;
cache = &infos->cache[oldnumcaches];
for (cachenum = 0; ; cachenum++) {
unsigned long linesize, linepart, ways, sets;
@ -542,11 +569,12 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
cache++;
}
}
}
/* Get package/core/thread information from cpuid 0x0b
* (Intel x2APIC)
*/
if (cpuid_type == intel && highest_cpuid >= 0x0b && has_x2apic(features)) {
if ((cpuid_type == intel || cpuid_type == zhaoxin) && highest_cpuid >= 0x0b && has_x2apic(features)) {
unsigned level, apic_nextshift, apic_number, apic_type, apic_id = 0, apic_shift = 0, id;
for (level = 0; ; level++) {
ecx = level;
@ -556,8 +584,9 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
break;
}
if (level) {
infos->levels = level;
infos->otherids = malloc(level * sizeof(*infos->otherids));
if (infos->otherids) {
infos->levels = level;
for (level = 0; ; level++) {
ecx = level;
eax = 0x0b;
@ -594,6 +623,7 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
hwloc_debug("this is thread %u of core %u\n", infos->threadid, infos->coreid);
}
}
}
/* Now that we have all info, compute cacheids and apply quirks */
for (cachenum = 0; cachenum < infos->numcaches; cachenum++) {
@ -602,9 +632,17 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
/* default cacheid value */
cache->cacheid = infos->apicid / cache->nbthreads_sharing;
/* AMD quirk */
if (cpuid_type == amd
&& infos->cpufamilynumber== 0x10 && infos->cpumodelnumber == 0x9
if (cpuid_type == amd) {
/* AMD quirks */
if (infos->cpufamilynumber == 0x17
&& cache->level == 3 && cache->nbthreads_sharing == 6) {
/* AMD family 0x17 always shares L3 between 8 APIC ids,
* even when only 6 APIC ids are enabled and reported in nbthreads_sharing
* (on 24-core CPUs).
*/
cache->cacheid = infos->apicid / 8;
} else if (infos->cpufamilynumber== 0x10 && infos->cpumodelnumber == 0x9
&& cache->level == 3
&& (cache->ways == -1 || (cache->ways % 2 == 0)) && cache->nbthreads_sharing >= 8) {
/* Fix AMD family 0x10 model 0x9 (Magny-Cours) with 8 or 12 cores.
@ -625,17 +663,17 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
cache->cacheid = (infos->apicid % legacy_max_log_proc) / cache->nbthreads_sharing /* cacheid within the package */
+ 2 * (infos->apicid / legacy_max_log_proc); /* add 2 caches per previous package */
} else if (cpuid_type == amd
&& infos->cpufamilynumber == 0x15
} else if (infos->cpufamilynumber == 0x15
&& (infos->cpumodelnumber == 0x1 /* Bulldozer */ || infos->cpumodelnumber == 0x2 /* Piledriver */)
&& cache->level == 3 && cache->nbthreads_sharing == 6) {
/* AMD Bulldozer and Piledriver 12-core processors have same APIC ids as Magny-Cours above,
/* AMD Bulldozer and Piledriver 12-core processors have same APIC ids as Magny-Cours below,
* but we can't merge the checks because the original nbthreads_sharing must be exactly 6 here.
*/
cache->cacheid = (infos->apicid % legacy_max_log_proc) / cache->nbthreads_sharing /* cacheid within the package */
+ 2 * (infos->apicid / legacy_max_log_proc); /* add 2 cache per previous package */
}
}
}
if (hwloc_bitmap_isset(data->apicid_set, infos->apicid))
data->apicid_unique = 0;
@ -644,22 +682,23 @@ static void look_proc(struct hwloc_backend *backend, struct procinfo *infos, uns
}
static void
hwloc_x86_add_cpuinfos(hwloc_obj_t obj, struct procinfo *info, int nodup)
hwloc_x86_add_cpuinfos(hwloc_obj_t obj, struct procinfo *info, int replace)
{
char number[8];
hwloc_obj_add_info_nodup(obj, "CPUVendor", info->cpuvendor, nodup);
if (info->cpuvendor[0])
hwloc__add_info_nodup(&obj->infos, &obj->infos_count, "CPUVendor", info->cpuvendor, replace);
snprintf(number, sizeof(number), "%u", info->cpufamilynumber);
hwloc_obj_add_info_nodup(obj, "CPUFamilyNumber", number, nodup);
hwloc__add_info_nodup(&obj->infos, &obj->infos_count, "CPUFamilyNumber", number, replace);
snprintf(number, sizeof(number), "%u", info->cpumodelnumber);
hwloc_obj_add_info_nodup(obj, "CPUModelNumber", number, nodup);
hwloc__add_info_nodup(&obj->infos, &obj->infos_count, "CPUModelNumber", number, replace);
if (info->cpumodel[0]) {
const char *c = info->cpumodel;
while (*c == ' ')
c++;
hwloc_obj_add_info_nodup(obj, "CPUModel", c, nodup);
hwloc__add_info_nodup(&obj->infos, &obj->infos_count, "CPUModel", c, replace);
}
snprintf(number, sizeof(number), "%u", info->cpustepping);
hwloc_obj_add_info_nodup(obj, "CPUStepping", number, nodup);
hwloc__add_info_nodup(&obj->infos, &obj->infos_count, "CPUStepping", number, replace);
}
/* Analyse information stored in infos, and build/annotate topology levels accordingly */
@ -672,6 +711,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, int
unsigned i, j, l, level;
int one = -1;
hwloc_bitmap_t remaining_cpuset;
int gotnuma = 0;
for (i = 0; i < nbprocs; i++)
if (infos[i].present) {
@ -771,6 +811,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, int
hwloc_debug_1arg_bitmap("os node %u has cpuset %s\n",
nodeid, node_cpuset);
hwloc_insert_object_by_cpuset(topology, node);
gotnuma++;
}
}
@ -963,7 +1004,7 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, int
hwloc_bitmap_clr(remaining_cpuset, j);
}
}
cache = hwloc_alloc_setup_object(topology, otype, -1);
cache = hwloc_alloc_setup_object(topology, otype, HWLOC_UNKNOWN_INDEX);
cache->attr->cache.depth = level;
cache->attr->cache.size = infos[i].cache[l].size;
cache->attr->cache.linesize = infos[i].cache[l].linesize;
@ -984,6 +1025,9 @@ static void summarize(struct hwloc_backend *backend, struct procinfo *infos, int
hwloc_bitmap_free(remaining_cpuset);
hwloc_bitmap_free(complete_cpuset);
if (gotnuma)
topology->support.discovery->numa = 1;
}
static int
@ -1012,6 +1056,8 @@ look_procs(struct hwloc_backend *backend, struct procinfo *infos, int fulldiscov
struct cpuiddump *src_cpuiddump = NULL;
if (data->src_cpuiddump_path) {
src_cpuiddump = cpuiddump_read(data->src_cpuiddump_path, i);
if (!src_cpuiddump)
continue;
} else {
hwloc_bitmap_only(set, i);
hwloc_debug("binding to CPU%u\n", i);
@ -1066,15 +1112,25 @@ static void hwloc_x86_os_state_save(hwloc_x86_os_state_t *state __hwloc_attribut
static void hwloc_x86_os_state_restore(hwloc_x86_os_state_t *state __hwloc_attribute_unused, struct cpuiddump *src_cpuiddump __hwloc_attribute_unused) { }
#endif /* !defined HWLOC_FREEBSD_SYS || !defined HAVE_CPUSET_SETID */
/* GenuineIntel */
#define INTEL_EBX ('G' | ('e'<<8) | ('n'<<16) | ('u'<<24))
#define INTEL_EDX ('i' | ('n'<<8) | ('e'<<16) | ('I'<<24))
#define INTEL_ECX ('n' | ('t'<<8) | ('e'<<16) | ('l'<<24))
/* AuthenticAMD */
#define AMD_EBX ('A' | ('u'<<8) | ('t'<<16) | ('h'<<24))
#define AMD_EDX ('e' | ('n'<<8) | ('t'<<16) | ('i'<<24))
#define AMD_ECX ('c' | ('A'<<8) | ('M'<<16) | ('D'<<24))
/* (Zhaoxin) CentaurHauls */
#define ZX_EBX ('C' | ('e'<<8) | ('n'<<16) | ('t'<<24))
#define ZX_EDX ('a' | ('u'<<8) | ('r'<<16) | ('H'<<24))
#define ZX_ECX ('a' | ('u'<<8) | ('l'<<16) | ('s'<<24))
/* (Zhaoxin) Shanghai */
#define SH_EBX (' ' | (' '<<8) | ('S'<<16) | ('h'<<24))
#define SH_EDX ('a' | ('n'<<8) | ('g'<<16) | ('h'<<24))
#define SH_ECX ('a' | ('i'<<8) | (' '<<16) | (' '<<24))
/* fake cpubind for when nbprocs=1 and no binding support */
static int fake_get_cpubind(hwloc_topology_t topology __hwloc_attribute_unused,
hwloc_cpuset_t set __hwloc_attribute_unused,
@ -1114,6 +1170,9 @@ int hwloc_look_x86(struct hwloc_backend *backend, int fulldiscovery)
if (data->src_cpuiddump_path) {
/* just read cpuid from the dump */
src_cpuiddump = cpuiddump_read(data->src_cpuiddump_path, 0);
if (!src_cpuiddump)
goto out;
} else {
/* otherwise check if binding works */
memset(&hooks, 0, sizeof(hooks));
@ -1157,8 +1216,11 @@ int hwloc_look_x86(struct hwloc_backend *backend, int fulldiscovery)
highest_cpuid = eax;
if (ebx == INTEL_EBX && ecx == INTEL_ECX && edx == INTEL_EDX)
cpuid_type = intel;
if (ebx == AMD_EBX && ecx == AMD_ECX && edx == AMD_EDX)
else if (ebx == AMD_EBX && ecx == AMD_ECX && edx == AMD_EDX)
cpuid_type = amd;
else if ((ebx == ZX_EBX && ecx == ZX_ECX && edx == ZX_EDX)
|| (ebx == SH_EBX && ecx == SH_ECX && edx == SH_EDX))
cpuid_type = zhaoxin;
hwloc_debug("highest cpuid %x, cpuid type %u\n", highest_cpuid, cpuid_type);
if (highest_cpuid < 0x01) {
@ -1241,8 +1303,17 @@ hwloc_x86_discover(struct hwloc_backend *backend)
}
#endif
if (!data->src_cpuiddump_path)
data->nbprocs = hwloc_fallback_nbprocessors(topology);
if (data->src_cpuiddump_path) {
assert(data->nbprocs > 0); /* enforced by hwloc_x86_component_instantiate() */
topology->support.discovery->pu = 1;
} else {
int nbprocs = hwloc_fallback_nbprocessors(topology);
if (nbprocs >= 1)
topology->support.discovery->pu = 1;
else
nbprocs = 1;
data->nbprocs = (unsigned) nbprocs;
}
if (topology->levels[0][0]->cpuset) {
/* somebody else discovered things */
@ -1260,7 +1331,7 @@ hwloc_x86_discover(struct hwloc_backend *backend)
return 0;
} else {
/* topology is empty, initialize it */
hwloc_alloc_obj_cpusets(topology->levels[0][0]);
hwloc_alloc_root_sets(topology->levels[0][0]);
}
fulldiscovery:
@ -1294,7 +1365,6 @@ hwloc_x86_check_cpuiddump_input(const char *src_cpuiddump_path, hwloc_bitmap_t s
#if !(defined HWLOC_WIN_SYS && !defined __MINGW32__) /* needs a lot of work */
struct dirent *dirent;
DIR *dir;
char *path;
FILE *file;
char line [32];
@ -1302,30 +1372,23 @@ hwloc_x86_check_cpuiddump_input(const char *src_cpuiddump_path, hwloc_bitmap_t s
if (!dir)
return -1;
path = malloc(strlen(src_cpuiddump_path) + strlen("/hwloc-cpuid-info") + 1);
if (!path)
goto out_with_dir;
char path[strlen(src_cpuiddump_path) + strlen("/hwloc-cpuid-info") + 1];
sprintf(path, "%s/hwloc-cpuid-info", src_cpuiddump_path);
file = fopen(path, "r");
if (!file) {
fprintf(stderr, "Couldn't open dumped cpuid summary %s\n", path);
free(path);
goto out_with_dir;
}
if (!fgets(line, sizeof(line), file)) {
fprintf(stderr, "Found read dumped cpuid summary in %s\n", path);
fclose(file);
free(path);
goto out_with_dir;
}
fclose(file);
if (strcmp(line, "Architecture: x86\n")) {
fprintf(stderr, "Found non-x86 dumped cpuid summary in %s: %s\n", path, line);
free(path);
goto out_with_dir;
}
free(path);
while ((dirent = readdir(dir)) != NULL) {
if (!strncmp(dirent->d_name, "pu", 2)) {
@ -1404,6 +1467,7 @@ hwloc_x86_component_instantiate(struct hwloc_disc_component *component,
if (!hwloc_x86_check_cpuiddump_input(src_cpuiddump_path, set)) {
backend->is_thissystem = 0;
data->src_cpuiddump_path = strdup(src_cpuiddump_path);
assert(!hwloc_bitmap_iszero(set)); /* enforced by hwloc_x86_check_cpuiddump_input() */
data->nbprocs = hwloc_bitmap_weight(set);
} else {
fprintf(stderr, "Ignoring dumped cpuid directory.\n");
@ -1425,6 +1489,7 @@ static struct hwloc_disc_component hwloc_x86_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_x86_component_instantiate,
45, /* between native and no_os */
1,
NULL
};

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

@ -1,6 +1,6 @@
/*
* 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 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -55,7 +55,7 @@ hwloc_libxml2_cleanup(void)
typedef struct hwloc__libxml_import_state_data_s {
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 */
} __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;
for (subnode = attr->children; subnode; subnode = subnode->next) {
if (subnode->type == XML_TEXT_NODE) {
if (subnode->content && subnode->content[0] != '\0' && subnode->content[0] != '\n') {
if (subnode->content) {
*namep = (char *) attr->name;
*valuep = (char *) subnode->content;
lstate->attr = attr;
@ -83,12 +83,14 @@ hwloc__libxml_import_next_attr(hwloc__xml_import_state_t state, char **namep, ch
}
} else {
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 {
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;
}
@ -104,11 +106,13 @@ hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
childstate->parent = state;
childstate->global = state->global;
if (!lstate->child)
/* All children proceeded */
return 0;
child = lstate->child->next;
for (; child; child = child->next)
child = lstate->child;
if (child->type == XML_ELEMENT_NODE) {
lstate->child = lchildstate->node = child;
lstate->child = child->next;
lchildstate->node = child;
lchildstate->child = child->children;
lchildstate->attr = NULL;
*tagp = (char*) child->name;
@ -116,10 +120,12 @@ hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
} else if (child->type == XML_TEXT_NODE) {
if (child->content && child->content[0] != '\0' && child->content[0] != '\n')
if (hwloc__xml_verbose())
fprintf(stderr, "ignoring object text content %s\n", (const char*) child->content);
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, "ignoring unexpected xml node type %u\n", child->type);
fprintf(stderr, "%s: ignoring unexpected xml node type %u\n",
state->global->msgprefix, child->type);
}
return 0;
@ -149,7 +155,7 @@ hwloc__libxml_import_get_content(hwloc__xml_import_state_t state,
if (!child || child->type != XML_TEXT_NODE) {
if (expected_length)
return -1;
*beginp = "";
*beginp = (char *) "";
return 0;
}
@ -171,27 +177,44 @@ hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlNode* root_node;
xmlDtd *dtd;
xmlNodePtr root_node;
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 (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topology without DTD\n");
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")) {
fprintf(stderr, "%s: Loading XML topology without DTD\n",
state->global->msgprefix);
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")
&& strcmp((char *) dtd->SystemID, "hwloc2.dtd")) {
if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topology with wrong DTD SystemID (%s instead of %s)\n",
(char *) dtd->SystemID, "hwloc.dtd");
fprintf(stderr, "%s: Loading XML topology with wrong DTD SystemID (%s instead of %s)\n",
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) */
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;
}
@ -211,6 +234,24 @@ hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
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
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;
int ret;
assert(sizeof(*lstate) <= sizeof(state->data));
HWLOC_BUILD_ASSERT(sizeof(*lstate) <= sizeof(state->data));
LIBXML_TEST_VERSION;
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 */
if (xmlpath)
doc = xmlReadFile(xmlpath, NULL, 0);
doc = xmlReadFile(xmlpath, NULL, XML_PARSE_NOBLANKS);
else if (xmlbuffer)
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0);
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, XML_PARSE_NOBLANKS);
if (!doc) {
if (!errno)
/* libxml2 read the file fine, but it got an error during parsing */
errno = EINVAL;
hwloc_libxml2_cleanup();
goto out;
}
dtd = xmlGetIntSubset(doc);
if (!dtd) {
if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topologydiff without DTD\n");
} else if (strcmp((char *) dtd->SystemID, "hwloc.dtd")) {
fprintf(stderr, "%s: Loading XML topologydiff without DTD\n",
state->global->msgprefix);
} else if (strcmp((char *) dtd->SystemID, "hwloc2-diff.dtd")) {
if (hwloc__xml_verbose())
fprintf(stderr, "Loading XML topologydiff with wrong DTD SystemID (%s instead of %s)\n",
(char *) dtd->SystemID, "hwloc.dtd");
fprintf(stderr, "%s: Loading XML topologydiff with wrong DTD SystemID (%s instead of %s)\n",
state->global->msgprefix, (char *) dtd->SystemID, "hwloc2-diff.dtd");
}
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")) {
/* root node should be in "topologydiff" class */
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;
}
@ -306,7 +350,7 @@ out:
static void
hwloc_libxml_backend_exit(struct hwloc_xml_backend_data_s *bdata)
{
xmlFreeDoc((xmlDoc*)bdata->data);
hwloc_libxml_free_buffers(bdata);
hwloc_libxml2_cleanup();
}
@ -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 */
if (xmlpath)
doc = xmlReadFile(xmlpath, NULL, 0);
doc = xmlReadFile(xmlpath, NULL, XML_PARSE_NOBLANKS);
else if (xmlbuffer)
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, 0);
doc = xmlReadMemory(xmlbuffer, xmlbuflen, "", NULL, XML_PARSE_NOBLANKS);
if (!doc) {
if (!errno)
/* libxml2 read the file fine, but it got an error during parsing */
errno = EINVAL;
hwloc_libxml2_cleanup();
return -1;
}
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->data = doc;
return 0;
@ -361,6 +406,7 @@ hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object;
state->global = parentstate->global;
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
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;
hwloc__libxml_export_state_data_t data = (void *) state.data;
int v1export = flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1;
xmlDocPtr doc = NULL; /* document pointer */
xmlNodePtr root_node = NULL; /* root pointer */
assert(sizeof(*data) <= sizeof(state.data));
HWLOC_BUILD_ASSERT(sizeof(*data) <= sizeof(state.data));
LIBXML_TEST_VERSION;
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. */
doc = xmlNewDoc(BAD_CAST "1.0");
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);
/* 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_prop = hwloc__libxml_export_new_prop;
state.add_content = hwloc__libxml_export_add_content;
state.end_object = hwloc__libxml_export_end_object;
state.global = edata;
data->current_node = root_node;
@ -419,14 +470,15 @@ hwloc__libxml2_prepare_export(hwloc_topology_t topology, unsigned long flags)
}
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;
int ret;
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);
xmlFreeDoc(doc);
hwloc_libxml2_cleanup();
@ -441,11 +493,12 @@ hwloc_libxml_export_file(hwloc_topology_t topology, const char *filename, unsign
}
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;
doc = hwloc__libxml2_prepare_export(topology, flags);
doc = hwloc__libxml2_prepare_export(topology, edata, flags);
xmlDocDumpFormatMemoryEnc(doc, (xmlChar **)xmlbuffer, buflen, "UTF-8", 1);
xmlFreeDoc(doc);
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 */
xmlNodePtr root_node = NULL; /* root pointer */
assert(sizeof(*data) <= sizeof(state.data));
HWLOC_BUILD_ASSERT(sizeof(*data) <= sizeof(state.data));
LIBXML_TEST_VERSION;
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);
/* 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_prop = hwloc__libxml_export_new_prop;

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

@ -1,6 +1,6 @@
/*
* 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 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -117,6 +117,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__nolibxml_import_state_data_t nchildstate = (void*) childstate->data;
char *buffer = nstate->tagbuffer;
char *end;
char *tag;
size_t namelen;
childstate->parent = state;
@ -137,7 +138,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
return 0;
/* normal tag */
*tagp = nchildstate->tagname = buffer;
tag = nchildstate->tagname = buffer;
/* find the end, mark it and return it */
end = strchr(buffer, '>');
@ -159,6 +160,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
if (buffer[namelen] == '\0') {
/* no attributes */
nchildstate->attrbuffer = NULL;
*tagp = tag;
return 1;
}
@ -168,6 +170,7 @@ hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
/* found a space, likely starting attributes */
buffer[namelen] = '\0';
nchildstate->attrbuffer = buffer+namelen+1;
*tagp = tag;
return 1;
}
@ -222,7 +225,7 @@ hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
if (nstate->closed) {
if (expected_length)
return -1;
*beginp = "";
*beginp = (char *) "";
return 0;
}
@ -255,9 +258,11 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
unsigned major, minor;
char *end;
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 */
buffer = nbdata->copy;
@ -272,7 +277,19 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
}
/* 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;
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->parent = NULL;
nstate->closed = 0;
nstate->tagbuffer = buffer+10;
nstate->tagbuffer = end;
nstate->tagname = (char *) "topology";
nstate->attrbuffer = NULL;
return 0; /* success */
@ -292,10 +309,29 @@ hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
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_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;
if (nbdata->buffer) {
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)
{
struct hwloc__nolibxml_backend_data_s *nbdata = bdata->data;
free(nbdata->buffer);
free(nbdata->copy);
hwloc_nolibxml_free_buffers(bdata);
free(nbdata);
}
@ -399,7 +434,7 @@ hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
goto out_with_buffer;
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;
return 0;
@ -423,7 +458,7 @@ hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
size_t buflen;
int ret;
assert(sizeof(*nstate) <= sizeof(state->data));
HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
if (xmlbuffer) {
buffer = malloc(xmlbuflen);
@ -581,6 +616,7 @@ hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
state->new_prop = parentstate->new_prop;
state->add_content = parentstate->add_content;
state->end_object = parentstate->end_object;
state->global = parentstate->global;
ndata->buffer = npdata->buffer;
ndata->written = npdata->written;
@ -644,18 +680,21 @@ hwloc__nolibxml_export_add_content(hwloc__xml_export_state_t state, const char *
}
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;
hwloc__nolibxml_export_state_data_t ndata = (void *) &state.data;
int v1export = flags & HWLOC_TOPOLOGY_EXPORT_XML_FLAG_V1;
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_prop = hwloc__nolibxml_export_new_prop;
state.add_content = hwloc__nolibxml_export_add_content;
state.end_object = hwloc__nolibxml_export_end_object;
state.global = edata;
ndata->indent = 0;
ndata->written = 0;
@ -667,9 +706,11 @@ hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?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_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__nolibxml_export_end_object(&childstate, "topology");
@ -677,7 +718,8 @@ hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, 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;
size_t bufferlen, res;
@ -686,7 +728,7 @@ hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buf
buffer = malloc(bufferlen);
if (!buffer)
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) {
char *tmp = realloc(buffer, res);
@ -695,7 +737,7 @@ hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buf
return -1;
}
buffer = tmp;
hwloc___nolibxml_prepare_export(topology, buffer, (int)res, flags);
hwloc___nolibxml_prepare_export(topology, edata, buffer, (int)res, flags);
}
*bufferp = buffer;
@ -704,14 +746,15 @@ hwloc_nolibxml_export_buffer(hwloc_topology_t topology, char **bufferp, int *buf
}
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;
char *buffer;
int bufferlen;
int ret;
ret = hwloc_nolibxml_export_buffer(topology, &buffer, &bufferlen, flags);
ret = hwloc_nolibxml_export_buffer(topology, edata, &buffer, &bufferlen, flags);
if (ret < 0)
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;
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_prop = hwloc__nolibxml_export_new_prop;
@ -764,7 +807,7 @@ hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff, const char *ref
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?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_new_child(&state, &childstate, "topologydiff");
if (refname)

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

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

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2010 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -18,14 +18,20 @@
int
hwloc_get_type_depth (struct hwloc_topology *topology, hwloc_obj_type_t 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_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) {
case HWLOC_TYPE_DEPTH_NUMANODE:
return HWLOC_OBJ_NUMANODE;
case HWLOC_TYPE_DEPTH_BRIDGE:
return HWLOC_OBJ_BRIDGE;
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;
}
unsigned
hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, unsigned depth)
int
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);
if (l < HWLOC_NR_SLEVELS)
return topology->slevels[l].nbobjs;
@ -54,9 +85,9 @@ hwloc_get_nbobjs_by_depth (struct hwloc_topology *topology, unsigned depth)
}
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);
if (l < HWLOC_NR_SLEVELS)
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];
}
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)
{
struct hwloc_obj *parent, *nextparent, **src_objs;
int i,src_nbobjects;
unsigned i,src_nbobjects;
unsigned stored = 0;
if (!src->cpuset)
@ -163,11 +230,10 @@ hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_con
}
const char *
hwloc_type_name (hwloc_obj_type_t obj)
hwloc_obj_type_string (hwloc_obj_type_t obj)
{
switch (obj)
{
case HWLOC_OBJ_SYSTEM: return "System";
case HWLOC_OBJ_MACHINE: return "Machine";
case HWLOC_OBJ_MISC: return "Misc";
case HWLOC_OBJ_GROUP: return "Group";
@ -206,8 +272,30 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
*/
/* 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)) {
type = HWLOC_OBJ_MACHINE;
} else if (!hwloc_strncasecmp(string, "node", 2)
@ -235,28 +323,6 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
} else if (!hwloc_strncasecmp(string, "pci", 3)) {
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 */
} else if ((string[0] == 'l' || string[0] == 'L') && string[1] >= '0' && string[1] <= '9') {
depthattr = strtol(string+1, &end, 10);
@ -288,7 +354,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
*typep = type;
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.type = cachetypeattr;
} else if (type == HWLOC_OBJ_GROUP && attrsize >= sizeof(attrp->group)) {
@ -325,7 +391,7 @@ hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
for(l=0; l<topology->nb_levels; l++) {
if (topology->levels[l][0]->type == HWLOC_OBJ_GROUP
&& topology->levels[l][0]->attr->group.depth == attr.group.depth) {
depth = l;
depth = (int)l;
break;
}
}
@ -333,7 +399,7 @@ hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
if (typep)
*typep = type;
*depthp = (unsigned) depth;
*depthp = depth;
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;
switch (type) {
case HWLOC_OBJ_MISC:
case HWLOC_OBJ_SYSTEM:
case HWLOC_OBJ_MACHINE:
case HWLOC_OBJ_NUMANODE:
case HWLOC_OBJ_PACKAGE:
case HWLOC_OBJ_CORE:
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_L2CACHE:
case HWLOC_OBJ_L3CACHE:
@ -373,9 +438,9 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
verbose ? "Cache" : "");
case HWLOC_OBJ_GROUP:
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
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:
return snprintf(string, size, obj->attr->bridge.upstream_type == HWLOC_OBJ_BRIDGE_PCI ? "PCIBridge" : "HostBridge");
case HWLOC_OBJ_PCI_DEVICE:
@ -417,25 +482,25 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
/* print memory attributes */
res = 0;
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",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose),
(unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose),
separator,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.local_memory, verbose));
else if (obj->memory.total_memory)
(unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
hwloc_memory_size_printf_unit(obj->total_memory, verbose));
else if (obj->total_memory)
res = hwloc_snprintf(tmp, tmplen, "%stotal=%lu%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.total_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.total_memory, verbose));
(unsigned long) hwloc_memory_size_printf_value(obj->total_memory, verbose),
hwloc_memory_size_printf_unit(obj->total_memory, verbose));
} 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",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->memory.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->memory.local_memory, verbose));
(unsigned long) hwloc_memory_size_printf_value(obj->attr->numanode.local_memory, verbose),
hwloc_memory_size_printf_unit(obj->attr->numanode.local_memory, verbose));
}
if (res < 0)
return -1;
@ -529,14 +594,12 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (verbose) {
unsigned i;
for(i=0; i<obj->infos_count; i++) {
if (strchr(obj->infos[i].value, ' '))
res = hwloc_snprintf(tmp, tmplen, "%s%s=\"%s\"",
struct hwloc_info_s *info = &obj->infos[i];
const char *quote = strchr(info->value, ' ') ? "\"" : "";
res = hwloc_snprintf(tmp, tmplen, "%s%s=%s%s%s",
prefix,
obj->infos[i].name, obj->infos[i].value);
else
res = hwloc_snprintf(tmp, tmplen, "%s%s=%s",
prefix,
obj->infos[i].name, obj->infos[i].value);
info->name,
quote, info->value, quote);
if (res < 0)
return -1;
ret += res;

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

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

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -168,29 +168,22 @@ typedef hwloc_const_bitmap_t hwloc_const_nodeset_t;
* may be defined in the future! If you need to compare types, use
* hwloc_compare_types() instead.
*/
#define HWLOC_OBJ_TYPE_MIN HWLOC_OBJ_MACHINE /**< \private Sentinel value */
typedef enum {
HWLOC_OBJ_SYSTEM, /**< \brief Whole system (may be a cluster of machines).
* The whole system that is accessible to hwloc.
* That may comprise several machines in SSI systems.
* This object type is currently unused in native backends.
*/
HWLOC_OBJ_MACHINE, /**< \brief Machine.
* The typical root object type.
* A set of processors and memory with cache
* coherency.
*/
HWLOC_OBJ_NUMANODE, /**< \brief NUMA node.
* A set of processors around memory which the
* processors can directly access.
*
* There is always at one such object in the topology
* even if the machine is not NUMA.
*/
HWLOC_OBJ_PACKAGE, /**< \brief Physical package, what goes into a socket.
* In the physical meaning, i.e. that you can add
* or remove physically.
* This type is always used for the root object of a topology,
* and never used anywhere else.
* Hence its parent is always \c NULL.
*/
HWLOC_OBJ_PACKAGE, /**< \brief Physical package.
* The physical package that usually gets inserted
* into a socket on the motherboard.
* A processor package usually contains multiple cores.
*/
HWLOC_OBJ_CORE, /**< \brief Core.
* A computation unit (may be shared by several
* logical processors).
@ -200,6 +193,9 @@ typedef enum {
* other logical processors, e.g. in the case of
* an SMT core).
*
* This is the smallest object representing CPU resources,
* it cannot have any child except Misc objects.
*
* Objects of this kind are always reported and can
* thus be used as fallback when others are not.
*/
@ -227,15 +223,21 @@ typedef enum {
* any structure.
*/
HWLOC_OBJ_MISC, /**< \brief Miscellaneous objects (filtered out by default).
* Objects without particular meaning, that can e.g. be
* added by the application for its own use, or by hwloc
* for miscellaneous objects such as MemoryModule (DIMMs).
* These objects are not listed in the main children list,
* but rather in the dedicated misc children list.
* Misc objects may only have Misc objects as children,
* and those are in the dedicated misc children list as well.
* Misc objects have NULL CPU and node sets.
HWLOC_OBJ_NUMANODE, /**< \brief NUMA node.
* An object that contains memory that is directly
* and byte-accessible to the host processors.
* It is usually close to some cores (the corresponding objects
* are descendants of the NUMA node object in the hwloc tree).
*
* There is always at one such object in the topology
* even if the machine is not NUMA.
*
* Memory objects are not listed in the main children list,
* but rather in the dedicated Memory children list.
*
* NUMA nodes have a special depth ::HWLOC_TYPE_DEPTH_NUMANODE
* instead of a normal depth just like other objects in the
* main tree.
*/
HWLOC_OBJ_BRIDGE, /**< \brief Bridge (filtered out by default).
@ -262,6 +264,17 @@ typedef enum {
* I/O objects have NULL CPU and node sets.
*/
HWLOC_OBJ_MISC, /**< \brief Miscellaneous objects (filtered out by default).
* Objects without particular meaning, that can e.g. be
* added by the application for its own use, or by hwloc
* for miscellaneous objects such as MemoryModule (DIMMs).
* These objects are not listed in the main children list,
* but rather in the dedicated misc children list.
* Misc objects may only have Misc objects as children,
* and those are in the dedicated misc children list as well.
* Misc objects have NULL CPU and node sets.
*/
HWLOC_OBJ_TYPE_MAX /**< \private Sentinel value */
} hwloc_obj_type_t;
@ -310,7 +323,9 @@ typedef enum hwloc_obj_osdev_type_e {
* contain packages which contain caches, which contain cores, which contain
* processors).
*
* \note ::HWLOC_OBJ_PU will always be the deepest.
* \note ::HWLOC_OBJ_PU will always be the deepest,
* while ::HWLOC_OBJ_MACHINE is always the highest.
*
* \note This does not mean that the actual topology will respect that order:
* e.g. as of today cores may also contain caches, and packages may also contain
* nodes. This is thus just to be seen as a fallback comparison method.
@ -331,27 +346,9 @@ enum hwloc_compare_types_e {
union hwloc_obj_attr_u;
/** \brief Object memory */
struct hwloc_obj_memory_s {
hwloc_uint64_t total_memory; /**< \brief Total memory (in bytes) in this object and its children */
hwloc_uint64_t local_memory; /**< \brief Local memory (in bytes) */
/** \brief Size of array \p page_types */
unsigned page_types_len;
/** \brief Array of local memory page types, \c NULL if no local memory and \p page_types is 0.
*
* The array is sorted by increasing \p size fields.
* It contains \p page_types_len slots.
*/
struct hwloc_obj_memory_page_type_s {
hwloc_uint64_t size; /**< \brief Size of pages */
hwloc_uint64_t count; /**< \brief Number of pages of this size */
} * page_types;
};
/** \brief Structure of a topology object
*
* Applications must not modify any field except hwloc_obj.userdata.
* Applications must not modify any field except \p hwloc_obj.userdata.
*/
struct hwloc_obj {
/* physical information */
@ -361,22 +358,35 @@ struct hwloc_obj {
unsigned os_index; /**< \brief OS-provided physical index number.
* It is not guaranteed unique across the entire machine,
* except for PUs and NUMA nodes.
* Set to HWLOC_UNKNOWN_INDEX if unknown or irrelevant for this object.
*/
#define HWLOC_UNKNOWN_INDEX (unsigned)-1
char *name; /**< \brief Object-specific name if any.
* Mostly used for identifying OS devices and Misc objects where
* a name string is more useful than numerical indexes.
*/
struct hwloc_obj_memory_s memory; /**< \brief Memory attributes */
hwloc_uint64_t total_memory; /**< \brief Total memory (in bytes) in NUMA nodes below this object. */
union hwloc_obj_attr_u *attr; /**< \brief Object type-specific Attributes,
* may be \c NULL if no attribute value was found */
/* global position */
unsigned depth; /**< \brief Vertical index in the hierarchy.
* If the topology is symmetric, this is equal to the
* parent depth plus one, and also equal to the number
* of parent/child links from the root object to here.
int depth; /**< \brief Vertical index in the hierarchy.
*
* For normal objects, this is the depth of the horizontal level
* that contains this object and its cousins of the same type.
* If the topology is symmetric, this is equal to the parent depth
* plus one, and also equal to the number of parent/child links
* from the root object to here.
*
* For special objects (NUMA nodes, I/O and Misc) that are not
* in the main tree, this is a special negative value that
* corresponds to their dedicated level,
* see hwloc_get_type_depth() and ::hwloc_get_type_depth_e.
* Those special values can be passed to hwloc functions such
* hwloc_get_nbobjs_by_depth() as usual.
*/
unsigned logical_index; /**< \brief Horizontal index in the whole list of similar objects,
* hence guaranteed unique across the entire machine.
@ -390,32 +400,64 @@ struct hwloc_obj {
struct hwloc_obj *prev_cousin; /**< \brief Previous object of same type and depth */
/* children of the same parent are siblings, even if they may have different type and depth */
struct hwloc_obj *parent; /**< \brief Parent, \c NULL if root (system object) */
unsigned sibling_rank; /**< \brief Index in parent's \c children[] array. Or the index in parent's I/O or Misc children list. */
struct hwloc_obj *next_sibling; /**< \brief Next object below the same parent */
struct hwloc_obj *prev_sibling; /**< \brief Previous object below the same parent */
/* children array below this object (except I/O and Misc children) */
unsigned arity; /**< \brief Number of children */
struct hwloc_obj **children; /**< \brief Children, \c children[0 .. arity -1] */
struct hwloc_obj *first_child; /**< \brief First child */
struct hwloc_obj *last_child; /**< \brief Last child */
struct hwloc_obj *parent; /**< \brief Parent, \c NULL if root (Machine object) */
unsigned sibling_rank; /**< \brief Index in parent's \c children[] array. Or the index in parent's Memory, I/O or Misc children list. */
struct hwloc_obj *next_sibling; /**< \brief Next object below the same parent (inside the same list of children). */
struct hwloc_obj *prev_sibling; /**< \brief Previous object below the same parent (inside the same list of children). */
/** @name List and array of normal children below this object (except Memory, I/O and Misc children). */
/**@{*/
unsigned arity; /**< \brief Number of normal children.
* Memory, Misc and I/O children are not listed here
* but rather in their dedicated children list.
*/
struct hwloc_obj **children; /**< \brief Normal children, \c children[0 .. arity -1] */
struct hwloc_obj *first_child; /**< \brief First normal child */
struct hwloc_obj *last_child; /**< \brief Last normal child */
/**@}*/
int symmetric_subtree; /**< \brief Set if the subtree of normal objects below this object is symmetric,
* which means all children and their children have identical subtrees.
* I/O and Misc children are ignored.
* which means all normal children and their children have identical subtrees.
*
* Memory, I/O and Misc children are ignored.
*
* If set in the topology root object, lstopo may export the topology
* as a synthetic string.
*/
/* specific list of I/O children */
unsigned io_arity; /**< \brief Number of I/O children */
struct hwloc_obj *io_first_child; /**< \brief First I/O child */
/** @name List of Memory children below this object. */
/**@{*/
unsigned memory_arity; /**< \brief Number of Memory children.
* These children are listed in \p memory_first_child.
*/
struct hwloc_obj *memory_first_child; /**< \brief First Memory child.
* NUMA nodes are listed here (\p memory_arity and \p memory_first_child)
* instead of in the normal children list.
* See also hwloc_obj_type_is_memory().
*/
/**@}*/
/* specific list of Misc children */
unsigned misc_arity; /**< \brief Number of Misc children */
struct hwloc_obj *misc_first_child; /**< \brief First Misc child */
/** @name List of I/O children below this object. */
/**@{*/
unsigned io_arity; /**< \brief Number of I/O children.
* These children are listed in \p io_first_child.
*/
struct hwloc_obj *io_first_child; /**< \brief First I/O child.
* Bridges, PCI and OS devices are listed here (\p io_arity and \p io_first_child)
* instead of in the normal children list.
* See also hwloc_obj_type_is_io().
*/
/**@}*/
/** @name List of Misc children below this object. */
/**@{*/
unsigned misc_arity; /**< \brief Number of Misc children.
* These children are listed in \p misc_first_child.
*/
struct hwloc_obj *misc_first_child; /**< \brief First Misc child.
* Misc objects are listed here (\p misc_arity and \p misc_first_child)
* instead of in the normal children list.
*/
/**@}*/
/* cpusets and nodesets */
hwloc_cpuset_t cpuset; /**< \brief CPUs covered by this object
@ -426,7 +468,8 @@ struct hwloc_obj {
* objects).
*
* If the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM configuration flag is set,
* some of these CPUs may not be allowed for binding, see allowed_cpuset.
* some of these CPUs may not be allowed for binding,
* see hwloc_topology_get_allowed_cpuset().
*
* \note All objects have non-NULL CPU and node sets except Misc and I/O objects.
*
@ -444,17 +487,6 @@ struct hwloc_obj {
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_cpuset_t allowed_cpuset; /**< \brief The CPU set of allowed logical processors
*
* This includes the CPUs contained in this object which are allowed for
* binding, i.e. passing them to the hwloc binding functions should not return
* permission errors. This is usually restricted by administration rules.
*
* If the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM configuration flag is set,
* allowed_cpuset may be smaller than cpuset. Otherwise they are identical.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_nodeset_t nodeset; /**< \brief NUMA nodes covered by this object or containing this object
*
@ -466,7 +498,8 @@ struct hwloc_obj {
* In the end, these nodes are those that are close to the current object.
*
* If the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM configuration flag is set,
* some of these nodes may not be allowed for allocation, see allowed_nodeset.
* some of these nodes may not be allowed for allocation,
* see hwloc_topology_get_allowed_nodeset().
*
* If there are no NUMA nodes in the machine, all the memory is close to this
* object, so only the first bit may be set in \p nodeset.
@ -490,23 +523,8 @@ struct hwloc_obj {
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
hwloc_nodeset_t allowed_nodeset; /**< \brief The set of allowed NUMA memory nodes
*
* This includes the NUMA memory nodes contained in this object which are
* allowed for memory allocation, i.e. passing them to NUMA node-directed
* memory allocation should not return permission errors. This is usually
* restricted by administration rules.
*
* If the ::HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM configuration flag is set,
* allowed_nodeset may be smaller than nodeset. Otherwise they are identical.
*
* If there are no NUMA nodes in the machine, all the memory is close to this
* object, so only the first bit may be set in \p allowed_nodeset.
*
* \note Its value must not be changed, hwloc_bitmap_dup() must be used instead.
*/
struct hwloc_obj_info_s *infos; /**< \brief Array of stringified info type=name. */
struct hwloc_info_s *infos; /**< \brief Array of stringified info type=name. */
unsigned infos_count; /**< \brief Size of infos array. */
/* misc */
@ -528,6 +546,21 @@ typedef struct hwloc_obj * hwloc_obj_t;
/** \brief Object type-specific Attributes */
union hwloc_obj_attr_u {
/** \brief NUMA node-specific Object Attributes */
struct hwloc_numanode_attr_s {
hwloc_uint64_t local_memory; /**< \brief Local memory (in bytes) */
unsigned page_types_len; /**< \brief Size of array \p page_types */
/** \brief Array of local memory page types, \c NULL if no local memory and \p page_types is 0.
*
* The array is sorted by increasing \p size fields.
* It contains \p page_types_len slots.
*/
struct hwloc_memory_page_type_s {
hwloc_uint64_t size; /**< \brief Size of pages */
hwloc_uint64_t count; /**< \brief Number of pages of this size */
} * page_types;
} numanode;
/** \brief Cache-specific Object Attributes */
struct hwloc_cache_attr_s {
hwloc_uint64_t size; /**< \brief Size of cache in bytes */
@ -578,7 +611,7 @@ union hwloc_obj_attr_u {
*
* \sa hwlocality_info_attr
*/
struct hwloc_obj_info_s {
struct hwloc_info_s {
char *name; /**< \brief Info name */
char *value; /**< \brief Info value */
};
@ -646,6 +679,25 @@ HWLOC_DECLSPEC void hwloc_topology_destroy (hwloc_topology_t topology);
*/
HWLOC_DECLSPEC int hwloc_topology_dup(hwloc_topology_t *newtopology, hwloc_topology_t oldtopology);
/** \brief Verify that the topology is compatible with the current hwloc library.
*
* This is useful when using the same topology structure (in memory)
* in different libraries that may use different hwloc installations
* (for instance if one library embeds a specific version of hwloc,
* while another library uses a default system-wide hwloc installation).
*
* If all libraries/programs use the same hwloc installation, this function
* always returns success.
*
* \return \c 0 on success.
*
* \return \c -1 with \p errno set to \c EINVAL if incompatible.
*
* \note If sharing between processes with hwloc_shmem_topology_write(),
* the relevant check is already performed inside hwloc_shmem_topology_adopt().
*/
HWLOC_DECLSPEC int hwloc_topology_abi_check(hwloc_topology_t topology);
/** \brief Run internal checks on a topology structure
*
* The program aborts if an inconsistency is detected in the given topology.
@ -676,10 +728,10 @@ HWLOC_DECLSPEC void hwloc_topology_check(hwloc_topology_t topology);
*
* This is the depth of ::HWLOC_OBJ_PU objects plus one.
*
* \note I/O and Misc objects are ignored when computing the depth
* of the tree (they are placed on special levels).
* \note NUMA nodes, I/O and Misc objects are ignored when computing
* the depth of the tree (they are placed on special levels).
*/
HWLOC_DECLSPEC unsigned hwloc_topology_get_depth(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
HWLOC_DECLSPEC int hwloc_topology_get_depth(hwloc_topology_t __hwloc_restrict topology) __hwloc_attribute_pure;
/** \brief Returns the depth of objects of type \p type.
*
@ -693,12 +745,13 @@ HWLOC_DECLSPEC unsigned hwloc_topology_get_depth(hwloc_topology_t __hwloc_restri
* If ::HWLOC_OBJ_GROUP is given, the function may return ::HWLOC_TYPE_DEPTH_MULTIPLE
* if multiple levels of Groups exist.
*
* If an I/O or Misc object type is given, the function returns a virtual value
* because these objects are stored in special levels that are not CPU-related.
* If a NUMA node, I/O or Misc object type is given, the function returns a virtual
* value because these objects are stored in special levels that are not CPU-related.
* This virtual depth may be passed to other hwloc functions such as
* hwloc_get_obj_by_depth() but it should not be considered as an actual
* depth by the application. In particular, it should not be compared with
* any other object depth or with the entire topology depth.
* \sa hwloc_get_memory_parents_depth().
*
* \sa hwloc_type_sscanf_as_depth() for returning the depth of objects
* whose type is given as a string.
@ -708,18 +761,44 @@ HWLOC_DECLSPEC int hwloc_get_type_depth (hwloc_topology_t topology, hwloc_obj_ty
enum hwloc_get_type_depth_e {
HWLOC_TYPE_DEPTH_UNKNOWN = -1, /**< \brief No object of given type exists in the topology. \hideinitializer */
HWLOC_TYPE_DEPTH_MULTIPLE = -2, /**< \brief Objects of given type exist at different depth in the topology (only for Groups). \hideinitializer */
HWLOC_TYPE_DEPTH_BRIDGE = -3, /**< \brief Virtual depth for bridge object level. \hideinitializer */
HWLOC_TYPE_DEPTH_PCI_DEVICE = -4, /**< \brief Virtual depth for PCI device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_OS_DEVICE = -5, /**< \brief Virtual depth for software device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_MISC = -6 /**< \brief Virtual depth for Misc object. \hideinitializer */
HWLOC_TYPE_DEPTH_NUMANODE = -3, /**< \brief Virtual depth for NUMA nodes. \hideinitializer */
HWLOC_TYPE_DEPTH_BRIDGE = -4, /**< \brief Virtual depth for bridge object level. \hideinitializer */
HWLOC_TYPE_DEPTH_PCI_DEVICE = -5, /**< \brief Virtual depth for PCI device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_OS_DEVICE = -6, /**< \brief Virtual depth for software device object level. \hideinitializer */
HWLOC_TYPE_DEPTH_MISC = -7 /**< \brief Virtual depth for Misc object. \hideinitializer */
};
/** \brief Return the depth of parents where memory objects are attached.
*
* Memory objects have virtual negative depths because they are not part of
* the main CPU-side hierarchy of objects. This depth should not be compared
* with other level depths.
*
* If all Memory objects are attached to Normal parents at the same depth,
* this parent depth may be compared to other as usual, for instance
* for knowing whether NUMA nodes is attached above or below Packages.
*
* \return The depth of Normal parents of all memory children
* if all these parents have the same depth. For instance the depth of
* the Package level if all NUMA nodes are attached to Package objects.
*
* \return ::HWLOC_TYPE_DEPTH_MULTIPLE if Normal parents of all
* memory children do not have the same depth. For instance if some
* NUMA nodes are attached to Packages while others are attached to
* Groups.
*/
HWLOC_DECLSPEC int hwloc_get_memory_parents_depth (hwloc_topology_t topology);
/** \brief Returns the depth of objects of type \p type or below
*
* If no object of this type is present on the underlying architecture, the
* function returns the depth of the first "present" object typically found
* inside \p type.
*
* This function is only meaningful for normal object types.
* If a memory, I/O or Misc object type is given, the corresponding virtual
* depth is always returned (see hwloc_get_type_depth()).
*
* May return ::HWLOC_TYPE_DEPTH_MULTIPLE for ::HWLOC_OBJ_GROUP just like
* hwloc_get_type_depth().
*/
@ -732,6 +811,10 @@ hwloc_get_type_or_below_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
* function returns the depth of the first "present" object typically
* containing \p type.
*
* This function is only meaningful for normal object types.
* If a memory, I/O or Misc object type is given, the corresponding virtual
* depth is always returned (see hwloc_get_type_depth()).
*
* May return ::HWLOC_TYPE_DEPTH_MULTIPLE for ::HWLOC_OBJ_GROUP just like
* hwloc_get_type_depth().
*/
@ -744,11 +827,11 @@ hwloc_get_type_or_above_depth (hwloc_topology_t topology, hwloc_obj_type_t type)
*
* \return (hwloc_obj_type_t)-1 if depth \p depth does not exist.
*/
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_get_depth_type (hwloc_topology_t topology, unsigned depth) __hwloc_attribute_pure;
HWLOC_DECLSPEC hwloc_obj_type_t hwloc_get_depth_type (hwloc_topology_t topology, int depth) __hwloc_attribute_pure;
/** \brief Returns the width of level at depth \p depth.
*/
HWLOC_DECLSPEC unsigned hwloc_get_nbobjs_by_depth (hwloc_topology_t topology, unsigned depth) __hwloc_attribute_pure;
HWLOC_DECLSPEC unsigned hwloc_get_nbobjs_by_depth (hwloc_topology_t topology, int depth) __hwloc_attribute_pure;
/** \brief Returns the width of level type \p type
*
@ -760,14 +843,13 @@ hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type) __hw
/** \brief Returns the top-object of the topology-tree.
*
* Its type is typically ::HWLOC_OBJ_MACHINE but it could be different
* for complex topologies.
* Its type is ::HWLOC_OBJ_MACHINE.
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_root_obj (hwloc_topology_t topology) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx from depth \p depth */
HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, unsigned depth, unsigned idx) __hwloc_attribute_pure;
HWLOC_DECLSPEC hwloc_obj_t hwloc_get_obj_by_depth (hwloc_topology_t topology, int depth, unsigned idx) __hwloc_attribute_pure;
/** \brief Returns the topology object at logical index \p idx with type \p type
*
@ -783,7 +865,7 @@ hwloc_get_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type, unsigne
* If \p prev is \c NULL, return the first object at depth \p depth.
*/
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);
/** \brief Returns the next object of type \p type.
*
@ -810,14 +892,12 @@ hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
*
* hwloc_obj_type_snprintf() may return a more precise output for a specific
* object, but it requires the caller to provide the output buffer.
*
* \note This function replaces the now deprecated hwloc_obj_type_string().
*/
HWLOC_DECLSPEC const char * hwloc_type_name (hwloc_obj_type_t type) __hwloc_attribute_const;
HWLOC_DECLSPEC const char * hwloc_obj_type_string (hwloc_obj_type_t type) __hwloc_attribute_const;
/** \brief Stringify the type of a given topology object into a human-readable form.
*
* Contrary to hwloc_type_name(), this function includes object-specific
* Contrary to hwloc_obj_type_string(), this function includes object-specific
* attributes (such as the Group depth, the Bridge type, or OS device type)
* in the output, and it requires the caller to provide the output buffer.
*
@ -870,7 +950,7 @@ HWLOC_DECLSPEC int hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_
* \return 0 if a type was correctly identified, otherwise -1.
*
* \note This function is guaranteed to match any string returned by
* hwloc_type_name() or hwloc_obj_type_snprintf().
* hwloc_obj_type_string() or hwloc_obj_type_snprintf().
*
* \note This is an extended version of the now deprecated hwloc_obj_type_sscanf().
*/
@ -897,7 +977,7 @@ HWLOC_DECLSPEC int hwloc_type_sscanf(const char *string,
* multiple group levels etc.
*
* \note This function is guaranteed to match any string returned by
* hwloc_type_name() or hwloc_obj_type_snprintf().
* hwloc_obj_type_string() or hwloc_obj_type_snprintf().
*/
HWLOC_DECLSPEC int hwloc_type_sscanf_as_depth(const char *string,
hwloc_obj_type_t *typep,
@ -928,6 +1008,8 @@ hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name) __hwloc_attribute_
*
* The input strings are copied before being added in the object infos.
*
* \return \c 0 on success, \c -1 on error.
*
* \note This function may be used to enforce object colors in the lstopo
* graphical output by using "lstopoStyle" as a name and "Background=#rrggbb"
* as a value. See CUSTOM COLORS in the lstopo(1) manpage for details.
@ -935,7 +1017,7 @@ hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name) __hwloc_attribute_
* \note If \p value contains some non-printable characters, they will
* be dropped when exporting to XML, see hwloc_topology_export_xml() in hwloc/export.h.
*/
HWLOC_DECLSPEC void hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const char *value);
HWLOC_DECLSPEC int hwloc_obj_add_info(hwloc_obj_t obj, const char *name, const char *value);
/** @} */
@ -1236,20 +1318,19 @@ typedef enum {
* Depending on the operating system, this may correspond to
* ::HWLOC_MEMBIND_FIRSTTOUCH (Linux),
* or ::HWLOC_MEMBIND_BIND (AIX, HP-UX, Solaris, Windows).
* This policy is never returned by get membind functions when running
* on normal machines.
* It is only returned when binding hooks are empty because the topology
* was loaded from XML, or HWLOC_THISSYSTEM=0, etc.
* This policy is never returned by get membind functions.
* The nodeset argument is ignored.
* \hideinitializer */
HWLOC_MEMBIND_DEFAULT = 0,
/** \brief Allocate memory
* but do not immediately bind it to a specific locality. Instead,
* each page in the allocation is bound only when it is first
* touched. Pages are individually bound to the local NUMA node of
* the first thread that touches it. If there is not enough memory
* on the node, allocation may be done in the specified nodes
* before allocating on other nodes.
/** \brief Allocate each memory page individually on the local NUMA
* node of the thread that touches it.
*
* The given nodeset should usually be hwloc_topology_get_topology_nodeset()
* so that the touching thread may run and allocate on any node in the system.
*
* On AIX, if the nodeset is smaller, pages are allocated locally (if the local
* node is in the nodeset) or from a random non-local node (otherwise).
* \hideinitializer */
HWLOC_MEMBIND_FIRSTTOUCH = 1,
@ -1276,6 +1357,8 @@ typedef enum {
/** \brief Returned by get_membind() functions when multiple
* threads or parts of a memory area have differing memory binding
* policies.
* Also returned when binding is unknown because binding hooks are empty
* when the topology is loaded from XML without HWLOC_THISSYSTEM=1, etc.
* \hideinitializer */
HWLOC_MEMBIND_MIXED = -1
} hwloc_membind_policy_t;
@ -1339,6 +1422,7 @@ typedef enum {
*
* Memory binding by CPU set cannot work for CPU-less NUMA memory nodes.
* Binding by nodeset should therefore be preferred whenever possible.
* \hideinitializer
*/
HWLOC_MEMBIND_BYNODESET = (1<<5)
} hwloc_membind_flags_t;
@ -1516,12 +1600,10 @@ HWLOC_DECLSPEC int hwloc_get_area_membind(hwloc_topology_t topology, const void
* so this function may return something that is already
* outdated.
*
* If ::HWLOC_MEMBIND_BYNODESET is specified, set is considered a nodeset.
* Otherwise it's a cpuset.
* If ::HWLOC_MEMBIND_BYNODESET is specified in \p flags, set is
* considered a nodeset. Otherwise it's a cpuset.
*
* If \p len is 0, \p set is emptied.
*
* Flags are currently unused.
*/
HWLOC_DECLSPEC int hwloc_get_area_memlocation(hwloc_topology_t topology, const void *addr, size_t len, hwloc_bitmap_t set, int flags);
@ -1715,13 +1797,16 @@ enum hwloc_topology_flags_e {
* Gather all resources, even if some were disabled by the administrator.
* For instance, ignore Linux Cgroup/Cpusets and gather all processors and memory nodes.
*
* When this flag is not set, PUs that are disallowed are not added to the topology.
* When this flag is not set, PUs and NUMA nodes that are disallowed are not added to the topology.
* Parent objects (package, core, cache, etc.) are added only if some of their children are allowed.
* NUMA nodes are always added but their available memory is set to 0 when disallowed.
*
* When this flag is set, each object has allowed_cpuset <= cpuset <= complete_cpuset.
* Otherwise allowed_cpuset = cpuset <= complete_cpuset.
* The same applies to nodesets.
* When this flag is set, the actual sets of allowed PUs and NUMA nodes are given
* by hwloc_topology_get_allowed_cpuset() and hwloc_topology_get_allowed_nodeset().
* They may be smaller than the root object cpuset and nodeset.
*
* When this flag is not set, all existing PUs and NUMA nodes in the topology
* are allowed. hwloc_topology_get_allowed_cpuset() and hwloc_topology_get_allowed_nodeset()
* are equal to the root object cpuset and nodeset.
*
* If the current topology is exported to XML and reimported later, this flag
* should be set again in the reimported topology so that disallowed resources
@ -1804,6 +1889,10 @@ HWLOC_DECLSPEC int hwloc_topology_is_thissystem(hwloc_topology_t __hwloc_restri
struct hwloc_topology_discovery_support {
/** \brief Detecting the number of PU objects is supported. */
unsigned char pu;
/** \brief Detecting the number of NUMA nodes is supported. */
unsigned char numa;
/** \brief Detecting the amount of memory in NUMA nodes is supported. */
unsigned char numa_memory;
};
/** \brief Flags describing actual PU binding support for this topology.
@ -1916,8 +2005,8 @@ enum hwloc_type_filter_e {
/** \brief Ignore all objects of this type.
*
* The bottom-level type ::HWLOC_OBJ_PU and the ::HWLOC_OBJ_NUMANODE type may not be ignored.
* The top-level object of the hierarchy will never actually be removed even if its type is ignored.
* The bottom-level type ::HWLOC_OBJ_PU, the ::HWLOC_OBJ_NUMANODE type, and
* the top-level type ::HWLOC_OBJ_MACHINE may not be ignored.
* \hideinitializer
*/
HWLOC_TYPE_FILTER_KEEP_NONE = 1,
@ -1942,9 +2031,10 @@ enum hwloc_type_filter_e {
* For ::HWLOC_OBJ_PCI_DEVICE and ::HWLOC_OBJ_OS_DEVICE, it means that only objects
* of major/common kinds are kept (storage, network, OpenFabrics, Intel MICs, CUDA,
* OpenCL, NVML, and displays).
* Also, only OS devices directly attached on PCI (e.g. no USB) are reported.
* For ::HWLOC_OBJ_BRIDGE, it means that bridges are kept only if they have children.
*
* This flag equivalent to ::HWLOC_TYPE_FILTER_KEEP_ALL for normal and Misc types
* This flag equivalent to ::HWLOC_TYPE_FILTER_KEEP_ALL for Normal, Memory and Misc types
* since they are likely important.
* \hideinitializer
*/
@ -1967,37 +2057,15 @@ HWLOC_DECLSPEC int hwloc_topology_set_all_types_filter(hwloc_topology_t topology
/** \brief Set the filtering for all cache object types.
*/
static __hwloc_inline int
hwloc_topology_set_cache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter)
{
unsigned i;
for(i=HWLOC_OBJ_L1CACHE; i<HWLOC_OBJ_L3ICACHE; i++)
hwloc_topology_set_type_filter(topology, (hwloc_obj_type_t) i, filter);
return 0;
}
HWLOC_DECLSPEC int hwloc_topology_set_cache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the filtering for all instruction cache object types.
*/
static __hwloc_inline int
hwloc_topology_set_icache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter)
{
unsigned i;
for(i=HWLOC_OBJ_L1ICACHE; i<HWLOC_OBJ_L3ICACHE; i++)
hwloc_topology_set_type_filter(topology, (hwloc_obj_type_t) i, filter);
return 0;
}
HWLOC_DECLSPEC int hwloc_topology_set_icache_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the filtering for I/O and Misc object types.
/** \brief Set the filtering for all I/O object types.
*/
static __hwloc_inline int
hwloc_topology_set_io_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter)
{
hwloc_topology_set_type_filter(topology, HWLOC_OBJ_MISC, filter);
hwloc_topology_set_type_filter(topology, HWLOC_OBJ_BRIDGE, filter);
hwloc_topology_set_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, filter);
hwloc_topology_set_type_filter(topology, HWLOC_OBJ_OS_DEVICE, filter);
return 0;
}
HWLOC_DECLSPEC int hwloc_topology_set_io_types_filter(hwloc_topology_t topology, enum hwloc_type_filter_e filter);
/** \brief Set the topology-specific userdata pointer.
*

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

@ -1,6 +1,6 @@
/* -*- c -*-
* Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -67,6 +67,13 @@
#define GCC_ABOVE_3_3 0
#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 */
#ifdef HWLOC_HAVE_ATTRIBUTE_UNUSED
#define __HWLOC_HAVE_ATTRIBUTE_UNUSED HWLOC_HAVE_ATTRIBUTE_UNUSED
@ -146,6 +153,19 @@
# define __hwloc_attribute_may_alias
#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
# if HWLOC_C_HAVE_VISIBILITY
# define HWLOC_DECLSPEC __attribute__((__visibility__("default")))

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved.
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
* 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 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
* doc/examples/ directory in the source tree.
* 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;
/** \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);
/** \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);
@ -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);
/** \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);
@ -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);
/** \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);
@ -165,16 +175,16 @@ HWLOC_DECLSPEC void hwloc_bitmap_zero(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 */
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 */
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 */
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 */
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 */
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.
*
* 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 */
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 */
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.
*
* 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
*
@ -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
* 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;
/** \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
*
* The loop must start with hwloc_bitmap_foreach_begin() and end
@ -304,31 +334,31 @@ do { \
*
* \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
*
* \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
*
* \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
*
* \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
*
* \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 © 2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -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.
*
* 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
* hwloc_cuda_get_device_cpuset().
*

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved.
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -21,6 +21,8 @@
extern "C" {
#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 */
#define HWLOC_OBJ_SOCKET HWLOC_OBJ_PACKAGE
/* 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;
}
/** \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.
*
* 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;
if (hwloc_obj_type_is_cache(*typep)) {
if (depthattrp)
*depthattrp = attr.cache.depth;
*depthattrp = (int) attr.cache.depth;
if (typeattrp && typeattrsize >= sizeof(hwloc_obj_cache_type_t))
memcpy(typeattrp, &attr.cache.type, sizeof(hwloc_obj_cache_type_t));
} else if (*typep == HWLOC_OBJ_GROUP) {
if (depthattrp)
*depthattrp = attr.group.depth;
*depthattrp = (int) attr.group.depth;
}
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.
*/
@ -136,7 +136,7 @@ typedef union hwloc_topology_diff_u {
hwloc_topology_diff_type_t type; /* must be ::HWLOC_TOPOLOGY_DIFF_OBJ_ATTR */
union hwloc_topology_diff_u * next;
/* List of attribute differences for a single object */
unsigned obj_depth;
int obj_depth;
unsigned obj_index;
union hwloc_topology_diff_obj_attr_u diff;
} 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 */
union hwloc_topology_diff_u * next;
/* Where we had to stop computing the diff in the first topology */
unsigned obj_depth;
int obj_depth;
unsigned obj_index;
} too_complex;
} * hwloc_topology_diff_t;

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

@ -122,7 +122,7 @@ hwloc_distances_get(hwloc_topology_t topology,
* Identical to hwloc_distances_get() with the additional \p depth filter.
*/
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 long kind, unsigned long flags);
@ -136,7 +136,7 @@ hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
unsigned long kind, unsigned long flags)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth < 0) {
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE) {
*nr = 0;
return 0;
}
@ -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.
*/
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.
*
@ -254,7 +254,7 @@ static __hwloc_inline int
hwloc_distances_remove_by_type(hwloc_topology_t topology, hwloc_obj_type_t 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 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-2011 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -34,6 +34,7 @@ extern "C" {
*/
enum hwloc_topology_export_xml_flags_e {
/** \brief Export XML that is loadable by hwloc v1.x.
* However, the export may miss some details about the topology.
* \hideinitializer
*/
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().
*
* 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.
*
* \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().
*
* 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.
*
* \return -1 if a failure occured.
@ -198,7 +217,27 @@ enum hwloc_topology_export_synthetic_flags_e {
* This is required if loading the synthetic description with hwloc < 1.10.
* \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.

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

@ -132,3 +132,4 @@ hwloc_gl_get_display_by_osdev(hwloc_topology_t topology __hwloc_attribute_unused
#endif /* HWLOC_GL_H */

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* See COPYING in top-level directory.
@ -83,7 +83,7 @@ HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topolo
*/
static __hwloc_inline hwloc_obj_t
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);
if (!next)
@ -125,10 +125,10 @@ hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const
*/
static __hwloc_inline hwloc_obj_t
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
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);
unsigned count = 0;
@ -180,10 +180,10 @@ hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpus
*/
static __hwloc_inline unsigned
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
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);
unsigned count = 0;
@ -221,7 +221,7 @@ hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_c
return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
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.
@ -319,7 +319,7 @@ hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t s
*/
static __hwloc_inline hwloc_obj_t
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);
if (!next)
@ -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. */
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
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;
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.
*
* 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.
*
* 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;
if (prev) {
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)
state = 2;
else if (prev->type == HWLOC_OBJ_NUMANODE)
state = 1;
obj = prev->next_sibling;
} else {
obj = parent->first_child;
}
if (!obj && state == 0) {
obj = parent->io_first_child;
obj = parent->memory_first_child;
state = 1;
}
if (!obj && state == 1) {
obj = parent->misc_first_child;
obj = parent->io_first_child;
state = 2;
}
if (!obj && state == 2) {
obj = parent->misc_first_child;
state = 3;
}
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
* @{
*/
/** \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.
*
* Return the depth of the topology level that contains cache objects
@ -758,7 +816,7 @@ hwloc_distrib(hwloc_topology_t topology,
hwloc_obj_t *roots, unsigned n_roots,
hwloc_cpuset_t *set,
unsigned n,
unsigned until, unsigned long flags)
int until, unsigned long flags)
{
unsigned i;
unsigned tot_weight;
@ -772,13 +830,16 @@ hwloc_distrib(hwloc_topology_t topology,
tot_weight = 0;
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++) {
unsigned chunk, weight;
hwloc_obj_t root = roots[flags & HWLOC_DISTRIB_FLAG_REVERSE ? n_roots-1-i : i];
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)
continue;
/* Give to root a chunk proportional to its weight.
@ -819,20 +880,18 @@ hwloc_distrib(hwloc_topology_t topology,
/** \defgroup hwlocality_helper_topology_sets CPU and node sets of entire topologies
* @{
*/
/** \brief Get complete CPU set
*
* \return the complete CPU set of logical processors of the system.
*
* \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.
*
* \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;
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
*
@ -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
* 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;
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
*
* \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
* 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;
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
*
@ -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
* 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;
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
*
@ -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
* 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;
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
*
* \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
* 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;
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,7 +990,7 @@ hwloc_topology_get_allowed_nodeset(hwloc_topology_t topology)
* If \p cpuset is empty, \p nodeset will be emptied as well.
* 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)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
@ -940,7 +998,9 @@ hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset,
assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
hwloc_bitmap_zero(nodeset);
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
@ -951,7 +1011,7 @@ hwloc_cpuset_to_nodeset(hwloc_topology_t topology, hwloc_const_cpuset_t _cpuset,
* Otherwise \p cpuset will be entirely filled.
* 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)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
@ -961,8 +1021,10 @@ hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwl
while ((obj = hwloc_get_next_obj_by_depth(topology, depth, obj)) != NULL) {
if (hwloc_bitmap_isset(nodeset, obj->os_index))
/* 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,8 +1038,13 @@ hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwl
/** \brief Get the first non-I/O ancestor object.
*
* 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
* its locality is the same as \p ioobj.
* object. This object (normal or memory) may then be used for binding
* 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
hwloc_get_non_io_ancestor_obj(hwloc_topology_t topology __hwloc_attribute_unused,

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2016 Inria. All rights reserved.
* Copyright © 2009-2018 Inria. All rights reserved.
* Copyright © 2009-2012 Université Bordeaux
* Copyright © 2009-2010 Cisco Systems, Inc. All rights reserved.
* 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)
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(); */
}
@ -67,7 +67,7 @@ hwloc_get_nbobjs_by_type (hwloc_topology_t topology, hwloc_obj_type_t type)
return 0;
if (depth == HWLOC_TYPE_DEPTH_MULTIPLE)
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
@ -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
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)
return hwloc_get_obj_by_depth (topology, depth, 0);
@ -111,9 +111,11 @@ static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
{
unsigned i;
for(i=0; i<obj->infos_count; i++)
if (!strcmp(obj->infos[i].name, name))
return obj->infos[i].value;
for(i=0; i<obj->infos_count; i++) {
struct hwloc_info_s *info = &obj->infos[i];
if (!strcmp(info->name, name))
return info->value;
}
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);
if (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);
if (p && policy != HWLOC_MEMBIND_FIRSTTOUCH)
/* Enforce the binding by touching the data */

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

@ -1,6 +1,6 @@
/*
* Copyright © 2009 CNRS
* Copyright © 2009-2014 Inria. All rights reserved.
* Copyright © 2009-2017 Inria. All rights reserved.
* Copyright © 2009-2010, 2012 Université Bordeaux
* See COPYING in top-level directory.
*/
@ -196,7 +196,7 @@ hwloc_cpuset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_cpu
if (!bitmask)
return 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);
return bitmask;
}
@ -221,7 +221,7 @@ hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_no
if (!bitmask)
return 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);
return bitmask;
}

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

@ -1,6 +1,6 @@
/*
* Copyright © 2012-2017 Inria. All rights reserved.
* Copyright © 2013 Université Bordeaux. All right reserved.
* Copyright © 2012-2018 Inria. All rights reserved.
* Copyright © 2013, 2018 Université Bordeaux. All right reserved.
* See COPYING in top-level directory.
*/
@ -21,8 +21,13 @@
#include <hwloc/linux.h>
#endif
#ifdef __APPLE__
#include <OpenCL/cl.h>
#include <OpenCL/cl_ext.h>
#else
#include <CL/cl.h>
#include <CL/cl_ext.h>
#endif
#include <stdio.h>
@ -130,10 +135,15 @@ hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
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
* OpenCL device \p device. Return NULL if there is none.
* Use OpenCL device attributes to find the corresponding hwloc OS device object.
* 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.
* I/O devices detection and the OpenCL component must be enabled in the topology.

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

@ -86,6 +86,11 @@ struct hwloc_disc_component {
*/
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
* (the component structure is usually read-only,
* the core copies it before using this field for queueing)
@ -140,7 +145,8 @@ struct hwloc_backend {
/** \brief Main discovery callback.
* returns -1 on error, either because it couldn't add its objects ot the existing topology,
* 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);
/** \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.
*
* 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.
*
@ -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);
/** \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);
/** \brief Allocate and initialize an object of the given type and physical 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.
*

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

@ -1,6 +1,6 @@
/*
* 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.
*/
@ -47,7 +47,6 @@ extern "C" {
#define hwloc_nodeset_t HWLOC_NAME(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_NUMANODE HWLOC_NAME_CAPS(OBJ_NUMANODE)
#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_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_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_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_group_attr_s HWLOC_NAME(group_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_destroy HWLOC_NAME(topology_destroy)
#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_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_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_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_OS_DEVICE HWLOC_NAME_CAPS(TYPE_DEPTH_OS_DEVICE)
#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_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_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_attr_snprintf HWLOC_NAME(obj_attr_snprintf )
#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_last HWLOC_NAME(bitmap_last)
#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_compare_first HWLOC_NAME(bitmap_compare_first)
#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_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_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_dcache HWLOC_NAME(obj_type_is_dcache)
#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_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_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)
/* 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_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 */
#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_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_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_weight_long HWLOC_NAME(weight_long)
#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_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_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_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 */
@ -597,6 +611,7 @@ extern "C" {
#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_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_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_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_get_sysctlbyname HWLOC_NAME(get_sysctlbyname)
#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_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_prepare HWLOC_NAME(pci_discovery_prepare)
#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_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__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__free_infos HWLOC_NAME(_free_infos)
@ -694,12 +710,8 @@ extern "C" {
#define hwloc_encode_to_base64 HWLOC_NAME(encode_to_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_bitmap_compare_inclusion HWLOC_NAME(bitmap_compare_inclusion)
#define hwloc__topology_disadopt HWLOC_NAME(_topology_disadopt)
#define hwloc__topology_dup HWLOC_NAME(_topology_dup)
@ -711,8 +723,8 @@ extern "C" {
/* private/solaris-chiptype.h */
#define hwloc_solaris_get_chip_type HWLOC_NAME(solaris_get_chip_type)
#define hwloc_solaris_get_chip_model HWLOC_NAME(solaris_get_chip_model)
#define hwloc_solaris_chip_info_s HWLOC_NAME(solaris_chip_info_s)
#define hwloc_solaris_get_chip_info HWLOC_NAME(solaris_get_chip_info)
#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.
*/
@ -29,7 +29,7 @@ extern "C" {
*
* Then it must find a virtual memory area of that size that is available
* 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.
*
* Once found, it must open a destination file for storing the buffer,
@ -110,10 +110,17 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
* that created the shared topology also placed userdata-pointed buffers
* 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
* 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
* 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,
int fd, hwloc_uint64_t fileoffset,

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