]> git.djapps.eu Git - pkg/ggml/sources/whisper.cpp/commitdiff
Build a vfpv4 library for armeabi-v7a and do runtime detection to select the right...
authorKevin Brothaler <redacted>
Tue, 20 Dec 2022 20:15:59 +0000 (15:15 -0500)
committerGeorgi Gerganov <redacted>
Thu, 22 Dec 2022 14:47:54 +0000 (16:47 +0200)
examples/whisper.android/app/src/main/java/com/whispercppdemo/whisper/LibWhisper.kt
examples/whisper.android/app/src/main/jni/whisper/Android.mk
examples/whisper.android/app/src/main/jni/whisper/Whisper.mk [new file with mode: 0644]

index 69acec12cbdd6b1ad27465fb0f600d9ad7bc1ff7..a6dfdcca338e21e4fd0fca8c058ae7c82da2101a 100644 (file)
@@ -1,8 +1,13 @@
 package com.whispercppdemo.whisper
 
+import android.os.Build
+import android.util.Log
 import kotlinx.coroutines.*
+import java.io.File
 import java.util.concurrent.Executors
 
+private const val LOG_TAG = "LibWhisper"
+
 class WhisperContext private constructor(private var ptr: Long) {
     // Meet Whisper C++ constraint: Don't access from more than one thread at a time.
     private val scope: CoroutineScope = CoroutineScope(
@@ -47,7 +52,27 @@ class WhisperContext private constructor(private var ptr: Long) {
 private class WhisperLib {
     companion object {
         init {
-            System.loadLibrary("whisper")
+            Log.d(LOG_TAG, "Primary ABI: ${Build.SUPPORTED_ABIS[0]}")
+            var loadVfpv4 = false
+            if (isArmEabiV7a()) {
+                // armeabi-v7a needs runtime detection support
+                val cpuInfo = cpuInfo()
+                cpuInfo?.let {
+                    Log.d(LOG_TAG, "CPU info: $cpuInfo")
+                    if (cpuInfo.contains("vfpv4")) {
+                        Log.d(LOG_TAG, "CPU supports vfpv4")
+                        loadVfpv4 = true
+                    }
+                }
+            }
+
+            if (loadVfpv4) {
+                Log.d(LOG_TAG, "Loading libwhisper_vfpv4.so")
+                System.loadLibrary("whisper_vfpv4")
+            } else {
+                Log.d(LOG_TAG, "Loading libwhisper.so")
+                System.loadLibrary("whisper")
+            }
         }
 
         // JNI methods
@@ -59,3 +84,17 @@ private class WhisperLib {
     }
 }
 
+private fun isArmEabiV7a(): Boolean {
+    return Build.SUPPORTED_ABIS[0].equals("armeabi-v7a")
+}
+
+private fun cpuInfo(): String? {
+    return try {
+        File("/proc/cpuinfo").inputStream().bufferedReader().use {
+            it.readText()
+        }
+    } catch (e: Exception) {
+        Log.w(LOG_TAG, "Couldn't read /proc/cpuinfo", e)
+        null
+    }
+}
\ No newline at end of file
index 549cdcbba460fb69399e6640c8ce4682b2421254..3e3da8b545f817d213bd8ce604140cca43629289 100644 (file)
@@ -1,22 +1,15 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
-WHISPER_LIB_DIR := $(LOCAL_PATH)/../../../../../../../
-LOCAL_LDLIBS    := -llog
 LOCAL_MODULE    := libwhisper
+include $(LOCAL_PATH)/Whisper.mk
+include $(BUILD_SHARED_LIBRARY)
 
-# Make the final output library smaller by only keeping the symbols referenced from the app.
-ifneq ($(APP_OPTIM),debug)
-    LOCAL_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
-    LOCAL_CFLAGS += -ffunction-sections -fdata-sections
-    LOCAL_LDFLAGS += -Wl,--gc-sections
-    LOCAL_LDFLAGS += -Wl,--exclude-libs,ALL
-    LOCAL_LDFLAGS += -flto
-endif
-
-LOCAL_CFLAGS    += -DSTDC_HEADERS -std=c11 -I $(WHISPER_LIB_DIR)
-LOCAL_CPPFLAGS  += -std=c++11
-LOCAL_SRC_FILES := $(WHISPER_LIB_DIR)/ggml.c \
-                   $(WHISPER_LIB_DIR)/whisper.cpp \
-                   $(LOCAL_PATH)/jni.c
-
-include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+       include $(CLEAR_VARS)
+       LOCAL_MODULE    := libwhisper_vfpv4
+       include $(LOCAL_PATH)/Whisper.mk
+       # Allow building NEON FMA code.
+       # https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h
+       LOCAL_CFLAGS += -mfpu=neon-vfpv4
+       include $(BUILD_SHARED_LIBRARY)
+endif
\ No newline at end of file
diff --git a/examples/whisper.android/app/src/main/jni/whisper/Whisper.mk b/examples/whisper.android/app/src/main/jni/whisper/Whisper.mk
new file mode 100644 (file)
index 0000000..b4f050e
--- /dev/null
@@ -0,0 +1,18 @@
+WHISPER_LIB_DIR := $(LOCAL_PATH)/../../../../../../../
+LOCAL_LDLIBS    := -llog
+
+# Make the final output library smaller by only keeping the symbols referenced from the app.
+ifneq ($(APP_OPTIM),debug)
+    LOCAL_CFLAGS += -O3
+    LOCAL_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
+    LOCAL_CFLAGS += -ffunction-sections -fdata-sections
+    LOCAL_LDFLAGS += -Wl,--gc-sections
+    LOCAL_LDFLAGS += -Wl,--exclude-libs,ALL
+    LOCAL_LDFLAGS += -flto
+endif
+
+LOCAL_CFLAGS    += -DSTDC_HEADERS -std=c11 -I $(WHISPER_LIB_DIR)
+LOCAL_CPPFLAGS  += -std=c++11
+LOCAL_SRC_FILES := $(WHISPER_LIB_DIR)/ggml.c \
+                   $(WHISPER_LIB_DIR)/whisper.cpp \
+                   $(LOCAL_PATH)/jni.c
\ No newline at end of file