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_CONSTRUCT_JOBID(family,local) \
((family & 0x0000) | local)
#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) \
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,100 +706,68 @@ 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;
}
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 (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;
return NULL;
}
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
* counting physical objects, we can't just count the number
* that are in the hwloc tree as the only entries in the tree
* are LOGICAL objects - i.e., any physical gaps won't show. So
* we instead return the MAX os_index, as this is the best we
* can do to tell you how many PHYSICAL objects are in the system.
*
* NOTE: if the last PHYSICAL object is not present (e.g., the last
* socket on the node is empty), then the count we return will
* be wrong!
*/
hwloc_obj_t found = NULL;
obj = NULL;
if (num_objs)
*num_objs = 0;
while ((obj = hwloc_get_next_obj_by_depth(topo, search_depth, obj)) != NULL) {
if (num_objs && obj->os_index > *num_objs)
*num_objs = obj->os_index;
if (obj->os_index == nobj)
found = obj;
}
if (OPAL_HWLOC_PHYSICAL == rtype) {
/* the PHYSICAL object number is stored as the os_index. When
* counting physical objects, we can't just count the number
* that are in the hwloc tree as the only entries in the tree
* are LOGICAL objects - i.e., any physical gaps won't show. So
* we instead return the MAX os_index, as this is the best we
* can do to tell you how many PHYSICAL objects are in the system.
*
* NOTE: if the last PHYSICAL object is not present (e.g., the last
* socket on the node is empty), then the count we return will
* be wrong!
*/
if (NULL != num_objs) {
/* we are counting the number of these objects */
if (*num_objs < (unsigned int)start->os_index) {
*num_objs = (unsigned int)start->os_index;
}
} else if (*idx == nobj) {
/* found the specific instance of the cache level being sought */
return start;
}
*idx += 1;
return NULL;
return found;
}
if (OPAL_HWLOC_AVAILABLE == rtype) {
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++;
}
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) {
return obj;
}
}
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()
and hwloc_topology_set_all_types_filter().
- 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()
with HWLOC_TYPE_FILTER_KEEP_ALL.
+ 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.
+ 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
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()
with HWLOC_TYPE_FILTER_KEEP_ALL.
- 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.
+ HWLOC_MEMBIND_DEFAULT and HWLOC_MEMBIND_FIRSTTOUCH were clarified.
* New APIs and Features
+ Add hwloc/shmem.h for sharing topologies between processes running on
the same machine (for reducing the memory footprint).
+ Add the experimental netloc subproject. It is disabled by default
and can be enabled with --enable-netloc.
It currently brings command-line tools to gather and visualize the
topology of InfiniBand fabrics, and an API to convert such topologies
into Scotch architectures for process mapping.
See the documentation for details.
* Removed APIs and features
+ Remove the online_cpuset from struct hwloc_obj. Offline PUs get unknown
topologies on Linux nowadays, and wrong topology on Solaris. Other OS
do not support them. And one cannot do much about them anyway. Just keep
them in complete_cpuset.
+ Remove the now-unused "System" object type HWLOC_OBJ_SYSTEM,
defined to MACHINE for backward compatibility.
+ The almost-unused "os_level" attribute has been removed from the
hwloc_obj structure.
+ Remove the custom interface for assembling the topologies of different
nodes as well as the hwloc-assembler tools.
+ hwloc_topology_set_fsroot() is removed, the environment variable
HWLOC_FSROOT may be used for the same remote testing/debugging purpose.
+ Remove the deprecated hwloc_obj_snprintf(), hwloc_obj_type_of_string(),
hwloc_distribute[v]().
* Remove Myrinet Express interoperability (hwloc/myriexpress.h).
+ Remove Kerrighed support from the Linux backend.
+ Remove Tru64 (OSF/1) support.
- Remove HWLOC_MEMBIND_REPLICATE which wasn't available anywhere else.
* Backend improvements
+ Linux
- OS devices do not have to be attached through PCI anymore,
for instance enabling the discovery of NVDIMM block devices.
- Remove the dependency on libnuma.
- Add a SectorSize attribute to block OS devices.
+ Mac OS X
- Fix detection of cores and hyperthreads.
- Add CPUVendor, Model, ... attributes.
+ Windows
- Add get_area_memlocation().
* Tools
- 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().
+ 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
+ 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
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,
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
with a single HWLOC_PCI_LOCALITY where bus ranges may be specified.
+ 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
anymore, they should be passed in HWLOC_XMLFILE or HWLOC_SYNTHETIC instead.
+ HWLOC_COMPONENTS takes precedence over other environment variables
for selecting components.
+ Remove the dependency on libnuma on Linux.
+ 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 `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 HWLOC_PCI_<domain>_<bus>_LOCALCPUS environment variables are superseded
with a single HWLOC_PCI_LOCALITY where bus ranges may be specified.
- 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
anymore, they should be passed in HWLOC_XMLFILE or HWLOC_SYNTHETIC instead.
- HWLOC_COMPONENTS takes precedence over other environment variables
for selecting components.
+ 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"
@ -433,12 +442,12 @@ EOF])
[HWLOC_LIBS="-lpicl $HWLOC_LIBS"])])
AC_CHECK_DECLS([_SC_NPROCESSORS_ONLN,
_SC_NPROCESSORS_CONF,
_SC_NPROC_ONLN,
_SC_NPROC_CONF,
_SC_PAGESIZE,
_SC_PAGE_SIZE,
_SC_LARGE_PAGESIZE],,[:],[[#include <unistd.h>]])
_SC_NPROCESSORS_CONF,
_SC_NPROC_ONLN,
_SC_NPROC_CONF,
_SC_PAGESIZE,
_SC_PAGE_SIZE,
_SC_LARGE_PAGESIZE],,[:],[[#include <unistd.h>]])
AC_HAVE_HEADERS([mach/mach_host.h])
AC_HAVE_HEADERS([mach/mach_init.h], [
@ -471,27 +480,39 @@ EOF])
AC_CHECK_DECLS([_putenv], [], [], [AC_INCLUDES_DEFAULT])
# Could add mkdir and access for hwloc-gather-cpuid.c on Windows
# Do a full link test instead of just using AC_CHECK_FUNCS, which
# just checks to see if the symbol exists or not. For example,
# the prototype of sysctl uses u_int, which on some platforms
# (such as FreeBSD) is only defined under __BSD_VISIBLE, __USE_BSD
# 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_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_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]))
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
# (such as FreeBSD) is only defined under __BSD_VISIBLE, __USE_BSD
# 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_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
AC_MSG_CHECKING([for sysctlbyname])
AC_TRY_LINK([
#include <stdio.h>
#include <sys/types.h>
#include <sys/sysctl.h>
],
[return sysctlbyname(NULL,NULL,NULL,NULL,0);],
[AC_DEFINE([HAVE_SYSCTLBYNAME],[1],[Define to '1' if sysctlbyname is present and usable])
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
fi
AC_CHECK_DECLS([getprogname], [], [], [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([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"],[
@ -748,24 +776,38 @@ EOF])
# OpenCL support
hwloc_opencl_happy=no
if test "x$enable_io" != xno && test "x$enable_opencl" != "xno"; then
hwloc_opencl_happy=yes
hwloc_opencl_happy=yes
case ${target} in
*-*-darwin*)
# On Darwin, only use the OpenCL framework
AC_CHECK_HEADERS([OpenCL/cl_ext.h], [
AC_MSG_CHECKING([for the OpenCL framework])
tmp_save_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS -framework OpenCL"
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
#include <OpenCL/opencl.h>
]], [[
return clGetDeviceIDs(0, 0, 0, NULL, NULL);
]])],
[AC_MSG_RESULT(yes)
HWLOC_OPENCL_LDFLAGS="-framework OpenCL"],
[AC_MSG_RESULT(no)
hwloc_opencl_happy=no])
LDFLAGS="$tmp_save_LDFLAGS"
], [hwloc_opencl_happy=no])
;;
*)
# On Others, look for OpenCL at normal locations
AC_CHECK_HEADERS([CL/cl_ext.h], [
AC_CHECK_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"],
@ -1138,7 +1181,7 @@ EOF])
AC_CONFIG_FILES(
hwloc_config_prefix[Makefile]
hwloc_config_prefix[include/Makefile]
hwloc_config_prefix[hwloc/Makefile ]
hwloc_config_prefix[hwloc/Makefile]
)
# Cleanup
@ -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])
])

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

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

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

@ -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])
@ -185,8 +185,8 @@ EOF
AC_MSG_CHECKING([if will install doxygen docs])
AS_IF([test "x$hwloc_generate_doxs" = "xyes" -o \
-f "$srcdir/doc/doxygen-doc/man/man3/hwloc_distrib.3" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-a4.pdf" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-letter.pdf"],
-f "$srcdir/doc/doxygen-doc/hwloc-a4.pdf" -a \
-f "$srcdir/doc/doxygen-doc/hwloc-letter.pdf"],
[hwloc_install_doxs=yes],
[hwloc_install_doxs=no])
AC_MSG_RESULT([$hwloc_install_doxs])
@ -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]
@ -353,7 +356,7 @@ EOF
# linux-libnuma.h testing requires libnuma with numa_bitmask_alloc()
AC_CHECK_LIB([numa], [numa_available], [
AC_CHECK_DECL([numa_bitmask_alloc], [hwloc_have_linux_libnuma=yes], [],
[#include <numa.h>])
[#include <numa.h>])
])
AC_CHECK_HEADERS([stdlib.h], [
@ -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

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

@ -126,7 +126,7 @@
obj:*libatiadl*
}
#
#
{
libpciaccess_device_name_leak
Memcheck:Leak
@ -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;
}
@ -704,9 +683,9 @@ hwloc_alloc_membind(hwloc_topology_t topology, size_t len, hwloc_const_bitmap_t
hwloc_nodeset_t nodeset = hwloc_bitmap_alloc();
if (hwloc_fix_membind_cpuset(topology, nodeset, set)) {
if (flags & HWLOC_MEMBIND_STRICT)
ret = NULL;
ret = NULL;
else
ret = hwloc_alloc(topology, len);
ret = hwloc_alloc(topology, len);
} else
ret = hwloc_alloc_membind_by_nodeset(topology, len, nodeset, policy, flags);
hwloc_bitmap_free(nodeset);
@ -729,12 +708,8 @@ hwloc_free(hwloc_topology_t topology, void *addr, size_t len)
static int dontset_return_complete_cpuset(hwloc_topology_t topology, hwloc_cpuset_t set)
{
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;
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
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;
return 0;
} else
return -1;
hwloc_bitmap_copy(set, hwloc_topology_get_complete_nodeset(topology));
*policy = HWLOC_MEMBIND_MIXED;
return 0;
}
static int dontset_thisproc_membind(hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_bitmap_t set __hwloc_attribute_unused, hwloc_membind_policy_t policy __hwloc_attribute_unused, int flags __hwloc_attribute_unused)
@ -835,7 +806,7 @@ static int dontfree_membind(hwloc_topology_t topology __hwloc_attribute_unused,
}
static void hwloc_set_dummy_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_thisproc_cpubind = dontset_thisproc_cpubind;
hooks->get_thisproc_cpubind = dontget_thisproc_cpubind;

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

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

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

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

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

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

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

@ -1,5 +1,5 @@
/*
* Copyright © 2010-2017 Inria. All rights reserved.
* Copyright © 2010-2018 Inria. All rights reserved.
* Copyright © 2011-2012 Université Bordeaux
* Copyright © 2011 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;
@ -173,13 +176,13 @@ int hwloc_distances_remove_by_depth(hwloc_topology_t topology, unsigned depth)
next = dist->next;
if (dist->type == type) {
if (next)
next->prev = dist->prev;
next->prev = dist->prev;
else
topology->last_dist = dist->prev;
topology->last_dist = dist->prev;
if (dist->prev)
dist->prev->next = dist->next;
dist->prev->next = dist->next;
else
topology->first_dist = dist->next;
topology->first_dist = dist->next;
hwloc_internal_distances_free(dist);
}
}
@ -199,8 +202,8 @@ hwloc__groups_by_distances(struct hwloc_topology *topology, unsigned nbobjs, str
*/
static int
hwloc_internal_distances__add(hwloc_topology_t topology,
hwloc_obj_type_t type, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *indexes, uint64_t *values,
unsigned long kind)
hwloc_obj_type_t type, unsigned nbobjs, hwloc_obj_t *objs, uint64_t *indexes, uint64_t *values,
unsigned long kind)
{
struct hwloc_internal_distances_s *dist = calloc(1, sizeof(*dist));
if (!dist)
@ -230,15 +233,17 @@ hwloc_internal_distances__add(hwloc_topology_t topology,
goto err_with_dist;
if (dist->type == HWLOC_OBJ_PU || dist->type == HWLOC_OBJ_NUMANODE) {
for(i=0; i<nbobjs; i++)
dist->indexes[i] = objs[i]->os_index;
dist->indexes[i] = objs[i]->os_index;
} else {
for(i=0; i<nbobjs; i++)
dist->indexes[i] = objs[i]->gp_index;
dist->indexes[i] = objs[i]->gp_index;
}
}
dist->values = values;
dist->id = topology->next_dist_id++;
if (topology->last_dist)
topology->last_dist->next = dist;
else
@ -258,8 +263,8 @@ hwloc_internal_distances__add(hwloc_topology_t topology,
}
int hwloc_internal_distances_add_by_index(hwloc_topology_t topology,
hwloc_obj_type_t type, unsigned nbobjs, uint64_t *indexes, uint64_t *values,
unsigned long kind, unsigned long flags)
hwloc_obj_type_t type, unsigned nbobjs, uint64_t *indexes, uint64_t *values,
unsigned long kind, unsigned long flags)
{
if (nbobjs < 2) {
errno = EINVAL;
@ -283,8 +288,8 @@ int hwloc_internal_distances_add_by_index(hwloc_topology_t topology,
}
int hwloc_internal_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values,
unsigned long kind, unsigned long flags)
unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values,
unsigned long kind, unsigned long flags)
{
if (nbobjs < 2) {
errno = EINVAL;
@ -310,18 +315,18 @@ int hwloc_internal_distances_add(hwloc_topology_t topology,
fprintf(stderr, "Trying to group objects using distance matrix:\n");
fprintf(stderr, "%s", gp ? "gp_index" : "os_index");
for(j=0; j<nbobjs; j++)
fprintf(stderr, " % 5d", (int)(gp ? objs[j]->gp_index : objs[j]->os_index));
fprintf(stderr, " % 5d", (int)(gp ? objs[j]->gp_index : objs[j]->os_index));
fprintf(stderr, "\n");
for(i=0; i<nbobjs; i++) {
fprintf(stderr, " % 5d", (int)(gp ? objs[i]->gp_index : objs[i]->os_index));
for(j=0; j<nbobjs; j++)
fprintf(stderr, " % 5lld", (long long) values[i*nbobjs + j]);
fprintf(stderr, "\n");
fprintf(stderr, " % 5d", (int)(gp ? objs[i]->gp_index : objs[i]->os_index));
for(j=0; j<nbobjs; j++)
fprintf(stderr, " % 5lld", (long long) values[i*nbobjs + j]);
fprintf(stderr, "\n");
}
}
hwloc__groups_by_distances(topology, nbobjs, objs, values,
kind, nbaccuracies, accuracies, 1 /* check the first matrice */);
kind, nbaccuracies, accuracies, 1 /* check the first matrice */);
}
return hwloc_internal_distances__add(topology, objs[0]->type, nbobjs, objs, NULL, values, kind);
@ -340,8 +345,8 @@ int hwloc_internal_distances_add(hwloc_topology_t topology,
/* The actual function exported to the user
*/
int hwloc_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values,
unsigned long kind, unsigned long flags)
unsigned nbobjs, hwloc_obj_t *objs, uint64_t *values,
unsigned long kind, unsigned long flags)
{
hwloc_obj_type_t type;
unsigned i;
@ -417,8 +422,8 @@ static hwloc_obj_t hwloc_find_obj_by_type_and_gp_index(hwloc_topology_t topology
static void
hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist,
hwloc_obj_t *objs,
unsigned disappeared)
hwloc_obj_t *objs,
unsigned disappeared)
{
unsigned nbobjs = dist->nbobjs;
unsigned i, newi;
@ -427,10 +432,10 @@ hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist,
for(i=0, newi=0; i<nbobjs; i++)
if (objs[i]) {
for(j=0, newj=0; j<nbobjs; j++)
if (objs[j]) {
dist->values[newi*(nbobjs-disappeared)+newj] = dist->values[i*nbobjs+j];
newj++;
}
if (objs[j]) {
dist->values[newi*(nbobjs-disappeared)+newj] = dist->values[i*nbobjs+j];
newj++;
}
newi++;
}
@ -446,7 +451,7 @@ hwloc_internal_distances_restrict(struct hwloc_internal_distances_s *dist,
static int
hwloc_internal_distances_refresh_one(hwloc_topology_t topology,
struct hwloc_internal_distances_s *dist)
struct hwloc_internal_distances_s *dist)
{
hwloc_obj_type_t type = dist->type;
unsigned nbobjs = dist->nbobjs;
@ -497,13 +502,13 @@ hwloc_internal_distances_refresh(hwloc_topology_t topology)
if (hwloc_internal_distances_refresh_one(topology, dist) < 0) {
assert(!topology->tma || !topology->tma->dontfree); /* this tma cannot fail to allocate */
if (dist->prev)
dist->prev->next = next;
dist->prev->next = next;
else
topology->first_dist = next;
topology->first_dist = next;
if (next)
next->prev = dist->prev;
next->prev = dist->prev;
else
topology->last_dist = dist->prev;
topology->last_dist = dist->prev;
hwloc_internal_distances_free(dist);
continue;
}
@ -524,7 +529,7 @@ hwloc_internal_distances_invalidate_cached_objs(hwloc_topology_t topology)
void
hwloc_distances_release(hwloc_topology_t topology __hwloc_attribute_unused,
struct hwloc_distances_s *distances)
struct hwloc_distances_s *distances)
{
free(distances->values);
free(distances->objs);
@ -533,7 +538,7 @@ hwloc_distances_release(hwloc_topology_t topology __hwloc_attribute_unused,
static struct hwloc_distances_s *
hwloc_distances_get_one(hwloc_topology_t topology __hwloc_attribute_unused,
struct hwloc_internal_distances_s *dist)
struct hwloc_internal_distances_s *dist)
{
struct hwloc_distances_s *distances;
unsigned nbobjs;
@ -566,9 +571,9 @@ hwloc_distances_get_one(hwloc_topology_t topology __hwloc_attribute_unused,
static int
hwloc__distances_get(hwloc_topology_t topology,
hwloc_obj_type_t type,
unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags __hwloc_attribute_unused)
hwloc_obj_type_t type,
unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags __hwloc_attribute_unused)
{
struct hwloc_internal_distances_s *dist;
unsigned nr = 0, i;
@ -585,6 +590,11 @@ hwloc__distances_get(hwloc_topology_t topology,
/* we could refresh only the distances that match, but we won't have many distances anyway,
* 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);
@ -603,7 +613,7 @@ hwloc__distances_get(hwloc_topology_t topology,
if (nr < *nrp) {
struct hwloc_distances_s *distances = hwloc_distances_get_one(topology, dist);
if (!distances)
goto error;
goto error;
distancesp[nr] = distances;
}
nr++;
@ -622,8 +632,8 @@ hwloc__distances_get(hwloc_topology_t topology,
int
hwloc_distances_get(hwloc_topology_t topology,
unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags)
unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags)
{
if (flags || !topology->is_loaded) {
errno = EINVAL;
@ -634,9 +644,9 @@ hwloc_distances_get(hwloc_topology_t topology,
}
int
hwloc_distances_get_by_depth(hwloc_topology_t topology, unsigned depth,
unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags)
hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth,
unsigned *nrp, struct hwloc_distances_s **distancesp,
unsigned long kind, unsigned long flags)
{
hwloc_obj_type_t type;
@ -690,10 +700,10 @@ static int hwloc_compare_values(uint64_t a, uint64_t b, float accuracy)
*/
static unsigned
hwloc__find_groups_by_min_distance(unsigned nbobjs,
uint64_t *_values,
float accuracy,
unsigned *groupids,
int verbose)
uint64_t *_values,
float accuracy,
unsigned *groupids,
int verbose)
{
uint64_t min_distance = UINT64_MAX;
unsigned groupid = 1;
@ -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,25 +738,25 @@ 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[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)
newfirstfound = k;
if (i == j)
hwloc_debug(" object %u is minimally connected to %u\n", k, i);
else
hwloc_debug(" object %u is minimally connected to %u through %u\n", k, i, j);
}
groupids[k] = groupid;
size++;
if (newfirstfound == (unsigned)-1)
newfirstfound = k;
if (i == j)
hwloc_debug(" object %u is minimally connected to %u\n", k, i);
else
hwloc_debug(" object %u is minimally connected to %u through %u\n", k, i, j);
}
firstfound = newfirstfound;
}
@ -761,7 +771,7 @@ hwloc__find_groups_by_min_distance(unsigned nbobjs,
groupid++;
if (verbose)
fprintf(stderr, " Found transitive graph with %u objects with minimal distance %llu accuracy %f\n",
size, (unsigned long long) min_distance, accuracy);
size, (unsigned long long) min_distance, accuracy);
}
if (groupid == 2 && !skipped)
@ -781,17 +791,17 @@ hwloc__check_grouping_matrix(unsigned nbobjs, uint64_t *_values, float accuracy,
for(j=i+1; j<nbobjs; j++) {
/* should be symmetric */
if (hwloc_compare_values(VALUE(i, j), VALUE(j, i), accuracy)) {
if (verbose)
fprintf(stderr, " Distance matrix asymmetric ([%u,%u]=%llu != [%u,%u]=%llu), aborting\n",
i, j, (unsigned long long) VALUE(i, j), j, i, (unsigned long long) VALUE(j, i));
return -1;
if (verbose)
fprintf(stderr, " Distance matrix asymmetric ([%u,%u]=%llu != [%u,%u]=%llu), aborting\n",
i, j, (unsigned long long) VALUE(i, j), j, i, (unsigned long long) VALUE(j, i));
return -1;
}
/* diagonal is smaller than everything else */
if (hwloc_compare_values(VALUE(i, j), VALUE(i, i), accuracy) <= 0) {
if (verbose)
fprintf(stderr, " Distance to self not strictly minimal ([%u,%u]=%llu <= [%u,%u]=%llu), aborting\n",
i, j, (unsigned long long) VALUE(i, j), i, i, (unsigned long long) VALUE(i, i));
return -1;
if (verbose)
fprintf(stderr, " Distance to self not strictly minimal ([%u,%u]=%llu <= [%u,%u]=%llu), aborting\n",
i, j, (unsigned long long) VALUE(i, j), i, i, (unsigned long long) VALUE(i, i));
return -1;
}
}
}
@ -803,15 +813,15 @@ hwloc__check_grouping_matrix(unsigned nbobjs, uint64_t *_values, float accuracy,
*/
static void
hwloc__groups_by_distances(struct hwloc_topology *topology,
unsigned nbobjs,
struct hwloc_obj **objs,
uint64_t *_values,
unsigned long kind,
unsigned nbaccuracies,
float *accuracies,
int needcheck)
unsigned nbobjs,
struct hwloc_obj **objs,
uint64_t *_values,
unsigned long kind,
unsigned nbaccuracies,
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,53 +845,44 @@ 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;
for (j=0; j<nbobjs; j++)
if (groupids[j] == i+1) {
/* assemble the group sets */
hwloc_obj_add_other_obj_sets(group_obj, objs[j]);
if (groupids[j] == i+1) {
/* assemble the group sets */
hwloc_obj_add_other_obj_sets(group_obj, objs[j]);
groupsizes[i]++;
}
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,
(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)
failed++;
/* or it may be different from groupobjs if we got groups from XML import before grouping */
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)
failed++;
/* or it may be different from groupobjs if we got groups from XML import before grouping */
groupobjs[i] = res_obj;
}
topology->grouping_next_subkind++;
if (failed)
/* don't try to group above if we got a NULL group here, just keep this incomplete level */
goto inner_free;
/* don't try to group above if we got a NULL group here, just keep this incomplete level */
return;
/* factorize values */
memset(&(groupvalues[0]), 0, sizeof(groupvalues[0]) * nbgroups * nbgroups);
@ -894,9 +890,9 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
#define VALUE(i, j) _values[(i) * nbobjs + (j)]
#define GROUP_VALUE(i, j) groupvalues[(i) * nbgroups + (j)]
for(i=0; i<nbobjs; i++)
if (groupids[i])
for(j=0; j<nbobjs; j++)
if (groupids[j])
if (groupids[i])
for(j=0; j<nbobjs; j++)
if (groupids[j])
GROUP_VALUE(groupids[i]-1, groupids[j]-1) += VALUE(i, j);
for(i=0; i<nbgroups; i++)
for(j=0; j<nbgroups; j++) {
@ -907,25 +903,16 @@ hwloc__groups_by_distances(struct hwloc_topology *topology,
hwloc_debug("%s", "generated new distance matrix between groups:\n");
hwloc_debug("%s", " index");
for(j=0; j<nbgroups; j++)
hwloc_debug(" % 5d", (int) j); /* print index because os_index is -1 for Groups */
hwloc_debug(" % 5d", (int) j); /* print index because os_index is -1 for Groups */
hwloc_debug("%s", "\n");
for(i=0; i<nbgroups; i++) {
hwloc_debug(" % 5d", (int) i);
for(j=0; j<nbgroups; j++)
hwloc_debug(" %llu", (unsigned long long) GROUP_VALUE(i, j));
hwloc_debug("%s", "\n");
hwloc_debug(" % 5d", (int) i);
for(j=0; j<nbgroups; j++)
hwloc_debug(" %llu", (unsigned long long) GROUP_VALUE(i, j));
hwloc_debug("%s", "\n");
}
#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 "" >

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

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

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

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

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

@ -27,7 +27,7 @@ struct hwloc_shmem_header {
static void *
tma_shmem_malloc(struct hwloc_tma * tma,
size_t length)
size_t length)
{
void *current = tma->data;
tma->data = (char*)tma->data + ((length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1));
@ -37,7 +37,7 @@ tma_shmem_malloc(struct hwloc_tma * tma,
static void *
tma_get_length_malloc(struct hwloc_tma * tma,
size_t length)
size_t length)
{
size_t *tma_length = tma->data;
*tma_length += (length + HWLOC_SHMEM_MALLOC_ALIGN - 1) & ~(HWLOC_SHMEM_MALLOC_ALIGN - 1);
@ -47,8 +47,8 @@ tma_get_length_malloc(struct hwloc_tma * tma,
int
hwloc_shmem_topology_get_length(hwloc_topology_t topology,
size_t *lengthp,
unsigned long flags)
size_t *lengthp,
unsigned long flags)
{
hwloc_topology_t new;
struct hwloc_tma tma;
@ -76,9 +76,9 @@ hwloc_shmem_topology_get_length(hwloc_topology_t topology,
int
hwloc_shmem_topology_write(hwloc_topology_t topology,
int fd, uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags)
int fd, uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags)
{
hwloc_topology_t new;
struct hwloc_tma tma;
@ -144,9 +144,9 @@ hwloc_shmem_topology_write(hwloc_topology_t topology,
int
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp,
int fd, uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags)
int fd, uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags)
{
hwloc_topology_t new, old;
struct hwloc_shmem_header header;
@ -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;
}
@ -240,8 +250,8 @@ hwloc__topology_disadopt(hwloc_topology_t topology)
int
hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unused,
size_t *lengthp __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
size_t *lengthp __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
{
errno = ENOSYS;
return -1;
@ -249,9 +259,9 @@ hwloc_shmem_topology_get_length(hwloc_topology_t topology __hwloc_attribute_unus
int
hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused,
int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
{
errno = ENOSYS;
return -1;
@ -259,9 +269,9 @@ hwloc_shmem_topology_write(hwloc_topology_t topology __hwloc_attribute_unused,
int
hwloc_shmem_topology_adopt(hwloc_topology_t *topologyp __hwloc_attribute_unused,
int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
int fd __hwloc_attribute_unused, uint64_t fileoffset __hwloc_attribute_unused,
void *mmap_address __hwloc_attribute_unused, size_t length __hwloc_attribute_unused,
unsigned long flags __hwloc_attribute_unused)
{
errno = ENOSYS;
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.
@ -173,9 +173,9 @@ hwloc_aix_get_tid_getthrds_cpubind(hwloc_topology_t topology __hwloc_attribute_u
#endif
if (thread_info.ti_tid == tid) {
if (PROCESSOR_CLASS_ANY != thread_info.ti_cpuid)
hwloc_bitmap_set(hwloc_set, thread_info.ti_cpuid);
hwloc_bitmap_set(hwloc_set, thread_info.ti_cpuid);
else
hwloc_bitmap_fill(hwloc_set);
hwloc_bitmap_fill(hwloc_set);
break;
}
}
@ -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));
@ -620,7 +636,7 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
cpuset = hwloc_bitmap_alloc();
for (j = 0; j < maxcpus; j++) {
if (rs_op(RS_TESTRESOURCE, rad, NULL, R_PROCS, j))
hwloc_bitmap_set(cpuset, j);
hwloc_bitmap_set(cpuset, j);
}
if (type == HWLOC_OBJ_PU) {
@ -639,76 +655,76 @@ look_rset(int sdl, hwloc_obj_type_t type, struct hwloc_topology *topology, int l
switch(type) {
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->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, i);
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 */
break;
/* 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;
obj->attr->cache.associativity = _system_configuration.L2_cache_asc;
obj->attr->cache.size = _system_configuration.L2_cache_size;
obj->attr->cache.associativity = _system_configuration.L2_cache_asc;
obj->attr->cache.linesize = 0; /* unknown by default */
if (__power_pc())
if (__power_4() || __power_5() || __power_6() || __power_7())
obj->attr->cache.linesize = 128;
obj->attr->cache.linesize = 0; /* unknown by default */
if (__power_pc())
if (__power_4() || __power_5() || __power_6() || __power_7())
obj->attr->cache.linesize = 128;
obj->attr->cache.depth = 2;
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; /* OK for power[4567], unknown for others */
break;
obj->attr->cache.depth = 2;
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED; /* OK for power[4567], unknown for others */
break;
case HWLOC_OBJ_GROUP:
obj->attr->group.kind = HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN;
obj->attr->group.subkind = level;
break;
obj->attr->group.kind = HWLOC_GROUP_KIND_AIX_SDL_UNKNOWN;
obj->attr->group.subkind = level;
break;
case HWLOC_OBJ_CORE:
{
hwloc_obj_t obj2, obj3;
obj2 = hwloc_alloc_setup_object(topology, HWLOC_OBJ_L1CACHE, -1);
obj2->cpuset = hwloc_bitmap_dup(obj->cpuset);
obj2->attr->cache.size = _system_configuration.dcache_size;
obj2->attr->cache.associativity = _system_configuration.dcache_asc;
obj2->attr->cache.linesize = _system_configuration.dcache_line;
obj2->attr->cache.depth = 1;
if (_system_configuration.cache_attrib & (1<<30)) {
/* Unified cache */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
hwloc_debug("Adding an L1u cache for core %d\n", i);
} else {
/* Separate Instruction and Data caches */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
hwloc_debug("Adding an L1d cache for core %d\n", i);
hwloc_obj_t obj2, obj3;
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;
obj2->attr->cache.linesize = _system_configuration.dcache_line;
obj2->attr->cache.depth = 1;
if (_system_configuration.cache_attrib & (1<<30)) {
/* Unified cache */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
hwloc_debug("Adding an L1u cache for core %d\n", i);
} else {
/* Separate Instruction and Data caches */
obj2->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
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->cpuset = hwloc_bitmap_dup(obj->cpuset);
obj3->attr->cache.size = _system_configuration.icache_size;
obj3->attr->cache.associativity = _system_configuration.icache_asc;
obj3->attr->cache.linesize = _system_configuration.icache_line;
obj3->attr->cache.depth = 1;
obj3->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
hwloc_debug("Adding an L1i cache for core %d\n", i);
hwloc_insert_object_by_cpuset(topology, obj3);
}
}
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE))
hwloc_insert_object_by_cpuset(topology, obj2);
else
hwloc_free_unlinked_object(obj2); /* FIXME: don't built at all, just build the cpuset in case l1/l1i needs it */
break;
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
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;
obj3->attr->cache.linesize = _system_configuration.icache_line;
obj3->attr->cache.depth = 1;
obj3->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
hwloc_debug("Adding an L1i cache for core %d\n", i);
hwloc_insert_object_by_cpuset(topology, obj3);
}
}
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1CACHE))
hwloc_insert_object_by_cpuset(topology, obj2);
else
hwloc_free_unlinked_object(obj2); /* FIXME: don't built at all, just build the cpuset in case l1/l1i needs it */
break;
}
default:
break;
break;
}
hwloc_debug_2args_bitmap("%s %d has cpuset %s\n",
hwloc_type_name(type),
i, obj->cpuset);
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);
else
@ -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 */
@ -743,52 +759,53 @@ hwloc_look_aix(struct hwloc_backend *backend)
int known = 0;
#if 0
if (i == rs_getinfo(NULL, R_SMPSDL, 0))
/* Not enabled for now because I'm not sure what it corresponds to. On
* decrypthon it contains all the cpus. Is it a "machine" or a "system"
* level ?
*/
{
hwloc_debug("looking AIX \"SMP\" sdl %d\n", i);
look_rset(i, HWLOC_OBJ_MACHINE, topology, i);
known = 1;
}
/* Not enabled for now because I'm not sure what it corresponds to. On
* decrypthon it contains all the cpus. Is it a "machine" or a "system"
* level ?
*/
{
hwloc_debug("looking AIX \"SMP\" sdl %d\n", i);
look_rset(i, HWLOC_OBJ_MACHINE, topology, i);
known = 1;
}
#endif
if (i == rs_getinfo(NULL, R_MCMSDL, 0))
{
hwloc_debug("looking AIX node sdl %d\n", i);
look_rset(i, HWLOC_OBJ_NUMANODE, topology, i);
known = 1;
}
{
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))
{
hwloc_debug("looking AIX L2 sdl %d\n", i);
look_rset(i, HWLOC_OBJ_L2CACHE, topology, i);
known = 1;
}
{
hwloc_debug("looking AIX L2 sdl %d\n", i);
look_rset(i, HWLOC_OBJ_L2CACHE, topology, i);
known = 1;
}
# endif
# ifdef R_PCORESDL
if (i == rs_getinfo(NULL, R_PCORESDL, 0))
{
hwloc_debug("looking AIX core sdl %d\n", i);
look_rset(i, HWLOC_OBJ_CORE, topology, i);
known = 1;
}
{
hwloc_debug("looking AIX core sdl %d\n", i);
look_rset(i, HWLOC_OBJ_CORE, topology, i);
known = 1;
}
# endif
if (i == rs_getinfo(NULL, R_MAXSDL, 0))
{
hwloc_debug("looking AIX max sdl %d\n", i);
look_rset(i, HWLOC_OBJ_PU, topology, i);
known = 1;
{
hwloc_debug("looking AIX max sdl %d\n", i);
look_rset(i, HWLOC_OBJ_PU, topology, i);
known = 1;
topology->support.discovery->pu = 1;
}
}
/* Don't know how it should be rendered, make a misc object for it. */
if (!known)
{
hwloc_debug("looking AIX unknown sdl %d\n", i);
look_rset(i, HWLOC_OBJ_GROUP, topology, i);
}
{
hwloc_debug("looking AIX unknown sdl %d\n", i);
look_rset(i, HWLOC_OBJ_GROUP, topology, i);
}
}
hwloc_obj_add_info(topology->levels[0][0], "Backend", "AIX");
@ -798,7 +815,7 @@ hwloc_look_aix(struct hwloc_backend *backend)
void
hwloc_set_aix_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_aix_set_proc_cpubind;
hooks->get_proc_cpubind = hwloc_aix_get_proc_cpubind;
@ -845,9 +862,9 @@ hwloc_set_aix_hooks(struct hwloc_binding_hooks *hooks,
static struct hwloc_backend *
hwloc_aix_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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");
@ -34,9 +34,9 @@ hwloc_bgq__get_allowed_resources(struct hwloc_topology *topology)
/* process cannot use cores/threads outside of its Kernel_ThreadMask() unless BG_THREADMODEL=2 */
uint64_t bgmask = Kernel_ThreadMask(Kernel_MyTcoord());
/* 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);
for(i=0; i<64; i++)
if (((bgmask >> i) & 1) == 0)
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 */
@ -231,7 +234,7 @@ hwloc_bgq_get_allowed_resources(struct hwloc_topology *topology)
void
hwloc_set_bgq_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_thisthread_cpubind = hwloc_bgq_set_thisthread_cpubind;
hooks->set_thread_cpubind = hwloc_bgq_set_thread_cpubind;
@ -246,9 +249,9 @@ hwloc_set_bgq_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
static struct hwloc_backend *
hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct utsname utsname;
struct hwloc_backend *backend;
@ -261,11 +264,11 @@ hwloc_bgq_component_instantiate(struct hwloc_disc_component *component,
if (!env || !atoi(env)) {
fprintf(stderr, "*** Found unexpected uname sysname `%s' machine `%s'.\n", utsname.sysname, utsname.machine);
fprintf(stderr, "*** The BlueGene/Q backend (bgq) is only enabled by default on compute nodes\n"
"*** (where uname returns sysname=CNK and machine=BGQ).\n"
"*** If you know you *really* want to run the bgq backend on this non-compute node,\n"
"*** set HWLOC_FORCE_BGQ=1 in the environment.\n"
"*** If you just want to discover the native topology of this non-compute node,\n"
"*** do not pass any BlueGene/Q-specific options on the configure command-line.\n");
"*** (where uname returns sysname=CNK and machine=BGQ).\n"
"*** If you know you *really* want to run the bgq backend on this non-compute node,\n"
"*** set HWLOC_FORCE_BGQ=1 in the environment.\n"
"*** If you just want to discover the native topology of this non-compute node,\n"
"*** do not pass any BlueGene/Q-specific options on the configure command-line.\n");
return NULL;
} else {
forced_nonbgq = 1;
@ -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);
@ -111,7 +111,7 @@ hwloc_cuda_discover(struct hwloc_backend *backend)
if (hwloc_cudart_get_device_pci_ids(NULL /* topology unused */, i, &domain, &bus, &dev) == 0) {
parent = hwloc_pcidisc_find_by_busid(topology, domain, bus, dev, 0);
if (!parent)
parent = hwloc_pcidisc_find_busid_parent(topology, domain, bus, dev, 0);
parent = hwloc_pcidisc_find_busid_parent(topology, domain, bus, dev, 0);
}
if (!parent)
parent = hwloc_get_root_obj(topology);
@ -144,6 +144,7 @@ static struct hwloc_disc_component hwloc_cuda_disc_component = {
HWLOC_DISC_COMPONENT_TYPE_GLOBAL,
hwloc_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;
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. */
@ -73,7 +114,7 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_debug("%u threads per package\n", logical_per_package);
if (nprocs == npackages * logical_per_package
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_PACKAGE))
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_PACKAGE))
for (i = 0; i < npackages; i++) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PACKAGE, i);
obj->cpuset = hwloc_bitmap_alloc();
@ -83,17 +124,46 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_debug_1arg_bitmap("package %u has cpuset %s\n",
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
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_CORE)) {
unsigned cores_per_package = _cores_per_package;
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)) {
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");
@ -191,13 +262,14 @@ hwloc_look_darwin(struct hwloc_backend *backend)
for (i = 0; i < n; i++) {
/* cacheconfig tells us how many cpus share it, let's iterate on each cache */
for (j = 0; j < (nprocs / cacheconfig[i]); j++) {
if (!i) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_NUMANODE, j);
if (!i) {
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];
cpu < ((j+1)*cacheconfig[i]);
@ -205,10 +277,10 @@ hwloc_look_darwin(struct hwloc_backend *backend)
hwloc_bitmap_set(obj->cpuset, cpu);
if (i == 1 && l1icachesize
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
&& hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_L1ICACHE)) {
/* FIXME assuming that L1i and L1d are shared the same way. Darwin
* 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,29 +309,32 @@ 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
}
if (hwloc_filter_check_keep_object_type(topology, obj->type))
hwloc_insert_object_by_cpuset(topology, obj);
else
hwloc_free_unlinked_object(obj); /* FIXME: don't built at all, just build the cpuset in case l1i needs it */
if (hwloc_filter_check_keep_object_type(topology, obj->type))
hwloc_insert_object_by_cpuset(topology, obj);
else
hwloc_free_unlinked_object(obj); /* FIXME: don't built at all, just build the cpuset in case l1i needs it */
}
}
}
out:
free(cacheconfig);
free(cachesize);
free(cacheconfig32);
}
if (gotnuma)
topology->support.discovery->numa = 1;
if (gotnumamemory)
topology->support.discovery->numa = 1;
/* add PU objects */
hwloc_setup_pu_level(topology, nprocs);
@ -271,15 +346,15 @@ hwloc_look_darwin(struct hwloc_backend *backend)
void
hwloc_set_darwin_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
}
static struct hwloc_backend *
hwloc_darwin_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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.
*/
@ -11,9 +11,9 @@
static struct hwloc_backend *
hwloc_fake_component_instantiate(struct hwloc_disc_component *component __hwloc_attribute_unused,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
if (getenv("HWLOC_DEBUG_FAKE_COMPONENT"))
printf("fake component instantiated\n");
@ -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);
}
@ -201,7 +205,7 @@ hwloc_look_freebsd(struct hwloc_backend *backend)
void
hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unused,
struct hwloc_topology_support *support __hwloc_attribute_unused)
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
#if defined(HAVE_SYS_CPUSET_H) && defined(HAVE_CPUSET_SETAFFINITY)
hooks->set_thisproc_cpubind = hwloc_freebsd_set_thisproc_cpubind;
@ -224,9 +228,9 @@ hwloc_set_freebsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unus
static struct hwloc_backend *
hwloc_freebsd_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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,26 +111,25 @@ 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);
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);
parent = hwloc_get_root_obj(topology);
hwloc_insert_object_by_parent(topology, parent, osdev);
hwloc_debug("GL device %s (product %s) on PCI %04x:%02x:%02x.%01x\n",
name, productname,
(unsigned) nv_ctrl_pci_domain, (unsigned) nv_ctrl_pci_bus, (unsigned) nv_ctrl_pci_device, (unsigned) nv_ctrl_pci_func);
name, productname,
(unsigned) nv_ctrl_pci_domain, (unsigned) nv_ctrl_pci_bus, (unsigned) nv_ctrl_pci_device, (unsigned) nv_ctrl_pci_func);
}
XCloseDisplay(display);
}
@ -140,9 +139,9 @@ hwloc_gl_discover(struct hwloc_backend *backend)
static struct hwloc_backend *
hwloc_gl_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
@ -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.
@ -50,8 +50,8 @@ hwloc_hpux_find_ldom(hwloc_topology_t topology, hwloc_const_bitmap_t hwloc_set)
while (obj->type != HWLOC_OBJ_NUMANODE) {
/* try the first child, in case it has the same cpuset */
if (!obj->first_child
|| !obj->first_child->cpuset
|| !hwloc_bitmap_isequal(obj->cpuset, obj->first_child->cpuset))
|| !obj->first_child->cpuset
|| !hwloc_bitmap_isequal(obj->cpuset, obj->first_child->cpuset))
return -1;
obj = obj->first_child;
}
@ -139,13 +139,16 @@ hwloc_hpux_set_thisthread_cpubind(hwloc_topology_t topology, hwloc_const_bitmap_
#ifdef MAP_MEM_FIRST_TOUCH
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);
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);
@ -262,7 +266,7 @@ hwloc_look_hpux(struct hwloc_backend *backend)
void
hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support __hwloc_attribute_unused)
struct hwloc_topology_support *support __hwloc_attribute_unused)
{
hooks->set_proc_cpubind = hwloc_hpux_set_proc_cpubind;
hooks->set_thisproc_cpubind = hwloc_hpux_set_thisproc_cpubind;
@ -282,9 +286,9 @@ hwloc_set_hpux_hooks(struct hwloc_binding_hooks *hooks,
static struct hwloc_backend *
hwloc_hpux_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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);
}
@ -183,9 +187,9 @@ hwloc_set_netbsd_hooks(struct hwloc_binding_hooks *hooks __hwloc_attribute_unuse
static struct hwloc_backend *
hwloc_netbsd_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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,22 +14,29 @@ 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;
}
static struct hwloc_backend *
hwloc_noos_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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");
@ -71,21 +71,21 @@ hwloc_nvml_discover(struct hwloc_backend *backend)
if (NVML_SUCCESS == nvmlDeviceGetPciInfo(device, &pci)) {
parent = hwloc_pcidisc_find_by_busid(topology, pci.domain, pci.bus, pci.device, 0);
if (!parent)
parent = hwloc_pcidisc_find_busid_parent(topology, pci.domain, pci.bus, pci.device, 0);
parent = hwloc_pcidisc_find_busid_parent(topology, pci.domain, pci.bus, pci.device, 0);
#if HAVE_DECL_NVMLDEVICEGETMAXPCIELINKGENERATION
if (parent && parent->type == HWLOC_OBJ_PCI_DEVICE) {
unsigned maxwidth = 0, maxgen = 0;
float lanespeed;
nvmlDeviceGetMaxPcieLinkWidth(device, &maxwidth);
nvmlDeviceGetMaxPcieLinkGeneration(device, &maxgen);
/* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane
* PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane
* PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane
*/
lanespeed = maxgen <= 2 ? 2.5 * maxgen * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */
if (lanespeed * maxwidth != 0.)
/* we found the max link speed, replace the current link speed found by pci (or none) */
parent->attr->pcidev.linkspeed = lanespeed * maxwidth / 8; /* GB/s */
unsigned maxwidth = 0, maxgen = 0;
float lanespeed;
nvmlDeviceGetMaxPcieLinkWidth(device, &maxwidth);
nvmlDeviceGetMaxPcieLinkGeneration(device, &maxgen);
/* PCIe Gen1 = 2.5GT/s signal-rate per lane with 8/10 encoding = 0.25GB/s data-rate per lane
* PCIe Gen2 = 5 GT/s signal-rate per lane with 8/10 encoding = 0.5 GB/s data-rate per lane
* PCIe Gen3 = 8 GT/s signal-rate per lane with 128/130 encoding = 1 GB/s data-rate per lane
*/
lanespeed = maxgen <= 2 ? 2.5 * maxgen * 0.8 : 8.0 * 128/130; /* Gbit/s per lane */
if (lanespeed * maxwidth != 0.)
/* we found the max link speed, replace the current link speed found by pci (or none) */
parent->attr->pcidev.linkspeed = lanespeed * maxwidth / 8; /* GB/s */
}
#endif
}
@ -101,9 +101,9 @@ hwloc_nvml_discover(struct hwloc_backend *backend)
static struct hwloc_backend *
hwloc_nvml_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
@ -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,53 +67,42 @@ 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);
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
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;
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");
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");
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Accelerator");
else if (type == CL_DEVICE_TYPE_CUSTOM)
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Custom");
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Custom");
else
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Unknown");
hwloc_obj_add_info(osdev, "OpenCLDeviceType", "Unknown");
buffer[0] = '\0';
clGetDeviceInfo(device_ids[i], CL_DEVICE_VENDOR, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "GPUVendor", buffer);
hwloc_obj_add_info(osdev, "GPUVendor", buffer);
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);
hwloc_obj_add_info(osdev, "GPUModel", buffer);
snprintf(buffer, sizeof(buffer), "%u", j);
hwloc_obj_add_info(osdev, "OpenCLPlatformIndex", buffer);
@ -123,9 +110,9 @@ hwloc_opencl_discover(struct hwloc_backend *backend)
buffer[0] = '\0';
clret = clGetDeviceInfo(device_ids[i], CL_DEVICE_PLATFORM, sizeof(platform_id), &platform_id, NULL);
if (CL_SUCCESS == clret) {
clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "OpenCLPlatformName", buffer);
clGetPlatformInfo(platform_id, CL_PLATFORM_NAME, sizeof(buffer), buffer, NULL);
if (buffer[0] != '\0')
hwloc_obj_add_info(osdev, "OpenCLPlatformName", buffer);
}
snprintf(buffer, sizeof(buffer), "%u", i);
@ -141,26 +128,33 @@ 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);
if (!parent)
parent = hwloc_pcidisc_find_busid_parent(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, (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);
parent = hwloc_get_root_obj(topology);
hwloc_insert_object_by_parent(topology, parent, osdev);
}
free(device_ids);
}
free(platform_ids);
return 0;
}
static struct hwloc_backend *
hwloc_opencl_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
@ -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)
@ -96,7 +109,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
tmp = hwloc_get_root_obj(topology)->io_first_child;
while (tmp) {
if (tmp->type == HWLOC_OBJ_PCI_DEVICE
|| (tmp->type == HWLOC_OBJ_BRIDGE && tmp->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI)) {
|| (tmp->type == HWLOC_OBJ_BRIDGE && tmp->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI)) {
hwloc_debug("%s", "PCI objects already added, ignoring linuxpci backend.\n");
return 0;
}
@ -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;
}
@ -147,15 +166,15 @@ hwloc_look_pci(struct hwloc_backend *backend)
enum hwloc_type_filter_e filter;
hwloc_topology_get_type_filter(topology, HWLOC_OBJ_PCI_DEVICE, &filter);
if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
continue;
continue;
if (filter == HWLOC_TYPE_FILTER_KEEP_IMPORTANT
&& !hwloc_filter_check_pcidev_subtype_important(device_class))
continue;
&& !hwloc_filter_check_pcidev_subtype_important(device_class))
continue;
} else if (type == HWLOC_OBJ_BRIDGE) {
enum hwloc_type_filter_e filter;
hwloc_topology_get_type_filter(topology, HWLOC_OBJ_BRIDGE, &filter);
if (filter == HWLOC_TYPE_FILTER_KEEP_NONE)
continue;
continue;
/* HWLOC_TYPE_FILTER_KEEP_IMPORTANT filtered later in the core */
}
@ -188,30 +207,30 @@ hwloc_look_pci(struct hwloc_backend *backend)
size_t read;
snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/vendor",
domain, pcidev->bus, pcidev->dev, pcidev->func);
domain, pcidev->bus, pcidev->dev, pcidev->func);
file = fopen(path, "r");
if (file) {
read = fread(value, 1, sizeof(value), file);
fclose(file);
if (read)
/* fixup the pciaccess struct so that pci_device_get_vendor_name() is correct later. */
read = fread(value, 1, sizeof(value), file);
fclose(file);
if (read)
/* fixup the pciaccess struct so that pci_device_get_vendor_name() is correct later. */
pcidev->vendor_id = strtoul(value, NULL, 16);
}
snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/device",
domain, pcidev->bus, pcidev->dev, pcidev->func);
domain, pcidev->bus, pcidev->dev, pcidev->func);
file = fopen(path, "r");
if (file) {
read = fread(value, 1, sizeof(value), file);
fclose(file);
if (read)
/* fixup the pciaccess struct so that pci_device_get_device_name() is correct later. */
read = fread(value, 1, sizeof(value), file);
fclose(file);
if (read)
/* fixup the pciaccess struct so that pci_device_get_device_name() is correct later. */
pcidev->device_id = strtoul(value, NULL, 16);
}
#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;
@ -229,7 +248,7 @@ hwloc_look_pci(struct hwloc_backend *backend)
if (type == HWLOC_OBJ_BRIDGE) {
if (hwloc_pcidisc_setup_bridge_attr(obj, config_space_cache) < 0)
continue;
continue;
}
if (obj->type == HWLOC_OBJ_PCI_DEVICE) {
@ -255,10 +274,10 @@ hwloc_look_pci(struct hwloc_backend *backend)
hwloc_obj_add_info(obj, "PCIDevice", devicename);
hwloc_debug(" %04x:%02x:%02x.%01x %04x %04x:%04x %s %s\n",
domain, pcidev->bus, pcidev->dev, pcidev->func,
device_class, pcidev->vendor_id, pcidev->device_id,
vendorname && *vendorname ? vendorname : "??",
devicename && *devicename ? devicename : "??");
domain, pcidev->bus, pcidev->dev, pcidev->func,
device_class, pcidev->vendor_id, pcidev->device_id,
vendorname && *vendorname ? vendorname : "??",
devicename && *devicename ? devicename : "??");
hwloc_pcidisc_tree_insert_by_busid(&tree, obj);
}
@ -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;
@ -273,9 +293,9 @@ hwloc_look_pci(struct hwloc_backend *backend)
static struct hwloc_backend *
hwloc_pci_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
@ -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;
@ -234,40 +235,40 @@ static void hwloc_win_get_function_ptrs(void)
kernel32 = LoadLibrary("kernel32.dll");
if (kernel32) {
GetActiveProcessorGroupCountProc =
(PFN_GETACTIVEPROCESSORGROUPCOUNT) GetProcAddress(kernel32, "GetActiveProcessorGroupCount");
(PFN_GETACTIVEPROCESSORGROUPCOUNT) GetProcAddress(kernel32, "GetActiveProcessorGroupCount");
GetActiveProcessorCountProc =
(PFN_GETACTIVEPROCESSORCOUNT) GetProcAddress(kernel32, "GetActiveProcessorCount");
(PFN_GETACTIVEPROCESSORCOUNT) GetProcAddress(kernel32, "GetActiveProcessorCount");
GetLogicalProcessorInformationProc =
(PFN_GETLOGICALPROCESSORINFORMATION) GetProcAddress(kernel32, "GetLogicalProcessorInformation");
(PFN_GETLOGICALPROCESSORINFORMATION) GetProcAddress(kernel32, "GetLogicalProcessorInformation");
GetCurrentProcessorNumberProc =
(PFN_GETCURRENTPROCESSORNUMBER) GetProcAddress(kernel32, "GetCurrentProcessorNumber");
(PFN_GETCURRENTPROCESSORNUMBER) GetProcAddress(kernel32, "GetCurrentProcessorNumber");
GetCurrentProcessorNumberExProc =
(PFN_GETCURRENTPROCESSORNUMBEREX) GetProcAddress(kernel32, "GetCurrentProcessorNumberEx");
(PFN_GETCURRENTPROCESSORNUMBEREX) GetProcAddress(kernel32, "GetCurrentProcessorNumberEx");
SetThreadGroupAffinityProc =
(PFN_SETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "SetThreadGroupAffinity");
(PFN_SETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "SetThreadGroupAffinity");
GetThreadGroupAffinityProc =
(PFN_GETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "GetThreadGroupAffinity");
(PFN_GETTHREADGROUPAFFINITY) GetProcAddress(kernel32, "GetThreadGroupAffinity");
GetNumaAvailableMemoryNodeProc =
(PFN_GETNUMAAVAILABLEMEMORYNODE) GetProcAddress(kernel32, "GetNumaAvailableMemoryNode");
(PFN_GETNUMAAVAILABLEMEMORYNODE) GetProcAddress(kernel32, "GetNumaAvailableMemoryNode");
GetNumaAvailableMemoryNodeExProc =
(PFN_GETNUMAAVAILABLEMEMORYNODEEX) GetProcAddress(kernel32, "GetNumaAvailableMemoryNodeEx");
(PFN_GETNUMAAVAILABLEMEMORYNODEEX) GetProcAddress(kernel32, "GetNumaAvailableMemoryNodeEx");
GetLogicalProcessorInformationExProc =
(PFN_GETLOGICALPROCESSORINFORMATIONEX)GetProcAddress(kernel32, "GetLogicalProcessorInformationEx");
(PFN_GETLOGICALPROCESSORINFORMATIONEX)GetProcAddress(kernel32, "GetLogicalProcessorInformationEx");
QueryWorkingSetExProc =
(PFN_QUERYWORKINGSETEX) GetProcAddress(kernel32, "K32QueryWorkingSetEx");
VirtualAllocExNumaProc =
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "K32QueryWorkingSetEx");
VirtualAllocExNumaProc =*
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "VirtualAllocExNuma");
(PFN_VIRTUALALLOCEXNUMA) GetProcAddress(kernel32, "VirtualAllocExNuma");
VirtualFreeExProc =
(PFN_VIRTUALFREEEX) GetProcAddress(kernel32, "VirtualFreeEx");
(PFN_VIRTUALFREEEX) GetProcAddress(kernel32, "VirtualFreeEx");
}
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);
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
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);
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
hwloc_bitmap_free(_cpuset);
return ret;
}
@ -596,7 +609,7 @@ hwloc_win_get_proc_membind(hwloc_topology_t topology, hwloc_pid_t pid, hwloc_nod
int ret;
hwloc_cpuset_t cpuset = hwloc_bitmap_alloc();
ret = hwloc_win_get_proc_cpubind(topology, pid, cpuset,
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
(flags & HWLOC_MEMBIND_STRICT) ? HWLOC_CPUBIND_STRICT : 0);
if (!ret) {
*policy = HWLOC_MEMBIND_BIND;
hwloc_cpuset_to_nodeset(topology, cpuset, nodeset);
@ -645,6 +658,10 @@ hwloc_win_alloc_membind(hwloc_topology_t topology __hwloc_attribute_unused, size
return NULL;
}
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,38 +705,24 @@ 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;
pv = calloc(nb, sizeof(*pv));
for (i = 0; i < nb; i++)
pv[i].VirtualAddress = (void*) (start + i * page_size);
if (!QueryWorkingSetExProc(GetCurrentProcess(), pv, nb * sizeof(*pv))) {
free(pv);
return -1;
}
*policy = HWLOC_MEMBIND_BIND;
if (flags & HWLOC_MEMBIND_STRICT) {
unsigned node = pv[0].VirtualAttributes.Node;
for (i = 1; i < nb; i++) {
if (pv[i].VirtualAttributes.Node != node) {
errno = EXDEV;
free(pv);
return -1;
}
}
hwloc_bitmap_only(nodeset, node);
free(pv);
return 0;
}
hwloc_bitmap_zero(nodeset);
for (i = 0; i < nb; i++)
hwloc_bitmap_set(nodeset, pv[i].VirtualAttributes.Node);
for (i = 0; i < nb; i++)
pv[i].VirtualAddress = (void*) (start + i * page_size);
if (!QueryWorkingSetExProc(GetCurrentProcess(), pv, nb * sizeof(*pv))) {
free(pv);
return 0;
return -1;
}
for (i = 0; i < nb; i++) {
if (pv[i].VirtualAttributes.Valid)
hwloc_bitmap_set(nodeset, pv[i].VirtualAttributes.Node);
}
free(pv);
return 0;
}
@ -732,12 +737,14 @@ hwloc_look_windows(struct hwloc_backend *backend)
hwloc_bitmap_t groups_pu_set = NULL;
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);
@ -752,16 +759,16 @@ hwloc_look_windows(struct hwloc_backend *backend)
procInfo = NULL;
while (1) {
if (GetLogicalProcessorInformationProc(procInfo, &length))
break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
tmpprocInfo = realloc(procInfo, length);
if (!tmpprocInfo) {
free(procInfo);
goto out;
}
procInfo = tmpprocInfo;
if (GetLogicalProcessorInformationProc(procInfo, &length))
break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
tmpprocInfo = realloc(procInfo, length);
if (!tmpprocInfo) {
free(procInfo);
goto out;
}
procInfo = tmpprocInfo;
}
assert(!length || procInfo);
@ -769,97 +776,102 @@ hwloc_look_windows(struct hwloc_backend *backend)
for (i = 0; i < length / sizeof(*procInfo); i++) {
/* Ignore unknown caches */
if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction)
continue;
if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction)
continue;
id = -1;
switch (procInfo[i].Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
id = procInfo[i].NumaNode.NodeNumber;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
break;
case RelationCache:
type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1;
break;
case RelationProcessorCore:
type = HWLOC_OBJ_CORE;
break;
case RelationGroup:
default:
type = HWLOC_OBJ_GROUP;
break;
}
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;
break;
case RelationCache:
type = (procInfo[i].Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo[i].Cache.Level - 1;
break;
case RelationProcessorCore:
type = HWLOC_OBJ_CORE;
break;
case RelationGroup:
default:
type = HWLOC_OBJ_GROUP;
break;
}
if (!hwloc_filter_check_keep_object_type(topology, type))
continue;
if (!hwloc_filter_check_keep_object_type(topology, type))
continue;
obj = hwloc_alloc_setup_object(topology, type, id);
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);
/* 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("%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_obj_type_string(type), id, obj->cpuset);
switch (type) {
case HWLOC_OBJ_NUMANODE:
{
ULONGLONG avail;
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;
switch (type) {
case HWLOC_OBJ_NUMANODE:
{
ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (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;
}
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:
obj->attr->cache.size = procInfo[i].Cache.Size;
obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ;
obj->attr->cache.linesize = procInfo[i].Cache.LineSize;
obj->attr->cache.depth = procInfo[i].Cache.Level;
switch (procInfo->Cache.Type) {
case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
default:
hwloc_free_unlinked_object(obj);
continue;
}
break;
case HWLOC_OBJ_GROUP:
obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN;
break;
default:
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
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:
obj->attr->cache.size = procInfo[i].Cache.Size;
obj->attr->cache.associativity = procInfo[i].Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo[i].Cache.Associativity ;
obj->attr->cache.linesize = procInfo[i].Cache.LineSize;
obj->attr->cache.depth = procInfo[i].Cache.Level;
switch (procInfo->Cache.Type) {
case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
default:
hwloc_free_unlinked_object(obj);
continue;
}
break;
case HWLOC_OBJ_GROUP:
obj->attr->group.kind = procInfo[i].Relationship == RelationGroup ? HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP : HWLOC_GROUP_KIND_WINDOWS_RELATIONSHIP_UNKNOWN;
break;
default:
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
}
free(procInfo);
@ -875,158 +887,167 @@ hwloc_look_windows(struct hwloc_backend *backend)
procInfoTotal = NULL;
while (1) {
if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length))
break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
if (GetLogicalProcessorInformationExProc(RelationAll, procInfoTotal, &length))
break;
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return -1;
tmpprocInfoTotal = realloc(procInfoTotal, length);
if (!tmpprocInfoTotal) {
free(procInfoTotal);
goto out;
}
procInfoTotal = tmpprocInfoTotal;
if (!tmpprocInfoTotal) {
free(procInfoTotal);
goto out;
}
procInfoTotal = tmpprocInfoTotal;
}
for (procInfo = procInfoTotal;
(void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length);
procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) {
(void*) procInfo < (void*) ((uintptr_t) procInfoTotal + length);
procInfo = (void*) ((uintptr_t) procInfo + procInfo->Size)) {
unsigned num, i;
GROUP_AFFINITY *GroupMask;
/* Ignore unknown caches */
if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction)
continue;
if (procInfo->Relationship == RelationCache
&& procInfo->Cache.Type != CacheUnified
&& procInfo->Cache.Type != CacheData
&& procInfo->Cache.Type != CacheInstruction)
continue;
id = -1;
switch (procInfo->Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
id = HWLOC_UNKNOWN_INDEX;
switch (procInfo->Relationship) {
case RelationNumaNode:
type = HWLOC_OBJ_NUMANODE;
num = 1;
GroupMask = &procInfo->NumaNode.GroupMask;
id = procInfo->NumaNode.NodeNumber;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
id = procInfo->NumaNode.NodeNumber;
gotnuma++;
if (id > max_numanode_index)
max_numanode_index = id;
break;
case RelationProcessorPackage:
type = HWLOC_OBJ_PACKAGE;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
case RelationCache:
type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1;
break;
case RelationCache:
type = (procInfo->Cache.Type == CacheInstruction ? HWLOC_OBJ_L1ICACHE : HWLOC_OBJ_L1CACHE) + procInfo->Cache.Level - 1;
num = 1;
GroupMask = &procInfo->Cache.GroupMask;
break;
case RelationProcessorCore:
type = HWLOC_OBJ_CORE;
break;
case RelationProcessorCore:
type = HWLOC_OBJ_CORE;
num = procInfo->Processor.GroupCount;
GroupMask = procInfo->Processor.GroupMask;
break;
case RelationGroup:
/* So strange an interface... */
for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) {
break;
case RelationGroup:
/* So strange an interface... */
for (id = 0; id < procInfo->Group.ActiveGroupCount; id++) {
KAFFINITY mask;
hwloc_bitmap_t set;
hwloc_bitmap_t set;
set = hwloc_bitmap_alloc();
mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask;
hwloc_debug("group %u %d cpus mask %lx\n", id,
procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask);
/* KAFFINITY is ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask);
/* FIXME: what if running 32bits on a 64bits windows with 64-processor groups?
* ULONG_PTR is 32bits, so half the group is invisible?
* maybe scale id to id*8/sizeof(ULONG_PTR) so that groups are 64-PU aligned?
*/
hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, set);
set = hwloc_bitmap_alloc();
mask = procInfo->Group.GroupInfo[id].ActiveProcessorMask;
hwloc_debug("group %u %d cpus mask %lx\n", id,
procInfo->Group.GroupInfo[id].ActiveProcessorCount, mask);
/* KAFFINITY is ULONG_PTR */
hwloc_bitmap_set_ith_ULONG_PTR(set, id, mask);
/* FIXME: what if running 32bits on a 64bits windows with 64-processor groups?
* ULONG_PTR is 32bits, so half the group is invisible?
* maybe scale id to id*8/sizeof(ULONG_PTR) so that groups are 64-PU aligned?
*/
hwloc_debug_2args_bitmap("group %u %d bitmap %s\n", id, procInfo->Group.GroupInfo[id].ActiveProcessorCount, set);
/* save the set of PUs so that we can create them at the end */
if (!groups_pu_set)
groups_pu_set = hwloc_bitmap_alloc();
hwloc_bitmap_or(groups_pu_set, groups_pu_set, set);
/* save the set of PUs so that we can create them at the end */
if (!groups_pu_set)
groups_pu_set = hwloc_bitmap_alloc();
hwloc_bitmap_or(groups_pu_set, groups_pu_set, set);
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id);
obj->cpuset = set;
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
hwloc_insert_object_by_cpuset(topology, obj);
} else
hwloc_bitmap_free(set);
}
continue;
default:
/* Don't know how to get the mask. */
if (hwloc_filter_check_keep_object_type(topology, HWLOC_OBJ_GROUP)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_GROUP, id);
obj->cpuset = set;
obj->attr->group.kind = HWLOC_GROUP_KIND_WINDOWS_PROCESSOR_GROUP;
hwloc_insert_object_by_cpuset(topology, obj);
} else
hwloc_bitmap_free(set);
}
continue;
default:
/* Don't know how to get the mask. */
hwloc_debug("unknown relation %d\n", procInfo->Relationship);
continue;
}
continue;
}
if (!hwloc_filter_check_keep_object_type(topology, type))
continue;
if (!hwloc_filter_check_keep_object_type(topology, type))
continue;
obj = hwloc_alloc_setup_object(topology, type, id);
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);
/* 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("%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);
switch (type) {
case HWLOC_OBJ_NUMANODE:
{
ULONGLONG avail;
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;
hwloc_debug_2args_bitmap("%s#%u bitmap %s\n", hwloc_obj_type_string(type), id, obj->cpuset);
switch (type) {
case HWLOC_OBJ_NUMANODE:
{
ULONGLONG avail;
obj->nodeset = hwloc_bitmap_alloc();
hwloc_bitmap_set(obj->nodeset, id);
if ((GetNumaAvailableMemoryNodeExProc && GetNumaAvailableMemoryNodeExProc(id, &avail))
|| (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;
}
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:
obj->attr->cache.size = procInfo->Cache.CacheSize;
obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ;
obj->attr->cache.linesize = procInfo->Cache.LineSize;
obj->attr->cache.depth = procInfo->Cache.Level;
switch (procInfo->Cache.Type) {
case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
default:
hwloc_free_unlinked_object(obj);
continue;
}
break;
default:
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
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:
obj->attr->cache.size = procInfo->Cache.CacheSize;
obj->attr->cache.associativity = procInfo->Cache.Associativity == CACHE_FULLY_ASSOCIATIVE ? -1 : procInfo->Cache.Associativity ;
obj->attr->cache.linesize = procInfo->Cache.LineSize;
obj->attr->cache.depth = procInfo->Cache.Level;
switch (procInfo->Cache.Type) {
case CacheUnified:
obj->attr->cache.type = HWLOC_OBJ_CACHE_UNIFIED;
break;
case CacheData:
obj->attr->cache.type = HWLOC_OBJ_CACHE_DATA;
break;
case CacheInstruction:
obj->attr->cache.type = HWLOC_OBJ_CACHE_INSTRUCTION;
break;
default:
hwloc_free_unlinked_object(obj);
continue;
}
break;
default:
break;
}
hwloc_insert_object_by_cpuset(topology, obj);
}
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.
@ -1038,7 +1059,7 @@ hwloc_look_windows(struct hwloc_backend *backend)
obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_only(obj->cpuset, idx);
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
idx, obj->cpuset);
idx, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
} hwloc_bitmap_foreach_end();
hwloc_bitmap_free(groups_pu_set);
@ -1050,12 +1071,12 @@ hwloc_look_windows(struct hwloc_backend *backend)
GetSystemInfo(&sysinfo);
for(idx=0; idx<32; idx++)
if (sysinfo.dwActiveProcessorMask & (((DWORD_PTR)1)<<idx)) {
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx);
obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_only(obj->cpuset, idx);
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
idx, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
obj = hwloc_alloc_setup_object(topology, HWLOC_OBJ_PU, idx);
obj->cpuset = hwloc_bitmap_alloc();
hwloc_bitmap_only(obj->cpuset, idx);
hwloc_debug_1arg_bitmap("cpu %u has cpuset %s\n",
idx, obj->cpuset);
hwloc_insert_object_by_cpuset(topology, obj);
}
}
@ -1067,7 +1088,7 @@ hwloc_look_windows(struct hwloc_backend *backend)
void
hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks,
struct hwloc_topology_support *support)
struct hwloc_topology_support *support)
{
if (GetCurrentProcessorNumberExProc || (GetCurrentProcessorNumberProc && nr_processor_groups == 1))
hooks->get_thisthread_last_cpu_location = hwloc_win_get_thisthread_last_cpu_location;
@ -1100,8 +1121,8 @@ hwloc_set_windows_hooks(struct hwloc_binding_hooks *hooks,
support->membind->bind_membind = 1;
}
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)
@ -1116,9 +1137,9 @@ static void hwloc_windows_component_finalize(unsigned long flags __hwloc_attribu
static struct hwloc_backend *
hwloc_windows_component_instantiate(struct hwloc_disc_component *component,
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
const void *_data1 __hwloc_attribute_unused,
const void *_data2 __hwloc_attribute_unused,
const void *_data3 __hwloc_attribute_unused)
{
struct hwloc_backend *backend;
backend = hwloc_backend_alloc(component);
@ -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;
@ -1158,14 +1180,10 @@ hwloc_fallback_nbprocessors(struct hwloc_topology *topology) {
/* assume n-1 groups are complete, since that's how we store things in cpusets */
if (GetActiveProcessorCountProc)
n = MAXIMUM_PROC_PER_GROUP*(nr_processor_groups-1)
+ GetActiveProcessorCountProc((WORD)nr_processor_groups-1);
+ GetActiveProcessorCountProc((WORD)nr_processor_groups-1);
else
n = MAXIMUM_PROC_PER_GROUP*nr_processor_groups;
}
if (n >= 1)
topology->support.discovery->pu = 1;
else
n = 1;
return n;
}

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

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

