/*    ALIGN11
TESTING align CLAUSE */

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

static void align111();
static void align1111();
static void align1112();
static void align112();
static void align113();
static void align114();
static void align115();

static void ansyes(const char tname[]);
static void ansno(const char tname[]);

static int NL = 1000;
static int ER = 10000;
static int erri, i, j, ia, ib;

int main(int an, char **as)
{
    printf("=== START OF ALIGN11 ======================\n");
        /* ALIGN arrB[i] WITH arrA[i] normal*/
    align111();
        /* ALIGN arrB[i] WITH arrA[i] small array*/
    align1111();
        /* ALIGN arrB[i] WITH arrA[2 * i+3] small array*/
    align1112();
        /* ALIGN arrB[i] WITH arrA[i + 4] shift along i*/
    align112();
        /* ALIGN arrB[i] WITH arrA[-i + 7] reverse on i*/
//    align113();
        /* ALIGN arrB[i] WITH arrA[2 * i + 8] stretching along i*/
    align114();
        /* ALIGN arrB[] WITH arrA[]*/
    align115();

    printf("=== END OF ALIGN11 ========================\n");
    return 0;
}
/* ---------------------------------------------ALIGN111*/
/* ALIGN arrB[i] WITH arrA[i] normal*/
void align111()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 8
    #define BN1 8
    int k1i = 1;
    int li = 0;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([i] with A1[k1i * i + li])
    int B1[BN1];
    char tname[] = "align111 ";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = 0;
    #pragma dvm parallel([i] on A1[i]) private(ib)
    for (i = 0; i < AN1; i++)
    {
        A1[i] = i;
        if (((i - li) == (((i - li) / k1i) * k1i)) &&
            (((i - li) / k1i) >= 0) &&
            (((i - li) / k1i) < BN1))
        {
            ib = (i - li) / k1i;
            B1[ib] = ib;
        }
    }
    #pragma dvm parallel([i] on B1[i]) reduction(min(erri)), private(ia)
    for (i = 0; i < BN1; i++)
    {
        if (B1[i] != i)
            if (erri > i) erri = i;
        ia = k1i * i + li;
        if (A1[ia] != ia)
            if (erri > i) erri = i;
    }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}
/* ---------------------------------------------ALIGN1111*/
/* ALIGN arrB[i] WITH arrA[i] small array*/
void align1111()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 5
    #define BN1 2
    int k1i = 1;
    int li = 0;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([i] with A1[k1i * i + li])
    int B1[BN1];
    char tname[] = "align1111";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = 0;
    #pragma dvm parallel([i] on A1[i]) private(ib)
    for (i = 0; i < AN1; i++)
    {
        A1[i] = i;
        if (((i - li) == (((i - li) / k1i) * k1i)) &&
            (((i - li) / k1i) >= 0) &&
            (((i - li) / k1i) < BN1))
        {
            ib = (i - li) / k1i;
            B1[ib] = ib;
        }
    }
    #pragma dvm parallel([i] on B1[i]) reduction(min(erri)), private(ia)
    for (i = 0; i < BN1; i++)
    {
        if (B1[i] != i)
            if (erri > i) erri = i;
        ia = k1i * i + li;
        if (A1[ia] != ia)
            if (erri > i) erri = i;
    }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}
/* ---------------------------------------------ALIGN1112*/
/* ALIGN arrB[i] WITH arrA[2 * i + 1] small array*/
void align1112()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 5
    #define BN1 2
    int k1i = 2;
    int li  = 1;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([i] with A1[k1i * i + li])
    int B1[BN1];
    char tname[] = "align1112";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = 0;
    #pragma dvm parallel([i] on A1[i]) private(ib)
    for (i = 0; i < AN1; i++)
    {
        A1[i] = i;
        if (((i - li) == (((i - li) / k1i) * k1i)) &&
            (((i - li) / k1i) >= 0) &&
            (((i - li) / k1i) < BN1))
        {
            ib = (i - li) / k1i;
            B1[ib] = ib;
        }
    }
    #pragma dvm parallel([i] on B1[i]) reduction(min(erri)), private(ia)
    for (i = 0; i < BN1; i++)
    {
        if (B1[i] != i)
            if (erri > i) erri = i;
        ia = k1i * i + li;
        if (A1[ia] != ia)
            if (erri > i) erri = i;
    }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}
