1*da0073e9SAndroid Build Coastguard Worker## TestApp 2*da0073e9SAndroid Build Coastguard Worker 3*da0073e9SAndroid Build Coastguard WorkerThe TestApp is currently being used as a dummy app by Circle CI for nightly jobs. The challenge comes when testing the arm64 build as we don't have a way to code-sign our TestApp. This is where Fastlane came to rescue. [Fastlane](https://fastlane.tools/) is a trendy automation tool for building and managing iOS applications. It also works seamlessly with Circle CI. We are going to leverage the `import_certificate` action, which can install developer certificates on CI machines. See `Fastfile` for more details. 4*da0073e9SAndroid Build Coastguard Worker 5*da0073e9SAndroid Build Coastguard WorkerFor simulator build, we run unit tests as the last step of our CI workflow. Those unit tests can also be run manually via the `fastlane scan` command. 6*da0073e9SAndroid Build Coastguard Worker 7*da0073e9SAndroid Build Coastguard Worker## Run Simulator Test Locally 8*da0073e9SAndroid Build Coastguard WorkerFollow these steps if you want to run the test locally. 9*da0073e9SAndroid Build Coastguard Worker 10*da0073e9SAndroid Build Coastguard Worker1. Checkout PyTorch repo including all submodules 11*da0073e9SAndroid Build Coastguard Worker 12*da0073e9SAndroid Build Coastguard Worker2. Build PyTorch for ios 13*da0073e9SAndroid Build Coastguard Worker``` 14*da0073e9SAndroid Build Coastguard WorkerUSE_COREML_DELEGATE=1 IOS_PLATFORM=SIMULATOR ./scripts/build_ios.sh 15*da0073e9SAndroid Build Coastguard Worker``` 16*da0073e9SAndroid Build Coastguard Worker 17*da0073e9SAndroid Build Coastguard Worker3. Generate on-the-fly test models 18*da0073e9SAndroid Build Coastguard Worker``` 19*da0073e9SAndroid Build Coastguard Workerpython test/mobile/model_test/gen_test_model.py ios-test 20*da0073e9SAndroid Build Coastguard Worker``` 21*da0073e9SAndroid Build Coastguard WorkerYou need to install regular PyTorch on your local machine to run this script. 22*da0073e9SAndroid Build Coastguard WorkerCheck https://github.com/pytorch/pytorch/tree/master/test/mobile/model_test#diagnose-failed-test to learn more. 23*da0073e9SAndroid Build Coastguard Worker 24*da0073e9SAndroid Build Coastguard Worker4. Create XCode project (for lite interpreter) 25*da0073e9SAndroid Build Coastguard Worker``` 26*da0073e9SAndroid Build Coastguard Workercd ios/TestApp/benchmark 27*da0073e9SAndroid Build Coastguard Workerruby setup.rb --lite 1 28*da0073e9SAndroid Build Coastguard Worker``` 29*da0073e9SAndroid Build Coastguard Worker 30*da0073e9SAndroid Build Coastguard Worker5. Open the generated TestApp/TestApp.xcodeproj in XCode and run simulator test. 31*da0073e9SAndroid Build Coastguard Worker 32*da0073e9SAndroid Build Coastguard Worker## Re-generate All Test Models 33*da0073e9SAndroid Build Coastguard Worker1. Make sure PyTorch (not PyTorch for iOS) is installed 34*da0073e9SAndroid Build Coastguard WorkerSee https://pytorch.org/get-started/locally/ 35*da0073e9SAndroid Build Coastguard Worker 36*da0073e9SAndroid Build Coastguard Worker2. Re-generate models for operator test 37*da0073e9SAndroid Build Coastguard Worker``` 38*da0073e9SAndroid Build Coastguard Workerpython test/mobile/model_test/gen_test_model.py ios 39*da0073e9SAndroid Build Coastguard Workerpython test/mobile/model_test/gen_test_model.py ios-test 40*da0073e9SAndroid Build Coastguard Worker``` 41*da0073e9SAndroid Build Coastguard Worker 42*da0073e9SAndroid Build Coastguard Worker3. Re-generate Core ML model 43*da0073e9SAndroid Build Coastguard Worker``` 44*da0073e9SAndroid Build Coastguard Workercd ios/TestApp/benchmark; python coreml_backend.py 45*da0073e9SAndroid Build Coastguard Worker``` 46*da0073e9SAndroid Build Coastguard Worker 47*da0073e9SAndroid Build Coastguard Worker## Run test on AWS Device Farm 48*da0073e9SAndroid Build Coastguard WorkerThe test app and its test suite could also be run on actual devices via 49*da0073e9SAndroid Build Coastguard WorkerAWS Device Farm. 50*da0073e9SAndroid Build Coastguard Worker 51*da0073e9SAndroid Build Coastguard Worker1. The following steps could only be done on MacOS with Xcode installed. 52*da0073e9SAndroid Build Coastguard Worker I'm using Xcode 15.0 on MacOS M1 arm64 53*da0073e9SAndroid Build Coastguard Worker 54*da0073e9SAndroid Build Coastguard Worker2. Checkout PyTorch repo including all submodules 55*da0073e9SAndroid Build Coastguard Worker 56*da0073e9SAndroid Build Coastguard Worker3. Build PyTorch for iOS devices, not for simulator 57*da0073e9SAndroid Build Coastguard Worker``` 58*da0073e9SAndroid Build Coastguard Workerexport BUILD_LITE_INTERPRETER=1 59*da0073e9SAndroid Build Coastguard Workerexport USE_PYTORCH_METAL=1 60*da0073e9SAndroid Build Coastguard Workerexport USE_COREML_DELEGATE=1 61*da0073e9SAndroid Build Coastguard Workerexport IOS_PLATFORM=OS 62*da0073e9SAndroid Build Coastguard Workerexport IOS_ARCH=arm64 63*da0073e9SAndroid Build Coastguard Worker 64*da0073e9SAndroid Build Coastguard Worker./scripts/build_ios.sh 65*da0073e9SAndroid Build Coastguard Worker``` 66*da0073e9SAndroid Build Coastguard Worker 67*da0073e9SAndroid Build Coastguard Worker4. Build the test app locally 68*da0073e9SAndroid Build Coastguard Worker``` 69*da0073e9SAndroid Build Coastguard Worker# Use the pytorch nightly build to generate models 70*da0073e9SAndroid Build Coastguard Workerpip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu 71*da0073e9SAndroid Build Coastguard Worker 72*da0073e9SAndroid Build Coastguard Worker# Generate models for differnet backends 73*da0073e9SAndroid Build Coastguard Workerpushd ios/TestApp/benchmark 74*da0073e9SAndroid Build Coastguard Workermkdir -p ../models 75*da0073e9SAndroid Build Coastguard Worker 76*da0073e9SAndroid Build Coastguard Worker# This requires numpy==1.23.1 77*da0073e9SAndroid Build Coastguard Workerpython coreml_backend.py 78*da0073e9SAndroid Build Coastguard Worker 79*da0073e9SAndroid Build Coastguard Worker# NB: Also need to set the team ID with -t if you are running this locally. This 80*da0073e9SAndroid Build Coastguard Worker# command setups an app that could be used to launch TestAppTests on device. On 81*da0073e9SAndroid Build Coastguard Worker# the other hand, adding the --benchmark flag to build the one that runs benchmark 82*da0073e9SAndroid Build Coastguard Worker# instead. 83*da0073e9SAndroid Build Coastguard Workerruby setup.rb --lite 1 84*da0073e9SAndroid Build Coastguard Workerpopd 85*da0073e9SAndroid Build Coastguard Worker 86*da0073e9SAndroid Build Coastguard Worker# Build the TestApp and its TestAppTests 87*da0073e9SAndroid Build Coastguard Workerruby scripts/xcode_build.rb -i build_ios/install -x ios/TestApp/TestApp.xcodeproj -p "OS" 88*da0073e9SAndroid Build Coastguard Worker``` 89*da0073e9SAndroid Build Coastguard Worker 90*da0073e9SAndroid Build Coastguard Worker5. Prepare the artifacts 91*da0073e9SAndroid Build Coastguard Workerhttps://docs.aws.amazon.com/devicefarm/latest/developerguide/test-types-ios-xctest.html 92*da0073e9SAndroid Build Coastguard Worker 93*da0073e9SAndroid Build Coastguard Worker``` 94*da0073e9SAndroid Build Coastguard Workerexport DEST_DIR="Payload" 95*da0073e9SAndroid Build Coastguard Worker 96*da0073e9SAndroid Build Coastguard Workerpushd ios/TestApp/build/Release-iphoneos 97*da0073e9SAndroid Build Coastguard Workermkdir "${DEST_DIR}" 98*da0073e9SAndroid Build Coastguard Worker 99*da0073e9SAndroid Build Coastguard Workercp -r TestApp.app "${DEST_DIR}" 100*da0073e9SAndroid Build Coastguard Worker# TestApp.ipa is just a zip file with a payload subdirectory 101*da0073e9SAndroid Build Coastguard Workerzip -vr TestApp.ipa "${DEST_DIR}" 102*da0073e9SAndroid Build Coastguard Worker 103*da0073e9SAndroid Build Coastguard Workerpushd TestApp.app/PlugIns 104*da0073e9SAndroid Build Coastguard Worker# Also zip the TestAppTests.xctest test suite 105*da0073e9SAndroid Build Coastguard Workerzip -vr TestAppTests.xctest.zip TestAppTests.xctest 106*da0073e9SAndroid Build Coastguard Workerpopd 107*da0073e9SAndroid Build Coastguard Worker 108*da0073e9SAndroid Build Coastguard Workercp TestApp.app/PlugIns/TestAppTests.xctest.zip . 109*da0073e9SAndroid Build Coastguard Workerpopd 110*da0073e9SAndroid Build Coastguard Worker``` 111*da0073e9SAndroid Build Coastguard Worker 112*da0073e9SAndroid Build Coastguard Worker6. Upload the artifacts to AWS Device Farm and run the tests 113*da0073e9SAndroid Build Coastguard Worker``` 114*da0073e9SAndroid Build Coastguard Workerexport PYTORCH_ARN="arn:aws:devicefarm:us-west-2:308535385114:project:b531574a-fb82-40ae-b687-8f0b81341ae0" 115*da0073e9SAndroid Build Coastguard Worker 116*da0073e9SAndroid Build Coastguard Workerpushd ios/TestApp 117*da0073e9SAndroid Build Coastguard Worker# AWS Device Farm is only available on us-west-2 118*da0073e9SAndroid Build Coastguard WorkerAWS_DEFAULT_REGION=us-west-2 python run_on_aws_devicefarm.py \ 119*da0073e9SAndroid Build Coastguard Worker --project-arn "${PYTORCH_ARN}" \ 120*da0073e9SAndroid Build Coastguard Worker --app-file build/Release-iphoneos/TestApp.ipa \ 121*da0073e9SAndroid Build Coastguard Worker --xctest-file build/Release-iphoneos/TestAppTests.xctest.zip \ 122*da0073e9SAndroid Build Coastguard Worker --name-prefix PyTorch 123*da0073e9SAndroid Build Coastguard Workerpopd 124*da0073e9SAndroid Build Coastguard Worker``` 125*da0073e9SAndroid Build Coastguard Worker 126*da0073e9SAndroid Build Coastguard Worker7. The script will continue polling for the outcome. A visual output of 127*da0073e9SAndroid Build Coastguard Worker the test results could be view on AWS Device Farm console for [PyTorch project](https://us-west-2.console.aws.amazon.com/devicefarm/home#/mobile/projects/b531574a-fb82-40ae-b687-8f0b81341ae0/runs) 128*da0073e9SAndroid Build Coastguard Worker 129*da0073e9SAndroid Build Coastguard Worker## Debug Test Failures 130*da0073e9SAndroid Build Coastguard WorkerMake sure all models are generated. See https://github.com/pytorch/pytorch/tree/master/test/mobile/model_test to learn more. 131*da0073e9SAndroid Build Coastguard Worker 132*da0073e9SAndroid Build Coastguard WorkerThere's no debug information in simulator test (project TestAppTests). You can copy the failed test code to 133*da0073e9SAndroid Build Coastguard WorkerTestApp/TestApp/ViewController.mm and debug in the main TestApp. 134*da0073e9SAndroid Build Coastguard Worker 135*da0073e9SAndroid Build Coastguard Worker### Benchmark 136*da0073e9SAndroid Build Coastguard Worker 137*da0073e9SAndroid Build Coastguard WorkerThe benchmark folder contains two scripts that help you setup the benchmark project. The `setup.rb` does the heavy-lifting jobs of setting up the XCode project, whereas the `trace_model.py` is a Python script that you can tweak to generate your model for benchmarking. Simply follow the steps below to setup the project 138*da0073e9SAndroid Build Coastguard Worker 139*da0073e9SAndroid Build Coastguard Worker1. In the PyTorch root directory, run `IOS_ARCH=arm64 ./scripts/build_ios.sh` to generate the custom build from **Master** branch 140*da0073e9SAndroid Build Coastguard Worker2. Navigate to the `benchmark` folder, run `python trace_model.py` to generate your model. 141*da0073e9SAndroid Build Coastguard Worker3. In the same directory, open `config.json`. Those are the input parameters you can tweak. 142*da0073e9SAndroid Build Coastguard Worker4. Again, in the same directory, run `ruby setup.rb` to setup the XCode project. 143*da0073e9SAndroid Build Coastguard Worker5. Open the `TestApp.xcodeproj`, you're ready to go. 144*da0073e9SAndroid Build Coastguard Worker 145*da0073e9SAndroid Build Coastguard WorkerThe benchmark code is written in C++, you can use `UI_LOG` to visualize the log. See `benchmark.mm` for more details. 146