@ -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,20 +83,22 @@ 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;
}
static int
hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate,
char **tagp)
hwloc__xml_import_state_t childstate,
char **tagp)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
hwloc__libxml_import_state_data_t lchildstate = (void*) childstate->data;
@ -104,23 +106,27 @@ hwloc__libxml_import_find_child(hwloc__xml_import_state_t state,
childstate->parent = state;
childstate->global = state->global;
if (!lstate->child)
/* All children proceeded */
return 0;
child = lstate->child->next;
for (; child; child = child->next)
if (child->type == XML_ELEMENT_NODE) {
lstate->child = lchildstate->node = child;
lchildstate->child = child->children;
lchildstate->attr = NULL;
*tagp = (char*) child->name;
return 1;
} 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);
} else if (child->type != XML_COMMENT_NODE) {
child = lstate->child;
if (child->type == XML_ELEMENT_NODE) {
lstate->child = child->next;
lchildstate->node = child;
lchildstate->child = child->children;
lchildstate->attr = NULL;
*tagp = (char*) child->name;
return 1;
} 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 unexpected xml node type %u\n", child->type);
}
fprintf(stderr, "%s: ignoring object text content %s\n",
state->global->msgprefix, (const char*) child->content);
} else if (child->type != XML_COMMENT_NODE) {
if (hwloc__xml_verbose())
fprintf(stderr, "%s: ignoring unexpected xml node type %u\n",
state->global->msgprefix, child->type);
}
return 0;
}
@ -139,7 +145,7 @@ hwloc__libxml_import_close_child(hwloc__xml_import_state_t state __hwloc_attribu
static int
hwloc__libxml_import_get_content(hwloc__xml_import_state_t state,
char **beginp, size_t expected_length)
char **beginp, size_t expected_length)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
xmlNode *child;
@ -149,7 +155,7 @@ hwloc__libxml_import_get_content(hwloc__xml_import_state_t state,
if (!child || child->type != XML_TEXT_NODE) {
if (expected_length)
return -1;
*beginp = "";
*beginp = (char *) "";
return 0;
}
@ -168,30 +174,47 @@ hwloc__libxml_import_close_content(hwloc__xml_import_state_t state __hwloc_attri
static int
hwloc_libxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state)
struct hwloc__xml_import_state_s *state)
{
hwloc__libxml_import_state_data_t lstate = (void*) state->data;
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;
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,13 +350,13 @@ 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();
}
static int
hwloc_libxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{
xmlDoc *doc = NULL;
@ -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;
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;
@ -350,8 +395,8 @@ typedef struct hwloc__libxml_export_state_data_s {
static void
hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state,
const char *name)
hwloc__xml_export_state_t state,
const char *name)
{
hwloc__libxml_export_state_data_t lpdata = (void *) parentstate->data;
hwloc__libxml_export_state_data_t ldata = (void *) state->data;
@ -361,6 +406,7 @@ hwloc__libxml_export_new_child(hwloc__xml_export_state_t parentstate,
state->new_prop = parentstate->new_prop;
state->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.
@ -70,28 +70,28 @@ hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep,
while (value[len+escaped] != '\"') {
if (value[len+escaped] == '&') {
if (!strncmp(&value[1+len+escaped], "#10;", 4)) {
escaped += 4;
value[len] = '\n';
escaped += 4;
value[len] = '\n';
} else if (!strncmp(&value[1+len+escaped], "#13;", 4)) {
escaped += 4;
value[len] = '\r';
escaped += 4;
value[len] = '\r';
} else if (!strncmp(&value[1+len+escaped], "#9;", 3)) {
escaped += 3;
value[len] = '\t';
escaped += 3;
value[len] = '\t';
} else if (!strncmp(&value[1+len+escaped], "quot;", 5)) {
escaped += 5;
value[len] = '\"';
escaped += 5;
value[len] = '\"';
} else if (!strncmp(&value[1+len+escaped], "lt;", 3)) {
escaped += 3;
value[len] = '<';
escaped += 3;
value[len] = '<';
} else if (!strncmp(&value[1+len+escaped], "gt;", 3)) {
escaped += 3;
value[len] = '>';
escaped += 3;
value[len] = '>';
} else if (!strncmp(&value[1+len+escaped], "amp;", 4)) {
escaped += 4;
value[len] = '&';
escaped += 4;
value[len] = '&';
} else {
return -1;
return -1;
}
} else {
value[len] = value[len+escaped];
@ -110,13 +110,14 @@ hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state, char **namep,
static int
hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state,
hwloc__xml_import_state_t childstate,
char **tagp)
hwloc__xml_import_state_t childstate,
char **tagp)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
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;
}
@ -211,7 +214,7 @@ hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state)
static int
hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state,
char **beginp, size_t expected_length)
char **beginp, size_t expected_length)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
char *buffer = nstate->tagbuffer;
@ -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;
}
@ -251,13 +254,15 @@ hwloc__nolibxml_import_close_content(hwloc__xml_import_state_t state)
static int
hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s *bdata,
struct hwloc__xml_import_state_s *state)
struct hwloc__xml_import_state_s *state)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
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,12 +309,31 @@ 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 */
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");
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);
}
@ -372,7 +407,7 @@ hwloc_nolibxml_read_file(const char *xmlpath, char **bufferp, size_t *buflenp)
static int
hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s *bdata,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
const char *xmlpath, const char *xmlbuffer, int xmlbuflen)
{
struct hwloc__nolibxml_backend_data_s *nbdata = malloc(sizeof(*nbdata));
@ -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;
@ -413,8 +448,8 @@ out:
static int
hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
const char *xmlpath, const char *xmlbuffer, int xmlbuflen,
hwloc_topology_diff_t *firstdiffp, char **refnamep)
const char *xmlpath, const char *xmlbuffer, int xmlbuflen,
hwloc_topology_diff_t *firstdiffp, char **refnamep)
{
hwloc__nolibxml_import_state_data_t nstate = (void*) state->data;
struct hwloc__xml_import_state_s childstate;
@ -423,7 +458,7 @@ hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s *state,
size_t buflen;
int ret;
assert(sizeof(*nstate) <= sizeof(state->data));
HWLOC_BUILD_ASSERT(sizeof(*nstate) <= sizeof(state->data));
if (xmlbuffer) {
buffer = malloc(xmlbuflen);
@ -562,8 +597,8 @@ hwloc__nolibxml_export_escape_string(const char *src)
static void
hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
hwloc__xml_export_state_t state,
const char *name)
hwloc__xml_export_state_t state,
const char *name)
{
hwloc__nolibxml_export_state_data_t npdata = (void *) parentstate->data;
hwloc__nolibxml_export_state_data_t ndata = (void *) state->data;
@ -581,6 +616,7 @@ hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate,
state->new_prop = parentstate->new_prop;
state->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;
@ -666,10 +705,12 @@ hwloc___nolibxml_prepare_export(hwloc_topology_t topology, char *xmlbuffer, int
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topology SYSTEM \"hwloc.dtd\">\n");
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\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;
@ -763,8 +806,8 @@ hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff, const char *ref
ndata->has_content = 0;
res = hwloc_snprintf(ndata->buffer, ndata->remaining,
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<!DOCTYPE topologydiff SYSTEM \"hwloc.dtd\">\n");
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\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)
{
return topology->type_depth[type];
HWLOC_BUILD_ASSERT(HWLOC_OBJ_TYPE_MIN == 0);
if ((unsigned) type >= HWLOC_OBJ_TYPE_MAX)
return HWLOC_TYPE_DEPTH_UNKNOWN;
else
return topology->type_depth[type];
}
hwloc_obj_type_t
hwloc_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)
@ -85,19 +152,19 @@ unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_o
while (1) {
nextparent = parent->parent;
if (!nextparent)
goto out;
goto out;
if (!hwloc_bitmap_isequal(parent->cpuset, nextparent->cpuset))
break;
break;
parent = nextparent;
}
/* traverse src's objects and find those that are in nextparent and were not in parent */
for(i=0; i<src_nbobjects; i++) {
if (hwloc_bitmap_isincluded(src_objs[i]->cpuset, nextparent->cpuset)
&& !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) {
objs[stored++] = src_objs[i];
if (stored == max)
goto out;
&& !hwloc_bitmap_isincluded(src_objs[i]->cpuset, parent->cpuset)) {
objs[stored++] = src_objs[i];
if (stored == max)
goto out;
}
}
parent = nextparent;
@ -109,7 +176,7 @@ unsigned hwloc_get_closest_objs (struct hwloc_topology *topology, struct hwloc_o
static int
hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bitmap_t set,
struct hwloc_obj ***res, int *max)
struct hwloc_obj ***res, int *max)
{
int gotten = 0;
unsigned i;
@ -149,7 +216,7 @@ hwloc__get_largest_objs_inside_cpuset (struct hwloc_obj *current, hwloc_const_bi
int
hwloc_get_largest_objs_inside_cpuset (struct hwloc_topology *topology, hwloc_const_bitmap_t set,
struct hwloc_obj **objs, int max)
struct hwloc_obj **objs, int max)
{
struct hwloc_obj *current = topology->levels[0][0];
@ -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";
@ -192,7 +258,7 @@ hwloc_type_name (hwloc_obj_type_t obj)
int
hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
union hwloc_obj_attr_u *attrp, size_t attrsize)
union hwloc_obj_attr_u *attrp, size_t attrsize)
{
hwloc_obj_type_t type = (hwloc_obj_type_t) -1;
unsigned depthattr = (unsigned) -1;
@ -206,15 +272,37 @@ 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)
|| !hwloc_strncasecmp(string, "numa", 2)) { /* matches node and numanode */
|| !hwloc_strncasecmp(string, "numa", 2)) { /* matches node and numanode */
type = HWLOC_OBJ_NUMANODE;
} else if (!hwloc_strncasecmp(string, "package", 2)
|| !hwloc_strncasecmp(string, "socket", 2)) { /* backward compat with v1.10 */
|| !hwloc_strncasecmp(string, "socket", 2)) { /* backward compat with v1.10 */
type = HWLOC_OBJ_PACKAGE;
} else if (!hwloc_strncasecmp(string, "core", 2)) {
type = HWLOC_OBJ_CORE;
@ -235,43 +323,21 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
} else if (!hwloc_strncasecmp(string, "pci", 3)) {
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);
if (*end == 'i') {
if (depthattr >= 1 && depthattr <= 3) {
type = HWLOC_OBJ_L1ICACHE + depthattr-1;
cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION;
type = HWLOC_OBJ_L1ICACHE + depthattr-1;
cachetypeattr = HWLOC_OBJ_CACHE_INSTRUCTION;
} else
return -1;
return -1;
} else {
if (depthattr >= 1 && depthattr <= 5) {
type = HWLOC_OBJ_L1CACHE + depthattr-1;
cachetypeattr = *end == 'd' ? HWLOC_OBJ_CACHE_DATA : HWLOC_OBJ_CACHE_UNIFIED;
type = HWLOC_OBJ_L1CACHE + depthattr-1;
cachetypeattr = *end == 'd' ? HWLOC_OBJ_CACHE_DATA : HWLOC_OBJ_CACHE_UNIFIED;
} else
return -1;
return -1;
}
} else if (!hwloc_strncasecmp(string, "group", 2)) {
@ -279,7 +345,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
type = HWLOC_OBJ_GROUP;
length = strcspn(string, "0123456789");
if (length <= 5 && !hwloc_strncasecmp(string, "group", length)
&& string[length] >= '0' && string[length] <= '9') {
&& string[length] >= '0' && string[length] <= '9') {
depthattr = strtol(string+length, &end, 10);
}
@ -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)) {
@ -305,7 +371,7 @@ hwloc_type_sscanf(const char *string, hwloc_obj_type_t *typep,
int
hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
hwloc_topology_t topology, int *depthp)
hwloc_topology_t topology, int *depthp)
{
union hwloc_obj_attr_u attr;
hwloc_obj_type_t type;
@ -324,16 +390,16 @@ hwloc_type_sscanf_as_depth(const char *string, hwloc_obj_type_t *typep,
depth = HWLOC_TYPE_DEPTH_UNKNOWN;
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;
break;
&& topology->levels[l][0]->attr->group.depth == attr.group.depth) {
depth = (int)l;
break;
}
}
}
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:
@ -369,13 +434,13 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
case HWLOC_OBJ_L2ICACHE:
case HWLOC_OBJ_L3ICACHE:
return hwloc_snprintf(string, size, "L%u%s%s", obj->attr->cache.depth,
hwloc_obj_cache_type_letter(obj->attr->cache.type),
verbose ? "Cache" : "");
hwloc_obj_cache_type_letter(obj->attr->cache.type),
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:
@ -390,7 +455,7 @@ hwloc_obj_type_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
case HWLOC_OBJ_OSDEV_COPROC: return hwloc_snprintf(string, size, verbose ? "Co-Processor" : "CoProc");
default:
if (size > 0)
*string = '\0';
*string = '\0';
return 0;
}
break;
@ -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),
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)
prefix,
(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->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));
prefix,
(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));
prefix,
(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;
@ -461,22 +526,22 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (verbose) {
char assoc[32];
if (obj->attr->cache.associativity == -1)
snprintf(assoc, sizeof(assoc), "%sfully-associative", separator);
snprintf(assoc, sizeof(assoc), "%sfully-associative", separator);
else if (obj->attr->cache.associativity == 0)
*assoc = '\0';
*assoc = '\0';
else
snprintf(assoc, sizeof(assoc), "%sways=%d", separator, obj->attr->cache.associativity);
snprintf(assoc, sizeof(assoc), "%sways=%d", separator, obj->attr->cache.associativity);
res = hwloc_snprintf(tmp, tmplen, "%ssize=%lu%s%slinesize=%u%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose),
separator, obj->attr->cache.linesize,
assoc);
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose),
separator, obj->attr->cache.linesize,
assoc);
} else
res = hwloc_snprintf(tmp, tmplen, "%s%lu%s",
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose));
prefix,
(unsigned long) hwloc_memory_size_printf_value(obj->attr->cache.size, verbose),
hwloc_memory_size_printf_unit(obj->attr->cache.size, verbose));
break;
case HWLOC_OBJ_BRIDGE:
if (verbose) {
@ -486,19 +551,19 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
char linkspeed[64]= "";
if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
snprintf(up, sizeof(up), "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
snprintf(up, sizeof(up), "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
} else
*up = '\0';
/* downstream is_PCI */
snprintf(down, sizeof(down), "buses=%04x:[%02x-%02x]",
obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus);
obj->attr->bridge.downstream.pci.domain, obj->attr->bridge.downstream.pci.secondary_bus, obj->attr->bridge.downstream.pci.subordinate_bus);
if (*up)
res = snprintf(string, size, "%s%s%s", up, separator, down);
res = snprintf(string, size, "%s%s%s", up, separator, down);
else
res = snprintf(string, size, "%s", down);
res = snprintf(string, size, "%s", down);
}
break;
case HWLOC_OBJ_PCI_DEVICE:
@ -507,9 +572,9 @@ hwloc_obj_attr_snprintf(char * __hwloc_restrict string, size_t size, hwloc_obj_t
if (obj->attr->pcidev.linkspeed)
snprintf(linkspeed, sizeof(linkspeed), "%slink=%.2fGB/s", separator, obj->attr->pcidev.linkspeed);
res = snprintf(string, size, "busid=%04x:%02x:%02x.%01x%sid=%04x:%04x%sclass=%04x(%s)%s",
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
obj->attr->pcidev.domain, obj->attr->pcidev.bus, obj->attr->pcidev.dev, obj->attr->pcidev.func, separator,
obj->attr->pcidev.vendor_id, obj->attr->pcidev.device_id, separator,
obj->attr->pcidev.class_id, hwloc_pci_class_string(obj->attr->pcidev.class_id), linkspeed);
}
break;
default:
@ -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\"",
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);
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,
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 @@
/* -*- 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,9 +67,16 @@
#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
#define __HWLOC_HAVE_ATTRIBUTE_UNUSED HWLOC_HAVE_ATTRIBUTE_UNUSED
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_UNUSED (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)
#else
@ -82,7 +89,7 @@
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_MALLOC
#define __HWLOC_HAVE_ATTRIBUTE_MALLOC HWLOC_HAVE_ATTRIBUTE_MALLOC
#define __HWLOC_HAVE_ATTRIBUTE_MALLOC HWLOC_HAVE_ATTRIBUTE_MALLOC
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_MALLOC (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)
#else
@ -95,7 +102,7 @@
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_CONST
#define __HWLOC_HAVE_ATTRIBUTE_CONST HWLOC_HAVE_ATTRIBUTE_CONST
#define __HWLOC_HAVE_ATTRIBUTE_CONST HWLOC_HAVE_ATTRIBUTE_CONST
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_CONST (GXX_ABOVE_3_4 || GCC_ABOVE_2_95)
#else
@ -108,7 +115,7 @@
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_PURE
#define __HWLOC_HAVE_ATTRIBUTE_PURE HWLOC_HAVE_ATTRIBUTE_PURE
#define __HWLOC_HAVE_ATTRIBUTE_PURE HWLOC_HAVE_ATTRIBUTE_PURE
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_PURE (GXX_ABOVE_3_4 || GCC_ABOVE_2_96)
#else
@ -121,7 +128,7 @@
#endif
#ifdef HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED HWLOC_HAVE_ATTRIBUTE_DEPRECATED
#elif defined(__GNUC__)
# define __HWLOC_HAVE_ATTRIBUTE_DEPRECATED (GXX_ABOVE_3_4 || GCC_ABOVE_3_3)
#else
@ -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
@ -291,7 +321,7 @@ do { \
* \sa hwloc_bitmap_foreach_begin()
* \hideinitializer
*/
#define hwloc_bitmap_foreach_end() \
#define hwloc_bitmap_foreach_end() \
} \
} while (0)
@ -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.
@ -45,7 +45,7 @@ extern "C" {
*/
static __hwloc_inline int
hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, int *domain, int *bus, int *dev)
CUdevice cudevice, int *domain, int *bus, int *dev)
{
CUresult cres;
@ -90,7 +90,7 @@ hwloc_cuda_get_device_pci_ids(hwloc_topology_t topology __hwloc_attribute_unused
*/
static __hwloc_inline int
hwloc_cuda_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
CUdevice cudevice, hwloc_cpuset_t set)
CUdevice cudevice, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
@ -144,7 +144,7 @@ hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
* CUDA device \p cudevice. Return NULL if there is none.
*
* 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().
*
@ -156,28 +156,28 @@ hwloc_cuda_get_device_pcidev(hwloc_topology_t topology, CUdevice cudevice)
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
{
hwloc_obj_t osdev = NULL;
int domain, bus, dev;
hwloc_obj_t osdev = NULL;
int domain, bus, dev;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL;
if (hwloc_cuda_get_device_pci_ids(topology, cudevice, &domain, &bus, &dev))
return NULL;
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "cuda", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& (int) pcidev->attr->pcidev.domain == domain
&& (int) pcidev->attr->pcidev.bus == bus
&& (int) pcidev->attr->pcidev.dev == dev
&& pcidev->attr->pcidev.func == 0)
return osdev;
/* if PCI are filtered out, we need a info attr to match on */
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "cuda", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& (int) pcidev->attr->pcidev.domain == domain
&& (int) pcidev->attr->pcidev.bus == bus
&& (int) pcidev->attr->pcidev.dev == dev
&& pcidev->attr->pcidev.func == 0)
return osdev;
/* if PCI are filtered out, we need a info attr to match on */
}
return NULL;
return NULL;
}
/** \brief Get the hwloc OS device object corresponding to the
@ -198,15 +198,15 @@ hwloc_cuda_get_device_osdev(hwloc_topology_t topology, CUdevice cudevice)
static __hwloc_inline hwloc_obj_t
hwloc_cuda_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("cuda", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
}
/** @} */

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

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

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

