-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_harness.cpp
127 lines (98 loc) · 4.29 KB
/
test_harness.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <cuda.h>
#include <cutil.h>
#include "util.h"
#include "ref_2dhisto.h"
#include "opt_2dhisto.h"
#define SQRT_2 1.4142135623730950488
#define SPREAD_BOTTOM (2)
#define SPREAD_TOP (6)
#define NEXT(init_, spread_) \
(init_ + (int)((drand48() - 0.5) * (drand48() - 0.5) * 4.0 * SQRT_2 * SQRT_2 * spread_));
#define CLAMP(value_, min_, max_) \
if (value_ < 0) \
value_ = (min_); \
else if (value_ > (max_)) \
value_ = (max_);
// Generate another bin for the histogram. The bins are created as a random walk ...
static uint32_t next_bin(uint32_t pix)
{
const uint16_t bottom = pix & ((1<<HISTO_LOG)-1);
const uint16_t top = (uint16_t)(pix >> HISTO_LOG);
int new_bottom = NEXT(bottom, SPREAD_BOTTOM) // this is evil. Where's the semicolon?
CLAMP(new_bottom, 0, HISTO_WIDTH-1)
int new_top = NEXT(top, SPREAD_TOP)
CLAMP(new_top, 0, HISTO_HEIGHT-1)
const uint32_t result = (new_bottom | (new_top << HISTO_LOG));
return result;
}
// Return a 2D array of histogram bin-ids. This function generates
// bin-ids with correlation characteristics similar to some actual images.
// The key point here is that the pixels (and thus the bin-ids) are *NOT*
// randomly distributed ... a given pixel tends to be similar to the
// pixels near it.
static uint32_t **generate_histogram_bins()
{
uint32_t **input = (uint32_t**)alloc_2d(INPUT_HEIGHT, INPUT_WIDTH, sizeof(uint32_t));
input[0][0] = HISTO_WIDTH/2 | ((HISTO_HEIGHT/2) << HISTO_LOG);
for (int i = 1; i < INPUT_WIDTH; ++i)
input[0][i] = next_bin(input[0][i - 1]);
for (int j = 1; j < INPUT_HEIGHT; ++j)
{
input[j][0] = next_bin(input[j - 1][0]);
for (int i = 1; i < INPUT_WIDTH; ++i)
input[j][i] = next_bin(input[j][i - 1]);
}
return input;
}
int main(int argc, char* argv[])
{
/* Case of 0 arguments: Default seed is used */
if (argc < 2){
srand48(0);
}
/* Case of 1 argument: Seed is specified as first command line argument */
else {
int seed = atoi(argv[1]);
srand48(seed);
}
uint8_t *gold_bins = (uint8_t*)malloc(HISTO_HEIGHT*HISTO_WIDTH*sizeof(uint8_t));
// Use kernel_bins for your final result
uint8_t *kernel_bins = (uint8_t*)malloc(HISTO_HEIGHT*HISTO_WIDTH*sizeof(uint8_t));
// A 2D array of histogram bin-ids. One can think of each of these bins-ids as
// being associated with a pixel in a 2D image.
uint32_t **input = generate_histogram_bins();
TIME_IT("ref_2dhisto",
1000,
ref_2dhisto(input, INPUT_HEIGHT, INPUT_WIDTH, gold_bins););
/* Include your setup code below (temp variables, function calls, etc.) */
uint32_t *d_result = NULL;
uint32_t *d_data = NULL;
setup(&d_result, &d_data, input);
/* End of setup code */
/* This is the call you will use to time your parallel implementation */
TIME_IT("opt_2dhisto",
1000,
opt_2dhisto(d_data, d_result););
/* Include your teardown code below (temporary variables, function calls, etc.) */
teardown(d_result, kernel_bins, d_data);
/* End of teardown code */
printf("The true result, and the actual result:\n");
for(int i = 0; i <NUM_BINS; i++){
printf("%d, %d\n", gold_bins[i], kernel_bins[i]);
}
int passed=1;
for (int i=0; i < HISTO_HEIGHT*HISTO_WIDTH; i++){
if (gold_bins[i] != kernel_bins[i]){
printf("failure at bin %d", i);
printf("Correct is %d\n", gold_bins[i]);
printf("Actual is %d\n", kernel_bins[i]);
passed = 0;
break;
}
}
(passed) ? printf("\n Test PASSED\n") : printf("\n Test FAILED\n");
}