Skip to content

Commit 5b41cd7

Browse files
authored
Add capability for extra binaries to be built with rwkv.cpp (#87)
* Add capability for examples This also adds a quantizer that works without python. in the future, we might be able to convert from pytorch as well, without python. * example implied code style * rename examples to tools * rename cpuinfo.c to cpu_info.c * include ggml header again * Return EXIT_FAILURE on help * done with this * final name: extras * going To have a seizure * wait literal double n
1 parent fb6708b commit 5b41cd7

File tree

4 files changed

+76
-0
lines changed

4 files changed

+76
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,4 @@ endif()
286286

287287
enable_testing()
288288
add_subdirectory(tests)
289+
add_subdirectory(extras)

extras/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
function(rwkv_add_extra source)
2+
get_filename_component(EXTRA_TARGET ${source} NAME_WE)
3+
add_executable(rwkv_${EXTRA_TARGET} ${source})
4+
target_link_libraries(rwkv_${EXTRA_TARGET} PRIVATE ggml rwkv)
5+
endfunction()
6+
7+
file(GLOB extras *.c)
8+
foreach (extra ${extras})
9+
rwkv_add_extra(${extra})
10+
endforeach()

extras/cpu_info.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "rwkv.h"
2+
3+
#include <stdio.h>
4+
5+
int main() {
6+
printf("%s", rwkv_get_system_info_string());
7+
}

extras/quantize.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "ggml.h"
2+
#include "rwkv.h"
3+
4+
#include <stdlib.h>
5+
#include <stdio.h>
6+
#include <string.h>
7+
8+
enum ggml_type type_from_string(const char* string) {
9+
if (strcmp(string, "Q4_0") == 0) return GGML_TYPE_Q4_0;
10+
if (strcmp(string, "Q4_1") == 0) return GGML_TYPE_Q4_1;
11+
if (strcmp(string, "Q5_0") == 0) return GGML_TYPE_Q5_0;
12+
if (strcmp(string, "Q5_1") == 0) return GGML_TYPE_Q5_1;
13+
if (strcmp(string, "Q8_0") == 0) return GGML_TYPE_Q8_0;
14+
return GGML_TYPE_COUNT;
15+
}
16+
17+
#ifdef _WIN32
18+
bool QueryPerformanceFrequency(uint64_t* lpFrequency);
19+
bool QueryPerformanceCounter(uint64_t* lpPerformanceCount);
20+
21+
#define time_t uint64_t
22+
#define time_calibrate(freq) do { QueryPerformanceFrequency(&freq); freq /= 1000; } while (0)
23+
#define time_measure(x) QueryPerformanceCounter(&x)
24+
#define TIME_DIFF(freq, start, end) (double) ((end - start) / freq) / 1000.
25+
#else
26+
#include <time.h>
27+
28+
#define time_t struct timespec
29+
#define time_calibrate(freq) (void) freq
30+
#define time_measure(x) clock_gettime(CLOCK_MONOTONIC, &x)
31+
#define TIME_DIFF(freq, start, end) (double) ((end.tv_nsec - start.tv_nsec) / 1000000) / 1000
32+
#endif
33+
34+
int main(int argc, char* argv[]) {
35+
if (argc != 4 || type_from_string(argv[3]) == GGML_TYPE_COUNT) {
36+
fprintf(stderr, "Usage: %s INPUT OUTPUT FORMAT\n\nAvailable formats: Q4_0 Q4_1 Q5_0 Q5_1 Q8_0\n", argv[0]);
37+
return EXIT_FAILURE;
38+
}
39+
40+
time_t freq, start, end;
41+
time_calibrate(freq);
42+
43+
fprintf(stderr, "Quantizing ...\n");
44+
45+
time_measure(start);
46+
bool success = rwkv_quantize_model_file(argv[1], argv[2], argv[3]);
47+
time_measure(end);
48+
49+
double diff = TIME_DIFF(freq, start, end);
50+
51+
if (success) {
52+
fprintf(stderr, "Succeeded in %.3fs\n", diff);
53+
return EXIT_SUCCESS;
54+
} else {
55+
fprintf(stderr, "Error in %.3fs: 0x%.8X\n", diff, rwkv_get_last_error(NULL));
56+
return EXIT_FAILURE;
57+
}
58+
}

0 commit comments

Comments
 (0)