Merge pull request #5213 from rhc54/topic/rte
Enable the PMIx ompi/rte component
Этот коммит содержится в:
Коммит
3020b699f3
1
.gitignore
поставляемый
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
поставляемый
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
поставляемый
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
Обычный файл
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
Обычный файл
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>
|
21
opal/mca/hwloc/hwloc201/hwloc/hwloc/hwloc2-diff.dtd
Обычный файл
21
opal/mca/hwloc/hwloc201/hwloc/hwloc/hwloc2-diff.dtd
Обычный файл
@ -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 "" >
|
63
opal/mca/hwloc/hwloc201/hwloc/hwloc/hwloc2.dtd
Обычный файл
63
opal/mca/hwloc/hwloc201/hwloc/hwloc/hwloc2.dtd
Обычный файл
@ -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
|
||||
};
|
||||
|
510
opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-solaris-chiptype.c
Обычный файл
510
opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-solaris-chiptype.c
Обычный файл
@ -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 */
|
1073
opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-solaris.c
Обычный файл
1073
opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-solaris.c
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1517
opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-synthetic.c
Обычный файл
1517
opal/mca/hwloc/hwloc201/hwloc/hwloc/topology-synthetic.c
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@ -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);
|
||||
/** @} */
|
||||
|
||||
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
x
Ссылка в новой задаче
Block a user