import jdk.incubator.vector.*;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.IntFunction;
import java.util.stream.IntStream;

public class Test {

    static final int INVOC_COUNT = Integer.getInteger("jdk.incubator.vector.test.loop-iterations", 200);

    static VectorSpecies<Byte> SPECIES = ByteVector.SPECIES_512;

    static byte TESTING_BYTE = 7;

    static byte[] getBytes() {
        byte[] a = new byte[SPECIES.length()];
        for (int i = 0; i < a.length; i++) {
            a[i] = TESTING_BYTE;
        }
        return a;
    }

    static boolean[] getMask() {
        boolean[] a = new boolean[SPECIES.length()];
        for (int i = 0; i < a.length; i++) {
            a[i] = (i % 5) == 0;
        }
        return a;
    }

    public static void main(String[] args) {
        for (int i = 0; i < 500; i++) {
            MULReduceByteNNNVectorTestsMasked();
        }
    }

    static void MULReduceByteNNNVectorTestsMasked() {
        byte[] a = getBytes(); // cornerCaseValue(i));
        byte[] r = new byte[a.length];
        boolean[] mask = getMask();
        VectorMask<Byte> vmask = VectorMask.fromArray(SPECIES, mask, 0);

        for (int ic = 0; ic < INVOC_COUNT * INVOC_COUNT; ic++) {
            for (int i = 0; i < a.length; i += SPECIES.length()) {
                ByteVector av = ByteVector.fromArray(SPECIES, a, i);
                r[i] = av.reduceLanes(VectorOperators.MUL, vmask);
            }
        }

        check(r, a, mask);
    }

    static byte MULReduceMasked(byte[] a, int idx, boolean[] mask) {
        byte res = 1;
        for (int i = idx; i < (idx + SPECIES.length()); i++) {
            if (mask[i % SPECIES.length()])
                res *= a[i];
        }
        return res;
    }

    static void check(byte[] r, byte[] a, boolean[] mask) {
		for (int i = 0; i < a.length; i += SPECIES.length()) {
			int result = MULReduceMasked(a, i, mask);
			if (r[i] != result) {
				throw new RuntimeException(" r[i]: " + r[i] + " not equal result: " + result);
			}

		}
	}
}
