/*    ALIGN22
TESTING align CLAUSE*/

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

static void align221();
static void align222();
static void align223();
static void align224();
static void align225();
static void align2251();
static void align226();
static void align227();

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

static int NL = 10000;
static int ER = 100000;
static int s, cs, erri, i, j, ia, ja, ib, jb;

int main(int an, char **as)
{
    printf("=== START OF ALIGN22 ======================\n");
            /* ALIGN arrB[i][j] WITH arrA[i][j] normal*/
    align221();
            /* ALIGN arrB[i][j] WITH arrA[i][2 * j] stretching along j*/
    align222();
            /* ALIGN arrB[i][j] WITH arrA[i + 4][j] shift along i*/
    align223();
             /* ALIGN arrB[i][j] WITH arrA[-i + 9][j] reverse on i*/
//    align224();
             /* ALIGN arrB[i][j] WITH arrA[i + 4][j + 4] shift along i and j*/
    align225();
             /*  */
    align2251();
             /* ALIGN arrB[i][j] WITH arrA[j][i] rotation*/
    align226();
             /* ALIGN arrB[i][j] WITH arrA[j + 1][i] rotation and shift*/
    align227();

    printf("=== END OF ALIGN22 ========================\n");
    return 0;
}
/* ---------------------------------------------ALIGN221*/
/* ALIGN arrB[i][j] WITH arrA[i][j] normal*/
void align221()
{
/*     parameters for ALIGN arrB[i][j] WITH arrA[k1i * i + li][k2j * j + lj]*/
    #define AN1 8
    #define AN2 8
    #define BN1 8
    #define BN2 8
    int k1i = 1, k2i = 0, li = 0;
    int k1j = 0, k2j = 1, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k1i * i + li][k2j * j + lj])
    int B2[BN1][BN2];
    char tname[] = "align221 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for(j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k1i) * k1i)) &&
                ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                (((i - li) / k1i) >= 0) &&
                (((j - lj) / k2j) >= 0) &&
                (((i - li) / k1i) < BN1) &&
                (((j - lj) / k2j) < BN2))
            {
                ib = (i - li) / k1i;
                jb = (j - lj) / k2j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k1i * i + li;
            ja = k2j * j + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN222*/
/* ALIGN arrB[i][j] WITH arrA[i][2*j] stretching along j*/
void align222()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k1i * i + li][k2j * j + lj]*/
    #define AN1 8
    #define AN2 8
    #define BN1 8
    #define BN2 4
    int k1i = 1, k2i = 0, li = 0;
    int k1j = 0, k2j = 2, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k1i * i + li][k2j * j + lj])
    int B2[BN1][BN2];
    char tname[] = "align222 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for(j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k1i) * k1i)) &&
                ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                (((i - li) / k1i) >= 0) &&
                (((j - lj) / k2j) >= 0) &&
                (((i - li) / k1i) < BN1) &&
                (((j - lj) / k2j) < BN2))
            {
                ib = (i - li) / k1i;
                jb = (j - lj) / k2j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k1i * i + li;
            ja = k2j * j + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN223*/
/* ALIGN arrB[i][j] WITH arrA[i+4][j] shift along i*/
void align223()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k1i * i + li][k2j * j + lj]*/
    #define AN1 8
    #define AN2 8
    #define BN1 4
    #define BN2 8
    int k1i = 1, k2i = 0, li = 4;
    int k1j = 0, k2j = 1, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k1i * i + li][k2j * j + lj])
    int B2[BN1][BN2];
    char tname[] = "align223 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for(j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k1i) * k1i)) &&
                ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                (((i - li) / k1i) >= 0) &&
                (((j - lj) / k2j) >= 0) &&
                (((i - li) / k1i) < BN1) &&
                (((j - lj) / k2j) < BN2))
            {
                ib = (i - li) / k1i;
                jb = (j - lj) / k2j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k1i * i + li;
            ja = k2j * j + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN224*/
/* ALIGN arrB[i][j] WITH arrA[-i+9][j]  reverse on i*/
void align224()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k1i * i + li][k2j * j + lj]*/
    #define AN1 10
    #define AN2 8
    #define BN1 8
    #define BN2 8
    int k1i = -1, k2i = 0, li = 9;
    int k1j = 0, k2j = 1, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k1i * i + li][k2j * j + lj])
    int B2[BN1][BN2];
    char tname[] = "align224 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for(j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k1i) * k1i)) &&
                ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                (((i - li) / k1i) >= 0) &&
                (((j - lj) / k2j) >= 0) &&
                (((i - li) / k1i) < BN1) &&
                (((j - lj) / k2j) < BN2))
            {
                ib = (i - li) / k1i;
                jb = (j - lj) / k2j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k1i * i + li;
            ja = k2j * j + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN225*/
/* ALIGN arrB[i][j] WITH arrA[i+4][j+4]shift along i and j*/
void align225()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k1i * i + li][k2j * j + lj]*/
    #define AN1 8
    #define AN2 8
    #define BN1 4
    #define BN2 4
    int k1i = 1, k2i = 0, li = 4;
    int k1j = 0, k2j = 1, lj = 4;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k1i * i + li][k2j * j + lj])
    int B2[BN1][BN2];
    char tname[] = "align225 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for(j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k1i) * k1i)) &&
                ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                (((i - li) / k1i) >= 0) &&
                (((j - lj) / k2j) >= 0) &&
                (((i - li) / k1i) < BN1) &&
                (((j - lj) / k2j) < BN2))
            {
                ib = (i - li) / k1i;
                jb = (j - lj) / k2j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k1i * i + li;
            ja = k2j * j + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN2251*/
/* ALIGN arrB[i][j] WITH arrA[i+1][2*j] small arrays*/
void align2251()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k1i * i + li][k2j * j + lj]*/
    #define AN1 3
    #define AN2 5
    #define BN1 2
    #define BN2 3
    int k1i = 1, k2i = 0, li = 1;
    int k1j = 0, k2j = 2, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k1i * i + li][k2j * j + lj])
    int B2[BN1][BN2];
    char tname[] = "align2251";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for(j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k1i) * k1i)) &&
                ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                (((i - li) / k1i) >= 0) &&
                (((j - lj) / k2j) >= 0) &&
                (((i - li) / k1i) < BN1) &&
                (((j - lj) / k2j) < BN2))
            {
                ib = (i - li) / k1i;
                jb = (j - lj) / k2j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k1i * i + li;
            ja = k2j * j + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN226*/
/* ALIGN arrB[i][j] WITH arrA[j][i] rotation*/
void align226()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k2i * j + li][k1j * i + lj]*/
    #define AN1 4
    #define AN2 4
    #define BN1 4
    #define BN2 4
    int k1i = 0, k2i = 1, li = 0;
    int k1j = 1, k2j = 0, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k2i * j + li][k1j * i + lj])
    int B2[BN1][BN2];
    char tname[] = "align226 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k2i) * k2i)) &&
                ((j - lj) == (((j - lj) / k1j) * k1j)) &&
                (((i - li) / k2i) >= 0) &&
                (((j - lj) / k1j) >= 0) &&
                (((i - li) / k2i) < BN2) &&
                (((j - lj) / k1j) < BN1))
            {
                jb = (i - li) / k2i;
                ib = (j - lj) / k1j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k2i * j + li;
            ja = k1j * i + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

    if (erri == ER)
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef BN1
    #undef BN2
}
/* ---------------------------------------------ALIGN227*/
/* ALIGN arrB[i][j] WITH arrA[j+1][i] rotation and shift*/
void align227()
{
/*    parameters for ALIGN arrB[i][j] WITH arrA[k2i*j+li][k1j*i+lj]*/
    #define AN1 8
    #define AN2 8
    #define BN1 4
    #define BN2 4
    int k1i = 0, k2i = 1, li = 1;
    int k1j = 1, k2j = 0, lj = 0;

    #pragma dvm array distribute[block][block]
    int A2[AN1][AN2];
    #pragma dvm array align([i][j] with A2[k2i * j + li][k1j * i + lj])
    int B2[BN1][BN2];
    char tname[] = "align227 ";

    erri = ER;

    #pragma dvm actual(erri)
    #pragma dvm region local(A2, B2)
    {
    #pragma dvm parallel([i][j] on B2[i][j])
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
            B2[i][j] = 0;
    #pragma dvm parallel([i][j] on A2[i][j]) private(ib, jb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
        {
            A2[i][j] = i * NL + j;
            if (((i - li) == (((i - li) / k2i) * k2i)) &&
                ((j - lj) == (((j - lj) / k1j) * k1j)) &&
                (((i - li) / k2i) >= 0) &&
                (((j - lj) / k1j) >= 0) &&
                (((i - li) / k2i) < BN2) &&
                (((j - lj) / k1j) < BN1))
            {
                jb = (i - li) / k2i;
                ib = (j - lj) / k1j;
                B2[ib][jb] = ib * NL + jb;
            }
        }
    #pragma dvm parallel([i][j] on B2[i][j]) reduction(min(erri)), private(ia, ja)
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
        {
            if (B2[i][j] != (i * NL + j))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
            ia = k2i * j + li;
            ja = k1j * i + lj;
            if (A2[ia][ja] != (ia * NL + ja))
                if (erri > i * NL / 10 + j) erri = i * NL / 10 + j;
        }

    }
    #pragma dvm get_actual(erri)

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

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

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