Example #1
0
/**
 *      Is graphA isomorphic to graphB?
 *
 *  If this function returns true, then Perm will contain the permutation
 *  required to transform graphB into graphA.
 *  We also use the degree of each Node, that is the number of connections it has, to
 *  speed up rejection of non-isomorphic graphs (if there is a Node in graphA with n
 *  connections, there must be at least one unmatched in graphB with n connections).
 *
 * @param[in]     Node     the discovered Node which we are trying to match
 *                      with a permutation the topology
 * @param[in,out] State our global state, degree and adjacency matrix,
 *                      output a permutation if successful
 * @retval TRUE         the graphs are isomorphic
 * @retval FALSE        the graphs are not isomorphic
 *
 */
BOOLEAN
STATIC
IsIsomorphic (
  IN       UINT8         Node,
  IN OUT   STATE_DATA    *State
  )
{
  UINT8 j;
  UINT8 k;
  UINT8 Nodecnt;

  // We have only been called if Nodecnt == pSelected->size !
  Nodecnt = State->NodesDiscovered + 1;

  if (Node != Nodecnt) {
    // Keep building the permutation
    for (j = 0; j < Nodecnt; j++) {
      // Make sure the degree matches
      if (State->Fabric->SysDegree[Node] != State->Fabric->DbDegree[j]) {
        continue;
      }

      // Make sure that j hasn't been used yet (ought to use a "used"
      // array instead, might be faster)
      for (k = 0; k < Node; k++) {
        if (State->Fabric->Perm[k] == j) {
          break;
        }
      }
      if (k != Node) {
        continue;
      }
      State->Fabric->Perm[Node] = j;
      if (IsIsomorphic (Node + 1, State)) {
        return TRUE;
      }
    }
    return FALSE;
  } else {
    // Test to see if the permutation is isomorphic
    for (j = 0; j < Nodecnt; j++) {
      for (k = 0; k < Nodecnt; k++) {
        if (State->Fabric->SysMatrix[j][k] != State->Fabric->DbMatrix[State->Fabric->Perm[j]][State->Fabric->Perm[k]] ) {
          return FALSE;
        }
      }
    }
    return TRUE;
  }
}
Example #2
0
static int IsDual(int mj, MatRep_t *rep_m, int nj)

{
    MatRep_t *rep_n;	    /* Generators of constituent of N */
    int result;
    CfInfo *minfo = InfoM.Cf + mj;

    /* First check: Dimensions and splitting field must match
       ------------------------------------------------------ */
    if (InfoN.Cf[nj].dim != minfo->dim || InfoN.Cf[nj].spl != minfo->spl)
	return 0;

    /* Read the (contragrediate) generators and compare
       ------------------------------------------------ */
    MESSAGE(2,(" (%s%s)",InfoN.BaseName,Lat_CfName(&InfoN,nj)));
    rep_n = Lat_ReadCfGens(&InfoN,nj,LAT_RG_INVERT|LAT_RG_TRANSPOSE
	| (InfoN.Cf[nj].peakword >= 0 ? LAT_RG_STD : 0));
    
    result = IsIsomorphic(rep_m,minfo,rep_n,Trans + TKInfo.NCf,
	minfo->peakword >= 0);
    MrFree(rep_n);
    return result;
}
Example #3
0
static int AddConstituent(MatRep_t *cf, CfInfo *info, int modno, int cfno)

