[ofa-general] [PATCH][5] opensm: compute local geometry

Robert Pearson rpearson at systemfabricworks.com
Tue Nov 11 08:59:58 PST 2008


Sasha,

Here is the fifth patch implementing the mesh analysis algorithm.

This patch implements
      - routine to compute characteristics polynomial of a matrix
      - routine to compute the local 'metric' around each switch
      - routine to classify switches into a histogram of local geometry
classes

Regards,

Bob Pearson

Signed-off-by: Bob Pearson <rpearson at systemfabricworks.com>
----
diff --git a/opensm/opensm/osm_mesh.c b/opensm/opensm/osm_mesh.c
index 7434fee..9254de3 100644
--- a/opensm/opensm/osm_mesh.c
+++ b/opensm/opensm/osm_mesh.c
@@ -338,6 +338,172 @@ static int determinant(lash_t *p_lash, int deg, int
rank, int ***m, int *p)
 }
 
 /*
+ * char_poly
+ *
+ * compute the characteristic polynomial of matrix of rank
+ * by computing the determinant of m-x*I and return in poly
+ * as an array. caller must free poly
+ */
+static int char_poly(lash_t *p_lash, int rank, int **matrix, int **poly)
+{
+	int ret = -1;
+	int i, j;
+	int ***m = NULL;
+	int *p = NULL;
+	int deg = rank;
+
+	do {
+		if (!(p = poly_alloc(p_lash, deg))) {
+			break;
+		}
+
+		if (!(m = pm_alloc(p_lash, rank, deg))) {
+			free(p);
+			p = NULL;
+			break;
+		}
+
+		for (i = 0; i < rank; i++) {
+			for (j = 0; j < rank; j++) {
+				m[i][j][0] = matrix[i][j];
+			}
+			m[i][i][1] = -1;
+		}
+
+		if (determinant(p_lash, deg, rank, m, p)) {
+			free(p);
+			p = NULL;
+			break;
+		}
+
+		ret = 0;
+	} while(0);
+
+	pm_free(m, rank);
+	*poly = p;
+	return ret;
+}
+
+/*
+ * get_switch_metric
+ *
+ * compute the matrix of minimum distances between each of
+ * the adjacent switch nodes to sw along paths
+ * that do not go through sw. do calculation by
+ * relaxation method
+ * allocate space for the matrix and save in node_t structure
+ */
+static int get_switch_metric(lash_t *p_lash, int sw)
+{
+	int ret = -1;
+	int i, j, change;
+	int sw1, sw2, sw3;
+	switch_t *s = p_lash->switches[sw];
+	switch_t *s1, *s2, *s3;
+	int **m;
+	mesh_node_t *node = s->node;
+	int num_links = node->num_links;
+
+	do {
+		if (!(m = m_alloc(p_lash, num_links)))
+			break;
+
+		for (i = 0; i < num_links; i++) {
+			sw1 = node->links[i]->switch_id;
+			s1 = p_lash->switches[sw1];
+
+			/* make all distances big except s1 to itself */
+			for (sw2 = 0; sw2 < p_lash->num_switches; sw2++)
+				p_lash->switches[sw2]->node->temp =
0x7fffffff;
+
+			s1->node->temp = 0;
+
+			do {
+				change = 0;
+
+				for (sw2 = 0; sw2 < p_lash->num_switches;
sw2++) {
+					s2 = p_lash->switches[sw2];
+					if (s2->node->temp == 0x7fffffff)
+						continue;
+					for (j = 0; j < s2->node->num_links;
j++) {
+						sw3 =
s2->node->links[j]->switch_id;
+						s3 = p_lash->switches[sw3];
+
+						if (sw3 == sw)
+							continue;
+
+						if ((s2->node->temp + 1) <
s3->node->temp) {
+							s3->node->temp =
s2->node->temp + 1;
+							change++;
+						}
+					}
+				}
+			} while(change);
+
+			for (j = 0; j < num_links; j++) {
+				sw2 = node->links[j]->switch_id;
+				s2 = p_lash->switches[sw2];
+				m[i][j] = s2->node->temp;
+			}
+		}
+
+		if (char_poly(p_lash, num_links, m, &node->poly)) {
+			m_free(m, num_links);
+			m = NULL;
+			break;
+		}
+
+		ret = 0;
+	} while(0);
+
+	node->matrix = m;
+	return ret;
+}
+
+/*
+ * classify_switch
+ *
+ * add switch to histogram of switch types
+ */
+static void classify_switch(lash_t *p_lash, int sw)
+{
+	int i;
+	switch_t *s = p_lash->switches[sw];
+	switch_t *s1;
+	mesh_t *mesh = p_lash->mesh;
+
+	for (i = 0; i < mesh->num_class; i++) {
+		s1 = p_lash->switches[mesh->class_type[i]];
+	
+		if (poly_diff(s->node->num_links, s->node->poly, s1))
+			continue;
+
+		mesh->class_count[i]++;
+		return;
+	}
+
+	mesh->class_type[mesh->num_class] = sw;
+	mesh->class_count[mesh->num_class] = 1;
+	mesh->num_class++;
+	return;
+}
+
+/*
+ * get_local_geometry
+ *
+ * analyze the local geometry around each switch
+ */
+static void get_local_geometry(lash_t *p_lash)
+{
+	int sw;
+
+	for (sw = 0; sw < p_lash->num_switches; sw++) {
+		get_switch_metric(p_lash, sw);
+		classify_switch(p_lash, sw);
+	}
+}
+
+/*
  * osm_mesh_cleanup - free per mesh resources
  */
 void osm_mesh_cleanup(lash_t *p_lash)
@@ -404,6 +570,12 @@ int osm_do_mesh_analysis(lash_t *p_lash)
 		return -1;
 	}
 
+	/*
+	 * get local metric and invariant for each switch
+	 * also classify each switch
+	 */
+	get_local_geometry(p_lash);
+
 	printf("lash: do_mesh_analysis stub called\n");
 
 	OSM_LOG_EXIT(p_log);





More information about the general mailing list