17fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni/*
27fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * Copyright (C) 2015 The Android Open Source Project
37fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni *
47fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
57fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * in compliance with the License. You may obtain a copy of the License at
67fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni *
77fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * http://www.apache.org/licenses/LICENSE-2.0
87fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni *
97fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * Unless required by applicable law or agreed to in writing, software distributed under the License
107fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
117fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * or implied. See the License for the specific language governing permissions and limitations under
127fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni * the License.
137fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni */
147fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
157fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Nipackage com.android.rs.test;
167fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
177fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Niimport android.content.Context;
18c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Allocation;
19c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Element;
20c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.RenderScript;
21c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.ScriptGroup;
22c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wangimport android.renderscript.Type;
237fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Niimport android.util.Log;
247fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
257fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Nipublic class UT_script_group2_gatherscatter extends UnitTest {
267fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    private static final int ARRAY_SIZE = 256;
277fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
287fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    private static final String TAG = "ScriptGroup2 (GatherScatter)";
297fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
307fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    int[] mArray;
317fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
3233709e1da5e801ca331642c25a61847ced8539e8Miao Wang    protected UT_script_group2_gatherscatter(RSTestCore rstc, Context ctx) {
337fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        super(rstc, TAG, ctx);
347fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    }
357fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
367fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    public void initializeGlobals(RenderScript RS, ScriptC_addup s) {
377fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        mArray = new int[ARRAY_SIZE * 4];
387fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
397fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        for (int i = 0; i < ARRAY_SIZE; i++) {
40c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            mArray[i * 4] = i * 7;
41c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            mArray[i * 4 + 1] = i * 7 + 1;
42c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            mArray[i * 4 + 2] = i * 7 + 2;
43c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang            mArray[i * 4 + 3] = i * 7 + 3;
447fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        }
457fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    }
467fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
477fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // This test tests ScriptGroup2 API for handling gather scatter operations
487fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // on global allocations that are passed across kernels in a script group.
497fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // The test sums up all elements in the input int4 array of size ARRAY_SIZE.
507fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // To do so, it adds up the second half of the array to its first half using
517fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // kernel function add() in addsup.rs, and then repeatedly applies the same
527fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // kernel function to the shrinking result arrays until the result is a
537fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // single int4 value.
547fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // These steps are created as a script group by repeatedly adding the
557fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // same kernel function, with the input of one kernel being the output of
567fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // the previous added kernel function.
577fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // Since the kernel function relies on rsGetElementAt to access the counterpart
587fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // of the current element in the second half of the array, the compiler cannot
597fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // fuse it with the other kernel that it dependes on.
607fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // This test verifies an ScriptGroup2 implementation correctly handles such
617fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    // a case.
627fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    public void run() {
637fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        RenderScript pRS = RenderScript.create(mCtx);
647fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        ScriptC_addup s = new ScriptC_addup(pRS);
657fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        pRS.setMessageHandler(mRsMessage);
667fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        initializeGlobals(pRS, s);
677fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
687fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        Allocation input = Allocation.createSized(pRS, Element.I32_4(pRS), ARRAY_SIZE);
697fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        input.copyFrom(mArray);
707fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
71bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni        ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(pRS);
727fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
73bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni        ScriptGroup.Input unbound = builder.addInput();
747fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
75bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni        ScriptGroup.Closure c = null;
76bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni        ScriptGroup.Future f = null;
777fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        int stride;
787fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        for (stride = ARRAY_SIZE / 2; stride >= 1; stride >>= 1) {
79bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni            ScriptGroup.Binding binding;
807fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            if (f == null) {
81bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni                binding = new ScriptGroup.Binding(s.getFieldID_a_in(), unbound);
827fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            } else {
83bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni                binding = new ScriptGroup.Binding(s.getFieldID_a_in(), f);
847fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            }
857fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            c = builder.addKernel(s.getKernelID_add(),
86c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    Type.createX(pRS, Element.I32_4(pRS), stride),
87c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    new ScriptGroup.Binding(s.getFieldID_reduction_stride(), stride),
88c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    binding);
897fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            f = c.getReturn();
907fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        }
917fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
92bef00fb73762f13d6e3074effe9f6f30c03eeeb0Yang Ni        ScriptGroup group = builder.create("Summation", c.getReturn());
937fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
947fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        if (c == null) {
957fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            return;
967fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        }
977fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
987fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        int[] a = new int[4];
99c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang        ((Allocation) group.execute(input)[0]).copyTo(a);
1007fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
1017fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        pRS.finish();
1021c3a11a3287d971458a021d16a54e16b37f391f9Yang Ni
1031c3a11a3287d971458a021d16a54e16b37f391f9Yang Ni        group.destroy();
1041c3a11a3287d971458a021d16a54e16b37f391f9Yang Ni        input.destroy();
1051c3a11a3287d971458a021d16a54e16b37f391f9Yang Ni        s.destroy();
1067fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        pRS.destroy();
1077fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni
1087fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        boolean failed = false;
1097fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        for (int i = 0; i < 4; i++) {
1107fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            if (failed == false &&
111c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                    a[i] != ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2 + i * ARRAY_SIZE) {
112c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                Log.e(TAG, "a[" + i + "]=" + a[i] + ", should be " +
113c619e32616d4f6f02fb4bc74a6e6907270fc7c4eMiao Wang                        (ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2 + i * ARRAY_SIZE));
1147fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni                failed = true;
1157fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            }
1167fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        }
1177fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        if (failed) {
1187fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            failTest();
1197fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni            return;
1207fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        }
1217fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni        passTest();
1227fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni    }
1237fa7a5b18fe3f693ab1ca43de70937440759bdbdYang Ni}
124