Move the carto framework to the trunk.
This commit was SVN r17177.
Этот коммит содержится в:
родитель
889f6c79fe
Коммит
025b68becf
@ -42,6 +42,7 @@
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/sys/atomic.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
|
||||
#include "orte/util/proc_info.h"
|
||||
#include "orte/mca/schema/schema.h"
|
||||
@ -146,6 +147,8 @@ int ompi_mpi_finalize(void)
|
||||
opal_maffinity_base_close();
|
||||
}
|
||||
|
||||
opal_carto_base_close();
|
||||
|
||||
/* wait for everyone to reach this point
|
||||
This is a grpcomm barrier instead of an MPI barrier because an
|
||||
MPI barrier doesn't ensure that all messages have been transmitted
|
||||
|
@ -39,6 +39,7 @@
|
||||
#include "opal/util/num_procs.h"
|
||||
#include "opal/runtime/opal.h"
|
||||
#include "opal/event/event.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
|
||||
#include "orte/util/sys_info.h"
|
||||
#include "orte/util/proc_info.h"
|
||||
@ -321,6 +322,16 @@ int ompi_mpi_init(int argc, char **argv, int requested, int *provided)
|
||||
}
|
||||
}
|
||||
|
||||
if (OPAL_SUCCESS != (ret = opal_carto_base_open())) {
|
||||
error = "opal_carto_base_open";
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (OPAL_SUCCESS != (ret = opal_carto_base_select())) {
|
||||
error = "opal_carto_base_select";
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* initialize datatypes. This step should be done early as it will
|
||||
* create the local convertor and local arch used in the proc
|
||||
* init.
|
||||
|
@ -36,6 +36,8 @@
|
||||
#include "opal/mca/backtrace/base/base.h"
|
||||
#include "opal/mca/paffinity/paffinity.h"
|
||||
#include "opal/mca/paffinity/base/base.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
#include "opal/mca/maffinity/maffinity.h"
|
||||
#include "opal/mca/maffinity/base/base.h"
|
||||
#include "opal/mca/memory/memory.h"
|
||||
@ -211,6 +213,9 @@ void ompi_info::open_components()
|
||||
opal_paffinity_base_open();
|
||||
component_map["paffinity"] = &opal_paffinity_base_components_opened;
|
||||
|
||||
opal_carto_base_open();
|
||||
component_map["carto"] = &opal_carto_base_components_opened;
|
||||
|
||||
opal_maffinity_base_open();
|
||||
component_map["maffinity"] = &opal_maffinity_base_components_opened;
|
||||
|
||||
@ -395,6 +400,7 @@ void ompi_info::close_components()
|
||||
opal_backtrace_base_close();
|
||||
opal_memory_base_close();
|
||||
opal_paffinity_base_close();
|
||||
opal_carto_base_close();
|
||||
opal_maffinity_base_close();
|
||||
opal_timer_base_close();
|
||||
#if OPAL_ENABLE_FT == 1
|
||||
|
@ -183,6 +183,7 @@ int main(int argc, char *argv[])
|
||||
ompi_info::mca_types.push_back("backtrace");
|
||||
ompi_info::mca_types.push_back("memory");
|
||||
ompi_info::mca_types.push_back("paffinity");
|
||||
ompi_info::mca_types.push_back("carto");
|
||||
ompi_info::mca_types.push_back("maffinity");
|
||||
ompi_info::mca_types.push_back("timer");
|
||||
ompi_info::mca_types.push_back("installdirs");
|
||||
|
@ -25,6 +25,7 @@ headers += \
|
||||
class/opal_hash_table.h \
|
||||
class/opal_list.h \
|
||||
class/opal_object.h \
|
||||
class/opal_graph.h\
|
||||
class/opal_atomic_lifo.h \
|
||||
class/opal_pointer_array.h \
|
||||
class/opal_value_array.h
|
||||
@ -34,6 +35,7 @@ libopen_pal_la_SOURCES += \
|
||||
class/opal_hash_table.c \
|
||||
class/opal_list.c \
|
||||
class/opal_object.c \
|
||||
class/opal_graph.c\
|
||||
class/opal_atomic_lifo.c \
|
||||
class/opal_pointer_array.c \
|
||||
class/opal_value_array.c
|
||||
|
883
opal/class/opal_graph.c
Исполняемый файл
883
opal/class/opal_graph.c
Исполняемый файл
@ -0,0 +1,883 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2007 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Voltaire All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/class/opal_list.h"
|
||||
#include "opal/constants.h"
|
||||
#include "opal/class/opal_graph.h"
|
||||
|
||||
|
||||
static int compare_vertex_distance(const void *item1, const void *item2);
|
||||
|
||||
/*
|
||||
* Graph classes
|
||||
*/
|
||||
|
||||
|
||||
static void opal_graph_vertex_construct(opal_graph_vertex_t *vertex);
|
||||
static void opal_graph_vertex_destruct(opal_graph_vertex_t *vertex);
|
||||
static void delete_all_edges_connected_to_vertex(opal_graph_t *graph, opal_graph_vertex_t *vertex);
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
opal_graph_vertex_t,
|
||||
opal_list_item_t,
|
||||
opal_graph_vertex_construct,
|
||||
opal_graph_vertex_destruct
|
||||
);
|
||||
|
||||
|
||||
static void opal_graph_edge_construct(opal_graph_edge_t *edge);
|
||||
static void opal_graph_edge_destruct(opal_graph_edge_t *edge);
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
opal_graph_edge_t,
|
||||
opal_list_item_t,
|
||||
opal_graph_edge_construct,
|
||||
opal_graph_edge_destruct
|
||||
);
|
||||
|
||||
static void opal_graph_construct(opal_graph_t *graph);
|
||||
static void opal_graph_destruct(opal_graph_t *graph);
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
opal_graph_t,
|
||||
opal_object_t,
|
||||
opal_graph_construct,
|
||||
opal_graph_destruct
|
||||
);
|
||||
|
||||
static void opal_adjacency_list_construct(opal_adjacency_list_t *aj_list);
|
||||
static void opal_adjacency_list_destruct(opal_adjacency_list_t *aj_list);
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
opal_adjacency_list_t,
|
||||
opal_list_item_t,
|
||||
opal_adjacency_list_construct,
|
||||
opal_adjacency_list_destruct
|
||||
);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* opal_graph_vertex_t interface
|
||||
*
|
||||
*/
|
||||
|
||||
static void opal_graph_vertex_construct(opal_graph_vertex_t *vertex)
|
||||
{
|
||||
vertex->in_adj_list = NULL;
|
||||
vertex->in_graph = NULL;
|
||||
vertex->vertex_data = NULL;
|
||||
vertex->sibling = NULL;
|
||||
vertex->copy_vertex_data = NULL;
|
||||
vertex->free_vertex_data = NULL;
|
||||
vertex->alloc_vertex_data = NULL;
|
||||
vertex->compare_vertex = NULL;
|
||||
vertex->print_vertex = NULL;
|
||||
}
|
||||
|
||||
static void opal_graph_vertex_destruct(opal_graph_vertex_t *vertex)
|
||||
{
|
||||
vertex->in_adj_list = NULL;
|
||||
vertex->in_graph = NULL;
|
||||
vertex->sibling = NULL;
|
||||
vertex->copy_vertex_data = NULL;
|
||||
vertex->alloc_vertex_data = NULL;
|
||||
vertex->compare_vertex = NULL;
|
||||
if (NULL != vertex->free_vertex_data) {
|
||||
vertex->free_vertex_data(vertex->vertex_data);
|
||||
}
|
||||
vertex->vertex_data = NULL;
|
||||
vertex->print_vertex = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* opal_graph_edge_t interface
|
||||
*
|
||||
*/
|
||||
|
||||
static void opal_graph_edge_construct(opal_graph_edge_t *edge)
|
||||
{
|
||||
edge->end = NULL;
|
||||
edge->start = NULL;
|
||||
edge->weight = 0;
|
||||
edge->in_adj_list = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void opal_graph_edge_destruct(opal_graph_edge_t *edge)
|
||||
{
|
||||
edge->end = NULL;
|
||||
edge->start = NULL;
|
||||
edge->weight = 0;
|
||||
edge->in_adj_list = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* opal_graph_t interface
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
static void opal_graph_construct(opal_graph_t *graph)
|
||||
{
|
||||
graph->adjacency_list = OBJ_NEW(opal_list_t);
|
||||
graph->number_of_vertices = 0;
|
||||
graph->number_of_edges = 0;
|
||||
}
|
||||
|
||||
static void opal_graph_destruct(opal_graph_t *graph)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
|
||||
while (false == opal_list_is_empty(graph->adjacency_list)) {
|
||||
aj_list = (opal_adjacency_list_t *)opal_list_remove_first(graph->adjacency_list);
|
||||
OBJ_RELEASE(aj_list);
|
||||
}
|
||||
OBJ_RELEASE(graph->adjacency_list);
|
||||
graph->number_of_vertices = 0;
|
||||
graph->number_of_edges = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* opal_adjacency_list interface
|
||||
*
|
||||
*/
|
||||
|
||||
static void opal_adjacency_list_construct(opal_adjacency_list_t *aj_list)
|
||||
{
|
||||
aj_list->vertex = NULL;
|
||||
aj_list->edges = OBJ_NEW(opal_list_t);
|
||||
}
|
||||
|
||||
static void opal_adjacency_list_destruct(opal_adjacency_list_t *aj_list)
|
||||
{
|
||||
opal_graph_edge_t *edge;
|
||||
|
||||
aj_list->vertex = NULL;
|
||||
while (false == opal_list_is_empty(aj_list->edges)) {
|
||||
edge = (opal_graph_edge_t *)opal_list_remove_first(aj_list->edges);
|
||||
OBJ_RELEASE(edge);
|
||||
}
|
||||
OBJ_RELEASE(aj_list->edges);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This function deletes all the edges that are connected *to* a
|
||||
* vertex.
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex
|
||||
*/
|
||||
static void delete_all_edges_conceded_to_vertex(opal_graph_t *graph, opal_graph_vertex_t *vertex)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
opal_list_item_t *aj_list_item;
|
||||
opal_graph_edge_t *edge;
|
||||
opal_list_item_t *edge_item;
|
||||
|
||||
/**
|
||||
* for all the adjacency list in the graph
|
||||
*/
|
||||
for (aj_list_item = opal_list_get_first(graph->adjacency_list);
|
||||
aj_list_item != opal_list_get_end(graph->adjacency_list);
|
||||
aj_list_item = opal_list_get_next(aj_list_item)) {
|
||||
aj_list = (opal_adjacency_list_t *) aj_list_item;
|
||||
/**
|
||||
* for all the edges in the adjacency list
|
||||
*/
|
||||
for (edge_item = opal_list_get_first(aj_list->edges);
|
||||
edge_item != opal_list_get_end(aj_list->edges);
|
||||
edge_item = opal_list_get_next(edge_item)) {
|
||||
edge = (opal_graph_edge_t *)edge_item;
|
||||
/**
|
||||
* if the edge is ended in the vertex
|
||||
*/
|
||||
if (edge->end == vertex) {
|
||||
/* Delete this edge */
|
||||
opal_list_remove_item(edge->in_adj_list->edges, (opal_list_item_t*)edge);
|
||||
/* distract this edge */
|
||||
OBJ_RELEASE(edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API adds a vertex to graph. The most common use
|
||||
* for this API is while building a graph.
|
||||
*
|
||||
* @param graph The graph that the vertex will be added to.
|
||||
* @param vertex The vertex we want to add.
|
||||
*/
|
||||
void opal_graph_add_vertex(opal_graph_t *graph, opal_graph_vertex_t *vertex)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
opal_list_item_t *item;
|
||||
|
||||
/**
|
||||
* Find if this vertex already exists in the graph.
|
||||
*/
|
||||
for (item = opal_list_get_first(graph->adjacency_list);
|
||||
item != opal_list_get_end(graph->adjacency_list);
|
||||
item = opal_list_get_next(item)) {
|
||||
aj_list = (opal_adjacency_list_t *) item;
|
||||
if (aj_list->vertex == vertex) {
|
||||
/* If this vertex exists, dont do anything. */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Construct a new adjacency list */
|
||||
aj_list = OBJ_NEW(opal_adjacency_list_t);
|
||||
aj_list->vertex = vertex;
|
||||
/* point the vertex to the adjacency list of the vertex (for easy searching) */
|
||||
vertex->in_adj_list = aj_list;
|
||||
/* Append the new creates adjacency list to the graph */
|
||||
opal_list_append(graph->adjacency_list, (opal_list_item_t*)aj_list);
|
||||
/* point the vertex to the graph it belongs to (mostly for debug uses)*/
|
||||
vertex->in_graph = graph;
|
||||
/* increase the number of vertices in the graph */
|
||||
graph->number_of_vertices++;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This graph API adds an edge (connection between two
|
||||
* vertices) to a graph. The most common use
|
||||
* for this API is while building a graph.
|
||||
*
|
||||
* @param graph The graph that this edge will be added to.
|
||||
* @param edge The edge that we want to add.
|
||||
*
|
||||
* @return int Success or error. this API can return an error if
|
||||
* one of the vertices is not in the graph.
|
||||
*/
|
||||
int opal_graph_add_edge(opal_graph_t *graph, opal_graph_edge_t *edge)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list, *start_aj_list, *end_aj_list;
|
||||
opal_list_item_t *item;
|
||||
bool start_found = false, end_found = false;
|
||||
|
||||
|
||||
/**
|
||||
* find the vertices that this edge should connect.
|
||||
*/
|
||||
for (item = opal_list_get_first(graph->adjacency_list);
|
||||
item != opal_list_get_end(graph->adjacency_list);
|
||||
item = opal_list_get_next(item)) {
|
||||
aj_list = (opal_adjacency_list_t *) item;
|
||||
if (aj_list->vertex == edge->start) {
|
||||
start_found = true;
|
||||
start_aj_list = aj_list;
|
||||
}
|
||||
if (aj_list->vertex == edge->end) {
|
||||
end_found = true;
|
||||
end_aj_list = aj_list;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* if one of the vertices either the start or the end is not
|
||||
* found - return an error.
|
||||
*/
|
||||
if (false == start_found && false == end_found) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
/* point the edge to the adjacency list of the start vertex (for easy search) */
|
||||
edge->in_adj_list=start_aj_list;
|
||||
/* append the edge to the adjacency list of the start vertex */
|
||||
opal_list_append(start_aj_list->edges, (opal_list_item_t*)edge);
|
||||
/* increase the graph size */
|
||||
graph->number_of_edges++;
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This graph API removes an edge (a connection between two
|
||||
* vertices) from the graph. The most common use of this API is
|
||||
* while destructing a graph or while removing vertices from a
|
||||
* graph. while removing vertices from a graph, we should also
|
||||
* remove the connections from and to the vertices that we are
|
||||
* removing.
|
||||
*
|
||||
* @param graph The graph that this edge will be remove from.
|
||||
* @param edge the edge that we want to remove.
|
||||
*/
|
||||
void opal_graph_remove_edge (opal_graph_t *graph, opal_graph_edge_t *edge)
|
||||
{
|
||||
/* remove the edge from the list it belongs to */
|
||||
opal_list_remove_item(edge->in_adj_list->edges, (opal_list_item_t*)edge);
|
||||
/* decrees the number of edges in the graph */
|
||||
graph->number_of_edges--;
|
||||
/* Note that the edge is not destructed - the caller should destruct this edge. */
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API remove a vertex from graph. The most common
|
||||
* use for this API is while distracting a graph or while
|
||||
* removing relevant vertices from a graph.
|
||||
*
|
||||
* @param graph The graph that the vertex will be remove from.
|
||||
* @param vertex The vertex we want to remove.
|
||||
*/
|
||||
|
||||
void opal_graph_remove_vertex(opal_graph_t *graph, opal_graph_vertex_t *vertex)
|
||||
{
|
||||
opal_adjacency_list_t *adj_list;
|
||||
opal_graph_edge_t *edge;
|
||||
|
||||
/**
|
||||
* remove all the edges of this vertex and destruct them.
|
||||
*/
|
||||
adj_list = vertex->in_adj_list;
|
||||
while (false == opal_list_is_empty(adj_list->edges)) {
|
||||
edge = (opal_graph_edge_t *)opal_list_remove_first(adj_list->edges);
|
||||
OBJ_RELEASE(edge);
|
||||
}
|
||||
/**
|
||||
* remove the adjscency list of this vertex from the graph and
|
||||
* destruct it.
|
||||
*/
|
||||
opal_list_remove_item(graph->adjacency_list, (opal_list_item_t*)adj_list);
|
||||
OBJ_RELEASE(adj_list);
|
||||
/**
|
||||
* delete all the edges that connected *to* the vertex.
|
||||
*/
|
||||
delete_all_edges_conceded_to_vertex(graph, vertex);
|
||||
/* destruct the vertex */
|
||||
OBJ_RELEASE(vertex);
|
||||
/* decrease the number of vertices in the graph. */
|
||||
graph->number_of_vertices--;
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API tell us if two vertices are adjacent
|
||||
*
|
||||
* @param graph The graph that the vertices belongs to.
|
||||
* @param vertex1 first vertex.
|
||||
* @param vertex2 second vertex.
|
||||
*
|
||||
* @return uint32_t the weight of the connection between the two
|
||||
* vertices or infinity if the vertices are not
|
||||
* connected.
|
||||
*/
|
||||
uint32_t opal_graph_adjacent(opal_graph_t *graph, opal_graph_vertex_t *vertex1, opal_graph_vertex_t *vertex2)
|
||||
{
|
||||
opal_adjacency_list_t *adj_list;
|
||||
opal_list_item_t *item;
|
||||
opal_graph_edge_t *edge;
|
||||
|
||||
/**
|
||||
* Verify that the first vertex belongs to the graph.
|
||||
*/
|
||||
if (graph != vertex1->in_graph) {
|
||||
opal_output(0,"opal_graph_adjacent 1 Vertex1 %p not in the graph %p\n",(void *)vertex1,(void *)graph);
|
||||
return DISTANCE_INFINITY;
|
||||
}
|
||||
/**
|
||||
* Verify that the second vertex belongs to the graph.
|
||||
*/
|
||||
if (graph != vertex2->in_graph) {
|
||||
opal_output(0,"opal_graph_adjacent 2 Vertex2 %p not in the graph %p\n",(void *)vertex2,(void *)graph);
|
||||
return DISTANCE_INFINITY;
|
||||
}
|
||||
/**
|
||||
* If the first vertex and the second vertex are the same
|
||||
* vertex, the distance between the is 0.
|
||||
*/
|
||||
if (vertex1 == vertex2) {
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* find the second vertex in the adjacency list of the first
|
||||
* vertex.
|
||||
*/
|
||||
adj_list = (opal_adjacency_list_t *) vertex1->in_adj_list;
|
||||
for (item = opal_list_get_first(adj_list->edges);
|
||||
item != opal_list_get_end(adj_list->edges);
|
||||
item = opal_list_get_next(item)) {
|
||||
edge = (opal_graph_edge_t *)item;
|
||||
if (edge->end == vertex2) {
|
||||
/* if the second vertex was found in the adjacency list of the first one, return the weight */
|
||||
return edge->weight;
|
||||
}
|
||||
}
|
||||
/* if the second vertex was not found in the adjacency list of the first one, return infinity */
|
||||
return DISTANCE_INFINITY;
|
||||
}
|
||||
|
||||
/**
|
||||
* This Graph API returns the order of the graph (number of
|
||||
* vertices)
|
||||
*
|
||||
* @param graph
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int opal_graph_get_order(opal_graph_t *graph)
|
||||
{
|
||||
return graph->number_of_vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* This Graph API returns the size of the graph (number of
|
||||
* edges)
|
||||
*
|
||||
* @param graph
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int opal_graph_get_size(opal_graph_t *graph)
|
||||
{
|
||||
return graph->number_of_edges;
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API finds a vertex in the graph according the
|
||||
* vertex data.
|
||||
* @param graph the graph we searching in.
|
||||
* @param vertex_data the vertex data we are searching according
|
||||
* to.
|
||||
*
|
||||
* @return opal_graph_vertex_t* The vertex founded or NULL.
|
||||
*/
|
||||
opal_graph_vertex_t *opal_graph_find_vertex(opal_graph_t *graph, void *vertex_data)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
opal_list_item_t *item;
|
||||
|
||||
/**
|
||||
* Run on all the vertices of the graph
|
||||
*/
|
||||
for (item = opal_list_get_first(graph->adjacency_list);
|
||||
item != opal_list_get_end(graph->adjacency_list);
|
||||
item = opal_list_get_next(item)) {
|
||||
aj_list = (opal_adjacency_list_t *) item;
|
||||
if (NULL != aj_list->vertex->compare_vertex) {
|
||||
/* if the vertex data of a vertex is equal to the vertex data */
|
||||
if (0 == aj_list->vertex->compare_vertex(aj_list->vertex->vertex_data, vertex_data)) {
|
||||
/* return the found vertex */
|
||||
return aj_list->vertex;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if a vertex is not found, return NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This graph API returns an array of pointers of all the
|
||||
* vertices in the graph.
|
||||
*
|
||||
*
|
||||
* @param graph
|
||||
* @param vertices_list an array of pointers of all the
|
||||
* vertices in the graph vertices.
|
||||
*
|
||||
* @return int returning the graph order (the
|
||||
* number of vertices in the returned array)
|
||||
*/
|
||||
int opal_graph_get_graph_vertices(opal_graph_t *graph, opal_pointer_array_t *vertices_list)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
opal_list_item_t *item;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* If the graph order is 0, return NULL.
|
||||
*/
|
||||
if (0 == graph->number_of_vertices) {
|
||||
return 0;
|
||||
}
|
||||
/* Run on all the vertices of the graph */
|
||||
for (item = opal_list_get_first(graph->adjacency_list), i = 0;
|
||||
item != opal_list_get_end(graph->adjacency_list);
|
||||
item = opal_list_get_next(item), i++) {
|
||||
aj_list = (opal_adjacency_list_t *) item;
|
||||
/* Add the vertex to the vertices array */
|
||||
opal_pointer_array_add(vertices_list,(void *)aj_list->vertex);
|
||||
}
|
||||
/* return the vertices list */
|
||||
return graph->number_of_vertices;
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API returns all the adjacents of a vertex and the
|
||||
* distance (weight) of those adjacents and the vertex.
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex The reference vertex
|
||||
* @param adjacents An allocated pointer array of vertices and
|
||||
* their distance from the reference vertex.
|
||||
* Note that this pointer should be free after
|
||||
* usage by the user
|
||||
*
|
||||
* @return int the number of adjacents in the list.
|
||||
*/
|
||||
int opal_graph_get_adjacent_vertices(opal_graph_t *graph, opal_graph_vertex_t *vertex, opal_value_array_t *adjacents)
|
||||
{
|
||||
opal_adjacency_list_t *adj_list;
|
||||
opal_graph_edge_t *edge;
|
||||
int adjacents_number;
|
||||
opal_list_item_t *item;
|
||||
vertex_distance_from_t distance_from;
|
||||
int i;
|
||||
|
||||
/**
|
||||
* Verify that the vertex belongs to the graph.
|
||||
*/
|
||||
if (graph != vertex->in_graph) {
|
||||
opal_output(0,"Vertex %p not in the graph %p\n", (void *)vertex, (void *)graph);
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* find the adjacency list that this vertex belongs to
|
||||
*/
|
||||
adj_list = (opal_adjacency_list_t *) vertex->in_adj_list;
|
||||
/* find the number of adjcents of this vertex */
|
||||
adjacents_number = opal_list_get_size(adj_list->edges);
|
||||
/* Run on all the edges from this vertex */
|
||||
for (item = opal_list_get_first(adj_list->edges), i = 0;
|
||||
item != opal_list_get_end(adj_list->edges);
|
||||
item = opal_list_get_next(item), i++) {
|
||||
edge = (opal_graph_edge_t *)item;
|
||||
/* assign vertices and their weight in the adjcents list */
|
||||
distance_from.vertex = edge->end;
|
||||
distance_from.weight = edge->weight;
|
||||
opal_value_array_append_item(adjacents, &distance_from);
|
||||
}
|
||||
/* return the number of the adjacents in the list */
|
||||
return adjacents_number;
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API finds the shortest path between two vertices.
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex1 The start vertex.
|
||||
* @param vertex2 The end vertex.
|
||||
*
|
||||
* @return uint32_t the distance between the two vertices.
|
||||
*/
|
||||
|
||||
uint32_t opal_graph_spf(opal_graph_t *graph, opal_graph_vertex_t *vertex1, opal_graph_vertex_t *vertex2)
|
||||
{
|
||||
opal_value_array_t *distance_array;
|
||||
uint32_t items_in_distance_array, spf = DISTANCE_INFINITY;
|
||||
vertex_distance_from_t *vertex_distance;
|
||||
uint32_t i;
|
||||
|
||||
/**
|
||||
* Verify that the first vertex belongs to the graph.
|
||||
*/
|
||||
if (graph != vertex1->in_graph) {
|
||||
opal_output(0,"opal_graph_spf 1 Vertex1 %p not in the graph %p\n",(void *)vertex1,(void *)graph);
|
||||
return DISTANCE_INFINITY;
|
||||
}
|
||||
/**
|
||||
* Verify that the second vertex belongs to the graph.
|
||||
*/
|
||||
if (graph != vertex2->in_graph) {
|
||||
opal_output(0,"opal_graph_spf 2 Vertex2 %p not in the graph %p\n",(void *)vertex2,(void *)graph);
|
||||
return DISTANCE_INFINITY;
|
||||
}
|
||||
/**
|
||||
* Run Dijkstra algorithm on the graph from the start vertex.
|
||||
*/
|
||||
distance_array = OBJ_NEW(opal_value_array_t);
|
||||
opal_value_array_init(distance_array, sizeof(vertex_distance_from_t));
|
||||
opal_value_array_reserve(distance_array,50);
|
||||
items_in_distance_array = dijkstra(graph, vertex1, distance_array);
|
||||
/**
|
||||
* find the end vertex in the distance array that Dijkstra
|
||||
* algorithm returned.
|
||||
*/
|
||||
for (i = 0; i < items_in_distance_array; i++) {
|
||||
vertex_distance = opal_value_array_get_item(distance_array, i);
|
||||
if (vertex_distance->vertex == vertex2) {
|
||||
spf = vertex_distance->weight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
OBJ_RELEASE(distance_array);
|
||||
/* return the distance (weight) to the end vertex */
|
||||
return spf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the distance between two vertex distance items. this
|
||||
* function is used for sorting an array of vertices distance by
|
||||
* qsort function.
|
||||
*
|
||||
* @param item1 a void pointer to vertex distance structure
|
||||
* @param item2 a void pointer to vertex distance structure
|
||||
*
|
||||
* @return int 1 - the first item weight is higher then the
|
||||
* second item weight. 0 - the weights are equal. -1 -
|
||||
* the second item weight is higher the the first item
|
||||
* weight.
|
||||
*/
|
||||
static int compare_vertex_distance(const void *item1, const void *item2)
|
||||
{
|
||||
vertex_distance_from_t *vertex_dist1, *vertex_dist2;
|
||||
|
||||
/* convert the void pointers to vertex distance pointers. */
|
||||
vertex_dist1 = (vertex_distance_from_t *)item1;
|
||||
vertex_dist2 = (vertex_distance_from_t *)item2;
|
||||
|
||||
/* If the first item weight is higher then the second item weight return 1*/
|
||||
if (vertex_dist1->weight > vertex_dist2->weight) {
|
||||
return 1;
|
||||
}
|
||||
/* If they are equal return 0 */
|
||||
else if (vertex_dist1->weight == vertex_dist2->weight) {
|
||||
return 0;
|
||||
}
|
||||
/* if you reached here then the second item weight is higher the the first item weight */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This graph API returns the distance (weight) from a reference
|
||||
* vertex to all other vertices in the graph using the Dijkstra
|
||||
* algorithm
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex The reference vertex.
|
||||
* @param distance_array An array of vertices and
|
||||
* their distance from the reference vertex.
|
||||
*
|
||||
* @return uint32_t the size of the distance array
|
||||
*/
|
||||
uint32_t dijkstra(opal_graph_t *graph, opal_graph_vertex_t *vertex, opal_value_array_t *distance_array)
|
||||
{
|
||||
int graph_order;
|
||||
vertex_distance_from_t *Q, *q_start, *current_vertex;
|
||||
opal_list_item_t *adj_list_item;
|
||||
opal_adjacency_list_t *adj_list;
|
||||
int number_of_items_in_q;
|
||||
int i;
|
||||
uint32_t weight;
|
||||
|
||||
|
||||
/**
|
||||
* Verify that the reference vertex belongs to the graph.
|
||||
*/
|
||||
if (graph != vertex->in_graph) {
|
||||
opal_output(0,"dijkstra: vertex %p not in the graph %p\n",(void *)vertex,(void *)graph);
|
||||
return 0;
|
||||
}
|
||||
/* get the order of the graph and allocate a working queue accordingly */
|
||||
graph_order = opal_graph_get_order(graph);
|
||||
Q = (vertex_distance_from_t *)malloc(graph_order * sizeof(vertex_distance_from_t));
|
||||
/* assign a pointer to the start of the queue */
|
||||
q_start = Q;
|
||||
/* run on all the vertices of the graph */
|
||||
for (adj_list_item = opal_list_get_first(graph->adjacency_list), i=0;
|
||||
adj_list_item != opal_list_get_end(graph->adjacency_list);
|
||||
adj_list_item = opal_list_get_next(adj_list_item), i++) {
|
||||
adj_list = (opal_adjacency_list_t *)adj_list_item;
|
||||
/* insert the vertices pointes to the working queue */
|
||||
Q[i].vertex = adj_list->vertex;
|
||||
/**
|
||||
* assign an infinity distance to all the vertices in the queue
|
||||
* except the reference vertex which its distance should be 0.
|
||||
*/
|
||||
if (Q[i].vertex == vertex) {
|
||||
Q[i].weight = 0;
|
||||
}
|
||||
else {
|
||||
Q[i].weight = DISTANCE_INFINITY;
|
||||
}
|
||||
}
|
||||
number_of_items_in_q = i;
|
||||
/* sort the working queue according the distance from the reference vertex */
|
||||
qsort(q_start, number_of_items_in_q, sizeof(vertex_distance_from_t), compare_vertex_distance);
|
||||
/* while the working queue is not empty */
|
||||
while (number_of_items_in_q > 0) {
|
||||
/* start to work with the first vertex in the working queue */
|
||||
current_vertex = q_start;
|
||||
/* remove the first vertex from the queue */
|
||||
q_start++;
|
||||
/* decrees the number of vertices in the queue */
|
||||
number_of_items_in_q--;
|
||||
/* find the distance of all other vertices in the queue from the first vertex in the queue */
|
||||
for (i = 0; i < number_of_items_in_q; i++) {
|
||||
weight = opal_graph_adjacent(graph, current_vertex->vertex, q_start[i].vertex);
|
||||
/**
|
||||
* if the distance from the first vertex in the queue to the I
|
||||
* vertex in the queue plus the distance of the first vertex in
|
||||
* the queue from the referenced vertex is smaller then the
|
||||
* distance of the I vertex from the referenced vertex, assign
|
||||
* the lower distance to the I vertex.
|
||||
*/
|
||||
if (current_vertex->weight + weight < q_start[i].weight) {
|
||||
q_start[i].weight = weight + current_vertex->weight;
|
||||
}
|
||||
}
|
||||
/* sort again the working queue */
|
||||
qsort(q_start, number_of_items_in_q, sizeof(vertex_distance_from_t), compare_vertex_distance);
|
||||
}
|
||||
/* copy the working queue the the returned distance array */
|
||||
for (i = 0; i < graph_order-1; i++) {
|
||||
opal_value_array_append_item(distance_array, (void *)&(Q[i+1]));
|
||||
}
|
||||
/* free the working queue */
|
||||
free(Q);
|
||||
/* assign the distance array size. */
|
||||
return graph_order - 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This graph API duplicates a graph. Note that this API does
|
||||
* not copy the graph but builds a new graph while coping just
|
||||
* the vertex data.
|
||||
*
|
||||
* @param dest The new created graph.
|
||||
* @param src The graph we want to duplicate.
|
||||
*/
|
||||
void opal_graph_duplicate(opal_graph_t **dest, opal_graph_t *src)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
opal_list_item_t *aj_list_item, *edg_item;
|
||||
opal_graph_vertex_t *vertex;
|
||||
opal_graph_edge_t *edge, *new_edge;
|
||||
|
||||
/* construct a new graph */
|
||||
*dest = OBJ_NEW(opal_graph_t);
|
||||
/* Run on all the vertices of the src graph */
|
||||
for (aj_list_item = opal_list_get_first(src->adjacency_list);
|
||||
aj_list_item != opal_list_get_end(src->adjacency_list);
|
||||
aj_list_item = opal_list_get_next(aj_list_item)) {
|
||||
aj_list = (opal_adjacency_list_t *) aj_list_item;
|
||||
/* for each vertex in the src graph, construct a new vertex */
|
||||
vertex = OBJ_NEW(opal_graph_vertex_t);
|
||||
/* associate the new vertex to a vertex from the original graph */
|
||||
vertex->sibling = aj_list->vertex;
|
||||
/* associate the original vertex to the new constructed vertex */
|
||||
aj_list->vertex->sibling = vertex;
|
||||
/* allocate space to vertex data in the new vertex */
|
||||
if (NULL != aj_list->vertex->alloc_vertex_data) {
|
||||
vertex->vertex_data = aj_list->vertex->alloc_vertex_data();
|
||||
vertex->alloc_vertex_data = aj_list->vertex->alloc_vertex_data;
|
||||
}
|
||||
/* copy the vertex data from the original vertex to the new vertex */
|
||||
if (NULL != aj_list->vertex->copy_vertex_data) {
|
||||
aj_list->vertex->copy_vertex_data(&(vertex->vertex_data), aj_list->vertex->vertex_data);
|
||||
vertex->copy_vertex_data = aj_list->vertex->copy_vertex_data;
|
||||
}
|
||||
/* copy all the fields of the original vertex to the new vertex. */
|
||||
vertex->free_vertex_data = aj_list->vertex->free_vertex_data;
|
||||
vertex->print_vertex = aj_list->vertex->print_vertex;
|
||||
vertex->compare_vertex = aj_list->vertex->compare_vertex;
|
||||
vertex->in_graph = *dest;
|
||||
/* add the new vertex to the new graph */
|
||||
opal_graph_add_vertex(*dest, vertex);
|
||||
}
|
||||
/**
|
||||
* Now, copy all the edges from the source graph
|
||||
*/
|
||||
/* Run on all the adjscency lists in the graph */
|
||||
for (aj_list_item = opal_list_get_first(src->adjacency_list);
|
||||
aj_list_item != opal_list_get_end(src->adjacency_list);
|
||||
aj_list_item = opal_list_get_next(aj_list_item)) {
|
||||
aj_list = (opal_adjacency_list_t *) aj_list_item;
|
||||
/* for all the edges in the adjscency list */
|
||||
for (edg_item = opal_list_get_first(aj_list->edges);
|
||||
edg_item != opal_list_get_end(aj_list->edges);
|
||||
edg_item = opal_list_get_next(edg_item)) {
|
||||
edge = (opal_graph_edge_t *)edg_item;
|
||||
/* construct new edge for the new graph */
|
||||
new_edge = OBJ_NEW(opal_graph_edge_t);
|
||||
/* copy the edge weight from the original edge */
|
||||
new_edge->weight = edge->weight;
|
||||
/* connect the new edge according to start and end associations to the vertices of the src graph */
|
||||
new_edge->start = edge->start->sibling;
|
||||
new_edge->end = edge->end->sibling;
|
||||
/* add the new edge to the new graph */
|
||||
opal_graph_add_edge(*dest, new_edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This graph API prints a graph - mostly for debug uses.
|
||||
* @param graph
|
||||
*/
|
||||
void opal_graph_print(opal_graph_t *graph)
|
||||
{
|
||||
opal_adjacency_list_t *aj_list;
|
||||
opal_list_item_t *aj_list_item;
|
||||
opal_graph_edge_t *edge;
|
||||
opal_list_item_t *edge_item;
|
||||
char *tmp_str1, *tmp_str2;
|
||||
|
||||
/* print header */
|
||||
opal_output(0, " Graph ");
|
||||
opal_output(0, "====================");
|
||||
/* run on all the vertices of the graph */
|
||||
for (aj_list_item = opal_list_get_first(graph->adjacency_list);
|
||||
aj_list_item != opal_list_get_end(graph->adjacency_list);
|
||||
aj_list_item = opal_list_get_next(aj_list_item)) {
|
||||
aj_list = (opal_adjacency_list_t *) aj_list_item;
|
||||
/* print vertex data to temporary string*/
|
||||
if (NULL != aj_list->vertex->print_vertex) {
|
||||
tmp_str1 = aj_list->vertex->print_vertex(aj_list->vertex->vertex_data);
|
||||
}
|
||||
else {
|
||||
tmp_str1 = "";
|
||||
}
|
||||
/* print vertex */
|
||||
opal_output(0, "V(%s) Connections:",tmp_str1);
|
||||
/* run on all the edges of the vertex */
|
||||
for (edge_item = opal_list_get_first(aj_list->edges);
|
||||
edge_item != opal_list_get_end(aj_list->edges);
|
||||
edge_item = opal_list_get_next(edge_item)) {
|
||||
edge = (opal_graph_edge_t *)edge_item;
|
||||
/* print the vertex data of the vertex in the end of the edge to a temporary string */
|
||||
if (NULL != edge->end->print_vertex) {
|
||||
tmp_str2 = edge->end->print_vertex(edge->end->vertex_data);
|
||||
}
|
||||
else {
|
||||
tmp_str2 = "";
|
||||
}
|
||||
/* print the edge */
|
||||
opal_output(0, " E(%s -> %d -> %s)",tmp_str1, edge->weight, tmp_str2);
|
||||
free(tmp_str2);
|
||||
}
|
||||
free(tmp_str1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
359
opal/class/opal_graph.h
Исполняемый файл
359
opal/class/opal_graph.h
Исполняемый файл
@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Voltaire All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
* The opal_graph interface is used to provide a generic graph infrastructure
|
||||
* to Open-MPI. The graph is represented as an adjacentcy list.
|
||||
* The graph is a list of vertices. The graph is a weighted directional graph.
|
||||
* Each vertex contains a pointer to a vertex data.
|
||||
* This pointer can point to the structure that this vertex belongs to.
|
||||
*/
|
||||
#ifndef OPAL_GRAPH_H
|
||||
#define OPAL_GRAPH_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "opal/class/opal_object.h"
|
||||
#include "opal/class/opal_list.h"
|
||||
#include "opal/class/opal_pointer_array.h"
|
||||
#include "opal/class/opal_value_array.h"
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* When two vertices are not connected, the distance between them is infinite. */
|
||||
#define DISTANCE_INFINITY 0x7fffffff
|
||||
|
||||
/* A class for vertex */
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_graph_vertex_t);
|
||||
|
||||
/* A class for an edge (a connection between two verices) */
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_graph_edge_t);
|
||||
|
||||
/* A class for an adjacency list */
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_adjacency_list_t);
|
||||
|
||||
/* A class for graph */
|
||||
OPAL_DECLSPEC OBJ_CLASS_DECLARATION(opal_graph_t);
|
||||
|
||||
/**
|
||||
* Function pointer for coping a vertex data from one vertex to
|
||||
* another
|
||||
*
|
||||
* @param dst The destination pointer of vertex_data
|
||||
* @param src The source pointer of the vertex_data
|
||||
*
|
||||
*
|
||||
*/
|
||||
typedef void (*opal_graph_copy_vertex_data)(void **dst, void *src);
|
||||
|
||||
/**
|
||||
* free vertex data.
|
||||
* @param vertex_data
|
||||
*
|
||||
* The vertex data can point to the structure that this vertex
|
||||
* belongs to.
|
||||
*/
|
||||
typedef void (*opal_graph_free_vertex_data)(void *vertex_data);
|
||||
|
||||
/**
|
||||
* Allocate vertex data.
|
||||
*/
|
||||
typedef void *(*opal_graph_alloc_vertex_data)(void);
|
||||
|
||||
/**
|
||||
* Compare two vertices data.
|
||||
*
|
||||
*@param vertex_data1
|
||||
*@param vertex_data2
|
||||
*
|
||||
*@return int The comparition results. 1- vertex_data1 is bigger
|
||||
* then vertex_data2, 0- vertex_data1 is equal to
|
||||
* vertex_data2 and -1- vertex_data1 is smaller the
|
||||
* vertex_data2.
|
||||
*/
|
||||
typedef int (*opal_graph_compare_vertex_data)(void *vertex_data1, void *vertex_data2);
|
||||
|
||||
/**
|
||||
* print a vertex data.
|
||||
*
|
||||
* @param vertex_data
|
||||
*/
|
||||
typedef char *(*opal_graph_print_vertex)(void *vertex_data);
|
||||
|
||||
|
||||
/**
|
||||
* A vertex class.
|
||||
*/
|
||||
struct opal_graph_vertex_t {
|
||||
opal_list_item_t super; /* A pointer to a vertex parent */
|
||||
void *in_graph; /* A pointer to the graph that this vertex belongs to */
|
||||
void *in_adj_list; /* A pointer to the adjacency that this vertex belongs to */
|
||||
void *vertex_data;/* A pointer to some data. this pointer can point to the struct the this*/
|
||||
/* vertex belongs to*/
|
||||
struct opal_graph_vertex_t *sibling;/* A pointer to a sibling vertex. */
|
||||
/* if this vertex was copied this pointer will point to the source vertex */
|
||||
/* This pointer is for internal uses. */
|
||||
opal_graph_copy_vertex_data copy_vertex_data; /* A function to copy vertex data */
|
||||
opal_graph_free_vertex_data free_vertex_data; /* A function to print vertex data */
|
||||
opal_graph_alloc_vertex_data alloc_vertex_data;/* A function to allocate vertex data */
|
||||
opal_graph_compare_vertex_data compare_vertex; /* A function to compare between two vertices data */
|
||||
opal_graph_print_vertex print_vertex; /* A function to print vertex data */
|
||||
};
|
||||
|
||||
/**
|
||||
* A type for vertex.
|
||||
*/
|
||||
typedef struct opal_graph_vertex_t opal_graph_vertex_t;
|
||||
|
||||
/**
|
||||
* An opal_adjacency_list_t class
|
||||
*/
|
||||
struct opal_adjacency_list_t {
|
||||
opal_list_item_t super; /* A pointer to vertex parent */
|
||||
opal_graph_vertex_t *vertex; /* The adjacency_list is for adjacent of this vertex */
|
||||
opal_list_t *edges; /* An edge list for all the adjacent and their weights */
|
||||
};
|
||||
|
||||
/**
|
||||
* A type for opal_adjacency_list_t
|
||||
*/
|
||||
typedef struct opal_adjacency_list_t opal_adjacency_list_t;
|
||||
|
||||
/**
|
||||
* An edge class. (connection between two vertices.) Since the
|
||||
* graph is a directional graph, each vertex contains a start
|
||||
* and an end pointers for the start vertex and the end vertex
|
||||
* of this edge. Since the graph is a weighted graph, the edges
|
||||
* contains a weight field.
|
||||
*/
|
||||
struct opal_graph_edge_t {
|
||||
opal_list_item_t super; /* A pointer to the edge parent */
|
||||
opal_graph_vertex_t *start; /* The start vertex. */
|
||||
opal_graph_vertex_t *end; /* The end vertex */
|
||||
uint32_t weight; /* The weight of this edge */
|
||||
opal_adjacency_list_t *in_adj_list; /* The adjacency list in witch this edge in.*/
|
||||
/* This adjacency list contains the start vertex of this edge*/
|
||||
/* and its for internal uses */
|
||||
};
|
||||
|
||||
/**
|
||||
* A type for an edge
|
||||
*/
|
||||
typedef struct opal_graph_edge_t opal_graph_edge_t;
|
||||
|
||||
|
||||
/**
|
||||
* A graph class.
|
||||
*/
|
||||
struct opal_graph_t {
|
||||
opal_object_t super;
|
||||
opal_list_t *adjacency_list;
|
||||
int number_of_edges;
|
||||
int number_of_vertices;
|
||||
};
|
||||
|
||||
/**
|
||||
* A type for graph class
|
||||
*/
|
||||
typedef struct opal_graph_t opal_graph_t;
|
||||
|
||||
/**
|
||||
* This structure represent the distance (weight) of a vertex
|
||||
* from some point in the graph.
|
||||
*/
|
||||
struct vertex_distance_from_t {
|
||||
opal_graph_vertex_t *vertex;
|
||||
uint32_t weight;
|
||||
};
|
||||
|
||||
/**
|
||||
* A type for vertex distance.
|
||||
*/
|
||||
typedef struct vertex_distance_from_t vertex_distance_from_t;
|
||||
|
||||
/**
|
||||
* This graph API adds a vertex to graph. The most common use
|
||||
* for this API is while building a graph.
|
||||
*
|
||||
* @param graph The graph that the vertex will be added to.
|
||||
* @param vertex The vertex we want to add.
|
||||
*/
|
||||
void opal_graph_add_vertex(opal_graph_t *graph, opal_graph_vertex_t *vertex);
|
||||
|
||||
/**
|
||||
* This graph API remove a vertex from graph. The most common
|
||||
* use for this API is while distracting a graph or while
|
||||
* removing relevant vertices from a graph.
|
||||
*
|
||||
* @param graph The graph that the vertex will be remove from.
|
||||
* @param vertex The vertex we want to remove.
|
||||
*/
|
||||
void opal_graph_remove_vertex(opal_graph_t *graph, opal_graph_vertex_t *vertex);
|
||||
|
||||
/**
|
||||
* This graph API adds an edge (connection between two
|
||||
* vertices) to a graph. The most common use
|
||||
* for this API is while building a graph.
|
||||
*
|
||||
* @param graph The graph that this edge will be added to.
|
||||
* @param edge The edge that we want to add.
|
||||
*
|
||||
* @return int Success or error. this API can return an error if
|
||||
* one of the vertices is not in the graph.
|
||||
*/
|
||||
int opal_graph_add_edge(opal_graph_t *graph, opal_graph_edge_t *edge);
|
||||
|
||||
/**
|
||||
* This graph API removes an edge (a connection between two
|
||||
* vertices) from the graph. The most common use of this API is
|
||||
* while destructing a graph or while removing vertices from a
|
||||
* graph. while removing vertices from a graph, we should also
|
||||
* remove the connections from and to the vertices that we are
|
||||
* removing.
|
||||
*
|
||||
* @param graph The graph that this edge will be remove from.
|
||||
* @param edge the edge that we want to remove.
|
||||
*/
|
||||
void opal_graph_remove_edge (opal_graph_t *graph, opal_graph_edge_t *edge);
|
||||
|
||||
/**
|
||||
* This graph API tell us if two vertices are adjacent
|
||||
*
|
||||
* @param graph The graph that the vertices belongs to.
|
||||
* @param vertex1 first vertex.
|
||||
* @param vertex2 second vertex.
|
||||
*
|
||||
* @return uint32_t the weight of the connection between the two
|
||||
* vertices or infinity if the vertices are not
|
||||
* connected.
|
||||
*/
|
||||
uint32_t opal_graph_adjacent(opal_graph_t *graph, opal_graph_vertex_t *vertex1, opal_graph_vertex_t *vertex2);
|
||||
|
||||
/**
|
||||
* This Graph API returns the order of the graph (number of
|
||||
* vertices)
|
||||
*
|
||||
* @param graph
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int opal_graph_get_order(opal_graph_t *graph);
|
||||
|
||||
/**
|
||||
* This Graph API returns the size of the graph (number of
|
||||
* edges)
|
||||
*
|
||||
* @param graph
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int opal_graph_get_size(opal_graph_t *graph);
|
||||
|
||||
/**
|
||||
* This graph API finds a vertex in the graph according the
|
||||
* vertex data.
|
||||
* @param graph the graph we searching in.
|
||||
* @param vertex_data the vertex data we are searching according
|
||||
* to.
|
||||
*
|
||||
* @return opal_graph_vertex_t* The vertex founded or NULL.
|
||||
*/
|
||||
opal_graph_vertex_t *opal_graph_find_vertex(opal_graph_t *graph, void *vertex_data);
|
||||
|
||||
|
||||
/**
|
||||
* This graph API returns an array of pointers of all the
|
||||
* vertices in the graph.
|
||||
*
|
||||
*
|
||||
* @param graph
|
||||
* @param vertices_list an array of pointers of all the
|
||||
* vertices in the graph vertices.
|
||||
*
|
||||
* @return int returning the graph order (the
|
||||
* number of vertices in the returned array)
|
||||
*/
|
||||
int opal_graph_get_graph_vertices(opal_graph_t *graph, opal_pointer_array_t *vertices_list);
|
||||
|
||||
/**
|
||||
* This graph API returns all the adjacent of a vertex and the
|
||||
* distance (weight) of those adjacent and the vertex.
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex The reference vertex
|
||||
* @param adjacent An allocated pointer array of vertices and
|
||||
* their distance from the reference vertex.
|
||||
* Note that this pointer should be free after
|
||||
* usage by the user
|
||||
*
|
||||
* @return int the number of adjacent in the list.
|
||||
*/
|
||||
int opal_graph_get_adjacent_vertices(opal_graph_t *graph, opal_graph_vertex_t *vertex, opal_value_array_t *adjacent);
|
||||
|
||||
/**
|
||||
* This graph API duplicates a graph. Note that this API does
|
||||
* not copy the graph but builds a new graph while coping just
|
||||
* the vertices data.
|
||||
*
|
||||
* @param dest The new created graph.
|
||||
* @param src The graph we want to duplicate.
|
||||
*/
|
||||
void opal_graph_duplicate(opal_graph_t **dest, opal_graph_t *src);
|
||||
|
||||
/**
|
||||
* This graph API finds the shortest path between two vertices.
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex1 The start vertex.
|
||||
* @param vertex2 The end vertex.
|
||||
*
|
||||
* @return uint32_t the distance between the two vertices.
|
||||
*/
|
||||
uint32_t opal_graph_spf(opal_graph_t *graph, opal_graph_vertex_t *vertex1, opal_graph_vertex_t *vertex2);
|
||||
|
||||
/**
|
||||
* This graph API returns the distance (weight) from a reference
|
||||
* vertex to all other vertices in the graph using the Dijkstra
|
||||
* algorithm
|
||||
*
|
||||
* @param graph
|
||||
* @param vertex The reference vertex.
|
||||
* @param distance_array An array of vertices and
|
||||
* their distance from the reference vertex.
|
||||
*
|
||||
* @return uint32_t the size of the distance array
|
||||
*/
|
||||
uint32_t dijkstra(opal_graph_t *graph, opal_graph_vertex_t *vertex, opal_value_array_t *distance_array);
|
||||
|
||||
/**
|
||||
* This graph API prints a graph - mostly for debug uses.
|
||||
* @param graph
|
||||
*/
|
||||
void opal_graph_print(opal_graph_t *graph);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif /* OPAL_GRAPH_H */
|
||||
|
42
opal/mca/carto/Makefile.am
Исполняемый файл
42
opal/mca/carto/Makefile.am
Исполняемый файл
@ -0,0 +1,42 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copryght (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# main library setup
|
||||
noinst_LTLIBRARIES = libmca_carto.la
|
||||
libmca_carto_la_SOURCES =
|
||||
|
||||
# header setup
|
||||
nobase_opal_HEADERS =
|
||||
|
||||
# local files
|
||||
headers = carto.h
|
||||
libmca_carto_la_SOURCES += $(headers)
|
||||
|
||||
# Conditionally install the header files
|
||||
if WANT_INSTALL_HEADERS
|
||||
nobase_opal_HEADERS += $(headers)
|
||||
opaldir = $(includedir)/openmpi/opal/mca/carto
|
||||
else
|
||||
opaldir = $(includedir)
|
||||
endif
|
||||
|
||||
include base/Makefile.am
|
||||
|
||||
distclean-local:
|
||||
rm -f base/static-components.h
|
47
opal/mca/carto/auto_detect/Makefile.am
Обычный файл
47
opal/mca/carto/auto_detect/Makefile.am
Обычный файл
@ -0,0 +1,47 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
sources = \
|
||||
carto_auto_detect.h \
|
||||
carto_auto_detect_component.c \
|
||||
carto_auto_detect_module.c
|
||||
|
||||
# Make the output library in this directory, and name it either
|
||||
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
|
||||
# (for static builds).
|
||||
|
||||
if OMPI_BUILD_carto_auto_detect_DSO
|
||||
component_noinst =
|
||||
component_install = mca_carto_auto_detect.la
|
||||
else
|
||||
component_noinst = libmca_carto_auto_detect.la
|
||||
component_install =
|
||||
endif
|
||||
|
||||
mcacomponentdir = $(pkglibdir)
|
||||
mcacomponent_LTLIBRARIES = $(component_install)
|
||||
mca_carto_auto_detect_la_SOURCES = $(sources)
|
||||
mca_carto_auto_detect_la_LDFLAGS = -module -avoid-version
|
||||
mca_carto_auto_detect_la_LIBADD = \
|
||||
$(top_ompi_builddir)/opal/libopen-pal.la
|
||||
|
||||
noinst_LTLIBRARIES = $(component_noinst)
|
||||
libmca_carto_auto_detect_la_SOURCES =$(sources)
|
||||
libmca_carto_auto_detect_la_LDFLAGS = -module -avoid-version
|
||||
|
54
opal/mca/carto/auto_detect/carto_auto_detect.h
Обычный файл
54
opal/mca/carto/auto_detect/carto_auto_detect.h
Обычный файл
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The auto detect component discover automaticly the structure
|
||||
* of the host.
|
||||
*/
|
||||
|
||||
#ifndef MCA_CARTO_AUTO_DETECT_H
|
||||
#define MCA_CARTO_AUTO_DETECT_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* Globally exported variable
|
||||
*/
|
||||
OPAL_DECLSPEC extern const opal_carto_base_component_1_0_0_t
|
||||
mca_carto_auto_detect_component;
|
||||
|
||||
|
||||
/**
|
||||
* carto query API function
|
||||
*/
|
||||
const opal_carto_base_module_1_0_0_t *
|
||||
opal_carto_auto_detect_component_query(int *query);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /* MCA_CARTO_FILE_EXPORT_H */
|
||||
|
92
opal/mca/carto/auto_detect/carto_auto_detect_component.c
Обычный файл
92
opal/mca/carto/auto_detect/carto_auto_detect_component.c
Обычный файл
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
* These symbols are in a file by themselves to provide nice linker
|
||||
* semantics. Since linkers generally pull in symbols by object
|
||||
* files, keeping these symbols as the only symbols in this file
|
||||
* prevents utility programs such as "ompi_info" from having to import
|
||||
* entire components just to query their version and parameters.
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "carto_auto_detect.h"
|
||||
|
||||
/*
|
||||
* Public string showing the carto ompi_file component version number
|
||||
*/
|
||||
const char *opal_carto_auto_detect_component_version_string =
|
||||
"OPAL auto detect carto MCA component version " OPAL_VERSION;
|
||||
|
||||
/*
|
||||
* Local function
|
||||
*/
|
||||
static int auto_detect_open(void);
|
||||
|
||||
/*
|
||||
* Instantiate the public struct with all of our public information
|
||||
* and pointers to our public functions in it
|
||||
*/
|
||||
|
||||
const opal_carto_base_component_1_0_0_t mca_carto_auto_detect_component = {
|
||||
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
|
||||
{
|
||||
/* Indicate that we are a carto v1.1.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
|
||||
OPAL_CARTO_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
|
||||
"auto_detect",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
|
||||
auto_detect_open,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
||||
/* The component is checkpoint ready */
|
||||
MCA_BASE_METADATA_PARAM_CHECKPOINT
|
||||
},
|
||||
|
||||
/* Query function */
|
||||
|
||||
opal_carto_auto_detect_component_query
|
||||
};
|
||||
|
||||
|
||||
static int auto_detect_open(void)
|
||||
{
|
||||
mca_base_param_reg_int(&mca_carto_auto_detect_component.cartoc_version,
|
||||
"priority",
|
||||
"Priority of the auto_detect carto component",
|
||||
false, false, 11, NULL);
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
95
opal/mca/carto/auto_detect/carto_auto_detect_module.c
Обычный файл
95
opal/mca/carto/auto_detect/carto_auto_detect_module.c
Обычный файл
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
/* This component will only be compiled on File, where we are
|
||||
guaranteed to have <unistd.h> and friends */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
#include "opal/mca/carto/base/carto_base_graph.h"
|
||||
#include "carto_auto_detect.h"
|
||||
|
||||
|
||||
static int opal_carto_auto_detect_init(void);
|
||||
static int opal_carto_auto_detect_finalize(void);
|
||||
|
||||
|
||||
/*
|
||||
* Auto detect carto module
|
||||
*/
|
||||
static const opal_carto_base_module_1_0_0_t module = {
|
||||
opal_carto_auto_detect_init,
|
||||
opal_carto_base_graph_get_host_graph,
|
||||
opal_carto_base_free_graph,
|
||||
opal_carto_base_get_nodes_distance,
|
||||
opal_carto_base_graph_spf,
|
||||
opal_carto_auto_detect_finalize,
|
||||
};
|
||||
|
||||
|
||||
const opal_carto_base_module_1_0_0_t *
|
||||
opal_carto_auto_detect_component_query(int *query)
|
||||
{
|
||||
int param;
|
||||
|
||||
param = mca_base_param_find("carto", "auto_detect", "priority");
|
||||
mca_base_param_lookup_int(param, query);
|
||||
|
||||
return &module;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Init the auto detect module. this function build an empty
|
||||
* carto grap and does nothing more. to comleate this module,
|
||||
* this function should read the system files and fill the
|
||||
* carto graph
|
||||
*
|
||||
* @return int success or error
|
||||
*/
|
||||
static int opal_carto_auto_detect_init(void)
|
||||
{
|
||||
opal_carto_base_graph_create(&carto_base_common_host_graph);
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans the auto detect module.
|
||||
*
|
||||
* @return int success or error
|
||||
*/
|
||||
static int opal_carto_auto_detect_finalize(void)
|
||||
{
|
||||
opal_carto_base_free_graph(carto_base_common_host_graph);
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
23
opal/mca/carto/auto_detect/configure.params
Обычный файл
23
opal/mca/carto/auto_detect/configure.params
Обычный файл
@ -0,0 +1,23 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2007 Los Alamos National Security, LLC. All rights
|
||||
# reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
PARAM_CONFIG_FILES="Makefile"
|
||||
|
27
opal/mca/carto/base/Makefile.am
Исполняемый файл
27
opal/mca/carto/base/Makefile.am
Исполняемый файл
@ -0,0 +1,27 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
headers += \
|
||||
base/base.h
|
||||
|
||||
libmca_carto_la_SOURCES += \
|
||||
base/carto_base_close.c \
|
||||
base/carto_base_select.c \
|
||||
base/carto_base_graph.c \
|
||||
base/carto_base_open.c
|
141
opal/mca/carto/base/base.h
Исполняемый файл
141
opal/mca/carto/base/base.h
Исполняемый файл
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPAL_CARTO_BASE_H
|
||||
#define OPAL_CARTO_BASE_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/carto/carto.h"
|
||||
|
||||
/*
|
||||
* Global functions for MCA overall carto open and close
|
||||
*/
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* Initialize the carto MCA framework
|
||||
*
|
||||
* @retval OPAL_SUCCESS Upon success
|
||||
* @retval OPAL_ERROR Upon failure
|
||||
*
|
||||
* This must be the first function invoked in the carto MCA
|
||||
* framework. It initializes the carto MCA framework, finds
|
||||
* and opens carto components, etc.
|
||||
*
|
||||
* This function is invoked during opal_init().
|
||||
*
|
||||
* This function fills in the internal global variable
|
||||
* opal_carto_base_components_opened, which is a list of all
|
||||
* carto components that were successfully opened. This
|
||||
* variable should \em only be used by other carto base
|
||||
* functions -- it is not considered a public interface member --
|
||||
* and is only mentioned here for completeness.
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_carto_base_open(void);
|
||||
|
||||
/**
|
||||
* Select an available component.
|
||||
*
|
||||
* @return OPAL_SUCCESS Upon success.
|
||||
* @return OPAL_NOT_FOUND If no component can be selected.
|
||||
* @return OPAL_ERROR Upon other failure.
|
||||
*
|
||||
* This function invokes the selection process for carto components,
|
||||
* which works as follows:
|
||||
*
|
||||
* - If the \em carto MCA parameter is not specified, the
|
||||
* selection set is all available carto components.
|
||||
* - If the \em carto MCA parameter is specified, the
|
||||
* selection set is just that component.
|
||||
* - All components in the selection set are queried to see if
|
||||
* they want to run. All components that want to run are ranked
|
||||
* by their priority and the highest priority component is
|
||||
* selected. All non-selected components have their "close"
|
||||
* function invoked to let them know that they were not selected.
|
||||
* - The selected component will have its "init" function invoked to
|
||||
* let it know that it was selected.
|
||||
*
|
||||
* If we fall through this entire process and no component is
|
||||
* selected, then return OPAL_NOT_FOUND (this is not a fatal
|
||||
* error).
|
||||
*
|
||||
* At the end of this process, we'll either have a single
|
||||
* component that is selected and initialized, or no component was
|
||||
* selected. If no component was selected, subsequent invocation
|
||||
* of the carto wrapper functions will return an error.
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_carto_base_select(void);
|
||||
|
||||
/**
|
||||
* Shut down the carto MCA framework.
|
||||
*
|
||||
* @retval OPAL_SUCCESS Always
|
||||
*
|
||||
* This function shuts down everything in the carto MCA
|
||||
* framework, and is called during opal_finalize().
|
||||
*
|
||||
* It must be the last function invoked on the carto MCA
|
||||
* framework.
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_carto_base_close(void);
|
||||
|
||||
/**
|
||||
* Indication of whether a component was successfully selected or
|
||||
* not
|
||||
*/
|
||||
OPAL_DECLSPEC extern bool opal_carto_base_selected;
|
||||
|
||||
/**
|
||||
* Global component struct for the selected component
|
||||
*/
|
||||
OPAL_DECLSPEC extern const opal_carto_base_component_1_0_0_t
|
||||
*opal_carto_base_component;
|
||||
|
||||
/**
|
||||
* Global module struct for the selected module
|
||||
*/
|
||||
OPAL_DECLSPEC extern const opal_carto_base_module_1_0_0_t
|
||||
*opal_carto_base_module;
|
||||
|
||||
/**
|
||||
* Indicator as to whether the list of opened carto components
|
||||
* is valid or not.
|
||||
*/
|
||||
OPAL_DECLSPEC extern bool opal_carto_base_components_opened_valid;
|
||||
|
||||
/**
|
||||
* List of all opened components; created when the carto
|
||||
* framework is initialized and destroyed when we reduce the list
|
||||
* to all available carto components.
|
||||
*/
|
||||
OPAL_DECLSPEC extern opal_list_t opal_carto_base_components_opened;
|
||||
|
||||
/**
|
||||
* Debugging output stream
|
||||
*/
|
||||
extern int opal_carto_base_output;
|
||||
|
||||
extern opal_carto_graph_t *carto_base_common_host_graph;
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /* OPAL_BASE_CARTO_H */
|
50
opal/mca/carto/base/carto_base_close.c
Исполняемый файл
50
opal/mca/carto/base/carto_base_close.c
Исполняемый файл
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
|
||||
int opal_carto_base_close(void)
|
||||
{
|
||||
/* If there is a selected carto module, finalize it */
|
||||
|
||||
if (NULL != opal_carto_base_module &&
|
||||
NULL != opal_carto_base_module->carto_module_finalize) {
|
||||
opal_carto_base_module->carto_module_finalize();
|
||||
}
|
||||
|
||||
/* Close all components that are still open (this should only
|
||||
happen during ompi_info). */
|
||||
|
||||
if (opal_carto_base_components_opened_valid) {
|
||||
mca_base_components_close(opal_carto_base_output,
|
||||
&opal_carto_base_components_opened, NULL);
|
||||
OBJ_DESTRUCT(&opal_carto_base_components_opened);
|
||||
opal_carto_base_components_opened_valid = false;
|
||||
}
|
||||
|
||||
/* All done */
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
395
opal/mca/carto/base/carto_base_graph.c
Обычный файл
395
opal/mca/carto/base/carto_base_graph.c
Обычный файл
@ -0,0 +1,395 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
# Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* This file is an implementation of the carto graph base on the graph class.
|
||||
* This file is common to all the carto components.
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
|
||||
#include "opal/class/opal_graph.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/carto_base_graph.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
|
||||
static void opal_carto_base_free_node(void *node);
|
||||
static void opal_carto_base_copy_nodes(void **dst, void *src);
|
||||
static void *opal_carto_base_alloc_node(void);
|
||||
static int opal_carto_compare_nodes(void *node1, void *node2);
|
||||
static char* opal_carto_print_node(void* node);
|
||||
|
||||
opal_carto_graph_t *carto_base_common_host_graph;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* A function to print a node. this function allocates buffer
|
||||
* and prints in it the node type and the node name. this
|
||||
* function will be assign to the print_vertex function pointer
|
||||
* when building a new node.
|
||||
*
|
||||
* @param node The node we want to print
|
||||
*
|
||||
* @return char* the string to print.
|
||||
*/
|
||||
static char* opal_carto_print_node(void* node)
|
||||
{
|
||||
char *print_str;
|
||||
char cpu_str[32];
|
||||
opal_carto_base_node_t *tmp_node = (opal_carto_base_node_t *)node;
|
||||
if (true == tmp_node->is_cpu) {
|
||||
strcpy(cpu_str,"(CPU)");
|
||||
}
|
||||
else {
|
||||
cpu_str[0] = 0;
|
||||
}
|
||||
asprintf(&print_str,"%s %5s -%s", tmp_node->node_type, cpu_str, tmp_node->node_name);
|
||||
|
||||
return print_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to free node. this function will be assigned to
|
||||
* the free_vertex_data pointer
|
||||
*
|
||||
* @param node the node to free.
|
||||
*/
|
||||
static void opal_carto_base_free_node(void *node)
|
||||
{
|
||||
opal_carto_base_node_t *tmp_node = (opal_carto_base_node_t *)node;
|
||||
/* free the node name string */
|
||||
free(tmp_node->node_name);
|
||||
free(tmp_node->node_type);
|
||||
/* free the node */
|
||||
free(tmp_node);
|
||||
}
|
||||
|
||||
/**
|
||||
* A function to copy a node. this function will be assign in
|
||||
* the copy_vertex_data function pointer.
|
||||
*
|
||||
* @param dst the destination node.
|
||||
* @param src the source node.
|
||||
*/
|
||||
static void opal_carto_base_copy_nodes(void **dst, void *src)
|
||||
{
|
||||
opal_carto_base_node_t *src_node = (opal_carto_base_node_t *)src,
|
||||
*dst_node = (opal_carto_base_node_t *)*dst;
|
||||
|
||||
/* duplicate the node name */
|
||||
dst_node->node_name = strdup(src_node->node_name);
|
||||
/* copy the node type */
|
||||
dst_node->node_type = strdup(src_node->node_type);
|
||||
dst_node->is_cpu = src_node->is_cpu;
|
||||
/* If the nodes vertex was copied, get the copied vertex */
|
||||
dst_node->vertex = src_node->vertex->sibling;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate memory for node. this function will be assign to the
|
||||
* alloc_vertex_data function pointer.
|
||||
*
|
||||
* @return void*
|
||||
*/
|
||||
static void *opal_carto_base_alloc_node(void)
|
||||
{
|
||||
opal_carto_base_node_t *node;
|
||||
|
||||
/* allocate memory fore node */
|
||||
node = (opal_carto_base_node_t *)malloc(sizeof(opal_carto_base_node_t));
|
||||
/*Init the node fields */
|
||||
node->node_name = NULL;
|
||||
node->node_type = NULL;
|
||||
node->is_cpu = false;
|
||||
node->vertex = NULL;
|
||||
|
||||
return (void*)node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two nodes. in our case we needs to compare only the
|
||||
* node name. this function will be assign to the compare vertex
|
||||
* data function pointer.
|
||||
*
|
||||
* @param node1
|
||||
* @param node2
|
||||
*
|
||||
* @return int 0-equal, 1-the first is bigger, -1-the first is
|
||||
* smaller.
|
||||
*/
|
||||
static int opal_carto_compare_nodes(void *node1, void *node2)
|
||||
{
|
||||
opal_carto_base_node_t *tmp_node1 = (opal_carto_base_node_t *)node1,
|
||||
*tmp_node2 = (opal_carto_base_node_t *)node2;
|
||||
|
||||
/* use str compare to compare the node names */
|
||||
return strcmp(tmp_node1->node_name, tmp_node2->node_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new carto graph.
|
||||
*
|
||||
* @param graph an empty graph pointer
|
||||
*/
|
||||
void opal_carto_base_graph_create(opal_carto_graph_t **graph)
|
||||
{
|
||||
*graph = (opal_carto_graph_t *)OBJ_NEW(opal_graph_t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a node to carto graph.
|
||||
*
|
||||
* @param graph the carto graph to add the node to.
|
||||
* @param node the node to add.
|
||||
*/
|
||||
void opal_carto_base_graph_add_node(opal_carto_graph_t *graph, opal_carto_base_node_t *node)
|
||||
{
|
||||
/* construct new vertex */
|
||||
node->vertex = OBJ_NEW(opal_graph_vertex_t);
|
||||
/* assign the node as the vertex data */
|
||||
node->vertex->vertex_data = (void *)node;
|
||||
/* assign the vertex function pointers */
|
||||
node->vertex->free_vertex_data = opal_carto_base_free_node;
|
||||
node->vertex->copy_vertex_data = opal_carto_base_copy_nodes;
|
||||
node->vertex->alloc_vertex_data = opal_carto_base_alloc_node;
|
||||
node->vertex->compare_vertex = opal_carto_compare_nodes;
|
||||
node->vertex->print_vertex = opal_carto_print_node;
|
||||
/* add the new node to the carto graph by adding the nodes vertex to the graph */
|
||||
opal_graph_add_vertex((opal_graph_t *)graph, node->vertex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Free a carto graph
|
||||
* @param graph the graph we want to free.
|
||||
*/
|
||||
void opal_carto_base_free_graph(opal_carto_graph_t *graph)
|
||||
{
|
||||
int i, graph_order;
|
||||
opal_carto_base_node_t *node;
|
||||
opal_pointer_array_t *graph_vertices;
|
||||
opal_graph_vertex_t *vertex;
|
||||
|
||||
graph_vertices = OBJ_NEW(opal_pointer_array_t);
|
||||
opal_pointer_array_init(graph_vertices, 20, INT_MAX, 20);
|
||||
/* get all the graph vertices */
|
||||
graph_order = opal_graph_get_graph_vertices(graph, graph_vertices);
|
||||
/* for all the vertices in the graph, free the nodes (and distract the vertices) */
|
||||
for (i = 0; i < graph_order; i++) {
|
||||
vertex = (opal_graph_vertex_t *)opal_pointer_array_get_item(graph_vertices, i);
|
||||
node = vertex->vertex_data;
|
||||
opal_carto_base_free_node((void *)node);
|
||||
}
|
||||
OBJ_RELEASE(graph_vertices);
|
||||
/* destruct the graph */
|
||||
OBJ_RELEASE(graph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect two nodes by adding an edge to the graph.
|
||||
*
|
||||
* @param graph the graph that the nodes belongs to.
|
||||
* @param start the start node
|
||||
* @param end the end node
|
||||
* @param weight the weight of the connection
|
||||
*
|
||||
* @return int success or error (if one of the nodes does not
|
||||
* belong to the graph.
|
||||
*/
|
||||
int opal_carto_base_connect_nodes(opal_carto_graph_t *graph, opal_carto_base_node_t *start, opal_carto_base_node_t *end, uint32_t weight)
|
||||
{
|
||||
opal_graph_edge_t *edge;
|
||||
|
||||
/* construct anew edge */
|
||||
edge = OBJ_NEW(opal_graph_edge_t);
|
||||
/* assigne the start and the end nodes vertices to the new edge */
|
||||
edge->start = start->vertex;
|
||||
edge->end = end->vertex;
|
||||
/* assign the weight to the edge */
|
||||
edge->weight = weight;
|
||||
/* add the edge to the graph */
|
||||
return opal_graph_add_edge((opal_graph_t *)graph, edge);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate a carto graph and reduce the new graph to contain
|
||||
* nodes from a ceratin type(s)
|
||||
*
|
||||
* @param destination The new graph.
|
||||
* @param source the original graph.
|
||||
* @param node_type the node type(s) that the new graph will
|
||||
* include.
|
||||
*/
|
||||
void opal_carto_base_duplicate_graph(opal_carto_graph_t **destination, const opal_carto_graph_t *source, char *node_type)
|
||||
{
|
||||
opal_pointer_array_t *vertices;
|
||||
int i, graph_order;
|
||||
opal_carto_base_node_t *node;
|
||||
opal_graph_vertex_t *vertex;
|
||||
|
||||
/* duplicate the graph */
|
||||
opal_graph_duplicate((opal_graph_t **)destination, (opal_graph_t *)source);
|
||||
/* if there is no need for reduction, return */
|
||||
if (NULL == node_type) {
|
||||
return;
|
||||
}
|
||||
vertices = OBJ_NEW(opal_pointer_array_t);
|
||||
opal_pointer_array_init(vertices, 20, INT_MAX, 20);
|
||||
/* get all the vertices of the new graph */
|
||||
graph_order = opal_graph_get_graph_vertices(*destination, vertices);
|
||||
/* remove all the nodes that are not in the required type */
|
||||
for (i = 0; i < graph_order; i++ ) {
|
||||
vertex = (opal_graph_vertex_t *)opal_pointer_array_get_item(vertices, i);
|
||||
node = vertex->vertex_data;
|
||||
if (!(0 == strcmp(node_type, node->node_type) || node->is_cpu)) {
|
||||
opal_graph_remove_vertex(*destination, vertex);
|
||||
}
|
||||
}
|
||||
/* free the vertices array */
|
||||
OBJ_RELEASE(vertices);
|
||||
}
|
||||
|
||||
/**
|
||||
* opal_carto_base_get_nodes_distance - returns the distance of
|
||||
* all the nodes from the reference node.
|
||||
*
|
||||
* @param graph
|
||||
* @param reference_node
|
||||
* @param node_type the type of the nodes in the returned array
|
||||
* @param dist_array
|
||||
*
|
||||
* @return int number of nodes in the returned array.
|
||||
*/
|
||||
int opal_carto_base_get_nodes_distance(opal_carto_graph_t *graph, opal_carto_base_node_t *reference_node,
|
||||
char *node_type, opal_value_array_t *dist_array)
|
||||
{
|
||||
opal_value_array_t *distance_array;
|
||||
vertex_distance_from_t *vertex_distance;
|
||||
opal_carto_base_node_t *node;
|
||||
uint32_t i, graph_order;
|
||||
int distance_array_size;
|
||||
opal_carto_node_distance_t node_distance;
|
||||
|
||||
|
||||
distance_array = OBJ_NEW(opal_value_array_t);
|
||||
opal_value_array_init(distance_array, sizeof(vertex_distance_from_t));
|
||||
opal_value_array_reserve(distance_array,50);
|
||||
/* use dijkstra algorithm to receive the distance of all the nodes from the referenced node */
|
||||
graph_order = dijkstra(graph, reference_node->vertex, distance_array);
|
||||
/* for all the nodes in the dijkstra array */
|
||||
for (i = 0, distance_array_size = 0; i < graph_order; i++) {
|
||||
vertex_distance = opal_value_array_get_item(distance_array, i);
|
||||
node = vertex_distance->vertex->vertex_data;
|
||||
/* check if the node is in the correct type */
|
||||
if (NULL == node_type || 0 == strcmp(node->node_type, node_type)) {
|
||||
/* assigne the result distance array */
|
||||
node_distance.node = vertex_distance->vertex->vertex_data;
|
||||
node_distance.node_distance = vertex_distance->weight;
|
||||
opal_value_array_append_item(dist_array, (void *)&node_distance);
|
||||
}
|
||||
}
|
||||
/* return the result distance array */
|
||||
return distance_array_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the shortest path between two nodes in the graph
|
||||
*
|
||||
* @param graph the graph that the nodes belongs to.
|
||||
* @param node1 first node.
|
||||
* @param node2 second node.
|
||||
*
|
||||
* @return uint32_t he distance between the nodes.
|
||||
*/
|
||||
uint32_t opal_carto_base_graph_spf(opal_carto_graph_t *graph, opal_carto_base_node_t *node1, opal_carto_base_node_t *node2)
|
||||
{
|
||||
return opal_graph_spf((opal_graph_t *)graph, node1->vertex, node2->vertex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a node in the graph according to its name.
|
||||
*
|
||||
* @param graph the graph in which we are searching.
|
||||
* @param node_name the node name.
|
||||
*
|
||||
* @return opal_carto_base_node_t* the node with the name -if
|
||||
* found or NULL.
|
||||
*/
|
||||
opal_carto_base_node_t *opal_carto_base_graph_find_node(opal_carto_graph_t *graph, char *node_name)
|
||||
{
|
||||
opal_carto_base_node_t node;
|
||||
opal_graph_vertex_t *vertex;
|
||||
|
||||
/* build a temporary node */
|
||||
node.node_name = node_name;
|
||||
/**
|
||||
* find a vertex in the graph. the find_vertex uses the
|
||||
* compare_vertex_data method. in our case, compare_vertex_data
|
||||
* is assigned to opal_carto_compare_nodes that compares two
|
||||
* nodes names.
|
||||
*/
|
||||
vertex = opal_graph_find_vertex((opal_graph_t *)graph, (void *)&node);
|
||||
if (NULL != vertex) {
|
||||
/* return the fund vertex data (node) */
|
||||
return vertex->vertex_data;
|
||||
}
|
||||
/* if not found, return NULL */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a carto graph (for debug uses)
|
||||
*
|
||||
* @param graph the graph we want to print.
|
||||
*/
|
||||
void opal_carto_print_graph(opal_carto_graph_t *graph)
|
||||
{
|
||||
opal_graph_print(graph);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the host cartography graph.
|
||||
*
|
||||
* @param graph an unallocated pointer to a graph.
|
||||
* @param graph_type the type of nodes we want the returned
|
||||
* graph will contain.
|
||||
*
|
||||
* @return int success or error
|
||||
*/
|
||||
int opal_carto_base_graph_get_host_graph(opal_carto_graph_t **graph, char *graph_type)
|
||||
{
|
||||
/* duplicate the host graph and delete all the relevant nodes */
|
||||
opal_carto_base_duplicate_graph(graph, carto_base_common_host_graph, graph_type);
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
133
opal/mca/carto/base/carto_base_graph.h
Обычный файл
133
opal/mca/carto/base/carto_base_graph.h
Обычный файл
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OPAL_CARTO_BASE_GRAPH_H
|
||||
#define OPAL_CARTO_BASE_GRAPH_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/carto/carto.h"
|
||||
|
||||
extern opal_carto_graph_t *carto_base_common_host_graph;
|
||||
|
||||
/**
|
||||
* Create new carto graph.
|
||||
*
|
||||
* @param graph an empty graph pointer
|
||||
*/
|
||||
void opal_carto_base_graph_create(opal_carto_graph_t **graph);
|
||||
|
||||
/**
|
||||
* Add a node to carto graph.
|
||||
*
|
||||
* @param graph the carto graph to add the node to.
|
||||
* @param node the node to add.
|
||||
*/
|
||||
void opal_carto_base_graph_add_node(opal_carto_graph_t *graph, opal_carto_base_node_t *node);
|
||||
|
||||
/**
|
||||
* Free a carto graph
|
||||
* @param graph the graph we want to free.
|
||||
*/
|
||||
void opal_carto_base_free_graph(opal_carto_graph_t *graph);
|
||||
|
||||
/**
|
||||
* Connect two nodes by adding an edge to the graph.
|
||||
*
|
||||
* @param graph the graph that the nodes belongs to.
|
||||
* @param start the start node
|
||||
* @param end the end node
|
||||
* @param weight the weight of the connection
|
||||
*
|
||||
* @return int success or error (if one of the nodes does not
|
||||
* belong to the graph.
|
||||
*/
|
||||
int opal_carto_base_connect_nodes(opal_carto_graph_t *graph, opal_carto_base_node_t *start,
|
||||
opal_carto_base_node_t *end, uint32_t weight);
|
||||
|
||||
/**
|
||||
* Duplicate a carto graph and reduce the new graph to contain
|
||||
* nodes from a ceratin type(s)
|
||||
*
|
||||
* @param destination The new graph.
|
||||
* @param source the original graph.
|
||||
* @param node_type the node type(s) that the new graph will
|
||||
* include.
|
||||
*/
|
||||
void opal_carto_base_duplicate_graph(opal_carto_graph_t **destination, const opal_carto_graph_t *source,
|
||||
char *node_type);
|
||||
|
||||
|
||||
/**
|
||||
* opal_carto_base_get_nodes_distance - returns the distance of
|
||||
* all the nodes from the reference node.
|
||||
*
|
||||
* @param graph
|
||||
* @param reference_node
|
||||
* @param node_type the type of the nodes in the returned array
|
||||
* @param dist_array
|
||||
*
|
||||
* @return int number of nodes in the returned array.
|
||||
*/
|
||||
int opal_carto_base_get_nodes_distance(opal_carto_graph_t *graph, opal_carto_base_node_t *reference_node,
|
||||
char *node_type, opal_value_array_t *dist_array);
|
||||
|
||||
/**
|
||||
* Find the shortest path between two nodes in the graph
|
||||
*
|
||||
* @param graph the graph that the nodes belongs to.
|
||||
* @param node1 first node.
|
||||
* @param node2 second node.
|
||||
*
|
||||
* @return uint32_t he distance between the nodes.
|
||||
*/
|
||||
uint32_t opal_carto_base_graph_spf(opal_carto_graph_t *graph, opal_carto_base_node_t *node1,
|
||||
opal_carto_base_node_t *node2);
|
||||
|
||||
/**
|
||||
* Find a node in the graph according to its name.
|
||||
*
|
||||
* @param graph the graph in which we are searching.
|
||||
* @param node_name the node name.
|
||||
*
|
||||
* @return opal_carto_base_node_t* the node with the name -if
|
||||
* found or NULL.
|
||||
*/
|
||||
opal_carto_base_node_t *opal_carto_base_graph_find_node(opal_carto_graph_t *graph, char *node_name);
|
||||
|
||||
/**
|
||||
* Print a carto graph (for debug uses)
|
||||
*
|
||||
* @param graph the graph we want to print.
|
||||
*/
|
||||
void opal_carto_print_graph(opal_carto_graph_t *graph);
|
||||
|
||||
/**
|
||||
* Get the host cartography graph.
|
||||
*
|
||||
* @param graph an unallocated pointer to a graph.
|
||||
* @param graph_type the type of nodes we want the returned
|
||||
* graph will contain.
|
||||
*
|
||||
* @return int success or error
|
||||
*/
|
||||
int opal_carto_base_graph_get_host_graph(opal_carto_graph_t **graph, char * graph_type);
|
||||
|
||||
#endif
|
84
opal/mca/carto/base/carto_base_open.c
Исполняемый файл
84
opal/mca/carto/base/carto_base_open.c
Исполняемый файл
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
# Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
|
||||
|
||||
/*
|
||||
* The following file was created by configure. It contains extern
|
||||
* statements and the definition of an array of pointers to each
|
||||
* component's public mca_base_component_t struct.
|
||||
*/
|
||||
#include "opal/mca/carto/base/static-components.h"
|
||||
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
int opal_carto_base_output = -1;
|
||||
bool opal_carto_base_components_opened_valid = false;
|
||||
opal_list_t opal_carto_base_components_opened;
|
||||
|
||||
|
||||
/*
|
||||
* Function for finding and opening either all MCA components, or the one
|
||||
* that was specifically requested via a MCA parameter.
|
||||
*/
|
||||
int opal_carto_base_open(void)
|
||||
{
|
||||
int value;
|
||||
|
||||
/* Debugging / verbose output */
|
||||
|
||||
mca_base_param_reg_int_name("carto", "base_verbose",
|
||||
"Verbosity level of the carto framework",
|
||||
false, false,
|
||||
0, &value);
|
||||
if (0 != value) {
|
||||
opal_carto_base_output = opal_output_open(NULL);
|
||||
} else {
|
||||
opal_carto_base_output = -1;
|
||||
}
|
||||
|
||||
opal_carto_base_components_opened_valid = false;
|
||||
|
||||
/* Open up all available components */
|
||||
|
||||
if (OPAL_SUCCESS !=
|
||||
mca_base_components_open("carto", opal_carto_base_output,
|
||||
mca_carto_base_static_components,
|
||||
&opal_carto_base_components_opened,
|
||||
true)) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
opal_carto_base_components_opened_valid = true;
|
||||
|
||||
/* All done */
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
148
opal/mca/carto/base/carto_base_select.c
Исполняемый файл
148
opal/mca/carto/base/carto_base_select.c
Исполняемый файл
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/util/output.h"
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
|
||||
/*
|
||||
* Globals
|
||||
*/
|
||||
bool opal_carto_base_selected = false;
|
||||
const opal_carto_base_component_1_0_0_t *opal_carto_base_component = NULL;
|
||||
const opal_carto_base_module_1_0_0_t *opal_carto_base_module = NULL;
|
||||
|
||||
|
||||
int opal_carto_base_select(void)
|
||||
{
|
||||
int priority = 0, best_priority = 0;
|
||||
opal_list_item_t *item = NULL;
|
||||
mca_base_component_list_item_t *cli = NULL;
|
||||
opal_carto_base_component_1_0_0_t *component = NULL,
|
||||
*best_component = NULL;
|
||||
const opal_carto_base_module_1_0_0_t *module = NULL,
|
||||
*best_module = NULL;
|
||||
char *value;
|
||||
|
||||
/* Register the framework MCA param and look it up */
|
||||
|
||||
mca_base_param_reg_string_name("carto", NULL,
|
||||
"Which carto component to use (empty = auto-select)",
|
||||
false, false,
|
||||
NULL, &value);
|
||||
|
||||
if (NULL == value || 0 == strlen(value)) {
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: auto-selecting");
|
||||
} else {
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: looking for %s component",
|
||||
value);
|
||||
}
|
||||
|
||||
/* Traverse the list of available components; call their init
|
||||
functions. */
|
||||
|
||||
best_priority = -1;
|
||||
best_component = NULL;
|
||||
module = NULL;
|
||||
for (item = opal_list_get_first(&opal_carto_base_components_opened);
|
||||
opal_list_get_end(&opal_carto_base_components_opened) != item;
|
||||
item = opal_list_get_next(item) ) {
|
||||
cli = (mca_base_component_list_item_t *) item;
|
||||
component = (opal_carto_base_component_1_0_0_t *) cli->cli_component;
|
||||
|
||||
/* if there is an include list - item must be in the list to
|
||||
be included */
|
||||
|
||||
if (NULL != value && strlen(value) > 0 &&
|
||||
0 != strcmp(component->cartoc_version.mca_component_name,
|
||||
value)) {
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: skipping %s component",
|
||||
component->cartoc_version.mca_component_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (NULL == component->cartoc_query) {
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: no init function; ignoring component %s",
|
||||
component->cartoc_version.mca_component_name );
|
||||
continue;
|
||||
}
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: initializing component %s",
|
||||
component->cartoc_version.mca_component_name);
|
||||
module = component->cartoc_query(&priority);
|
||||
if (NULL == module) {
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: init returned failure for component %s",
|
||||
component->cartoc_version.mca_component_name );
|
||||
continue;
|
||||
}
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: init returned priority %d",
|
||||
priority );
|
||||
if (priority > best_priority) {
|
||||
best_priority = priority;
|
||||
best_component = component;
|
||||
best_module = module;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finished querying all components. Check for the bozo case. */
|
||||
|
||||
if (NULL == best_component ) {
|
||||
return OPAL_ERR_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* Now go through the opened list and close all the non-selected
|
||||
components */
|
||||
|
||||
mca_base_components_close(opal_carto_base_output,
|
||||
&opal_carto_base_components_opened,
|
||||
(mca_base_component_t *) best_component);
|
||||
|
||||
/* Save the winner */
|
||||
|
||||
opal_carto_base_component = best_component;
|
||||
opal_carto_base_module = best_module;
|
||||
opal_output_verbose(10, opal_carto_base_output,
|
||||
"carto:select: component %s selected",
|
||||
best_component->cartoc_version.mca_component_name);
|
||||
opal_carto_base_selected = true;
|
||||
|
||||
/* Initialize the winner */
|
||||
|
||||
if (NULL != opal_carto_base_module) {
|
||||
if (OPAL_SUCCESS != opal_carto_base_module->carto_module_init()) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
18
opal/mca/carto/base/static-components.h
Исполняемый файл
18
opal/mca/carto/base/static-components.h
Исполняемый файл
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* $HEADER$
|
||||
*/
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
const mca_base_component_t *mca_carto_base_static_components[] = {
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
172
opal/mca/carto/carto.h
Исполняемый файл
172
opal/mca/carto/carto.h
Исполняемый файл
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The carto framework suplies an information of the the host structure and connection between the
|
||||
* host components i.e memory nodes,CPUs, Ethernet port and inifiniband ports.
|
||||
*/
|
||||
|
||||
#ifndef OPAL_CARTO_H
|
||||
#define OPAL_CARTO_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/base/base.h"
|
||||
#include "opal/class/opal_graph.h"
|
||||
|
||||
|
||||
/**
|
||||
* Query function for carto components. Simply returns a priority
|
||||
* to rank it against other available carto components (assumedly,
|
||||
* only one component will be available per platform, but it's
|
||||
* possible that there could be more than one available).
|
||||
*/
|
||||
typedef const struct opal_carto_base_module_1_0_0_t *
|
||||
(*opal_carto_base_component_query_1_0_0_fn_t)
|
||||
(int *priority);
|
||||
|
||||
/**
|
||||
* type for carto graph
|
||||
*/
|
||||
typedef opal_graph_t opal_carto_graph_t;
|
||||
|
||||
/* A structure of carto node */
|
||||
struct opal_carto_base_node_t {
|
||||
opal_graph_vertex_t *vertex; /* the parent of a node is a graph vertex */
|
||||
char *node_name;
|
||||
char *node_type; /* the type of the node */
|
||||
bool is_cpu;
|
||||
};
|
||||
|
||||
/**
|
||||
* A definition of carto node type.
|
||||
*/
|
||||
typedef struct opal_carto_base_node_t opal_carto_base_node_t;
|
||||
|
||||
|
||||
/**
|
||||
* A structure of node distance from some other node
|
||||
*/
|
||||
struct opal_carto_node_distance_t {
|
||||
opal_carto_base_node_t *node; /* The node */
|
||||
uint32_t node_distance; /* and the distance */
|
||||
};
|
||||
|
||||
/**
|
||||
* A definition of node distance type.
|
||||
*/
|
||||
typedef struct opal_carto_node_distance_t opal_carto_node_distance_t;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Module initialization function. Should return OPAL_SUCCESS.
|
||||
*/
|
||||
typedef int (*opal_carto_base_module_init_1_0_0_fn_t)(void);
|
||||
|
||||
/**
|
||||
* Get the local host graph. you can reduce the graph for only
|
||||
* the nodes that interst you using the node type.
|
||||
*/
|
||||
typedef int (*opal_carto_base_get_host_graph_fn_t)
|
||||
(opal_carto_graph_t **graph, char *graph_type);
|
||||
|
||||
/**
|
||||
* Frre a graph
|
||||
*/
|
||||
typedef void (*opal_carto_base_free_graph_fn_t)
|
||||
(opal_carto_graph_t *graph);
|
||||
|
||||
/**
|
||||
* Get the distance (weight) from a start node to all other
|
||||
* nodes. you can reduce the list to the list to the node types
|
||||
* that intersts you.
|
||||
*/
|
||||
typedef int (*opal_carto_base_get_nodes_distance_fn_t)
|
||||
(opal_carto_graph_t *graph, opal_carto_base_node_t *start, char *node_type, opal_value_array_t *distance_);
|
||||
|
||||
/**
|
||||
* find the distance between two nodes.
|
||||
*/
|
||||
typedef uint32_t (*opal_carto_base_spf_fn_t)
|
||||
(opal_carto_graph_t *graph,opal_carto_base_node_t *start, opal_carto_base_node_t *end);
|
||||
|
||||
|
||||
/**
|
||||
* Module finalize function. Invoked by the base on the selected
|
||||
* module when the carto framework is being shut down.
|
||||
*/
|
||||
typedef int (*opal_carto_base_module_finalize_fn_t)(void);
|
||||
|
||||
|
||||
/**
|
||||
* Structure for carto v1.1.0 components.
|
||||
* Chained to MCA v1.0.0
|
||||
*/
|
||||
struct opal_carto_base_component_1_0_0_t {
|
||||
/** MCA base component */
|
||||
mca_base_component_t cartoc_version;
|
||||
/** MCA base data */
|
||||
mca_base_component_data_1_0_0_t cartoc_data;
|
||||
|
||||
/** Component query function */
|
||||
opal_carto_base_component_query_1_0_0_fn_t cartoc_query;
|
||||
};
|
||||
/**
|
||||
* Convenience typedef
|
||||
*/
|
||||
typedef struct opal_carto_base_component_1_0_0_t opal_carto_base_component_1_0_0_t;
|
||||
|
||||
|
||||
/**
|
||||
* Structure for carto v1.0.0 modules
|
||||
*/
|
||||
struct opal_carto_base_module_1_0_0_t {
|
||||
|
||||
/** Module initialization function */
|
||||
opal_carto_base_module_init_1_0_0_fn_t carto_module_init;
|
||||
/** Get host graph */
|
||||
opal_carto_base_get_host_graph_fn_t get_host_graph;
|
||||
/** free graph */
|
||||
opal_carto_base_free_graph_fn_t free_graph;
|
||||
/** Get the distance from one node to all other nodes */
|
||||
opal_carto_base_get_nodes_distance_fn_t get_nodes_distance;
|
||||
/** Find the distance between two nodes */
|
||||
opal_carto_base_spf_fn_t spf;
|
||||
/** Shut down this module */
|
||||
opal_carto_base_module_finalize_fn_t carto_module_finalize;
|
||||
};
|
||||
/**
|
||||
* Convenience typedef
|
||||
*/
|
||||
typedef struct opal_carto_base_module_1_0_0_t opal_carto_base_module_1_0_0_t;
|
||||
|
||||
|
||||
/*
|
||||
* Macro for use in components that are of type carto v1.1.0
|
||||
*/
|
||||
#define OPAL_CARTO_BASE_VERSION_1_0_0 \
|
||||
/* carto v1.1 is chained to MCA v1.0 */ \
|
||||
MCA_BASE_VERSION_1_0_0, \
|
||||
/* carto v1.0 */ \
|
||||
"carto", 1, 0, 0
|
||||
|
||||
#endif /* OPAL_CARTO_H */
|
55
opal/mca/carto/file/Makefile.am
Исполняемый файл
55
opal/mca/carto/file/Makefile.am
Исполняемый файл
@ -0,0 +1,55 @@
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2007 Cisco Systems, Inc. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
AM_LFLAGS = -Pcarto_file_
|
||||
LEX_OUTPUT_ROOT = lex.carto_file_
|
||||
|
||||
dist_pkgdata_DATA = \
|
||||
help-opal-carto-file.txt
|
||||
|
||||
|
||||
sources = \
|
||||
carto_file.h \
|
||||
carto_file_lex.h \
|
||||
carto_file_lex.l \
|
||||
carto_file_component.c \
|
||||
carto_file_module.c
|
||||
|
||||
# Make the output library in this directory, and name it either
|
||||
# mca_<type>_<name>.la (for DSO builds) or libmca_<type>_<name>.la
|
||||
# (for static builds).
|
||||
|
||||
if OMPI_BUILD_carto_file_DSO
|
||||
component_noinst =
|
||||
component_install = mca_carto_file.la
|
||||
else
|
||||
component_noinst = libmca_carto_file.la
|
||||
component_install =
|
||||
endif
|
||||
|
||||
mcacomponentdir = $(pkglibdir)
|
||||
mcacomponent_LTLIBRARIES = $(component_install)
|
||||
mca_carto_file_la_SOURCES = $(sources)
|
||||
mca_carto_file_la_LDFLAGS = -module -avoid-version
|
||||
mca_carto_file_la_LIBADD = \
|
||||
$(top_ompi_builddir)/opal/libopen-pal.la
|
||||
|
||||
noinst_LTLIBRARIES = $(component_noinst)
|
||||
libmca_carto_file_la_SOURCES =$(sources)
|
||||
libmca_carto_file_la_LDFLAGS = -module -avoid-version
|
107
opal/mca/carto/file/carto_file.h
Исполняемый файл
107
opal/mca/carto/file/carto_file.h
Исполняемый файл
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* The file component uses a cartograpy file to discover the
|
||||
* host cartography.
|
||||
*
|
||||
* An example cartography file:
|
||||
*
|
||||
|
||||
# This is a comment
|
||||
# Node declaration Node type (Free string) Node name (Free string)
|
||||
# (Reserve word) (slot is a reserve word (free string)
|
||||
# for CPU slot)
|
||||
#=======================================================================
|
||||
NODE Memory mem0
|
||||
NODE Memory mem1
|
||||
NODE Memory mem2
|
||||
NODE Memory mem3
|
||||
#
|
||||
NODE slot slot0
|
||||
NODE slot slot1
|
||||
NODE slot slot2
|
||||
NODE slot slot3
|
||||
#
|
||||
NODE Infiniband mthca0
|
||||
NODE Infiniband mthca1
|
||||
#
|
||||
NODE Ethernet eth0
|
||||
NODE Ethernet eth1
|
||||
#
|
||||
#
|
||||
# Connection decleration From node To node:weight To node:weight ......
|
||||
# (Reserve word) (declered (declered (declered
|
||||
# above) above) above)
|
||||
#===============================================================================================
|
||||
CONNECTION mem0 slot0:0
|
||||
CONNECTION mem1 slot1:0
|
||||
CONNECTION mem2 slot2:0
|
||||
CONNECTION mem3 slot3:0
|
||||
CONNECTION slot0 mem0:0 slot1:1 slot2:1 mthca0:1 eth0:1
|
||||
CONNECTION slot1 mem1:0 slot0:1 slot3:1
|
||||
CONNECTION slot2 mem2:0 slot1:1 slot3:1
|
||||
CONNECTION slot3 mem3:0 slot1:1 slot2:1 mthca1:1 eth1:1
|
||||
#
|
||||
CONNECTION mthca0 slot0:1
|
||||
CONNECTION mthca1 slot3:1
|
||||
#
|
||||
CONNECTION eth0 slot0:1
|
||||
CONNECTION eth1 slot3:1
|
||||
#
|
||||
# end of carto file.
|
||||
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MCA_CARTO_FILE_H
|
||||
#define MCA_CARTO_FILE_H
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/mca/mca.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
extern char *carto_file_path;
|
||||
|
||||
/**
|
||||
* Globally exported variable
|
||||
*/
|
||||
OPAL_DECLSPEC extern const opal_carto_base_component_1_0_0_t
|
||||
mca_carto_file_component;
|
||||
|
||||
|
||||
/**
|
||||
* carto query API function
|
||||
*/
|
||||
const opal_carto_base_module_1_0_0_t *
|
||||
opal_carto_file_component_query(int *query);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /* MCA_CARTO_FILE_EXPORT_H */
|
110
opal/mca/carto/file/carto_file_component.c
Исполняемый файл
110
opal/mca/carto/file/carto_file_component.c
Исполняемый файл
@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2007 Cisco, Inc. All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
* These symbols are in a file by themselves to provide nice linker
|
||||
* semantics. Since linkers generally pull in symbols by object
|
||||
* files, keeping these symbols as the only symbols in this file
|
||||
* prevents utility programs such as "ompi_info" from having to import
|
||||
* entire components just to query their version and parameters.
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "carto_file.h"
|
||||
|
||||
/*
|
||||
* Public string showing the carto ompi_file component version number
|
||||
*/
|
||||
const char *opal_carto_file_component_version_string =
|
||||
"OPAL file carto MCA component version " OPAL_VERSION;
|
||||
|
||||
/*
|
||||
* Local function
|
||||
*/
|
||||
static int file_open(void);
|
||||
|
||||
/*
|
||||
* Instantiate the public struct with all of our public information
|
||||
* and pointers to our public functions in it
|
||||
*/
|
||||
|
||||
const opal_carto_base_component_1_0_0_t mca_carto_file_component = {
|
||||
|
||||
/* First, the mca_component_t struct containing meta information
|
||||
about the component itself */
|
||||
|
||||
{
|
||||
/* Indicate that we are a carto v1.1.0 component (which also
|
||||
implies a specific MCA version) */
|
||||
|
||||
OPAL_CARTO_BASE_VERSION_1_0_0,
|
||||
|
||||
/* Component name and version */
|
||||
|
||||
"file",
|
||||
OPAL_MAJOR_VERSION,
|
||||
OPAL_MINOR_VERSION,
|
||||
OPAL_RELEASE_VERSION,
|
||||
|
||||
/* Component open and close functions */
|
||||
|
||||
file_open,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
|
||||
/* The component is checkpoint ready */
|
||||
MCA_BASE_METADATA_PARAM_CHECKPOINT
|
||||
},
|
||||
|
||||
/* Query function */
|
||||
|
||||
opal_carto_file_component_query
|
||||
};
|
||||
|
||||
|
||||
static int file_open(void)
|
||||
{
|
||||
int index;
|
||||
|
||||
mca_base_param_reg_int(&mca_carto_file_component.cartoc_version,
|
||||
"priority",
|
||||
"Priority of the file carto component",
|
||||
false, false, 10, NULL);
|
||||
|
||||
mca_base_param_reg_string(&mca_carto_file_component.cartoc_version,
|
||||
"path",
|
||||
"The path to the cartography file",
|
||||
false, false, NULL, &carto_file_path);
|
||||
/**
|
||||
* If the user specified the carto file path (not NULL), use the
|
||||
* carto file component. The auto detect component is with
|
||||
* higher priority, so by default it will be chosen.
|
||||
*/
|
||||
if (NULL != carto_file_path) {
|
||||
index = mca_base_param_find("carto",NULL,NULL);
|
||||
if (index != OPAL_ERROR) {
|
||||
/* set the "carto" mca parameter to "file" */
|
||||
mca_base_param_set_string(index,"file");
|
||||
}
|
||||
}
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
1798
opal/mca/carto/file/carto_file_lex.c
Обычный файл
1798
opal/mca/carto/file/carto_file_lex.c
Обычный файл
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
67
opal/mca/carto/file/carto_file_lex.h
Обычный файл
67
opal/mca/carto/file/carto_file_lex.h
Обычный файл
@ -0,0 +1,67 @@
|
||||
/* -*- C -*-
|
||||
*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#ifndef CARTO_FILE_LEX_LEX_H_
|
||||
#define CARTO_FILE_LEX_LEX_H_
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
#ifdef malloc
|
||||
#undef malloc
|
||||
#endif
|
||||
#ifdef realloc
|
||||
#undef realloc
|
||||
#endif
|
||||
#ifdef free
|
||||
#undef free
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
typedef union {
|
||||
int ival;
|
||||
char* sval;
|
||||
} orte_rds_value_t;
|
||||
|
||||
extern int carto_file_lex(void);
|
||||
extern FILE *carto_file_in;
|
||||
extern int carto_file_line;
|
||||
extern bool carto_file_done;
|
||||
extern orte_rds_value_t carto_file_value;
|
||||
|
||||
/*
|
||||
* Make lex-generated files not issue compiler warnings
|
||||
*/
|
||||
#define YY_STACK_USED 0
|
||||
#define YY_ALWAYS_INTERACTIVE 0
|
||||
#define YY_NEVER_INTERACTIVE 0
|
||||
#define YY_MAIN 0
|
||||
#define YY_NO_UNPUT 1
|
||||
#define YY_SKIP_YYWRAP 1
|
||||
|
||||
#define OPAL_CARTO_FILE_NEWLINE 0
|
||||
#define OPAL_CARTO_FILE_ERROR 1
|
||||
#define OPAL_CARTO_FILE_NODE_DECELERATION 2
|
||||
#define OPAL_CARTO_FILE_CONNECTION_DECELERATION 3
|
||||
#define OPAL_CARTO_FILE_INT 4
|
||||
#define OPAL_CARTO_FILE_NAME 5
|
||||
#define OPAL_CARTO_FILE_NODE_CONNECTION 6
|
||||
|
||||
#endif
|
||||
|
101
opal/mca/carto/file/carto_file_lex.l
Обычный файл
101
opal/mca/carto/file/carto_file_lex.l
Обычный файл
@ -0,0 +1,101 @@
|
||||
%{ /* -*- C -*- */
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2006 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
#include "opal_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "opal/mca/carto/file/carto_file_lex.h"
|
||||
|
||||
/*
|
||||
* local functions
|
||||
*/
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif /* defined(c_plusplus) || defined(__cplusplus) */
|
||||
|
||||
int carto_file_wrap(void);
|
||||
|
||||
#if defined(c_plusplus) || defined(__cplusplus)
|
||||
}
|
||||
#endif /* defined(c_plusplus) || defined(__cplusplus) */
|
||||
|
||||
int carto_file_wrap(void)
|
||||
{
|
||||
carto_file_done = true;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* global variables
|
||||
*/
|
||||
int carto_file_line=1;
|
||||
orte_rds_value_t carto_file_value;
|
||||
bool carto_file_done = false;
|
||||
|
||||
%}
|
||||
|
||||
WHITE [\f\t\v ]
|
||||
|
||||
%x comment
|
||||
|
||||
%%
|
||||
|
||||
{WHITE}*\n { carto_file_line++;
|
||||
return OPAL_CARTO_FILE_NEWLINE; }
|
||||
#.*\n { carto_file_line++;
|
||||
return OPAL_CARTO_FILE_NEWLINE; }
|
||||
"//".*\n { carto_file_line++;
|
||||
return OPAL_CARTO_FILE_NEWLINE; }
|
||||
|
||||
"/*" { BEGIN(comment);
|
||||
return OPAL_CARTO_FILE_NEWLINE; }
|
||||
<comment>[^*\n]* ; /* Eat up non '*'s */
|
||||
<comment>"*"+[^*/\n]* ; /* Eat '*'s not followed by a '/' */
|
||||
<comment>\n { carto_file_line++;
|
||||
return OPAL_CARTO_FILE_NEWLINE; }
|
||||
<comment>"*"+"/" { BEGIN(INITIAL); /* Done with Block Comment */
|
||||
return OPAL_CARTO_FILE_NEWLINE; }
|
||||
|
||||
{WHITE}+ ; /* whitespace */
|
||||
|
||||
|
||||
|
||||
|
||||
NODE { carto_file_value.sval = yytext;
|
||||
return OPAL_CARTO_FILE_NODE_DECELERATION; }
|
||||
|
||||
CONNECTION { carto_file_value.sval = yytext;
|
||||
return OPAL_CARTO_FILE_CONNECTION_DECELERATION; }
|
||||
|
||||
[0-9] { carto_file_value.ival = atol(yytext);
|
||||
return OPAL_CARTO_FILE_INT; }
|
||||
|
||||
[A-Za-z0-9_-]* { carto_file_value.sval = yytext;
|
||||
return OPAL_CARTO_FILE_NAME; }
|
||||
|
||||
|
||||
([[A-Za-z0-9_\-]*)+":"([0-9]*) { carto_file_value.sval = yytext;
|
||||
return OPAL_CARTO_FILE_NODE_CONNECTION; }
|
||||
|
||||
|
||||
%%
|
||||
|
257
opal/mca/carto/file/carto_file_module.c
Исполняемый файл
257
opal/mca/carto/file/carto_file_module.c
Исполняемый файл
@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
||||
*
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*/
|
||||
|
||||
#include "opal_config.h"
|
||||
|
||||
/* This component will only be compiled on File, where we are
|
||||
guaranteed to have <unistd.h> and friends */
|
||||
#include <stdio.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "opal/constants.h"
|
||||
#include "opal/mca/base/mca_base_param.h"
|
||||
#include "opal/util/argv.h"
|
||||
#include "opal/util/show_help.h"
|
||||
#include "opal/mca/carto/carto.h"
|
||||
#include "opal/mca/carto/base/base.h"
|
||||
#include "opal/mca/carto/base/carto_base_graph.h"
|
||||
#include "carto_file.h"
|
||||
#include "carto_file_lex.h"
|
||||
|
||||
|
||||
|
||||
char *carto_file_path;
|
||||
|
||||
static int opal_carto_file_init(void);
|
||||
static int opal_carto_file_finalize(void);
|
||||
static int opal_carto_file_parse(const char *cartofile);
|
||||
|
||||
|
||||
/*
|
||||
* File carto module
|
||||
*/
|
||||
static const opal_carto_base_module_1_0_0_t module = {
|
||||
opal_carto_file_init,
|
||||
opal_carto_base_graph_get_host_graph,
|
||||
opal_carto_base_free_graph,
|
||||
opal_carto_base_get_nodes_distance,
|
||||
opal_carto_base_graph_spf,
|
||||
opal_carto_file_finalize,
|
||||
};
|
||||
|
||||
|
||||
const opal_carto_base_module_1_0_0_t *
|
||||
opal_carto_file_component_query(int *query)
|
||||
{
|
||||
int param;
|
||||
|
||||
param = mca_base_param_find("carto", "file", "priority");
|
||||
mca_base_param_lookup_int(param, query);
|
||||
|
||||
param = mca_base_param_find("carto", "file", "path");
|
||||
mca_base_param_lookup_string(param, &carto_file_path);
|
||||
|
||||
return &module;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Init the carto file module.
|
||||
*
|
||||
* @return int success or error
|
||||
*/
|
||||
static int opal_carto_file_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* create an empty graph */
|
||||
opal_carto_base_graph_create(&carto_base_common_host_graph);
|
||||
if (NULL == carto_file_path) {
|
||||
return OPAL_ERROR;
|
||||
}
|
||||
/* parse the carto file and add nodes and connections to the graph */
|
||||
rc = opal_carto_file_parse(carto_file_path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* finalize the carto file module.
|
||||
*
|
||||
* @return int success or error
|
||||
*/
|
||||
static int opal_carto_file_finalize(void)
|
||||
{
|
||||
/* free the host cartography graph. */
|
||||
opal_carto_base_free_graph(carto_base_common_host_graph);
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse the carto file and file the host graph with nodes and
|
||||
* connections.
|
||||
*
|
||||
* @param cartofile the path to the carto file.
|
||||
*
|
||||
* @return int success or error.
|
||||
*/
|
||||
static int opal_carto_file_parse(const char *cartofile)
|
||||
{
|
||||
int token;
|
||||
opal_carto_base_node_t *node, *end_node;
|
||||
uint32_t weight;
|
||||
char *node1_name, *node2_name, *value, **argv;
|
||||
int cnt, line_number = 1;
|
||||
char *token_to_string[] = {
|
||||
"New-line",
|
||||
"File-error",
|
||||
"Node deceleration",
|
||||
"Connection deceleration",
|
||||
"Integer",
|
||||
"Name",
|
||||
"Node connection",
|
||||
"Undefined"
|
||||
};
|
||||
|
||||
/* set the done flag to false. at the end of file the the lexical analyzer will set it to true */
|
||||
carto_file_done = false;
|
||||
carto_file_in = fopen(cartofile, "r"); /* open the carto file */
|
||||
/* if the file not found, return an error */
|
||||
if (NULL == carto_file_in) {
|
||||
opal_show_help("help-opal-carto-file.txt", "expected node name", true, cartofile);
|
||||
return OPAL_ERR_NOT_FOUND;
|
||||
}
|
||||
while (!carto_file_done) {
|
||||
token = carto_file_lex();
|
||||
switch (token) {
|
||||
case OPAL_CARTO_FILE_NEWLINE:
|
||||
line_number++;
|
||||
break;
|
||||
case OPAL_CARTO_FILE_NODE_DECELERATION:
|
||||
token = carto_file_lex();
|
||||
switch (token) {
|
||||
case OPAL_CARTO_FILE_NAME:
|
||||
node = (opal_carto_base_node_t *)malloc(sizeof(opal_carto_base_node_t));
|
||||
node->node_type = strdup(carto_file_value.sval);
|
||||
if (0 == strcmp("slot",node->node_type)) {
|
||||
node->is_cpu = true;
|
||||
}
|
||||
else {
|
||||
node->is_cpu = false;
|
||||
}
|
||||
token = carto_file_lex();
|
||||
switch (token) {
|
||||
case OPAL_CARTO_FILE_NAME:
|
||||
node->node_name = strdup(carto_file_value.sval);
|
||||
opal_carto_base_graph_add_node(carto_base_common_host_graph, node);
|
||||
break;
|
||||
default:
|
||||
free(node);
|
||||
opal_show_help("help-opal-carto-file.txt", "expected node name",
|
||||
true, cartofile, line_number, token_to_string[token]);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
opal_show_help("help-opal-carto-file.txt", "expected node type",
|
||||
true, cartofile, line_number, token_to_string[token]);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
case OPAL_CARTO_FILE_CONNECTION_DECELERATION:
|
||||
token = carto_file_lex();
|
||||
switch (token) {
|
||||
case OPAL_CARTO_FILE_NAME:
|
||||
node1_name = strdup(carto_file_value.sval);
|
||||
while (OPAL_CARTO_FILE_NEWLINE != token) {
|
||||
token = carto_file_lex();
|
||||
switch (token) {
|
||||
case OPAL_CARTO_FILE_NODE_CONNECTION:
|
||||
value = carto_file_value.sval;
|
||||
argv = opal_argv_split (value, ':');
|
||||
cnt = opal_argv_count (argv);
|
||||
if (2 == cnt) {
|
||||
node2_name = strdup(argv[0]);
|
||||
weight = atoi(argv[1]);
|
||||
} else {
|
||||
opal_show_help("help-opal-carto-file.txt", "incorrect connection", true, cartofile, line_number, value);
|
||||
opal_argv_free (argv);
|
||||
free(node1_name);
|
||||
free(node2_name);
|
||||
goto error;
|
||||
}
|
||||
opal_argv_free (argv);
|
||||
/* find the start node of the connection */
|
||||
node = opal_carto_base_graph_find_node(carto_base_common_host_graph,node1_name);
|
||||
if (NULL == node) {
|
||||
opal_show_help("help-opal-carto-file.txt", "vertex not found", true, cartofile, line_number, node1_name);
|
||||
free(node1_name);
|
||||
free(node2_name);
|
||||
goto error;
|
||||
}
|
||||
/* find the end node of the connection */
|
||||
end_node = opal_carto_base_graph_find_node(carto_base_common_host_graph,node2_name);
|
||||
if (NULL == end_node) {
|
||||
opal_show_help("help-opal-carto-file.txt", "vertex not found", true, cartofile, line_number, node2_name);
|
||||
free(node1_name);
|
||||
free(node2_name);
|
||||
goto error;
|
||||
}
|
||||
opal_carto_base_connect_nodes(carto_base_common_host_graph, node, end_node, weight);
|
||||
free(node2_name);
|
||||
break;
|
||||
case OPAL_CARTO_FILE_NEWLINE:
|
||||
line_number++;
|
||||
break;
|
||||
default:
|
||||
opal_show_help("help-opal-carto-file.txt", "expected Connection",
|
||||
true, cartofile, line_number, token_to_string[token]);
|
||||
free(node1_name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
free(node1_name);
|
||||
break;
|
||||
default:
|
||||
opal_show_help("help-opal-carto-file.txt", "expected node name",
|
||||
true, cartofile, line_number, token_to_string[token]);
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
opal_show_help("help-opal-carto-file.txt", "expected deceleration",
|
||||
true, cartofile, line_number, token_to_string[token]);
|
||||
goto error;
|
||||
|
||||
}
|
||||
}
|
||||
return OPAL_SUCCESS;
|
||||
error:
|
||||
fclose(carto_file_in);
|
||||
return OPAL_ERR_BAD_PARAM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
22
opal/mca/carto/file/configure.params
Исполняемый файл
22
opal/mca/carto/file/configure.params
Исполняемый файл
@ -0,0 +1,22 @@
|
||||
# -*- shell-script -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2007 Los Alamos National Security, LLC. All rights
|
||||
# reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
PARAM_CONFIG_FILES="Makefile"
|
56
opal/mca/carto/file/help-opal-carto-file.txt
Обычный файл
56
opal/mca/carto/file/help-opal-carto-file.txt
Обычный файл
@ -0,0 +1,56 @@
|
||||
# -*- text -*-
|
||||
#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2006 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2006-2007 Cisco Systems, Inc. All rights reserved.
|
||||
# Copyright (c) 2007 Mellanox Technologies. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
# This is the US/English help file for Open MPI's OpenFabrics support
|
||||
# (the carto file).
|
||||
#
|
||||
|
||||
[file not found]
|
||||
File %s: No such file or directory
|
||||
#
|
||||
|
||||
[expected node type]
|
||||
File: %s line: %d expected node type (free string). received %s
|
||||
#
|
||||
|
||||
[expected node name]
|
||||
File: %s line: %d expected Node name (free string). received %s
|
||||
#
|
||||
|
||||
[expected Connection]
|
||||
File: %s line: %d expected Node connection (node name:weight). received %s
|
||||
#
|
||||
|
||||
[expected deceleration]
|
||||
File: %s line: %d expected Node deceleration (NODE) or connection deceleration (CONNECTION). received %s
|
||||
#
|
||||
|
||||
[incorrect connection]
|
||||
File: %s line: %d - %s - incorrect connection
|
||||
#
|
||||
|
||||
[vertex not found]
|
||||
File: %s line: %d - Node %s is not in the graph
|
||||
#
|
||||
|
||||
[unknown token]
|
||||
File: %s line: %d - lexical analyzer returned
|
||||
unknown value - %d
|
||||
#
|
@ -171,6 +171,9 @@ opal_cmd_line_init_t cmd_line_init[] = {
|
||||
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Provide a hostfile" },
|
||||
|
||||
{ "carto", "file", "path", '\0', "cf", "cartofile", 1,
|
||||
NULL, OPAL_CMD_LINE_TYPE_STRING,
|
||||
"Provide a cartography file" },
|
||||
/* Don't wait for the process to finish before exiting */
|
||||
#if 0
|
||||
{ NULL, NULL, NULL, '\0', "nw", "nw", 0,
|
||||
|
39
test/carto/carto-file
Обычный файл
39
test/carto/carto-file
Обычный файл
@ -0,0 +1,39 @@
|
||||
# This is a comment
|
||||
# Node declaration Node type (Free string) Node name (Free string)
|
||||
# (Reserve word) (slot is a reserve word (free string)
|
||||
# for CPU slot)
|
||||
#=======================================================================
|
||||
NODE Memory mem0
|
||||
NODE Memory mem1
|
||||
NODE Memory mem2
|
||||
NODE Memory mem3
|
||||
#
|
||||
NODE slot slot0
|
||||
NODE slot slot1
|
||||
NODE slot slot2
|
||||
NODE slot slot3
|
||||
#
|
||||
NODE Infiniband mthca0
|
||||
NODE Infiniband mthca1
|
||||
#
|
||||
NODE Ethernet eth0
|
||||
NODE Ethernet eth1
|
||||
#
|
||||
#
|
||||
# Connection decleration From node To node:weight To node:weight ......
|
||||
# (Reserve word) (declered (declered (declered
|
||||
# above) above) above)
|
||||
#===============================================================================================
|
||||
CONNECTION slot0 mem0:0 slot1:1 slot2:1 mthca0:1 eth0:1
|
||||
CONNECTION slot1 mem1:0 slot0:1 slot3:1
|
||||
CONNECTION slot2 mem2:0 slot1:1 slot3:1
|
||||
CONNECTION slot3 mem3:0 slot1:1 slot2:1 mthca1:1 eth1:1
|
||||
#
|
||||
CONNECTION mthca0 slot0:1
|
||||
CONNECTION mthca1 slot3:1
|
||||
#
|
||||
CONNECTION eth0 slot0:1
|
||||
CONNECTION eth1 slot3:1
|
||||
#
|
||||
# end of carto file.
|
||||
|
181
test/carto/carto_test.c
Обычный файл
181
test/carto/carto_test.c
Обычный файл
@ -0,0 +1,181 @@
|
||||
/* -*- C -*-
|
||||
*
|
||||
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
* University Research and Technology
|
||||
* Corporation. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
* University of Stuttgart. All rights reserved.
|
||||
* Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
*
|
||||
* $HEADER$
|
||||
*
|
||||
* The most basic of MPI applications
|
||||
*/
|
||||
|
||||
#define bool int
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
|
||||
#include <mpi.h>
|
||||
#include <stdio.h>
|
||||
#include "../../opal/mca/carto/carto.h"
|
||||
#include "../../opal/mca/carto/base/base.h"
|
||||
#include "../../opal/mca/carto/base/carto_base_graph.h"
|
||||
#include "../../opal/util/output.h"
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int rank, size, distance, distance_array_size, i;
|
||||
opal_carto_graph_t *graph;
|
||||
opal_carto_base_node_t *slot0, *end_node;
|
||||
opal_carto_node_distance_t *node_distance;
|
||||
opal_value_array_t *distance_array;
|
||||
|
||||
MPI_Init(&argc, &argv);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
|
||||
MPI_Comm_size(MPI_COMM_WORLD, &size);
|
||||
|
||||
|
||||
printf("Hello, world, I am %d of %d\n", rank, size);
|
||||
if (0 == rank) {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
opal_output(0," \n\nget_host_graph Full\n");
|
||||
opal_carto_base_module->get_host_graph(&graph,NULL);
|
||||
opal_graph_print(graph);
|
||||
slot0 = opal_carto_base_graph_find_node(graph, "slot0");
|
||||
if (NULL == slot0) {
|
||||
opal_output(0,"couldnt find slot0 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
end_node = opal_carto_base_graph_find_node(graph, "slot3");
|
||||
if (NULL == end_node) {
|
||||
opal_output(0,"couldnt find mthca1 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
distance = opal_carto_base_module->spf(graph, slot0, end_node);
|
||||
opal_output(0,"\nThe distance between slot0 and slot3 is %d\n",distance);
|
||||
distance_array = OBJ_NEW(opal_value_array_t);
|
||||
opal_value_array_init(distance_array, sizeof(opal_carto_node_distance_t));
|
||||
opal_value_array_reserve(distance_array, 50);
|
||||
distance_array_size = opal_carto_base_module->get_nodes_distance(graph, slot0, NULL, distance_array);
|
||||
for (i=0; i < distance_array_size; i++) {
|
||||
node_distance = opal_value_array_get_item(distance_array, i);
|
||||
opal_output(0,"Node %s distance from slot0 is %d\n",node_distance->node->node_name, node_distance->node_distance);
|
||||
}
|
||||
OBJ_RELEASE(distance_array);
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
opal_output(0," \n\nget_host_graph Infiniband\n");
|
||||
opal_carto_base_module->get_host_graph(&graph,"Infiniband");
|
||||
opal_graph_print(graph);
|
||||
slot0 = opal_carto_base_graph_find_node(graph, "slot0");
|
||||
if (NULL == slot0) {
|
||||
opal_output(0,"couldnt find slot0 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
end_node = opal_carto_base_graph_find_node(graph, "mthca1");
|
||||
if (NULL == end_node) {
|
||||
opal_output(0,"couldnt find mthca1 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
distance = opal_carto_base_module->spf(graph, slot0, end_node);
|
||||
opal_output(0,"\nThe distance between slot0 and mthca1 is %d\n",distance);
|
||||
distance_array = OBJ_NEW(opal_value_array_t);
|
||||
opal_value_array_init(distance_array, sizeof(opal_carto_node_distance_t));
|
||||
opal_value_array_reserve(distance_array, 50);
|
||||
distance_array_size = opal_carto_base_module->get_nodes_distance(graph, slot0, "Infiniband", distance_array);
|
||||
for (i=0; i < distance_array_size; i++) {
|
||||
node_distance = opal_value_array_get_item(distance_array, i);
|
||||
opal_output(0,"Node %s distance from slot0 is %d\n",node_distance->node->node_name, node_distance->node_distance);
|
||||
}
|
||||
OBJ_RELEASE(distance_array);
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
opal_output(0," \n\nget_host_graph Ethernet\n");
|
||||
opal_carto_base_module->get_host_graph(&graph,"Ethernet");
|
||||
opal_graph_print(graph);
|
||||
slot0 = opal_carto_base_graph_find_node(graph, "slot0");
|
||||
if (NULL == slot0) {
|
||||
opal_output(0,"couldnt find slot0 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
end_node = opal_carto_base_graph_find_node(graph, "eth1");
|
||||
if (NULL == end_node) {
|
||||
opal_output(0,"couldnt find mthca1 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
distance = opal_carto_base_module->spf(graph, slot0, end_node);
|
||||
opal_output(0,"\nThe distance between slot0 and eth1 is %d\n",distance);
|
||||
distance_array = OBJ_NEW(opal_value_array_t);
|
||||
opal_value_array_init(distance_array, sizeof(opal_carto_node_distance_t));
|
||||
opal_value_array_reserve(distance_array, 50);
|
||||
distance_array_size = opal_carto_base_module->get_nodes_distance(graph, slot0, "Ethernet", distance_array);
|
||||
for (i=0; i < distance_array_size; i++) {
|
||||
node_distance = opal_value_array_get_item(distance_array, i);
|
||||
opal_output(0,"Node %s distance from slot0 is %d\n",node_distance->node->node_name, node_distance->node_distance);
|
||||
}
|
||||
OBJ_RELEASE(distance_array);
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
||||
opal_output(0," \n\nget_host_graph Memory\n");
|
||||
opal_carto_base_module->get_host_graph(&graph,"Memory");
|
||||
opal_graph_print(graph);
|
||||
slot0 = opal_carto_base_graph_find_node(graph, "slot0");
|
||||
if (NULL == slot0) {
|
||||
opal_output(0,"couldnt find slot0 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
end_node = opal_carto_base_graph_find_node(graph, "mem3");
|
||||
if (NULL == end_node) {
|
||||
opal_output(0,"couldnt find mthca1 in the graph exiting\n");
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
return -1;
|
||||
}
|
||||
distance = opal_carto_base_module->spf(graph, slot0, end_node);
|
||||
opal_output(0,"\nThe distance between slot0 and mem3 is %d\n",distance);
|
||||
distance_array = OBJ_NEW(opal_value_array_t);
|
||||
opal_value_array_init(distance_array, sizeof(opal_carto_node_distance_t));
|
||||
opal_value_array_reserve(distance_array, 50);
|
||||
distance_array_size = opal_carto_base_module->get_nodes_distance(graph, slot0, "Memory", distance_array);
|
||||
for (i=0; i < distance_array_size; i++) {
|
||||
node_distance = opal_value_array_get_item(distance_array, i);
|
||||
opal_output(0,"Node %s distance from slot0 is %d\n",node_distance->node->node_name, node_distance->node_distance);
|
||||
}
|
||||
OBJ_RELEASE(distance_array);
|
||||
opal_carto_base_module->free_graph(graph);
|
||||
|
||||
}
|
||||
MPI_Barrier(MPI_COMM_WORLD);
|
||||
MPI_Finalize();
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user