|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2008-2009 Voltaire, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
* Copyright (c) 2008,2009 System Fabric Works, Inc. All rights reserved.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* This software is available to you under a choice of one of two
|
|
Packit Service |
54dbc3 |
* licenses. You may choose to be licensed under the terms of the GNU
|
|
Packit Service |
54dbc3 |
* General Public License (GPL) Version 2, available from the file
|
|
Packit Service |
54dbc3 |
* COPYING in the main directory of this source tree, or the
|
|
Packit Service |
54dbc3 |
* OpenIB.org BSD license below:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* Redistribution and use in source and binary forms, with or
|
|
Packit Service |
54dbc3 |
* without modification, are permitted provided that the following
|
|
Packit Service |
54dbc3 |
* conditions are met:
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions of source code must retain the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* - Redistributions in binary form must reproduce the above
|
|
Packit Service |
54dbc3 |
* copyright notice, this list of conditions and the following
|
|
Packit Service |
54dbc3 |
* disclaimer in the documentation and/or other materials
|
|
Packit Service |
54dbc3 |
* provided with the distribution.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
Packit Service |
54dbc3 |
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
Packit Service |
54dbc3 |
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
Packit Service |
54dbc3 |
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
Packit Service |
54dbc3 |
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
Packit Service |
54dbc3 |
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
Packit Service |
54dbc3 |
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
Packit Service |
54dbc3 |
* SOFTWARE.
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* Abstract:
|
|
Packit Service |
54dbc3 |
* routines to analyze certain meshes
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#if HAVE_CONFIG_H
|
|
Packit Service |
54dbc3 |
# include <config.h>
|
|
Packit Service |
54dbc3 |
#endif /* HAVE_CONFIG_H */
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#include <stdio.h>
|
|
Packit Service |
54dbc3 |
#include <stdlib.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_file_ids.h>
|
|
Packit Service |
54dbc3 |
#define FILE_ID OSM_FILE_MESH_C
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_switch.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_opensm.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_log.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_mesh.h>
|
|
Packit Service |
54dbc3 |
#include <opensm/osm_ucast_lash.h>
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
#define MAX_DEGREE (8)
|
|
Packit Service |
54dbc3 |
#define MAX_DIMENSION (8)
|
|
Packit Service |
54dbc3 |
#define LARGE (0x7fffffff)
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* characteristic polynomials for selected 1d through 8d tori
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static const struct mesh_info {
|
|
Packit Service |
54dbc3 |
int dimension; /* dimension of the torus */
|
|
Packit Service |
54dbc3 |
int size[MAX_DIMENSION]; /* size of the torus */
|
|
Packit Service |
54dbc3 |
unsigned int degree; /* degree of polynomial */
|
|
Packit Service |
54dbc3 |
int poly[MAX_DEGREE+1]; /* polynomial */
|
|
Packit Service |
54dbc3 |
} mesh_info[] = {
|
|
Packit Service |
54dbc3 |
{0, {0}, 0, {0}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{1, {2}, 1, {0, -1}, },
|
|
Packit Service |
54dbc3 |
{1, {3}, 2, {-1, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{1, {5}, 2, {-9, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{1, {6}, 2, {-36, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{2, {2, 2}, 2, {-4, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{2, {3, 2}, 3, {8, 9, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{2, {5, 2}, 3, {24, 17, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{2, {6, 2}, 3, {32, 24, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{2, {3, 3}, 4, {-15, -32, -18, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{2, {5, 3}, 4, {-39, -64, -26, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{2, {6, 3}, 4, {-48, -80, -33, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{2, {5, 5}, 4, {-63, -96, -34, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{2, {6, 5}, 4, {-48, -112, -41, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{2, {6, 6}, 4, {0, -128, -48, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{3, {2, 2, 2}, 3, {16, 12, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {3, 2, 2}, 4, {-28, -48, -21, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {5, 2, 2}, 4, {-60, -80, -29, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 2, 2}, 4, {-64, -96, -36, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {3, 3, 2}, 5, {48, 127, 112, 34, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {5, 3, 2}, 5, {96, 215, 160, 42, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 3, 2}, 5, {96, 232, 184, 49, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {5, 5, 2}, 5, {144, 303, 208, 50, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 5, 2}, 5, {96, 296, 232, 57, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 6, 2}, 5, {0, 256, 256, 64, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{3, {3, 3, 3}, 6, {-81, -288, -381, -224, -51, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {5, 3, 3}, 6, {-153, -480, -557, -288, -59, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 3, 3}, 6, {-144, -480, -591, -320, -66, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {5, 5, 3}, 6, {-225, -672, -733, -352, -67, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 5, 3}, 6, {-144, -576, -743, -384, -74, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 6, 3}, 6, {0, -384, -720, -416, -81, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {5, 5, 5}, 6, {-297, -864, -909, -416, -75, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 5, 5}, 6, {-144, -672, -895, -448, -82, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 6, 5}, 6, {0, -384, -848, -480, -89, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{3, {6, 6, 6}, 6, {0, 0, -768, -512, -96, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{4, {2, 2, 2, 2}, 4, {-48, -64, -24, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {3, 2, 2, 2}, 5, {80, 180, 136, 37, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 2, 2, 2}, 5, {144, 276, 184, 45, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 2, 2, 2}, 5, {128, 288, 208, 52, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {3, 3, 2, 2}, 6, {-132, -416, -487, -256, -54, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 3, 2, 2}, 6, {-228, -640, -671, -320, -62, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 3, 2, 2}, 6, {-192, -608, -700, -352, -69, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 5, 2, 2}, 6, {-324, -864, -855, -384, -70, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 5, 2, 2}, 6, {-192, -736, -860, -416, -77, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 2, 2}, 6, {0, -512, -832, -448, -84, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {3, 3, 3, 2}, 7, {216, 873, 1392, 1101, 440, 75, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 3, 3, 2}, 7, {360, 1329, 1936, 1405, 520, 83, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 3, 3, 2}, 7, {288, 1176, 1872, 1455, 560, 90, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 5, 3, 2}, 7, {504, 1785, 2480, 1709, 600, 91, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 5, 3, 2}, 7, {288, 1368, 2272, 1735, 640, 98, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 3, 2}, 7, {0, 768, 1920, 1728, 680, 105, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 5, 5, 2}, 7, {648, 2241, 3024, 2013, 680, 99, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 5, 5, 2}, 7, {288, 1560, 2672, 2015, 720, 106, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 5, 2}, 7, {0, 768, 2176, 1984, 760, 113, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 6, 2}, 7, {0, 0, 1536, 1920, 800, 120, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{4, {3, 3, 3, 3}, 8, {-351, -1728, -3492, -3712, -2202, -704, -100, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 3, 3, 3}, 8, {-567, -2592, -4860, -4800, -2658, -800, -108, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 3, 3, 3}, 8, {-432, -2160, -4401, -4672, -2733, -848, -115, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 5, 3, 3}, 8, {-783, -3456, -6228, -5888, -3114, -896, -116, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 5, 3, 3}, 8, {-432, -2448, -5241, -5568, -3165, -944, -123, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 3, 3}, 8, {0, -1152, -3888, -5056, -3183, -992, -130, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {5, 5, 5, 3}, 8, {-999, -4320, -7596, -6976, -3570, -992, -124, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 5, 5, 3}, 8, {-432, -2736, -6081, -6464, -3597, -1040, -131, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 5, 3}, 8, {0, -1152, -4272, -5760, -3591, -1088, -138, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{4, {6, 6, 6, 3}, 8, {0, 0, -2304, -4864, -3552, -1136, -145, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{5, {2, 2, 2, 2, 2}, 5, {128, 240, 160, 40, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {3, 2, 2, 2, 2}, 6, {-208, -576, -600, -288, -57, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {5, 2, 2, 2, 2}, 6, {-336, -832, -792, -352, -65, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 2, 2, 2, 2}, 6, {-256, -768, -816, -384, -72, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {3, 3, 2, 2, 2}, 7, {336, 1228, 1776, 1287, 480, 78, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {5, 3, 2, 2, 2}, 7, {528, 1772, 2368, 1599, 560, 86, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 3, 2, 2, 2}, 7, {384, 1504, 2256, 1644, 600, 93, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {5, 5, 2, 2, 2}, 7, {720, 2316, 2960, 1911, 640, 94, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 5, 2, 2, 2}, 7, {384, 1760, 2704, 1932, 680, 101, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 6, 2, 2, 2}, 7, {0, 1024, 2304, 1920, 720, 108, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{5, {3, 3, 3, 2, 2}, 8, {-540, -2448, -4557, -4480, -2481, -752, -103, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {5, 3, 3, 2, 2}, 8, {-828, -3504, -6101, -5632, -2945, -848, -111, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 3, 3, 2, 2}, 8, {-576, -2784, -5412, -5440, -3015, -896, -118, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {5, 5, 3, 2, 2}, 8, {-1116, -4560, -7645, -6784, -3409, -944, -119, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 5, 3, 2, 2}, 8, {-576, -3168, -6404, -6400, -3455, -992, -126, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 6, 3, 2, 2}, 8, {0, -1536, -4800, -5824, -3468, -1040, -133, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {5, 5, 5, 2, 2}, 8, {-1404, -5616, -9189, -7936, -3873, -1040, -127, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 5, 5, 2, 2}, 8, {-576, -3552, -7396, -7360, -3895, -1088, -134, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 6, 5, 2, 2}, 8, {0, -1536, -5312, -6592, -3884, -1136, -141, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{5, {6, 6, 6, 2, 2}, 8, {0, 0, -3072, -5632, -3840, -1184, -148, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{6, {2, 2, 2, 2, 2, 2}, 6, {-320, -768, -720, -320, -60, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{6, {3, 2, 2, 2, 2, 2}, 7, {512, 1680, 2208, 1480, 520, 81, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{6, {5, 2, 2, 2, 2, 2}, 7, {768, 2320, 2848, 1800, 600, 89, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{6, {6, 2, 2, 2, 2, 2}, 7, {512, 1920, 2688, 1840, 640, 96, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{6, {3, 3, 2, 2, 2, 2}, 8, {-816, -3392, -5816, -5312, -2767, -800, -106, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{6, {5, 3, 2, 2, 2, 2}, 8, {-1200, -4672, -7544, -6528, -3239, -896, -114, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{6, {6, 3, 2, 2, 2, 2}, 8, {-768, -3584, -6608, -6272, -3304, -944, -121, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{6, {5, 5, 2, 2, 2, 2}, 8, {-1584, -5952, -9272, -7744, -3711, -992, -122, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{6, {6, 5, 2, 2, 2, 2}, 8, {-768, -4096, -7760, -7296, -3752, -1040, -129, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{6, {6, 6, 2, 2, 2, 2}, 8, {0, -2048, -5888, -6656, -3760, -1088, -136, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{7, {2, 2, 2, 2, 2, 2, 2}, 7, {768, 2240, 2688, 1680, 560, 84, 0, -1}, },
|
|
Packit Service |
54dbc3 |
{7, {3, 2, 2, 2, 2, 2, 2}, 8, {-1216, -4608, -7280, -6208, -3060, -848, -109, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{7, {5, 2, 2, 2, 2, 2, 2}, 8, {-1728, -6144, -9200, -7488, -3540, -944, -117, 0, 1}, },
|
|
Packit Service |
54dbc3 |
{7, {6, 2, 2, 2, 2, 2, 2}, 8, {-1024, -4608, -8000, -7168, -3600, -992, -124, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{8, {2, 2, 2, 2, 2, 2, 2, 2}, 8, {-1792, -6144, -8960, -7168, -3360, -896, -112, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* mesh errors
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
{2, {6, 6}, 4, {-192, -256, -80, 0, 1}, },
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
{-1, {0,}, 0, {0, }, },
|
|
Packit Service |
54dbc3 |
};
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* per fabric mesh info
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
typedef struct _mesh {
|
|
Packit Service |
54dbc3 |
int num_class; /* number of switch classes */
|
|
Packit Service |
54dbc3 |
int *class_type; /* index of first switch found for each class */
|
|
Packit Service |
54dbc3 |
int *class_count; /* population of each class */
|
|
Packit Service |
54dbc3 |
int dimension; /* mesh dimension */
|
|
Packit Service |
54dbc3 |
int *size; /* an array to hold size of mesh */
|
|
Packit Service |
54dbc3 |
int dim_order[MAX_DIMENSION];
|
|
Packit Service |
54dbc3 |
} mesh_t;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
typedef struct sort_ctx {
|
|
Packit Service |
54dbc3 |
lash_t *p_lash;
|
|
Packit Service |
54dbc3 |
mesh_t *mesh;
|
|
Packit Service |
54dbc3 |
} sort_ctx_t;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
typedef struct comp {
|
|
Packit Service |
54dbc3 |
int index;
|
|
Packit Service |
54dbc3 |
sort_ctx_t ctx;
|
|
Packit Service |
54dbc3 |
} comp_t;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* poly_alloc
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* allocate a polynomial of degree n
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int *poly_alloc(lash_t *p_lash, int n)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int *p;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(p = calloc(n+1, sizeof(int))))
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating poly - out of memory\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return p;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* print a polynomial
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static char *poly_print(int n, int *coeff)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
static char str[(MAX_DEGREE+1)*20];
|
|
Packit Service |
54dbc3 |
char *p = str;
|
|
Packit Service |
54dbc3 |
int i;
|
|
Packit Service |
54dbc3 |
int first = 1;
|
|
Packit Service |
54dbc3 |
int t;
|
|
Packit Service |
54dbc3 |
int sign;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
str[0] = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i <= n; i++) {
|
|
Packit Service |
54dbc3 |
if (!coeff[i])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (coeff[i] < 0) {
|
|
Packit Service |
54dbc3 |
sign = 1;
|
|
Packit Service |
54dbc3 |
t = -coeff[i];
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
sign = 0;
|
|
Packit Service |
54dbc3 |
t = coeff[i];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%s", sign? "-" : (first? "" : "+"));
|
|
Packit Service |
54dbc3 |
first = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (t != 1 || i == 0)
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%d", t);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (i)
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "x");
|
|
Packit Service |
54dbc3 |
if (i > 1)
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "^%d", i);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return str;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* poly_diff
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* return a nonzero value if polynomials differ else 0
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int poly_diff(unsigned int n, const int *p, switch_t *s)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
if (s->node->num_links != n)
|
|
Packit Service |
54dbc3 |
return 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return memcmp(p, s->node->poly, n*sizeof(int));
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* m_free
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* free a square matrix of rank l
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void m_free(int **m, int l)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int i;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (m) {
|
|
Packit Service |
54dbc3 |
for (i = 0; i < l; i++) {
|
|
Packit Service |
54dbc3 |
if (m[i])
|
|
Packit Service |
54dbc3 |
free(m[i]);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
free(m);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* m_alloc
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* allocate a square matrix of rank l
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int **m_alloc(lash_t *p_lash, int l)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int i;
|
|
Packit Service |
54dbc3 |
int **m = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
if (!(m = calloc(l, sizeof(int *))))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < l; i++) {
|
|
Packit Service |
54dbc3 |
if (!(m[i] = calloc(l, sizeof(int))))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (i != l)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return m;
|
|
Packit Service |
54dbc3 |
} while (0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating matrix - out of memory\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
m_free(m, l);
|
|
Packit Service |
54dbc3 |
return NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* pm_free
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* free a square matrix of rank l of polynomials
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void pm_free(int ***m, int l)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int i, j;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (m) {
|
|
Packit Service |
54dbc3 |
for (i = 0; i < l; i++) {
|
|
Packit Service |
54dbc3 |
if (m[i]) {
|
|
Packit Service |
54dbc3 |
for (j = 0; j < l; j++) {
|
|
Packit Service |
54dbc3 |
if (m[i][j])
|
|
Packit Service |
54dbc3 |
free(m[i][j]);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
free(m[i]);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
free(m);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* pm_alloc
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* allocate a square matrix of rank l of polynomials of degree n
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int ***pm_alloc(lash_t *p_lash, int l, int n)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int i, j;
|
|
Packit Service |
54dbc3 |
int ***m = NULL;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
if (!(m = calloc(l, sizeof(int **))))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < l; i++) {
|
|
Packit Service |
54dbc3 |
if (!(m[i] = calloc(l, sizeof(int *))))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j < l; j++) {
|
|
Packit Service |
54dbc3 |
if (!(m[i][j] = calloc(n+1, sizeof(int))))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (j != l)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
if (i != l)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return m;
|
|
Packit Service |
54dbc3 |
} while (0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating matrix - out of memory\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
pm_free(m, l);
|
|
Packit Service |
54dbc3 |
return NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static int determinant(lash_t *p_lash, int n, int rank, int ***m, int *p);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* sub_determinant
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* compute the determinant of a submatrix of matrix of rank l of polynomials of degree n
|
|
Packit Service |
54dbc3 |
* with row and col removed in poly. caller must free poly
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int sub_determinant(lash_t *p_lash, int n, int l, int row, int col,
|
|
Packit Service |
54dbc3 |
int ***matrix, int **poly)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int ret = -1;
|
|
Packit Service |
54dbc3 |
int ***m = NULL;
|
|
Packit Service |
54dbc3 |
int *p = NULL;
|
|
Packit Service |
54dbc3 |
int i, j, k, x, y;
|
|
Packit Service |
54dbc3 |
int rank = l - 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
if (!(p = poly_alloc(p_lash, n))) {
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (rank <= 0) {
|
|
Packit Service |
54dbc3 |
p[0] = 1;
|
|
Packit Service |
54dbc3 |
ret = 0;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(m = pm_alloc(p_lash, rank, n))) {
|
|
Packit Service |
54dbc3 |
free(p);
|
|
Packit Service |
54dbc3 |
p = NULL;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
x = 0;
|
|
Packit Service |
54dbc3 |
for (i = 0; i < l; i++) {
|
|
Packit Service |
54dbc3 |
if (i == row)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
y = 0;
|
|
Packit Service |
54dbc3 |
for (j = 0; j < l; j++) {
|
|
Packit Service |
54dbc3 |
if (j == col)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (k = 0; k <= n; k++)
|
|
Packit Service |
54dbc3 |
m[x][y][k] = matrix[i][j][k];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
y++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
x++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (determinant(p_lash, n, rank, m, p)) {
|
|
Packit Service |
54dbc3 |
free(p);
|
|
Packit Service |
54dbc3 |
p = NULL;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ret = 0;
|
|
Packit Service |
54dbc3 |
} while (0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
pm_free(m, rank);
|
|
Packit Service |
54dbc3 |
*poly = p;
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* determinant
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* compute the determinant of matrix m of rank of polynomials of degree deg
|
|
Packit Service |
54dbc3 |
* and add the result to polynomial p allocated by caller
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int determinant(lash_t *p_lash, int deg, int rank, int ***m, int *p)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int i, j, k;
|
|
Packit Service |
54dbc3 |
int *q;
|
|
Packit Service |
54dbc3 |
int sign = 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* handle simple case of 1x1 matrix
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (rank == 1) {
|
|
Packit Service |
54dbc3 |
for (i = 0; i <= deg; i++)
|
|
Packit Service |
54dbc3 |
p[i] += m[0][0][i];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* handle simple case of 2x2 matrix
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
else if (rank == 2) {
|
|
Packit Service |
54dbc3 |
for (i = 0; i <= deg; i++) {
|
|
Packit Service |
54dbc3 |
if (m[0][0][i] == 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j <= deg; j++) {
|
|
Packit Service |
54dbc3 |
if (m[1][1][j] == 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p[i+j] += m[0][0][i]*m[1][1][j];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i <= deg; i++) {
|
|
Packit Service |
54dbc3 |
if (m[0][1][i] == 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j <= deg; j++) {
|
|
Packit Service |
54dbc3 |
if (m[1][0][j] == 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p[i+j] -= m[0][1][i]*m[1][0][j];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* handle the general case
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
else {
|
|
Packit Service |
54dbc3 |
for (i = 0; i < rank; i++) {
|
|
Packit Service |
54dbc3 |
if (sub_determinant(p_lash, deg, rank, 0, i, m, &q))
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j <= deg; j++) {
|
|
Packit Service |
54dbc3 |
if (m[0][i][j] == 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (k = 0; k <= deg; k++) {
|
|
Packit Service |
54dbc3 |
if (q[k] == 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p[j+k] += sign*m[0][i][j]*q[k];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
free(q);
|
|
Packit Service |
54dbc3 |
sign = -sign;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* char_poly
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* compute the characteristic polynomial of matrix of rank
|
|
Packit Service |
54dbc3 |
* by computing the determinant of m-x*I and return in poly
|
|
Packit Service |
54dbc3 |
* as an array. caller must free poly
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int char_poly(lash_t *p_lash, int rank, int **matrix, int **poly)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int ret = -1;
|
|
Packit Service |
54dbc3 |
int i, j;
|
|
Packit Service |
54dbc3 |
int ***m = NULL;
|
|
Packit Service |
54dbc3 |
int *p = NULL;
|
|
Packit Service |
54dbc3 |
int deg = rank;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
if (!matrix)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(p = poly_alloc(p_lash, deg)))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(m = pm_alloc(p_lash, rank, deg))) {
|
|
Packit Service |
54dbc3 |
free(p);
|
|
Packit Service |
54dbc3 |
p = NULL;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < rank; i++) {
|
|
Packit Service |
54dbc3 |
for (j = 0; j < rank; j++) {
|
|
Packit Service |
54dbc3 |
m[i][j][0] = matrix[i][j];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
m[i][i][1] = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (determinant(p_lash, deg, rank, m, p)) {
|
|
Packit Service |
54dbc3 |
free(p);
|
|
Packit Service |
54dbc3 |
p = NULL;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ret = 0;
|
|
Packit Service |
54dbc3 |
} while (0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
pm_free(m, rank);
|
|
Packit Service |
54dbc3 |
*poly = p;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* get_switch_metric
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* compute the matrix of minimum distances between each of
|
|
Packit Service |
54dbc3 |
* the adjacent switch nodes to sw along paths
|
|
Packit Service |
54dbc3 |
* that do not go through sw. do calculation by
|
|
Packit Service |
54dbc3 |
* relaxation method
|
|
Packit Service |
54dbc3 |
* allocate space for the matrix and save in node_t structure
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int get_switch_metric(lash_t *p_lash, int sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int ret = -1;
|
|
Packit Service |
54dbc3 |
unsigned int i, j, change;
|
|
Packit Service |
54dbc3 |
int sw1, sw2, sw3;
|
|
Packit Service |
54dbc3 |
switch_t *s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
switch_t *s1, *s2, *s3;
|
|
Packit Service |
54dbc3 |
int **m;
|
|
Packit Service |
54dbc3 |
mesh_node_t *node = s->node;
|
|
Packit Service |
54dbc3 |
unsigned int num_links = node->num_links;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
if (!(m = m_alloc(p_lash, num_links)))
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_links; i++) {
|
|
Packit Service |
54dbc3 |
sw1 = node->links[i]->switch_id;
|
|
Packit Service |
54dbc3 |
s1 = p_lash->switches[sw1];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* make all distances big except s1 to itself */
|
|
Packit Service |
54dbc3 |
for (sw2 = 0; sw2 < p_lash->num_switches; sw2++)
|
|
Packit Service |
54dbc3 |
p_lash->switches[sw2]->node->temp = LARGE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s1->node->temp = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
change = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw2 = 0; sw2 < p_lash->num_switches; sw2++) {
|
|
Packit Service |
54dbc3 |
s2 = p_lash->switches[sw2];
|
|
Packit Service |
54dbc3 |
if (s2->node->temp == LARGE)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
for (j = 0; j < s2->node->num_links; j++) {
|
|
Packit Service |
54dbc3 |
sw3 = s2->node->links[j]->switch_id;
|
|
Packit Service |
54dbc3 |
s3 = p_lash->switches[sw3];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (sw3 == sw)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if ((s2->node->temp + 1) < s3->node->temp) {
|
|
Packit Service |
54dbc3 |
s3->node->temp = s2->node->temp + 1;
|
|
Packit Service |
54dbc3 |
change++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} while (change);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j < num_links; j++) {
|
|
Packit Service |
54dbc3 |
sw2 = node->links[j]->switch_id;
|
|
Packit Service |
54dbc3 |
s2 = p_lash->switches[sw2];
|
|
Packit Service |
54dbc3 |
m[i][j] = s2->node->temp;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (char_poly(p_lash, num_links, m, &node->poly)) {
|
|
Packit Service |
54dbc3 |
m_free(m, num_links);
|
|
Packit Service |
54dbc3 |
m = NULL;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
ret = 0;
|
|
Packit Service |
54dbc3 |
} while (0);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
node->matrix = m;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* classify_switch
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* add switch to histogram of switch types
|
|
Packit Service |
54dbc3 |
* we keep a reference to the first switch
|
|
Packit Service |
54dbc3 |
* found of each type as an exemplar
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void classify_switch(lash_t *p_lash, mesh_t *mesh, int sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int i;
|
|
Packit Service |
54dbc3 |
switch_t *s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
switch_t *s1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s->node->poly)
|
|
Packit Service |
54dbc3 |
goto done;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < mesh->num_class; i++) {
|
|
Packit Service |
54dbc3 |
s1 = p_lash->switches[mesh->class_type[i]];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (poly_diff(s->node->num_links, s->node->poly, s1))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
mesh->class_count[i]++;
|
|
Packit Service |
54dbc3 |
goto done;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
mesh->class_type[mesh->num_class] = sw;
|
|
Packit Service |
54dbc3 |
mesh->class_count[mesh->num_class] = 1;
|
|
Packit Service |
54dbc3 |
mesh->num_class++;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
done:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* classify_mesh_type
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* try to look up node polynomial in table
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void classify_mesh_type(lash_t *p_lash, int sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int i;
|
|
Packit Service |
54dbc3 |
switch_t *s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
const struct mesh_info *t;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s->node->poly)
|
|
Packit Service |
54dbc3 |
goto done;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 1; (t = &mesh_info[i])->dimension != -1; i++) {
|
|
Packit Service |
54dbc3 |
if (poly_diff(t->degree, t->poly, s))
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s->node->type = i;
|
|
Packit Service |
54dbc3 |
s->node->dimension = t->dimension;
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
done:
|
|
Packit Service |
54dbc3 |
s->node->type = 0;
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* remove_edges
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* remove type from nodes that have fewer links
|
|
Packit Service |
54dbc3 |
* than adjacent nodes
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void remove_edges(lash_t *p_lash)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int sw;
|
|
Packit Service |
54dbc3 |
mesh_node_t *n, *nn;
|
|
Packit Service |
54dbc3 |
unsigned i;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < p_lash->num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
n = p_lash->switches[sw]->node;
|
|
Packit Service |
54dbc3 |
if (!n->type)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n->num_links; i++) {
|
|
Packit Service |
54dbc3 |
nn = p_lash->switches[n->links[i]->switch_id]->node;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (nn->num_links > n->num_links) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"removed edge switch %s\n",
|
|
Packit Service |
54dbc3 |
p_lash->switches[sw]->p_sw->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
n->type = -1;
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* get_local_geometry
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* analyze the local geometry around each switch
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int get_local_geometry(lash_t *p_lash, mesh_t *mesh)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int sw;
|
|
Packit Service |
54dbc3 |
int status = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < p_lash->num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* skip switches with more links than MAX_DEGREE
|
|
Packit Service |
54dbc3 |
* since they will never match a known case
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (p_lash->switches[sw]->node->num_links > MAX_DEGREE)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (get_switch_metric(p_lash, sw)) {
|
|
Packit Service |
54dbc3 |
status = -1;
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
classify_mesh_type(p_lash, sw);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
remove_edges(p_lash);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < p_lash->num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
if (p_lash->switches[sw]->node->type < 0)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
classify_switch(p_lash, mesh, sw);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return status;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void print_axis(lash_t *p_lash, char *p, int sw, int port)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
mesh_node_t *node = p_lash->switches[sw]->node;
|
|
Packit Service |
54dbc3 |
char *name = p_lash->switches[sw]->p_sw->p_node->print_desc;
|
|
Packit Service |
54dbc3 |
int c = node->axes[port];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%s[%d] = ", name, port);
|
|
Packit Service |
54dbc3 |
if (c)
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%s%c -> ", ((c - 1) & 1) ? "-" : "+", 'X' + (c - 1)/2);
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "N/A -> ");
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%s\n",
|
|
Packit Service |
54dbc3 |
p_lash->switches[node->links[port]->switch_id]->p_sw->p_node->print_desc);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* seed_axes
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* assign axes to the links of the seed switch
|
|
Packit Service |
54dbc3 |
* assumes switch is of type cartesian mesh
|
|
Packit Service |
54dbc3 |
* axes are numbered 1 to n i.e. +x => 1 -x => 2 etc.
|
|
Packit Service |
54dbc3 |
* this assumes that if all distances are 2 that
|
|
Packit Service |
54dbc3 |
* an axis has only 2 nodes so +A and -A collapse to +A
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void seed_axes(lash_t *p_lash, int sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
mesh_node_t *node = p_lash->switches[sw]->node;
|
|
Packit Service |
54dbc3 |
int n = node->num_links;
|
|
Packit Service |
54dbc3 |
int i, j, c;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!node->matrix || !node->dimension)
|
|
Packit Service |
54dbc3 |
goto done;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (c = 1; c <= 2*node->dimension; c++) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* find the next unassigned axis
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
if (!node->axes[i])
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
node->axes[i] = c++;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* find the matching opposite direction
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
for (j = 0; j < n; j++) {
|
|
Packit Service |
54dbc3 |
if (node->axes[j] || j == i)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node->matrix[i][j] != 2)
|
|
Packit Service |
54dbc3 |
break;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (j != n) {
|
|
Packit Service |
54dbc3 |
node->axes[j] = c;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (OSM_LOG_IS_ACTIVE_V2(p_log, OSM_LOG_DEBUG)) {
|
|
Packit Service |
54dbc3 |
char buf[256], *p;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
p = buf;
|
|
Packit Service |
54dbc3 |
print_axis(p_lash, p, sw, i);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG, "%s", buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
done:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* opposite
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* compute the opposite of axis for switch
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static inline int opposite(switch_t *s, int axis)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
unsigned i, j;
|
|
Packit Service |
54dbc3 |
int negaxis = 1 + (1 ^ (axis - 1));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s->node->matrix)
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < s->node->num_links; i++) {
|
|
Packit Service |
54dbc3 |
if (s->node->axes[i] == axis) {
|
|
Packit Service |
54dbc3 |
for (j = 0; j < s->node->num_links; j++) {
|
|
Packit Service |
54dbc3 |
if (j == i)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
if (s->node->matrix[i][j] != 2)
|
|
Packit Service |
54dbc3 |
return negaxis;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return axis;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* make_geometry
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* induce a geometry on the switches
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void make_geometry(lash_t *p_lash, int sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int num_switches = p_lash->num_switches;
|
|
Packit Service |
54dbc3 |
int sw1, sw2;
|
|
Packit Service |
54dbc3 |
switch_t *s, *s1, *s2, *seed;
|
|
Packit Service |
54dbc3 |
unsigned int i, j, k, l, n, m;
|
|
Packit Service |
54dbc3 |
unsigned int change;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s->node->matrix)
|
|
Packit Service |
54dbc3 |
goto done;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* assign axes to seed switch
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
seed_axes(p_lash, sw);
|
|
Packit Service |
54dbc3 |
seed = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* induce axes in other switches until
|
|
Packit Service |
54dbc3 |
* there is no more change
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
change = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* phase 1 opposites */
|
|
Packit Service |
54dbc3 |
for (sw1 = 0; sw1 < num_switches; sw1++) {
|
|
Packit Service |
54dbc3 |
s1 = p_lash->switches[sw1];
|
|
Packit Service |
54dbc3 |
n = s1->node->num_links;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* ignore chain fragments
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (n < seed->node->num_links && n <= 2)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* only process 'mesh' switches
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
if (!s1->node->matrix)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
if (!s1->node->axes[i])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* can't tell across if more than one
|
|
Packit Service |
54dbc3 |
* likely looking link
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
m = 0;
|
|
Packit Service |
54dbc3 |
for (j = 0; j < n; j++) {
|
|
Packit Service |
54dbc3 |
if (j == i)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (s1->node->matrix[i][j] != 2)
|
|
Packit Service |
54dbc3 |
m++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (m != 1) {
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j < n; j++) {
|
|
Packit Service |
54dbc3 |
if (j == i)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Rule out opposite nodes when distance greater than 4 */
|
|
Packit Service |
54dbc3 |
if (s1->node->matrix[i][j] != 2 &&
|
|
Packit Service |
54dbc3 |
s1->node->matrix[i][j] <= 4) {
|
|
Packit Service |
54dbc3 |
if (s1->node->axes[j]) {
|
|
Packit Service |
54dbc3 |
if (s1->node->axes[j] != opposite(seed, s1->node->axes[i])) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"phase 1 mismatch\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
s1->node->axes[j] = opposite(seed, s1->node->axes[i]);
|
|
Packit Service |
54dbc3 |
change++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* phase 2 switch to switch */
|
|
Packit Service |
54dbc3 |
for (sw1 = 0; sw1 < num_switches; sw1++) {
|
|
Packit Service |
54dbc3 |
s1 = p_lash->switches[sw1];
|
|
Packit Service |
54dbc3 |
n = s1->node->num_links;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s1->node->matrix)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
int l2 = s1->node->links[i]->link_id;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s1->node->axes[i])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (l2 == -1) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"no reverse link\n");
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
sw2 = s1->node->links[i]->switch_id;
|
|
Packit Service |
54dbc3 |
s2 = p_lash->switches[sw2];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s2->node->matrix)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s2->node->axes[l2]) {
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* set axis to opposite of s1->node->axes[i]
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
s2->node->axes[l2] = opposite(seed, s1->node->axes[i]);
|
|
Packit Service |
54dbc3 |
change++;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
if (s2->node->axes[l2] != opposite(seed, s1->node->axes[i])) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG,
|
|
Packit Service |
54dbc3 |
"phase 2 mismatch\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/* Phase 3 corners */
|
|
Packit Service |
54dbc3 |
for (sw1 = 0; sw1 < num_switches; sw1++) {
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[sw1];
|
|
Packit Service |
54dbc3 |
n = s->node->num_links;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!s->node->matrix)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
if (!s->node->axes[i])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j < n; j++) {
|
|
Packit Service |
54dbc3 |
if (i == j || !s->node->axes[j] || s->node->matrix[i][j] != 2)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s1 = p_lash->switches[s->node->links[i]->switch_id];
|
|
Packit Service |
54dbc3 |
s2 = p_lash->switches[s->node->links[j]->switch_id];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* find switch (other than s1) that neighbors i and j
|
|
Packit Service |
54dbc3 |
* have in common
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
for (k = 0; k < s1->node->num_links; k++) {
|
|
Packit Service |
54dbc3 |
if (s1->node->links[k]->switch_id == sw1)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (l = 0; l < s2->node->num_links; l++) {
|
|
Packit Service |
54dbc3 |
if (s2->node->links[l]->switch_id == sw1)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (s1->node->links[k]->switch_id == s2->node->links[l]->switch_id) {
|
|
Packit Service |
54dbc3 |
if (s1->node->axes[k]) {
|
|
Packit Service |
54dbc3 |
if (s1->node->axes[k] != s->node->axes[j]) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG, "phase 3 mismatch\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
s1->node->axes[k] = s->node->axes[j];
|
|
Packit Service |
54dbc3 |
change++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (s2->node->axes[l]) {
|
|
Packit Service |
54dbc3 |
if (s2->node->axes[l] != s->node->axes[i]) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG, "phase 3 mismatch\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
s2->node->axes[l] = s->node->axes[i];
|
|
Packit Service |
54dbc3 |
change++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
goto next_j;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
next_j:
|
|
Packit Service |
54dbc3 |
;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} while (change);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
done:
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* return |a| < |b|
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static inline int ltmag(int a, int b)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
int a1 = (a >= 0)? a : -a;
|
|
Packit Service |
54dbc3 |
int b1 = (b >= 0)? b : -b;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return (a1 < b1) || (a1 == b1 && a > b);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* reorder_node_links
|
|
Packit Service |
54dbc3 |
*
|
|
Packit Service |
54dbc3 |
* reorder the links out of a switch in sign/dimension order
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int reorder_node_links(lash_t *p_lash, mesh_t *mesh, int sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
switch_t *s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
mesh_node_t *node = s->node;
|
|
Packit Service |
54dbc3 |
int n = node->num_links;
|
|
Packit Service |
54dbc3 |
link_t **links;
|
|
Packit Service |
54dbc3 |
int *axes;
|
|
Packit Service |
54dbc3 |
int i, j, k, l;
|
|
Packit Service |
54dbc3 |
int c;
|
|
Packit Service |
54dbc3 |
int next = 0;
|
|
Packit Service |
54dbc3 |
int dimension = mesh->dimension;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(links = calloc(n, sizeof(link_t *)))) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating links array - out of memory\n");
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(axes = calloc(n, sizeof(int)))) {
|
|
Packit Service |
54dbc3 |
free(links);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating axes array - out of memory\n");
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* find the links with axes
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++) {
|
|
Packit Service |
54dbc3 |
j = mesh->dim_order[i];
|
|
Packit Service |
54dbc3 |
for (k = 1; k <= 2; k++) {
|
|
Packit Service |
54dbc3 |
c = 2*j + k;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node->coord[j] > 0)
|
|
Packit Service |
54dbc3 |
c = opposite(s, c);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (l = 0; l < n; l++) {
|
|
Packit Service |
54dbc3 |
if (!node->links[l])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
if (node->axes[l] == c) {
|
|
Packit Service |
54dbc3 |
links[next] = node->links[l];
|
|
Packit Service |
54dbc3 |
axes[next] = node->axes[l];
|
|
Packit Service |
54dbc3 |
node->links[l] = NULL;
|
|
Packit Service |
54dbc3 |
next++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* get the rest
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
if (!node->links[i])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
links[next] = node->links[i];
|
|
Packit Service |
54dbc3 |
axes[next] = node->axes[i];
|
|
Packit Service |
54dbc3 |
node->links[i] = NULL;
|
|
Packit Service |
54dbc3 |
next++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < n; i++) {
|
|
Packit Service |
54dbc3 |
node->links[i] = links[i];
|
|
Packit Service |
54dbc3 |
node->axes[i] = axes[i];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
free(links);
|
|
Packit Service |
54dbc3 |
free(axes);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* make_coord
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int make_coord(lash_t *p_lash, mesh_t *mesh, int seed)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
unsigned int i, j, k;
|
|
Packit Service |
54dbc3 |
int sw;
|
|
Packit Service |
54dbc3 |
switch_t *s, *s1;
|
|
Packit Service |
54dbc3 |
unsigned int change;
|
|
Packit Service |
54dbc3 |
unsigned int dimension = mesh->dimension;
|
|
Packit Service |
54dbc3 |
int num_switches = p_lash->num_switches;
|
|
Packit Service |
54dbc3 |
int assigned_axes = 0, unassigned_axes = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s->node->coord = calloc(dimension, sizeof(int));
|
|
Packit Service |
54dbc3 |
if (!s->node->coord) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating coord - out of memory\n");
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++)
|
|
Packit Service |
54dbc3 |
s->node->coord[i] = (sw == seed) ? 0 : LARGE;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < s->node->num_links; i++)
|
|
Packit Service |
54dbc3 |
if (s->node->axes[i] == 0)
|
|
Packit Service |
54dbc3 |
unassigned_axes++;
|
|
Packit Service |
54dbc3 |
else
|
|
Packit Service |
54dbc3 |
assigned_axes++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG, "%d/%d unassigned/assigned axes\n",
|
|
Packit Service |
54dbc3 |
unassigned_axes, assigned_axes);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
do {
|
|
Packit Service |
54dbc3 |
change = 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (s->node->coord[0] == LARGE)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (j = 0; j < s->node->num_links; j++) {
|
|
Packit Service |
54dbc3 |
if (!s->node->axes[j])
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s1 = p_lash->switches[s->node->links[j]->switch_id];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (k = 0; k < dimension; k++) {
|
|
Packit Service |
54dbc3 |
int coord = s->node->coord[k];
|
|
Packit Service |
54dbc3 |
unsigned axis = s->node->axes[j] - 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (k == axis/2)
|
|
Packit Service |
54dbc3 |
coord += (axis & 1)? -1 : +1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (ltmag(coord, s1->node->coord[k])) {
|
|
Packit Service |
54dbc3 |
s1->node->coord[k] = coord;
|
|
Packit Service |
54dbc3 |
change++;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
} while (change);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* measure geometry
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int measure_geometry(lash_t *p_lash, mesh_t *mesh)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int i, j;
|
|
Packit Service |
54dbc3 |
int sw;
|
|
Packit Service |
54dbc3 |
switch_t *s;
|
|
Packit Service |
54dbc3 |
int dimension = mesh->dimension;
|
|
Packit Service |
54dbc3 |
int num_switches = p_lash->num_switches;
|
|
Packit Service |
54dbc3 |
int max[MAX_DIMENSION];
|
|
Packit Service |
54dbc3 |
int min[MAX_DIMENSION];
|
|
Packit Service |
54dbc3 |
int size[MAX_DIMENSION];
|
|
Packit Service |
54dbc3 |
int max_size;
|
|
Packit Service |
54dbc3 |
int max_index;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
mesh->size = calloc(dimension, sizeof(int));
|
|
Packit Service |
54dbc3 |
if (!mesh->size) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating size - out of memory\n");
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++) {
|
|
Packit Service |
54dbc3 |
max[i] = -LARGE;
|
|
Packit Service |
54dbc3 |
min[i] = LARGE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++) {
|
|
Packit Service |
54dbc3 |
if (s->node->coord[i] == LARGE)
|
|
Packit Service |
54dbc3 |
continue;
|
|
Packit Service |
54dbc3 |
if (s->node->coord[i] > max[i])
|
|
Packit Service |
54dbc3 |
max[i] = s->node->coord[i];
|
|
Packit Service |
54dbc3 |
if (s->node->coord[i] < min[i])
|
|
Packit Service |
54dbc3 |
min[i] = s->node->coord[i];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++)
|
|
Packit Service |
54dbc3 |
mesh->size[i] = size[i] = max[i] - min[i] + 1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* find an order of dimensions that places largest
|
|
Packit Service |
54dbc3 |
* sizes first since this seems to work best with LASH
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
for (j = 0; j < dimension; j++) {
|
|
Packit Service |
54dbc3 |
max_size = -1;
|
|
Packit Service |
54dbc3 |
max_index = -1;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++) {
|
|
Packit Service |
54dbc3 |
if (size[i] > max_size) {
|
|
Packit Service |
54dbc3 |
max_size = size[i];
|
|
Packit Service |
54dbc3 |
max_index = i;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
mesh->dim_order[j] = max_index;
|
|
Packit Service |
54dbc3 |
size[max_index] = -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* reorder links
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int reorder_links(lash_t *p_lash, mesh_t *mesh)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int sw;
|
|
Packit Service |
54dbc3 |
int num_switches = p_lash->num_switches;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
if (reorder_node_links(p_lash, mesh, sw)) {
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* compare two switches in a sort
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static int compare_switches(const void *p1, const void *p2)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
const comp_t *cp1 = p1, *cp2 = p2;
|
|
Packit Service |
54dbc3 |
const sort_ctx_t *ctx = &cp1->ctx;
|
|
Packit Service |
54dbc3 |
switch_t *s1 = ctx->p_lash->switches[cp1->index];
|
|
Packit Service |
54dbc3 |
switch_t *s2 = ctx->p_lash->switches[cp2->index];
|
|
Packit Service |
54dbc3 |
int i, j;
|
|
Packit Service |
54dbc3 |
int ret;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < ctx->mesh->dimension; i++) {
|
|
Packit Service |
54dbc3 |
j = ctx->mesh->dim_order[i];
|
|
Packit Service |
54dbc3 |
ret = s1->node->coord[j] - s2->node->coord[j];
|
|
Packit Service |
54dbc3 |
if (ret)
|
|
Packit Service |
54dbc3 |
return ret;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* sort_switches - reorder switch array
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void sort_switches(lash_t *p_lash, mesh_t *mesh)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
unsigned int i, j;
|
|
Packit Service |
54dbc3 |
unsigned int num_switches = p_lash->num_switches;
|
|
Packit Service |
54dbc3 |
comp_t *comp;
|
|
Packit Service |
54dbc3 |
int *reverse;
|
|
Packit Service |
54dbc3 |
switch_t *s;
|
|
Packit Service |
54dbc3 |
switch_t **switches;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
comp = malloc(num_switches * sizeof(comp_t));
|
|
Packit Service |
54dbc3 |
reverse = malloc(num_switches * sizeof(int));
|
|
Packit Service |
54dbc3 |
switches = malloc(num_switches * sizeof(switch_t *));
|
|
Packit Service |
54dbc3 |
if (!comp || !reverse || !switches) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(&p_lash->p_osm->log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed memory allocation - switches not sorted!\n");
|
|
Packit Service |
54dbc3 |
goto Exit;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_switches; i++) {
|
|
Packit Service |
54dbc3 |
comp[i].index = i;
|
|
Packit Service |
54dbc3 |
comp[i].ctx.mesh = mesh;
|
|
Packit Service |
54dbc3 |
comp[i].ctx.p_lash = p_lash;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
qsort(comp, num_switches, sizeof(comp_t), compare_switches);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_switches; i++)
|
|
Packit Service |
54dbc3 |
reverse[comp[i].index] = i;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_switches; i++) {
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[comp[i].index];
|
|
Packit Service |
54dbc3 |
switches[i] = s;
|
|
Packit Service |
54dbc3 |
s->id = i;
|
|
Packit Service |
54dbc3 |
for (j = 0; j < s->node->num_links; j++)
|
|
Packit Service |
54dbc3 |
s->node->links[j]->switch_id =
|
|
Packit Service |
54dbc3 |
reverse[s->node->links[j]->switch_id];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_switches; i++)
|
|
Packit Service |
54dbc3 |
p_lash->switches[i] = switches[i];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
Exit:
|
|
Packit Service |
54dbc3 |
if (switches)
|
|
Packit Service |
54dbc3 |
free(switches);
|
|
Packit Service |
54dbc3 |
if (comp)
|
|
Packit Service |
54dbc3 |
free(comp);
|
|
Packit Service |
54dbc3 |
if (reverse)
|
|
Packit Service |
54dbc3 |
free(reverse);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* osm_mesh_delete - free per mesh resources
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static void mesh_delete(mesh_t *mesh)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
if (mesh) {
|
|
Packit Service |
54dbc3 |
if (mesh->class_type)
|
|
Packit Service |
54dbc3 |
free(mesh->class_type);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (mesh->class_count)
|
|
Packit Service |
54dbc3 |
free(mesh->class_count);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (mesh->size)
|
|
Packit Service |
54dbc3 |
free(mesh->size);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
free(mesh);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* osm_mesh_create - allocate per mesh resources
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
static mesh_t *mesh_create(lash_t *p_lash)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
mesh_t *mesh;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if(!(mesh = calloc(1, sizeof(mesh_t))))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(mesh->class_type = calloc(p_lash->num_switches, sizeof(int))))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(mesh->class_count = calloc(p_lash->num_switches, sizeof(int))))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
return mesh;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
err:
|
|
Packit Service |
54dbc3 |
mesh_delete(mesh);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating mesh - out of memory\n");
|
|
Packit Service |
54dbc3 |
return NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* osm_mesh_node_delete - cleanup per switch resources
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
void osm_mesh_node_delete(lash_t *p_lash, switch_t *sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
unsigned i;
|
|
Packit Service |
54dbc3 |
mesh_node_t *node = sw->node;
|
|
Packit Service |
54dbc3 |
unsigned num_ports = sw->p_sw->num_ports;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node) {
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_ports; i++)
|
|
Packit Service |
54dbc3 |
if (node->links[i])
|
|
Packit Service |
54dbc3 |
free(node->links[i]);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node->poly)
|
|
Packit Service |
54dbc3 |
free(node->poly);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node->matrix) {
|
|
Packit Service |
54dbc3 |
for (i = 0; i < node->num_links; i++) {
|
|
Packit Service |
54dbc3 |
if (node->matrix[i])
|
|
Packit Service |
54dbc3 |
free(node->matrix[i]);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
free(node->matrix);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node->axes)
|
|
Packit Service |
54dbc3 |
free(node->axes);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (node->coord)
|
|
Packit Service |
54dbc3 |
free(node->coord);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
free(node);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
sw->node = NULL;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* osm_mesh_node_create - allocate per switch resources
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
int osm_mesh_node_create(lash_t *p_lash, switch_t *sw)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
unsigned i;
|
|
Packit Service |
54dbc3 |
mesh_node_t *node;
|
|
Packit Service |
54dbc3 |
unsigned num_ports = sw->p_sw->num_ports;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(node = sw->node = calloc(1, sizeof(mesh_node_t) + num_ports * sizeof(link_t *))))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_ports; i++)
|
|
Packit Service |
54dbc3 |
if (!(node->links[i] = calloc(1, sizeof(link_t) + num_ports * sizeof(int))))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (!(node->axes = calloc(num_ports, sizeof(int))))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < num_ports; i++) {
|
|
Packit Service |
54dbc3 |
node->links[i]->switch_id = NONE;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
err:
|
|
Packit Service |
54dbc3 |
osm_mesh_node_delete(p_lash, sw);
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_ERROR,
|
|
Packit Service |
54dbc3 |
"Failed allocating mesh node - out of memory\n");
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
static void dump_mesh(lash_t *p_lash)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
int sw;
|
|
Packit Service |
54dbc3 |
int num_switches = p_lash->num_switches;
|
|
Packit Service |
54dbc3 |
int dimension;
|
|
Packit Service |
54dbc3 |
int i, j, k, n;
|
|
Packit Service |
54dbc3 |
switch_t *s, *s2;
|
|
Packit Service |
54dbc3 |
char buf[256];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (sw = 0; sw < num_switches; sw++) {
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[sw];
|
|
Packit Service |
54dbc3 |
dimension = s->node->dimension;
|
|
Packit Service |
54dbc3 |
n = sprintf(buf, "[");
|
|
Packit Service |
54dbc3 |
for (i = 0; i < dimension; i++) {
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n,
|
|
Packit Service |
54dbc3 |
"%2d", s->node->coord[i]);
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
if (i != dimension - 1) {
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n, "%s", ",");
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n, "]");
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
for (j = 0; j < s->node->num_links; j++) {
|
|
Packit Service |
54dbc3 |
s2 = p_lash->switches[s->node->links[j]->switch_id];
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n, " [%d]->[", j);
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
for (k = 0; k < dimension; k++) {
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n, "%2d",
|
|
Packit Service |
54dbc3 |
s2->node->coord[k]);
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
if (k != dimension - 1) {
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n,
|
|
Packit Service |
54dbc3 |
",");
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
n += snprintf(buf + n, sizeof(buf) - n, "]");
|
|
Packit Service |
54dbc3 |
if (n > sizeof(buf))
|
|
Packit Service |
54dbc3 |
n = sizeof(buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_DEBUG, "%s\n", buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* osm_do_mesh_analysis
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
int osm_do_mesh_analysis(lash_t *p_lash)
|
|
Packit Service |
54dbc3 |
{
|
|
Packit Service |
54dbc3 |
osm_log_t *p_log = &p_lash->p_osm->log;
|
|
Packit Service |
54dbc3 |
mesh_t *mesh;
|
|
Packit Service |
54dbc3 |
int max_class_num = 0;
|
|
Packit Service |
54dbc3 |
int max_class_type = -1;
|
|
Packit Service |
54dbc3 |
int i;
|
|
Packit Service |
54dbc3 |
switch_t *s;
|
|
Packit Service |
54dbc3 |
char buf[256], *p;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG_ENTER(p_log);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
mesh = mesh_create(p_lash);
|
|
Packit Service |
54dbc3 |
if (!mesh)
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (get_local_geometry(p_lash, mesh))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (mesh->num_class == 0) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO,
|
|
Packit Service |
54dbc3 |
"found no likely mesh nodes - done\n");
|
|
Packit Service |
54dbc3 |
goto done;
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
/*
|
|
Packit Service |
54dbc3 |
* find dominant switch class
|
|
Packit Service |
54dbc3 |
*/
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO, "found %d node class%s\n",
|
|
Packit Service |
54dbc3 |
mesh->num_class, (mesh->num_class == 1) ? "" : "es");
|
|
Packit Service |
54dbc3 |
for (i = 0; i < mesh->num_class; i++) {
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO,
|
|
Packit Service |
54dbc3 |
"class[%d] has %d members with type = %d\n",
|
|
Packit Service |
54dbc3 |
i, mesh->class_count[i],
|
|
Packit Service |
54dbc3 |
p_lash->switches[mesh->class_type[i]]->node->type);
|
|
Packit Service |
54dbc3 |
if (mesh->class_count[i] > max_class_num) {
|
|
Packit Service |
54dbc3 |
max_class_num = mesh->class_count[i];
|
|
Packit Service |
54dbc3 |
max_class_type = mesh->class_type[i];
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
s = p_lash->switches[max_class_type];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p = buf;
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%snode shape is ",
|
|
Packit Service |
54dbc3 |
(mesh->num_class == 1) ? "" : "most common ");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (s->node->type) {
|
|
Packit Service |
54dbc3 |
const struct mesh_info *t = &mesh_info[s->node->type];
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
for (i = 0; i < t->dimension; i++) {
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%s%d%s", i? " x " : "", t->size[i],
|
|
Packit Service |
54dbc3 |
(t->size[i] == 6)? "+" : "");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
p += sprintf(p, " mesh\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
mesh->dimension = t->dimension;
|
|
Packit Service |
54dbc3 |
} else {
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "unknown geometry\n");
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO, "%s", buf);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO, "poly = %s\n",
|
|
Packit Service |
54dbc3 |
poly_print(s->node->num_links, s->node->poly));
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (s->node->type) {
|
|
Packit Service |
54dbc3 |
make_geometry(p_lash, max_class_type);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (make_coord(p_lash, mesh, max_class_type))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (measure_geometry(p_lash, mesh))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (reorder_links(p_lash, mesh))
|
|
Packit Service |
54dbc3 |
goto err;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
sort_switches(p_lash, mesh);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
p = buf;
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "found ");
|
|
Packit Service |
54dbc3 |
for (i = 0; i < mesh->dimension; i++)
|
|
Packit Service |
54dbc3 |
p += sprintf(p, "%s%d", i? " x " : "", mesh->size[i]);
|
|
Packit Service |
54dbc3 |
p += sprintf(p, " mesh\n");
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
OSM_LOG(p_log, OSM_LOG_INFO, "%s", buf);
|
|
Packit Service |
54dbc3 |
}
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
if (OSM_LOG_IS_ACTIVE_V2(p_log, OSM_LOG_DEBUG))
|
|
Packit Service |
54dbc3 |
dump_mesh(p_lash);
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
done:
|
|
Packit Service |
54dbc3 |
mesh_delete(mesh);
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return 0;
|
|
Packit Service |
54dbc3 |
|
|
Packit Service |
54dbc3 |
err:
|
|
Packit Service |
54dbc3 |
mesh_delete(mesh);
|
|
Packit Service |
54dbc3 |
OSM_LOG_EXIT(p_log);
|
|
Packit Service |
54dbc3 |
return -1;
|
|
Packit Service |
54dbc3 |
}
|