#include #include #include #include "CMU418intrin.h" #include "logger.h" using namespace std; #define EXP_MAX 10 Logger CMU418Logger; void usage(const char* progname); void initValue(float* values, int* exponents, float* output, float* gold, unsigned int N); void absSerial(float* values, float* output, int N); void absVector(float* values, float* output, int N); void clampedExpSerial(float* values, int* exponents, float* output, int N); void clampedExpVector(float* values, int* exponents, float* output, int N); float arraySumSerial(float* values, int N); float arraySumVector(float* values, int N); bool verifyResult(float* values, int* exponents, float* output, float* gold, int N); int main(int argc, char * argv[]) { int N = 16; bool printLog = false; // parse commandline options //////////////////////////////////////////// for (int i = 1; i < argc; i++) { if (i < argc - 1) { if (strcmp(argv[i], "-size") == 0 || strcmp(argv[i], "-s") == 0) { N = atoi(argv[i + 1]); if (N <= 0) { printf("Error: Workload size is set to %d (<0).\n", N); return -1; } } } else { if (strcmp(argv[i], "help") == 0 || strcmp(argv[i], "?") == 0) { usage(argv[0]); return 1; } else if (strcmp(argv[i], "-log") == 0 || strcmp(argv[i], "-l") == 0) { printLog = true; } } } float* values = new float[N+VECTOR_WIDTH]; int* exponents = new int[N+VECTOR_WIDTH]; float* output = new float[N+VECTOR_WIDTH]; float* gold = new float[N+VECTOR_WIDTH]; initValue(values, exponents, output, gold, N); clampedExpSerial(values, exponents, gold, N); clampedExpVector(values, exponents, output, N); //absSerial(values, gold, N); //absVector(values, output, N); printf("CLAMPED EXPONENT (required) \n"); bool clampedCorrect = verifyResult(values, exponents, output, gold, N); if (printLog) CMU418Logger.printLog(); CMU418Logger.printStats(); printf("************************ Result Verification *************************\n"); if (!clampedCorrect) { printf("@@@ Failed!!!\n"); } else { printf("Passed!!!\n"); } printf("\nARRAY SUM (bonus) \n"); if (N % VECTOR_WIDTH == 0) { float sumGold = arraySumSerial(values, N); float sumOutput = arraySumVector(values, N); float epsilon = 0.1f; bool sumCorrect = abs(sumGold - sumOutput) < epsilon * 2; if (!sumCorrect) { printf("Expected %f, got %f\n.", sumGold, sumOutput); printf("@@@ Failed!!!\n"); } else { printf("Passed!!!\n"); } } else { printf("Must have N %% VECTOR_WIDTH == 0 for this problem (VECTOR_WIDTH is %d)\n", VECTOR_WIDTH); } delete[] values; delete[] exponents; delete[] output; delete gold; return 0; } void usage(const char* progname) { printf("Usage: %s [options]\n", progname); printf("Program Options:\n"); printf(" -s --size Use workload size N (Default = 16)\n"); printf(" -l --log Print vector unit execution log\n"); printf(" -? --help This message\n"); } void initValue(float* values, int* exponents, float* output, float* gold, unsigned int N) { for (unsigned int i=0; i(rand()) / RAND_MAX; exponents[i] = rand() % EXP_MAX; output[i] = 0.f; gold[i] = 0.f; } } bool verifyResult(float* values, int* exponents, float* output, float* gold, int N) { int incorrect = -1; float epsilon = 0.00001f; for (int i=0; i epsilon ) { incorrect = i; break; } } if (incorrect != -1) { if (incorrect >= N) printf("You have written to out of bound value!\n"); printf("Wrong calculation at value[%d]!\n", incorrect); printf("value = "); for (int i=0; i 0) { result *= x; count--; } if (result > 9.999999f) { result = 9.999999f; } output[i] = result; } } } void clampedExpVector(float* values, int* exponents, float* output, int N) { __cmu418_vec_float x; __cmu418_vec_int y, count; __cmu418_vec_float result; __cmu418_vec_int zero = _cmu418_vset_int(0); __cmu418_vec_float zero_float = _cmu418_vset_float(0.f); __cmu418_vec_float ones = _cmu418_vset_float(1.f); __cmu418_vec_int one_int = _cmu418_vset_int(1); __cmu418_vec_float upper = _cmu418_vset_float(9.999999f); __cmu418_mask maskAll, maskIsZero, maskIsNotZero, maskcount, maskup; for (int i = 0; i