/*      TESTING OF THE OWN CALCULASHION
        FOR DISTRIBUTED ARRAY A[N][M].
*/

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

#define N 32
#define M 32
#define NL 1000

static void owncal2101();
static void owncal2102();
static void owncal2103();
static void owncal2104();
static void owncal2105();
static void owncal2106();
static void owncal2107();
static void owncal2108();
static void owncal2109();
static void owncal2110();

static void serial2(int AR[][M], int NN, int NM, int NNL);
static void ansyes(const char tname[]);
static void ansno(const char tname[]);

int main(int argc, char *argv[])
{
    printf("===START OF OWNCAL21========================\n");
    owncal2101();
    owncal2102();
    owncal2103();
    owncal2104();
    owncal2105();
    owncal2106();
    owncal2107();
    owncal2108();
    owncal2109();
    owncal2110();

    printf("=== END OF OWNCAL21 ========================= \n");
    return 0;
}
/* ---------------------------------------------OWNCAL2101  */
void owncal2101()
{
    int C[N][M];
    char tname[] = "OWN2101";
    int i, j, NN, NM, NNL, nloopi, nloopj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A)
    {
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;
    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2102  */
void owncal2102()
{
    int C[N][M];
    char tname[] = "OWN2102";
    int i, j, NN, NM, NNL, nloopi, nloopj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    C[0][0] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[0][0] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2103  */
void owncal2103()
{
    int C[N][M];
    char tname[] = "OWN2103";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    ni = N / 2;
    nj = M / 2;
    C[ni][nj] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;
    #pragma dvm actual(ni,nj)

    #pragma dvm region out(A), in(ni, nj)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[ni][nj] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2104  */
void owncal2104()
{
    int  C[N][M];
    char tname[] = "OWN2104";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    ni = N / 2;
    nj = M / 2;
    C[ni + 1][nj + 1] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A), in(ni, nj)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[ni + 1][nj + 1] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2105  */
void owncal2105()
{
    int C[N][M];
    char tname[] = "OWN2105";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    ni = N / 2;
    nj = M / 2 ;
    C[ni - 1][nj - 1] = -(N + M + NL + 1);

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A), in(ni, nj)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[ni - 1][nj - 1] = -(N + M + NL + 1);

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2106  */
void owncal2106()
{
    int C[N][M];
    char tname[] = "OWN2106";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    ni = N / 2;
    nj = M / 2 ;
    C[ni + 1][nj - 1] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A), in(ni, nj)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[ni + 1][nj - 1] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2107  */
void owncal2107()
{
    int C[N][M];
    char tname[] = "OWN2107";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    ni = N / 2;
    nj = M / 2 ;
    C[ni - 1][nj + 1] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A), in(ni, nj)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[ni - 1][nj + 1] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2108  */
void owncal2108()
{
    int C[N][M];
    char tname[] = "OWN2108";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);

    C[0][M - 1] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[0][M - 1] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2109  */
      void owncal2109()
{
    int C[N][M];
    char tname[] = "OWN2109";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    C[N - 1][0] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[N - 1][0] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL2110  */
void owncal2110()
{
    int C[N][M];
    char tname[] = "OWN2110";
    int i, j, NN, NM, NNL, nloopi, nloopj, ni, nj;

    #pragma dvm array distribute[block][block]
    int A[N][M];

    NN = N;
    NM = M;
    NNL = NL;

    serial2(C, NN, NM, NNL);
    nj = M / 2;
    C[0][nj + 1] = N + M + NL + 1;

    nloopi = NL;
    nloopj = NL;

    #pragma dvm region out(A), in(nj)
    {
    #pragma dvm parallel([i][j] on A[i][j])
    for (i = 0; i < N; i++)
        for (j = 0; j < M; j++)
            A[i][j] = NL + i + j;

    A[0][nj + 1] = N + M + NL + 1;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i][j] on A[i][j]) reduction(min(nloopi), min(nloopj))
    for (i = 1; i < N - 1; i++)
        for (j = 1; j < M - 1; j++)
            if (A[i][j] != C[i][j]) {
                if (nloopi > i) nloopi = i;
                if (nloopj > j) nloopj = j;
            }
    if (nloopi == NL && nloopj == NL)
        ansyes(tname);
    else
        ansno(tname);
}

void serial2(int AR[][M], int NN, int NM, int NNL)
{
    int i, j;
    for (i = 0; i < NN; i++)
        for (j = 0; j < NM; j++)
            AR[i][j] = NNL + i + j;
}

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

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