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

pull/317/head
Kevin Brothaler 2 years ago committed by Georgi Gerganov
parent e1432dd91a
commit 91fc08c641

@ -1,8 +1,13 @@
package com.whispercppdemo.whisper package com.whispercppdemo.whisper
import android.os.Build
import android.util.Log
import kotlinx.coroutines.* import kotlinx.coroutines.*
import java.io.File
import java.util.concurrent.Executors import java.util.concurrent.Executors
private const val LOG_TAG = "LibWhisper"
class WhisperContext private constructor(private var ptr: Long) { class WhisperContext private constructor(private var ptr: Long) {
// Meet Whisper C++ constraint: Don't access from more than one thread at a time. // Meet Whisper C++ constraint: Don't access from more than one thread at a time.
private val scope: CoroutineScope = CoroutineScope( private val scope: CoroutineScope = CoroutineScope(
@ -47,7 +52,27 @@ class WhisperContext private constructor(private var ptr: Long) {
private class WhisperLib { private class WhisperLib {
companion object { companion object {
init { 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 // 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
}
}

@ -1,22 +1,15 @@
LOCAL_PATH := $(call my-dir) LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS) include $(CLEAR_VARS)
WHISPER_LIB_DIR := $(LOCAL_PATH)/../../../../../../../
LOCAL_LDLIBS := -llog
LOCAL_MODULE := libwhisper 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. ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
ifneq ($(APP_OPTIM),debug) include $(CLEAR_VARS)
LOCAL_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden LOCAL_MODULE := libwhisper_vfpv4
LOCAL_CFLAGS += -ffunction-sections -fdata-sections include $(LOCAL_PATH)/Whisper.mk
LOCAL_LDFLAGS += -Wl,--gc-sections # Allow building NEON FMA code.
LOCAL_LDFLAGS += -Wl,--exclude-libs,ALL # https://android.googlesource.com/platform/ndk/+/master/sources/android/cpufeatures/cpu-features.h
LOCAL_LDFLAGS += -flto LOCAL_CFLAGS += -mfpu=neon-vfpv4
include $(BUILD_SHARED_LIBRARY)
endif 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)

@ -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
Loading…
Cancel
Save