@ -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;

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

@ -39,18 +39,18 @@ extern "C" {
* possibly provided by the user, as specified in the \p kind attribute.
*/
struct hwloc_distances_s {
unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */
hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix.
* These objects are not in any particular order,
* see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values()
* for easy ways to find objects in this array and their corresponding values.
*/
unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */
hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array.
*
* Distance from i-th to j-th object is stored in slot i*nbobjs+j.
* The meaning of the value depends on the \p kind attribute.
*/
unsigned nbobjs; /**< \brief Number of objects described by the distance matrix. */
hwloc_obj_t *objs; /**< \brief Array of objects described by the distance matrix.
* These objects are not in any particular order,
* see hwloc_distances_obj_index() and hwloc_distances_obj_pair_values()
* for easy ways to find objects in this array and their corresponding values.
*/
unsigned long kind; /**< \brief OR'ed set of ::hwloc_distances_kind_e. */
hwloc_uint64_t *values; /**< \brief Matrix of distances between objects, stored as a one-dimension array.
*
* Distance from i-th to j-th object is stored in slot i*nbobjs+j.
* The meaning of the value depends on the \p kind attribute.
*/
};
/** \brief Kinds of distance matrices.
@ -114,17 +114,17 @@ enum hwloc_distances_kind_e {
*/
HWLOC_DECLSPEC int
hwloc_distances_get(hwloc_topology_t topology,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
/** \brief Retrieve distance matrices for object at a specific depth in the 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,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
hwloc_distances_get_by_depth(hwloc_topology_t topology, int depth,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags);
/** \brief Retrieve distance matrices for object of a specific type.
*
@ -132,11 +132,11 @@ hwloc_distances_get_by_depth(hwloc_topology_t topology, unsigned depth,
*/
static __hwloc_inline int
hwloc_distances_get_by_type(hwloc_topology_t topology, hwloc_obj_type_t type,
unsigned *nr, struct hwloc_distances_s **distances,
unsigned long kind, unsigned long flags)
unsigned *nr, struct hwloc_distances_s **distances,
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;
}
@ -178,8 +178,8 @@ hwloc_distances_obj_index(struct hwloc_distances_s *distances, hwloc_obj_t obj)
*/
static __hwloc_inline int
hwloc_distances_obj_pair_values(struct hwloc_distances_s *distances,
hwloc_obj_t obj1, hwloc_obj_t obj2,
hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1)
hwloc_obj_t obj1, hwloc_obj_t obj2,
hwloc_uint64_t *value1to2, hwloc_uint64_t *value2to1)
{
int i1 = hwloc_distances_obj_index(distances, obj1);
int i2 = hwloc_distances_obj_index(distances, obj2);
@ -227,8 +227,8 @@ enum hwloc_distances_add_flag_e {
* Objects must be of the same type. They cannot be of type Group.
*/
HWLOC_DECLSPEC int hwloc_distances_add(hwloc_topology_t topology,
unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values,
unsigned long kind, unsigned long flags);
unsigned nbobjs, hwloc_obj_t *objs, hwloc_uint64_t *values,
unsigned long kind, unsigned long flags);
/** \brief Remove all distance matrices from a topology.
*
@ -244,7 +244,7 @@ HWLOC_DECLSPEC int hwloc_distances_remove(hwloc_topology_t topology);
*
* Identical to hwloc_distances_remove() but only applies to one level of the topology.
*/
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.
@ -104,7 +123,7 @@ HWLOC_DECLSPEC void hwloc_free_xmlbuffer(hwloc_topology_t topology, char *xmlbuf
* \note The topology-specific userdata pointer is ignored when exporting to XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_export_callback(hwloc_topology_t topology,
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
void (*export_cb)(void *reserved, hwloc_topology_t topology, hwloc_obj_t obj));
/** \brief Export some object userdata to XML
*
@ -171,7 +190,7 @@ HWLOC_DECLSPEC int hwloc_export_obj_userdata_base64(void *reserved, hwloc_topolo
* \note The topology-specific userdata pointer is ignored when importing from XML.
*/
HWLOC_DECLSPEC void hwloc_topology_set_userdata_import_callback(hwloc_topology_t topology,
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
void (*import_cb)(hwloc_topology_t topology, hwloc_obj_t obj, const char *name, const void *buffer, size_t length));
/** @} */
@ -198,7 +217,27 @@ enum hwloc_topology_export_synthetic_flags_e {
* This is required if loading the synthetic description with hwloc < 1.10.
* \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.

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

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

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

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

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

@ -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.
@ -49,7 +49,7 @@ hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const
hwloc_obj_t child = obj->first_child;
while (child) {
if (hwloc_bitmap_intersects(child->cpuset, set))
break;
break;
child = child->next_sibling;
}
if (!child)
@ -67,7 +67,7 @@ hwloc_get_first_largest_obj_inside_cpuset(hwloc_topology_t topology, hwloc_const
* \return the number of objects returned in \p objs.
*/
HWLOC_DECLSPEC int hwloc_get_largest_objs_inside_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_t * __hwloc_restrict objs, int max);
hwloc_obj_t * __hwloc_restrict objs, int max);
/** \brief Return the next object at depth \p depth included in CPU set \p set.
*
@ -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)
@ -107,7 +107,7 @@ hwloc_get_next_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_cons
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, hwloc_obj_t prev)
hwloc_obj_type_t type, hwloc_obj_t prev)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -125,10 +125,10 @@ hwloc_get_next_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const
*/
static __hwloc_inline hwloc_obj_t
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;
@ -137,7 +137,7 @@ hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpu
while (obj) {
if (!hwloc_bitmap_iszero(obj->cpuset) && hwloc_bitmap_isincluded(obj->cpuset, set)) {
if (count == idx)
return obj;
return obj;
count++;
}
obj = obj->next_cousin;
@ -159,10 +159,10 @@ hwloc_get_obj_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_cpu
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
hwloc_obj_type_t type, unsigned idx) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, unsigned idx)
hwloc_obj_type_t type, unsigned idx)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -180,10 +180,10 @@ hwloc_get_obj_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpus
*/
static __hwloc_inline unsigned
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;
@ -211,17 +211,17 @@ hwloc_get_nbobjs_inside_cpuset_by_depth (hwloc_topology_t topology, hwloc_const_
*/
static __hwloc_inline int
hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type) __hwloc_attribute_pure;
hwloc_obj_type_t type) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type)
hwloc_obj_type_t type)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN)
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.
@ -239,10 +239,10 @@ hwloc_get_nbobjs_inside_cpuset_by_type (hwloc_topology_t topology, hwloc_const_c
*/
static __hwloc_inline int
hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t obj) __hwloc_attribute_pure;
hwloc_obj_t obj) __hwloc_attribute_pure;
static __hwloc_inline int
hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t obj)
hwloc_obj_t obj)
{
int idx = 0;
if (!hwloc_bitmap_isincluded(obj->cpuset, set))
@ -270,10 +270,10 @@ hwloc_get_obj_index_inside_cpuset (hwloc_topology_t topology __hwloc_attribute_u
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t parent) __hwloc_attribute_pure;
hwloc_obj_t parent) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_child_covering_cpuset (hwloc_topology_t topology __hwloc_attribute_unused, hwloc_const_cpuset_t set,
hwloc_obj_t parent)
hwloc_obj_t parent)
{
hwloc_obj_t child;
if (hwloc_bitmap_iszero(set))
@ -319,7 +319,7 @@ hwloc_get_obj_covering_cpuset (hwloc_topology_t topology, hwloc_const_cpuset_t s
*/
static __hwloc_inline hwloc_obj_t
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)
@ -346,7 +346,7 @@ hwloc_get_next_obj_covering_cpuset_by_depth(hwloc_topology_t topology, hwloc_con
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_const_cpuset_t set,
hwloc_obj_type_t type, hwloc_obj_t prev)
hwloc_obj_type_t type, hwloc_obj_t prev)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -369,9 +369,9 @@ hwloc_get_next_obj_covering_cpuset_by_type(hwloc_topology_t topology, hwloc_cons
/** \brief Returns the ancestor object of \p obj at depth \p depth. */
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
@ -516,7 +574,7 @@ hwloc_obj_type_is_icache(hwloc_obj_type_t type)
*/
static __hwloc_inline int
hwloc_get_cache_type_depth (hwloc_topology_t topology,
unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
unsigned cachelevel, hwloc_obj_cache_type_t cachetype)
{
int depth;
int found = HWLOC_TYPE_DEPTH_UNKNOWN;
@ -529,7 +587,7 @@ hwloc_get_cache_type_depth (hwloc_topology_t topology,
continue;
if (cachetype == (hwloc_obj_cache_type_t) -1) {
if (found != HWLOC_TYPE_DEPTH_UNKNOWN) {
/* second match, return MULTIPLE */
/* second match, return MULTIPLE */
return HWLOC_TYPE_DEPTH_MULTIPLE;
}
/* first match, mark it as found */
@ -666,12 +724,12 @@ HWLOC_DECLSPEC unsigned hwloc_get_closest_objs (hwloc_topology_t topology, hwloc
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_below_by_type (hwloc_topology_t topology,
hwloc_obj_type_t type1, unsigned idx1,
hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
hwloc_obj_type_t type1, unsigned idx1,
hwloc_obj_type_t type2, unsigned idx2) __hwloc_attribute_pure;
static __hwloc_inline hwloc_obj_t
hwloc_get_obj_below_by_type (hwloc_topology_t topology,
hwloc_obj_type_t type1, unsigned idx1,
hwloc_obj_type_t type2, unsigned idx2)
hwloc_obj_type_t type1, unsigned idx1,
hwloc_obj_type_t type2, unsigned idx2)
{
hwloc_obj_t obj;
obj = hwloc_get_obj_by_type (topology, type1, idx1);
@ -755,10 +813,10 @@ enum hwloc_distrib_flags_e {
*/
static __hwloc_inline int
hwloc_distrib(hwloc_topology_t topology,
hwloc_obj_t *roots, unsigned n_roots,
hwloc_cpuset_t *set,
unsigned n,
unsigned until, unsigned long flags)
hwloc_obj_t *roots, unsigned n_roots,
hwloc_cpuset_t *set,
unsigned n,
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.
@ -788,17 +849,17 @@ hwloc_distrib(hwloc_topology_t topology,
if (!root->arity || chunk <= 1 || root->depth >= until) {
/* We can't split any more, put everything there. */
if (chunk) {
/* Fill cpusets with ours */
unsigned j;
for (j=0; j < chunk; j++)
cpusetp[j] = hwloc_bitmap_dup(cpuset);
/* Fill cpusets with ours */
unsigned j;
for (j=0; j < chunk; j++)
cpusetp[j] = hwloc_bitmap_dup(cpuset);
} else {
/* We got no chunk, just merge our cpuset to a previous one
* (the first chunk cannot be empty)
* so that this root doesn't get ignored.
*/
assert(given);
hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
/* We got no chunk, just merge our cpuset to a previous one
* (the first chunk cannot be empty)
* so that this root doesn't get ignored.
*/
assert(given);
hwloc_bitmap_or(cpusetp[-1], cpusetp[-1], cpuset);
}
} else {
/* Still more to distribute, recurse into children */
@ -819,20 +880,18 @@ hwloc_distrib(hwloc_topology_t topology,
/** \defgroup hwlocality_helper_topology_sets CPU and node sets of entire topologies
* @{
*/
/** \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,15 +990,17 @@ 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);
hwloc_obj_t obj = NULL;
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);
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj = NULL;
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)
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,18 +1011,20 @@ 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);
hwloc_obj_t obj = NULL;
assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
hwloc_bitmap_zero(_cpuset);
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);
}
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t obj = NULL;
assert(depth != HWLOC_TYPE_DEPTH_UNKNOWN);
hwloc_bitmap_zero(_cpuset);
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 */
if (hwloc_bitmap_or(_cpuset, _cpuset, obj->cpuset) < 0)
return -1;
}
return 0;
}
/** @} */
@ -976,12 +1038,17 @@ hwloc_cpuset_from_nodeset(hwloc_topology_t topology, hwloc_cpuset_t _cpuset, hwl
/** \brief Get the first non-I/O ancestor object.
*
* 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,
hwloc_obj_t ioobj)
hwloc_obj_t ioobj)
{
hwloc_obj_t obj = ioobj;
while (obj && !obj->cpuset) {
@ -1005,14 +1072,14 @@ hwloc_get_next_pcidev(hwloc_topology_t topology, hwloc_obj_t prev)
*/
static __hwloc_inline hwloc_obj_t
hwloc_get_pcidev_by_busid(hwloc_topology_t topology,
unsigned domain, unsigned bus, unsigned dev, unsigned func)
unsigned domain, unsigned bus, unsigned dev, unsigned func)
{
hwloc_obj_t obj = NULL;
while ((obj = hwloc_get_next_pcidev(topology, obj)) != NULL) {
if (obj->attr->pcidev.domain == domain
&& obj->attr->pcidev.bus == bus
&& obj->attr->pcidev.dev == dev
&& obj->attr->pcidev.func == func)
&& obj->attr->pcidev.bus == bus
&& obj->attr->pcidev.dev == dev
&& obj->attr->pcidev.func == func)
return obj;
}
return NULL;
@ -1060,7 +1127,7 @@ hwloc_get_next_bridge(hwloc_topology_t topology, hwloc_obj_t prev)
*/
static __hwloc_inline int
hwloc_bridge_covers_pcibus(hwloc_obj_t bridge,
unsigned domain, unsigned bus)
unsigned domain, unsigned bus)
{
return bridge->type == HWLOC_OBJ_BRIDGE
&& bridge->attr->bridge.downstream_type == HWLOC_OBJ_BRIDGE_PCI

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

@ -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);
@ -93,7 +93,7 @@ hwloc_get_next_obj_by_depth (hwloc_topology_t topology, unsigned depth, hwloc_ob
static __hwloc_inline hwloc_obj_t
hwloc_get_next_obj_by_type (hwloc_topology_t topology, hwloc_obj_type_t type,
hwloc_obj_t prev)
hwloc_obj_t prev)
{
int depth = hwloc_get_type_depth(topology, type);
if (depth == HWLOC_TYPE_DEPTH_UNKNOWN || depth == HWLOC_TYPE_DEPTH_MULTIPLE)
@ -111,9 +111,11 @@ static __hwloc_inline const char *
hwloc_obj_get_info_by_name(hwloc_obj_t obj, const char *name)
{
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 */

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

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

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

@ -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.
*/
@ -52,7 +52,7 @@ extern "C" {
*/
static __hwloc_inline int
hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpuset_t cpuset,
unsigned long *mask, unsigned long *maxnode)
unsigned long *mask, unsigned long *maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1;
@ -86,7 +86,7 @@ hwloc_cpuset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_cpus
*/
static __hwloc_inline int
hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nodeset_t nodeset,
unsigned long *mask, unsigned long *maxnode)
unsigned long *mask, unsigned long *maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
unsigned long outmaxnode = -1;
@ -121,14 +121,14 @@ hwloc_nodeset_to_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_const_nod
*/
static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const unsigned long *mask, unsigned long maxnode)
const unsigned long *mask, unsigned long maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(cpuset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_or(cpuset, cpuset, node->cpuset);
return 0;
}
@ -144,14 +144,14 @@ hwloc_cpuset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_cpuset_t
*/
static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_ulongs(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const unsigned long *mask, unsigned long maxnode)
const unsigned long *mask, unsigned long maxnode)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
hwloc_bitmap_zero(nodeset);
while ((node = hwloc_get_next_obj_by_depth(topology, depth, node)) != NULL)
if (node->os_index < maxnode
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
&& (mask[node->os_index/sizeof(*mask)/8] & (1UL << (node->os_index % (sizeof(*mask)*8)))))
hwloc_bitmap_set(nodeset, node->os_index);
return 0;
}
@ -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;
}
@ -233,7 +233,7 @@ hwloc_nodeset_to_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_const_no
*/
static __hwloc_inline int
hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_t cpuset,
const struct bitmask *bitmask)
const struct bitmask *bitmask)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;
@ -251,7 +251,7 @@ hwloc_cpuset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_cpuset_
*/
static __hwloc_inline int
hwloc_nodeset_from_linux_libnuma_bitmask(hwloc_topology_t topology, hwloc_nodeset_t nodeset,
const struct bitmask *bitmask)
const struct bitmask *bitmask)
{
int depth = hwloc_get_type_depth(topology, HWLOC_OBJ_NUMANODE);
hwloc_obj_t node = NULL;

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

@ -54,7 +54,7 @@ extern "C" {
*/
static __hwloc_inline int
hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
nvmlDevice_t device, hwloc_cpuset_t set)
nvmlDevice_t device, hwloc_cpuset_t set)
{
#ifdef HWLOC_LINUX_SYS
/* If we're on Linux, use the sysfs mechanism to get the local cpus */
@ -101,12 +101,12 @@ hwloc_nvml_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
{
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_GPU == osdev->attr->osdev.type
&& osdev->name
&& !strncmp("nvml", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
&& !strncmp("nvml", osdev->name, 4)
&& atoi(osdev->name + 4) == (int) idx)
return osdev;
}
return NULL;
@ -128,46 +128,46 @@ hwloc_nvml_get_device_osdev_by_index(hwloc_topology_t topology, unsigned idx)
static __hwloc_inline hwloc_obj_t
hwloc_nvml_get_device_osdev(hwloc_topology_t topology, nvmlDevice_t device)
{
hwloc_obj_t osdev;
nvmlReturn_t nvres;
nvmlPciInfo_t pci;
char uuid[64];
hwloc_obj_t osdev;
nvmlReturn_t nvres;
nvmlPciInfo_t pci;
char uuid[64];
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return NULL;
}
nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres)
return NULL;
nvres = nvmlDeviceGetPciInfo(device, &pci);
if (NVML_SUCCESS != nvres)
return NULL;
nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
if (NVML_SUCCESS != nvres)
uuid[0] = '\0';
nvres = nvmlDeviceGetUUID(device, uuid, sizeof(uuid));
if (NVML_SUCCESS != nvres)
uuid[0] = '\0';
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
const char *info;
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
const char *info;
if (strncmp(osdev->name, "nvml", 4))
continue;
if (strncmp(osdev->name, "nvml", 4))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.domain
&& pcidev->attr->pcidev.bus == pci.bus
&& pcidev->attr->pcidev.dev == pci.device
&& pcidev->attr->pcidev.func == 0)
return osdev;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == pci.domain
&& pcidev->attr->pcidev.bus == pci.bus
&& pcidev->attr->pcidev.dev == pci.device
&& pcidev->attr->pcidev.func == 0)
return osdev;
info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
if (info && !strcmp(info, uuid))
return osdev;
}
info = hwloc_obj_get_info_by_name(osdev, "NVIDIAUUID");
if (info && !strcmp(info, uuid))
return osdev;
}
return NULL;
return 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.
*/
@ -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>
@ -62,39 +67,39 @@ extern "C" {
*/
static __hwloc_inline int
hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused,
hwloc_cpuset_t set)
cl_device_id device __hwloc_attribute_unused,
hwloc_cpuset_t set)
{
#if (defined HWLOC_LINUX_SYS) && (defined CL_DEVICE_TOPOLOGY_AMD)
/* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */
/* If we're on Linux + AMD OpenCL, use the AMD extension + the sysfs mechanism to get the local cpus */
#define HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX 128
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
cl_device_topology_amd amdtopo;
cl_int clret;
char path[HWLOC_OPENCL_DEVICE_SYSFS_PATH_MAX];
cl_device_topology_amd amdtopo;
cl_int clret;
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
if (!hwloc_topology_is_thissystem(topology)) {
errno = EINVAL;
return -1;
}
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
return 0;
}
sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus",
(unsigned) amdtopo.pcie.bus, (unsigned) amdtopo.pcie.device, (unsigned) amdtopo.pcie.function);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
sprintf(path, "/sys/bus/pci/devices/0000:%02x:%02x.%01x/local_cpus",
(unsigned) amdtopo.pcie.bus, (unsigned) amdtopo.pcie.device, (unsigned) amdtopo.pcie.function);
if (hwloc_linux_read_path_as_cpumask(path, set) < 0
|| hwloc_bitmap_iszero(set))
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#else
/* Non-Linux + AMD OpenCL systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
/* Non-Linux + AMD OpenCL systems simply get a full cpuset */
hwloc_bitmap_copy(set, hwloc_topology_get_complete_cpuset(topology));
#endif
return 0;
}
@ -116,24 +121,29 @@ hwloc_opencl_get_device_cpuset(hwloc_topology_t topology __hwloc_attribute_unuse
*/
static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
unsigned platform_index, unsigned device_index)
unsigned platform_index, unsigned device_index)
{
unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
unsigned x = (unsigned) -1, y = (unsigned) -1;
hwloc_obj_t osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
if (HWLOC_OBJ_OSDEV_COPROC == osdev->attr->osdev.type
&& osdev->name
&& sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
&& platform_index == x && device_index == y)
&& sscanf(osdev->name, "opencl%ud%u", &x, &y) == 2
&& platform_index == x && device_index == y)
return osdev;
}
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.
@ -147,41 +157,41 @@ hwloc_opencl_get_device_osdev_by_index(hwloc_topology_t topology,
*/
static __hwloc_inline hwloc_obj_t
hwloc_opencl_get_device_osdev(hwloc_topology_t topology __hwloc_attribute_unused,
cl_device_id device __hwloc_attribute_unused)
cl_device_id device __hwloc_attribute_unused)
{
#ifdef CL_DEVICE_TOPOLOGY_AMD
hwloc_obj_t osdev;
cl_device_topology_amd amdtopo;
cl_int clret;
hwloc_obj_t osdev;
cl_device_topology_amd amdtopo;
cl_int clret;
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
errno = EINVAL;
return NULL;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
errno = EINVAL;
return NULL;
}
clret = clGetDeviceInfo(device, CL_DEVICE_TOPOLOGY_AMD, sizeof(amdtopo), &amdtopo, NULL);
if (CL_SUCCESS != clret) {
errno = EINVAL;
return NULL;
}
if (CL_DEVICE_TOPOLOGY_TYPE_PCIE_AMD != amdtopo.raw.type) {
errno = EINVAL;
return NULL;
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "opencl", 6))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == 0
&& pcidev->attr->pcidev.bus == amdtopo.pcie.bus
&& pcidev->attr->pcidev.dev == amdtopo.pcie.device
&& pcidev->attr->pcidev.func == amdtopo.pcie.function)
return osdev;
/* if PCI are filtered out, we need a info attr to match on */
}
osdev = NULL;
while ((osdev = hwloc_get_next_osdev(topology, osdev)) != NULL) {
hwloc_obj_t pcidev = osdev->parent;
if (strncmp(osdev->name, "opencl", 6))
continue;
if (pcidev
&& pcidev->type == HWLOC_OBJ_PCI_DEVICE
&& pcidev->attr->pcidev.domain == 0
&& pcidev->attr->pcidev.bus == amdtopo.pcie.bus
&& pcidev->attr->pcidev.dev == amdtopo.pcie.device
&& pcidev->attr->pcidev.func == amdtopo.pcie.function)
return osdev;
/* if PCI are filtered out, we need a info attr to match on */
}
return NULL;
return NULL;
#else
return NULL;
return NULL;
#endif
}

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

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

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

