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

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

#define N 32
#define NL 1000

static void owncal1101();
static void owncal1102();
static void owncal1103();
static void owncal1104();
static void owncal1105();
static void owncal1106();

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

int main(int argc, char *argv[])
{
    printf("===START OF OWNCAL11========================\n");
    owncal1101();
    owncal1102();
    owncal1103();
    owncal1104();
    owncal1105();
    owncal1106();

    printf("=== END OF OWNCAL11 ========================= \n");
    return 0;
}
/* ---------------------------------------------OWNCAL1101  */
void owncal1101()
{
    int C[N];
    char tname[] = "OWN1101";
    int i, NN, NNL, nloopi;

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

    NN = N;
    NNL = NL;

    serial(C, NN, NNL);

    nloopi = NL;

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

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i] on A[i]) reduction(min(nloopi))
    for (i = 1; i < N - 1; i++)
        if (A[i] != C[i])
            if (nloopi > i) nloopi = i;
    if (nloopi == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL1102  */
void owncal1102()
{
    int C[N];
    char tname[] = "OWN1102";
    int i, NN, NNL, nloopi;

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

    NN = N;
    NNL = NL;

    serial(C, NN, NNL);
    C[0] = N + NL + 2;

    nloopi = NL;

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

    A[0]=N+NL+2;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i] on A[i]) reduction(min(nloopi))
    for (i = 1; i < N - 1; i++)
        if (A[i] != C[i])
            if (nloopi > i) nloopi = i;
    if (nloopi == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL1103  */
void owncal1103()
{
    int C[N];
    char tname[] = "OWN1103";
    int i, NN, NNL, nloopi, ni;

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

    NN = N;
    NNL = NL;

    serial(C, NN, NNL);
    ni = N / 2;
    C[ni] = N + NL + 3;

    nloopi = NL;
    #pragma dvm actual(ni)

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

    A[ni] = N + NL + 3;

    } /*end region*/

      #pragma dvm get_actual(A)

    #pragma dvm parallel([i] on A[i]) reduction(min(nloopi))
    for (i = 1; i < N - 1; i++)
        if (A[i] != C[i])
            if (nloopi > i) nloopi = i;
    if (nloopi == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL1104  */
void owncal1104()
{
    int C[N];
    char tname[] = "OWN1104";
    int i, NN, NNL, nloopi, ni;

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

    NN = N;
    NNL = NL;

    serial(C, NN, NNL);
    ni = N / 2;
    C[ni+1] = N + NL + 4;

    nloopi = NL;

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

    A[ni + 1] = N + NL + 4;

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i] on A[i]) reduction(min(nloopi))
    for (i = 1; i < N - 1; i++)
        if (A[i] != C[i])
            if (nloopi > i) nloopi = i;
    if (nloopi == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL1105  */
void owncal1105()
{
    int C[N];
    char tname[] = "OWN1105";
    int i, NN, NNL, nloopi, ni;

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

    NN = N;
    NNL = NL;

    serial(C, NN, NNL);
    ni = N / 2;
    C[ni - 1] = -(N + NL + 5);

    nloopi = NL;

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

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

    } /*end region*/

    #pragma dvm get_actual(A)

    #pragma dvm parallel([i] on A[i]) reduction(min(nloopi))
    for (i = 1; i < N - 1; i++)
        if (A[i] != C[i])
            if (nloopi > i) nloopi = i;
    if (nloopi == NL)
        ansyes(tname);
    else
        ansno(tname);
}
/* ---------------------------------------------OWNCAL1106  */
void owncal1106()
{
    int C[N];
    char tname[] = "OWN1106";
    int i, NN, NNL, nloopi, ni;

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

    NN = N;
    NNL = NL;

    serial(C, NN, NNL);
    C[N - 1] = N + NL + 6;

    nloopi = NL;

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

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

    } /*end region*/

    #pragma dvm get_actual(A)

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

void serial(int AR[], int NN, int NNL)
{
    int i;
    for (i = 0; i < NN; i++)
        AR[i] = NNL+i;
}

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

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