whispercpp 1.2.0.2 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/LICENSE +1 -1
- data/README.md +165 -434
- data/Rakefile +46 -86
- data/ext/.gitignore +13 -0
- data/ext/cpu.mk +9 -0
- data/ext/{dr_wav.h → examples/dr_wav.h} +3560 -1179
- data/ext/extconf.rb +185 -7
- data/ext/ggml/include/ggml-alloc.h +76 -0
- data/ext/ggml/include/ggml-backend.h +352 -0
- data/ext/ggml/include/ggml-blas.h +25 -0
- data/ext/ggml/include/ggml-cann.h +123 -0
- data/ext/ggml/include/ggml-cpp.h +38 -0
- data/ext/ggml/include/ggml-cpu.h +135 -0
- data/ext/ggml/include/ggml-cuda.h +47 -0
- data/ext/ggml/include/ggml-kompute.h +50 -0
- data/ext/ggml/include/ggml-metal.h +66 -0
- data/ext/ggml/include/ggml-opencl.h +26 -0
- data/ext/ggml/include/ggml-opt.h +216 -0
- data/ext/ggml/include/ggml-rpc.h +28 -0
- data/ext/ggml/include/ggml-sycl.h +49 -0
- data/ext/ggml/include/ggml-vulkan.h +31 -0
- data/ext/ggml/include/ggml.h +2285 -0
- data/ext/ggml/src/ggml-alloc.c +1037 -0
- data/ext/ggml/src/ggml-amx/common.h +94 -0
- data/ext/ggml/src/ggml-amx/ggml-amx.cpp +446 -0
- data/ext/ggml/src/ggml-amx/mmq.cpp +2510 -0
- data/ext/ggml/src/ggml-amx/mmq.h +17 -0
- data/ext/ggml/src/ggml-backend-impl.h +256 -0
- data/ext/ggml/src/ggml-backend-reg.cpp +552 -0
- data/ext/ggml/src/ggml-backend.cpp +1999 -0
- data/ext/ggml/src/ggml-blas/ggml-blas.cpp +517 -0
- data/ext/ggml/src/ggml-cann/acl_tensor.cpp +175 -0
- data/ext/ggml/src/ggml-cann/acl_tensor.h +258 -0
- data/ext/ggml/src/ggml-cann/aclnn_ops.cpp +3427 -0
- data/ext/ggml/src/ggml-cann/aclnn_ops.h +592 -0
- data/ext/ggml/src/ggml-cann/common.h +286 -0
- data/ext/ggml/src/ggml-cann/ggml-cann.cpp +2188 -0
- data/ext/ggml/src/ggml-cann/kernels/ascendc_kernels.h +19 -0
- data/ext/ggml/src/ggml-cann/kernels/dup.cpp +236 -0
- data/ext/ggml/src/ggml-cann/kernels/get_row_f16.cpp +197 -0
- data/ext/ggml/src/ggml-cann/kernels/get_row_f32.cpp +190 -0
- data/ext/ggml/src/ggml-cann/kernels/get_row_q4_0.cpp +204 -0
- data/ext/ggml/src/ggml-cann/kernels/get_row_q8_0.cpp +191 -0
- data/ext/ggml/src/ggml-cann/kernels/quantize_f16_q8_0.cpp +218 -0
- data/ext/ggml/src/ggml-cann/kernels/quantize_f32_q8_0.cpp +216 -0
- data/ext/ggml/src/ggml-cann/kernels/quantize_float_to_q4_0.cpp +295 -0
- data/ext/ggml/src/ggml-common.h +1853 -0
- data/ext/ggml/src/ggml-cpu/amx/amx.cpp +220 -0
- data/ext/ggml/src/ggml-cpu/amx/amx.h +8 -0
- data/ext/ggml/src/ggml-cpu/amx/common.h +91 -0
- data/ext/ggml/src/ggml-cpu/amx/mmq.cpp +2511 -0
- data/ext/ggml/src/ggml-cpu/amx/mmq.h +10 -0
- data/ext/ggml/src/ggml-cpu/cpu-feats-x86.cpp +323 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-aarch64.cpp +4262 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-aarch64.h +8 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-hbm.cpp +55 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-hbm.h +8 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-impl.h +386 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-quants.c +10835 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-quants.h +63 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-traits.cpp +36 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu-traits.h +38 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu.c +14123 -0
- data/ext/ggml/src/ggml-cpu/ggml-cpu.cpp +622 -0
- data/ext/ggml/src/ggml-cpu/llamafile/sgemm.cpp +1884 -0
- data/ext/ggml/src/ggml-cpu/llamafile/sgemm.h +14 -0
- data/ext/ggml/src/ggml-cuda/vendors/cuda.h +14 -0
- data/ext/ggml/src/ggml-cuda/vendors/hip.h +186 -0
- data/ext/ggml/src/ggml-cuda/vendors/musa.h +134 -0
- data/ext/ggml/src/ggml-impl.h +556 -0
- data/ext/ggml/src/ggml-kompute/ggml-kompute.cpp +2251 -0
- data/ext/ggml/src/ggml-metal/ggml-metal-impl.h +288 -0
- data/ext/ggml/src/ggml-metal/ggml-metal.m +4884 -0
- data/ext/ggml/src/ggml-metal/ggml-metal.metal +6732 -0
- data/ext/ggml/src/ggml-opt.cpp +854 -0
- data/ext/ggml/src/ggml-quants.c +5238 -0
- data/ext/ggml/src/ggml-quants.h +100 -0
- data/ext/ggml/src/ggml-rpc/ggml-rpc.cpp +1406 -0
- data/ext/ggml/src/ggml-sycl/common.cpp +95 -0
- data/ext/ggml/src/ggml-sycl/concat.cpp +196 -0
- data/ext/ggml/src/ggml-sycl/conv.cpp +99 -0
- data/ext/ggml/src/ggml-sycl/convert.cpp +547 -0
- data/ext/ggml/src/ggml-sycl/dmmv.cpp +1023 -0
- data/ext/ggml/src/ggml-sycl/element_wise.cpp +1030 -0
- data/ext/ggml/src/ggml-sycl/ggml-sycl.cpp +4729 -0
- data/ext/ggml/src/ggml-sycl/im2col.cpp +126 -0
- data/ext/ggml/src/ggml-sycl/mmq.cpp +3031 -0
- data/ext/ggml/src/ggml-sycl/mmvq.cpp +1015 -0
- data/ext/ggml/src/ggml-sycl/norm.cpp +378 -0
- data/ext/ggml/src/ggml-sycl/outprod.cpp +56 -0
- data/ext/ggml/src/ggml-sycl/rope.cpp +276 -0
- data/ext/ggml/src/ggml-sycl/softmax.cpp +251 -0
- data/ext/ggml/src/ggml-sycl/tsembd.cpp +72 -0
- data/ext/ggml/src/ggml-sycl/wkv6.cpp +141 -0
- data/ext/ggml/src/ggml-threading.cpp +12 -0
- data/ext/ggml/src/ggml-threading.h +14 -0
- data/ext/ggml/src/ggml-vulkan/ggml-vulkan.cpp +8657 -0
- data/ext/ggml/src/ggml-vulkan/vulkan-shaders/vulkan-shaders-gen.cpp +593 -0
- data/ext/ggml/src/ggml.c +7694 -0
- data/ext/include/whisper.h +672 -0
- data/ext/metal-embed.mk +17 -0
- data/ext/metal.mk +6 -0
- data/ext/ruby_whisper.cpp +1608 -159
- data/ext/ruby_whisper.h +10 -0
- data/ext/scripts/get-flags.mk +38 -0
- data/ext/src/coreml/whisper-decoder-impl.h +146 -0
- data/ext/src/coreml/whisper-decoder-impl.m +201 -0
- data/ext/src/coreml/whisper-encoder-impl.h +142 -0
- data/ext/src/coreml/whisper-encoder-impl.m +197 -0
- data/ext/src/coreml/whisper-encoder.h +26 -0
- data/ext/src/openvino/whisper-openvino-encoder.cpp +108 -0
- data/ext/src/openvino/whisper-openvino-encoder.h +31 -0
- data/ext/src/whisper.cpp +7393 -0
- data/extsources.rb +6 -0
- data/lib/whisper/model/uri.rb +157 -0
- data/lib/whisper.rb +2 -0
- data/tests/helper.rb +7 -0
- data/tests/jfk_reader/.gitignore +5 -0
- data/tests/jfk_reader/extconf.rb +3 -0
- data/tests/jfk_reader/jfk_reader.c +68 -0
- data/tests/test_callback.rb +160 -0
- data/tests/test_error.rb +20 -0
- data/tests/test_model.rb +71 -0
- data/tests/test_package.rb +31 -0
- data/tests/test_params.rb +160 -0
- data/tests/test_segment.rb +83 -0
- data/tests/test_whisper.rb +211 -123
- data/whispercpp.gemspec +36 -0
- metadata +137 -11
- data/ext/ggml.c +0 -8616
- data/ext/ggml.h +0 -748
- data/ext/whisper.cpp +0 -4829
- data/ext/whisper.h +0 -402
@@ -0,0 +1,556 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
// GGML internal header
|
4
|
+
|
5
|
+
#include "ggml.h"
|
6
|
+
#include <assert.h>
|
7
|
+
#include <math.h>
|
8
|
+
#include <stdlib.h> // load `stdlib.h` before other headers to work around MinGW bug: https://sourceforge.net/p/mingw-w64/bugs/192/
|
9
|
+
#include <stdbool.h>
|
10
|
+
#include <stdint.h>
|
11
|
+
#include <string.h>
|
12
|
+
|
13
|
+
#ifdef __ARM_FEATURE_SVE
|
14
|
+
#include <arm_sve.h>
|
15
|
+
#endif // __ARM_FEATURE_SVE
|
16
|
+
|
17
|
+
#if defined(__ARM_NEON) && !defined(__CUDACC__)
|
18
|
+
// if YCM cannot find <arm_neon.h>, make a symbolic link to it, for example:
|
19
|
+
//
|
20
|
+
// $ ln -sfn /Library/Developer/CommandLineTools/usr/lib/clang/13.1.6/include/arm_neon.h ./src/
|
21
|
+
//
|
22
|
+
#include <arm_neon.h>
|
23
|
+
#endif
|
24
|
+
|
25
|
+
#if defined(__F16C__)
|
26
|
+
#include <immintrin.h>
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#ifdef __cplusplus
|
30
|
+
extern "C" {
|
31
|
+
#endif
|
32
|
+
|
33
|
+
#ifndef MIN
|
34
|
+
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
35
|
+
#endif
|
36
|
+
|
37
|
+
#ifndef MAX
|
38
|
+
# define MAX(a, b) ((a) > (b) ? (a) : (b))
|
39
|
+
#endif
|
40
|
+
|
41
|
+
// required for mmap as gguf only guarantees 32-byte alignment
|
42
|
+
#define TENSOR_ALIGNMENT 32
|
43
|
+
|
44
|
+
// static_assert should be a #define, but if it's not,
|
45
|
+
// fall back to the _Static_assert C11 keyword.
|
46
|
+
// if C99 - static_assert is noop
|
47
|
+
// ref: https://stackoverflow.com/a/53923785/4039976
|
48
|
+
#ifndef __cplusplus
|
49
|
+
#ifndef static_assert
|
50
|
+
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201100L)
|
51
|
+
#define static_assert(cond, msg) _Static_assert(cond, msg)
|
52
|
+
#else
|
53
|
+
#define static_assert(cond, msg) struct global_scope_noop_trick
|
54
|
+
#endif
|
55
|
+
#endif
|
56
|
+
#endif
|
57
|
+
|
58
|
+
static inline int ggml_up32(int n) {
|
59
|
+
return (n + 31) & ~31;
|
60
|
+
}
|
61
|
+
|
62
|
+
//static inline int ggml_up64(int n) {
|
63
|
+
// return (n + 63) & ~63;
|
64
|
+
//}
|
65
|
+
|
66
|
+
static inline int ggml_up(int n, int m) {
|
67
|
+
// assert m is a power of 2
|
68
|
+
GGML_ASSERT((m & (m - 1)) == 0);
|
69
|
+
return (n + m - 1) & ~(m - 1);
|
70
|
+
}
|
71
|
+
|
72
|
+
//
|
73
|
+
// logging
|
74
|
+
//
|
75
|
+
|
76
|
+
GGML_ATTRIBUTE_FORMAT(2, 3)
|
77
|
+
GGML_API void ggml_log_internal (enum ggml_log_level level, const char * format, ...);
|
78
|
+
GGML_API void ggml_log_callback_default(enum ggml_log_level level, const char * text, void * user_data);
|
79
|
+
|
80
|
+
#define GGML_LOG(...) ggml_log_internal(GGML_LOG_LEVEL_NONE , __VA_ARGS__)
|
81
|
+
#define GGML_LOG_INFO(...) ggml_log_internal(GGML_LOG_LEVEL_INFO , __VA_ARGS__)
|
82
|
+
#define GGML_LOG_WARN(...) ggml_log_internal(GGML_LOG_LEVEL_WARN , __VA_ARGS__)
|
83
|
+
#define GGML_LOG_ERROR(...) ggml_log_internal(GGML_LOG_LEVEL_ERROR, __VA_ARGS__)
|
84
|
+
#define GGML_LOG_DEBUG(...) ggml_log_internal(GGML_LOG_LEVEL_DEBUG, __VA_ARGS__)
|
85
|
+
#define GGML_LOG_CONT(...) ggml_log_internal(GGML_LOG_LEVEL_CONT , __VA_ARGS__)
|
86
|
+
|
87
|
+
#define GGML_DEBUG 0
|
88
|
+
|
89
|
+
#if (GGML_DEBUG >= 1)
|
90
|
+
#define GGML_PRINT_DEBUG(...) GGML_LOG_DEBUG(__VA_ARGS__)
|
91
|
+
#else
|
92
|
+
#define GGML_PRINT_DEBUG(...)
|
93
|
+
#endif
|
94
|
+
|
95
|
+
#if (GGML_DEBUG >= 5)
|
96
|
+
#define GGML_PRINT_DEBUG_5(...) GGML_LOG_DEBUG(__VA_ARGS__)
|
97
|
+
#else
|
98
|
+
#define GGML_PRINT_DEBUG_5(...)
|
99
|
+
#endif
|
100
|
+
|
101
|
+
#if (GGML_DEBUG >= 10)
|
102
|
+
#define GGML_PRINT_DEBUG_10(...) GGML_LOG_DEBUG(__VA_ARGS__)
|
103
|
+
#else
|
104
|
+
#define GGML_PRINT_DEBUG_10(...)
|
105
|
+
#endif
|
106
|
+
|
107
|
+
// tensor params
|
108
|
+
|
109
|
+
static void ggml_set_op_params(struct ggml_tensor * tensor, const void * params, size_t params_size) {
|
110
|
+
GGML_ASSERT(tensor != NULL); // silence -Warray-bounds warnings
|
111
|
+
assert(params_size <= GGML_MAX_OP_PARAMS);
|
112
|
+
memcpy(tensor->op_params, params, params_size);
|
113
|
+
}
|
114
|
+
|
115
|
+
static int32_t ggml_get_op_params_i32(const struct ggml_tensor * tensor, uint32_t i) {
|
116
|
+
assert(i < GGML_MAX_OP_PARAMS / sizeof(int32_t));
|
117
|
+
return ((const int32_t *)(tensor->op_params))[i];
|
118
|
+
}
|
119
|
+
|
120
|
+
static float ggml_get_op_params_f32(const struct ggml_tensor * tensor, uint32_t i) {
|
121
|
+
assert(i < GGML_MAX_OP_PARAMS / sizeof(float));
|
122
|
+
return ((const float *)(tensor->op_params))[i];
|
123
|
+
}
|
124
|
+
|
125
|
+
static void ggml_set_op_params_i32(struct ggml_tensor * tensor, uint32_t i, int32_t value) {
|
126
|
+
assert(i < GGML_MAX_OP_PARAMS / sizeof(int32_t));
|
127
|
+
((int32_t *)(tensor->op_params))[i] = value;
|
128
|
+
}
|
129
|
+
|
130
|
+
static void ggml_set_op_params_f32(struct ggml_tensor * tensor, uint32_t i, float value) {
|
131
|
+
assert(i < GGML_MAX_OP_PARAMS / sizeof(float));
|
132
|
+
((float *)(tensor->op_params))[i] = value;
|
133
|
+
}
|
134
|
+
|
135
|
+
struct ggml_map_custom1_op_params {
|
136
|
+
ggml_custom1_op_t fun;
|
137
|
+
int n_tasks;
|
138
|
+
void * userdata;
|
139
|
+
};
|
140
|
+
|
141
|
+
struct ggml_map_custom2_op_params {
|
142
|
+
ggml_custom2_op_t fun;
|
143
|
+
int n_tasks;
|
144
|
+
void * userdata;
|
145
|
+
};
|
146
|
+
|
147
|
+
struct ggml_map_custom3_op_params {
|
148
|
+
ggml_custom3_op_t fun;
|
149
|
+
int n_tasks;
|
150
|
+
void * userdata;
|
151
|
+
};
|
152
|
+
|
153
|
+
// bitset
|
154
|
+
|
155
|
+
typedef uint32_t ggml_bitset_t;
|
156
|
+
|
157
|
+
static_assert(sizeof(ggml_bitset_t) == 4, "bitset_t constants must be updated");
|
158
|
+
#define BITSET_SHR 5 // log2(sizeof(ggml_bitset_t)*8)
|
159
|
+
#define BITSET_MASK (sizeof(ggml_bitset_t)*8 - 1)
|
160
|
+
|
161
|
+
static size_t ggml_bitset_size(size_t n) {
|
162
|
+
return (n + BITSET_MASK) >> BITSET_SHR;
|
163
|
+
}
|
164
|
+
|
165
|
+
static inline bool ggml_bitset_get(const ggml_bitset_t * bitset, size_t i) {
|
166
|
+
return !!(bitset[i >> BITSET_SHR] & (1u << (i & BITSET_MASK)));
|
167
|
+
}
|
168
|
+
|
169
|
+
static inline void ggml_bitset_set(ggml_bitset_t * bitset, size_t i) {
|
170
|
+
bitset[i >> BITSET_SHR] |= (1u << (i & BITSET_MASK));
|
171
|
+
}
|
172
|
+
|
173
|
+
static inline void ggml_bitset_clear(ggml_bitset_t * bitset, size_t i) {
|
174
|
+
bitset[i >> BITSET_SHR] &= ~(1u << (i & BITSET_MASK));
|
175
|
+
}
|
176
|
+
|
177
|
+
// hash set
|
178
|
+
|
179
|
+
#define GGML_HASHSET_FULL ((size_t)-1)
|
180
|
+
#define GGML_HASHSET_ALREADY_EXISTS ((size_t)-2)
|
181
|
+
|
182
|
+
struct ggml_hash_set {
|
183
|
+
size_t size;
|
184
|
+
ggml_bitset_t * used; // whether or not the keys are in use i.e. set
|
185
|
+
struct ggml_tensor ** keys; // actual tensors in the set, keys[i] is only defined if ggml_bitset_get(used, i)
|
186
|
+
};
|
187
|
+
|
188
|
+
struct ggml_hash_set ggml_hash_set_new(size_t size);
|
189
|
+
void ggml_hash_set_free(struct ggml_hash_set * hash_set);
|
190
|
+
|
191
|
+
// returns the minimum size for a hash set that can hold min_sz elements
|
192
|
+
size_t ggml_hash_size(size_t min_sz);
|
193
|
+
|
194
|
+
// remove all elements from the hash set
|
195
|
+
void ggml_hash_set_reset(struct ggml_hash_set * hash_set);
|
196
|
+
|
197
|
+
// returns true if key is in the hash set
|
198
|
+
static bool ggml_hash_contains(const struct ggml_hash_set * hash_set, struct ggml_tensor * key);
|
199
|
+
|
200
|
+
// returns GGML_HASHSET_FULL if table is full, otherwise the current index of the key or where it should be inserted
|
201
|
+
static size_t ggml_hash_find(const struct ggml_hash_set * hash_set, const struct ggml_tensor * key);
|
202
|
+
|
203
|
+
// returns GGML_HASHSET_ALREADY_EXISTS if key already exists, index otherwise, asserts if table is full
|
204
|
+
static size_t ggml_hash_insert(struct ggml_hash_set * hash_set, struct ggml_tensor * key);
|
205
|
+
|
206
|
+
// return index, asserts if table is full
|
207
|
+
static size_t ggml_hash_find_or_insert(struct ggml_hash_set * hash_set, struct ggml_tensor * key);
|
208
|
+
|
209
|
+
// hash function for ggml_tensor
|
210
|
+
static inline size_t ggml_hash(const struct ggml_tensor * p) {
|
211
|
+
// the last 4 bits are always zero due to alignment
|
212
|
+
return (size_t)(uintptr_t)p >> 4;
|
213
|
+
}
|
214
|
+
|
215
|
+
static size_t ggml_hash_find(const struct ggml_hash_set * hash_set, const struct ggml_tensor * key) {
|
216
|
+
size_t h = ggml_hash(key) % hash_set->size;
|
217
|
+
|
218
|
+
// linear probing
|
219
|
+
size_t i = h;
|
220
|
+
while (ggml_bitset_get(hash_set->used, i) && hash_set->keys[i] != key) {
|
221
|
+
i = (i + 1) % hash_set->size;
|
222
|
+
if (i == h) {
|
223
|
+
// visited all hash table entries -> not found
|
224
|
+
return GGML_HASHSET_FULL;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
return i;
|
228
|
+
}
|
229
|
+
|
230
|
+
static bool ggml_hash_contains(const struct ggml_hash_set * hash_set, struct ggml_tensor * key) {
|
231
|
+
size_t i = ggml_hash_find(hash_set, key);
|
232
|
+
return i != GGML_HASHSET_FULL && ggml_bitset_get(hash_set->used, i);
|
233
|
+
}
|
234
|
+
|
235
|
+
static size_t ggml_hash_insert(struct ggml_hash_set * hash_set, struct ggml_tensor * key) {
|
236
|
+
size_t h = ggml_hash(key) % hash_set->size;
|
237
|
+
|
238
|
+
// linear probing
|
239
|
+
size_t i = h;
|
240
|
+
do {
|
241
|
+
if (!ggml_bitset_get(hash_set->used, i)) {
|
242
|
+
ggml_bitset_set(hash_set->used, i);
|
243
|
+
hash_set->keys[i] = key;
|
244
|
+
return i;
|
245
|
+
}
|
246
|
+
if (hash_set->keys[i] == key) {
|
247
|
+
return GGML_HASHSET_ALREADY_EXISTS;
|
248
|
+
}
|
249
|
+
i = (i + 1) % hash_set->size;
|
250
|
+
} while (i != h);
|
251
|
+
|
252
|
+
// visited all hash table entries -> not found
|
253
|
+
GGML_ABORT("fatal error");
|
254
|
+
}
|
255
|
+
|
256
|
+
static size_t ggml_hash_find_or_insert(struct ggml_hash_set * hash_set, struct ggml_tensor * key) {
|
257
|
+
size_t h = ggml_hash(key) % hash_set->size;
|
258
|
+
|
259
|
+
// linear probing
|
260
|
+
size_t i = h;
|
261
|
+
do {
|
262
|
+
if (!ggml_bitset_get(hash_set->used, i)) {
|
263
|
+
ggml_bitset_set(hash_set->used, i);
|
264
|
+
hash_set->keys[i] = key;
|
265
|
+
return i;
|
266
|
+
}
|
267
|
+
if (hash_set->keys[i] == key) {
|
268
|
+
return i;
|
269
|
+
}
|
270
|
+
i = (i + 1) % hash_set->size;
|
271
|
+
} while (i != h);
|
272
|
+
|
273
|
+
// visited all hash table entries -> not found
|
274
|
+
GGML_ABORT("fatal error");
|
275
|
+
}
|
276
|
+
|
277
|
+
// computation graph
|
278
|
+
|
279
|
+
enum ggml_cgraph_eval_order {
|
280
|
+
GGML_CGRAPH_EVAL_ORDER_LEFT_TO_RIGHT = 0,
|
281
|
+
GGML_CGRAPH_EVAL_ORDER_RIGHT_TO_LEFT,
|
282
|
+
GGML_CGRAPH_EVAL_ORDER_COUNT
|
283
|
+
};
|
284
|
+
|
285
|
+
struct ggml_cgraph {
|
286
|
+
int size; // maximum number of nodes/leafs/grads/grad_accs
|
287
|
+
int n_nodes; // number of nodes currently in use
|
288
|
+
int n_leafs; // number of leafs currently in use
|
289
|
+
|
290
|
+
struct ggml_tensor ** nodes; // tensors with data that can change if the graph is evaluated
|
291
|
+
struct ggml_tensor ** grads; // the outputs of these tensors are the gradients of the nodes
|
292
|
+
struct ggml_tensor ** grad_accs; // accumulators for node gradients
|
293
|
+
struct ggml_tensor ** leafs; // tensors with constant data
|
294
|
+
|
295
|
+
struct ggml_hash_set visited_hash_set;
|
296
|
+
|
297
|
+
enum ggml_cgraph_eval_order order;
|
298
|
+
};
|
299
|
+
|
300
|
+
// returns a slice of cgraph with nodes [i0, i1)
|
301
|
+
// the slice does not have leafs or gradients
|
302
|
+
// if you need the gradients, get them from the original graph
|
303
|
+
struct ggml_cgraph ggml_graph_view(struct ggml_cgraph * cgraph, int i0, int i1);
|
304
|
+
|
305
|
+
// Memory allocation
|
306
|
+
|
307
|
+
GGML_API void * ggml_aligned_malloc(size_t size);
|
308
|
+
GGML_API void ggml_aligned_free(void * ptr, size_t size);
|
309
|
+
|
310
|
+
// FP16 to FP32 conversion
|
311
|
+
|
312
|
+
#if defined(__ARM_NEON)
|
313
|
+
#if defined(_MSC_VER) || (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ <= 11)
|
314
|
+
typedef uint16_t ggml_fp16_internal_t;
|
315
|
+
#else
|
316
|
+
typedef __fp16 ggml_fp16_internal_t;
|
317
|
+
#endif
|
318
|
+
#endif
|
319
|
+
|
320
|
+
#if defined(__ARM_NEON) && !defined(_MSC_VER) && !(defined(__CUDACC__) && __CUDACC_VER_MAJOR__ <= 11)
|
321
|
+
#define GGML_COMPUTE_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x)
|
322
|
+
#define GGML_COMPUTE_FP32_TO_FP16(x) ggml_compute_fp32_to_fp16(x)
|
323
|
+
|
324
|
+
#define GGML_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x)
|
325
|
+
|
326
|
+
static inline float ggml_compute_fp16_to_fp32(ggml_fp16_t h) {
|
327
|
+
ggml_fp16_internal_t tmp;
|
328
|
+
memcpy(&tmp, &h, sizeof(ggml_fp16_t));
|
329
|
+
return (float)tmp;
|
330
|
+
}
|
331
|
+
|
332
|
+
static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) {
|
333
|
+
ggml_fp16_t res;
|
334
|
+
ggml_fp16_internal_t tmp = f;
|
335
|
+
memcpy(&res, &tmp, sizeof(ggml_fp16_t));
|
336
|
+
return res;
|
337
|
+
}
|
338
|
+
|
339
|
+
#elif defined(__F16C__)
|
340
|
+
|
341
|
+
#ifdef _MSC_VER
|
342
|
+
#define GGML_COMPUTE_FP16_TO_FP32(x) _mm_cvtss_f32(_mm_cvtph_ps(_mm_cvtsi32_si128(x)))
|
343
|
+
#define GGML_COMPUTE_FP32_TO_FP16(x) _mm_extract_epi16(_mm_cvtps_ph(_mm_set_ss(x), 0), 0)
|
344
|
+
#else
|
345
|
+
#define GGML_COMPUTE_FP16_TO_FP32(x) _cvtsh_ss(x)
|
346
|
+
#define GGML_COMPUTE_FP32_TO_FP16(x) _cvtss_sh(x, 0)
|
347
|
+
#endif
|
348
|
+
|
349
|
+
#elif defined(__POWER9_VECTOR__)
|
350
|
+
|
351
|
+
#define GGML_COMPUTE_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x)
|
352
|
+
#define GGML_COMPUTE_FP32_TO_FP16(x) ggml_compute_fp32_to_fp16(x)
|
353
|
+
/* the inline asm below is about 12% faster than the lookup method */
|
354
|
+
#define GGML_FP16_TO_FP32(x) GGML_COMPUTE_FP16_TO_FP32(x)
|
355
|
+
#define GGML_FP32_TO_FP16(x) GGML_COMPUTE_FP32_TO_FP16(x)
|
356
|
+
|
357
|
+
static inline float ggml_compute_fp16_to_fp32(ggml_fp16_t h) {
|
358
|
+
register float f;
|
359
|
+
register double d;
|
360
|
+
__asm__(
|
361
|
+
"mtfprd %0,%2\n"
|
362
|
+
"xscvhpdp %0,%0\n"
|
363
|
+
"frsp %1,%0\n" :
|
364
|
+
/* temp */ "=d"(d),
|
365
|
+
/* out */ "=f"(f):
|
366
|
+
/* in */ "r"(h));
|
367
|
+
return f;
|
368
|
+
}
|
369
|
+
|
370
|
+
static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) {
|
371
|
+
register double d;
|
372
|
+
register ggml_fp16_t r;
|
373
|
+
__asm__( /* xscvdphp can work on double or single precision */
|
374
|
+
"xscvdphp %0,%2\n"
|
375
|
+
"mffprd %1,%0\n" :
|
376
|
+
/* temp */ "=d"(d),
|
377
|
+
/* out */ "=r"(r):
|
378
|
+
/* in */ "f"(f));
|
379
|
+
return r;
|
380
|
+
}
|
381
|
+
|
382
|
+
#else
|
383
|
+
|
384
|
+
// FP16 <-> FP32
|
385
|
+
// ref: https://github.com/Maratyszcza/FP16
|
386
|
+
|
387
|
+
static inline float fp32_from_bits(uint32_t w) {
|
388
|
+
union {
|
389
|
+
uint32_t as_bits;
|
390
|
+
float as_value;
|
391
|
+
} fp32;
|
392
|
+
fp32.as_bits = w;
|
393
|
+
return fp32.as_value;
|
394
|
+
}
|
395
|
+
|
396
|
+
static inline uint32_t fp32_to_bits(float f) {
|
397
|
+
union {
|
398
|
+
float as_value;
|
399
|
+
uint32_t as_bits;
|
400
|
+
} fp32;
|
401
|
+
fp32.as_value = f;
|
402
|
+
return fp32.as_bits;
|
403
|
+
}
|
404
|
+
|
405
|
+
static inline float ggml_compute_fp16_to_fp32(ggml_fp16_t h) {
|
406
|
+
const uint32_t w = (uint32_t) h << 16;
|
407
|
+
const uint32_t sign = w & UINT32_C(0x80000000);
|
408
|
+
const uint32_t two_w = w + w;
|
409
|
+
|
410
|
+
const uint32_t exp_offset = UINT32_C(0xE0) << 23;
|
411
|
+
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__)) && (!defined(__cplusplus) || __cplusplus >= 201703L)
|
412
|
+
const float exp_scale = 0x1.0p-112f;
|
413
|
+
#else
|
414
|
+
const float exp_scale = fp32_from_bits(UINT32_C(0x7800000));
|
415
|
+
#endif
|
416
|
+
const float normalized_value = fp32_from_bits((two_w >> 4) + exp_offset) * exp_scale;
|
417
|
+
|
418
|
+
const uint32_t magic_mask = UINT32_C(126) << 23;
|
419
|
+
const float magic_bias = 0.5f;
|
420
|
+
const float denormalized_value = fp32_from_bits((two_w >> 17) | magic_mask) - magic_bias;
|
421
|
+
|
422
|
+
const uint32_t denormalized_cutoff = UINT32_C(1) << 27;
|
423
|
+
const uint32_t result = sign |
|
424
|
+
(two_w < denormalized_cutoff ? fp32_to_bits(denormalized_value) : fp32_to_bits(normalized_value));
|
425
|
+
return fp32_from_bits(result);
|
426
|
+
}
|
427
|
+
|
428
|
+
static inline ggml_fp16_t ggml_compute_fp32_to_fp16(float f) {
|
429
|
+
#if (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) || defined(__GNUC__) && !defined(__STRICT_ANSI__)) && (!defined(__cplusplus) || __cplusplus >= 201703L)
|
430
|
+
const float scale_to_inf = 0x1.0p+112f;
|
431
|
+
const float scale_to_zero = 0x1.0p-110f;
|
432
|
+
#else
|
433
|
+
const float scale_to_inf = fp32_from_bits(UINT32_C(0x77800000));
|
434
|
+
const float scale_to_zero = fp32_from_bits(UINT32_C(0x08800000));
|
435
|
+
#endif
|
436
|
+
float base = (fabsf(f) * scale_to_inf) * scale_to_zero;
|
437
|
+
|
438
|
+
const uint32_t w = fp32_to_bits(f);
|
439
|
+
const uint32_t shl1_w = w + w;
|
440
|
+
const uint32_t sign = w & UINT32_C(0x80000000);
|
441
|
+
uint32_t bias = shl1_w & UINT32_C(0xFF000000);
|
442
|
+
if (bias < UINT32_C(0x71000000)) {
|
443
|
+
bias = UINT32_C(0x71000000);
|
444
|
+
}
|
445
|
+
|
446
|
+
base = fp32_from_bits((bias >> 1) + UINT32_C(0x07800000)) + base;
|
447
|
+
const uint32_t bits = fp32_to_bits(base);
|
448
|
+
const uint32_t exp_bits = (bits >> 13) & UINT32_C(0x00007C00);
|
449
|
+
const uint32_t mantissa_bits = bits & UINT32_C(0x00000FFF);
|
450
|
+
const uint32_t nonsign = exp_bits + mantissa_bits;
|
451
|
+
return (sign >> 16) | (shl1_w > UINT32_C(0xFF000000) ? UINT16_C(0x7E00) : nonsign);
|
452
|
+
}
|
453
|
+
|
454
|
+
#define GGML_COMPUTE_FP16_TO_FP32(x) ggml_compute_fp16_to_fp32(x)
|
455
|
+
#define GGML_COMPUTE_FP32_TO_FP16(x) ggml_compute_fp32_to_fp16(x)
|
456
|
+
|
457
|
+
#endif // defined(__ARM_NEON) && (!defined(__MSC_VER)
|
458
|
+
|
459
|
+
// precomputed f32 table for f16 (256 KB)
|
460
|
+
// defined in ggml.c, initialized in ggml_init()
|
461
|
+
GGML_API float ggml_table_f32_f16[1 << 16];
|
462
|
+
|
463
|
+
// On ARM NEON, it's quicker to directly convert x -> x instead of calling into ggml_lookup_fp16_to_fp32,
|
464
|
+
// so we define GGML_FP16_TO_FP32 and GGML_FP32_TO_FP16 elsewhere for NEON.
|
465
|
+
// This is also true for POWER9.
|
466
|
+
#if !defined(GGML_FP16_TO_FP32)
|
467
|
+
inline static float ggml_lookup_fp16_to_fp32(ggml_fp16_t f) {
|
468
|
+
uint16_t s;
|
469
|
+
memcpy(&s, &f, sizeof(uint16_t));
|
470
|
+
return ggml_table_f32_f16[s];
|
471
|
+
}
|
472
|
+
|
473
|
+
#define GGML_FP16_TO_FP32(x) ggml_lookup_fp16_to_fp32(x)
|
474
|
+
#endif
|
475
|
+
|
476
|
+
#if !defined(GGML_FP32_TO_FP16)
|
477
|
+
#define GGML_FP32_TO_FP16(x) GGML_COMPUTE_FP32_TO_FP16(x)
|
478
|
+
#endif
|
479
|
+
|
480
|
+
/**
|
481
|
+
* Converts brain16 to float32.
|
482
|
+
*
|
483
|
+
* The bfloat16 floating point format has the following structure:
|
484
|
+
*
|
485
|
+
* ┌sign
|
486
|
+
* │
|
487
|
+
* │ ┌exponent
|
488
|
+
* │ │
|
489
|
+
* │ │ ┌mantissa
|
490
|
+
* │ │ │
|
491
|
+
* │┌──┴───┐┌─┴───┐
|
492
|
+
* 0b0000000000000000 brain16
|
493
|
+
*
|
494
|
+
* Since bf16 has the same number of exponent bits as a 32bit float,
|
495
|
+
* encoding and decoding numbers becomes relatively straightforward.
|
496
|
+
*
|
497
|
+
* ┌sign
|
498
|
+
* │
|
499
|
+
* │ ┌exponent
|
500
|
+
* │ │
|
501
|
+
* │ │ ┌mantissa
|
502
|
+
* │ │ │
|
503
|
+
* │┌──┴───┐┌─┴───────────────────┐
|
504
|
+
* 0b00000000000000000000000000000000 IEEE binary32
|
505
|
+
*
|
506
|
+
* For comparison, the standard fp16 format has fewer exponent bits.
|
507
|
+
*
|
508
|
+
* ┌sign
|
509
|
+
* │
|
510
|
+
* │ ┌exponent
|
511
|
+
* │ │
|
512
|
+
* │ │ ┌mantissa
|
513
|
+
* │ │ │
|
514
|
+
* │┌─┴─┐┌─┴──────┐
|
515
|
+
* 0b0000000000000000 IEEE binary16
|
516
|
+
*
|
517
|
+
* @see IEEE 754-2008
|
518
|
+
*/
|
519
|
+
static inline float ggml_compute_bf16_to_fp32(ggml_bf16_t h) {
|
520
|
+
union {
|
521
|
+
float f;
|
522
|
+
uint32_t i;
|
523
|
+
} u;
|
524
|
+
u.i = (uint32_t)h.bits << 16;
|
525
|
+
return u.f;
|
526
|
+
}
|
527
|
+
|
528
|
+
/**
|
529
|
+
* Converts float32 to brain16.
|
530
|
+
*
|
531
|
+
* This is binary identical with Google Brain float conversion.
|
532
|
+
* Floats shall round to nearest even, and NANs shall be quiet.
|
533
|
+
* Subnormals aren't flushed to zero, except perhaps when used.
|
534
|
+
* This code should vectorize nicely if using modern compilers.
|
535
|
+
*/
|
536
|
+
static inline ggml_bf16_t ggml_compute_fp32_to_bf16(float s) {
|
537
|
+
ggml_bf16_t h;
|
538
|
+
union {
|
539
|
+
float f;
|
540
|
+
uint32_t i;
|
541
|
+
} u;
|
542
|
+
u.f = s;
|
543
|
+
if ((u.i & 0x7fffffff) > 0x7f800000) { /* nan */
|
544
|
+
h.bits = (u.i >> 16) | 64; /* force to quiet */
|
545
|
+
return h;
|
546
|
+
}
|
547
|
+
h.bits = (u.i + (0x7fff + ((u.i >> 16) & 1))) >> 16;
|
548
|
+
return h;
|
549
|
+
}
|
550
|
+
|
551
|
+
#define GGML_FP32_TO_BF16(x) ggml_compute_fp32_to_bf16(x)
|
552
|
+
#define GGML_BF16_TO_FP32(x) ggml_compute_bf16_to_fp32(x)
|
553
|
+
|
554
|
+
#ifdef __cplusplus
|
555
|
+
}
|
556
|
+
#endif
|