/* ---------------------------------------------ALIGN112*/
/* ALIGN arrB[i] WITH arrA[i + 4] shift along i*/
void align112()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 8
    #define BN1 4
    int k1i = 1;
    int li  = 4;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([i] with A1[k1i * i + li])
    int B1[BN1];
    char tname[] = "align112 ";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = 0;
    #pragma dvm parallel([i] on A1[i]) private(ib)
    for (i = 0; i < AN1; i++)
    {
        A1[i] = i;
        if (((i - li) == (((i - li) / k1i) * k1i)) &&
            (((i - li) / k1i) >= 0) &&
            (((i - li) / k1i) < BN1))
        {
            ib = (i - li) / k1i;
            B1[ib] = ib;
        }
    }
    #pragma dvm parallel([i] on B1[i]) reduction(min(erri)), private(ia)
    for (i = 0; i < BN1; i++)
    {
        if (B1[i] != i)
            if (erri > i) erri = i;
        ia = k1i * i + li;
        if (A1[ia] != ia)
            if (erri > i) erri = i;
    }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}
/* ---------------------------------------------ALIGN113*/
/* ALIGN arrB[i] WITH arrA[-i + 7] reverse on i*/
void align113()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 8
    #define BN1 8
    int k1i = -1;
    int li = 7;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([i] with A1[k1i * i + li])
    int B1[BN1];
    char tname[] = "align113 ";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = 0;
    #pragma dvm parallel([i] on A1[i]) private(ib)
    for (i = 0; i < AN1; i++)
    {
        A1[i] = i;
        if (((i - li) == (((i - li) / k1i) * k1i)) &&
            (((i - li) / k1i) >= 0) &&
            (((i - li) / k1i) < BN1))
        {
            ib = (i - li) / k1i;
            B1[ib] = ib;
        }
    }
    #pragma dvm parallel([i] on B1[i]) reduction(min(erri)), private(ia)
    for (i = 0; i < BN1; i++)
    {
        if (B1[i] != i)
            if (erri > i) erri = i;
        ia = k1i * i + li;
        if (A1[ia] != ia)
            if (erri > i) erri = i;
    }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}
/* ---------------------------------------------ALIGN114*/
/* ALIGN arrB[i] WITH arrA[2 * i + 8] stretching along i*/
void align114()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 24
    #define BN1 8
    int k1i = 2;
    int li  = 8;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([i] with A1[k1i * i + li])
    int B1[BN1];
    char tname[] = "align114 ";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1), inout(erri)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = 0;
    #pragma dvm parallel([i] on A1[i]) private(ib)
    for (i = 0; i < AN1; i++)
    {
        A1[i] = i;
        if (((i - li) == (((i - li) / k1i) * k1i)) &&
            (((i - li) / k1i) >= 0) &&
            (((i - li) / k1i) < BN1))
        {
            ib = (i - li) / k1i;
            B1[ib] = ib;
        }
    }
    #pragma dvm parallel([i] on B1[i]) reduction(min(erri)), private(ia)
    for (i = 0; i < BN1; i++)
    {
        if (B1[i] != i)
            if (erri > i) erri = i;
        ia = k1i * i + li;
        if (A1[ia] != ia)
            if (erri > i) erri = i;
    }
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}
/* ---------------------------------------------ALIGN115*/
/* ALIGN arrB[] WITH arrA[]*/
void align115()
{
/*    parameters for ALIGN arrB[i] WITH arrA[k1i * i + li]*/
    #define AN1 24
    #define BN1 8
    int k1i = 0;
    int li  = 0;

    #pragma dvm array distribute[block]
    int A1[AN1];
    #pragma dvm array align([] with A1[])
    int B1[BN1];
    char tname[] = "align115 ";

    erri = ER;
    #pragma dvm actual(erri)
    #pragma dvm region local(A1, B1)
    {
    #pragma dvm parallel([i] on B1[i])
    for (i = 0; i < BN1; i++)
        B1[i] = i;
    #pragma dvm parallel([i] on A1[i]) reduction(min(erri)), private(j)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < BN1; j++)
            if (B1[j] != (j))
                if (erri > j) erri = j;
    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef BN1
}

void ansyes(const char name[])
{
    printf("%s  -  complete\n", name);
}

void ansno(const char name[])
{
    printf("%s  -  ***error\n", name);
}
