diff --git a/Esm/ib/include/fm_xml.h b/Esm/ib/include/fm_xml.h
index 219945c1..7b22ddea 100644
--- a/Esm/ib/include/fm_xml.h
+++ b/Esm/ib/include/fm_xml.h
@@ -852,6 +852,7 @@ typedef struct _SMXmlConfig {
uint32_t node_appearance_msg_thresh;
uint32_t spine_first_routing;
uint32_t shortestPathBalanced;
+ uint32_t hypercube;
uint32_t lmc;
uint32_t lmc_e0;
char routing_algorithm[STRING_SIZE];
diff --git a/Esm/ib/src/config/fm_xml.c b/Esm/ib/src/config/fm_xml.c
index 1ad794d4..52f6e42d 100644
--- a/Esm/ib/src/config/fm_xml.c
+++ b/Esm/ib/src/config/fm_xml.c
@@ -1556,6 +1556,7 @@ void smInitConfig(SMXmlConfig_t *smp, SMDPLXmlConfig_t *dplp, SMMcastConfig_t *m
DEFAULT_AND_CKSUM_U32(smp->node_appearance_msg_thresh, 0, CKSUM_OVERALL_DISRUPT_CONSIST);
DEFAULT_AND_CKSUM_U32(smp->spine_first_routing, 0, CKSUM_OVERALL_DISRUPT_CONSIST);
DEFAULT_AND_CKSUM_U32(smp->shortestPathBalanced, 1, CKSUM_OVERALL_DISRUPT_CONSIST);
+ DEFAULT_AND_CKSUM_U32(smp->hypercube, 0, CKSUM_OVERALL_DISRUPT_CONSIST);
DEFAULT_AND_CKSUM_U32(smp->lid, 0x0, CKSUM_OVERALL_DISRUPT);
DEFAULT_U32(smp->lmc, 0x0);
@@ -1913,6 +1914,7 @@ void smShowConfig(SMXmlConfig_t *smp, SMDPLXmlConfig_t *dplp, SMMcastConfig_t *m
printf("XML - node_appearance_msg_thresh %u\n", (unsigned int)smp->node_appearance_msg_thresh);
printf("XML - spine_first_routing %u\n", (unsigned int)smp->spine_first_routing);
printf("XML - shortestPathBalanced %u\n", (unsigned int)smp->shortestPathBalanced);
+ printf("XML - hypercube %u\n", (unsigned int)smp->hypercube);
printf("XML - lid 0x%x\n", (unsigned int)smp->lid);
printf("XML - lmc 0x%x\n", (unsigned int)smp->lmc);
printf("XML - lmc_e0 0x%x\n", (unsigned int)smp->lmc_e0);
@@ -5953,6 +5955,7 @@ static IXML_FIELD SmFields[] = {
{ tag:"NodeAppearanceMsgThreshold", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, node_appearance_msg_thresh) },
{ tag:"SpineFirstRouting", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, spine_first_routing) },
{ tag:"ShortestPathBalanced", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, shortestPathBalanced) },
+ { tag:"Hypercube", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, hypercube) },
{ tag:"PathSelection", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, path_selection), end_func:SmPathSelectionParserEnd },
{ tag:"QueryValidation", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, queryValidation) },
{ tag:"SmaBatchSize", format:'u', IXML_FIELD_INFO(SMXmlConfig_t, sma_batch_size) },
diff --git a/Esm/ib/src/linux/startup/opafm_src.xml b/Esm/ib/src/linux/startup/opafm_src.xml
index c816d9ba..1b9446a1 100644
--- a/Esm/ib/src/linux/startup/opafm_src.xml
+++ b/Esm/ib/src/linux/startup/opafm_src.xml
@@ -931,6 +931,11 @@
shortestpath
+
+
+
+ 0
+
diff --git a/Esm/ib/src/smi/include/sm_l.h b/Esm/ib/src/smi/include/sm_l.h
index 8792e722..30dd616f 100755
--- a/Esm/ib/src/smi/include/sm_l.h
+++ b/Esm/ib/src/smi/include/sm_l.h
@@ -1519,7 +1519,7 @@ static __inline__ Lid_t sm_port_top_lid(Port_t * portp) {
(((Z) == STL_LINK_SPEED_12_5G) ? 12500000000ull : 25781250000ull)
// Cost should be evenly divisable by (width * SpeedFactor)
-#define SpeedWidth_to_Cost(X) ((X) ? 2400/(X) : 2400)
+#define SpeedWidth_to_Cost(X) (((X) && !sm_config.hypercube) ? 2400/(X) : 2400)
static __inline__ uint8_t sm_GetLsf(STL_PORT_INFO *portInfo) {
return (Decode_SpeedFactor(portInfo->LinkSpeed.Active));
diff --git a/Esm/ib/src/smi/sm/sm_shortestpath.c b/Esm/ib/src/smi/sm/sm_shortestpath.c
index 84ee41b4..7552a6af 100644
--- a/Esm/ib/src/smi/sm/sm_shortestpath.c
+++ b/Esm/ib/src/smi/sm/sm_shortestpath.c
@@ -231,6 +231,7 @@ _select_ports(Topology_t *topop, Node_t *switchp, int endIndex, SwitchportToNext
uint32_t best_switchLidsRouted = 0xffffffff;
int end_port = 0;
Node_t *next_nodep;
+ Node_t *first_nodep = 0;
Port_t *portp;
SpineFirstState_t sfstate;
SpineFirstResult_t sfres;
@@ -284,9 +285,13 @@ _select_ports(Topology_t *topop, Node_t *switchp, int endIndex, SwitchportToNext
best_speed = cur_speed;
best_lidsRouted = portp->portData->lidsRouted;
best_switchLidsRouted = next_nodep->numLidsRouted;
+ first_nodep = next_nodep;
end_port = 0;
}
else if (selectBest) {
+ if ((sm_config.hypercube) && (next_nodep != first_nodep)) {
+ break;
+ }
if (portp->portData->lidsRouted < best_lidsRouted) {
best_lidsRouted = portp->portData->lidsRouted;
best_switchLidsRouted = next_nodep->numLidsRouted;