1
1

Move the carto framework to the trunk.

This commit was SVN r17177.
Этот коммит содержится в:
Sharon Melamed 2008-01-23 09:20:34 +00:00
родитель 889f6c79fe
Коммит 025b68becf
34 изменённых файлов: 5582 добавлений и 0 удалений

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

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

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

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

@ -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 */

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

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

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

@ -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 Обычный файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Обычный файл

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

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 Обычный файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

@ -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 Исполняемый файл
Просмотреть файл

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

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

@ -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 Обычный файл
Просмотреть файл

@ -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 Обычный файл
Просмотреть файл

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