這裏還問有沒有運氣(https://groups.google.com/forum/#!topic/android-developers/Rh_L9Jv_S8Q)複製並針對Android(的renderScript)半精度F16分配
我試圖找出如何使用類型,如half
和half4
做半精度。唯一的問題似乎是從java到renderscript和後面的數字。
Java代碼:
private float[] input;
private float[] half_output;
private RenderScript mRS;
private ScriptC_mono mScript;
private final int dimen = 15;
...
//onCreate
input = new float[dimen * dimen * 3]; //later loaded from file 182.24 3.98 105.83 226.08 15.2 80.01...
half_output = new float[dimen * dimen * 3];
...
//function calling renderscript
mRS = RenderScript.create(this);
ScriptC_halfPrecision mScript = new ScriptC_halfPrecision(mRS);
Allocation input2 = Allocation.createSized(mRS, Element.F16(mRS), dimen * dimen * 3);
input2.copyFromUnchecked(input); //copy float values to F16 allocation
Allocation halfIndex = Allocation.createSized(mRS, Element.F16(mRS), dimen * dimen);
Type.Builder half_output_type = new Type.Builder(mRS, Element.F16(mRS)).setX(dimen * dimen * 3);
Allocation output3 = Allocation.createTyped(mRS, half_output_type.create());
mScript.set_half_in(input2);
mScript.set_half_out(output3);
mScript.forEach_half_operation(halfIndex);
output3.copy1DRangeToUnchecked(0, dimen * dimen * 3, half_output); //copy F16 allocation back to float array
的的renderScript:
#pragma version(1)
#pragma rs java_package_name(com.example.android.rs.hellocompute)
rs_allocation half_in;
rs_allocation half_out;
half __attribute__((kernel)) half_operation(uint32_t x) {
half4 out = rsGetElementAt_half4(half_in, x);
out.x /= 2.0;
out.y /= 2.0;
out.z /= 2.0;
out.w /= 2.0;
rsSetElementAt_half4(half_out, out, x);
}
我也試過在Java代碼中顯示的最後一行,而不是這樣的:
float temp_half[] = new float[1];
for (int i = 0; i < dimen * dimen * 3; ++i) { //copy F16 allocation back to float array
output3.copy1DRangeToUnchecked(i, 1, temp_half);
half_output[i]=temp_half[0];
}
Al l上面的代碼完美適用於在java中的renderscript和F32
分配中的float4
變量。 這顯然是因爲從renderscript float
到java float
沒有問題。 但試圖從java float
(因爲沒有java half
)renderscript half
並且返回是非常困難的。 任何人都可以告訴我該怎麼做嗎?
以上兩個版本的java代碼在half_output
數組中都會導致看似隨機的值。 它們顯然不是隨機的,因爲它們在每次運行時都是相同的值,不管在half_operation(uint32_t x)
函數中的操作如何。 我試着將out.x /= 2.0;
(和相應的y,z,w代碼)更改爲out.x /= 2000000.0;
或out.x *= 2000000.0;
並且仍然最後在half_output
數組中的值每次運行時都是相同的。
使用的182.24 3.98 105.83 226.08 15.2 80.01...
輸入使用該Java
output3.copy1DRangeToUnchecked(0, dimen * dimen * 3, half_output); //copy F16 allocation back to float array
所得half_output是46657.44 27094.48 3891.45 965.1825 36223.44 14959.08...
使用該Java
float temp_half[] = new float[1];
for (int i = 0; i < dimen * dimen * 3; ++i) { //copy F16 allocation back to float array
output3.copy1DRangeToUnchecked(i, 1, temp_half);
half_output[i]=temp_half[0];
}
所得half_output是2.3476E-41 2.5546E-41 6.2047E-41 2.5407E-41 1.9802E-41 2.4914E-41...
無論我將out.x /= 2.0;
算法更改爲什麼,這些都是結果。