This guide provides detailed instructions for integrating GPUFabric Mobile SDK into Android and iOS applications.
-
Copy library files
app/src/main/jniLibs/arm64-v8a/libgpuf_c.so -
Add dependencies
implementation("net.java.dev.jna:jna:5.13.0@aar") -
Call API
val client = GPUFabricClient() client.initialize() val version = client.getVersion()
-
Add static library
libgpuf_c.a gpuf_c.h -
Configure Build Settings
- Add library search paths
- Link static library
-
Call API
let result = gpuf_init() let version = gpuf_version()
# Using Android Studio
# File → New → New Project → Empty Activity
# Language: Kotlin
# Minimum SDK: API 24app/src/main/
├── jniLibs/
│ ├── arm64-v8a/
│ │ └── libgpuf_c.so # ARM64 library
│ ├── armeabi-v7a/
│ │ └── libgpuf_c.so # ARMv7 library (optional)
│ └── x86_64/
│ └── libgpuf_c.so # x86_64 library (emulator)
└── cpp/
└── gpuf_c.h # C header file (reference)
# Copy from build output
Copy-Item "target\aarch64-linux-android\release\libgpuf_c.so" `
"app\src\main\jniLibs\arm64-v8a\"plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
namespace = "com.example.gpufabric"
compileSdk = 34
defaultConfig {
applicationId = "com.example.gpufabric"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"
ndk {
abiFilters.add("arm64-v8a") // Main architecture
// abiFilters.add("armeabi-v7a") // Optional
// abiFilters.add("x86_64") // Emulator
}
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
}
dependencies {
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.11.0")
// JNA for native library access
implementation("net.java.dev.jna:jna:5.13.0@aar")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
}package com.example.gpufabric
import android.util.Log
import com.sun.jna.Library
import com.sun.jna.Native
import com.sun.jna.Pointer
interface GPUFabricNative : Library {
companion object {
val INSTANCE: GPUFabricNative by lazy {
System.loadLibrary("gpuf_c")
Native.load("gpuf_c", GPUFabricNative::class.java)
}
}
// Basic functions
fun gpuf_init(): Int
fun gpuf_get_last_error(): Pointer?
fun gpuf_free_string(ptr: Pointer?)
fun gpuf_version(): Pointer?
// LLM inference functions
fun gpuf_llm_init(modelPath: String, nCtx: Int, nGpuLayers: Int): Int
fun gpuf_llm_generate(prompt: String, maxTokens: Int): Pointer?
}
class GPUFabricClient {
private val TAG = "GPUFabric"
/**
* Initialize GPUFabric library
*/
fun initialize(): Boolean {
return try {
Log.i(TAG, "Initializing GPUFabric...")
val result = GPUFabricNative.INSTANCE.gpuf_init()
if (result != 0) {
val error = getLastError()
Log.e(TAG, "Initialization failed: $error")
false
} else {
Log.i(TAG, "✅ Initialization successful")
true
}
} catch (e: Exception) {
Log.e(TAG, "Initialization exception: ${e.message}", e)
false
}
}
/**
* Get version information
*/
fun getVersion(): String {
return try {
val versionPtr = GPUFabricNative.INSTANCE.gpuf_version()
versionPtr?.getString(0) ?: "unknown"
} catch (e: Exception) {
Log.e(TAG, "Failed to get version: ${e.message}")
"error"
}
}
/**
* Initialize LLM engine
*/
fun initLLM(modelPath: String, contextSize: Int = 2048, gpuLayers: Int = 0): Boolean {
return try {
Log.i(TAG, "Initializing LLM with model: $modelPath")
val result = GPUFabricNative.INSTANCE.gpuf_llm_init(modelPath, contextSize, gpuLayers)
if (result != 0) {
val error = getLastError()
Log.e(TAG, "LLM initialization failed: $error")
false
} else {
Log.i(TAG, "✅ LLM initialization successful")
true
}
} catch (e: Exception) {
Log.e(TAG, "LLM initialization exception: ${e.message}", e)
false
}
}
/**
* Generate text
*/
fun generateText(prompt: String, maxTokens: Int = 100): String {
return try {
Log.i(TAG, "Generating text for prompt: $prompt")
val resultPtr = GPUFabricNative.INSTANCE.gpuf_llm_generate(prompt, maxTokens)
if (resultPtr == null) {
val error = getLastError()
Log.e(TAG, "Generation failed: $error")
""
} else {
val text = resultPtr.getString(0)
GPUFabricNative.INSTANCE.gpuf_free_string(resultPtr)
text
}
} catch (e: Exception) {
Log.e(TAG, "Generation exception: ${e.message}", e)
""
}
}
/**
* Get last error message
*/
private fun getLastError(): String {
return try {
val errorPtr = GPUFabricNative.INSTANCE.gpuf_get_last_error()
if (errorPtr == null) "unknown error"
else {
val error = errorPtr.getString(0)
GPUFabricNative.INSTANCE.gpuf_free_string(errorPtr)
error
}
} catch (e: Exception) {
"Failed to get error: ${e.message}"
}
}
}package com.example.gpufabric
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
private lateinit var client: GPUFabricClient
private lateinit var logText: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
client = GPUFabricClient()
logText = findViewById(R.id.logText)
setupButtons()
}
private fun setupButtons() {
findViewById<Button>(R.id.btnInit).setOnClickListener {
testInitialization()
}
findViewById<Button>(R.id.btnVersion).setOnClickListener {
testVersion()
}
findViewById<Button>(R.id.btnLLM).setOnClickListener {
testLLM()
}
}
private fun testInitialization() {
logText.append("=== Testing Initialization ===\n")
val success = client.initialize()
logText.append(if (success) "✅ Success\n" else "❌ Failed\n")
}
private fun testVersion() {
logText.append("=== Getting Version ===\n")
val version = client.getVersion()
logText.append("Version: $version\n")
}
private fun testLLM() {
logText.append("=== Testing LLM ===\n")
// Note: Need to provide actual model file path
val modelPath = "/sdcard/Download/model.gguf"
val initSuccess = client.initLLM(modelPath)
if (initSuccess) {
val result = client.generateText("Hello, how are you?", 50)
logText.append("Generated: $result\n")
} else {
logText.append("❌ LLM initialization failed\n")
}
}
}# Using Xcode
# File → New → Project → App
# Interface: SwiftUI
# Language: Swift
# Minimum Deployment Target: iOS 14.0- Right-click on project folder in Xcode
- Select "Add Files to Project"
- Add
libgpuf_c.aandgpuf_c.h
- Open project settings
- Find in "Build Settings":
- Library Search Paths: Add directory containing
.afile - Header Search Paths: Add directory containing
.hfile
- Library Search Paths: Add directory containing
Build Settings → Linking → Other Linker Flags
Add: -lgpuf_c
Build Settings → Architectures → Valid Architectures
Ensure includes: arm64, x86_64
#ifndef GPUFabric_Bridging_Header_h
#define GPUFabric_Bridging_Header_h
#include "gpuf_c.h"
#endif /* GPUFabric_Bridging_Header_h */Build Settings → Swift Compiler → General → Objective-C Bridging Header
Add: GPUFabric-Bridging-Header.h
import Foundation
class GPUFabricClient {
static let shared = GPUFabricClient()
private init() {
// Initialize library
let result = gpuf_init()
if result != 0 {
let error = getLastError()
print("❌ GPUFabric initialization failed: \(error)")
} else {
print("✅ GPUFabric initialized successfully")
}
}
// MARK: - Basic Functions
/// Get version information
func getVersion() -> String {
guard let versionPtr = gpuf_version() else {
return "unknown"
}
let version = String(cString: versionPtr)
gpuf_free_string(versionPtr)
return version
}
/// Get last error
private func getLastError() -> String {
guard let errorPtr = gpuf_get_last_error() else {
return "unknown error"
}
let error = String(cString: errorPtr)
gpuf_free_string(errorPtr)
return error
}
// MARK: - LLM Functions
/// Initialize LLM engine
func initLLM(modelPath: String, contextSize: Int32 = 2048, gpuLayers: Int32 = 0) -> Bool {
let result = gpuf_llm_init(modelPath, contextSize, gpuLayers)
if result != 0 {
let error = getLastError()
print("❌ LLM initialization failed: \(error)")
return false
} else {
print("✅ LLM initialized successfully")
return true
}
}
/// Generate text
func generateText(prompt: String, maxTokens: Int32 = 100) -> String {
guard let resultPtr = gpuf_llm_generate(prompt, maxTokens) else {
let error = getLastError()
print("❌ Generation failed: \(error)")
return ""
}
let result = String(cString: resultPtr)
gpuf_free_string(resultPtr)
return result
}
}import SwiftUI
struct ContentView: View {
@State private var logText = "Ready for testing...\n"
@State private var isLoading = false
var body: some View {
VStack(spacing: 16) {
Text("GPUFabric iOS Test")
.font(.title)
.padding()
ScrollView {
Text(logText)
.font(.system(.caption, design: .monospaced))
.frame(maxWidth: .infinity, alignment: .leading)
.padding()
.background(Color(.systemGray6))
.cornerRadius(8)
}
.frame(maxHeight: 300)
VStack(spacing: 8) {
HStack(spacing: 16) {
Button("Init SDK") {
testInitialization()
}
.buttonStyle(.borderedProminent)
Button("Get Version") {
testVersion()
}
.buttonStyle(.bordered)
}
HStack(spacing: 16) {
Button("Init LLM") {
testLLMInit()
}
.buttonStyle(.bordered)
Button("Generate") {
testGeneration()
}
.buttonStyle(.bordered)
}
Button("Clear Log") {
logText = ""
}
.buttonStyle(.bordered)
}
Spacer()
}
.padding()
}
private func appendLog(_ message: String) {
DispatchQueue.main.async {
logText += message + "\n"
}
}
private func testInitialization() {
appendLog("=== Testing Initialization ===")
let client = GPUFabricClient.shared
appendLog("✅ SDK loaded successfully")
}
private func testVersion() {
appendLog("=== Getting Version ===")
let version = GPUFabricClient.shared.getVersion()
appendLog("Version: \(version)")
}
private func testLLMInit() {
appendLog("=== Testing LLM Initialization ===")
// Need to provide actual model file path
let modelPath = Bundle.main.path(forResource: "model", ofType: "gguf") ?? "/tmp/model.gguf"
let success = GPUFabricClient.shared.initLLM(modelPath)
appendLog(success ? "✅ LLM initialized" : "❌ LLM initialization failed")
}
private func testGeneration() {
appendLog("=== Testing Text Generation ===")
let result = GPUFabricClient.shared.generateText("Hello, how are you?", maxTokens: 50)
appendLog("Generated: \(result)")
}
}| Function | Description | Return Value |
|---|---|---|
gpuf_init() |
Initialize library | 0=success, non-zero=failure |
gpuf_version() |
Get version | char* (version string) |
gpuf_get_last_error() |
Get error | char* (error message) |
gpuf_free_string(ptr) |
Free string | void |
| Function | Description | Parameters | Return Value |
|---|---|---|---|
gpuf_llm_init() |
Initialize LLM | modelPath, nCtx, nGpuLayers |
0=success, non-zero=failure |
gpuf_llm_generate() |
Generate text | prompt, maxTokens |
char* (generation result) |
modelPath: GGUF model file pathnCtx: Context window size (recommended 2048)nGpuLayers: Number of GPU layers (0=CPU only, >0=GPU acceleration)maxTokens: Maximum generation token count
// Initialize in Application
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
// Preload library
GPUFabricClient.shared.initialize()
}
}// Initialize in AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
_ = GPUFabricClient.shared
return true
}// Release strings promptly
val resultPtr = GPUFabricNative.INSTANCE.gpuf_llm_generate(prompt, maxTokens)
try {
val result = resultPtr.getString(0)
// Use result
} finally {
GPUFabricNative.INSTANCE.gpuf_free_string(resultPtr)
}fun safeOperation(): String? {
return try {
val result = client.generateText("Hello")
if (result.isEmpty()) {
val error = client.getLastError()
Log.e("GPUFabric", "Operation failed: $error")
null
} else {
result
}
} catch (e: Exception) {
Log.e("GPUFabric", "Exception: ${e.message}", e)
null
}
}class ModelManager {
private var currentModel: String? = null
fun loadModel(modelPath: String): Boolean {
// Unload current model (if needed)
currentModel?.let {
// Implement model unload logic
}
// Load new model
val success = client.initLLM(modelPath)
if (success) {
currentModel = modelPath
}
return success
}
}java.lang.UnsatisfiedLinkError: couldn't find "libgpuf_c.so"
Solution:
- Check
jniLibsdirectory structure - Confirm ABI filter configuration
- Verify file permissions
gpuf_init() returns -1
Solution:
- Check Logcat output
- Confirm device architecture support
- Verify dependency library integrity
ld: library not found for -lgpuf_c
Solution:
- Check Library Search Paths
- Confirm static library file exists
- Verify architecture matching
'gpuf_c.h' file not found
Solution:
- Check Header Search Paths
- Confirm bridging header file path
- Verify file import
- Use GPU acceleration (
nGpuLayers > 0) - Choose appropriate context size
- Use quantized models
- Release strings promptly
- Monitor memory usage
- Avoid loading multiple models simultaneously
Welcome to submit integration issues and improvement suggestions!