Repository: ggerganov/llama.cpp
File: ggml/src/ggml-cuda/ggml-cuda.cu (CUDA)

Code before:
        } else if (sscanf(line, "Hugepagesize: %ld kB", &value) == 1) {
            hugeTlbPageSize = value;
        }

        line = nextLine;
    }

    GGML_LOG_DEBUG("%s: hugeTlbTotalPages: %ld\n", __func__, hugeTlbTotalPages);
    GGML_LOG_DEBUG("%s: hugeTlbFreePages: %ld\n", __func__, hugeTlbFreePages);
    GGML_LOG_DEBUG("%s: hugeTlbPageSize: %ld\n", __func__, hugeTlbPageSize);
    GGML_LOG_DEBUG("%s: availableMemoryKb: %ld\n", __func__, *availableMemoryKb);
    GGML_LOG_DEBUG("%s: freeSwapKb: %ld\n", __func__, *freeSwapKb);

    if (hugeTlbTotalPages != 0 && hugeTlbTotalPages != -1) {
        *availableMemoryKb = hugeTlbFreePages * hugeTlbPageSize;

        // Hugetlbfs pages are not swappable.
        *freeSwapKb = 0;
    }

    GGML_LOG_DEBUG("%s: final availableMemoryKb: %ld\n", __func__, *availableMemoryKb);
    return true;
}
#endif // defined(__linux__)

static void ggml_backend_cuda_device_get_memory(ggml_backend_dev_t dev, size_t * free, size_t * total) {
    ggml_backend_cuda_device_context * ctx = (ggml_backend_cuda_device_context *)dev->context;
    ggml_cuda_set_device(ctx->device);
    CUDA_CHECK(cudaMemGetInfo(free, total));

#if defined(__linux__)
    // Check if this is a UMA (Unified Memory Architecture) system
    cudaDeviceProp prop;
    CUDA_CHECK(cudaGetDeviceProperties(&prop, ctx->device));

    GGML_LOG_DEBUG("%s: prop.name: %s\n", __func__, prop.name);
    GGML_LOG_DEBUG("%s: prop.unifiedAddressing: %d\n", __func__, prop.unifiedAddressing);

    // Check if UMA is explicitly enabled via environment variable
    const char * uma_env = getenv("GGML_CUDA_ENABLE_UNIFIED_MEMORY");

    bool is_uma = prop.unifiedAddressing > 0 || (uma_env != nullptr && uma_env[0] == '1');

    GGML_LOG_DEBUG("%s: is_uma: %d\n", __func__, is_uma);

    if (is_uma) {
        // For UMA systems (like DGX Spark), use system memory info
        long availableMemoryKb = 0;
        long freeSwapKb = 0;

        if (ggml_backend_cuda_get_available_uma_memory(&availableMemoryKb, &freeSwapKb) && availableMemoryKb > 0) {

Review comment (suggestion):
```suggestion

// ref: https://github.com/ggml-org/llama.cpp/pull/17368
#if defined(__linux__)
```

Code after:
        } else if (sscanf(line, "Hugepagesize: %ld kB", &value) == 1) {
            huge_tlb_page_size = value;
        }

        line = line_next;
    }

    if (huge_tlb_total_pages != 0 && huge_tlb_total_pages != -1) {
        *available_memory_kb = huge_tlb_free_pages * huge_tlb_page_size;

        // Hugetlbfs pages are not swappable.
        *free_swap_kb = 0;
    }

    GGML_LOG_DEBUG("%s: final available_memory_kb: %ld\n", __func__, *available_memory_kb);
    return true;
}
#endif // defined(__linux__)

static void ggml_backend_cuda_device_get_memory(ggml_backend_dev_t dev, size_t * free, size_t * total) {
    ggml_backend_cuda_device_context * ctx = (ggml_backend_cuda_device_context *)dev->context;
    ggml_cuda_set_device(ctx->device);
    CUDA_CHECK(cudaMemGetInfo(free, total));

// ref: https://github.com/ggml-org/llama.cpp/pull/17368
#if defined(__linux__)
    // Check if this is a UMA (Unified Memory Architecture) system
    cudaDeviceProp prop;
    CUDA_CHECK(cudaGetDeviceProperties(&prop, ctx->device));

    // Check if UMA is explicitly enabled via environment variable
    bool uma_env = getenv("GGML_CUDA_ENABLE_UNIFIED_MEMORY") != nullptr;
    bool is_uma = prop.unifiedAddressing > 0 || uma_env;

    if (is_uma) {
        // For UMA systems (like DGX Spark), use system memory info
        long available_memory_kb = 0;
        long free_swap_kb = 0;

        if (ggml_backend_cuda_get_available_uma_memory(&available_memory_kb, &free_swap_kb) && available_memory_kb > 0) {
            *free = (size_t)available_memory_kb * 1024;
        } else {
            GGML_LOG_ERROR("%s: /proc/meminfo reading failed, using cudaMemGetInfo\n", __func__);
        }
    }
#endif // defined(__linux__)

}

static enum ggml_backend_dev_type ggml_backend_cuda_device_get_type(ggml_backend_dev_t dev) {
    GGML_UNUSED(dev);