makeloops.cpp   makeloops.cpp 
#include <iostream.h> #include <iostream.h>
#include <string.h> #include <string.h>
#include <fstream.h> #include <fstream.h>
#include <stdlib.h> #include <stdlib.h>
#include <strstream.h> #include <strstream.h>
#include <iostream.h> #include <iostream.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
class loop { class loop
{
public: public:
loop() loop()
{ reset(); } {
reset();
void reset(); }
void parseLoop(istream& is); void reset();
int numArrays() const void parseLoop(istream& is);
{ return numArrays_; }
int numArrays() const
char arrayName(int i) const {
{ return arrays_[i]; } return numArrays_;
}
int numScalars() const
{ return numScalars_; } char arrayName(int i) const
{
char scalarName(int i) const return arrays_[i];
{ return scalars_[i]; } }
const char* loopName() const int numScalars() const
{ return loopName_; } {
return numScalars_;
const char* loopBuffer() const }
{ return loopBuffer_; }
char scalarName(int i) const
int flops() const {
{ return flops_; } return scalars_[i];
}
int isArray(char c) const
{ const char* loopName() const
for (int i=0; i < numArrays_; ++i) {
if (arrays_[i] == c) return loopName_;
return 1; }
return 0;
} const char* loopBuffer() const
{
int isScalar(char c) const return loopBuffer_;
{ }
for (int i=0; i < numScalars_; ++i)
if (scalars_[i] == c) int flops() const
return 1; {
return 0; return flops_;
} }
int isArray(char c) const
{
for (int i=0; i < numArrays_; ++i)
if (arrays_[i] == c)
return 1;
return 0;
}
int isScalar(char c) const
{
for (int i=0; i < numScalars_; ++i)
if (scalars_[i] == c)
return 1;
return 0;
}
private: private:
enum { maxArrays = 20, maxScalars = 20, bufLen = 128 }; enum { maxArrays = 20, maxScalars = 20, bufLen = 128 };
char arrays_[maxArrays]; char arrays_[maxArrays];
int numArrays_; int numArrays_;
char scalars_[maxScalars]; char scalars_[maxScalars];
int numScalars_; int numScalars_;
char loopBuffer_[bufLen]; char loopBuffer_[bufLen];
char loopName_[bufLen]; char loopName_[bufLen];
int flops_; int flops_;
}; };
void loop::reset() void loop::reset()
{ {
numArrays_ = 0; numArrays_ = 0;
numScalars_ = 0; numScalars_ = 0;
loopBuffer_[0] = '\0'; loopBuffer_[0] = '\0';
loopName_[0] = '\0'; loopName_[0] = '\0';
flops_ = 0; flops_ = 0;
} }
void loop::parseLoop(istream& is) void loop::parseLoop(istream& is)
{ {
const int bufLen = 128; const int bufLen = 128;
char buffer[bufLen]; char buffer[bufLen];
const char* whitespace = " \t"; const char* whitespace = " \t";
reset(); reset();
while (!is.eof()) while (!is.eof()) {
{ is.getline(buffer, bufLen);
is.getline(buffer, bufLen); char* token = strtok(buffer, whitespace);
char* token = strtok(buffer, whitespace); if (!token)
if (!token) continue;
continue;
if (!strcmp(token, "begin")) {
if (!strcmp(token, "begin")) token = strtok(0, whitespace);
{ strcpy(loopName_, token);
token = strtok(0, whitespace); cout << "Creating loop: " << loopName_ << endl;
strcpy(loopName_, token); } else if (!strcmp(token, "end"))
cout << "Creating loop: " << loopName_ << endl; return;
} else if (!strcmp(token, "array")) {
else if (!strcmp(token, "end")) while (token = strtok(0, whitespace)) {
return; arrays_[numArrays_++] = token[0];
else if (!strcmp(token, "array")) cout << "Array: " << token[0] << endl;
{ }
while (token = strtok(0, whitespace)) } else if (!strcmp(token, "scalar")) {
{ while (token = strtok(0, whitespace)) {
arrays_[numArrays_++] = token[0]; scalars_[numScalars_++] = token[0];
cout << "Array: " << token[0] << endl; cout << "Scalar: " << token[0] << endl;
} }
} } else if (!strcmp(token, "flops")) {
else if (!strcmp(token, "scalar")) token = strtok(0, whitespace);
{ flops_ = atoi(token);
while (token = strtok(0, whitespace)) cout << "Flops: " << flops_ << endl;
{ } else if (!strcmp(token, "loop")) {
scalars_[numScalars_++] = token[0]; loopBuffer_[0] = '\0';
cout << "Scalar: " << token[0] << endl; while (token = strtok(0, whitespace))
} strcat(loopBuffer_, token);
} cout << "Loop: " << loopBuffer_ << endl;
else if (!strcmp(token, "flops")) }
{ }
token = strtok(0, whitespace);
flops_ = atoi(token);
cout << "Flops: " << flops_ << endl;
}
else if (!strcmp(token, "loop"))
{
loopBuffer_[0] = '\0';
while (token = strtok(0, whitespace))
strcat(loopBuffer_, token);
cout << "Loop: " << loopBuffer_ << endl;
}
}
} }
void fortranVersion(loop& lp) void fortranVersion(loop& lp)
{ {
const char* numtype = "REAL*8"; const char* numtype = "REAL*8";
char filename[128]; char filename[128];
sprintf(filename, "%sf.f", lp.loopName()); sprintf(filename, "%sf.f", lp.loopName());
ofstream ofs(filename); ofstream ofs(filename);
ofs << " SUBROUTINE " << lp.loopName() << "_F77(N"; ofs << " SUBROUTINE " << lp.loopName() << "_F77(N";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i)
ofs << ", " << lp.arrayName(i); ofs << ", " << lp.arrayName(i);
for (int i=0; i < lp.numScalars(); ++i) for (int i=0; i < lp.numScalars(); ++i)
ofs << ", " << lp.scalarName(i); ofs << ", " << lp.scalarName(i);
ofs << ")" << endl ofs << ")" << endl
<< " INTEGER i, N" << endl << " INTEGER i, N" << endl
<< " " << numtype << " " << lp.arrayName(0) << "(N)"; << " " << numtype << " " << lp.arrayName(0) << "(N)";
for (int i=1; i < lp.numArrays(); ++i) for (int i=1; i < lp.numArrays(); ++i)
ofs << ", " << lp.arrayName(i) << "(N)"; ofs << ", " << lp.arrayName(i) << "(N)";
for (int i=0; i < lp.numScalars(); ++i) for (int i=0; i < lp.numScalars(); ++i)
ofs << ", " << lp.scalarName(i); ofs << ", " << lp.scalarName(i);
ofs << endl << endl ofs << endl << endl
<< " DO i=1,N" << endl << " DO i=1,N" << endl
<< " "; << " ";
const char* loopBuffer = lp.loopBuffer(); const char* loopBuffer = lp.loopBuffer();
for (int i=0; loopBuffer[i]; ++i) for (int i=0; loopBuffer[i]; ++i) {
{ if (loopBuffer[i] == ';')
if (loopBuffer[i] == ';') ofs << endl << " ";
ofs << endl << " "; else if (loopBuffer[i] != '$')
else if (loopBuffer[i] != '$') ofs << loopBuffer[i];
ofs << loopBuffer[i]; else {
else { ++i;
++i; if (lp.isArray(loopBuffer[i]))
if (lp.isArray(loopBuffer[i])) ofs << loopBuffer[i] << "(i)";
ofs << loopBuffer[i] << "(i)"; else if (lp.isScalar(loopBuffer[i]))
else if (lp.isScalar(loopBuffer[i])) ofs << loopBuffer[i];
ofs << loopBuffer[i]; }
} }
}
ofs << endl
ofs << endl << " END DO" << endl;
<< " END DO" << endl;
ofs << " RETURN" << endl
ofs << " RETURN" << endl << " END" << endl;
<< " END" << endl;
ofs << endl << endl
ofs << endl << endl << " SUBROUTINE " << lp.loopName() << "_F77Overhead(N";
<< " SUBROUTINE " << lp.loopName() << "_F77Overhead(N";
for (int i=0; i < lp.numArrays(); ++i)
for (int i=0; i < lp.numArrays(); ++i) ofs << ", " << lp.arrayName(i);
ofs << ", " << lp.arrayName(i); for (int i=0; i < lp.numScalars(); ++i)
for (int i=0; i < lp.numScalars(); ++i) ofs << ", " << lp.scalarName(i);
ofs << ", " << lp.scalarName(i); ofs << ")" << endl
ofs << ")" << endl << " INTEGER i, N" << endl
<< " INTEGER i, N" << endl << " " << numtype << " " << lp.arrayName(0) << "(N)";
<< " " << numtype << " " << lp.arrayName(0) << "(N)";
for (int i=1; i < lp.numArrays(); ++i)
for (int i=1; i < lp.numArrays(); ++i) ofs << ", " << lp.arrayName(i) << "(N)";
ofs << ", " << lp.arrayName(i) << "(N)"; for (int i=0; i < lp.numScalars(); ++i)
for (int i=0; i < lp.numScalars(); ++i) ofs << ", " << lp.scalarName(i);
ofs << ", " << lp.scalarName(i);
ofs << endl
ofs << endl << " RETURN" << endl
<< " RETURN" << endl << " END" << endl;
<< " END" << endl;
} }
void fortran90Version(loop& lp) void fortran90Version(loop& lp)
{ {
const char* numtype = "REAL*8"; const char* numtype = "REAL*8";
char filename[128]; char filename[128];
sprintf(filename, "%sf90.f", lp.loopName()); sprintf(filename, "%sf90.f90", lp.loopName());
ofstream ofs(filename); ofstream ofs(filename);
ofs << " SUBROUTINE " << lp.loopName() << "_F90(N"; ofs << " SUBROUTINE " << lp.loopName() << "_F90(N";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i)
ofs << ", " << lp.arrayName(i); ofs << ", " << lp.arrayName(i);
for (int i=0; i < lp.numScalars(); ++i) for (int i=0; i < lp.numScalars(); ++i)
ofs << ", " << lp.scalarName(i); ofs << ", " << lp.scalarName(i);
ofs << ")" << endl ofs << ")" << endl
<< " INTEGER i, N" << endl << " INTEGER i, N" << endl
<< " " << numtype << " " << lp.arrayName(0) << "(N)"; << " " << numtype << " " << lp.arrayName(0) << "(N)";
for (int i=1; i < lp.numArrays(); ++i) for (int i=1; i < lp.numArrays(); ++i)
ofs << ", " << lp.arrayName(i) << "(N)"; ofs << ", " << lp.arrayName(i) << "(N)";
for (int i=0; i < lp.numScalars(); ++i) for (int i=0; i < lp.numScalars(); ++i)
ofs << ", " << lp.scalarName(i); ofs << ", " << lp.scalarName(i);
ofs << endl << endl ofs << endl << endl
<< " "; << " ";
const char* loopBuffer = lp.loopBuffer(); const char* loopBuffer = lp.loopBuffer();
for (int i=0; loopBuffer[i]; ++i) for (int i=0; loopBuffer[i]; ++i) {
{ if (loopBuffer[i] == ';')
if (loopBuffer[i] == ';') ofs << endl << " ";
ofs << endl << " "; else if (loopBuffer[i] != '$')
else if (loopBuffer[i] != '$') ofs << loopBuffer[i];
ofs << loopBuffer[i]; }
}
ofs << endl
ofs << endl << " RETURN" << endl
<< " RETURN" << endl << " END" << endl;
<< " END" << endl;
ofs << endl << endl
ofs << endl << endl << " SUBROUTINE " << lp.loopName() << "_F90Overhead(N";
<< " SUBROUTINE " << lp.loopName() << "_F90Overhead(N"; for (int i=0; i < lp.numArrays(); ++i)
for (int i=0; i < lp.numArrays(); ++i) ofs << ", " << lp.arrayName(i);
ofs << ", " << lp.arrayName(i); for (int i=0; i < lp.numScalars(); ++i)
for (int i=0; i < lp.numScalars(); ++i) ofs << ", " << lp.scalarName(i);
ofs << ", " << lp.scalarName(i); ofs << ")" << endl
ofs << ")" << endl << " INTEGER i, N" << endl
<< " INTEGER i, N" << endl << " " << numtype << " " << lp.arrayName(0) << "(N)";
<< " " << numtype << " " << lp.arrayName(0) << "(N)";
for (int i=1; i < lp.numArrays(); ++i)
for (int i=1; i < lp.numArrays(); ++i) ofs << ", " << lp.arrayName(i) << "(N)";
ofs << ", " << lp.arrayName(i) << "(N)"; for (int i=0; i < lp.numScalars(); ++i)
for (int i=0; i < lp.numScalars(); ++i) ofs << ", " << lp.scalarName(i);
ofs << ", " << lp.scalarName(i);
ofs << endl << endl
ofs << endl << endl << " RETURN" << endl
<< " RETURN" << endl << " END" << endl;
<< " END" << endl;
} }
void writeFortranDecl(ofstream& ofs, const char* version, loop& lp, void writeFortranDecl(ofstream& ofs, const char* version, loop& lp,
const char* numtype); const char* numtype);
void VectorVersion(ostream& os, loop& lp, const char* numtype, void VectorVersion(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2); const char* scalarArgs, const char* scalarArgs2);
void ArrayVersion(ostream& os, loop& lp, const char* numtype, void ArrayVersion(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2); const char* scalarArgs, const char* scalarArgs2);
void ValarrayVersion(ostream& os, loop& lp, const char* numtype, void ValarrayVersion(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2); const char* scalarArgs, const char* scalarArgs2);
void F77Version(ostream& os, loop& lp, const char* numtype, void F77Version(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2); const char* scalarArgs, const char* scalarArgs2);
void F90Version(ostream& os, loop& lp, const char* numtype, void F90Version(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2); const char* scalarArgs, const char* scalarArgs2);
void cppVersion(loop& lp) void cppVersion(loop& lp)
{ {
const char* numtype = "double"; const char* numtype = "double";
char filename[128]; char filename[128];
sprintf(filename, "%s.cpp", lp.loopName()); sprintf(filename, "%s.cpp", lp.loopName());
ofstream ofs(filename); ofstream ofs(filename);
char capsLoopName[128]; char capsLoopName[128];
for (int i=0; i <= strlen(lp.loopName()); ++i) for (int i=0; i <= strlen(lp.loopName()); ++i)
capsLoopName[i] = toupper(lp.loopName()[i]); capsLoopName[i] = toupper(lp.loopName()[i]);
ofs << "// Generated code (makeloops.cpp) -- do not edit." << endl << e ofs << "// Generated code (makeloops.cpp) -- do not edit." << endl <
ndl < endl
<< "// In KAI C++ 3.2, restrict causes problems for copy propagatio << "// In KAI C++ 3.2, restrict causes problems for copy propagation
n." ."
<< endl << "// Temporary fix: disable restrict" << endl << endl << endl << "// Temporary fix: disable restrict" << endl << endl
<< "#define BZ_DISABLE_RESTRICT" << endl << endl << "#define BZ_DISABLE_RESTRICT" << endl << endl
<< <<
"#include <blitz/vector.h>\n" "#include <blitz/vector.h>\n"
"#include <blitz/array.h>\n" "#include <blitz/array.h>\n"
"#include <blitz/rand-uniform.h>\n" "#include <blitz/rand-uniform.h>\n"
"#include <blitz/benchext.h>\n" "#include <blitz/benchext.h>\n"
"\n" "\n"
"// Generated: " << __FILE__ << " " << __DATE__ << endl << endl << "// Generated: " << __FILE__ << " " << __DATE__ << endl << endl <<
"#ifdef BENCHMARK_VALARRAY\n" "#ifdef BZ_HAVE_VALARRAY\n"
"#include <valarray>\n" " #define BENCHMARK_VALARRAY\n"
"#endif\n" "#endif\n\n"
"\n" "#ifdef BENCHMARK_VALARRAY\n"
"BZ_USING_NAMESPACE(blitz)\n" "#include <valarray>\n"
"\n" "#endif\n"
"#ifdef BZ_FORTRAN_SYMBOLS_WITH_TRAILING_UNDERSCORES\n" "\n"
" #define " << lp.loopName() << "_f77 " << lp.loopName() << "_f77_\n" "BZ_USING_NAMESPACE(blitz)\n"
" #define " << lp.loopName() << "_f77overhead " << lp.loopName() << "_f77ov "\n"
erhead_\n" "#if defined(BZ_FORTRAN_SYMBOLS_WITH_TRAILING_UNDERSCORES)\n"
" #define " << lp.loopName() << "_f77 " << lp.loopName() << "_f77_\n
#ifndef NO_FORTRAN_90 "
" #define " << lp.loopName() << "_f90 " << lp.loopName() << "_f90_\n" " #define " << lp.loopName() << "_f77overhead " << lp.loopName() <<
" #define " << lp.loopName() << "_f90overhead " << lp.loopName() << "_f90ov "_f77overhead_\n"
erhead_\n"
#endif // NO_FORTRAN_90 " #define " << lp.loopName() << "_f90 " << lp.loopName() << "_f90_\n
"#endif\n\n" "
" #define " << lp.loopName() << "_f90overhead " << lp.loopName() <<
"#ifdef BZ_FORTRAN_SYMBOLS_WITH_DOUBLE_TRAILING_UNDERSCORES\n" "_f90overhead_\n"
" #define " << lp.loopName() << "_f77 " << lp.loopName() << "_f77__\n"
" #define " << lp.loopName() << "_f77overhead " << lp.loopName() << "_f77ov "#elif defined(BZ_FORTRAN_SYMBOLS_WITH_DOUBLE_TRAILING_UNDERSCORES)\
erhead__\n" n"
" #define " << lp.loopName() << "_f77 " << lp.loopName() << "_f77__\
#ifndef NO_FORTRAN_90 n"
" #define " << lp.loopName() << "_f90 " << lp.loopName() << "_f90__\n" " #define " << lp.loopName() << "_f77overhead " << lp.loopName() <<
" #define " << lp.loopName() << "_f90overhead " << lp.loopName() << "_f90ov "_f77overhead__\n"
erhead__\n"
#endif // NO_FORTRAN_90 " #define " << lp.loopName() << "_f90 " << lp.loopName() << "_f90__\
"#endif\n" n"
" #define " << lp.loopName() << "_f90overhead " << lp.loopName() <<
"\n" "_f90overhead__\n"
"#ifdef BZ_FORTRAN_SYMBOLS_CAPS\n"
" #define " << lp.loopName() << "_f77 " << capsLoopName << "_F77\n" "#elif defined(BZ_FORTRAN_SYMBOLS_CAPS)\n"
" #define " << lp.loopName() << "_f77overhead " << capsLoopName << "_F77OVE " #define " << lp.loopName() << "_f77 " << capsLoopName << "_F77\n"
RHEAD\n" " #define " << lp.loopName() << "_f77overhead " << capsLoopName << "
#ifndef NO_FORTRAN_90 _F77OVERHEAD\n"
" #define " << lp.loopName() << "_f90 " << capsLoopName << "_F90\n" " #define " << lp.loopName() << "_f90 " << capsLoopName << "_F90\n"
" #define " << lp.loopName() << "_f90overhead " << capsLoopName << "_F90OVE " #define " << lp.loopName() << "_f90overhead " << capsLoopName << "
RHEAD\n" _F90OVERHEAD\n"
#endif // NO_FORTRAN_90 "#endif\n"
"#endif\n" "\n"
"\n" "extern \"C\" {" << endl;
"extern \"C\" {" << endl;
writeFortranDecl(ofs, "_f77", lp, numtype);
writeFortranDecl(ofs, "_f77", lp, numtype); writeFortranDecl(ofs, "_f77overhead", lp, numtype);
writeFortranDecl(ofs, "_f77overhead", lp, numtype); writeFortranDecl(ofs, "_f90", lp, numtype);
#ifndef NO_FORTRAN_90 writeFortranDecl(ofs, "_f90overhead", lp, numtype);
writeFortranDecl(ofs, "_f90", lp, numtype);
writeFortranDecl(ofs, "_f90overhead", lp, numtype); ofs << "}" << endl << endl;
#endif
// Create a string with a list of arguments for the scalars
ofs << "}" << endl << endl; ostrstream tmpbuf;
for (int i=0; i < lp.numScalars(); ++i) {
// Create a string with a list of arguments for the scalars tmpbuf << ", " << numtype << " " << lp.scalarName(i);
ostrstream tmpbuf; }
for (int i=0; i < lp.numScalars(); ++i) tmpbuf << '\0';
{ const char* scalarArgs = tmpbuf.str();
tmpbuf << ", " << numtype << " " << lp.scalarName(i);
} ofs << "void VectorVersion(BenchmarkExt<int>& bench"
tmpbuf << '\0'; << scalarArgs << ");" << endl
const char* scalarArgs = tmpbuf.str(); << "void ArrayVersion(BenchmarkExt<int>& bench"
<< scalarArgs << ");" << endl
ofs << "void VectorVersion(BenchmarkExt<int>& bench" << "void F77Version(BenchmarkExt<int>& bench"
<< scalarArgs << ");" << endl << scalarArgs << ");" << endl
<< "void ArrayVersion(BenchmarkExt<int>& bench" << "#ifdef FORTRAN_90" << endl
<< scalarArgs << ");" << endl << "void F90Version(BenchmarkExt<int>& bench"
<< "void F77Version(BenchmarkExt<int>& bench" << scalarArgs << ");" << endl
<< scalarArgs << ");" << endl << "#endif" << endl
#ifndef NO_FORTRAN_90 << "#ifdef BENCHMARK_VALARRAY" << endl
<< "void F90Version(BenchmarkExt<int>& bench" << "void ValarrayVersion(BenchmarkExt<int>& bench"
<< scalarArgs << ");" << endl << endl << scalarArgs << ");" << endl << "#endif" << endl << endl;
#endif
<< "#ifdef BENCHMARK_VALARRAY" << endl ofs << "void sink() {}\n\n";
<< "void ValarrayVersion(BenchmarkExt<int>& bench"
<< scalarArgs << ");" << endl << "#endif" << endl << endl; ofs << "int main()\n"
"{\n"
ofs << "void sink() {}\n\n"; " int numBenchmarks = 5;\n"
"#ifndef BENCHMARK_VALARRAY\n"
ofs << "int main()\n" " numBenchmarks--; // No valarray\n"
"{\n" "#endif\n"
"#ifdef BENCHMARK_VALARRAY\n" "#ifndef FORTRAN_90\n"
" int numBenchmarks = 5;\n" " numBenchmarks--; // No fortran 90\n"
"#else\n" "#endif\n"
" int numBenchmarks = 4;\n"
"#endif\n" "\n"
" BenchmarkExt<int> bench(\"" << lp.loopName() << ": "
#ifdef NO_FORTRAN_90 << lp.loopBuffer() << "\", numBenchmarks);\n"
" --numBenchmarks; // No fortran 90" "\n"
#endif " const int numSizes = 23;\n"
" bench.setNumParameters(numSizes);\n"
"\n" " bench.setRateDescription(\"Mflops/s\");\n"
" BenchmarkExt<int> bench(\"" << lp.loopName() << ": " "\n"
<< lp.loopBuffer() << "\", numBenchmarks);\n" " Vector<int> parameters(numSizes);\n"
"\n" " Vector<long> iters(numSizes);\n"
" const int numSizes = 23;\n" " Vector<double> flops(numSizes);\n"
" bench.setNumParameters(numSizes);\n" "\n"
" bench.setRateDescription(\"Mflops/s\");\n" " for (int i=0; i < numSizes; ++i)\n"
"\n" " {\n"
" Vector<int> parameters(numSizes);\n" " parameters[i] = (int)pow(10.0, (i+1)/4.0);\n"
" Vector<long> iters(numSizes);\n" " iters[i] = 10000000L / parameters[i];\n"
" Vector<double> flops(numSizes);\n" " if (iters[i] < 2)\n"
"\n" " iters[i] = 2;\n"
" for (int i=0; i < numSizes; ++i)\n" " flops[i] = " << lp.flops() << " * parameters[i];\n"
" {\n" " }\n"
" parameters[i] = (int)pow(10.0, (i+1)/4.0);\n" "\n"
" iters[i] = 10000000L / parameters[i];\n" " bench.setParameterVector(parameters);\n"
" if (iters[i] < 2)\n" " bench.setIterations(iters);\n"
" iters[i] = 2;\n" " bench.setFlopsPerIteration(flops);\n"
" flops[i] = " << lp.flops() << " * parameters[i];\n" "\n"
" }\n" " bench.beginBenchmarking();" << endl << endl;
"\n"
" bench.setParameterVector(parameters);\n" // Create literals
" bench.setIterations(iters);\n" for (int i=0; i < lp.numScalars(); ++i) {
" bench.setFlopsPerIteration(flops);\n" ofs << " " << numtype << " " << lp.scalarName(i)
"\n" << " = 0.39123982498157938742;" << endl;
" bench.beginBenchmarking();" << endl << endl; }
// Create literals ofs << endl;
for (int i=0; i < lp.numScalars(); ++i)
{ ofs.flush();
ofs << " " << numtype << " " << lp.scalarName(i)
<< " = 0.39123982498157938742;" << endl; // Create a string with a list of arguments for the scalars
} ostrstream tmpbuf2;
for (int i=0; i < lp.numScalars(); ++i) {
ofs << endl; tmpbuf2 << ", " << lp.scalarName(i);
}
ofs.flush(); tmpbuf2 << '\0';
char* scalarArgs2 = tmpbuf2.str();
// Create a string with a list of arguments for the scalars
ostrstream tmpbuf2; ofs << " VectorVersion(bench" << scalarArgs2 << ");" << endl
for (int i=0; i < lp.numScalars(); ++i) << " ArrayVersion(bench" << scalarArgs2 << ");" << endl
{ << " F77Version(bench" << scalarArgs2 << ");" << endl
tmpbuf2 << ", " << lp.scalarName(i); << "#ifdef FORTRAN_90" << endl
} << " F90Version(bench" << scalarArgs2 << ");" << endl
tmpbuf2 << '\0'; << "#endif" << endl
char* scalarArgs2 = tmpbuf2.str(); << "#ifdef BENCHMARK_VALARRAY" << endl
<< " ValarrayVersion(bench" << scalarArgs2 << ");" << endl
ofs << " VectorVersion(bench" << scalarArgs2 << ");" << endl << "#endif" << endl << endl <<
<< " ArrayVersion(bench" << scalarArgs2 << ");" << endl " bench.endBenchmarking();\n"
<< " F77Version(bench" << scalarArgs2 << ");" << endl "\n"
#ifndef NO_FORTRAN_90 " bench.saveMatlabGraph(\"" << lp.loopName() << ".m\");\n"
<< " F90Version(bench" << scalarArgs2 << ");" << endl "\n"
#endif " return 0;\n"
<< "#ifdef BENCHMARK_VALARRAY" << endl "}\n\n"
<< " ValarrayVersion(bench" << scalarArgs2 << ");" << endl "template<class T>\n"
<< "#endif" << endl << endl << "void initializeRandomDouble(T data, int numElements, int stride = 1
" bench.endBenchmarking();\n" )\n"
"\n" "{\n"
" bench.saveMatlabGraph(\"" << lp.loopName() << ".m\");\n" " static Random<Uniform> rnd;\n"
"\n" "\n"
" return 0;\n" " for (int i=0; i < numElements; ++i)\n"
"}\n\n" " data[size_t(i*stride)] = rnd.random();\n"
"template<class T>\n" "}\n"
"void initializeRandomDouble(T data, int numElements, int stride = 1)\n" "\n"
"{\n" "template<class T>\n"
" static Random<Uniform> rnd;\n" "void initializeArray(T& array, int numElements)\n"
"\n" "{\n"
" for (int i=0; i < numElements; ++i)\n" " static Random<Uniform> rnd;\n"
" data[size_t(i*stride)] = rnd.random();\n" "\n"
"}\n" " for (size_t i=0; i < numElements; ++i)\n"
"\n" " array[i] = rnd.random();\n"
"template<class T>\n" "}\n\n";
"void initializeArray(T& array, int numElements)\n"
"{\n" VectorVersion(ofs, lp, numtype, scalarArgs, scalarArgs2);
" static Random<Uniform> rnd;\n" ArrayVersion(ofs, lp, numtype, scalarArgs, scalarArgs2);
"\n" ValarrayVersion(ofs, lp, numtype, scalarArgs, scalarArgs2);
" for (size_t i=0; i < numElements; ++i)\n" F77Version(ofs, lp, numtype, scalarArgs, scalarArgs2);
" array[i] = rnd.random();\n" F90Version(ofs, lp, numtype, scalarArgs, scalarArgs2);
"}\n\n";
VectorVersion(ofs, lp, numtype, scalarArgs, scalarArgs2);
ArrayVersion(ofs, lp, numtype, scalarArgs, scalarArgs2);
ValarrayVersion(ofs, lp, numtype, scalarArgs, scalarArgs2);
F77Version(ofs, lp, numtype, scalarArgs, scalarArgs2);
#ifndef NO_FORTRAN_90
F90Version(ofs, lp, numtype, scalarArgs, scalarArgs2);
#endif
} }
void writeFortranDecl(ofstream& ofs, const char* version, loop& lp, void writeFortranDecl(ofstream& ofs, const char* version, loop& lp,
const char* numtype) const char* numtype)
{ {
ofs << " void " << lp.loopName() << version ofs << " void " << lp.loopName() << version
<< "(const int& N"; << "(const int& N";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i)
ofs << ", " << numtype << "* " << lp.arrayName(i); ofs << ", " << numtype << "* " << lp.arrayName(i);
for (int i=0; i < lp.numScalars(); ++i) for (int i=0; i < lp.numScalars(); ++i)
ofs << ", const " << numtype << "& " << lp.scalarName(i); ofs << ", const " << numtype << "& " << lp.scalarName(i);
ofs << ");" << endl << endl; ofs << ");" << endl << endl;
} }
void VectorVersion(ostream& os, loop& lp, const char* numtype, void VectorVersion(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2) const char* scalarArgs, const char* scalarArgs2)
{ {
os << "void VectorVersion(BenchmarkExt<int>& bench" os << "void VectorVersion(BenchmarkExt<int>& bench"
<< scalarArgs << ")\n" << scalarArgs << ")\n"
<< <<
"{\n" "{\n"
" bench.beginImplementation(\"Vector<T>\");\n" " bench.beginImplementation(\"Vector<T>\");\n"
"\n" "\n"
" while (!bench.doneImplementationBenchmark())\n" " while (!bench.doneImplementationBenchmark())\n"
" {\n" " {\n"
" int N = bench.getParameter();\n" " int N = bench.getParameter();\n"
" cout << \"Vector<T>: N = \" << N << endl;\n" " cout << \"Vector<T>: N = \" << N << endl;\n"
" cout.flush();\n" " cout.flush();\n"
"\n" "\n"
" long iters = bench.getIterations();\n" " long iters = bench.getIterations();\n"
"\n"; "\n";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i) {
{ os << " Vector<" << numtype << "> " << lp.arrayName(i
os << " Vector<" << numtype << "> " << lp.arrayName(i) )
<< "(N);" << endl << "(N);" << endl
<< " initializeRandomDouble(" << lp.arrayName(i) << ".dat << " initializeRandomDouble(" << lp.arrayName(i) << "
a(), N);" << endl; .data(), N);" << endl;
} }
os << endl << os << endl <<
" bench.start();\n" " bench.start();\n"
" for (long i=0; i < iters; ++i)\n" " for (long i=0; i < iters; ++i)\n"
" {\n" " {\n"
" "; " ";
const char* loopBuffer = lp.loopBuffer(); const char* loopBuffer = lp.loopBuffer();
for (int i=0; loopBuffer[i]; ++i) for (int i=0; loopBuffer[i]; ++i) {
{ if (loopBuffer[i] != '$')
if (loopBuffer[i] != '$') os << loopBuffer[i];
os << loopBuffer[i]; }
}
os << ";" << endl <<
os << ";" << endl << " sink();\n";
" sink();\n";
os <<
os << " }\n"
" }\n" " bench.stop();\n\n"
" bench.stop();\n\n" " bench.startOverhead();\n"
" bench.startOverhead();\n" " for (long i=0; i < iters; ++i)\n"
" for (long i=0; i < iters; ++i)\n" " sink();\n"
" sink();\n" " bench.stopOverhead();\n"
" bench.stopOverhead();\n"
" }\n"
" }\n" "\n"
"\n" " bench.endImplementation();\n"
" bench.endImplementation();\n" "}" << endl << endl;
"}" << endl << endl;
} }
void ArrayVersion(ostream& os, loop& lp, const char* numtype, void ArrayVersion(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2) const char* scalarArgs, const char* scalarArgs2)
{ {
os << "void ArrayVersion(BenchmarkExt<int>& bench" os << "void ArrayVersion(BenchmarkExt<int>& bench"
<< scalarArgs << ")\n" << scalarArgs << ")\n"
<< <<
"{\n" "{\n"
" bench.beginImplementation(\"Array<T,1>\");\n" " bench.beginImplementation(\"Array<T,1>\");\n"
"\n" "\n"
" while (!bench.doneImplementationBenchmark())\n" " while (!bench.doneImplementationBenchmark())\n"
" {\n" " {\n"
" int N = bench.getParameter();\n" " int N = bench.getParameter();\n"
" cout << \"Array<T,1>: N = \" << N << endl;\n" " cout << \"Array<T,1>: N = \" << N << endl;\n"
" cout.flush();\n" " cout.flush();\n"
"\n" "\n"
" long iters = bench.getIterations();\n" " long iters = bench.getIterations();\n"
"\n"; "\n";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i) {
{ os << " Array<" << numtype << ", 1> " << lp.arrayName
os << " Array<" << numtype << ", 1> " << lp.arrayName(i) (i)
<< "(N);" << endl << "(N);" << endl
<< " initializeRandomDouble(" << lp.arrayName(i) << ".dat << " initializeRandomDouble(" << lp.arrayName(i) << "
aFirst(), N);" << endl; .dataFirst(), N);" << endl;
} }
os << endl << os << endl <<
" bench.start();\n" " bench.start();\n"
" for (long i=0; i < iters; ++i)\n" " for (long i=0; i < iters; ++i)\n"
" {\n" " {\n"
" "; " ";
const char* loopBuffer = lp.loopBuffer(); const char* loopBuffer = lp.loopBuffer();
for (int i=0; loopBuffer[i]; ++i) for (int i=0; loopBuffer[i]; ++i) {
{ if (loopBuffer[i] != '$')
if (loopBuffer[i] != '$') os << loopBuffer[i];
os << loopBuffer[i]; }
}
os << ";" << endl <<
os << ";" << endl << " sink();\n";
" sink();\n";
os <<
os << " }\n"
" }\n" " bench.stop();\n\n"
" bench.stop();\n\n" " bench.startOverhead();\n"
" bench.startOverhead();\n" " for (long i=0; i < iters; ++i)\n"
" for (long i=0; i < iters; ++i)\n" " sink();\n"
" sink();\n" " bench.stopOverhead();\n";
" bench.stopOverhead();\n"; os <<
os << " }\n"
" }\n" "\n"
"\n" " bench.endImplementation();\n"
" bench.endImplementation();\n" "}" << endl << endl;
"}" << endl << endl;
} }
void F77Version(ostream& os, loop& lp, const char* numtype, void F77Version(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2) const char* scalarArgs, const char* scalarArgs2)
{ {
os << "void F77Version(BenchmarkExt<int>& bench" os << "void F77Version(BenchmarkExt<int>& bench"
<< scalarArgs << ")\n" << scalarArgs << ")\n"
"{\n" "{\n"
" bench.beginImplementation(\"Fortran 77\");\n" " bench.beginImplementation(\"Fortran 77\");\n"
"\n" "\n"
" while (!bench.doneImplementationBenchmark())\n" " while (!bench.doneImplementationBenchmark())\n"
" {\n" " {\n"
" int N = bench.getParameter();\n\n" " int N = bench.getParameter();\n\n"
" cout << \"Fortran 77: N = \" << N << endl;\n" " cout << \"Fortran 77: N = \" << N << endl;\n"
" cout.flush();\n\n" " cout.flush();\n\n"
" int iters = bench.getIterations();\n" " int iters = bench.getIterations();\n"
"\n"; "\n";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i) {
{ os << " " << numtype << "* " << lp.arrayName(i)
os << " " << numtype << "* " << lp.arrayName(i) << " = new " << numtype << "[N];" << endl
<< " = new " << numtype << "[N];" << endl << " initializeRandomDouble(" << lp.arrayName(i)
<< " initializeRandomDouble(" << lp.arrayName(i) << ", N);" << endl;
<< ", N);" << endl; }
}
os << endl <<
os << endl << " bench.start();\n"
" bench.start();\n" " for (int iter=0; iter < iters; ++iter)\n"
" for (int iter=0; iter < iters; ++iter)\n" " " << lp.loopName() << "_f77(N";
" " << lp.loopName() << "_f77(N";
for (int i=0; i < lp.numArrays(); ++i)
for (int i=0; i < lp.numArrays(); ++i) os << ", " << lp.arrayName(i);
os << ", " << lp.arrayName(i); os << scalarArgs2 << ");\n"
os << scalarArgs2 << ");\n" " bench.stop();\n\n"
" bench.stop();\n\n" " bench.startOverhead();\n"
" bench.startOverhead();\n" " for (int iter=0; iter < iters; ++iter)\n"
" for (int iter=0; iter < iters; ++iter)\n" " " << lp.loopName() << "_f77overhead(N";
" " << lp.loopName() << "_f77overhead(N"; for (int i=0; i < lp.numArrays(); ++i)
for (int i=0; i < lp.numArrays(); ++i) os << ", " << lp.arrayName(i);
os << ", " << lp.arrayName(i); os << scalarArgs2 << ");\n";
os << scalarArgs2 << ");\n";
os << endl <<
os << endl << " bench.stopOverhead();\n";
" bench.stopOverhead();\n";
for (int i=0; i < lp.numArrays(); ++i) {
for (int i=0; i < lp.numArrays(); ++i) os << " delete [] " << lp.arrayName(i) << ";" << endl
{ ;
os << " delete [] " << lp.arrayName(i) << ";" << endl; }
}
os << " }\n"
os << " }\n" "\n"
"\n" " bench.endImplementation();\n"
" bench.endImplementation();\n" "}\n" << endl;
"}\n" << endl;
} }
#ifndef NO_FORTRAN_90
void F90Version(ostream& os, loop& lp, const char* numtype, void F90Version(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2) const char* scalarArgs, const char* scalarArgs2)
{ {
os << "void F90Version(BenchmarkExt<int>& bench" os << "#ifdef FORTRAN_90" << endl
<< scalarArgs << ")\n" << "void F90Version(BenchmarkExt<int>& bench"
"{\n" << scalarArgs << ")\n"
" bench.beginImplementation(\"Fortran 90\");\n" "{\n"
"\n" " bench.beginImplementation(\"Fortran 90\");\n"
" while (!bench.doneImplementationBenchmark())\n" "\n"
" {\n" " while (!bench.doneImplementationBenchmark())\n"
" int N = bench.getParameter();\n\n" " {\n"
" cout << \"Fortran 90: N = \" << N << endl;\n" " int N = bench.getParameter();\n\n"
" cout.flush();\n\n" " cout << \"Fortran 90: N = \" << N << endl;\n"
" int iters = bench.getIterations();\n" " cout.flush();\n\n"
"\n"; " int iters = bench.getIterations();\n"
"\n";
for (int i=0; i < lp.numArrays(); ++i)
{ for (int i=0; i < lp.numArrays(); ++i) {
os << " " << numtype << "* " << lp.arrayName(i) os << " " << numtype << "* " << lp.arrayName(i)
<< " = new " << numtype << "[N];" << endl << " = new " << numtype << "[N];" << endl
<< " initializeRandomDouble(" << lp.arrayName(i) << " initializeRandomDouble(" << lp.arrayName(i)
<< ", N);" << endl; << ", N);" << endl;
} }
os << endl << os << endl <<
" bench.start();\n" " bench.start();\n"
" for (int iter=0; iter < iters; ++iter)\n" " for (int iter=0; iter < iters; ++iter)\n"
" " << lp.loopName() << "_f90(N"; " " << lp.loopName() << "_f90(N";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i)
os << ", " << lp.arrayName(i); os << ", " << lp.arrayName(i);
os << scalarArgs2 << ");\n" os << scalarArgs2 << ");\n"
" bench.stop();\n\n" " bench.stop();\n\n"
" bench.startOverhead();\n" " bench.startOverhead();\n"
" for (int iter=0; iter < iters; ++iter)\n" " for (int iter=0; iter < iters; ++iter)\n"
" " << lp.loopName() << "_f90overhead(N"; " " << lp.loopName() << "_f90overhead(N";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i)
os << ", " << lp.arrayName(i); os << ", " << lp.arrayName(i);
os << scalarArgs2 << ");\n"; os << scalarArgs2 << ");\n";
os << endl << os << endl <<
" bench.stopOverhead();\n"; " bench.stopOverhead();\n";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i) {
{ os << " delete [] " << lp.arrayName(i) << ";" << endl
os << " delete [] " << lp.arrayName(i) << ";" << endl; ;
} }
os << " }\n" os << " }\n"
"\n" "\n"
" bench.endImplementation();\n" " bench.endImplementation();\n"
"}\n" << endl; "}\n"
<< "#endif\n" << endl;
} }
#endif
void ValarrayVersion(ostream& os, loop& lp, const char* numtype, void ValarrayVersion(ostream& os, loop& lp, const char* numtype,
const char* scalarArgs, const char* scalarArgs2) const char* scalarArgs, const char* scalarArgs2)
{ {
os << "#ifdef BENCHMARK_VALARRAY" << endl; os << "#ifdef BENCHMARK_VALARRAY" << endl;
os << "void ValarrayVersion(BenchmarkExt<int>& bench" os << "void ValarrayVersion(BenchmarkExt<int>& bench"
<< scalarArgs << ")\n" << scalarArgs << ")\n"
<< <<
"{\n" "{\n"
" bench.beginImplementation(\"valarray<T>\");\n" " bench.beginImplementation(\"valarray<T>\");\n"
"\n" "\n"
" while (!bench.doneImplementationBenchmark())\n" " while (!bench.doneImplementationBenchmark())\n"
" {\n" " {\n"
" int N = bench.getParameter();\n" " int N = bench.getParameter();\n"
" cout << \"valarray<T>: N = \" << N << endl;\n" " cout << \"valarray<T>: N = \" << N << endl;\n"
" cout.flush();\n" " cout.flush();\n"
"\n" "\n"
" long iters = bench.getIterations();\n" " long iters = bench.getIterations();\n"
"\n"; "\n";
for (int i=0; i < lp.numArrays(); ++i) for (int i=0; i < lp.numArrays(); ++i) {
{ os << " valarray<" << numtype << "> " << lp.arrayName
os << " valarray<" << numtype << "> " << lp.arrayName(i) (i)
<< "(N);" << endl << "(N);" << endl
<< " initializeArray(" << lp.arrayName(i) << ", N);" << e << " initializeArray(" << lp.arrayName(i) << ", N);"
ndl; << endl;
} }
os << endl << os << endl <<
" bench.start();\n" " bench.start();\n"
" for (long i=0; i < iters; ++i)\n" " for (long i=0; i < iters; ++i)\n"
" {\n" " {\n"
" "; " ";
const char* loopBuffer = lp.loopBuffer(); const char* loopBuffer = lp.loopBuffer();
for (int i=0; loopBuffer[i]; ++i) for (int i=0; loopBuffer[i]; ++i) {
{ if (loopBuffer[i] != '$')
if (loopBuffer[i] != '$') os << loopBuffer[i];
os << loopBuffer[i]; }
}
os << ";" << endl <<
os << ";" << endl << " sink();\n";
" sink();\n";
os <<
os << " }\n"
" }\n" " bench.stop();\n\n"
" bench.stop();\n\n" " bench.startOverhead();\n"
" bench.startOverhead();\n" " for (long i=0; i < iters; ++i)\n"
" for (long i=0; i < iters; ++i)\n" " sink();\n"
" sink();\n" " bench.stopOverhead();\n"
" bench.stopOverhead();\n"
" }\n"
" }\n" "\n"
"\n" " bench.endImplementation();\n"
" bench.endImplementation();\n" "}" << endl << endl << "#endif" << endl;
"}" << endl << endl << "#endif" << endl;
} }
int main() int main()
{ {
ifstream ifs("loops.data"); ifstream ifs("loops.data");
ofstream ofs("makefile.inc"); //ofstream ofs("makefile.inc");
loop lp; loop lp;
while (!ifs.eof()) while (!ifs.eof()) {
{ lp.parseLoop(ifs);
lp.parseLoop(ifs);
if (ifs.eof()) if (ifs.eof())
break; break;
ofs /*
#ifndef NO_FORTRAN_90 ofs
<< lp.loopName() << "f90.o:\t" << lp.loopName() << "f90.f" #ifdef FORTRAN_90
<< endl << "\t$(F90) $(F90FLAGS) -c " << lp.loopName() << "f90. << lp.loopName() << "f90.o:\t" << lp.loopName() << "f90.f"
f" << endl << "\t$(F90) $(F90FLAGS) -c " << lp.loopName() << "f
<< endl << endl 90.f"
<< endl << endl
#endif #endif
<< lp.loopName() << ":\t" << lp.loopName() << ".o " << lp.loopName() << ":\t" << lp.loopName() << ".o "
<< lp.loopName() << "f.o " << lp.loopName() << "f.o "
#ifndef NO_FORTRAN_90 #ifdef FORTRAN_90
<< lp.loopName() << "f90.o" << lp.loopName() << "f90.o"
#endif #endif
<< endl << endl
<< "\t$(CXX) $(CXXFLAGS) $(LDFLAGS) -o " << lp.loopName() << " << "\t$(CXX) $(CXXFLAGS) $(LDFLAGS) -o " << lp.loopName() <<
" " "
<< lp.loopName() << ".o " << lp.loopName() << "f.o " << lp.loopName() << ".o " << lp.loopName() << "f.o "
#ifndef NO_FORTRAN_90 #ifdef FORTRAN_90
<< lp.loopName() << "f90.o " << lp.loopName() << "f90.o "
#endif #endif
<< "$(LIBS)" << endl << endl; << "$(LIBS)" << endl << endl;
*/
fortranVersion(lp); fortranVersion(lp);
#ifndef NO_FORTRAN_90 //#ifdef FORTRAN_90
fortran90Version(lp); fortran90Version(lp);
#endif //#endif
cppVersion(lp); cppVersion(lp);
} }
return 0; return 0;
} }
 End of changes. 47 change blocks. 
733 lines changed or deleted 723 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/