forked from libocca/occa
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.cpp
131 lines (109 loc) · 2.96 KB
/
main.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
128
129
130
131
#include <iostream>
#include <occa.hpp>
//---[ Internal Tools ]-----------------
// Note: These headers are not officially supported
// Please don't rely on it outside of the occa examples
#include <occa/internal/utils/cli.hpp>
#include <occa/internal/utils/testing.hpp>
//======================================
occa::json parseArgs(int argc, const char **argv);
int main(int argc, const char **argv) {
occa::json args = parseArgs(argc, argv);
int entries = 12;
float *a = new float[entries];
float *b = new float[entries];
float *ab = new float[entries];
for (int i = 0; i < entries; ++i) {
a[i] = i;
b[i] = 1 - i;
ab[i] = 0;
}
occa::device device;
occa::memory o_a, o_b, o_ab;
//---[ Device Setup ]-------------------------------------
device.setup((std::string) args["options/device"]);
/*
* Examples of setting up a device in other backend modes:
*
* device.setup({
* {"mode", "Serial"}
* });
*
* device.setup({
* {"mode" , "OpenMP"},
* {"schedule", "compact"},
* {"chunk" , 10},
* });
*
* device.setup({
* {"mode" , "CUDA"},
* {"device_id", 0},
* });
*
* device.setup({
* {"mode" , "HIP"},
* {"device_id", 0},
* });
*
* device.setup({
* {"mode" , "OpenCL"},
* {"platform_id", 0},
* {"device_id" , 0},
* });
*
* device.setup({
* {"mode" , "Metal"},
* {"device_id", 0},
* });
*/
//========================================================
// Allocate memory on the device
o_a = device.malloc<float>(entries);
o_b = device.malloc<float>(entries);
// We can also allocate memory without a dtype
// WARNING: This will disable runtime type checking
o_ab = device.malloc(entries * sizeof(float));
// Compile the kernel at run-time
occa::kernel addVectors = device.buildKernel("addVectors.okl","addVectors");
// Copy memory to the device
o_a.copyFrom(a);
o_b.copyFrom(b);
// Launch device kernel
addVectors(entries, o_a, o_b, o_ab);
// Copy result to the host
o_ab.copyTo(ab);
// Assert values
for (int i = 0; i < entries; ++i) {
std::cout << i << ": " << ab[i] << '\n';
}
for (int i = 0; i < entries; ++i) {
if (!occa::areBitwiseEqual(ab[i], a[i] + b[i])) {
throw 1;
}
}
// Free host memory
delete [] a;
delete [] b;
delete [] ab;
return 0;
}
occa::json parseArgs(int argc, const char **argv) {
occa::cli::parser parser;
parser
.withDescription(
"Example adding two vectors"
)
.addOption(
occa::cli::option('d', "device",
"Device properties (default: \"{mode: 'Serial'}\")")
.withArg()
.withDefaultValue("{mode: 'Serial'}")
)
.addOption(
occa::cli::option('v', "verbose",
"Compile kernels in verbose mode")
);
occa::json args = parser.parseArgs(argc, argv);
occa::settings()["kernel/verbose"] = args["options/verbose"];
return args;
}