KitaitiMakoto commited on
Commit
bb2a01d
·
unverified ·
1 Parent(s): de79ec1

ruby : add Metal support (#2516)

Browse files
bindings/ruby/Rakefile CHANGED
@@ -17,7 +17,12 @@ extsources.each_pair do |src_dir, dests|
17
  end
18
  SOURCES = extsources.values.flatten
19
  CLEAN.include SOURCES
20
- CLEAN.include FileList["ext/*.o", "ext/whisper.so", "ext/whisper.bundle", "ext/whisper.dll"]
 
 
 
 
 
21
 
22
  task build: SOURCES + FileList[
23
  "ext/extconf.rb",
 
17
  end
18
  SOURCES = extsources.values.flatten
19
  CLEAN.include SOURCES
20
+ CLEAN.include FileList[
21
+ "ext/*.o",
22
+ "ext/*.metal",
23
+ "ext/whisper.{so,bundle,dll}",
24
+ "ext/depend"
25
+ ]
26
 
27
  task build: SOURCES + FileList[
28
  "ext/extconf.rb",
bindings/ruby/ext/extconf.rb CHANGED
@@ -12,4 +12,219 @@ if enable_config('march-tune-native', false)
12
  $CXXFLAGS << ' -march=native -mtune=native'
13
  end
14
 
15
- create_makefile('whisper')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  $CXXFLAGS << ' -march=native -mtune=native'
13
  end
14
 
15
+ def with_disabling_unsupported_files
16
+ disabled_files = []
17
+
18
+ unless $GGML_METAL
19
+ disabled_files << 'ggml-metal.h' << 'ggml-metal.m'
20
+ end
21
+
22
+ unless $GGML_METAL_EMBED_LIBRARY
23
+ disabled_files << 'ggml-metal.metal'
24
+ end
25
+
26
+ unless $OBJ_ALL&.include? 'ggml-blas.o'
27
+ disabled_files << 'ggml-blas.h' << 'ggml-blas.cpp'
28
+ end
29
+
30
+ disabled_files.filter! {|file| File.exist? file}
31
+
32
+ disabled_files.each do |file|
33
+ File.rename file, "#{file}.disabled"
34
+ end
35
+
36
+ yield
37
+
38
+ disabled_files.each do |file|
39
+ File.rename "#{file}.disabled", file
40
+ end
41
+ end
42
+
43
+ if ENV['WHISPER_METAL']
44
+ $GGML_METAL ||= true
45
+ $DEPRECATE_WARNING ||= true
46
+ end
47
+
48
+ $UNAME_S = `uname -s`.chomp
49
+ $UNAME_P = `uname -p`.chomp
50
+ $UNAME_M = `uname -m`.chomp
51
+
52
+ if $UNAME_S == 'Darwin'
53
+ unless ENV['GGML_NO_METAL']
54
+ $GGML_METAL ||= true
55
+ end
56
+ $GGML_NO_OPENMP ||= true
57
+ end
58
+
59
+ if $GGML_METAL
60
+ $GGML_METAL_EMBED_LIBRARY = true
61
+ end
62
+
63
+ $MK_CPPFLAGS = ''
64
+ $MK_CFLAGS = '-std=c11 -fPIC'
65
+ $MK_CXXFLAGS = '-std=c++11 -fPIC'
66
+ $MK_NVCCFLAGS = '-std=c++11'
67
+ $MK_LDFLAGS = ''
68
+
69
+ $OBJ_GGML = ''
70
+ $OBJ_WHISPER = ''
71
+ $OBJ_COMMON = ''
72
+ $OBJ_SDL = ''
73
+
74
+ $MK_CPPFLAGS << ' -D_XOPEN_SOURCE=600'
75
+
76
+ if $UNAME_S == 'Linux'
77
+ $MK_CPPFLAGS << ' -D_GNU_SOURCE'
78
+ end
79
+
80
+ if $UNAME_S == 'Darwin'
81
+ $MK_CPPFLAGS << ' -D_DARWIN_C_SOURCE'
82
+ end
83
+
84
+ if ENV['WHISPER_DEBUG']
85
+ $MK_CFLAGS << ' -O0 -g'
86
+ $MK_CXXFLAGS << ' -O0 -g'
87
+ $MK_LDFLAGS << ' -g'
88
+ $MK_NVCCFLAGS << ' -O0 -g'
89
+ else
90
+ $MK_CPPFLAGS << ' -DNDEBUG'
91
+ $MK_CFLAGS << ' -O3'
92
+ $MK_CXXFLAGS << ' -O3'
93
+ $MK_NVCCFLAGS << ' -O3'
94
+ end
95
+
96
+ $WARN_FLAGS =
97
+ ' -Wall' <<
98
+ ' -Wextra' <<
99
+ ' -Wpedantic' <<
100
+ ' -Wcast-qual' <<
101
+ ' -Wno-unused-function'
102
+
103
+ $MK_CFLAGS <<
104
+ $WARN_FLAGS <<
105
+ ' -Wshadow' <<
106
+ ' -Wstrict-prototypes' <<
107
+ ' -Wpointer-arith' <<
108
+ ' -Wmissing-prototypes' <<
109
+ ' -Werror=implicit-int' <<
110
+ ' -Werror=implicit-function-declaration'
111
+
112
+ $MK_CXXFLAGS <<
113
+ $WARN_FLAGS <<
114
+ ' -Wmissing-declarations' <<
115
+ ' -Wmissing-noreturn'
116
+
117
+ unless `#{cc_command} #{$LDFLAGS} -Wl,-v 2>&1`.chomp.include? 'dyld-1015.7'
118
+ $MK_CPPFLAGS << ' -DHAVE_BUGGY_APPLE_LINKER'
119
+ end
120
+
121
+ if %w[Linux Darwin FreeBSD NetBSD OpenBSD Haiku].include? $UNAME_S
122
+ $MK_CFLAGS << ' -pthread'
123
+ $MK_CXXFLAGS << ' -pthread'
124
+ end
125
+
126
+ unless $_WIN32
127
+ $DSO_EXT = '.so'
128
+ else
129
+ $DSO_EXT = '.dll'
130
+ end
131
+
132
+ unless ENV['RISCV']
133
+ if %w[x86_64 i686 amd64].include? $UNAME_M
134
+ $HOST_CXXFLAGS ||= ''
135
+
136
+ $MK_CFLAGS << ' -march=native -mtune=native'
137
+ $HOST_CXXFLAGS << ' -march=native -mtune=native'
138
+ end
139
+
140
+ if $UNAME_M.match? /aarch64.*/
141
+ $MK_CFLAGS << ' -mcpu=native'
142
+ $MK_CXXFLAGS << ' -mcpu=native'
143
+ end
144
+ else
145
+ $MK_CFLAGS << ' -march=rv64gcv -mabi=lp64d'
146
+ $MK_CXXFLAGS << ' -march=rv64gcv -mabi=lp64d'
147
+ end
148
+
149
+ unless ENV['GGML_NO_ACCELERATE']
150
+ if $UNAME_S == 'Darwin'
151
+ $MK_CPPFLAGS << ' -DGGML_USE_ACCELERATE -DGGML_USE_BLAS'
152
+ $MK_CPPFLAGS << ' -DACCELERATE_NEW_LAPACK'
153
+ $MK_CPPFLAGS << ' -DACCELERATE_LAPACK_ILP64'
154
+ $MK_LDFLAGS << ' -framework Accelerate'
155
+ $OBJ_GGML << ' ggml-blas.o'
156
+ end
157
+ end
158
+
159
+ if ENV['GGML_OPENBLAS']
160
+ $MK_CPPFLAGS << " -DGGML_USE_BLAS #{`pkg-config --cflags-only-I openblas`.chomp}"
161
+ $MK_CFLAGS << " #{`pkg-config --cflags-only-other openblas)`.chomp}"
162
+ $MK_LDFLAGS << " #{`pkg-config --libs openblas`}"
163
+ $OBJ_GGML << ' ggml-blas.o'
164
+ end
165
+
166
+ if ENV['GGML_OPENBLAS64']
167
+ $MK_CPPFLAGS << " -DGGML_USE_BLAS #{`pkg-config --cflags-only-I openblas64`.chomp}"
168
+ $MK_CFLAGS << " #{`pkg-config --cflags-only-other openblas64)`.chomp}"
169
+ $MK_LDFLAGS << " #{`pkg-config --libs openblas64`}"
170
+ $OBJ_GGML << ' ggml-blas.o'
171
+ end
172
+
173
+ if $GGML_METAL
174
+ $MK_CPPFLAGS << ' -DGGML_USE_METAL'
175
+ $MK_LDFLAGS << ' -framework Foundation -framework Metal -framework MetalKit'
176
+ $OBJ_GGML << ' ggml-metal.o'
177
+
178
+ if ENV['GGML_METAL_NDEBUG']
179
+ $MK_CPPFLAGS << ' -DGGML_METAL_NDEBUG'
180
+ end
181
+
182
+ if $GGML_METAL_EMBED_LIBRARY
183
+ $MK_CPPFLAGS << ' -DGGML_METAL_EMBED_LIBRARY'
184
+ $OBJ_GGML << ' ggml-metal-embed.o'
185
+ end
186
+ end
187
+
188
+ $OBJ_GGML <<
189
+ ' ggml.o' <<
190
+ ' ggml-alloc.o' <<
191
+ ' ggml-backend.o' <<
192
+ ' ggml-quants.o' <<
193
+ ' ggml-aarch64.o'
194
+
195
+ $OBJ_WHISPER <<
196
+ ' whisper.o'
197
+
198
+ $OBJ_ALL = "#{$OBJ_GGML} #{$OBJ_WHISPER} #{$OBJ_COMMON} #{$OBJ_SDL}"
199
+
200
+ $CPPFLAGS = "#{$MK_CPPFLAGS} #{$CPPFLAGS}"
201
+ $CFLAGS = "#{$CPPFLAGS} #{$MK_CFLAGS} #{$GF_CFLAGS} #{$CFLAGS}"
202
+ $BASE_CXXFLAGS = "#{$MK_CXXFLAGS} #{$CXXFLAGS}"
203
+ $CXXFLAGS = "#{$BASE_CXXFLAGS} #{$HOST_CXXFLAGS} #{$GF_CXXFLAGS} #{$CPPFLAGS}"
204
+ $NVCCFLAGS = "#{$MK_NVCCFLAGS} #{$NVCCFLAGS}"
205
+ $LDFLAGS = "#{$MK_LDFLAGS} #{$LDFLAGS}"
206
+
207
+ if $GGML_METAL_EMBED_LIBRARY
208
+ File.write 'depend', "$(OBJS): $(OBJS) ggml-metal-embed.o\n"
209
+ end
210
+
211
+ with_disabling_unsupported_files do
212
+
213
+ create_makefile('whisper')
214
+
215
+ end
216
+
217
+ File.open 'Makefile', 'a' do |file|
218
+ file.puts 'include get-flags.mk'
219
+
220
+ if $GGML_METAL
221
+ if $GGML_METAL_EMBED_LIBRARY
222
+ # mkmf determines object files to compile dependent on existing *.{c,cpp,m} files
223
+ # but ggml-metal-embed.c doesn't exist on creating Makefile.
224
+ file.puts "objs := $(OBJS)"
225
+ file.puts "OBJS = $(objs) 'ggml-metal-embed.o'"
226
+
227
+ file.puts 'include metal-embed.mk'
228
+ end
229
+ end
230
+ end
bindings/ruby/ext/metal-embed.mk ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ggml-metal-embed.o: \
2
+ ggml-metal.metal \
3
+ ggml-common.h
4
+ @echo "Embedding Metal library"
5
+ @sed -e '/#include "ggml-common.h"/r ggml-common.h' -e '/#include "ggml-common.h"/d' < ggml-metal.metal > ggml-metal-embed.metal
6
+ $(eval TEMP_ASSEMBLY=$(shell mktemp))
7
+ @echo ".section __DATA, __ggml_metallib" > $(TEMP_ASSEMBLY)
8
+ @echo ".globl _ggml_metallib_start" >> $(TEMP_ASSEMBLY)
9
+ @echo "_ggml_metallib_start:" >> $(TEMP_ASSEMBLY)
10
+ @echo ".incbin \"ggml-metal-embed.metal\"" >> $(TEMP_ASSEMBLY)
11
+ @echo ".globl _ggml_metallib_end" >> $(TEMP_ASSEMBLY)
12
+ @echo "_ggml_metallib_end:" >> $(TEMP_ASSEMBLY)
13
+ @$(AS) $(TEMP_ASSEMBLY) -o $@
14
+ @rm -f ${TEMP_ASSEMBLY}
bindings/ruby/extsources.yaml CHANGED
@@ -15,6 +15,9 @@
15
  - ext/ggml-quants.h
16
  - ext/ggml-quants.c
17
  - ext/ggml-cpu-impl.h
 
 
 
18
  ../../ggml/include:
19
  - ext/ggml.h
20
  - ext/ggml-alloc.h
@@ -24,9 +27,11 @@
24
  - ext/ggml-metal.h
25
  - ext/ggml-sycl.h
26
  - ext/ggml-vulkan.h
 
 
 
27
  ../../examples:
28
  - ext/dr_wav.h
29
  ../..:
30
  - README.md
31
  - LICENSE
32
-
 
15
  - ext/ggml-quants.h
16
  - ext/ggml-quants.c
17
  - ext/ggml-cpu-impl.h
18
+ - ext/ggml-metal.m
19
+ - ext/ggml-metal.metal
20
+ - ext/ggml-blas.cpp
21
  ../../ggml/include:
22
  - ext/ggml.h
23
  - ext/ggml-alloc.h
 
27
  - ext/ggml-metal.h
28
  - ext/ggml-sycl.h
29
  - ext/ggml-vulkan.h
30
+ - ext/ggml-blas.h
31
+ ../../scripts:
32
+ - ext/get-flags.mk
33
  ../../examples:
34
  - ext/dr_wav.h
35
  ../..:
36
  - README.md
37
  - LICENSE