-
Notifications
You must be signed in to change notification settings - Fork 3
/
host.c
126 lines (103 loc) · 3.67 KB
/
host.c
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
/*
* Copyright (c) 2014-2019 - UPMEM
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file host.c
* @brief Template for a Host Application Source File.
*/
#include <dpu.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#ifndef DPU_BINARY
#define DPU_BINARY "build/checksum_dpu"
#endif
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_RESET "\x1b[0m"
static uint8_t test_file[BUFFER_SIZE];
/**
* @brief creates a "test file"
*
* @return the theorical checksum value
*/
static uint32_t create_test_file()
{
uint32_t checksum = 0;
srand(0);
for (unsigned int i = 0; i < BUFFER_SIZE; i++) {
test_file[i] = (unsigned char)(rand());
checksum += test_file[i];
}
return checksum;
}
/**
* @brief Main of the Host Application.
*/
int main()
{
struct dpu_set_t dpu_set, dpu;
uint32_t nr_of_dpus;
uint32_t theoretical_checksum, dpu_checksum;
uint32_t dpu_cycles;
bool status = true;
DPU_ASSERT(dpu_alloc(NR_DPUS, NULL, &dpu_set));
DPU_ASSERT(dpu_load(dpu_set, DPU_BINARY, NULL));
DPU_ASSERT(dpu_get_nr_dpus(dpu_set, &nr_of_dpus));
printf("Allocated %d DPU(s)\n", nr_of_dpus);
// Create an "input file" with arbitrary data.
// Compute its theoretical checksum value.
theoretical_checksum = create_test_file();
printf("Load input data\n");
DPU_ASSERT(dpu_copy_to(dpu_set, XSTR(DPU_BUFFER), 0, test_file, BUFFER_SIZE));
printf("Run program on DPU(s)\n");
DPU_ASSERT(dpu_launch(dpu_set, DPU_SYNCHRONOUS));
DPU_FOREACH (dpu_set, dpu) {
DPU_ASSERT(dpu_log_read(dpu, stdout));
}
printf("Retrieve results\n");
dpu_results_t results[nr_of_dpus];
uint32_t each_dpu;
DPU_FOREACH (dpu_set, dpu, each_dpu) {
DPU_ASSERT(dpu_prepare_xfer(dpu, &results[each_dpu]));
}
DPU_ASSERT(dpu_push_xfer(dpu_set, DPU_XFER_FROM_DPU, XSTR(DPU_RESULTS), 0, sizeof(dpu_results_t), DPU_XFER_DEFAULT));
DPU_FOREACH (dpu_set, dpu, each_dpu) {
bool dpu_status;
dpu_checksum = 0;
dpu_cycles = 0;
// Retrieve tasklet results and compute the final checksum.
for (unsigned int each_tasklet = 0; each_tasklet < NR_TASKLETS; each_tasklet++) {
dpu_result_t *result = &results[each_dpu].tasklet_result[each_tasklet];
dpu_checksum += result->checksum;
if (result->cycles > dpu_cycles)
dpu_cycles = result->cycles;
}
dpu_status = (dpu_checksum == theoretical_checksum);
status = status && dpu_status;
printf("DPU execution time = %g cycles\n", (double)dpu_cycles);
printf("performance = %g cycles/byte\n", (double)dpu_cycles / BUFFER_SIZE);
printf("checksum computed by the DPU = 0x%08x\n", dpu_checksum);
printf("actual checksum value = 0x%08x\n", theoretical_checksum);
if (dpu_status) {
printf("[" ANSI_COLOR_GREEN "OK" ANSI_COLOR_RESET "] checksums are equal\n");
} else {
printf("[" ANSI_COLOR_RED "ERROR" ANSI_COLOR_RESET "] checksums differ!\n");
}
}
DPU_ASSERT(dpu_free(dpu_set));
return status ? 0 : -1;
}