/*    ALIGN33
TESTING align CLAUSE*/

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

static void align331();
static void align332();

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, n, m, k, l, ia, ja, na, ma, ib, jb, nb, mb, Avalue, Bvalue;

int main(int an, char **as)
{
    printf("=== START OF ALIGN33 ======================\n");
            /* ALIGN arrB[i][j][k] WITH arrA[i][j][k] normal*/
    align331();
            /* ALIGN arrB[][i][] WITH arrA[][lj][i]*/
    align332();
    printf("=== END OF ALIGN33 ========================\n");
    return 0;
}
/* ---------------------------------------------ALIGN331*/
/* ALIGN arrB[i][j][n] WITH arrA[i][j][n] normal*/
void align331()
{
/*     parameters for ALIGN arrB[i][j][n]
                      WITH arrA[k1i*i+li][k2j*j+lj][k3n*n+ln]*/
    #define AN1 5
    #define AN2 5
    #define AN3 5
    #define BN1 2
    #define BN2 2
    #define BN3 2
    int k1i = 1, k2i = 0, k3i = 0, li = 0;
    int k1j = 0, k2j = 1, k3j = 0, lj = 0;
    int k1n = 0, k2n = 0, k3n = 1, ln = 0;

    #pragma dvm array distribute[block][block][block]
    int A3[AN1][AN2][AN3];
    #pragma dvm array align([i][j][n] with A3[k1i*i+li][k2j*j+lj][k3n*n+ln])
    int B3[BN1][BN2][BN3];
    char tname[] = "align331";

    erri = ER;
    s = 0;

    #pragma dvm actual(erri, s)
    #pragma dvm region local(A3, B3)
    {
    #pragma dvm parallel([i][j][n] on B3[i][j][n])
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
            for (n = 0; n < BN3; n++)
                B3[i][j][n] = 0;
    #pragma dvm parallel([i][j][n] on A3[i][j][n]) private(ib, jb, nb)
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
            for (n = 0; n < AN3; n++)
            {
                A3[i][j][n] = i * NL / 10 + j * NL / 100 + n * NL / 1000;
                if (((i - li) == (((i - li) / k1i) * k1i)) &&
                    ((j - lj) == (((j - lj) / k2j) * k2j)) &&
                    ((n - ln) == (((n - ln) / k3n) * k3n)) &&
                    (((i - li) / k1i) >= 0) &&
                    (((j - lj) / k2j) >= 0) &&
                    (((n - ln) / k3n) >= 0) &&
                    (((i - li) / k1i) < BN1) &&
                    (((j - lj) /k2j) < BN2) &&
                    (((n - ln) / k3n) < BN3))
                {
                    ib = (i - li) / k1i;
                    jb = (j - lj) / k2j;
                    nb = (n - ln) / k3n;
                    B3[ib][jb][nb] = ib * NL / 10 + jb * NL / 100 + nb * NL / 1000;
                }
            }

    #pragma dvm parallel([i][j][n] on B3[i][j][n]) reduction(min(erri), sum(s))
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
            for (n = 0; n < BN3; n++)
            {
                int val = i * NL / 10 + j * NL / 100 + n * NL / 1000;
                s = s + B3[i][j][n];
                if (B3[i][j][n] != val)
                    if (erri > val) erri = val;
            }

    }
    #pragma dvm get_actual(erri, s)

    cs = 0;
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
            for (n = 0; n < BN3; n++)
                cs = cs + i * NL / 10 + j * NL / 100 + n * NL / 1000;
    if ((erri == ER) && (s == cs))
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef AN3
    #undef BN1
    #undef BN2
    #undef BN3
}
/* ---------------------------------------------ALIGN332*/
/* ALIGN arrB[][i][] WITH arrA[][lj][i]*/
void align332()
{
/*     parameters for ALIGN arrB[][i][]
                      WITH arrA[][lj][k3n*n+ln]*/
    #define AN1 4
    #define AN2 4
    #define AN3 4
    #define BN1 2
    #define BN2 2
    #define BN3 2
    int k1i = 0, k2i = 0, k3i = 0, li = 0;
    int k1j = 0, k2j = 0, k3j = 0, lj = 3;
    int k1n = 1, k2n = 0, k3n = 0, ln = 0;

    #pragma dvm array distribute[block][block][block]
    int A3[AN1][AN2][AN3];
    #pragma dvm array align([][i][] with A3[][lj][k1n*i+ln])
    int B3[BN1][BN2][BN3];
    char tname[] = "align332";

    erri = ER;
    s = 0;

    #pragma dvm actual(erri, s)
    #pragma dvm region local(A3, B3)
    {
    #pragma dvm parallel([i][j][n] on B3[i][j][n])
    for (i = 0; i < BN1; i++)
        for (j = 0; j < BN2; j++)
            for (n = 0; n < BN3; n++)
                B3[i][j][n] = i * NL / 10 + j * NL / 100 + n * NL / 1000;
    #pragma dvm parallel([i][j][n] on A3[i][j][n]) private(ib, jb, nb, k, l), reduction(min(erri))
    for (i = 0; i < AN1; i++)
        for (j = 0; j < AN2; j++)
            for (n = 0; n < AN3; n++)
            {
                A3[i][j][n] = i * NL / 10 + j * NL / 100 + n * NL / 1000;
                if (j == lj)
                {
                    for (k = 0; k < BN1; k++)
                        for (l = 0; l < BN3; l++)
                        {
                            if (((n - ln) == (((n - ln) / k1n) * k1n)) &&
                                (((n - ln) / k1n) >= 0) &&
                                (((n - ln) / k1n) < BN2))
                            {
                                int val = i * NL / 10 + j * NL / 100 + n * NL / 1000;
                                ib = k;
                                jb = (n - ln) / k1n;
                                nb = l;
                                if (B3[ib][jb][nb] != ib * NL / 10 + jb * NL / 100 + nb * NL / 1000)
                                    if (erri > val) erri = val;
                            }
                        }
                }
            }

    }
    #pragma dvm get_actual(erri, s)

    cs = 0;
    if ((erri == ER) && (s == cs))
        ansyes(tname);
    else
        ansno(tname);
    #undef AN1
    #undef AN2
    #undef AN3
    #undef BN1
    #undef BN2
    #undef BN3
}

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

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