diff --git a/Yolo/android/app/build.gradle.kts b/Yolo/android/app/build.gradle.kts index 99614ac8..b99e1551 100644 --- a/Yolo/android/app/build.gradle.kts +++ b/Yolo/android/app/build.gradle.kts @@ -7,78 +7,80 @@ */ plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) } val qnnVersion: String? = project.findProperty("qnnVersion") as? String val useLocalAar: Boolean? = (project.findProperty("useLocalAar") as? String)?.toBoolean() android { - namespace = "com.example.executorchyolodemo" - compileSdk = 34 + namespace = "com.example.executorchyolodemo" + compileSdk = 35 - defaultConfig { - applicationId = "com.example.executorchyolodemo" - minSdk = 28 - targetSdk = 33 - versionCode = 1 - versionName = "1.0" + defaultConfig { + applicationId = "com.example.executorchyolodemo" + minSdk = 28 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { useSupportLibrary = true } - externalNativeBuild { cmake { cppFlags += "" } } - } + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { useSupportLibrary = true } + externalNativeBuild { cmake { cppFlags += "" } } + } - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { jvmTarget = "1.8" } - buildFeatures { compose = true } - composeOptions { kotlinCompilerExtensionVersion = "1.5.14" } - packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } + buildFeatures { + compose = true + } + packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } } dependencies { - implementation("androidx.core:core-ktx:1.9.0") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") - implementation("androidx.activity:activity-compose:1.7.0") - implementation(platform("androidx.compose:compose-bom:2023.03.00")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.ui:ui-graphics") - implementation("androidx.compose.ui:ui-tooling-preview") - implementation("androidx.compose.material3:material3") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("androidx.camera:camera-core:1.3.0-rc02") - implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha12") - implementation("com.facebook.fbjni:fbjni:0.5.1") - implementation("com.google.code.gson:gson:2.8.6") - if (useLocalAar == true) { - implementation(files("libs/executorch.aar")) - } else { - implementation("org.pytorch:executorch-android:1.1.0") - } - - implementation("com.google.android.material:material:1.12.0") - implementation("androidx.activity:activity:1.9.0") - implementation("org.json:json:20250107") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) - androidTestImplementation("androidx.compose.ui:ui-test-junit4") - debugImplementation("androidx.compose.ui:ui-tooling") - debugImplementation("androidx.compose.ui:ui-test-manifest") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.appcompat) + implementation(libs.material) + implementation("androidx.constraintlayout:constraintlayout:2.2.0") + implementation("com.facebook.fbjni:fbjni:0.5.1") + implementation("com.google.code.gson:gson:2.10.1") + if (useLocalAar == true) { + implementation(files("libs/executorch.aar")) + } else { + implementation("org.pytorch:executorch-android:1.1.0") + } + implementation("androidx.activity:activity:1.9.0") + implementation("org.json:json:20250107") + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) - implementation ("androidx.camera:camera-camera2:1.3.0") - implementation ("androidx.camera:camera-lifecycle:1.3.0") - implementation ("androidx.camera:camera-view:1.3.0") - implementation ("com.google.code.gson:gson:2.10.1") + implementation(libs.androidx.camera.core) + implementation(libs.androidx.camera.camera2) + implementation(libs.androidx.camera.lifecycle) + implementation(libs.androidx.camera.view) } diff --git a/Yolo/android/build.gradle.kts b/Yolo/android/build.gradle.kts index a2f57ba6..53733080 100644 --- a/Yolo/android/build.gradle.kts +++ b/Yolo/android/build.gradle.kts @@ -8,6 +8,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.7.3" apply false - id("org.jetbrains.kotlin.android") version "1.9.24" apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false } diff --git a/Yolo/android/gradle/libs.versions.toml b/Yolo/android/gradle/libs.versions.toml new file mode 100644 index 00000000..a27d02df --- /dev/null +++ b/Yolo/android/gradle/libs.versions.toml @@ -0,0 +1,40 @@ +[versions] +agp = "8.9.0" +kotlin = "2.0.21" +coreKtx = "1.16.0" +junit = "4.13.2" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +lifecycleRuntimeKtx = "2.9.2" +activityCompose = "1.10.1" +composeBom = "2024.09.00" +appcompat = "1.7.1" +material = "1.12.0" +camera = "1.3.0" + +[libraries] +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "camera" } +androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "camera" } +androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camera" } +androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "camera" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } diff --git a/Yolo/android/gradle/wrapper/gradle-wrapper.properties b/Yolo/android/gradle/wrapper/gradle-wrapper.properties index 9355b415..e2847c82 100644 --- a/Yolo/android/gradle/wrapper/gradle-wrapper.properties +++ b/Yolo/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/cifar/android/CifarETTrainingDemo/app/build.gradle.kts b/cifar/android/CifarETTrainingDemo/app/build.gradle.kts index fba110fb..15322c32 100644 --- a/cifar/android/CifarETTrainingDemo/app/build.gradle.kts +++ b/cifar/android/CifarETTrainingDemo/app/build.gradle.kts @@ -28,18 +28,15 @@ android { } } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "11" } buildFeatures { compose = true } - composeOptions { - kotlinCompilerExtensionVersion = "1.5.1" - } packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" diff --git a/cifar/android/CifarETTrainingDemo/gradle/libs.versions.toml b/cifar/android/CifarETTrainingDemo/gradle/libs.versions.toml index ec659cd7..50683e68 100644 --- a/cifar/android/CifarETTrainingDemo/gradle/libs.versions.toml +++ b/cifar/android/CifarETTrainingDemo/gradle/libs.versions.toml @@ -3,9 +3,9 @@ agp = "8.9.0" kotlin = "2.0.21" coreKtx = "1.16.0" junit = "4.13.2" -junitVersion = "1.2.1" -espressoCore = "3.6.1" -lifecycleRuntimeKtx = "2.9.1" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +lifecycleRuntimeKtx = "2.9.2" activityCompose = "1.10.1" composeBom = "2024.09.00" @@ -29,4 +29,3 @@ androidx-material3 = { group = "androidx.compose.material3", name = "material3" android-application = { id = "com.android.application", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } - diff --git a/dl3/android/DeepLabV3Demo/app/build.gradle.kts b/dl3/android/DeepLabV3Demo/app/build.gradle.kts index 64d144dc..6dcbcf8e 100644 --- a/dl3/android/DeepLabV3Demo/app/build.gradle.kts +++ b/dl3/android/DeepLabV3Demo/app/build.gradle.kts @@ -7,64 +7,68 @@ */ plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) } val useLocalAar: Boolean? = (project.findProperty("useLocalAar") as? String)?.toBoolean() android { - namespace = "org.pytorch.executorchexamples.dl3" - compileSdk = 34 + namespace = "org.pytorch.executorchexamples.dl3" + compileSdk = 35 - defaultConfig { - applicationId = "org.pytorch.executorchexamples.dl3" - minSdk = 24 - targetSdk = 34 - versionCode = 1 - versionName = "1.0" + defaultConfig { + applicationId = "org.pytorch.executorchexamples.dl3" + minSdk = 24 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { useSupportLibrary = true } - } + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { useSupportLibrary = true } + } - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { jvmTarget = "1.8" } - buildFeatures { compose = true } - composeOptions { kotlinCompilerExtensionVersion = "1.5.14" } } dependencies { - implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") - implementation("androidx.activity:activity-compose:1.8.0") - implementation(platform("androidx.compose:compose-bom:2023.03.00")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.ui:ui-graphics") - implementation("androidx.compose.ui:ui-tooling-preview") - implementation("androidx.compose.material3:material3") - implementation("com.google.android.material:material:1.12.0") - implementation("androidx.appcompat:appcompat:1.7.0") - if (useLocalAar == true) { - implementation(files("libs/executorch.aar")) - implementation("com.facebook.fbjni:fbjni:0.5.1") - } else { - implementation("org.pytorch:executorch-android:1.0.1") - } - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) - androidTestImplementation("androidx.compose.ui:ui-test-junit4") - debugImplementation("androidx.compose.ui:ui-tooling") - debugImplementation("androidx.compose.ui:ui-test-manifest") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.material) + implementation(libs.androidx.appcompat) + if (useLocalAar == true) { + implementation(files("libs/executorch.aar")) + implementation("com.facebook.fbjni:fbjni:0.5.1") + } else { + implementation("org.pytorch:executorch-android:1.0.1") + } + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) } diff --git a/dl3/android/DeepLabV3Demo/app/src/main/java/org/pytorch/executorchexamples/dl3/MainActivity.kt b/dl3/android/DeepLabV3Demo/app/src/main/java/org/pytorch/executorchexamples/dl3/MainActivity.kt index 9ffcaf14..2a9f1855 100644 --- a/dl3/android/DeepLabV3Demo/app/src/main/java/org/pytorch/executorchexamples/dl3/MainActivity.kt +++ b/dl3/android/DeepLabV3Demo/app/src/main/java/org/pytorch/executorchexamples/dl3/MainActivity.kt @@ -420,7 +420,7 @@ class MainActivity : ComponentActivity() { } val bmpSegmentation = Bitmap.createScaledBitmap(inputBitmap, width, height, true) - val outputBitmap = bmpSegmentation.copy(bmpSegmentation.config, true) + val outputBitmap = bmpSegmentation.copy(bmpSegmentation.config ?: Bitmap.Config.ARGB_8888, true) outputBitmap.setPixels(intValues, 0, width, 0, 0, width, height) val transferredBitmap = Bitmap.createScaledBitmap( outputBitmap, diff --git a/dl3/android/DeepLabV3Demo/build.gradle.kts b/dl3/android/DeepLabV3Demo/build.gradle.kts index a2f57ba6..53733080 100644 --- a/dl3/android/DeepLabV3Demo/build.gradle.kts +++ b/dl3/android/DeepLabV3Demo/build.gradle.kts @@ -8,6 +8,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.7.3" apply false - id("org.jetbrains.kotlin.android") version "1.9.24" apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false } diff --git a/dl3/android/DeepLabV3Demo/gradle/libs.versions.toml b/dl3/android/DeepLabV3Demo/gradle/libs.versions.toml new file mode 100644 index 00000000..ae4e2d59 --- /dev/null +++ b/dl3/android/DeepLabV3Demo/gradle/libs.versions.toml @@ -0,0 +1,35 @@ +[versions] +agp = "8.9.0" +kotlin = "2.0.21" +coreKtx = "1.16.0" +junit = "4.13.2" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +lifecycleRuntimeKtx = "2.9.2" +activityCompose = "1.10.1" +composeBom = "2024.09.00" +appcompat = "1.7.1" +material = "1.12.0" + +[libraries] +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } diff --git a/llm/android/LlamaDemo/app/build.gradle.kts b/llm/android/LlamaDemo/app/build.gradle.kts index b4a5a86f..d4fba5e6 100644 --- a/llm/android/LlamaDemo/app/build.gradle.kts +++ b/llm/android/LlamaDemo/app/build.gradle.kts @@ -7,8 +7,9 @@ */ plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) } // Model files configuration for instrumentation tests @@ -208,84 +209,87 @@ val qnnVersion: String? = project.findProperty("qnnVersion") as? String val useLocalAar: Boolean? = (project.findProperty("useLocalAar") as? String)?.toBoolean() android { - namespace = "com.example.executorchllamademo" - compileSdk = 34 - - defaultConfig { - applicationId = "com.example.executorchllamademo" - testApplicationId = "com.example.executorchllamademo.test" - minSdk = 28 - targetSdk = 33 - versionCode = 1 - versionName = "1.0" - - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - - // Automatically set instrumentation arguments based on model preset - val preset = modelPresets[modelPreset] - if (preset != null) { - testInstrumentationRunnerArguments["modelFile"] = preset["pteFile"] as String - testInstrumentationRunnerArguments["tokenizerFile"] = preset["tokenizerFile"] as String - } + namespace = "com.example.executorchllamademo" + compileSdk = 35 + + defaultConfig { + applicationId = "com.example.executorchllamademo" + testApplicationId = "com.example.executorchllamademo.test" + minSdk = 28 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + + // Automatically set instrumentation arguments based on model preset + val preset = modelPresets[modelPreset] + if (preset != null) { + testInstrumentationRunnerArguments["modelFile"] = preset["pteFile"] as String + testInstrumentationRunnerArguments["tokenizerFile"] = preset["tokenizerFile"] as String + } - vectorDrawables { useSupportLibrary = true } - externalNativeBuild { cmake { cppFlags += "" } } - } + vectorDrawables { useSupportLibrary = true } + externalNativeBuild { cmake { cppFlags += "" } } + } - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { jvmTarget = "1.8" } - buildFeatures { compose = true } - composeOptions { kotlinCompilerExtensionVersion = "1.5.14" } - packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true + } + packaging { resources { excludes += "/META-INF/{AL2.0,LGPL2.1}" } } } dependencies { - implementation("androidx.core:core-ktx:1.9.0") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") - implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1") - implementation("androidx.activity:activity-compose:1.7.0") - implementation(platform("androidx.compose:compose-bom:2023.03.00")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.ui:ui-graphics") - implementation("androidx.compose.ui:ui-tooling-preview") - implementation("androidx.compose.material3:material3") - implementation("androidx.compose.material:material-icons-extended") - implementation("io.coil-kt:coil-compose:2.4.0") - implementation("androidx.appcompat:appcompat:1.6.1") - implementation("androidx.camera:camera-core:1.3.0-rc02") - implementation("androidx.constraintlayout:constraintlayout:2.2.0-alpha12") - implementation("com.facebook.fbjni:fbjni:0.5.1") - implementation("com.google.code.gson:gson:2.8.6") - if (useLocalAar == true) { - implementation(files("libs/executorch.aar")) - } else { - implementation("org.pytorch:executorch-android:1.1.0") - // https://mvnrepository.com/artifact/org.pytorch/executorch-android-qnn - // Uncomment this to enable QNN - // implementation("org.pytorch:executorch-android-qnn:1.1.0") - - // https://mvnrepository.com/artifact/org.pytorch/executorch-android-vulkan - // uncomment to enable vulkan - // implementation("org.pytorch:executorch-android-vulkan:1.1.0") - } - implementation("com.google.android.material:material:1.12.0") - implementation("androidx.activity:activity:1.9.0") - implementation("org.json:json:20250107") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0") - androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) - androidTestImplementation("androidx.compose.ui:ui-test-junit4") - debugImplementation("androidx.compose.ui:ui-tooling") - debugImplementation("androidx.compose.ui:ui-test-manifest") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.material.icons.extended) + implementation(libs.androidx.appcompat) + implementation(libs.material) + implementation("io.coil-kt:coil-compose:2.4.0") + implementation("androidx.camera:camera-core:1.3.0") + implementation("androidx.constraintlayout:constraintlayout:2.2.0") + implementation("com.facebook.fbjni:fbjni:0.5.1") + implementation("com.google.code.gson:gson:2.8.6") + if (useLocalAar == true) { + implementation(files("libs/executorch.aar")) + } else { + implementation("org.pytorch:executorch-android:1.1.0") + // https://mvnrepository.com/artifact/org.pytorch/executorch-android-qnn + // Uncomment this to enable QNN + // implementation("org.pytorch:executorch-android-qnn:1.1.0") + + // https://mvnrepository.com/artifact/org.pytorch/executorch-android-vulkan + // uncomment to enable vulkan + // implementation("org.pytorch:executorch-android-vulkan:1.1.0") + } + implementation("androidx.activity:activity:1.9.0") + implementation("org.json:json:20250107") + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation("androidx.test.uiautomator:uiautomator:2.2.0") + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) } diff --git a/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/Message.kt b/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/Message.kt index 4053d480..0e01ef1e 100644 --- a/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/Message.kt +++ b/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/Message.kt @@ -17,12 +17,16 @@ import java.util.Locale * * Note: This is not a data class because it has mutable state (text, tokensPerSecond, totalGenerationTime) * and custom initialization logic based on messageType. + * + * @param existingTimestamp Optional timestamp to preserve when copying a message. + * When null (default), timestamp is computed automatically. */ class Message( text: String, isSent: Boolean, val messageType: MessageType, - val promptID: Int + val promptID: Int, + existingTimestamp: Long? = null ) { // Use @JvmName to maintain Java compatibility - Java expects getIsSent() @get:JvmName("getIsSent") @@ -33,7 +37,8 @@ class Message( var imagePath: String? = if (messageType == MessageType.IMAGE) text else null private set - val timestamp: Long = if (messageType != MessageType.SYSTEM) System.currentTimeMillis() else 0L + val timestamp: Long = existingTimestamp + ?: if (messageType != MessageType.SYSTEM) System.currentTimeMillis() else 0L var tokensPerSecond: Float = 0f @@ -43,6 +48,20 @@ class Message( this.text += text } + /** + * Creates a new Message instance with the same state. + * Required for Compose strong skipping mode (default since Kotlin 2.0): composable functions + * compare unstable parameters by reference equality (===), so mutating an existing object and + * placing it back in a SnapshotStateList won't trigger recomposition. A new reference is needed. + */ + fun copy(): Message { + val sourceText = if (messageType == MessageType.IMAGE) (imagePath ?: "") else text + return Message(sourceText, isSent, messageType, promptID, timestamp).also { + it.tokensPerSecond = tokensPerSecond + it.totalGenerationTime = totalGenerationTime + } + } + fun getFormattedTimestamp(): String { val formatter = SimpleDateFormat(TIMESTAMP_FORMAT, Locale.getDefault()) val date = Date(timestamp) diff --git a/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/screens/ChatScreen.kt b/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/screens/ChatScreen.kt index 989c192f..b4790b5c 100644 --- a/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/screens/ChatScreen.kt +++ b/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/screens/ChatScreen.kt @@ -152,7 +152,7 @@ fun ChatScreen( ) } }, - colors = TopAppBarDefaults.smallTopAppBarColors( + colors = TopAppBarDefaults.topAppBarColors( containerColor = appColors.navBar, titleContentColor = appColors.textOnNavBar ) diff --git a/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/viewmodel/ChatViewModel.kt b/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/viewmodel/ChatViewModel.kt index a9e7c89c..e6b1e62e 100644 --- a/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/viewmodel/ChatViewModel.kt +++ b/llm/android/LlamaDemo/app/src/main/java/com/example/executorchllamademo/ui/viewmodel/ChatViewModel.kt @@ -687,7 +687,15 @@ class ChatViewModel(application: Application) : AndroidViewModel(application), L } val generateDuration = System.currentTimeMillis() - generateStartTime - resultMessage?.totalGenerationTime = generateDuration + resultMessage?.let { msg -> + msg.totalGenerationTime = generateDuration + val index = _messages.indexOfLast { it === msg } + if (index >= 0) { + val updated = msg.copy() + _messages[index] = updated + resultMessage = updated + } + } isGenerating = false ETLogging.getInstance().log("Inference completed") } @@ -769,10 +777,13 @@ class ChatViewModel(application: Application) : AndroidViewModel(application), L resultMessage?.text?.isNotEmpty() == true if (keepResult) { resultMessage?.appendText(processedResult) - // Force recomposition by updating the messages list + // Create a new Message reference to trigger recomposition under Compose strong + // skipping mode, which compares unstable parameters by reference equality (===). val index = _messages.indexOfLast { it === resultMessage } if (index >= 0) { - _messages[index] = resultMessage!! + val updated = resultMessage!!.copy() + _messages[index] = updated + resultMessage = updated } // Increment scroll trigger to auto-scroll during generation scrollTrigger++ @@ -792,10 +803,12 @@ class ChatViewModel(application: Application) : AndroidViewModel(application), L Log.e("LLM", "Error parsing JSON: ${e.message}") } msg.tokensPerSecond = tps - // Force recomposition + // Create a new reference to trigger recomposition under strong skipping mode val index = _messages.indexOfLast { it === msg } if (index >= 0) { - _messages[index] = msg + val updated = msg.copy() + _messages[index] = updated + resultMessage = updated } } } diff --git a/llm/android/LlamaDemo/build.gradle.kts b/llm/android/LlamaDemo/build.gradle.kts index a2f57ba6..53733080 100644 --- a/llm/android/LlamaDemo/build.gradle.kts +++ b/llm/android/LlamaDemo/build.gradle.kts @@ -8,6 +8,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.7.3" apply false - id("org.jetbrains.kotlin.android") version "1.9.24" apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false } diff --git a/llm/android/LlamaDemo/gradle/libs.versions.toml b/llm/android/LlamaDemo/gradle/libs.versions.toml new file mode 100644 index 00000000..f0b5dd81 --- /dev/null +++ b/llm/android/LlamaDemo/gradle/libs.versions.toml @@ -0,0 +1,37 @@ +[versions] +agp = "8.9.0" +kotlin = "2.0.21" +coreKtx = "1.16.0" +junit = "4.13.2" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +lifecycleRuntimeKtx = "2.9.2" +activityCompose = "1.10.1" +composeBom = "2024.09.00" +appcompat = "1.7.1" +material = "1.12.0" + +[libraries] +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +androidx-lifecycle-viewmodel-compose = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "lifecycleRuntimeKtx" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } diff --git a/llm/android/LlamaDemo/gradle/wrapper/gradle-wrapper.properties b/llm/android/LlamaDemo/gradle/wrapper/gradle-wrapper.properties index 9355b415..e2847c82 100644 --- a/llm/android/LlamaDemo/gradle/wrapper/gradle-wrapper.properties +++ b/llm/android/LlamaDemo/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/mv3/android/MV3Demo/app/build.gradle.kts b/mv3/android/MV3Demo/app/build.gradle.kts index d1ceb30f..0d6c5bad 100644 --- a/mv3/android/MV3Demo/app/build.gradle.kts +++ b/mv3/android/MV3Demo/app/build.gradle.kts @@ -7,64 +7,67 @@ */ plugins { - id("com.android.application") - id("org.jetbrains.kotlin.android") + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) } android { - namespace = "org.pytorch.executorchexamples.mv3" - compileSdk = 34 + namespace = "org.pytorch.executorchexamples.mv3" + compileSdk = 35 - defaultConfig { - applicationId = "org.pytorch.executorchexamples.mv3" - minSdk = 24 - targetSdk = 34 - versionCode = 1 - versionName = "1.0" + defaultConfig { + applicationId = "org.pytorch.executorchexamples.mv3" + minSdk = 24 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - vectorDrawables { useSupportLibrary = true } - } + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { useSupportLibrary = true } + } - buildTypes { - release { - isMinifyEnabled = false - proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + buildTypes { + release { + isMinifyEnabled = false + proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true } - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - kotlinOptions { jvmTarget = "1.8" } - buildFeatures { compose = true } - composeOptions { kotlinCompilerExtensionVersion = "1.5.14" } } dependencies { - implementation("androidx.core:core-ktx:1.12.0") - implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2") - implementation("androidx.activity:activity-compose:1.8.0") - implementation(platform("androidx.compose:compose-bom:2023.03.00")) - implementation("androidx.compose.ui:ui") - implementation("androidx.compose.ui:ui-graphics") - implementation("androidx.compose.ui:ui-tooling-preview") - implementation("androidx.compose.material3:material3") - implementation("androidx.compose.material:material-icons-extended") - implementation("com.google.android.material:material:1.12.0") - implementation("androidx.appcompat:appcompat:1.7.0") - implementation("org.pytorch:executorch-android:1.0.0") - testImplementation("junit:junit:4.13.2") - androidTestImplementation("androidx.test.ext:junit:1.1.5") - androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") - androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) - androidTestImplementation("androidx.compose.ui:ui-test-junit4") - debugImplementation("androidx.compose.ui:ui-tooling") - debugImplementation("androidx.compose.ui:ui-test-manifest") + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(libs.androidx.material.icons.extended) + implementation(libs.material) + implementation(libs.androidx.appcompat) + implementation("org.pytorch:executorch-android:1.0.0") + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) - val cameraVersion = "1.3.0" - implementation("androidx.camera:camera-core:$cameraVersion") - implementation("androidx.camera:camera-camera2:$cameraVersion") - implementation("androidx.camera:camera-lifecycle:$cameraVersion") - implementation("androidx.camera:camera-view:$cameraVersion") + implementation(libs.androidx.camera.core) + implementation(libs.androidx.camera.camera2) + implementation(libs.androidx.camera.lifecycle) + implementation(libs.androidx.camera.view) } diff --git a/mv3/android/MV3Demo/build.gradle.kts b/mv3/android/MV3Demo/build.gradle.kts index a2f57ba6..53733080 100644 --- a/mv3/android/MV3Demo/build.gradle.kts +++ b/mv3/android/MV3Demo/build.gradle.kts @@ -8,6 +8,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.7.3" apply false - id("org.jetbrains.kotlin.android") version "1.9.24" apply false + alias(libs.plugins.android.application) apply false + alias(libs.plugins.kotlin.android) apply false + alias(libs.plugins.kotlin.compose) apply false } diff --git a/mv3/android/MV3Demo/gradle/libs.versions.toml b/mv3/android/MV3Demo/gradle/libs.versions.toml new file mode 100644 index 00000000..7451e6c1 --- /dev/null +++ b/mv3/android/MV3Demo/gradle/libs.versions.toml @@ -0,0 +1,41 @@ +[versions] +agp = "8.9.0" +kotlin = "2.0.21" +coreKtx = "1.16.0" +junit = "4.13.2" +junitVersion = "1.3.0" +espressoCore = "3.7.0" +lifecycleRuntimeKtx = "2.9.2" +activityCompose = "1.10.1" +composeBom = "2024.09.00" +appcompat = "1.7.1" +material = "1.12.0" +camera = "1.3.0" + +[libraries] +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } +androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } +androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } +material = { group = "com.google.android.material", name = "material", version.ref = "material" } +androidx-camera-core = { group = "androidx.camera", name = "camera-core", version.ref = "camera" } +androidx-camera-camera2 = { group = "androidx.camera", name = "camera-camera2", version.ref = "camera" } +androidx-camera-lifecycle = { group = "androidx.camera", name = "camera-lifecycle", version.ref = "camera" } +androidx-camera-view = { group = "androidx.camera", name = "camera-view", version.ref = "camera" } + +[plugins] +android-application = { id = "com.android.application", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }