Kevin Brothaler commited on
Commit
b17dc4f
·
1 Parent(s): 1fff54f

Build a vfpv4 library for armeabi-v7a and do runtime detection to select the right library

Browse files
examples/whisper.android/app/src/main/java/com/whispercppdemo/whisper/LibWhisper.kt CHANGED
@@ -1,8 +1,13 @@
1
  package com.whispercppdemo.whisper
2
 
 
 
3
  import kotlinx.coroutines.*
 
4
  import java.util.concurrent.Executors
5
 
 
 
6
  class WhisperContext private constructor(private var ptr: Long) {
7
  // Meet Whisper C++ constraint: Don't access from more than one thread at a time.
8
  private val scope: CoroutineScope = CoroutineScope(
@@ -47,7 +52,27 @@ class WhisperContext private constructor(private var ptr: Long) {
47
  private class WhisperLib {
48
  companion object {
49
  init {
50
- System.loadLibrary("whisper")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  }
52
 
53
  // JNI methods
@@ -59,3 +84,17 @@ private class WhisperLib {
59
  }
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  package com.whispercppdemo.whisper
2
 
3
+ import android.os.Build
4
+ import android.util.Log
5
  import kotlinx.coroutines.*
6
+ import java.io.File
7
  import java.util.concurrent.Executors
8
 
9
+ private const val LOG_TAG = "LibWhisper"
10
+
11
  class WhisperContext private constructor(private var ptr: Long) {
12
  // Meet Whisper C++ constraint: Don't access from more than one thread at a time.
13
  private val scope: CoroutineScope = CoroutineScope(
 
52
  private class WhisperLib {
53
  companion object {
54
  init {
55
+ Log.d(LOG_TAG, "Primary ABI: ${Build.SUPPORTED_ABIS[0]}")
56
+ var loadVfpv4 = false
57
+ if (isArmEabiV7a()) {
58
+ // armeabi-v7a needs runtime detection support
59
+ val cpuInfo = cpuInfo()
60
+ cpuInfo?.let {
61
+ Log.d(LOG_TAG, "CPU info: $cpuInfo")
62
+ if (cpuInfo.contains("vfpv4")) {
63
+ Log.d(LOG_TAG, "CPU supports vfpv4")
64
+ loadVfpv4 = true
65
+ }
66
+ }
67
+ }
68
+
69
+ if (loadVfpv4) {
70
+ Log.d(LOG_TAG, "Loading libwhisper_vfpv4.so")
71
+ System.loadLibrary("whisper_vfpv4")
72
+ } else {
73
+ Log.d(LOG_TAG, "Loading libwhisper.so")
74
+ System.loadLibrary("whisper")
75
+ }
76
  }
77
 
78
  // JNI methods
 
84
  }
85
  }
86
 
87
+ private fun isArmEabiV7a(): Boolean {
88
+ return Build.SUPPORTED_ABIS[0].equals("armeabi-v7a")
89
+ }
90
+
91
+ private fun cpuInfo(): String? {
92
+ return try {
93
+ File("/proc/cpuinfo").inputStream().bufferedReader().use {
94
+ it.readText()
95
+ }
96
+ } catch (e: Exception) {
97
+ Log.w(LOG_TAG, "Couldn't read /proc/cpuinfo", e)
98
+ null
99
+ }
100
+ }
examples/whisper.android/app/src/main/jni/whisper/Android.mk CHANGED
@@ -1,22 +1,15 @@
1
  LOCAL_PATH := $(call my-dir)
2
  include $(CLEAR_VARS)
3
- WHISPER_LIB_DIR := $(LOCAL_PATH)/../../../../../../../
4
- LOCAL_LDLIBS := -llog
5
  LOCAL_MODULE := libwhisper
 
 
6
 
7
- # Make the final output library smaller by only keeping the symbols referenced from the app.
8
- ifneq ($(APP_OPTIM),debug)
9
- LOCAL_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
10
- LOCAL_CFLAGS += -ffunction-sections -fdata-sections
11
- LOCAL_LDFLAGS += -Wl,--gc-sections
12
- LOCAL_LDFLAGS += -Wl,--exclude-libs,ALL
13
- LOCAL_LDFLAGS += -flto
14
- endif
15
-
16
- LOCAL_CFLAGS += -DSTDC_HEADERS -std=c11 -I $(WHISPER_LIB_DIR)
17
- LOCAL_CPPFLAGS += -std=c++11
18
- LOCAL_SRC_FILES := $(WHISPER_LIB_DIR)/ggml.c \
19
- $(WHISPER_LIB_DIR)/whisper.cpp \
20
- $(LOCAL_PATH)/jni.c
21
-
22
- include $(BUILD_SHARED_LIBRARY)
 
1
  LOCAL_PATH := $(call my-dir)
2
  include $(CLEAR_VARS)
 
 
3
  LOCAL_MODULE := libwhisper
4
+ include $(LOCAL_PATH)/Whisper.mk
5
+ include $(BUILD_SHARED_LIBRARY)
6
 
7
+ ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
8
+ include $(CLEAR_VARS)
9
+ LOCAL_MODULE := libwhisper_vfpv4
10
+ include $(LOCAL_PATH)/Whisper.mk
11
+ # Allow building NEON FMA code.
12
+ # https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h
13
+ LOCAL_CFLAGS += -mfpu=neon-vfpv4
14
+ include $(BUILD_SHARED_LIBRARY)
15
+ endif
 
 
 
 
 
 
 
examples/whisper.android/app/src/main/jni/whisper/Whisper.mk ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ WHISPER_LIB_DIR := $(LOCAL_PATH)/../../../../../../../
2
+ LOCAL_LDLIBS := -llog
3
+
4
+ # Make the final output library smaller by only keeping the symbols referenced from the app.
5
+ ifneq ($(APP_OPTIM),debug)
6
+ LOCAL_CFLAGS += -O3
7
+ LOCAL_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden
8
+ LOCAL_CFLAGS += -ffunction-sections -fdata-sections
9
+ LOCAL_LDFLAGS += -Wl,--gc-sections
10
+ LOCAL_LDFLAGS += -Wl,--exclude-libs,ALL
11
+ LOCAL_LDFLAGS += -flto
12
+ endif
13
+
14
+ LOCAL_CFLAGS += -DSTDC_HEADERS -std=c11 -I $(WHISPER_LIB_DIR)
15
+ LOCAL_CPPFLAGS += -std=c++11
16
+ LOCAL_SRC_FILES := $(WHISPER_LIB_DIR)/ggml.c \
17
+ $(WHISPER_LIB_DIR)/whisper.cpp \
18
+ $(LOCAL_PATH)/jni.c