@@ -1250,6 +1250,31 @@ static const char * hwloc_memory_tier_type_snprintf(hwloc_memory_tier_type_t typ
1250
1250
}
1251
1251
}
1252
1252
1253
+ static hwloc_memory_tier_type_t hwloc_memory_tier_type_sscanf (const char * name )
1254
+ {
1255
+ if (!strcasecmp (name , "DRAM" ))
1256
+ return HWLOC_MEMORY_TIER_DRAM ;
1257
+ if (!strcasecmp (name , "HBM" ))
1258
+ return HWLOC_MEMORY_TIER_HBM ;
1259
+ if (!strcasecmp (name , "GPUMemory" ))
1260
+ return HWLOC_MEMORY_TIER_GPU ;
1261
+ if (!strcasecmp (name , "SPM" ))
1262
+ return HWLOC_MEMORY_TIER_SPM ;
1263
+ if (!strcasecmp (name , "NVM" ))
1264
+ return HWLOC_MEMORY_TIER_NVM ;
1265
+ if (!strcasecmp (name , "CXL-DRAM" ))
1266
+ return HWLOC_MEMORY_TIER_CXL |HWLOC_MEMORY_TIER_DRAM ;
1267
+ if (!strcasecmp (name , "CXL-HBM" ))
1268
+ return HWLOC_MEMORY_TIER_CXL |HWLOC_MEMORY_TIER_HBM ;
1269
+ if (!strcasecmp (name , "CXL-GPUMemory" ))
1270
+ return HWLOC_MEMORY_TIER_CXL |HWLOC_MEMORY_TIER_GPU ;
1271
+ if (!strcasecmp (name , "CXL-SPM" ))
1272
+ return HWLOC_MEMORY_TIER_CXL |HWLOC_MEMORY_TIER_SPM ;
1273
+ if (!strcasecmp (name , "CXL-NVM" ))
1274
+ return HWLOC_MEMORY_TIER_CXL |HWLOC_MEMORY_TIER_NVM ;
1275
+ return 0 ;
1276
+ }
1277
+
1253
1278
/* factorized tier, grouping multiple nodes */
1254
1279
struct hwloc_memory_tier_s {
1255
1280
hwloc_nodeset_t nodeset ;
@@ -1629,10 +1654,113 @@ hwloc__guess_memory_tiers_types(hwloc_topology_t topology __hwloc_attribute_unus
1629
1654
return 0 ;
1630
1655
}
1631
1656
1657
+ /* parses something like 0xf=HBM;0x0f=DRAM;0x00f=CXL-DRAM */
1658
+ static struct hwloc_memory_tier_s *
1659
+ hwloc__force_memory_tiers (hwloc_topology_t topology __hwloc_attribute_unused ,
1660
+ unsigned * nr_tiers_p ,
1661
+ const char * _env )
1662
+ {
1663
+ struct hwloc_memory_tier_s * tiers = NULL ;
1664
+ unsigned nr_tiers , i ;
1665
+ hwloc_bitmap_t nodeset = NULL ;
1666
+ char * env ;
1667
+ const char * tmp ;
1668
+
1669
+ env = strdup (_env );
1670
+ if (!env ) {
1671
+ fprintf (stderr , "[hwloc/memtiers] failed to duplicate HWLOC_MEMTIERS envvar\n" );
1672
+ goto out ;
1673
+ }
1674
+
1675
+ tmp = env ;
1676
+ nr_tiers = 1 ;
1677
+ while (1 ) {
1678
+ tmp = strchr (tmp , ';' );
1679
+ if (!tmp )
1680
+ break ;
1681
+ tmp ++ ;
1682
+ nr_tiers ++ ;
1683
+ }
1684
+
1685
+ nodeset = hwloc_bitmap_alloc ();
1686
+ if (!nodeset ) {
1687
+ fprintf (stderr , "[hwloc/memtiers] failed to allocated forced tiers' nodeset\n" );
1688
+ goto out_with_envvar ;
1689
+ }
1690
+
1691
+ tiers = calloc (nr_tiers , sizeof (* tiers ));
1692
+ if (!tiers ) {
1693
+ fprintf (stderr , "[hwloc/memtiers] failed to allocated forced tiers\n" );
1694
+ goto out_with_nodeset ;
1695
+ }
1696
+ nr_tiers = 0 ;
1697
+
1698
+ tmp = env ;
1699
+ while (1 ) {
1700
+ char * end ;
1701
+ char * equal ;
1702
+ hwloc_memory_tier_type_t type ;
1703
+
1704
+ end = strchr (tmp , ';' );
1705
+ if (end )
1706
+ * end = '\0' ;
1707
+
1708
+ equal = strchr (tmp , '=' );
1709
+ if (!equal ) {
1710
+ fprintf (stderr , "[hwloc/memtiers] missing `=' before end of forced tier description at `%s'\n" , tmp );
1711
+ goto out_with_tiers ;
1712
+ }
1713
+ * equal = '\0' ;
1714
+
1715
+ hwloc_bitmap_sscanf (nodeset , tmp );
1716
+ if (hwloc_bitmap_iszero (nodeset )) {
1717
+ fprintf (stderr , "[hwloc/memtiers] empty forced tier nodeset `%s', aborting\n" , tmp );
1718
+ goto out_with_tiers ;
1719
+ }
1720
+ type = hwloc_memory_tier_type_sscanf (equal + 1 );
1721
+ if (!type )
1722
+ hwloc_debug ("failed to recognize forced tier type `%s'\n" , equal + 1 );
1723
+ tiers [nr_tiers ].nodeset = hwloc_bitmap_dup (nodeset );
1724
+ tiers [nr_tiers ].type = type ;
1725
+ tiers [nr_tiers ].local_bw_min = tiers [nr_tiers ].local_bw_max = 0 ;
1726
+ tiers [nr_tiers ].local_lat_min = tiers [nr_tiers ].local_lat_max = 0 ;
1727
+ nr_tiers ++ ;
1728
+ if (!end )
1729
+ break ;
1730
+ tmp = end + 1 ;
1731
+ }
1732
+
1733
+ free (env );
1734
+ hwloc_bitmap_free (nodeset );
1735
+ hwloc_debug ("Forcing %u memory tiers\n" , nr_tiers );
1736
+ #ifdef HWLOC_DEBUG
1737
+ for (i = 0 ; i < nr_tiers ; i ++ ) {
1738
+ char * s ;
1739
+ hwloc_bitmap_asprintf (& s , tiers [i ].nodeset );
1740
+ hwloc_debug (" tier #%u type %lx nodeset %s\n" , i , tiers [i ].type , s );
1741
+ free (s );
1742
+ }
1743
+ #endif
1744
+ * nr_tiers_p = nr_tiers ;
1745
+ return tiers ;
1746
+
1747
+ out_with_tiers :
1748
+ for (i = 0 ; i < nr_tiers ; i ++ )
1749
+ hwloc_bitmap_free (tiers [i ].nodeset );
1750
+ free (tiers );
1751
+ out_with_nodeset :
1752
+ hwloc_bitmap_free (nodeset );
1753
+ out_with_envvar :
1754
+ free (env );
1755
+ out :
1756
+ return NULL ;
1757
+ }
1758
+
1632
1759
static void
1633
1760
hwloc__apply_memory_tiers_subtypes (hwloc_topology_t topology ,
1634
1761
unsigned nr_tiers ,
1635
- struct hwloc_memory_tier_s * tiers )
1762
+ struct hwloc_memory_tier_s * tiers ,
1763
+ int force )
1636
1764
{
1637
1765
hwloc_obj_t node = NULL ;
1638
1766
hwloc_debug ("Marking node tiers\n" );
@@ -1641,9 +1769,10 @@ hwloc__apply_memory_tiers_subtypes(hwloc_topology_t topology,
1641
1769
for (j = 0 ; j < nr_tiers ; j ++ ) {
1642
1770
if (hwloc_bitmap_isset (tiers [j ].nodeset , node -> os_index )) {
1643
1771
const char * subtype = hwloc_memory_tier_type_snprintf (tiers [j ].type );
1644
- if (!node -> subtype ) { /* don't overwrite the existing subtype */
1772
+ if (!node -> subtype || force ) { /* don't overwrite the existing subtype unless forced */
1645
1773
if (subtype ) { /* don't set a subtype for unknown tiers */
1646
1774
hwloc_debug (" marking node L#%u P#%u as %s (was %s)\n" , node -> logical_index , node -> os_index , subtype , node -> subtype );
1775
+ free (node -> subtype );
1647
1776
node -> subtype = strdup (subtype );
1648
1777
}
1649
1778
} else
@@ -1661,13 +1790,28 @@ hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology)
1661
1790
struct hwloc_memory_tier_s * tiers ;
1662
1791
unsigned nr_tiers ;
1663
1792
unsigned i ;
1793
+ int force_subtype = 0 ;
1794
+ const char * env ;
1795
+
1796
+ env = getenv ("HWLOC_MEMTIERS" );
1797
+ if (env ) {
1798
+ if (!strcmp (env , "none" ))
1799
+ goto out ;
1800
+ tiers = hwloc__force_memory_tiers (topology , & nr_tiers , env );
1801
+ if (tiers ) {
1802
+ assert (nr_tiers > 0 );
1803
+ force_subtype = 1 ;
1804
+ goto ready ;
1805
+ }
1806
+ }
1664
1807
1665
1808
tiers = hwloc__group_memory_tiers (topology , & nr_tiers );
1666
1809
if (!tiers )
1667
1810
goto out ;
1668
1811
1669
1812
hwloc__guess_memory_tiers_types (topology , nr_tiers , tiers );
1670
1813
1814
+ ready :
1671
1815
#ifdef HWLOC_DEBUG
1672
1816
for (i = 0 ; i < nr_tiers ; i ++ ) {
1673
1817
char * s ;
@@ -1683,7 +1827,7 @@ hwloc_internal_memattrs_guess_memory_tiers(hwloc_topology_t topology)
1683
1827
}
1684
1828
#endif
1685
1829
1686
- hwloc__apply_memory_tiers_subtypes (topology , nr_tiers , tiers );
1830
+ hwloc__apply_memory_tiers_subtypes (topology , nr_tiers , tiers , force_subtype );
1687
1831
1688
1832
for (i = 0 ; i < nr_tiers ; i ++ )
1689
1833
hwloc_bitmap_free (tiers [i ].nodeset );
0 commit comments