#ifndef ATLAS_MMTESTTIME_H
   #define ATLAS_MMTESTTIME_H

#include "atlas_mmparse.h"
#include "atlas_gentesttime.h"

int MMKernelFailsTest
(
   char pre,                    /* precision/type prefix */
   int mb, int nb, int kb,      /* dimensions to test */
   int beta,                    /* beta case to test */
   ATL_mmnode_t *umm            /* mmkern ptr */
)
/*
 * RETURNS: 0 on success, non-zero on failure
 */
{
   char ln[1024];
   int i, lda, ldb, ldc;
   char ch;

/*
 * If the file is generated, call generator to create it
 */
   if (umm->genstr)
   {
      if (system(umm->genstr))
      {
         fprintf(stderr, "ERROR, LINE %d of %s\n", __LINE__, __FILE__);
         fprintf(stderr, "UNABLE TO GENERATE WITH COMMAND: %s\n", umm->genstr);
         exit(-1);
      }
   }
   ldc = mb*2+4;
   if (FLAG_IS_SET(umm->flag, MMF_LDISKB))
      lda = ldb = kb;
   else if (FLAG_IS_SET(umm->flag, MMF_LDAB))
      lda = ldb = kb+8;
   else
   {
      lda = kb+4;
      ldb = kb+8;
   }
   if (pre == 'c' || pre == 'z')
      i = sprintf(ln, "make cmmutstcase mmrout=CASES/%s csC=2 ", umm->rout);
   else
      i = sprintf(ln, "make mmutstcase mmrout=CASES/%s ", umm->rout);
   if (umm->comp)
   {
      ch = (pre == 'c' || pre == 's') ? 'S' : 'D';
      i += sprintf(ln+i, "%cMC=\"%s\" %cMCFLAGS=\"%s\" ",
                   ch, umm->comp, ch, umm->flag);
   }
   i += sprintf(ln+i, "pre=%c M=%d N=%d K=%d mb=%d nb=%d kb=%d ",
                pre, mb, nb, kb,
                FLAG_IS_SET(umm->flag, MMF_MRUNTIME) ? 0 : mb,
                FLAG_IS_SET(umm->flag, MMF_NRUNTIME) ? 0 : nb,
                FLAG_IS_SET(umm->flag, MMF_KRUNTIME) ? 0 : kb);
   i += sprintf(ln+i, "lda=%d ldb=%d ldc=%d\n", lda, ldb, ldc);
   fprintf(stdout, "%s", ln);
   return(system(ln));
}

double TimeMMKernel
(
   int verb,                    /* 0: no output, 1 min output, 2: full output */
   int FORCETIME,               /* 1: ignore any prior output file */
   ATL_mmnode_t *mmp,           /* ptr to mmkern struct */
   char pre,                    /* type/prec prefix: z,c,d,s */
   int mb, int nb, int kb,      /* dimensions to time */
   int lda,                     /* >0: lda to use, else kb */
   int ldb,                     /* >0: ldb to use, else kb */
   int ldc,                     /* >0: ldc to use, else mb+8 */
   int beta,                    /* beta to time */
   int mflop,                   /* >0: force mflop MFLOPs in each time interv */
   int cflush                   /* >0: size of cache flush, else ignored */
)
{
   char fnam[128], ln[2048];
   const char *LO = FLAG_IS_SET(mmp->flag, MMF_AOUTER) ? "IJK": "JIK";
   char *be;
   int i, j;
   char ch;

   if (FLAG_IS_SET(mmp->flag, MMF_LDISKB))
      lda = ldb = kb;
   else
   {
      if (lda < 1)
         lda = kb;
      if (ldb < 1)
         ldb = kb;
      if (ldc < 1)
         ldc = mb + 8;
   }
   if (FLAG_IS_SET(mmp->flag, MMF_LDAB))
      ldb = lda;
/*
 * If the file is generated, call generator to create it
 */
   if (mmp->genstr)
   {
      if (system(mmp->genstr))
      {
         fprintf(stderr, "ERROR, LINE %d of %s\n", __LINE__, __FILE__);
         fprintf(stderr, "UNABLE TO GENERATE WITH COMMAND: %s\n", mmp->genstr);
         exit(-1);
      }
   }

   if (beta == 0)
      be = "b0";
   else if (beta == 1)
      be = "b1";
   else if (beta == -1)
      be = "bn1";
   else
      be = "bX";
/*   dmm%d_TNMBxNBxKB_muxnuxku_ldc_rtMxrtNxrtK_a1_bX */
   sprintf(fnam, "res/%cmm%d_%c%c%dx%dx%d_%dx%dx%d_%d_%dx%dx%d_a1_%s",
           pre, mmp->ID, 'T', 'N', mb, nb, kb, mmp->mu, mmp->nu, mmp->ku, ldc,
           FLAG_IS_SET(mmp->flag, MMF_MRUNTIME),
           FLAG_IS_SET(mmp->flag, MMF_NRUNTIME),
           FLAG_IS_SET(mmp->flag, MMF_KRUNTIME), be);

   if (FORCETIME || !FileExists(fnam))
   {
      if (pre == 'c' || pre == 'z')
         i = sprintf(ln, "make cmmucaseN mmrout=CASES/%s csC=2 ", mmp->rout);
      else i = sprintf(ln, "make mmucaseN mmrout=CASES/%s ", mmp->rout);
      if (mmp->comp)
      {
         ch = (pre == 'c' || pre == 's') ? 'S' : 'D';
         i += sprintf(ln+i, "%cMC=\"%s\" %cMCFLAGS=\"%s\" ",
                      ch, mmp->comp, ch, mmp->flag);
      }
      i += sprintf(ln+i, "casnam=%s ", fnam);
      i += sprintf(ln+i, "pre=%c M=%d N=%d K=%d mb=%d nb=%d kb=%d ",
                   pre, mb, nb, kb,
                   FLAG_IS_SET(mmp->flag, MMF_MRUNTIME) ? 0:mb,
                   FLAG_IS_SET(mmp->flag, MMF_NRUNTIME) ? 0:nb,
                   FLAG_IS_SET(mmp->flag, MMF_KRUNTIME) ? 0:kb);
      i += sprintf(ln+i, "mu=%d nu=%d ku=%d lda=%d ldb=%d ldc=%d beta=%d",
                   mmp->mu, mmp->nu, mmp->ku, lda, ldb, ldc, beta);
      if (verb < 3)
         i += sprintf(ln+i, "> /dev/null\n");
      else
         i += sprintf(ln+i, "\n");
      if (verb > 1)
         fprintf(stdout, "SYSTEM: %s", ln);
      if (system(ln))
      {
         fprintf(stderr, "ERROR IN COMMAND: %s", ln);
         fprintf(stderr, "   PROPOSED FILENAME: %s\n", fnam);
         sprintf(ln, "rm -f %s\n", fnam);
         system(ln);
         exit(-1);
      }
   }
   return(*((double*)ReadResultsFile(0, fnam)));
}

#endif  /* end guard around atlas_mmtesttime.h */
