mirror of
https://github.com/kmc7468/cs420.git
synced 2025-12-15 15:08:52 +00:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
34
bench/LICENSE
Normal file
34
bench/LICENSE
Normal file
@@ -0,0 +1,34 @@
|
||||
The following files are distributed under the following license with modifications.
|
||||
|
||||
* median.c
|
||||
* multiply.c
|
||||
* qsort.c
|
||||
* rsort.c
|
||||
* spmv.c
|
||||
* towers.c
|
||||
* vvadd.c
|
||||
|
||||
Copyright (c) 2012-2015, The Regents of the University of California (Regents).
|
||||
All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the Regents nor the
|
||||
names of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
|
||||
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
|
||||
OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
|
||||
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
|
||||
HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
|
||||
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
@@ -12,6 +12,13 @@ namespace model {
|
||||
#include <two_dimension_array.c>
|
||||
#include <matrix.c>
|
||||
#include <graph.c>
|
||||
#include <median.c>
|
||||
#include <multiply.c>
|
||||
#include <qsort.c>
|
||||
#include <rsort.c>
|
||||
#include <spmv.c>
|
||||
#include <towers.c>
|
||||
#include <vvadd.c>
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
@@ -28,6 +35,14 @@ extern "C" {
|
||||
int matrix_add(int, int);
|
||||
int graph_dijkstra(int, int);
|
||||
int graph_floyd_warshall(int, int);
|
||||
// From riscv-tests
|
||||
int run_median(int, int);
|
||||
int run_multiply(int, int);
|
||||
int run_qsort(int, int);
|
||||
int run_rsort(int, int);
|
||||
int run_spmv(int, int);
|
||||
int run_towers(int, int);
|
||||
int run_vvadd(int, int);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -80,6 +95,13 @@ int main() {
|
||||
cycles.push_back(evaluate("matrix_add", 30, matrix_add, model::matrix_add));
|
||||
cycles.push_back(evaluate("graph_dijkstra", 1000, graph_dijkstra, model::graph_dijkstra));
|
||||
cycles.push_back(evaluate("graph_floyd_warshall", 200, graph_floyd_warshall, model::graph_floyd_warshall));
|
||||
cycles.push_back(evaluate("median", -1, run_median, model::run_median));
|
||||
cycles.push_back(evaluate("mutiply", -1, run_multiply, model::run_multiply));
|
||||
cycles.push_back(evaluate("qsort", -1, run_qsort, model::run_qsort));
|
||||
cycles.push_back(evaluate("rsort", -1, run_rsort, model::run_rsort));
|
||||
cycles.push_back(evaluate("spmv", -1, run_spmv, model::run_spmv));
|
||||
cycles.push_back(evaluate("towers", -1, run_towers, model::run_towers));
|
||||
cycles.push_back(evaluate("vvadd", -1, run_vvadd, model::run_vvadd));
|
||||
}
|
||||
|
||||
// Calculates the geometric mean.
|
||||
|
||||
70
bench/median.c
Normal file
70
bench/median.c
Normal file
@@ -0,0 +1,70 @@
|
||||
//**************************************************************************
|
||||
// Median filter bencmark
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// This benchmark performs a 1D three element median filter.
|
||||
|
||||
int input_median[400];
|
||||
int results_median[400];
|
||||
|
||||
void median_data_init(int nonce) {
|
||||
int i;
|
||||
int x = nonce;
|
||||
|
||||
for (i = 0; i < 400; i++) {
|
||||
x = (x * 97 + 17) % 1000;
|
||||
input_median[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
void median(int n, int input[400], int results[400]) {
|
||||
int A, B, C, i;
|
||||
|
||||
// Zero the ends
|
||||
results[0] = 0;
|
||||
results[n - 1] = 0;
|
||||
|
||||
// Do the filter
|
||||
for (i = 1; i < (n - 1); i++) {
|
||||
A = input[i - 1];
|
||||
B = input[i];
|
||||
C = input[i + 1];
|
||||
|
||||
if (A < B) {
|
||||
if (B < C)
|
||||
results[i] = B;
|
||||
else if (C < A)
|
||||
results[i] = A;
|
||||
else
|
||||
results[i] = C;
|
||||
}
|
||||
|
||||
else {
|
||||
if (A < C)
|
||||
results[i] = A;
|
||||
else if (C < B)
|
||||
results[i] = B;
|
||||
else
|
||||
results[i] = C;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int verify_median(int n, int* test) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
int v = test[i];
|
||||
result += v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int run_median(int dummy_0, int nonce) {
|
||||
median_data_init(nonce);
|
||||
median(400, input_median, results_median);
|
||||
|
||||
return verify_median(400, results_median);
|
||||
}
|
||||
65
bench/multiply.c
Normal file
65
bench/multiply.c
Normal file
@@ -0,0 +1,65 @@
|
||||
// *************************************************************************
|
||||
// multiply filter bencmark
|
||||
// -------------------------------------------------------------------------
|
||||
//
|
||||
// This benchmark tests the software multiply implemenation.
|
||||
|
||||
int input1_multiply[100];
|
||||
int input2_multiply[100];
|
||||
int results_multiply[100];
|
||||
|
||||
void multiply_data_init(int nonce) {
|
||||
int i;
|
||||
int x = nonce;
|
||||
int y = nonce;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
x = (x * 97 + 17) % 10009;
|
||||
y = (y * 17 + 23) % 10007;
|
||||
input1_multiply[i] = x;
|
||||
input2_multiply[i] = y;
|
||||
}
|
||||
}
|
||||
|
||||
int multiply(int x, int y) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if ((x & 0x1) == 1)
|
||||
result = result + y;
|
||||
|
||||
x = x >> 1;
|
||||
y = y << 1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int verify_multiply(int n, int* test) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
int t0 = input1_multiply[i];
|
||||
int t1 = input2_multiply[i];
|
||||
int v = results_multiply[i];
|
||||
if (t0 * t1 != v)
|
||||
return 1;
|
||||
|
||||
result += v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int run_multiply(int dummy_0, int nonce) {
|
||||
int i;
|
||||
|
||||
multiply_data_init(nonce);
|
||||
for (i = 0; i < 100; i++) {
|
||||
results_multiply[i] = multiply(input1_multiply[i], input2_multiply[i]);
|
||||
}
|
||||
|
||||
return verify_multiply(100, results_multiply);
|
||||
}
|
||||
129
bench/qsort.c
Normal file
129
bench/qsort.c
Normal file
@@ -0,0 +1,129 @@
|
||||
//**************************************************************************
|
||||
// Quicksort benchmark
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// This benchmark uses quicksort to sort an array of integers. The
|
||||
// implementation is largely adapted from Numerical Recipes for C.
|
||||
|
||||
int input_qsort_data[16384];
|
||||
|
||||
void qsort_data_init(int nonce) {
|
||||
int i;
|
||||
int x = nonce;
|
||||
|
||||
for (i = 0; i < 16384; i++) {
|
||||
x = (x * 97 + 17) % 100000009;
|
||||
input_qsort_data[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(int* a, int* b) {
|
||||
int temp = *a;
|
||||
*a = *b;
|
||||
*b = temp;
|
||||
}
|
||||
|
||||
void swap_if_greater(int* a, int* b) {
|
||||
if (*a > *b)
|
||||
swap(a, b);
|
||||
}
|
||||
|
||||
void insertion_sort(int n, int* arr) {
|
||||
int i, j;
|
||||
int value;
|
||||
for (i = 1; i < n; i++) {
|
||||
value = arr[i];
|
||||
j = i;
|
||||
while (value < arr[j - 1]) {
|
||||
arr[j] = arr[j - 1];
|
||||
if (--j == 0)
|
||||
break;
|
||||
}
|
||||
arr[j] = value;
|
||||
}
|
||||
}
|
||||
|
||||
void qsort(int n, int arr[16384]) {
|
||||
int ir = n;
|
||||
int l = 1;
|
||||
int stack[50];
|
||||
int stackp = 0;
|
||||
|
||||
for (;;) {
|
||||
// Insertion sort when subarray small enough.
|
||||
if (ir - l < 10) {
|
||||
insertion_sort(ir - l + 1, &arr[l - 1]);
|
||||
|
||||
if (stackp == 0)
|
||||
break;
|
||||
|
||||
// Pop stack and begin a new round of partitioning.
|
||||
ir = stack[stackp--];
|
||||
l = stack[stackp--];
|
||||
} else {
|
||||
// Choose median of left, center, and right elements as
|
||||
// partitioning element a. Also rearrange so that a[l-1] <= a[l] <= a[ir-].
|
||||
swap(&arr[(l + ir) / 2 - 1], &arr[l]);
|
||||
swap_if_greater(&arr[l - 1], &arr[ir - 1]);
|
||||
swap_if_greater(&arr[l], &arr[ir - 1]);
|
||||
swap_if_greater(&arr[l - 1], &arr[l]);
|
||||
|
||||
// Initialize pointers for partitioning.
|
||||
int i = l + 1;
|
||||
int j = ir;
|
||||
|
||||
// Partitioning element.
|
||||
int a = arr[l];
|
||||
|
||||
for (;;) { // Beginning of innermost loop.
|
||||
while (arr[i++] < a)
|
||||
; // Scan up to find element > a.
|
||||
while (arr[(j-- - 2)] > a)
|
||||
; // Scan down to find element < a.
|
||||
if (j < i)
|
||||
break; // Pointers crossed. Partitioning complete.
|
||||
swap(&arr[i - 1], &arr[j - 1]); // Exchange elements.
|
||||
} // End of innermost loop.
|
||||
|
||||
// Insert partitioning element.
|
||||
arr[l] = arr[j - 1];
|
||||
arr[j - 1] = a;
|
||||
stackp += 2;
|
||||
|
||||
// Push pointers to larger subarray on stack,
|
||||
// process smaller subarray immediately.
|
||||
|
||||
if (ir - i + 1 >= j - l) {
|
||||
stack[stackp] = ir;
|
||||
stack[stackp - 1] = i;
|
||||
ir = j - 1;
|
||||
} else {
|
||||
stack[stackp] = j - 1;
|
||||
stack[stackp - 1] = l;
|
||||
l = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int verify_qsort(int n, int* test) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < n - 1; i++) {
|
||||
int t0 = test[i], t1 = test[i + 1];
|
||||
if (t0 > t1)
|
||||
return 1;
|
||||
|
||||
result += t0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int run_qsort(int dummy_0, int nonce) {
|
||||
qsort_data_init(nonce);
|
||||
qsort(16384, input_qsort_data);
|
||||
|
||||
return verify_qsort(16384, input_qsort_data);
|
||||
}
|
||||
117
bench/rsort.c
Normal file
117
bench/rsort.c
Normal file
@@ -0,0 +1,117 @@
|
||||
//**************************************************************************
|
||||
// Radix Sort benchmark
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// This benchmark uses radix sort to sort an array of integers. The
|
||||
// implementation is largely adapted from Numerical Recipes for C.
|
||||
|
||||
int input_rsort_data[2048];
|
||||
|
||||
void rsort_data_init(int nonce) {
|
||||
int i;
|
||||
int x = nonce;
|
||||
|
||||
for (i = 0; i < 2048; i++) {
|
||||
x = (x * 97 + 17) % 10000007;
|
||||
input_rsort_data[i] = x;
|
||||
}
|
||||
}
|
||||
|
||||
int fetch_add(int* ptr, int inc) {
|
||||
return (*ptr += inc) - inc;
|
||||
}
|
||||
|
||||
void memcpy_int(int* dest, int* src, int size) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
dest[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
int bucket[256];
|
||||
|
||||
void rsort(int n, int* arrIn, int* scratchIn) {
|
||||
int log_exp = 0;
|
||||
int *arr = arrIn, *scratch = scratchIn;
|
||||
int p;
|
||||
int b;
|
||||
|
||||
while (log_exp < 8 * sizeof(int)) {
|
||||
for (b = 0; b < (1 << 8); b++)
|
||||
bucket[b] = 0;
|
||||
|
||||
for (p = 0; p < n - 3; p += 4) {
|
||||
int a0 = arr[p + 0];
|
||||
int a1 = arr[p + 1];
|
||||
int a2 = arr[p + 2];
|
||||
int a3 = arr[p + 3];
|
||||
fetch_add(&bucket[(a0 >> log_exp) % (1 << 8)], 1);
|
||||
fetch_add(&bucket[(a1 >> log_exp) % (1 << 8)], 1);
|
||||
fetch_add(&bucket[(a2 >> log_exp) % (1 << 8)], 1);
|
||||
fetch_add(&bucket[(a3 >> log_exp) % (1 << 8)], 1);
|
||||
}
|
||||
for (; p < n; p++)
|
||||
bucket[(arr[p] >> log_exp) % (1 << 8)]++;
|
||||
|
||||
int prev = bucket[0];
|
||||
prev += fetch_add(&bucket[1], prev);
|
||||
for (b = 2; b < (1 << 8); b += 2) {
|
||||
prev += fetch_add(&bucket[b + 0], prev);
|
||||
prev += fetch_add(&bucket[b + 1], prev);
|
||||
}
|
||||
|
||||
for (p = n - 1; p >= 3; p -= 4) {
|
||||
int a0 = arr[p - 0];
|
||||
int a1 = arr[p - 1];
|
||||
int a2 = arr[p - 2];
|
||||
int a3 = arr[p - 3];
|
||||
int* pb0 = &bucket[(a0 >> log_exp) % (1 << 8)];
|
||||
int* pb1 = &bucket[(a1 >> log_exp) % (1 << 8)];
|
||||
int* pb2 = &bucket[(a2 >> log_exp) % (1 << 8)];
|
||||
int* pb3 = &bucket[(a3 >> log_exp) % (1 << 8)];
|
||||
int s0 = fetch_add(pb0, -1);
|
||||
int s1 = fetch_add(pb1, -1);
|
||||
int s2 = fetch_add(pb2, -1);
|
||||
int s3 = fetch_add(pb3, -1);
|
||||
scratch[s0 - 1] = a0;
|
||||
scratch[s1 - 1] = a1;
|
||||
scratch[s2 - 1] = a2;
|
||||
scratch[s3 - 1] = a3;
|
||||
}
|
||||
for (; p >= 0; p--)
|
||||
scratch[--bucket[(arr[p] >> log_exp) % (1 << 8)]] = arr[p];
|
||||
|
||||
int* tmp = arr;
|
||||
arr = scratch;
|
||||
scratch = tmp;
|
||||
|
||||
log_exp += 8;
|
||||
}
|
||||
if (arr != arrIn)
|
||||
memcpy_int(arr, scratch, n);
|
||||
}
|
||||
|
||||
int verify_rsort(int n, int* test) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < n - 1; i++) {
|
||||
int t0 = test[i], t1 = test[i + 1];
|
||||
if (t0 > t1)
|
||||
return 1;
|
||||
|
||||
result += t0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int scratch[2048];
|
||||
|
||||
int run_rsort(int dummy_0, int nonce) {
|
||||
rsort_data_init(nonce);
|
||||
rsort(2048, input_rsort_data, scratch);
|
||||
|
||||
return verify_rsort(2048, input_rsort_data);
|
||||
}
|
||||
90
bench/spmv.c
Normal file
90
bench/spmv.c
Normal file
@@ -0,0 +1,90 @@
|
||||
//**************************************************************************
|
||||
// Double-precision sparse matrix-vector multiplication benchmark
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
double val[2399];
|
||||
int idx[2399];
|
||||
|
||||
double x[500];
|
||||
int ptr[501] = {
|
||||
0, 4, 8, 10, 15, 22, 29, 33, 34, 36, 39, 44, 44, 47, 55, 61, 66, 68, 75, 82, 86, 91, 98, 104, 109, 113, 126, 131, 134,
|
||||
136, 143, 153, 159, 168, 170, 174, 176, 180, 187, 192, 198, 200, 204, 211, 213, 222, 225, 228, 233, 241, 247, 253, 256,
|
||||
262, 264, 270, 274, 277, 283, 288, 294, 301, 307, 312, 315, 319, 325, 329, 332, 338, 340, 342, 348, 353, 359, 362, 366,
|
||||
368, 374, 387, 393, 400, 403, 406, 412, 420, 425, 428, 433, 441, 442, 448, 456, 462, 468, 469, 477, 479, 485, 490, 495,
|
||||
501, 508, 513, 518, 524, 532, 535, 538, 542, 546, 552, 561, 563, 567, 571, 574, 576, 581, 584, 588, 592, 593, 597, 599,
|
||||
607, 612, 615, 619, 626, 633, 640, 646, 650, 653, 659, 665, 670, 673, 678, 685, 691, 697, 703, 708, 712, 717, 719, 722,
|
||||
725, 732, 736, 738, 742, 747, 753, 757, 763, 767, 769, 769, 777, 780, 784, 790, 797, 807, 810, 813, 815, 817, 822, 829,
|
||||
830, 835, 844, 848, 851, 854, 862, 864, 873, 876, 881, 884, 888, 895, 899, 901, 904, 908, 912, 919, 927, 931, 937, 941,
|
||||
944, 948, 950, 955, 960, 963, 970, 975, 979, 983, 985, 992, 993, 998, 1001, 1008, 1012, 1014, 1018, 1023, 1030, 1036,
|
||||
1040, 1045, 1052, 1058, 1061, 1066, 1069, 1071, 1077, 1080, 1084, 1087, 1090, 1092, 1095, 1100, 1102, 1110, 1117, 1122,
|
||||
1130, 1133, 1138, 1142, 1144, 1146, 1153, 1158, 1160, 1167, 1172, 1176, 1179, 1183, 1188, 1191, 1193, 1196, 1204, 1210,
|
||||
1216, 1219, 1221, 1225, 1229, 1234, 1236, 1239, 1244, 1248, 1253, 1256, 1264, 1268, 1271, 1272, 1275, 1278, 1284, 1287,
|
||||
1291, 1296, 1300, 1304, 1306, 1313, 1317, 1322, 1326, 1332, 1336, 1344, 1349, 1356, 1363, 1368, 1369, 1378, 1381, 1385,
|
||||
1388, 1395, 1399, 1407, 1414, 1422, 1425, 1433, 1435, 1438, 1439, 1445, 1448, 1450, 1453, 1456, 1470, 1472, 1475, 1481,
|
||||
1487, 1491, 1494, 1497, 1498, 1503, 1507, 1513, 1517, 1524, 1529, 1534, 1542, 1547, 1550, 1550, 1552, 1553, 1556, 1559,
|
||||
1563, 1571, 1577, 1580, 1585, 1590, 1594, 1598, 1600, 1602, 1610, 1615, 1620, 1628, 1634, 1637, 1649, 1652, 1656, 1662,
|
||||
1664, 1670, 1674, 1678, 1687, 1697, 1704, 1709, 1715, 1720, 1725, 1728, 1736, 1740, 1747, 1750, 1754, 1760, 1763, 1765,
|
||||
1773, 1781, 1783, 1788, 1795, 1802, 1810, 1815, 1820, 1824, 1829, 1836, 1839, 1843, 1847, 1849, 1854, 1859, 1863, 1873,
|
||||
1880, 1882, 1891, 1895, 1899, 1904, 1909, 1914, 1919, 1923, 1927, 1932, 1938, 1943, 1949, 1954, 1960, 1965, 1968, 1974,
|
||||
1980, 1983, 1990, 1992, 1995, 2002, 2011, 2017, 2024, 2028, 2035, 2037, 2048, 2055, 2063, 2067, 2069, 2078, 2081, 2085,
|
||||
2086, 2090, 2097, 2101, 2107, 2110, 2112, 2116, 2119, 2122, 2129, 2136, 2143, 2146, 2156, 2162, 2171, 2175, 2179, 2186,
|
||||
2189, 2194, 2198, 2206, 2211, 2215, 2222, 2228, 2237, 2241, 2245, 2256, 2259, 2269, 2272, 2275, 2278, 2279, 2281, 2287,
|
||||
2292, 2297, 2304, 2311, 2316, 2319, 2322, 2327, 2333, 2340, 2343, 2345, 2350, 2358, 2365, 2365, 2368, 2373, 2379, 2388,
|
||||
2394, 2399};
|
||||
|
||||
void spmv_init(int nonce) {
|
||||
int i;
|
||||
int t1 = nonce;
|
||||
int t2 = nonce;
|
||||
|
||||
for (i = 0; i < 2399; i++) {
|
||||
t1 = (t1 * 97 + 17) % 1000;
|
||||
t2 = (t2 * 17 + 23) % 500;
|
||||
val[i] = (double) t1;
|
||||
idx[i] = t2;
|
||||
}
|
||||
|
||||
for (i = 0; i < 500; i++) {
|
||||
t1 = (t1 * 17 + 23) % 1000;
|
||||
x[i] = (double) t1;
|
||||
}
|
||||
}
|
||||
|
||||
void spmv(int r, double* val, int* idx, double* x, int* ptr, double* y) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < r; i++) {
|
||||
int k;
|
||||
double yi0 = 0, yi1 = 0, yi2 = 0, yi3 = 0;
|
||||
for (k = ptr[i]; k < ptr[i + 1] - 3; k += 4) {
|
||||
yi0 += val[k + 0] * x[idx[k + 0]];
|
||||
yi1 += val[k + 1] * x[idx[k + 1]];
|
||||
yi2 += val[k + 2] * x[idx[k + 2]];
|
||||
yi3 += val[k + 3] * x[idx[k + 3]];
|
||||
}
|
||||
for (; k < ptr[i + 1]; k++) {
|
||||
yi0 += val[k] * x[idx[k]];
|
||||
}
|
||||
y[i] = (yi0 + yi1) + (yi2 + yi3);
|
||||
}
|
||||
}
|
||||
|
||||
int verifyDouble(int n, double* test) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
result += (int) (test[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double y[500];
|
||||
|
||||
int run_spmv(int dummy_0, int nonce) {
|
||||
spmv_init(nonce);
|
||||
spmv(500, val, idx, x, ptr, y);
|
||||
|
||||
return verifyDouble(500, y);
|
||||
}
|
||||
193
bench/towers.c
Normal file
193
bench/towers.c
Normal file
@@ -0,0 +1,193 @@
|
||||
//**************************************************************************
|
||||
// Towers of Hanoi benchmark
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// Towers of Hanoi is a classic puzzle problem. The game consists of
|
||||
// three pegs and a set of discs. Each disc is a different size, and
|
||||
// initially all of the discs are on the left most peg with the smallest
|
||||
// disc on top and the largest disc on the bottom. The goal is to move all
|
||||
// of the discs onto the right most peg. The catch is that you are only
|
||||
// allowed to move one disc at a time and you can never place a larger
|
||||
// disc on top of a smaller disc.
|
||||
//
|
||||
// This implementation starts with NUM_DISC discs and uses a recursive
|
||||
// algorithm to solve the puzzle.
|
||||
|
||||
struct Node {
|
||||
int val;
|
||||
struct Node* next;
|
||||
};
|
||||
|
||||
struct List {
|
||||
int size;
|
||||
struct Node* head;
|
||||
};
|
||||
|
||||
struct List g_nodeFreeList;
|
||||
struct Node g_nodePool[7];
|
||||
|
||||
int list_getSize(struct List* list) {
|
||||
return list->size;
|
||||
}
|
||||
|
||||
void list_init(struct List* list) {
|
||||
list->size = 0;
|
||||
list->head = 0;
|
||||
}
|
||||
|
||||
void list_push(struct List* list, int val) {
|
||||
struct Node* newNode;
|
||||
|
||||
// Pop the next free node off the free list
|
||||
newNode = g_nodeFreeList.head;
|
||||
g_nodeFreeList.head = g_nodeFreeList.head->next;
|
||||
|
||||
// Push the new node onto the given list
|
||||
newNode->next = list->head;
|
||||
list->head = newNode;
|
||||
|
||||
// Assign the value
|
||||
list->head->val = val;
|
||||
|
||||
// Increment size
|
||||
list->size++;
|
||||
}
|
||||
|
||||
int list_pop(struct List* list) {
|
||||
struct Node* freedNode;
|
||||
int val;
|
||||
|
||||
// Get the value from the->head of given list
|
||||
val = list->head->val;
|
||||
|
||||
// Pop the head node off the given list
|
||||
freedNode = list->head;
|
||||
list->head = list->head->next;
|
||||
|
||||
// Push the freed node onto the free list
|
||||
freedNode->next = g_nodeFreeList.head;
|
||||
g_nodeFreeList.head = freedNode;
|
||||
|
||||
// Decrement size
|
||||
list->size--;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void list_clear(struct List* list) {
|
||||
while (list_getSize(list) > 0)
|
||||
list_pop(list);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Tower data structure and functions
|
||||
|
||||
struct Towers {
|
||||
int numDiscs;
|
||||
int numMoves;
|
||||
struct List pegA;
|
||||
struct List pegB;
|
||||
struct List pegC;
|
||||
};
|
||||
|
||||
void towers_init(struct Towers* towers, int n, int nonce) {
|
||||
int i;
|
||||
|
||||
towers->numDiscs = n;
|
||||
towers->numMoves = 0;
|
||||
|
||||
list_init(&(towers->pegA));
|
||||
list_init(&(towers->pegB));
|
||||
list_init(&(towers->pegC));
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
list_push(&(towers->pegA), nonce * (n - i));
|
||||
}
|
||||
|
||||
void towers_clear(struct Towers* towers, int nonce) {
|
||||
list_clear(&(towers->pegA));
|
||||
list_clear(&(towers->pegB));
|
||||
list_clear(&(towers->pegC));
|
||||
|
||||
towers_init(towers, towers->numDiscs, nonce);
|
||||
}
|
||||
|
||||
void towers_solve_h(struct Towers* towers, int n, struct List* startPeg, struct List* tempPeg, struct List* destPeg) {
|
||||
int val;
|
||||
|
||||
if (n == 1) {
|
||||
val = list_pop(startPeg);
|
||||
list_push(destPeg, val);
|
||||
towers->numMoves++;
|
||||
} else {
|
||||
towers_solve_h(towers, n - 1, startPeg, destPeg, tempPeg);
|
||||
towers_solve_h(towers, 1, startPeg, tempPeg, destPeg);
|
||||
towers_solve_h(towers, n - 1, tempPeg, startPeg, destPeg);
|
||||
}
|
||||
}
|
||||
|
||||
void towers_solve(struct Towers* towers) {
|
||||
towers_solve_h(towers, towers->numDiscs, &(towers->pegA), &(towers->pegB), &(towers->pegC));
|
||||
}
|
||||
|
||||
int towers_verify(struct Towers* towers, int nonce) {
|
||||
struct Node* ptr;
|
||||
int numDiscs = 0;
|
||||
int result = 0;
|
||||
|
||||
if (list_getSize(&towers->pegA) != 0) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (list_getSize(&towers->pegB) != 0) {
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (list_getSize(&towers->pegC) != towers->numDiscs) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
for (ptr = towers->pegC.head; ptr != 0; ptr = ptr->next) {
|
||||
numDiscs++;
|
||||
if (ptr->val != nonce * numDiscs) {
|
||||
return 5;
|
||||
}
|
||||
result += ptr->val;
|
||||
}
|
||||
|
||||
if (towers->numMoves != ((1 << towers->numDiscs) - 1)) {
|
||||
return 6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Main
|
||||
|
||||
int run_towers(int dummy_0, int nonce) {
|
||||
struct Towers towers;
|
||||
int i;
|
||||
|
||||
// Initialize free list
|
||||
|
||||
list_init(&g_nodeFreeList);
|
||||
g_nodeFreeList.head = &(g_nodePool[0]);
|
||||
g_nodeFreeList.size = 7;
|
||||
g_nodePool[7 - 1].next = 0;
|
||||
g_nodePool[7 - 1].val = 99;
|
||||
for (i = 0; i < (7 - 1); i++) {
|
||||
g_nodePool[i].next = &(g_nodePool[i + 1]);
|
||||
g_nodePool[i].val = nonce * i;
|
||||
}
|
||||
|
||||
towers_init(&towers, 7, nonce);
|
||||
|
||||
// Solve it
|
||||
|
||||
towers_clear(&towers, nonce);
|
||||
towers_solve(&towers);
|
||||
|
||||
// Check the results
|
||||
return towers_verify(&towers, nonce);
|
||||
}
|
||||
48
bench/vvadd.c
Normal file
48
bench/vvadd.c
Normal file
@@ -0,0 +1,48 @@
|
||||
//**************************************************************************
|
||||
// Vector-vector add benchmark
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
// This benchmark uses adds to vectors and writes the results to a
|
||||
// third vector.
|
||||
|
||||
int input1_vvadd[1000];
|
||||
int input2_vvadd[1000];
|
||||
int results_vvadd[1000];
|
||||
|
||||
void vvadd_init(int nonce) {
|
||||
int i;
|
||||
int x = nonce;
|
||||
int y = nonce;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
x = (x * 97 + 17) % 1009;
|
||||
y = (x * 17 + 23) % 1007;
|
||||
input1_vvadd[i] = x;
|
||||
input2_vvadd[i] = y;
|
||||
}
|
||||
}
|
||||
|
||||
void vvadd(int n, int a[1000], int b[1000], int c[1000]) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
c[i] = a[i] + b[i];
|
||||
}
|
||||
|
||||
int verify_vvadd(int n, int* test) {
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
int v = test[i];
|
||||
result += v;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int run_vvadd(int dummy_0, int nonce) {
|
||||
vvadd_init(nonce);
|
||||
vvadd(1000, input1_vvadd, input2_vvadd, results_vvadd);
|
||||
return verify_vvadd(1000, results_vvadd);
|
||||
}
|
||||
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@@ -3,3 +3,4 @@
|
||||
/test*.c
|
||||
/reduce-criteria.sh
|
||||
/creduce_bug_*
|
||||
__pycache__
|
||||
|
||||
@@ -61,7 +61,7 @@ const IRGEN_SMALL_TEST_IGNORE_LIST: [&str; 12] = [
|
||||
];
|
||||
|
||||
// TODO: Enable this test next semester.
|
||||
const IRGEN_FULL_TEST_IGNORE_LIST: [&str; 1] = ["examples/c/side-effect.c"];
|
||||
const IRGEN_FULL_TEST_IGNORE_LIST: [&str; 1] = ["examples/c/side_effect.c"];
|
||||
|
||||
const ASMGEN_TEST_DIR_LIST: [&str; 5] = [
|
||||
"examples/ir0",
|
||||
|
||||
Reference in New Issue
Block a user