だいぶ解析進まれてますね。
タイトルに書かれている目的を達成するような回答ではありませんが、
以下の内容についての情報をお出しするため、シンタックスハイライトがされて見やすい回答欄を使わせてもらいます。
---------以下質問内容より抜粋------------------
cpp
1enum ggml_status ggml_backend_graph_compute_async(ggml_backend_t backend, struct ggml_cgraph * cgraph) {
2return backend->iface.graph_compute(backend, cgraph);
3}
上記にあるようなソースコードで息詰まってしまいました。
vscodeの機能で、graph_computeメソッドを探しても見つからない状況です。
---------以上質問内容より抜粋------------------
これはちょっと辿りづらいコードですね。
graph_compute
は以下にある通り、構造体の中に定義されている関数ポインタです。
https://github.com/ggerganov/llama.cpp/blob/master/ggml/src/ggml-backend-impl.h#L107-L108
cpp
1// compute graph (always async if supported by the backend)
2enum ggml_status (*graph_compute) (ggml_backend_t backend, struct ggml_cgraph * cgraph);
このため、graph_computeというそのものの関数の定義は存在せず、backend->iface.graph_compute(backend, cgraph)
ではgraph_compute
に代入されている関数が呼ばれていることになります。
では、このgraph_compute
はどこで設定されているかというと、ggml_backend_i
構造体を保持しているggml_backend_buffer
構造体の初期化で設定されています。
ggml_backend
の定義はこんな感じ。
https://github.com/ggerganov/llama.cpp/blob/master/ggml/src/ggml-backend-impl.h#L117-L122
cpp
1 struct ggml_backend {
2 ggml_guid_t guid;
3 struct ggml_backend_i iface;
4 ggml_backend_dev_t device;
5 void * context;
6 };
この初期化をしている部分を探してみると色々でてくるのですが例えば以下のようなcreate_backend()
で実施されていることが分かります。
https://github.com/ggerganov/llama.cpp/blob/master/examples/rpc/rpc-server.cpp#L72-L100
cpp
1static ggml_backend_t create_backend() {
2 ggml_backend_t backend = NULL;
3(各環境用のコードなので省略)
4 // if there aren't GPU Backends fallback to CPU backend
5 if (!backend) {
6 fprintf(stderr, "%s: using CPU backend\n", __func__);
7 backend = ggml_backend_cpu_init();
8 }
9 return backend;
10}
GPUを利用するための実装はいったん置いておいて、辿りやすいCPU用のggml_backend_cpu_init()
を確認してみます。
https://github.com/ggerganov/llama.cpp/blob/master/ggml/src/ggml-backend.cpp#L1034-L1060
cpp
1ggml_backend_t ggml_backend_cpu_init(void) {
2(今回の内容とは直接関係しないため省略)
3 ggml_backend_t cpu_backend = new ggml_backend {
4 /* .guid = */ ggml_backend_cpu_guid(),
5 /* .interface = */ ggml_backend_cpu_i,
6 /* .device = */ ggml_backend_reg_dev_get(ggml_backend_cpu_reg(), 0),
7 /* .context = */ ctx,
8 };
9
10 if (cpu_backend == NULL) {
11 delete ctx;
12 return NULL;
13 }
14
15 return cpu_backend;
16}
この.interface
に代入されているggml_backend_cpu_i
が目当てのデータです。
これはすぐ上に定義されています。
https://github.com/ggerganov/llama.cpp/blob/master/ggml/src/ggml-backend.cpp#L1013-L1027
cpp
1static const struct ggml_backend_i ggml_backend_cpu_i = {
2 /* .get_name = */ ggml_backend_cpu_get_name,
3 /* .free = */ ggml_backend_cpu_free,
4 /* .set_tensor_async = */ NULL,
5 /* .get_tensor_async = */ NULL,
6 /* .cpy_tensor_async = */ NULL,
7 /* .synchronize = */ NULL,
8 /* .graph_plan_create = */ ggml_backend_cpu_graph_plan_create,
9 /* .graph_plan_free = */ ggml_backend_cpu_graph_plan_free,
10 /* .graph_plan_update = */ NULL,
11 /* .graph_plan_compute = */ ggml_backend_cpu_graph_plan_compute,
12 /* .graph_compute = */ ggml_backend_cpu_graph_compute,
13 /* .event_record = */ NULL,
14 /* .event_wait = */ NULL,
15};
ということで、CPUがバックエンドの場合には.graph_compute
はggml_backend_cpu_graph_compute
が設定されていることが分かりました。
定義はこちらですね。
https://github.com/ggerganov/llama.cpp/blob/master/ggml/src/ggml-backend.cpp#L991-L1011
ここから先は今まで通り解析できると思いますがいかがでしょうか?
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/11/02 02:34