/*  TESTING OF THE REMOTE_ACCESS DIRECTIVE AND THE REMOTE_ACCESS CLAUSE'.
    DISTRIBUTED ARRAY A(N,M,K) OR ELEMENTS OF THIS ARRAY ARE REPLICATED
    ON ALL PROCESSORS. */
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define N 16
#define M 8
#define K 8
#define NL 1000

static void rem3101();
static void rem3102();
static void rem3103();
static void rem3104();
static void rem3105();
static void rem3106();
static void rem3107();
static void rem3108();
static void rem3109();
static void rem3110();
static void rem3111();
static void rem3112();
static void rem3113();
static void ansyes(const char tname[]);
static void ansno(const char tname[]);
static void serial3(int AR[N][M][K], int NN, int NM, int NK, int NNL);

int main(int an, char **as) {
  printf("===START OF REM31========================\n");
  rem3101();
  rem3102();
  rem3103();
  rem3104();
  rem3105();
  rem3106();
  rem3107();
  rem3108();
  rem3109();
  rem3110();
  rem3111();
  rem3112();
  rem3113();

  printf("=== END OF REM31 ========================= \n");
  return 0;
}
/* ---------------------------------------------REM3101  */
void rem3101() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3101";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A[0][0][0])
#pragma dvm remote_access(A[0][0][0])
  { ib = A[0][0][0]; }
  if (ib == C[0][0][0])
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3102  */
void rem3102() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3102";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A[N - 1][M - 1][K - 1])
#pragma dvm remote_access(A[N - 1][M - 1][K - 1])
  { ib = A[N - 1][M - 1][K - 1]; }
  if (ib == C[N - 1][M - 1][K - 1])
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3103  */
void rem3103() {

  int C[N][M][K];
  int nloop, ib, isuma, isumc;
  char tname[] = "REM3103";

  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];
  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;
  isuma = 0;
  isumc = 0;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A[][][])
#pragma dvm remote_access(A[][][])
  {
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          isumc = isumc + C[i][j][ii];
          isuma = isuma + A[i][j][ii];
        }
  }
  if (isuma == isumc)
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3104  */
void rem3104() {

  int C[N][M][K];
  int nloop, ib, isuma, isumc;
  char tname[] = "REM3104";

  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];
  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;
  isuma = 0;
  isumc = 0;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A[0][][])
#pragma dvm remote_access(A[0][][])
  {
    for (j = 0; j < M; j++)
      for (ii = 0; ii < K; ii++) {
        isumc = isumc + C[0][j][ii];
        isuma = isuma + A[0][j][ii];
      }
  }
  if (isuma == isumc)
    ansyes(tname);
  else
    ansno(tname);
}

/* ---------------------------------------------REM3105  */
void rem3105() {

  int C[N][M][K];
  int nloop, ib, isuma, isumc;
  char tname[] = "REM3105";

  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];
  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;
  isuma = 0;
  isumc = 0;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A[][M - 1][])
#pragma dvm remote_access(A[][M - 1][])
  {
    for (i = 0; i < N; i++)
      for (ii = 0; ii < K; ii++) {
        isumc = isumc + C[i][M - 1][ii];
        isuma = isuma + A[i][M - 1][ii];
      }
  }
  if (isuma == isumc)
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3106  */
void rem3106() {

  int C[N][M][K];
  int nloop, ib, isuma, isumc;
  char tname[] = "REM3106";

  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];
  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;
  isuma = 0;
  isumc = 0;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A[][][K - 1])
#pragma dvm remote_access(A[][][K - 1])
  {
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++) {
        isumc = isumc + C[i][j][K - 1];
        isuma = isuma + A[i][j][K - 1];
      }
  }
  if (isuma == isumc)
    ansyes(tname);
  else
    ansno(tname);
}

/* ---------------------------------------------REM3107  */
void rem3107() {

  int C[N][M][K];
  int nloop, ib, isuma, isumc;
  int ki, ki1, kj, kj1, kii, kii1;
  char tname[] = "REM3107";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];
  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;
  isuma = 0;
  isumc = 0;

#pragma dvm region out(A)
  {

#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
  }
#pragma dvm get_actual(A)
  ki = 2;
  ki1 = 3;
  kj = 2;
  kj1 = 3;
  kii = 2;
  kii1 = 3;
  for (i = 0; i < N / ki - ki1; i++)
    for (j = 0; j < M / kj - kj1; j++)
      for (ii = 0; ii < K / kii - kii1; ii++) {
#pragma dvm remote_access(A[ki * i + ki1][kj * j + kj1][kii * ii + kii1])
        { isuma = isuma + A[ki * i + ki1][kj * j + kj1][kii * ii + kii1]; }
        isumc = isumc + C[ki * i + ki1][kj * j + kj1][kii * ii + kii1];
      }

  if (isuma == isumc)
    ansyes(tname);
  else
    ansno(tname);
  return;
}

