Repository: pytorch
Issue: TorchScript model's output different on Mobile and PC
Labels: oncall: mobile

First of all I'd like to thank you and appreciate your work constructing pytorch, which is amazing.

## 🐛 Bug

I have [this model](https://github.com/roj4s/pytorch_mobile_example/raw/master/app/src/main/assets/mobile_model.pt) that I compiled with torch.jit.trace. I load it on my PC and it works just fine with following code:

```
  import torch
  import sys
  from PIL import Image
  import torchvision.transforms.functional as TF
  import torchvision

  image = Image.open(sys.argv[2])
  x = TF.to_tensor(image)
  x.unsqueeze_(0)
  print(x.shape)

  model = torch.load(sys.argv[1])
  model.eval()

  output = model(x)
  torchvision.utils.save_image(output, 'output.png')
```

When inputed Image 1. it outputs Image 2. and is an aceptable result.

Image 1
<img src="https://github.com/roj4s/pytorch_mobile_example/raw/master/data/cropped.jpg"/>

Image 2
<img src="https://github.com/roj4s/pytorch_mobile_example/raw/master/data/output.png"/>

However when used on the phone, this very same .pt file and same image it outputs what's shown on Image 3. which is not acceptable not only because the output is different than what's obtained on PC, it just doesn't make sense.

Image 3
<img src="https://github.com/roj4s/pytorch_mobile_example/raw/master/data/wrong_output.jpg"/>

On the phone I do something along, find all the [code here](https://raw.githubusercontent.com/roj4s/pytorch_mobile_example/master/app/src/main/java/com/rojas/sr/ShowFrameActivity.java):

```
     Bitmap image = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
     mModule = Module.load(moduleFileAbsoluteFilePath);
     mInputTensor = TensorImageUtils.bitmapToFloat32Tensor(croppedImage, ones, ones);
     final Tensor outputTensor = mModule.forward(IValue.from(mInputTensor)).toTensor();
     final float[] outputTensorAsFloatArray = outputTensor.getDataAsFloatArray();
     Bitmap outputBitmap = Util.bitmapFromRGBImageAsFloatArray(outputTensorAsFloatArray, width, height);
     imageView.setImageBitmap(outputBitmap);
```

Function Util.bitmapFromRGBImageAsFloatArray implementation as follows:
```
public static Bitmap bitmapFromRGBImageAsFloatArray(float[] data, int width, int height){

        Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

        float max = 0;
        float min = 999999;

        for(float f: data){
            if(f > max){
                max = f;
            }
            if(f < min){
                min = f;
            }
        }

        int delta = (int)(max - min);

        for (int i = 0; i < width * height; i++) {

            int r = (int) ((data[i] - min)/delta*255.0f);
            int g = (int) ((data[i + width * height] - min) / delta*255.0f);
            int b = (int) ((data[i + width * height * 2] - min) / delta*255.0f);

            int x = i / width;
            int y = i % width;

            int color = Color.rgb(r, g, b);
            bmp.setPixel(x, y, color);

        }
        return bmp;
    }
```

I tested Util.bitmapFromRGBImageAsFloatArray with a sample Image Tensor just to check is working fine.

All the code is [on this github repo](https://github.com/roj4s/pytorch_mobile_example): https://github.com/roj4s/pytorch_mobile_example

## To Reproduce

Steps to reproduce the behavior:

1. Perform inference on PC using [this model](https://github.com/roj4s/pytorch_mobile_example/raw/master/app/src/main/assets/mobile_model.pt) and the script presented above, or take the script [from here](https://raw.githubusercontent.com/roj4s/pytorch_mobile_example/master/load_model.py).
2. Build and run (on a phone) the android app here: https://github.com/roj4s/pytorch_mobile_example
3. Use android app to perform inference on sample image
4. Compare outputs from PC and from Mobile App

## Expected behavior

Both image outputs, from PC and from Mobile App are equal. Mobile App output is perceptually aceptable. 

## Environment

 - PyTorch Version: PC => 1.7.1, Android => org.pytorch:pytorch_android:1.8.0-SNAPSHOT, org.pytorch:pytorch_android_torchvision:1.8.0-SNAPSHOT, com.facebook.fbjni:fbjni-java-only:0.0.3
 - OS (e.g., Linux): Linux and Android 9
 - How you installed PyTorch (`conda`, `pip`, source): pip
 - Python version: 3.7
 - GPU models and configuration: Just cpu

Repositories on build.gradle file:
```
 repositories {
    jcenter()
    maven {
        url "https://oss.sonatype.org/content/repositories/snapshots"
    }
}
```
Android section on  build.gradle file:

```
android {
    compileSdkVersion 30
    buildToolsVersion "30.0.2"

    defaultConfig {
        applicationId "com.rojas.sr"
        minSdkVersion 21
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}
```



cc @gmagogsfm