{
    int i, m;
    for (i = 0; i < NumCf; ++i)
    {
	int rc;
	rc = IsIsomorphic(CfList[i].Gen,CfList[i].Info,cf,NULL,0);
	if (rc < 0)
	    return -1;
	if (rc) 
	    break;
    }

    if (i < NumCf)  /* Constituent was already in the list */
    {
	int m = CfList[i].Mult;
	MrFree(cf);
	CfList[i].CfMap[m][0] = modno;
    }
    else	    /* It's a new constituent */
    {
	CfList[i].Gen = cf;
	CfList[i].Info = info;
	CfList[i].Wg = WgAlloc(cf);
	CfList[i].Mod = &ModList[modno].Info;
	CfList[i].Mult = 0;
	++NumCf;
    }
    m = CfList[i].Mult;
    CfList[i].CfMap[m][0] = modno;
    CfList[i].CfMap[m][1] = cfno;
    CfList[i].Mult++;
    MESSAGE(1,("%s%s is constituent %d\n",ModList[modno].Info.BaseName,
	Lat_CfName(&ModList[modno].Info,cfno),i));
    return i;
}
Example #4
0
/**
 * Using the description of the fabric topology we discovered, try to find a match
 * among the supported topologies.
 *
 * @HtFeatMethod{::F_LOOKUP_COMPUTE_AND_LOAD_ROUTING_TABLES}
 *
 * A supported topology description matches the discovered fabric if the Nodes can be
 * matched in such a way that all the Nodes connected in one set are exactly the
 * Nodes connected in the other (formally, that the graphs are isomorphic).  Which
 * Links are used is not really important to matching.  If the graphs match, then
 * there is a permutation of one that translates the Node positions and Linkages to
 * the other.
 *
 * In order to make the isomorphism test efficient, we test for matched number of Nodes
 * (a 4 Node fabric is not isomorphic to a 2 Node topology), and provide degrees of Nodes
 * to the isomorphism test.
 *
 * The generic routing table solution for any topology is predetermined and represented
 * as part of the topology.  The permutation we computed tells us how to interpret the
 * routing onto the fabric we discovered.  We do this working backward from the last
 * Node discovered to the BSP, writing the routing tables as we go.
 *
 * @param[in,out]    State    the discovered fabric, degree matrix, permutation
 *
 */