/* ---------------------------------------------REM3108  */
void rem3108() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3108";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region local(A, B)
  {

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

#pragma dvm parallel([i][j][ii] on B[i][j][ii]) remote_access(A[0][0][0])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {

          B[i][j][ii] = A[0][0][0];
        }
#pragma dvm parallel([i][j][ii] on B[i][j][ii]) reduction(min(nloop))
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          if (B[i][j][ii] != C[0][0][0])
            nloop = i;
        }
  }
#pragma dvm get_actual(nloop)
  if (nloop == NL)
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3109  */
void rem3109() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3109";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region local(A, B)
  {
#pragma dvm parallel([i][j][ii] on A[i][j][ii])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          A[i][j][ii] = NL + i + j + ii;
        }
#pragma dvm parallel([i][j][ii] on B[i][j][ii])                                \
    remote_access(A[N - 1][M - 1][K - 1])
  for (i = 0; i < N; i++)
    for (j = 0; j < M; j++)
      for (ii = 0; ii < K; ii++) {

        B[i][j][ii] = A[N - 1][M - 1][K - 1];
      }
#pragma dvm parallel([i][j][ii] on B[i][j][ii]) reduction(min(nloop))
  for (i = 0; i < N; i++)
    for (j = 0; j < M; j++)
      for (ii = 0; ii < K; ii++) {
        if (B[i][j][ii] != C[N - 1][M - 1][K - 1])
          nloop = i;
      }
  }
  if (nloop == NL)
    ansyes(tname);
  else
    ansno(tname);
}

/* ---------------------------------------------REM3110  */
void rem3110() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3110";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region local(A, B)
  {

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

#pragma dvm parallel([i][j][ii] on B[i][j][ii]) remote_access(A[][][])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
            B[i][j][ii] = A[i][j][ii];
        }
#pragma dvm parallel([i][j][ii] on B[i][j][ii]) reduction(min(nloop))
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          if (B[i][j][ii] != C[i][j][ii])
            nloop = i;
        }
  }
#pragma dvm get_actual(nloop)
  if (nloop == NL)
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3111  */
void rem3111() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3111";

  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region local(A, B)
  {

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

#pragma dvm parallel([i][j][ii] on B[i][j][ii]) remote_access(A[0][][])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {

          B[i][j][ii] = A[0][j][ii];
        }
#pragma dvm parallel([i][j][ii] on B[i][j][ii]) reduction(min(nloop))
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          if (B[i][j][ii] != C[0][j][ii])
            nloop = i;
        }
  }
#pragma dvm get_actual(nloop)
  if (nloop == NL)
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3112  */
void rem3112() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3112";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region local(A, B)
  {

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

#pragma dvm parallel([i][j][ii] on B[i][j][ii]) remote_access(A[][M - 1][])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          B[i][j][ii] = A[i][M - 1][ii];
        }
#pragma dvm parallel([i][j][ii] on B[i][j][ii]) reduction(min(nloop))
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          if (B[i][j][ii] != C[i][M - 1][ii])
            nloop = i;
        }
  }
#pragma dvm get_actual(nloop)
  if (nloop == NL)
    ansyes(tname);
  else
    ansno(tname);
}
/* ---------------------------------------------REM3113  */
void rem3113() {

  int C[N][M][K];
  int nloop, ib;
  char tname[] = "REM3113";
  int i, j, ii, NN, NM, NK, NNL;

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

#pragma dvm array align([i][j][ii] with B[i][j][ii])
  int A[N][M][K];

  NN = N;
  NM = M;
  NK = K;
  NNL = NL;
  serial3(C, NN, NM, NK, NNL);
  nloop = NL;

#pragma dvm region local(A, B)
  {

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

#pragma dvm parallel([i][j][ii] on B[i][j][ii]) remote_access(A[][][K - 1])
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {

          B[i][j][ii] = A[i][j][K - 1];
        }
#pragma dvm parallel([i][j][ii] on B[i][j][ii]) reduction(min(nloop))
    for (i = 0; i < N; i++)
      for (j = 0; j < M; j++)
        for (ii = 0; ii < K; ii++) {
          if (B[i][j][ii] != C[i][j][K - 1])
            nloop = i;
        }
  }
#pragma dvm get_actual(nloop)
  if (nloop == NL)
    ansyes(tname);
  else
    ansno(tname);
}
void serial3(int AR[N][M][K], int NN, int NM, int NK, int NNL) {
  int i, j, ii;

  for (i = 0; i < NN; i++)
    for (j = 0; j < NM; j++)
      for (ii = 0; ii < NK; ii++)

      {
        AR[i][j][ii] = NNL + i + j + ii;
      }
}

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