0
|
1 /**
|
|
2 *
|
|
3 */
|
|
4 module opencl.program;
|
|
5
|
|
6 import opencl.c.opencl;
|
|
7 import opencl.wrapper;
|
|
8 import opencl.device;
|
|
9 import opencl.context;
|
|
10 import opencl.error;
|
|
11
|
|
12 /**
|
|
13 * An OpenCL program consists of a set of kernels that are identified as functions declared with
|
|
14 * the __kernel qualifier in the program source. OpenCL programs may also contain auxiliary
|
|
15 * functions and constant data that can be used by __kernel functions. The program executable
|
|
16 * can be generated online or offline by the OpenCL compiler for the appropriate target device(s).
|
|
17 */
|
|
18 class CLProgram : CLWrapper!(cl_program, clGetProgramInfo)
|
|
19 {
|
|
20 private:
|
|
21 CLContext _context; // the context that contains this program
|
|
22 // CLDevice[] _devices; // can be subset specified with CreateWithBinary
|
|
23 string _sourceCode; // the OpenCL C source code
|
|
24 public:
|
|
25 /**
|
|
26 * creates a program object for a context, and loads the source code specified by the text strings in
|
|
27 * the strings array into the program object. The devices associated with the program object are the
|
|
28 * devices associated with context.
|
|
29 */
|
|
30 this(CLContext context, string sourceCode)
|
|
31 {
|
|
32 cl_int res;
|
|
33 size_t* lengths = cast(size_t*) [sourceCode.length];
|
|
34 char** ptrs = cast(char**) [sourceCode.ptr];
|
|
35 super(clCreateProgramWithSource(context.getObject(), 1, ptrs, lengths, &res));
|
|
36
|
|
37 switch (res)
|
|
38 {
|
|
39 case CL_SUCCESS:
|
|
40 _context = context; // TODO: ok like that?
|
|
41 _sourceCode = sourceCode;
|
|
42 break;
|
|
43 case CL_INVALID_CONTEXT:
|
|
44 throw new CLInvalidContextException();
|
|
45 break;
|
|
46 case CL_INVALID_VALUE:
|
|
47 throw new CLInvalidValueException("source code string pointer is invalid");
|
|
48 break;
|
|
49 case CL_OUT_OF_HOST_MEMORY:
|
|
50 throw new CLOutOfHostMemoryException();
|
|
51 break;
|
|
52 default:
|
|
53 throw new CLUnrecognizedException(res);
|
|
54 break;
|
|
55 }
|
|
56 }
|
|
57
|
|
58 ~this()
|
|
59 {
|
|
60 release();
|
|
61 }
|
|
62
|
|
63 /**
|
|
64 * builds (compiles & links) a program executable from the program source or binary for all the
|
|
65 * devices or a specific device(s) in the OpenCL context associated with program. OpenCL allows
|
|
66 * program executables to be built using the source or the binary.
|
|
67 */
|
|
68 CLProgram build()
|
|
69 {
|
|
70 cl_int res;
|
|
71 res = clBuildProgram(_object, 0, null, null, null, null);
|
|
72
|
|
73 return this;
|
|
74 }
|
|
75
|
|
76 CLProgram buildDebug()
|
|
77 {
|
|
78 cl_int res;
|
|
79 res = clBuildProgram(_object, 0, null, "-Werror", null, null);
|
|
80 return this;
|
|
81 }
|
|
82
|
|
83 /// increments the context reference count
|
|
84 void retain()
|
|
85 {
|
|
86 cl_int res;
|
|
87 res = clRetainProgram(_object);
|
|
88 if(res != CL_SUCCESS)
|
|
89 throw new CLInvalidProgramException("internal program object is not a valid OpenCL context");
|
|
90 }
|
|
91
|
|
92 /// decrements the context reference count
|
|
93 void release()
|
|
94 {
|
|
95 cl_int res;
|
|
96 res = clReleaseContext(_object);
|
|
97 if(res != CL_SUCCESS)
|
|
98 throw new CLInvalidProgramException("internal program object is not a valid OpenCL context");
|
|
99 }
|
|
100
|
|
101 /**
|
|
102 * allows the implementation to release the resources allocated by the OpenCL compiler. This is a
|
|
103 * hint from the application and does not guarantee that the compiler will not be used in the future
|
|
104 * or that the compiler will actually be unloaded by the implementation. Calls to clBuildProgram
|
|
105 * after clUnloadCompiler will reload the compiler, if necessary, to build the appropriate program executable.
|
|
106 *
|
|
107 * TODO: should this stay in this class?
|
|
108 */
|
|
109 static void unloadCompiler()
|
|
110 {
|
|
111 cl_int res;
|
|
112 res = clUnloadCompiler();
|
|
113 if(res != CL_SUCCESS)
|
|
114 throw new CLException(res, "failed unloading compiler, this shouldn't happen in OpenCL 1.0");
|
|
115 }
|
|
116
|
|
117 /// returns the program reference count
|
|
118 // TODO: make it package?
|
|
119 cl_uint referenceCount()
|
|
120 {
|
|
121 return getInfo!(cl_uint)(CL_PROGRAM_REFERENCE_COUNT);
|
|
122 }
|
|
123
|
|
124 /// TODO: check those stuff for consistency with getInfo results
|
|
125 CLContext context()
|
|
126 {
|
|
127 return _context;
|
|
128 }
|
|
129
|
|
130 /**
|
|
131 * Return the list of devices associated with the program object. This can be the devices associated with context on
|
|
132 * which the program object has been created or can be a subset of devices that are specified when a progam object
|
|
133 * is created using clCreateProgramWithBinary
|
|
134 */
|
|
135 CLDevice[] devices()
|
|
136 {
|
|
137 cl_device_id[] ids = getArrayInfo!(cl_device_id)(CL_PROGRAM_DEVICES);
|
|
138 CLDevice[] res = new CLDevice[ids.length];
|
|
139 for(uint i=0; i<ids.length, i++)
|
|
140 res[i] = new CLDevice(ids[i]);
|
|
141 return res;
|
|
142 }
|
|
143
|
|
144 ///
|
|
145 string sourceCode()
|
|
146 {
|
|
147 return _sourceCode;
|
|
148 }
|
|
149
|
|
150 /**
|
|
151 * Return the program binaries for all devices associated with the program.
|
|
152 * Returns:
|
|
153 */
|
|
154 ubyte[][] binaries()
|
|
155 {
|
|
156 // TODO: make sure binaries are available?
|
|
157 size_t[] sizes = getArrayInfo!(size_t)(CL_PROGRAM_BINARY_SIZES);
|
|
158
|
|
159 ubyte*[] ptrs = getArrayInfo!(ubyte*)(CL_PROGRAM_BINARIES);
|
|
160
|
|
161 ubyte[][] res = new ubyte[][ptrs.length];
|
|
162 for (uint i=0; i<ptrs.length; i++)
|
|
163 {
|
|
164 res[i] = ptrs[i][0 .. sizes[i]];
|
|
165 }
|
|
166
|
|
167 return res;
|
|
168 }
|
|
169 } |