VOID
LookupComputeAndLoadRoutingTables (
  IN OUT   STATE_DATA    *State
  )
{
  TOPOLOGY_CONTEXT   TopologyContextHandle;
  UINT8 *Selected;
  UINT8 Size;
  UINT8 PairCounter;
  UINT8 ReqTargetLink;
  UINT8 RspTargetLink;
  UINT8 ReqTargetNode;
  UINT8 RspTargetNode;
  UINT8 AbstractBcTargetNodes;
  UINT32 BcTargetLinks;
  UINT8 NodeCounter;
  UINT8 NodeBeingRouted;
  UINT8 NodeRoutedTo;
  UINT8 BroadcastSourceNode;

  Size = State->NodesDiscovered + 1;
  BeginTopologies (&TopologyContextHandle, &Selected, State);
  while (Selected != NULL) {
    if (GraphHowManyNodes (Selected) == Size) {
      // Build Degree vector and Adjacency Matrix for this entry
      for (NodeCounter = 0; NodeCounter < Size; NodeCounter++) {
        State->Fabric->DbDegree[NodeCounter] = 0;
        for (PairCounter = 0; PairCounter < Size; PairCounter++) {
          if (GraphIsAdjacent (Selected, NodeCounter, PairCounter)) {
            State->Fabric->DbMatrix[NodeCounter][PairCounter] = TRUE;
            State->Fabric->DbDegree[NodeCounter]++;
          } else {
            State->Fabric->DbMatrix[NodeCounter][PairCounter] = FALSE;
          }
        }
      }

      if (IsIsomorphic (0, State)) {
        break;  // A matching topology was found
      }
    }
    GetNextTopology (&TopologyContextHandle, &Selected);
  }

  if (Selected != NULL) {
    // Compute the reverse Permutation
    for (NodeCounter = 0; NodeCounter < Size; NodeCounter++) {
      State->Fabric->ReversePerm[State->Fabric->Perm[NodeCounter]] = NodeCounter;
    }

    // Start with the last discovered Node, and move towards the BSP
    for (NodeCounter = 0; NodeCounter < Size; NodeCounter++) {
      NodeBeingRouted = ((Size - 1) - NodeCounter);
      for (NodeRoutedTo = 0; NodeRoutedTo < Size; NodeRoutedTo++) {
        BcTargetLinks = 0;
        AbstractBcTargetNodes = GraphGetBc (Selected, State->Fabric->Perm[NodeBeingRouted], State->Fabric->Perm[NodeRoutedTo]);

        for (BroadcastSourceNode = 0; BroadcastSourceNode < MAX_NODES; BroadcastSourceNode++) {
          if ((AbstractBcTargetNodes & ((UINT32)1 << BroadcastSourceNode)) != 0) {
            // Accepting broadcast from yourself is handled in Nb, so in the topology graph it is an error.
            ASSERT (NodeBeingRouted != State->Fabric->ReversePerm[BroadcastSourceNode]);
            BcTargetLinks |= (UINT32)1 << FindLinkToNode (NodeBeingRouted, State->Fabric->ReversePerm[BroadcastSourceNode], State);
          }
        }

        if (NodeBeingRouted == NodeRoutedTo) {
          ReqTargetLink = ROUTE_TO_SELF;
          RspTargetLink = ROUTE_TO_SELF;
        } else {
          ReqTargetNode = GraphGetReq (Selected, State->Fabric->Perm[NodeBeingRouted], State->Fabric->Perm[NodeRoutedTo]);
          ReqTargetLink = FindLinkToNode (NodeBeingRouted, State->Fabric->ReversePerm[ReqTargetNode], State);

          RspTargetNode = GraphGetRsp (Selected, State->Fabric->Perm[NodeBeingRouted], State->Fabric->Perm[NodeRoutedTo]);
          RspTargetLink = FindLinkToNode (NodeBeingRouted, State->Fabric->ReversePerm[RspTargetNode], State);
        }
        State->Nb->WriteFullRoutingTable (NodeBeingRouted, NodeRoutedTo, ReqTargetLink, RspTargetLink, BcTargetLinks, State->Nb);
      }
      //  Clean up discovery 'footprint' that otherwise remains in the routing table.  It didn't hurt
      // anything, but might cause confusion during debug and validation.  Do this by setting the
      // route back to all self routes. Since it's the Node that would be one more than actually installed,
      // this only applies if less than MaxNodes were found.
      //
      if (Size < MAX_NODES) {
        State->Nb->WriteFullRoutingTable (NodeBeingRouted, Size, ROUTE_TO_SELF, ROUTE_TO_SELF, 0, State->Nb);
      }
    }
  } else {
    //
    // No Matching Topology was found
    // Error Strategy:
    // Auto recovery doesn't seem likely, Force boot as 1P.
    // For reporting, logging, provide number of Nodes
    // If not implemented or returns, boot as BSP uniprocessor.
    //
    // This can be caused by not supplying an additional topology list, if your board is not one of the built-in topologies.
    //
    NotifyErrorCohNoTopology (State->NodesDiscovered, State);
    IDS_ERROR_TRAP;
    // Force 1P
    State->NodesDiscovered = 0;
    State->TotalLinks = 0;
    State->Nb->EnableRoutingTables (0, State->Nb);
    State->HtInterface->CleanMapsAfterError (State);
  }
  // Save the topology pointer, or NULL, for other features
  State->Fabric->MatchedTopology = Selected;
  IDS_HDT_CONSOLE (
    HT_TRACE,
    "System routed as %s.\n",
    ((TopologyContextHandle.IsCustomList) ?
     "custom topology" :
     (((Selected == amdHtTopologySingleNode) || (Selected == NULL)) ?
      "single node" :
      ((Selected == amdHtTopologyDualNode) ?
       "dual node" :
       ((Selected == amdHtTopologyFourSquare) ?
        "four node box" :
        ((Selected == amdHtTopologyFourKite) ?
         "four node kite" :
         ((Selected == amdHtTopologyFourFully) ?
          "fully connected four-way" :
          ((Selected == amdHtTopologyEightDoubloon) ?
           "MCM max performance" :
           ((Selected == amdHtTopologyEightTwinFullyFourWays) ?
            "MCM max I/O" :
            "AMD builtin topology"))))))))
    );
}