Files
pp2026-hw1/part1/main.cpp
T
2026-10-05 04:41:24 +08:00

205 lines
4.9 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <math.h>
#include "logger.h"
#include <sstream>
#include "def.h"
using namespace std;
Logger PPLogger;
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 ////////////////////////////////////////////
int opt;
static struct option long_options[] = {
{"size", 1, 0, 's'},
{"log", 0, 0, 'l'},
{"help", 0, 0, '?'},
{0, 0, 0, 0}};
while ((opt = getopt_long(argc, argv, "s:l?", long_options, NULL)) != EOF)
{
switch (opt)
{
case 's':
N = atoi(optarg);
if (N <= 0)
{
printf("Error: Workload size is set to %d (<0).\n", N);
return -1;
}
break;
case 'l':
printLog = true;
break;
case '?':
default:
usage(argv[0]);
return 1;
}
}
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("\e[1;31mCLAMPED EXPONENT\e[0m (required) \n");
bool clampedCorrect = verifyResult(values, exponents, output, gold, N);
if (printLog)
PPLogger.printLog();
PPLogger.printStats();
printf("************************ Result Verification *************************\n");
if (!clampedCorrect)
{
printf("@@@ ClampedExp Failed!!!\n");
}
else if (PPLogger.getTotalInstrs() == 0)
{
printf("Not using fake intrinsics in ClampedExp\n");
}
else
{
printf("ClampedExp Passed!!!\n");
}
PPLogger.refresh();
printf("\n\e[1;31mARRAY SUM\e[0m (bonus) \n");
if (N % VECTOR_WIDTH == 0)
{
float sumGold = arraySumSerial(values, N);
float sumOutput = arraySumVector(values, N);
if (printLog)
PPLogger.printLog();
PPLogger.printStats();
printf("************************ Result Verification *************************\n");
float epsilon = 0.1;
bool sumCorrect = abs(sumGold - sumOutput) < epsilon * 2;
if (!sumCorrect)
{
printf("Expected %f, got %f\n.", sumGold, sumOutput);
printf("@@@ ArraySum Failed!!!\n");
}
else if (PPLogger.getTotalInstrs() == 0)
{
printf("Not using fake intrinsics in ArraySum\n");
}
else
{
printf("ArraySum 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 <N> 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 < N + VECTOR_WIDTH; i++)
{
// random input values
values[i] = -1.f + 4.f * static_cast<float>(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.00001;
for (int i = 0; i < N + VECTOR_WIDTH; i++)
{
if (abs(output[i] - gold[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 < N; i++)
{
printf("% f ", values[i]);
}
printf("\n");
printf("exp = ");
for (int i = 0; i < N; i++)
{
printf("% 9d ", exponents[i]);
}
printf("\n");
printf("output = ");
for (int i = 0; i < N; i++)
{
printf("% f ", output[i]);
}
printf("\n");
printf("gold = ");
for (int i = 0; i < N; i++)
{
printf("% f ", gold[i]);
}
printf("\n");
return false;
}
printf("Results matched with answer!\n");
return true;
}