Skip to content

Conversation

@IvanKobzarev
Copy link
Contributor

@IvanKobzarev IvanKobzarev commented Oct 22, 2019

Reason:
To have one-step build for test android application based on the current code state that is ready for profiling with simpleperf, systrace etc. to profile performance inside the application.

Parameters to control debug symbols stripping

Introducing /CMakeLists parameter ANDROID_DEBUG_SYMBOLS to be able not to strip symbols for pytorch (not add linker flag -s)
which is checked in scripts/build_android.sh

On gradle side stripping happens by default, and to prevent it we have to specify

android {
  packagingOptions {
       doNotStrip "**/*.so"
  }
}

which is now controlled by new gradle property nativeLibsDoNotStrip

Test_App

android/test_app - android app with one MainActivity that does inference in cycle

android/build_test_app.sh - script to build libtorch with debug symbols for specified android abis and adds NDK_DEBUG=1 and -PnativeLibsDoNotStrip=true to keep all debug symbols for profiling.
Script assembles all debug flavors:

└─ $ find . -type f -name *apk
./test_app/app/build/outputs/apk/mobilenetQuant/debug/test_app-mobilenetQuant-debug.apk
./test_app/app/build/outputs/apk/resnet/debug/test_app-resnet-debug.apk

Different build configurations

Module for inference can be set in android/test_app/app/build.gradle as a BuildConfig parameters:

    productFlavors {
        mobilenetQuant {
            dimension "model"
            applicationIdSuffix ".mobilenetQuant"
            buildConfigField ("String", "MODULE_ASSET_NAME", buildConfigProps('MODULE_ASSET_NAME_MOBILENET_QUANT'))
            addManifestPlaceholders([APP_NAME: "PyMobileNetQuant"])
            buildConfigField ("String", "LOGCAT_TAG", "\"pytorch-mobilenet\"")
        }
        resnet {
            dimension "model"
            applicationIdSuffix ".resnet"
            buildConfigField ("String", "MODULE_ASSET_NAME", buildConfigProps('MODULE_ASSET_NAME_RESNET18'))
            addManifestPlaceholders([APP_NAME: "PyResnet"])
            buildConfigField ("String", "LOGCAT_TAG", "\"pytorch-resnet\"")
        }

In that case we can setup several apps on the same device for comparison, to separate packages applicationIdSuffix: 'org.pytorch.testapp.mobilenetQuant' and different application names and logcat tags as manifestPlaceholder and another BuildConfig parameter:

─ $ adb shell pm list packages | grep pytorch
package:org.pytorch.testapp.mobilenetQuant
package:org.pytorch.testapp.resnet

In future we can add another BuildConfig params e.g. single/multi threads and other configuration for profiling.

At the moment 2 flavors - for resnet18 and for mobilenetQuantized
which can be installed on connected device:

cd android
gradle test_app:installMobilenetQuantDebug
gradle test_app:installResnetDebug

Testing:

cd android
sh build_test_app.sh
adb install -r test_app/app/build/outputs/apk/mobilenetQuant/debug/test_app-mobilenetQuant-debug.apk
cd $ANDROID_NDK
python simpleperf/run_simpleperf_on_device.py record --app org.pytorch.testapp.mobilenetQuant -g --duration 10 -o /data/local/tmp/perf.data
adb pull /data/local/tmp/perf.data
python simpleperf/report_html.py

Simpleperf report has all symbols:
Screenshot 2019-10-22 11 06 21

@IvanKobzarev IvanKobzarev changed the title [WI{][android] Test application for profiling + CMake params for debug symbols [WIP][android] Test application for profiling + CMake params for debug symbols Oct 22, 2019
@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch 5 times, most recently from 73f2038 to da13dbf Compare October 22, 2019 17:51
@IvanKobzarev IvanKobzarev changed the title [WIP][android] Test application for profiling + CMake params for debug symbols [android] Test application for profiling, CMake params for debug symbols Oct 22, 2019
Copy link
Contributor

@AshkanAliabadi AshkanAliabadi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, thank you so much for doing this. You and Tao are life savers.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Am I correct to assume that since I don't spot a loop here, we are calling PyTorch forward only one time? Or is this function called from a loop somewhere?

I am mainly asking this question to understand whether we are profiling one or multiple runs of a network here. I think it is worthwhile to be able to have the ability to run a network multiple times through a configurable parameter to be able to study thermal behavior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. It can be the same image sent to the network over and over again to avoid image acquisition and decoding overhead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 private final Runnable mModuleForwardRunnable = new Runnable() {
    @Override
    public void run() {
      runOnUiThread(new Runnable() {
        @Override
        public void run() {
          handleResult(doModuleForward());
          if (mBackgroundHandler != null) {
            mBackgroundHandler.post(mModuleForwardRunnable);
          }
        }
      });
    }
  };

We call doModuleForward() in a loop, but its organized with scheduling the same implementation of Runnable interface mModuleForwardRunnable on mBackgroundHandler which does queue
of Runnableprocessing.
So it will put it on queue of the thread mBackgroundThread = new HandlerThread(TAG + "_bg"); the name depends what we put in build.gradle as LOG_TAG

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P.S. It can be the same image sent to the network over and over again to avoid image acquisition and decoding overhead.

At the moment here we even do not have image - just allocating buffer of proper size and creating tensor from it - so we should not see any overhead from camera, image decoding etc.

@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch from da13dbf to 33af80c Compare October 23, 2019 18:48
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: can you change the model names to mobilenet_v2 and resnet18 where it is used?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch from 33af80c to 0b010d1 Compare October 24, 2019 16:40
@dreiss
Copy link
Contributor

dreiss commented Nov 5, 2019

I don't think we should check in the models, since they are quite big. That puts a tax on everyone using this repo. Maybe have the build script download them from somewhere? Also, we don't need the hdpi and x*hdpi icons. Scaling up mdpi is fine. Other than that, I think this is fine as long as it works for you and Ashkan.

@dreiss dreiss removed their request for review November 5, 2019 23:14
@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch 2 times, most recently from d449f0f to 1a86fbf Compare November 7, 2019 21:47
@IvanKobzarev IvanKobzarev requested a review from dreiss November 7, 2019 21:58
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why isn't this ':test_app'?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this, since the top-level build.gradle already does it?

@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch from 1a86fbf to c9da33d Compare November 8, 2019 00:59
Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IvanKobzarev has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch from c9da33d to adee5e7 Compare November 8, 2019 01:40
@IvanKobzarev IvanKobzarev force-pushed the android_test_app_for_profiling branch from adee5e7 to c0f5360 Compare November 8, 2019 20:02
Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IvanKobzarev has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

Copy link
Contributor

@facebook-github-bot facebook-github-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@IvanKobzarev has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator.

@facebook-github-bot
Copy link
Contributor

@IvanKobzarev merged this pull request in 92b9de1.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants