/* * 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 #include #include #include #include #define NETLOCFILE_VERSION 1 #ifdef NETLOC_SCOTCH #include #include #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_