[ofa-general] [PATCH][8] opensm: measure size and reorder links
Robert Pearson
rpearson at systemfabricworks.com
Tue Nov 11 09:37:14 PST 2008
Sasha,
Here is the eighth patch implementing the mesh analysis algorithm.
This patch implements
- routine to reorder links and measure the size of the mesh
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 65afae6..a248522 100644
--- a/opensm/opensm/osm_mesh.c
+++ b/opensm/opensm/osm_mesh.c
@@ -832,6 +832,183 @@ next_j:
}
/*
+ * return |a| < |b|
+ */
+static inline int ltmag(int a, int b)
+{
+ int a1 = (a >= 0)? a : -a;
+ int b1 = (b >= 0)? b : -b;
+
+ return (a1 < b1) || (a1 == b1 && a > b);
+}
+
+/*
+ * reorder_links
+ *
+ * reorder the links out of a switch in sign/dimension order
+ */
+static int reorder_links(lash_t *p_lash, int sw)
+{
+ osm_log_t *p_log = &p_lash->p_osm->log;
+ switch_t *s = p_lash->switches[sw];
+ mesh_node_t *node = s->node;
+ int n = node->num_links;
+ link_t **links;
+ int *axes;
+ int i, j;
+ int c;
+ int next = 0;
+
+ if (!(links = calloc(n, sizeof(link_t *)))) {
+ OSM_LOG(p_log, OSM_LOG_ERROR, "Failed allocating temp array -
out of memory\n");
+ return -1;
+ }
+
+ if (!(axes = calloc(n, sizeof(int)))) {
+ free(links);
+ OSM_LOG(p_log, OSM_LOG_ERROR, "Failed allocating temp array -
out of memory\n");
+ return -1;
+ }
+
+ /*
+ * find the links with axes
+ */
+ for (j = 1; j <= 2*node->dimension; j++) {
+ c = j;
+ if (node->coord[(c-1)/2] > 0)
+ c = opposite(s, c);
+
+ for (i = 0; i < n; i++) {
+ if (!node->links[i])
+ continue;
+ if (node->axes[i] == c) {
+ links[next] = node->links[i];
+ axes[next] = node->axes[i];
+ node->links[i] = NULL;
+ next++;
+ }
+ }
+ }
+
+ /*
+ * get the rest
+ */
+ for (i = 0; i < n; i++) {
+ if (!node->links[i])
+ continue;
+
+ links[next] = node->links[i];
+ axes[next] = node->axes[i];
+ node->links[i] = NULL;
+ next++;
+ }
+
+ for (i = 0; i < n; i++) {
+ node->links[i] = links[i];
+ node->axes[i] = axes[i];
+ }
+
+ free(links);
+ free(axes);
+
+ return 0;
+}
+
+/*
+ * measure geometry
+ */
+static int measure_geometry(lash_t *p_lash, int seed)
+{
+ int i, j, k;
+ int sw;
+ switch_t *s, *s1;
+ int change;
+ int dimension = p_lash->mesh->dimension;
+ int num_switches = p_lash->num_switches;
+ int assigned_axes = 0, unassigned_axes = 0;
+ int *max, *min;
+
+ for (sw = 0; sw < num_switches; sw++) {
+ s = p_lash->switches[sw];
+
+ s->node->coord = calloc(dimension, sizeof(int));
+ for (i = 0; i < dimension; i++)
+ s->node->coord[i] = (sw == seed)? 0 : 0x7fffffff;
+
+ for (i = 0; i < s->node->num_links; i++)
+ if (s->node->axes[i] == 0)
+ unassigned_axes++;
+ else
+ assigned_axes++;
+ }
+
+ printf("lash: %d/%d unassigned/assigned axes\n", unassigned_axes,
assigned_axes);
+
+ do {
+ change = 0;
+
+ for (sw = 0; sw < num_switches; sw++) {
+ s = p_lash->switches[sw];
+
+ if (s->node->coord[0] == 0x7fffffff)
+ continue;
+
+ for (j = 0; j < s->node->num_links; j++) {
+ if (!s->node->axes[j])
+ continue;
+
+ s1 = p_lash->switches[s->node->links[j]->switch_id];
+
+ for (k = 0; k < dimension; k++) {
+ int coord = s->node->coord[k];
+ int axis = s->node->axes[j] - 1;
+
+ if (k == axis/2)
+ coord += (axis & 1)? -1 : +1;
+
+ if (ltmag(coord, s1->node->coord[k])) {
+ s1->node->coord[k] = coord;
+ change++;
+ }
+ }
+ }
+ }
+ } while (change);
+
+ for (sw = 0; sw < num_switches; sw++) {
+ if (reorder_links(p_lash, sw))
+ return -1;
+ }
+
+ max = calloc(dimension, sizeof(int));
+ min = calloc(dimension, sizeof(int));
+ p_lash->mesh->size = calloc(dimension, sizeof(int));
+
+ for (i = 0; i < dimension; i++) {
+ max[i] = -0x7fffffff;
+ min[i] = 0x7fffffff;
+ }
+
+ for (sw = 0; sw < num_switches; sw++) {
+ s = p_lash->switches[sw];
+
+ for (i = 0; i < dimension; i++) {
+ if (s->node->coord[i] == 0x7fffffff)
+ continue;
+ if (s->node->coord[i] > max[i])
+ max[i] = s->node->coord[i];
+ if (s->node->coord[i] < min[i])
+ min[i] = s->node->coord[i];
+ }
+ }
+
+ for (i = 0; i < dimension; i++)
+ p_lash->mesh->size[i] = max[i] - min[i] + 1;
+
+ return 0;
+}
+
+/*
* osm_mesh_cleanup - free per mesh resources
*/
void osm_mesh_cleanup(lash_t *p_lash)
@@ -941,6 +1118,14 @@ int osm_do_mesh_analysis(lash_t *p_lash)
if (s->node->type) {
make_geometry(p_lash, max_class_type);
+
+ if (measure_geometry(p_lash, max_class_type))
+ return -1;
+
+ printf("lash: found ");
+ for (i = 0; i < mesh->dimension; i++)
+ printf("%s%d", i? "X" : "", mesh->size[i]);
+ printf(" mesh\n");
}
OSM_LOG_EXIT(p_log);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openfabrics.org/pipermail/general/attachments/20081111/2ead8059/attachment.html>
More information about the general
mailing list