forked from halide/Halide
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDeviceArgument.h
106 lines (88 loc) · 3.24 KB
/
DeviceArgument.h
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
#ifndef HALIDE_DEVICE_ARGUMENT_H
#define HALIDE_DEVICE_ARGUMENT_H
/** \file
* Defines helpers for passing arguments to separate devices, such as GPUs.
*/
#include "IR.h"
#include "Closure.h"
#include "ModulusRemainder.h"
namespace Halide {
namespace Internal {
/** A DeviceArgument looks similar to an Halide::Argument, but has behavioral
* differences that make it specific to the GPU pipeline; the fact that
* neither is-a nor has-a Halide::Argument is deliberate. In particular, note
* that a Halide::Argument that is a buffer can be read or write, but not both,
* while a DeviceArgument that is a buffer can be read *and* write for some GPU
* backends. */
struct DeviceArgument {
/** The name of the argument */
std::string name;
/** An argument is either a primitive type (for parameters), or a
* buffer pointer.
*
* If is_buffer == false, then type fully encodes the expected type
* of the scalar argument.
*
* If is_buffer == true, then type.bytes() should be used to determine
* elem_size of the buffer; additionally, type.code *should* reflect
* the expected interpretation of the buffer data (e.g. float vs int),
* but there is no runtime enforcement of this at present.
*/
bool is_buffer;
/** If is_buffer is true, this is the dimensionality of the buffer.
* If is_buffer is false, this value is ignored (and should always be set to zero) */
uint8_t dimensions;
/** If this is a scalar parameter, then this is its type.
*
* If this is a buffer parameter, this is used to determine elem_size
* of the buffer_t.
*
* Note that type.lanes() should always be 1 here. */
Type type;
/** The static size of the argument if known, or zero otherwise. */
size_t size;
/** The index of the first element of the argument when packed into a wider
* type, such as packing scalar floats into vec4 for GLSL. */
size_t packed_index;
/** For buffers, these two variables can be used to specify whether the
* buffer is read or written. By default, we assume that the argument
* buffer is read-write and set both flags. */
bool read;
bool write;
/** Alignment information for integer parameters. */
ModulusRemainder alignment;
DeviceArgument() :
is_buffer(false),
dimensions(0),
size(0),
packed_index(0),
read(false),
write(false) {}
DeviceArgument(const std::string &_name,
bool _is_buffer,
Type _type,
uint8_t _dimensions,
size_t _size = 0) :
name(_name),
is_buffer(_is_buffer),
dimensions(_dimensions),
type(_type),
size(_size),
packed_index(0),
read(_is_buffer),
write(_is_buffer) {}
};
/** A Closure modified to inspect GPU-specific memory accesses, and
* produce a vector of DeviceArgument objects. */
class HostClosure : public Closure {
public:
HostClosure(Stmt s, const std::string &loop_variable = "");
/** Get a description of the captured arguments. */
std::vector<DeviceArgument> arguments();
protected:
using Internal::Closure::visit;
void visit(const For *loop);
void visit(const Call *op);
};
}}
#endif