578 lines
16 KiB
C
578 lines
16 KiB
C
/*
|
|
* Copyright © 2014 Cisco Systems, Inc. All rights reserved.
|
|
* Copyright © 2013-2014 University of Wisconsin-La Crosse.
|
|
* All rights reserved.
|
|
* Copyright © 2015-2017 Inria. All rights reserved.
|
|
*
|
|
* $COPYRIGHT$
|
|
*
|
|
* Additional copyrights may follow
|
|
* See COPYING in top-level directory.
|
|
*
|
|
* $HEADER$
|
|
*/
|
|
|
|
#ifndef _NETLOC_PRIVATE_H_
|
|
#define _NETLOC_PRIVATE_H_
|
|
|
|
#include <hwloc.h>
|
|
#include <netloc.h>
|
|
#include <netloc/uthash.h>
|
|
#include <netloc/utarray.h>
|
|
#include <private/autogen/config.h>
|
|
|
|
#define NETLOCFILE_VERSION 1
|
|
|
|
#ifdef NETLOC_SCOTCH
|
|
#include <stdint.h>
|
|
#include <scotch.h>
|
|
#define NETLOC_int SCOTCH_Num
|
|
#else
|
|
#define NETLOC_int int
|
|
#endif
|
|
|
|
/*
|
|
* "Import" a few things from hwloc
|
|
*/
|
|
#define __netloc_attribute_unused __hwloc_attribute_unused
|
|
#define __netloc_attribute_malloc __hwloc_attribute_malloc
|
|
#define __netloc_attribute_const __hwloc_attribute_const
|
|
#define __netloc_attribute_pure __hwloc_attribute_pure
|
|
#define __netloc_attribute_deprecated __hwloc_attribute_deprecated
|
|
#define __netloc_attribute_may_alias __hwloc_attribute_may_alias
|
|
#define NETLOC_DECLSPEC HWLOC_DECLSPEC
|
|
|
|
|
|
/**********************************************************************
|
|
* Types
|
|
**********************************************************************/
|
|
|
|
/**
|
|
* Definitions for Comparators
|
|
* \sa These are the return values from the following functions:
|
|
* netloc_network_compare, netloc_dt_edge_t_compare, netloc_dt_node_t_compare
|
|
*/
|
|
typedef enum {
|
|
NETLOC_CMP_SAME = 0, /**< Compared as the Same */
|
|
NETLOC_CMP_SIMILAR = -1, /**< Compared as Similar, but not the Same */
|
|
NETLOC_CMP_DIFF = -2 /**< Compared as Different */
|
|
} netloc_compare_type_t;
|
|
|
|
/**
|
|
* Enumerated type for the various types of supported networks
|
|
*/
|
|
typedef enum {
|
|
NETLOC_NETWORK_TYPE_ETHERNET = 1, /**< Ethernet network */
|
|
NETLOC_NETWORK_TYPE_INFINIBAND = 2, /**< InfiniBand network */
|
|
NETLOC_NETWORK_TYPE_INVALID = 3 /**< Invalid network */
|
|
} netloc_network_type_t;
|
|
|
|
/**
|
|
* Enumerated type for the various types of supported topologies
|
|
*/
|
|
typedef enum {
|
|
NETLOC_TOPOLOGY_TYPE_INVALID = -1, /**< Invalid */
|
|
NETLOC_TOPOLOGY_TYPE_TREE = 1, /**< Tree */
|
|
} netloc_topology_type_t;
|
|
|
|
/**
|
|
* Enumerated type for the various types of nodes
|
|
*/
|
|
typedef enum {
|
|
NETLOC_NODE_TYPE_HOST = 0, /**< Host (a.k.a., network addressable endpoint - e.g., MAC Address) node */
|
|
NETLOC_NODE_TYPE_SWITCH = 1, /**< Switch node */
|
|
NETLOC_NODE_TYPE_INVALID = 2 /**< Invalid node */
|
|
} netloc_node_type_t;
|
|
|
|
typedef enum {
|
|
NETLOC_ARCH_TREE = 0, /* Fat tree */
|
|
} netloc_arch_type_t;
|
|
|
|
|
|
/* Pre declarations to avoid inter dependency problems */
|
|
/** \cond IGNORE */
|
|
struct netloc_topology_t;
|
|
typedef struct netloc_topology_t netloc_topology_t;
|
|
struct netloc_node_t;
|
|
typedef struct netloc_node_t netloc_node_t;
|
|
struct netloc_edge_t;
|
|
typedef struct netloc_edge_t netloc_edge_t;
|
|
struct netloc_physical_link_t;
|
|
typedef struct netloc_physical_link_t netloc_physical_link_t;
|
|
struct netloc_path_t;
|
|
typedef struct netloc_path_t netloc_path_t;
|
|
|
|
struct netloc_arch_tree_t;
|
|
typedef struct netloc_arch_tree_t netloc_arch_tree_t;
|
|
struct netloc_arch_node_t;
|
|
typedef struct netloc_arch_node_t netloc_arch_node_t;
|
|
struct netloc_arch_node_slot_t;
|
|
typedef struct netloc_arch_node_slot_t netloc_arch_node_slot_t;
|
|
struct netloc_arch_t;
|
|
typedef struct netloc_arch_t netloc_arch_t;
|
|
/** \endcond */
|
|
|
|
/**
|
|
* \struct netloc_topology_t
|
|
* \brief Netloc Topology Context
|
|
*
|
|
* An opaque data structure used to reference a network topology.
|
|
*
|
|
* \note Must be initialized with \ref netloc_topology_construct()
|
|
*/
|
|
struct netloc_topology_t {
|
|
/** Topology path */
|
|
char *topopath;
|
|
/** Subnet ID */
|
|
char *subnet_id;
|
|
|
|
/** Node List */
|
|
netloc_node_t *nodes; /* Hash table of nodes by physical_id */
|
|
netloc_node_t *nodesByHostname; /* Hash table of nodes by hostname */
|
|
|
|
netloc_physical_link_t *physical_links; /* Hash table with physcial links */
|
|
|
|
/** Partition List */
|
|
UT_array *partitions;
|
|
|
|
/** Hwloc topology List */
|
|
char *hwlocpath;
|
|
UT_array *topos;
|
|
hwloc_topology_t *hwloc_topos;
|
|
|
|
/** Type of the graph */
|
|
netloc_topology_type_t type;
|
|
};
|
|
|
|
/**
|
|
* \brief Netloc Node Type
|
|
*
|
|
* Represents the concept of a node (a.k.a., vertex, endpoint) within a network
|
|
* graph. This could be a server or a network switch. The \ref node_type parameter
|
|
* will distinguish the exact type of node this represents in the graph.
|
|
*/
|
|
struct netloc_node_t {
|
|
UT_hash_handle hh; /* makes this structure hashable with physical_id */
|
|
UT_hash_handle hh2; /* makes this structure hashable with hostname */
|
|
|
|
/** Physical ID of the node */
|
|
char physical_id[20];
|
|
|
|
/** Logical ID of the node (if any) */
|
|
int logical_id;
|
|
|
|
/** Type of the node */
|
|
netloc_node_type_t type;
|
|
|
|
/* Pointer to physical_links */
|
|
UT_array *physical_links;
|
|
|
|
/** Description information from discovery (if any) */
|
|
char *description;
|
|
|
|
/**
|
|
* Application-given private data pointer.
|
|
* Initialized to NULL, and not used by the netloc library.
|
|
*/
|
|
void * userdata;
|
|
|
|
/** Outgoing edges from this node */
|
|
netloc_edge_t *edges;
|
|
|
|
UT_array *subnodes; /* the group of nodes for the virtual nodes */
|
|
|
|
netloc_path_t *paths;
|
|
|
|
char *hostname;
|
|
|
|
UT_array *partitions; /* index in the list from the topology */
|
|
|
|
hwloc_topology_t hwlocTopo;
|
|
int hwlocTopoIdx;
|
|
};
|
|
|
|
/**
|
|
* \brief Netloc Edge Type
|
|
*
|
|
* Represents the concept of a directed edge within a network graph.
|
|
*
|
|
* \note We do not point to the netloc_node_t structure directly to
|
|
* simplify the representation, and allow the information to more easily
|
|
* be entered into the data store without circular references.
|
|
* \todo JJH Is the note above still true?
|
|
*/
|
|
struct netloc_edge_t {
|
|
UT_hash_handle hh; /* makes this structure hashable */
|
|
|
|
netloc_node_t *dest;
|
|
|
|
int id;
|
|
|
|
/** Pointers to the parent node */
|
|
netloc_node_t *node;
|
|
|
|
/* Pointer to physical_links */
|
|
UT_array *physical_links;
|
|
|
|
/** total gbits of the links */
|
|
float total_gbits;
|
|
|
|
UT_array *partitions; /* index in the list from the topology */
|
|
|
|
UT_array *subnode_edges; /* for edges going to virtual nodes */
|
|
|
|
struct netloc_edge_t *other_way;
|
|
|
|
/**
|
|
* Application-given private data pointer.
|
|
* Initialized to NULL, and not used by the netloc library.
|
|
*/
|
|
void * userdata;
|
|
};
|
|
|
|
|
|
struct netloc_physical_link_t {
|
|
UT_hash_handle hh; /* makes this structure hashable */
|
|
|
|
int id; // TODO long long
|
|
netloc_node_t *src;
|
|
netloc_node_t *dest;
|
|
int ports[2];
|
|
char *width;
|
|
char *speed;
|
|
|
|
netloc_edge_t *edge;
|
|
|
|
int other_way_id;
|
|
struct netloc_physical_link_t *other_way;
|
|
|
|
UT_array *partitions; /* index in the list from the topology */
|
|
|
|
/** gbits of the link from speed and width */
|
|
float gbits;
|
|
|
|
/** Description information from discovery (if any) */
|
|
char *description;
|
|
};
|
|
|
|
struct netloc_path_t {
|
|
UT_hash_handle hh; /* makes this structure hashable */
|
|
char dest_id[20];
|
|
UT_array *links;
|
|
};
|
|
|
|
|
|
/**********************************************************************
|
|
* Architecture structures
|
|
**********************************************************************/
|
|
struct netloc_arch_tree_t {
|
|
NETLOC_int num_levels;
|
|
NETLOC_int *degrees;
|
|
NETLOC_int *cost;
|
|
};
|
|
|
|
struct netloc_arch_node_t {
|
|
UT_hash_handle hh; /* makes this structure hashable */
|
|
char *name; /* Hash key */
|
|
netloc_node_t *node; /* Corresponding node */
|
|
int idx_in_topo; /* idx with ghost hosts to have complete topo */
|
|
int num_slots; /* it is not the real number of slots but the maximum slot idx */
|
|
int *slot_idx; /* corresponding idx in slot_tree */
|
|
int *slot_os_idx; /* corresponding os index for each leaf in tree */
|
|
netloc_arch_tree_t *slot_tree; /* Tree built from hwloc */
|
|
int num_current_slots; /* Number of PUs */
|
|
NETLOC_int *current_slots; /* indices in the complete tree */
|
|
int *slot_ranks; /* corresponding MPI rank for each leaf in tree */
|
|
};
|
|
|
|
struct netloc_arch_node_slot_t {
|
|
netloc_arch_node_t *node;
|
|
int slot;
|
|
};
|
|
|
|
struct netloc_arch_t {
|
|
netloc_topology_t *topology;
|
|
int has_slots; /* if slots are included in the architecture */
|
|
netloc_arch_type_t type;
|
|
union {
|
|
netloc_arch_tree_t *node_tree;
|
|
netloc_arch_tree_t *global_tree;
|
|
} arch;
|
|
netloc_arch_node_t *nodes_by_name;
|
|
netloc_arch_node_slot_t *node_slot_by_idx; /* node_slot by index in complete topo */
|
|
NETLOC_int num_current_hosts; /* if has_slots, host is a slot, else host is a node */
|
|
NETLOC_int *current_hosts; /* indices in the complete topology */
|
|
};
|
|
|
|
/**********************************************************************
|
|
* Topology Functions
|
|
**********************************************************************/
|
|
/**
|
|
* Allocate a topology handle.
|
|
*
|
|
* User is responsible for calling \ref netloc_detach on the topology handle.
|
|
* The network parameter information is deep copied into the topology handle, so the
|
|
* user may destruct the network handle after calling this function and/or reuse
|
|
* the network handle.
|
|
*
|
|
* \returns NETLOC_SUCCESS on success
|
|
* \returns NETLOC_ERROR upon an error.
|
|
*/
|
|
netloc_topology_t *netloc_topology_construct(char *path);
|
|
|
|
/**
|
|
* Destruct a topology handle
|
|
*
|
|
* \param topology A valid pointer to a \ref netloc_topology_t handle created
|
|
* from a prior call to \ref netloc_topology_construct.
|
|
*
|
|
* \returns NETLOC_SUCCESS on success
|
|
* \returns NETLOC_ERROR upon an error.
|
|
*/
|
|
int netloc_topology_destruct(netloc_topology_t *topology);
|
|
|
|
int netloc_topology_find_partition_idx(netloc_topology_t *topology, char *partition_name);
|
|
|
|
int netloc_topology_read_hwloc(netloc_topology_t *topology, int num_nodes,
|
|
netloc_node_t **node_list);
|
|
|
|
#define netloc_topology_iter_partitions(topology,partition) \
|
|
for ((partition) = (char **)utarray_front(topology->partitions); \
|
|
(partition) != NULL; \
|
|
(partition) = (char **)utarray_next(topology->partitions, partition))
|
|
|
|
#define netloc_topology_iter_hwloctopos(topology,hwloctopo) \
|
|
for ((hwloctopo) = (char **)utarray_front(topology->topos); \
|
|
(hwloctopo) != NULL; \
|
|
(hwloctopo) = (char **)utarray_next(topology->topos, hwloctopo))
|
|
|
|
#define netloc_topology_find_node(topology,node_id,node) \
|
|
HASH_FIND_STR(topology->nodes, node_id, node)
|
|
|
|
#define netloc_topology_iter_nodes(topology,node,_tmp) \
|
|
HASH_ITER(hh, topology->nodes, node, _tmp)
|
|
|
|
#define netloc_topology_num_nodes(topology) \
|
|
HASH_COUNT(topology->nodes)
|
|
|
|
/*************************************************/
|
|
|
|
|
|
/**
|
|
* Constructor for netloc_node_t
|
|
*
|
|
* User is responsible for calling the destructor on the handle.
|
|
*
|
|
* Returns
|
|
* A newly allocated pointer to the network information.
|
|
*/
|
|
netloc_node_t *netloc_node_construct(void);
|
|
|
|
/**
|
|
* Destructor for netloc_node_t
|
|
*
|
|
* \param node A valid node handle
|
|
*
|
|
* Returns
|
|
* NETLOC_SUCCESS on success
|
|
* NETLOC_ERROR on error
|
|
*/
|
|
int netloc_node_destruct(netloc_node_t *node);
|
|
|
|
char *netloc_node_pretty_print(netloc_node_t* node);
|
|
|
|
#define netloc_node_get_num_subnodes(node) \
|
|
utarray_len((node)->subnodes)
|
|
|
|
#define netloc_node_get_subnode(node,i) \
|
|
(*(netloc_node_t **)utarray_eltptr((node)->subnodes, (i)))
|
|
|
|
#define netloc_node_get_num_edges(node) \
|
|
utarray_len((node)->edges)
|
|
|
|
#define netloc_node_get_edge(node,i) \
|
|
(*(netloc_edge_t **)utarray_eltptr((node)->edges, (i)))
|
|
|
|
#define netloc_node_iter_edges(node,edge,_tmp) \
|
|
HASH_ITER(hh, node->edges, edge, _tmp)
|
|
|
|
#define netloc_node_iter_paths(node,path,_tmp) \
|
|
HASH_ITER(hh, node->paths, path, _tmp)
|
|
|
|
#define netloc_node_is_host(node) \
|
|
(node->type == NETLOC_NODE_TYPE_HOST)
|
|
|
|
#define netloc_node_is_switch(node) \
|
|
(node->type == NETLOC_NODE_TYPE_SWITCH)
|
|
|
|
#define netloc_node_iter_paths(node, path,_tmp) \
|
|
HASH_ITER(hh, node->paths, path, _tmp)
|
|
|
|
int netloc_node_is_in_partition(netloc_node_t *node, int partition);
|
|
|
|
/*************************************************/
|
|
|
|
|
|
/**
|
|
* Constructor for netloc_edge_t
|
|
*
|
|
* User is responsible for calling the destructor on the handle.
|
|
*
|
|
* Returns
|
|
* A newly allocated pointer to the edge information.
|
|
*/
|
|
netloc_edge_t *netloc_edge_construct(void);
|
|
|
|
/**
|
|
* Destructor for netloc_edge_t
|
|
*
|
|
* \param edge A valid edge handle
|
|
*
|
|
* Returns
|
|
* NETLOC_SUCCESS on success
|
|
* NETLOC_ERROR on error
|
|
*/
|
|
int netloc_edge_destruct(netloc_edge_t *edge);
|
|
|
|
char * netloc_edge_pretty_print(netloc_edge_t* edge);
|
|
|
|
void netloc_edge_reset_uid(void);
|
|
|
|
int netloc_edge_is_in_partition(netloc_edge_t *edge, int partition);
|
|
|
|
#define netloc_edge_get_num_links(edge) \
|
|
utarray_len((edge)->physical_links)
|
|
|
|
#define netloc_edge_get_link(edge,i) \
|
|
(*(netloc_physical_link_t **)utarray_eltptr((edge)->physical_links, (i)))
|
|
|
|
#define netloc_edge_get_num_subedges(edge) \
|
|
utarray_len((edge)->subnode_edges)
|
|
|
|
#define netloc_edge_get_subedge(edge,i) \
|
|
(*(netloc_edge_t **)utarray_eltptr((edge)->subnode_edges, (i)))
|
|
|
|
/*************************************************/
|
|
|
|
|
|
/**
|
|
* Constructor for netloc_physical_link_t
|
|
*
|
|
* User is responsible for calling the destructor on the handle.
|
|
*
|
|
* Returns
|
|
* A newly allocated pointer to the physical link information.
|
|
*/
|
|
netloc_physical_link_t * netloc_physical_link_construct(void);
|
|
|
|
/**
|
|
* Destructor for netloc_physical_link_t
|
|
*
|
|
* Returns
|
|
* NETLOC_SUCCESS on success
|
|
* NETLOC_ERROR on error
|
|
*/
|
|
int netloc_physical_link_destruct(netloc_physical_link_t *link);
|
|
|
|
char * netloc_link_pretty_print(netloc_physical_link_t* link);
|
|
|
|
/*************************************************/
|
|
|
|
|
|
netloc_path_t *netloc_path_construct(void);
|
|
int netloc_path_destruct(netloc_path_t *path);
|
|
|
|
|
|
/**********************************************************************
|
|
* Architecture functions
|
|
**********************************************************************/
|
|
|
|
netloc_arch_t * netloc_arch_construct(void);
|
|
|
|
int netloc_arch_destruct(netloc_arch_t *arch);
|
|
|
|
int netloc_arch_build(netloc_arch_t *arch, int add_slots);
|
|
|
|
int netloc_arch_set_current_resources(netloc_arch_t *arch);
|
|
|
|
int netloc_arch_set_global_resources(netloc_arch_t *arch);
|
|
|
|
int netloc_arch_node_get_hwloc_info(netloc_arch_node_t *arch);
|
|
|
|
void netloc_arch_tree_complete(netloc_arch_tree_t *tree, UT_array **down_degrees_by_level,
|
|
int num_hosts, int **parch_idx);
|
|
|
|
NETLOC_int netloc_arch_tree_num_leaves(netloc_arch_tree_t *tree);
|
|
|
|
|
|
/**********************************************************************
|
|
* Access functions of various elements of the topology
|
|
**********************************************************************/
|
|
|
|
#define netloc_get_num_partitions(object) \
|
|
utarray_len((object)->partitions)
|
|
|
|
#define netloc_get_partition(object,i) \
|
|
(*(int *)utarray_eltptr((object)->partitions, (i)))
|
|
|
|
|
|
#define netloc_path_iter_links(path,link) \
|
|
for ((link) = (netloc_physical_link_t **)utarray_front(path->links); \
|
|
(link) != NULL; \
|
|
(link) = (netloc_physical_link_t **)utarray_next(path->links, link))
|
|
|
|
/**********************************************************************
|
|
* Misc functions
|
|
**********************************************************************/
|
|
|
|
/**
|
|
* Decode the network type
|
|
*
|
|
* \param net_type A valid member of the \ref netloc_network_type_t type
|
|
*
|
|
* \returns NULL if the type is invalid
|
|
* \returns A string for that \ref netloc_network_type_t type
|
|
*/
|
|
static inline const char * netloc_network_type_decode(netloc_network_type_t net_type) {
|
|
if( NETLOC_NETWORK_TYPE_ETHERNET == net_type ) {
|
|
return "ETH";
|
|
}
|
|
else if( NETLOC_NETWORK_TYPE_INFINIBAND == net_type ) {
|
|
return "IB";
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Decode the node type
|
|
*
|
|
* \param node_type A valid member of the \ref netloc_node_type_t type
|
|
*
|
|
* \returns NULL if the type is invalid
|
|
* \returns A string for that \ref netloc_node_type_t type
|
|
*/
|
|
static inline const char * netloc_node_type_decode(netloc_node_type_t node_type) {
|
|
if( NETLOC_NODE_TYPE_SWITCH == node_type ) {
|
|
return "SW";
|
|
}
|
|
else if( NETLOC_NODE_TYPE_HOST == node_type ) {
|
|
return "CA";
|
|
}
|
|
else {
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
ssize_t netloc_line_get(char **lineptr, size_t *n, FILE *stream);
|
|
|
|
char *netloc_line_get_next_token(char **string, char c);
|
|
|
|
int netloc_build_comm_mat(char *filename, int *pn, double ***pmat);
|
|
|
|
#define STRDUP_IF_NOT_NULL(str) (NULL == str ? NULL : strdup(str))
|
|
#define STR_EMPTY_IF_NULL(str) (NULL == str ? "" : str)
|
|
|
|
|
|
#endif // _NETLOC_PRIVATE_H_
|