char-fork/llama.cpp

git clone https://git.t4t.associates/char-fork/llama.cpp

Nick Farrellsycl: attribute device allocations by site (GGML_SYCL_MEMTRACE) (#27631)cd8cdf397

char/aliceai-t5-moe
5.3 KiB162 linesraw
1//
2// MIT license
3// Copyright (C) 2024 Intel Corporation
4// SPDX-License-Identifier: MIT
5//
6
7//
8// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9// See https://llvm.org/LICENSE.txt for license information.
10// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11//
12
13#include "common.hpp"
14#include <sycl/backend.hpp>
15#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
16#include <level_zero/ze_api.h>
17#endif
18
19#include "ggml-backend-impl.h"
20#include "ggml-impl.h"
21
22int get_current_device_id() {
23  return dpct::dev_mgr::instance().current_device_id();
24}
25
26void* ggml_sycl_host_malloc(size_t size) try {
27  if (getenv("GGML_SYCL_NO_PINNED") != nullptr) {
28    return nullptr;
29  }
30
31  void* ptr = nullptr;
32  // allow to use dpct::get_in_order_queue() for host malloc
33  dpct::err0 err = CHECK_TRY_ERROR(
34      ptr = (void*)sycl::malloc_host(size, dpct::get_in_order_queue()));
35
36  if (err != 0) {
37    // clear the error
38    GGML_LOG_ERROR("WARNING: failed to allocate %.2f MB of pinned memory: %s\n", size / 1024.0 / 1024.0,    "syclGetErrorString is not supported");
39    return nullptr;
40  }
41
42  return ptr;
43} catch (sycl::exception const& exc) {
44  std::cerr << exc.what() << "Exception caught at file:" << __FILE__
45            << ", line:" << __LINE__ << std::endl;
46  std::exit(1);
47}
48
49void ggml_sycl_host_free(void* ptr) try {
50  // allow to use dpct::get_in_order_queue() for host malloc
51  SYCL_CHECK(CHECK_TRY_ERROR(sycl::free(ptr, dpct::get_in_order_queue())));
52} catch (sycl::exception const& exc) {
53  std::cerr << exc.what() << "Exception caught at file:" << __FILE__
54            << ", line:" << __LINE__ << std::endl;
55  std::exit(1);
56}
57
58bool gpu_has_xmx(sycl::device &dev) {
59    return dev.has(sycl::aspect::ext_intel_matrix);
60}
61
62int ggml_sycl_get_env(const char *env_name, int default_val) {
63    char *user_device_string = getenv(env_name);
64    int user_number = default_val;
65
66    unsigned n;
67    if (user_device_string != NULL &&
68        sscanf(user_device_string, " %u", &n) == 1) {
69        user_number = (int)n;
70    } else {
71        user_number = default_val;
72    }
73    return user_number;
74}
75
76int64_t downsample_sycl_global_range(int64_t accumulate_block_num, int64_t block_size) {
77  const int64_t max_range = std::numeric_limits<int>::max();
78  int64_t sycl_down_blk_size = block_size;
79  int64_t global_range = accumulate_block_num * sycl_down_blk_size;
80  while(global_range > max_range) {
81      sycl_down_blk_size /= 2;
82      global_range = accumulate_block_num * sycl_down_blk_size;
83  }
84  return sycl_down_blk_size;
85}
86
87#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
88static bool ggml_sycl_use_level_zero_device_alloc(sycl::queue &q) {
89    return g_ggml_sycl_use_level_zero_api &&
90        q.get_device().is_gpu() &&
91        q.get_backend() == sycl::backend::ext_oneapi_level_zero;
92}
93#endif
94
95// Use Level Zero zeMemAllocDevice to avoid sycl::malloc_device triggering
96// DMA-buf/TTM system RAM staging in the xe kernel driver during multi-GPU inference.
97void * ggml_sycl_malloc_device(size_t size, sycl::queue &q, ggml_sycl_mem_type type) {
98#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
99    if (ggml_sycl_use_level_zero_device_alloc(q)) {
100        void *ptr = nullptr;
101        auto ze_ctx = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q.get_context());
102        auto ze_dev = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q.get_device());
103#ifdef ZE_RELAXED_ALLOCATION_LIMITS_EXP_NAME
104        ze_relaxed_allocation_limits_exp_desc_t relaxed_desc = {
105            ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC,
106            nullptr,
107            ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE,
108        };
109        ze_device_mem_alloc_desc_t alloc_desc = {
110            ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC,
111            &relaxed_desc,
112            0,
113            0,
114        };
115#else
116        ze_device_mem_alloc_desc_t alloc_desc = {ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC, nullptr, 0, 0};
117#endif
118        ze_result_t r = zeMemAllocDevice(ze_ctx, &alloc_desc, size, 64, ze_dev, &ptr);
119        if (r == ZE_RESULT_SUCCESS && ptr) {
120            ggml_sycl_memtrace_add(type, ptr, size);
121            return ptr;
122        }
123        ggml_sycl_memtrace_fail(type, size);
124        return nullptr;
125    }
126#endif
127    void * ptr = sycl::malloc_device(size, q);
128    if (ptr == nullptr) {
129        ggml_sycl_memtrace_fail(type, size);
130        return nullptr;
131    }
132    ggml_sycl_memtrace_add(type, ptr, size);
133    return ptr;
134}
135
136void ggml_sycl_free_device(void *ptr, sycl::queue &q) {
137    if (!ptr) return;
138    ggml_sycl_memtrace_del(ptr);
139#ifdef GGML_SYCL_SUPPORT_LEVEL_ZERO_API
140    if (ggml_sycl_use_level_zero_device_alloc(q)) {
141        auto ze_ctx = sycl::get_native<sycl::backend::ext_oneapi_level_zero>(q.get_context());
142        zeMemFree(ze_ctx, ptr);
143        return;
144    }
145#endif
146    SYCL_CHECK(CHECK_TRY_ERROR(sycl::free(ptr, q)));
147}
148
149void release_extra_gpu(ggml_tensor_extra_gpu * extra, std::vector<queue_ptr> streams) {
150    for (int i = 0; i < ggml_sycl_info().device_count; ++i) {
151        for (int64_t is = 0; is < GGML_SYCL_MAX_STREAMS; ++is) {
152            if (extra->events[i][is] != nullptr) {
153                SYCL_CHECK(CHECK_TRY_ERROR(dpct::destroy_event(extra->events[i][is])));
154            }
155        }
156        if (extra->data_device[i] != nullptr && streams.size()>0) {
157            ggml_sycl_set_device(i);
158            SYCL_CHECK(CHECK_TRY_ERROR(ggml_sycl_free_device(extra->data_device[i], *(streams[i]))));
159        }
160    }
161    delete extra;
162}