@ -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.
*
@ -356,7 +367,7 @@ hwloc_plugin_check_namespace(const char *pluginname __hwloc_attribute_unused, co
}
if (verboseenv_value)
fprintf(stderr, "Plugin `%s' disabling itself because it cannot find the `%s' core symbol.\n",
pluginname, symbol);
pluginname, symbol);
return -1;
}
#endif /* HWLOC_INSIDE_PLUGIN */
@ -381,12 +392,12 @@ hwloc_filter_check_pcidev_subtype_important(unsigned classid)
{
unsigned baseclass = classid >> 8;
return (baseclass == 0x03 /* PCI_BASE_CLASS_DISPLAY */
|| baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
|| baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
|| baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|| baseclass == 0x12 /* Processing Accelerators */);
|| baseclass == 0x02 /* PCI_BASE_CLASS_NETWORK */
|| baseclass == 0x01 /* PCI_BASE_CLASS_STORAGE */
|| baseclass == 0x0b /* PCI_BASE_CLASS_PROCESSOR */
|| classid == 0x0c04 /* PCI_CLASS_SERIAL_FIBER */
|| classid == 0x0c06 /* PCI_CLASS_SERIAL_INFINIBAND */
|| baseclass == 0x12 /* Processing Accelerators */);
}
/** \brief Check whether the given OS device subtype is important.

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

@ -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,
@ -51,8 +51,8 @@ extern "C" {
* \note Flags \p flags are currently unused, must be 0.
*/
HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology,
size_t *lengthp,
unsigned long flags);
size_t *lengthp,
unsigned long flags);
/** \brief Duplicate a topology to a shared memory file.
*
@ -80,9 +80,9 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_get_length(hwloc_topology_t topology,
* or \p length aren't page-aligned.
*/
HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags);
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags);
/** \brief Adopt a shared memory topology stored in a file.
*
@ -110,15 +110,22 @@ HWLOC_DECLSPEC int hwloc_shmem_topology_write(hwloc_topology_t topology,
* that created the shared topology also placed userdata-pointed buffers
* 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,
void *mmap_address, size_t length,
unsigned long flags);
int fd, hwloc_uint64_t fileoffset,
void *mmap_address, size_t length,
unsigned long flags);
/** @} */

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