1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include "allocation_utils.h"
17
reset_queue(cl_context context,cl_device_id device_id,cl_command_queue * queue,int * error)18 cl_command_queue reset_queue(cl_context context, cl_device_id device_id, cl_command_queue *queue, int *error)
19 {
20 log_info("Invalid command queue. Releasing and recreating the command queue.\n");
21 clReleaseCommandQueue(*queue);
22 *queue = clCreateCommandQueue(context, device_id, 0, error);
23 return *queue;
24 }
25
check_allocation_error(cl_context context,cl_device_id device_id,int error,cl_command_queue * queue,cl_event * event)26 int check_allocation_error(cl_context context, cl_device_id device_id, int error, cl_command_queue *queue, cl_event *event) {
27 //log_info("check_allocation_error context=%p device_id=%p error=%d *queue=%p\n", context, device_id, error, *queue);
28 if (error == CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST && event != 0)
29 {
30 // check for errors from clWaitForEvents (e.g after clEnqueueWriteBuffer)
31 cl_int eventError;
32 error = clGetEventInfo(*event, CL_EVENT_COMMAND_EXECUTION_STATUS, sizeof(error), &eventError, 0);
33 if (CL_SUCCESS != error)
34 {
35 log_error("Failed to get event execution status: %s\n", IGetErrorString(error));
36 return FAILED_ABORT;
37 }
38 if (eventError >= 0)
39 {
40 log_error("Non-negative event execution status after CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST: %s\n", IGetErrorString(error));
41 return FAILED_ABORT;
42 }
43 error = eventError;
44 }
45 if ((error == CL_MEM_OBJECT_ALLOCATION_FAILURE ) || (error == CL_OUT_OF_RESOURCES ) || (error == CL_OUT_OF_HOST_MEMORY) || (error == CL_INVALID_IMAGE_SIZE)) {
46 return FAILED_TOO_BIG;
47 } else if (error == CL_INVALID_COMMAND_QUEUE) {
48 *queue = reset_queue(context, device_id, queue, &error);
49 if (CL_SUCCESS != error)
50 {
51 log_error("Failed to reset command queue after corrupted queue: %s\n", IGetErrorString(error));
52 return FAILED_ABORT;
53 }
54 // Try again with smaller resources.
55 return FAILED_TOO_BIG;
56 } else if (error != CL_SUCCESS) {
57 log_error("Allocation failed with %s.\n", IGetErrorString(error));
58 return FAILED_ABORT;
59 }
60 return SUCCEEDED;
61 }
62
63
toMB(cl_ulong size_in)64 double toMB(cl_ulong size_in) {
65 return (double)size_in/(1024.0*1024.0);
66 }
67
get_actual_allocation_size(cl_mem mem)68 size_t get_actual_allocation_size(cl_mem mem) {
69 int error;
70 cl_mem_object_type type;
71 size_t size, width, height;
72
73 error = clGetMemObjectInfo(mem, CL_MEM_TYPE, sizeof(type), &type, NULL);
74 if (error) {
75 print_error(error, "clGetMemObjectInfo failed for CL_MEM_TYPE.");
76 return 0;
77 }
78
79 if (type == CL_MEM_OBJECT_BUFFER) {
80 error = clGetMemObjectInfo(mem, CL_MEM_SIZE, sizeof(size), &size, NULL);
81 if (error) {
82 print_error(error, "clGetMemObjectInfo failed for CL_MEM_SIZE.");
83 return 0;
84 }
85 return size;
86 } else if (type == CL_MEM_OBJECT_IMAGE2D) {
87 error = clGetImageInfo(mem, CL_IMAGE_WIDTH, sizeof(width), &width, NULL);
88 if (error) {
89 print_error(error, "clGetMemObjectInfo failed for CL_IMAGE_WIDTH.");
90 return 0;
91 }
92 error = clGetImageInfo(mem, CL_IMAGE_HEIGHT, sizeof(height), &height, NULL);
93 if (error) {
94 print_error(error, "clGetMemObjectInfo failed for CL_IMAGE_HEIGHT.");
95 return 0;
96 }
97 return width*height*4*sizeof(cl_uint);
98 }
99
100 log_error("Invalid CL_MEM_TYPE: %d\n", type);
101 return 0;
102 }
103
104
105