1
+ #if defined(_MSC_VER)
2
+ #define _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING
3
+ #endif
4
+
1
5
#include " ggml-cpu.h"
2
6
3
7
#ifdef GGML_USE_CUDA
18
22
19
23
#include " ggml-rpc.h"
20
24
#ifdef _WIN32
25
+ # define DIRECTORY_SEPARATOR ' \\ '
26
+ # include < locale>
21
27
# include < windows.h>
28
+ # include < fcntl.h>
29
+ # include < io.h>
22
30
#else
31
+ # define DIRECTORY_SEPARATOR ' /'
23
32
# include < unistd.h>
33
+ # include < sys/stat.h>
24
34
#endif
35
+ #include < codecvt>
25
36
#include < string>
26
37
#include < stdio.h>
38
+ #include < vector>
39
+ #include < filesystem>
40
+
41
+ namespace fs = std::filesystem;
42
+
43
+ // NOTE: this is copied from common.cpp to avoid linking with libcommon
44
+ // returns true if successful, false otherwise
45
+ static bool fs_create_directory_with_parents (const std::string & path) {
46
+ #ifdef _WIN32
47
+ std::wstring_convert<std::codecvt_utf8<wchar_t >> converter;
48
+ std::wstring wpath = converter.from_bytes (path);
49
+
50
+ // if the path already exists, check whether it's a directory
51
+ const DWORD attributes = GetFileAttributesW (wpath.c_str ());
52
+ if ((attributes != INVALID_FILE_ATTRIBUTES) && (attributes & FILE_ATTRIBUTE_DIRECTORY)) {
53
+ return true ;
54
+ }
55
+
56
+ size_t pos_slash = 0 ;
57
+
58
+ // process path from front to back, procedurally creating directories
59
+ while ((pos_slash = path.find (' \\ ' , pos_slash)) != std::string::npos) {
60
+ const std::wstring subpath = wpath.substr (0 , pos_slash);
61
+ const wchar_t * test = subpath.c_str ();
62
+
63
+ const bool success = CreateDirectoryW (test, NULL );
64
+ if (!success) {
65
+ const DWORD error = GetLastError ();
66
+
67
+ // if the path already exists, ensure that it's a directory
68
+ if (error == ERROR_ALREADY_EXISTS) {
69
+ const DWORD attributes = GetFileAttributesW (subpath.c_str ());
70
+ if (attributes == INVALID_FILE_ATTRIBUTES || !(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
71
+ return false ;
72
+ }
73
+ } else {
74
+ return false ;
75
+ }
76
+ }
77
+
78
+ pos_slash += 1 ;
79
+ }
80
+
81
+ return true ;
82
+ #else
83
+ // if the path already exists, check whether it's a directory
84
+ struct stat info;
85
+ if (stat (path.c_str (), &info) == 0 ) {
86
+ return S_ISDIR (info.st_mode );
87
+ }
88
+
89
+ size_t pos_slash = 1 ; // skip leading slashes for directory creation
90
+
91
+ // process path from front to back, procedurally creating directories
92
+ while ((pos_slash = path.find (' /' , pos_slash)) != std::string::npos) {
93
+ const std::string subpath = path.substr (0 , pos_slash);
94
+ struct stat info;
95
+
96
+ // if the path already exists, ensure that it's a directory
97
+ if (stat (subpath.c_str (), &info) == 0 ) {
98
+ if (!S_ISDIR (info.st_mode )) {
99
+ return false ;
100
+ }
101
+ } else {
102
+ // create parent directories
103
+ const int ret = mkdir (subpath.c_str (), 0755 );
104
+ if (ret != 0 ) {
105
+ return false ;
106
+ }
107
+ }
108
+
109
+ pos_slash += 1 ;
110
+ }
111
+
112
+ return true ;
113
+ #endif // _WIN32
114
+ }
115
+
116
+ // NOTE: this is copied from common.cpp to avoid linking with libcommon
117
+ static std::string fs_get_cache_directory () {
118
+ std::string cache_directory = " " ;
119
+ auto ensure_trailing_slash = [](std::string p) {
120
+ // Make sure to add trailing slash
121
+ if (p.back () != DIRECTORY_SEPARATOR) {
122
+ p += DIRECTORY_SEPARATOR;
123
+ }
124
+ return p;
125
+ };
126
+ if (getenv (" LLAMA_CACHE" )) {
127
+ cache_directory = std::getenv (" LLAMA_CACHE" );
128
+ } else {
129
+ #ifdef __linux__
130
+ if (std::getenv (" XDG_CACHE_HOME" )) {
131
+ cache_directory = std::getenv (" XDG_CACHE_HOME" );
132
+ } else {
133
+ cache_directory = std::getenv (" HOME" ) + std::string (" /.cache/" );
134
+ }
135
+ #elif defined(__APPLE__)
136
+ cache_directory = std::getenv (" HOME" ) + std::string (" /Library/Caches/" );
137
+ #elif defined(_WIN32)
138
+ cache_directory = std::getenv (" LOCALAPPDATA" );
139
+ #endif // __linux__
140
+ cache_directory = ensure_trailing_slash (cache_directory);
141
+ cache_directory += " llama.cpp" ;
142
+ }
143
+ return ensure_trailing_slash (cache_directory);
144
+ }
27
145
28
146
struct rpc_server_params {
29
147
std::string host = " 127.0.0.1" ;
30
148
int port = 50052 ;
31
149
size_t backend_mem = 0 ;
150
+ bool use_cache = false ;
32
151
};
33
152
34
153
static void print_usage (int /* argc*/ , char ** argv, rpc_server_params params) {
35
154
fprintf (stderr, " Usage: %s [options]\n\n " , argv[0 ]);
36
155
fprintf (stderr, " options:\n " );
37
- fprintf (stderr, " -h, --help show this help message and exit\n " );
38
- fprintf (stderr, " -H HOST, --host HOST host to bind to (default: %s)\n " , params.host .c_str ());
39
- fprintf (stderr, " -p PORT, --port PORT port to bind to (default: %d)\n " , params.port );
40
- fprintf (stderr, " -m MEM, --mem MEM backend memory size (in MB)\n " );
156
+ fprintf (stderr, " -h, --help show this help message and exit\n " );
157
+ fprintf (stderr, " -H HOST, --host HOST host to bind to (default: %s)\n " , params.host .c_str ());
158
+ fprintf (stderr, " -p PORT, --port PORT port to bind to (default: %d)\n " , params.port );
159
+ fprintf (stderr, " -m MEM, --mem MEM backend memory size (in MB)\n " );
160
+ fprintf (stderr, " -c, --cache enable local file cache\n " );
41
161
fprintf (stderr, " \n " );
42
162
}
43
163
@@ -58,6 +178,8 @@ static bool rpc_server_params_parse(int argc, char ** argv, rpc_server_params &
58
178
if (params.port <= 0 || params.port > 65535 ) {
59
179
return false ;
60
180
}
181
+ } else if (arg == " -c" || arg == " --cache" ) {
182
+ params.use_cache = true ;
61
183
} else if (arg == " -m" || arg == " --mem" ) {
62
184
if (++i >= argc) {
63
185
return false ;
@@ -164,8 +286,20 @@ int main(int argc, char * argv[]) {
164
286
} else {
165
287
get_backend_memory (&free_mem, &total_mem);
166
288
}
167
- printf (" Starting RPC server on %s, backend memory: %zu MB\n " , endpoint.c_str (), free_mem / (1024 * 1024 ));
168
- ggml_backend_rpc_start_server (backend, endpoint.c_str (), free_mem, total_mem);
289
+ const char * cache_dir = nullptr ;
290
+ std::string cache_dir_str = fs_get_cache_directory () + " rpc/" ;
291
+ if (params.use_cache ) {
292
+ if (!fs_create_directory_with_parents (cache_dir_str)) {
293
+ fprintf (stderr, " Failed to create cache directory: %s\n " , cache_dir_str.c_str ());
294
+ return 1 ;
295
+ }
296
+ cache_dir = cache_dir_str.c_str ();
297
+ }
298
+ printf (" Starting RPC server\n " );
299
+ printf (" endpoint : %s\n " , endpoint.c_str ());
300
+ printf (" local cache : %s\n " , cache_dir ? cache_dir : " n/a" );
301
+ printf (" backend memory : %zu MB\n " , free_mem / (1024 * 1024 ));
302
+ ggml_backend_rpc_start_server (backend, endpoint.c_str (), cache_dir, free_mem, total_mem);
169
303
ggml_backend_free (backend);
170
304
return 0 ;
171
305
}
0 commit comments