// This file is automatically generated from
// frameworks/rs/tests/java_api/RSUnitTests/RSUnitTests.py
/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */

package com.android.rs.unittest;

import android.content.Context;
import android.support.v8.renderscript.Allocation;
import android.support.v8.renderscript.Element;
import android.support.v8.renderscript.RenderScript;
import android.support.v8.renderscript.ScriptGroup;
import android.support.v8.renderscript.Type;
import android.util.Log;

public class UT_script_group2_gatherscatter extends UnitTest {
    private static final int ARRAY_SIZE = 256;

    private static final String TAG = "ScriptGroup2 (GatherScatter)";

    int[] mArray;

    public UT_script_group2_gatherscatter(Context ctx) {
        super(TAG, ctx);
    }

    public void initializeGlobals(RenderScript RS, ScriptC_addup s) {
        mArray = new int[ARRAY_SIZE * 4];

        for (int i = 0; i < ARRAY_SIZE; i++) {
            mArray[i * 4] = i * 7;
            mArray[i * 4 + 1] = i * 7 + 1;
            mArray[i * 4 + 2] = i * 7 + 2;
            mArray[i * 4 + 3] = i * 7 + 3;
        }
    }

    // This test tests ScriptGroup2 API for handling gather scatter operations
    // on global allocations that are passed across kernels in a script group.
    // The test sums up all elements in the input int4 array of size ARRAY_SIZE.
    // To do so, it adds up the second half of the array to its first half using
    // kernel function add() in addsup.rs, and then repeatedly applies the same
    // kernel function to the shrinking result arrays until the result is a
    // single int4 value.
    // These steps are created as a script group by repeatedly adding the
    // same kernel function, with the input of one kernel being the output of
    // the previous added kernel function.
    // Since the kernel function relies on rsGetElementAt to access the counterpart
    // of the current element in the second half of the array, the compiler cannot
    // fuse it with the other kernel that it dependes on.
    // This test verifies an ScriptGroup2 implementation correctly handles such
    // a case.
    public void run() {
        RenderScript pRS = createRenderScript(false);
        ScriptC_addup s = new ScriptC_addup(pRS);
        initializeGlobals(pRS, s);

        Allocation input = Allocation.createSized(pRS, Element.I32_4(pRS), ARRAY_SIZE);
        input.copyFrom(mArray);

        ScriptGroup.Builder2 builder = new ScriptGroup.Builder2(pRS);

        ScriptGroup.Input unbound = builder.addInput();

        ScriptGroup.Closure c = null;
        ScriptGroup.Future f = null;
        int stride;
        for (stride = ARRAY_SIZE / 2; stride >= 1; stride >>= 1) {
            ScriptGroup.Binding binding;
            if (f == null) {
                binding = new ScriptGroup.Binding(s.getFieldID_a_in(), unbound);
            } else {
                binding = new ScriptGroup.Binding(s.getFieldID_a_in(), f);
            }
            c = builder.addKernel(s.getKernelID_add(),
                    Type.createX(pRS, Element.I32_4(pRS), stride),
                    new ScriptGroup.Binding(s.getFieldID_reduction_stride(), stride),
                    binding);
            f = c.getReturn();
        }

        ScriptGroup group = builder.create("Summation", c.getReturn());

        if (c == null) {
            return;
        }

        int[] a = new int[4];
        ((Allocation) group.execute(input)[0]).copyTo(a);

        pRS.finish();

        group.destroy();
        input.destroy();
        s.destroy();
        pRS.destroy();

        boolean failed = false;
        for (int i = 0; i < 4; i++) {
            if (failed == false &&
                    a[i] != ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2 + i * ARRAY_SIZE) {
                Log.e(TAG, "a[" + i + "]=" + a[i] + ", should be " +
                        (ARRAY_SIZE * (ARRAY_SIZE - 1) * 7 / 2 + i * ARRAY_SIZE));
                failed = true;
            }
        }
        if (failed) {
            failTest();
            return;
        }
        passTest();
    }
}
