| 1853 | } |
| 1854 | |
| 1855 | void ggml_numa_init(void) { |
| 1856 | if (g_state.numa.n_nodes > 0) { |
| 1857 | fprintf(stderr, "ggml_numa_init: NUMA already initialized\n"); |
| 1858 | |
| 1859 | return; |
| 1860 | } |
| 1861 | |
| 1862 | #ifdef __linux__ |
| 1863 | struct stat st; |
| 1864 | char path[256]; |
| 1865 | int rv; |
| 1866 | |
| 1867 | // enumerate nodes |
| 1868 | while (g_state.numa.n_nodes < GGML_NUMA_MAX_NODES) { |
| 1869 | rv = snprintf(path, sizeof(path), "/sys/devices/system/node/node%u", g_state.numa.n_nodes); |
| 1870 | GGML_ASSERT(rv > 0 && (unsigned)rv < sizeof(path)); |
| 1871 | if (stat(path, &st) != 0) { break; } |
| 1872 | ++g_state.numa.n_nodes; |
| 1873 | } |
| 1874 | |
| 1875 | // enumerate CPUs |
| 1876 | while (g_state.numa.total_cpus < GGML_NUMA_MAX_CPUS) { |
| 1877 | rv = snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%u", g_state.numa.total_cpus); |
| 1878 | GGML_ASSERT(rv > 0 && (unsigned)rv < sizeof(path)); |
| 1879 | if (stat(path, &st) != 0) { break; } |
| 1880 | ++g_state.numa.total_cpus; |
| 1881 | } |
| 1882 | |
| 1883 | GGML_PRINT_DEBUG("found %u numa nodes, %u CPUs\n", g_state.numa.n_nodes, g_state.numa.total_cpus); |
| 1884 | |
| 1885 | if (g_state.numa.n_nodes < 1 || g_state.numa.total_cpus < 1) { |
| 1886 | g_state.numa.n_nodes = 0; |
| 1887 | return; |
| 1888 | } |
| 1889 | |
| 1890 | for (uint32_t n = 0; n < g_state.numa.n_nodes; ++n) { |
| 1891 | struct ggml_numa_node * node = &g_state.numa.nodes[n]; |
| 1892 | GGML_PRINT_DEBUG("CPUs on node %u:", n); |
| 1893 | node->n_cpus = 0; |
| 1894 | for (uint32_t c = 0; c < g_state.numa.total_cpus; ++c) { |
| 1895 | rv = snprintf(path, sizeof(path), "/sys/devices/system/node/node%u/cpu%u", n, c); |
| 1896 | GGML_ASSERT(rv > 0 && (unsigned)rv < sizeof(path)); |
| 1897 | if (stat(path, &st) == 0) { |
| 1898 | node->cpus[node->n_cpus++] = c; |
| 1899 | GGML_PRINT_DEBUG(" %u", c); |
| 1900 | } |
| 1901 | } |
| 1902 | GGML_PRINT_DEBUG("\n"); |
| 1903 | } |
| 1904 | |
| 1905 | if (ggml_is_numa()) { |
| 1906 | FILE *fptr = fopen("/proc/sys/kernel/numa_balancing", "r"); |
| 1907 | if (fptr != NULL) { |
| 1908 | char buf[42]; |
| 1909 | if (fgets(buf, sizeof(buf), fptr) && strncmp(buf, "0\n", sizeof(buf)) != 0) { |
| 1910 | GGML_PRINT("WARNING: /proc/sys/kernel/numa_balancing is enabled, this has been observed to impair performance\n"); |
| 1911 | } |
| 1912 | fclose(fptr); |
no test coverage detected