• No se han encontrado resultados

ENFOQUES PARA EL DESARROLLO DE LA EDUCACIÓN SUPERIOR cuencias que un problema puede producir

Educación Superior en Ecuador y Latinoamérica

ENFOQUES PARA EL DESARROLLO DE LA EDUCACIÓN SUPERIOR cuencias que un problema puede producir

Every well-written application must deal with errors. OpenCL provides ways of re- ceiving the exit status of functions. OpenCL C++ API provides more sophisticated ways of error handling, but both C and C++ provide sufficient information for the application.

2.7.1. Checking Error Codes

The most traditional and straightforward way of handling error is by checking the value that is returned by the function being checked. This method is present in both C and C++ OpenCL API. Almost every function or method present in OpenCL can return an error code. The code in listings 2.16 and 2.17 presents this method of error handling. This frequently used fragment of code creates the OpenCL pro- gram object. The error code is stored into the value err. CL_SUCCESS indicates that everything went well. The other error codes are also visible in the example – CL_INVALID_CONTEXT, CL_OUT_OF_RESOURCES and CL_OUT_OF_HOST_MEMORY. Error codes have self-explanatory names. For example CL_OUT_OF_HOST_MEMORY means that the host does not have enough free memory to perform the requested operation. Error codes are gathered in the header file cl.h. In the C++ API, error

1 program = clCreateProgramWithSource(context, 1, ( const char ** )&appsource, &size, 2 &err); 3 if (err != CL_SUCCESS) { 4 printf("ERROR: "); 5 switch (err) { 6 case CL_INVALID_CONTEXT:

7 printf("Context is not a valid context.\n");

8 break;

9 case CL_OUT_OF_RESOURCES:

10 printf(

11 "There is a failure to allocate resources required by the OpenCL implementation on the device.\n");

12 break;

13 case CL_OUT_OF_HOST_MEMORY:

14 printf(

15 "There is a failure to allocate resources required by the OpenCL implementation on the host.\n");

16 }

17 return NULL;

18 }

Listing 2.16: Error handling using error codes – the C version

handling in this way is the default, but it is possible to turn this off and use excep- tions.

1 program = cl::Program(context, sources, &err);

2 if (err != CL_SUCCESS) {

3 std::cout << "ERROR: ";

4 switch (err) {

5 case CL_INVALID_CONTEXT:

6 std::cout << "Context is not a valid context." << std::endl;

7 break;

8 case CL_OUT_OF_RESOURCES:

9 std::cout <<

10 "There is a failure to allocate resources required by the OpenCL implementation on the device."

11 << std::endl;

12 break;

13 case CL_OUT_OF_HOST_MEMORY:

14 std::cout <<

15 "There is a failure to allocate resources required by the OpenCL implementation on the host."

16 << std::endl;

17 }

18 exit(EXIT_FAILURE);

19 }

1 #define __CL_ENABLE_EXCEPTIONS

2

3 #include <cstdlib>

4 #include <iostream>

5

6 #if defined(__APPLE__) || defined(__MACOSX)

7 #include <OpenCL/cl.hpp>

8 #else

9 #include <CL/cl.hpp>

10 #endif

11

12 int main(int argc, char **argv) {

13 cl::Context context;

14 std::vector < cl::Platform > platforms;

15 cl::Platform::get(&platforms);

16 cl_context_properties cps [3] =

17 { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms [0])(), 0 };

18 try {

19 context = cl::Context(CL_DEVICE_TYPE_ACCELERATOR, cps);

20 } catch (cl::Error &e) {

21 std::cout << "Error in function " << e.what() << ": " << e.err() << std::endl;

22 }

23 return 0;

24 }

Listing 2.18: The full host program that uses exceptions available in C++ OpenCL API

2.7.2. Using Exceptions – Available in C++

The OpenCL C++ wrapper API provides a way of error handling by using exceptions. This method is used in most of the C++ examples in this book. It is a very convenient way of error handling. It allows for skipping implicit error checking and displays information about errors at the top-level function. Implicit error handling can even be completely omitted allowing the default exception handler to display errors. In order to use this feature, the program must define __CL_ENABLE_EXCEPTIONS. This preprocessor macro must be defined before inclusion of cl.hpp in order to work. An example of an application that catches the exception generated during context creation can be seen in listing 2.18.

On most configurations this code will generate an error, because it tries to create context with an accelerator device. Most consumer computers do not have such a device, so the error will be equal to(−1), that means CL_DEVICE_NOT_FOUND.

Note that __CL_ENABLE_EXCEPTIONS is defined in the very beginning of the application code. It is important to remember this, because it is a common mistake to define this macro after inclusion of the OpenCL header files. In that case, the cl::Error will be undefined and it will not turn on exceptions.

1 #define __CL_ENABLE_EXCEPTIONS

2 #define __CL_USER_OVERRIDE_ERROR_STRINGS

3

4 #define __GET_DEVICE_INFO_ERR "Get device info failed"

5 #define __CREATE_CONTEXT_FROM_TYPE_ERR "create context from type failed"

6 // ...

Listing 2.19: The macros that turn on the custom error strings

1 // ...

2 #define __CREATE_SUB_DEVICES "Create subdevices failed"

3 #define __CREATE_CONTEXT_ERR "Create context failed"

4

5 #include <cstdlib>

6 #include <iostream>

7 #if defined(__APPLE__) || defined(__MACOSX)

8 #include <OpenCL/cl.hpp>

9 #else

10 #include <CL/cl.hpp>

11 #endif

12

13 int main(int argc, char **argv) {

14 cl::Context context;

15 std::vector < cl::Platform > platforms;

16 cl::Platform::get(&platforms);

17 cl_context_properties cps [3] =

18 { CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms [0])(), 0 };

19 try {

20 context = cl::Context(CL_DEVICE_TYPE_ACCELERATOR, cps);

21 } catch (cl::Error &e) {

22 std::cout << "Error: " << e.what() << ": " << e.err() << std::endl;

23 }

24 return 0;

25 }

Listing 2.20: The main function for the example of custom error strings usage

2.7.3. Using Custom Error Messages

The default behavior of OpenCL C++ API is to store the function name that caused an error in the exception object of cl::Error class. The API allows for altering this behavior. This can be done by defining __CL_USER_OVERRIDE_ERROR_STRINGS and string constants for all of the possible functions. It is not a commonly used feature, but it allows more descriptive exceptions. In listings 2.19 and 2.20, there are examples of this approach. The code is split into two parts because of the number of needed macros.

1 cl_command_queue queue;

2 cl_device_id devices [1];

3 clGetContextInfo(context, CL_CONTEXT_DEVICES, sizeof(cl_device_id), devices, NULL);

4 queue = clCreateCommandQueue(context, devices [0], 0, NULL);

Listing 2.21: In-order command queue initialization – C programming language

Documento similar