From e6413dd05d31146989e8293a23e2b64929c4e5ac Mon Sep 17 00:00:00 2001 From: Han Yin Date: Thu, 3 Jul 2025 13:44:25 -0700 Subject: [PATCH] UI: support `NONE` Llama Tier in general settings --- .../ui/components/ArmFeaturesVisualizer.kt | 99 ++++++------------- .../llama/ui/screens/SettingsGeneralScreen.kt | 39 +++++++- .../java/android/llama/cpp/ArmFeatures.kt | 16 +-- 3 files changed, 76 insertions(+), 78 deletions(-) diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt index 4eb04b3f93..8cc6f1fe37 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/components/ArmFeaturesVisualizer.kt @@ -1,10 +1,7 @@ package com.example.llama.ui.components -import android.content.Intent import android.llama.cpp.ArmFeature -import android.llama.cpp.ArmFeaturesMapper -import android.llama.cpp.LLamaTier -import androidx.compose.foundation.layout.Column +import android.llama.cpp.ArmFeaturesMapper.DisplayItem import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme @@ -13,11 +10,8 @@ import androidx.compose.material3.SegmentedButton import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.font.FontWeight -import androidx.core.net.toUri import kotlin.math.sqrt /** @@ -26,72 +20,41 @@ import kotlin.math.sqrt @OptIn(ExperimentalMaterial3Api::class) @Composable fun ArmFeaturesVisualizer( - detectedTier: LLamaTier?, - modifier: Modifier = Modifier, + supportedFeatures: List, onFeatureClick: ((ArmFeature) -> Unit)? = null ) { - val featuresData = remember(detectedTier) { - ArmFeaturesMapper.getFeatureDisplayData(detectedTier) - } - - Column( - modifier = modifier.fillMaxWidth() + // Segmented Button Row for Features + MultiChoiceSegmentedButtonRow( + modifier = Modifier.fillMaxWidth() ) { - // Segmented Button Row for Features - MultiChoiceSegmentedButtonRow( - modifier = Modifier.fillMaxWidth() - ) { - featuresData.forEachIndexed { index, item -> - val weight = sqrt(item.feature.displayName.length.toFloat()) + supportedFeatures.forEachIndexed { index, item -> + val weight = sqrt(item.feature.displayName.length.toFloat()) - SegmentedButton( - modifier = Modifier.weight(weight), - shape = SegmentedButtonDefaults.itemShape( - index = index, - count = featuresData.size - ), - icon = {}, - onCheckedChange = { onFeatureClick?.invoke(item.feature) }, - checked = item.isSupported, - ) { - Text( - text = item.feature.displayName, - style = MaterialTheme.typography.labelSmall, - fontWeight = if (item.isSupported) { - FontWeight.Medium - } else { - FontWeight.Light - }, - color = if (item.isSupported) { - MaterialTheme.colorScheme.onSurface - } else { - MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) - } - ) - } + SegmentedButton( + modifier = Modifier.weight(weight), + shape = SegmentedButtonDefaults.itemShape( + index = index, + count = supportedFeatures.size + ), + icon = {}, + onCheckedChange = { onFeatureClick?.invoke(item.feature) }, + checked = item.isSupported, + ) { + Text( + text = item.feature.displayName, + style = MaterialTheme.typography.labelSmall, + fontWeight = if (item.isSupported) { + FontWeight.Medium + } else { + FontWeight.Light + }, + color = if (item.isSupported) { + MaterialTheme.colorScheme.onSurface + } else { + MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f) + } + ) } } } } - -/** - * Alternative version with clickable features that open ARM documentation. - */ -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun ArmFeaturesVisualizerClickable( - detectedTier: LLamaTier?, - modifier: Modifier = Modifier -) { - val context = LocalContext.current - - ArmFeaturesVisualizer( - detectedTier = detectedTier, - modifier = modifier, - onFeatureClick = { feature -> - // Open ARM documentation in browser - val intent = Intent(Intent.ACTION_VIEW, feature.armDocUrl.toUri()) - context.startActivity(intent) - } - ) -} diff --git a/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt b/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt index 531685b10a..d3bc1e5334 100644 --- a/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt +++ b/examples/llama.android/app/src/main/java/com/example/llama/ui/screens/SettingsGeneralScreen.kt @@ -1,5 +1,8 @@ package com.example.llama.ui.screens +import android.content.Intent +import android.llama.cpp.ArmFeaturesMapper +import android.llama.cpp.ArmFeaturesMapper.DisplayItem import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -10,6 +13,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Card +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SegmentedButton @@ -20,12 +24,15 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp +import androidx.core.net.toUri import com.example.llama.APP_NAME import com.example.llama.data.preferences.UserPreferences -import com.example.llama.ui.components.ArmFeaturesVisualizerClickable +import com.example.llama.ui.components.ArmFeaturesVisualizer import com.example.llama.viewmodel.SettingsViewModel /** @@ -41,6 +48,10 @@ fun SettingsGeneralScreen( val themeMode by viewModel.themeMode.collectAsState() val detectedTier = viewModel.detectedTier + val supportedFeatures = remember(detectedTier) { + ArmFeaturesMapper.getFeatureDisplayData(detectedTier) + } + Column( modifier = Modifier .fillMaxSize() @@ -128,9 +139,11 @@ fun SettingsGeneralScreen( detectedTier?.let { tier -> Spacer(modifier = Modifier.height(8.dp)) - ArmFeaturesVisualizerClickable(detectedTier = detectedTier) + supportedFeatures?.let { + ArmFeaturesVisualizerClickable(supportedFeatures = supportedFeatures) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(8.dp)) + } Text( text = "Optimization Tier: ${tier.name}", @@ -224,3 +237,23 @@ fun SettingsSwitch( ) } } + +/** + * Alternative version with clickable features that open ARM documentation. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ArmFeaturesVisualizerClickable( + supportedFeatures: List, +) { + val context = LocalContext.current + + ArmFeaturesVisualizer( + supportedFeatures = supportedFeatures, + onFeatureClick = { feature -> + // Open ARM documentation in browser + val intent = Intent(Intent.ACTION_VIEW, feature.armDocUrl.toUri()) + context.startActivity(intent) + } + ) +} diff --git a/examples/llama.android/llama/src/main/java/android/llama/cpp/ArmFeatures.kt b/examples/llama.android/llama/src/main/java/android/llama/cpp/ArmFeatures.kt index d049e803e4..a915391cb6 100644 --- a/examples/llama.android/llama/src/main/java/android/llama/cpp/ArmFeatures.kt +++ b/examples/llama.android/llama/src/main/java/android/llama/cpp/ArmFeatures.kt @@ -78,13 +78,15 @@ object ArmFeaturesMapper { /** * Gets the feature support data for UI display. */ - fun getFeatureDisplayData(tier: LLamaTier?): List = - getSupportedFeatures(tier).let { flags -> - allFeatures.mapIndexed { index, feature -> - DisplayItem( - feature = feature, - isSupported = flags?.getOrElse(index) { false } == true - ) + fun getFeatureDisplayData(tier: LLamaTier?): List? = + getSupportedFeatures(tier).let { optFlags -> + optFlags?.let { flags -> + allFeatures.mapIndexed { index, feature -> + DisplayItem( + feature = feature, + isSupported = flags.getOrElse(index) { false } + ) + } } } }