/*! \brief Initialize OpenCl environment on one device Init function for one device. Looks for supported devices and creates a context \return returns a context initialized */ cl_context cl_init(char devicePreference) { cl_int status; // Allocate the event table events = new EventList(); // Discover and populate the platforms status = clGetPlatformIDs(0, NULL, &numPlatforms); cl_errChk(status, "Getting platform IDs", true); if (numPlatforms > 0) { // Get all the platforms platforms = (cl_platform_id*)alloc(numPlatforms * sizeof(cl_platform_id)); status = clGetPlatformIDs(numPlatforms, platforms, NULL); cl_errChk(status, "Getting platform IDs", true); } else { // If no platforms are available, we shouldn't continue printf("No OpenCL platforms found\n"); exit(-1); } // Allocate space for the device lists and lengths numDevices = (cl_uint*)alloc(sizeof(cl_uint)*numPlatforms); devices = (cl_device_id**)alloc(sizeof(cl_device_id*)*numPlatforms); // If a device preference was supplied, we'll limit the search of devices // based on type cl_device_type deviceType = CL_DEVICE_TYPE_ALL; if(devicePreference == 'c') { deviceType = CL_DEVICE_TYPE_CPU; } if(devicePreference == 'g') { deviceType = CL_DEVICE_TYPE_GPU; } // Traverse the platforms array printing information and // populating devices for(unsigned int i = 0; i < numPlatforms ; i++) { // Print out some basic info about the platform char* platformName = NULL; char* platformVendor = NULL; platformName = cl_getPlatformName(platforms[i]); platformVendor = cl_getPlatformVendor(platforms[i]); status = clGetDeviceIDs(platforms[i], deviceType, 0, NULL, &numDevices[i]); cl_errChk(status, "Getting device IDs", false); if(status != CL_SUCCESS) { printf("This is a known NVIDIA bug (if platform == AMD then die)\n"); printf("Setting number of devices to 0 and continuing\n"); numDevices[i] = 0; } printf("Platform %d (%d devices):\n", i, numDevices[i]); printf("\tName: %s\n", platformName); printf("\tVendor: %s\n", platformVendor); free(platformName); free(platformVendor); // Populate OpenCL devices if any exist if(numDevices[i] != 0) { // Allocate an array of devices of size "numDevices" devices[i] = (cl_device_id*)alloc(sizeof(cl_device_id)*numDevices[i]); // Populate Arrray with devices status = clGetDeviceIDs(platforms[i], deviceType, numDevices[i], devices[i], NULL); cl_errChk(status, "Getting device IDs", true); } // Print some information about each device for( unsigned int j = 0; j < numDevices[i]; j++) { char* deviceName = NULL; char* deviceVendor = NULL; printf("\tDevice %d:\n", j); deviceName = cl_getDeviceName(devices[i][j]); deviceVendor = cl_getDeviceVendor(devices[i][j]); printf("\t\tName: %s\n", deviceName); printf("\t\tVendor: %s\n", deviceVendor); free(deviceName); free(deviceVendor); } } // Hard-code in the platform/device to use, or uncomment 'scanf' // to decide at runtime cl_uint chosen_platform, chosen_device; // UNCOMMENT the following two lines to manually select device each time //printf("Enter Platform and Device No (Seperated by Space) \n"); //scanf("%d %d", &chosen_platform, &chosen_device); chosen_platform = 0; chosen_device = 0; printf("Using Platform %d, Device %d \n", chosen_platform, chosen_device); // Do a sanity check of platform/device selection if(chosen_platform >= numPlatforms || chosen_device >= numDevices[chosen_platform]) { printf("Invalid platform/device combination\n"); exit(-1); } // Set the selected platform and device platform = platforms[chosen_platform]; device = devices[chosen_platform][chosen_device]; // Create the context cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platform), 0}; context = clCreateContext(cps, 1, &device, NULL, NULL, &status); cl_errChk(status, "Creating context", true); // Create the command queue commandQueueProf = clCreateCommandQueue(context, device, CL_QUEUE_PROFILING_ENABLE, &status); cl_errChk(status, "creating command queue", true); commandQueueNoProf = clCreateCommandQueue(context, device, 0, &status); cl_errChk(status, "creating command queue", true); if(eventsEnabled) { printf("Profiling enabled\n"); commandQueue = commandQueueProf; } else { printf("Profiling disabled\n"); commandQueue = commandQueueNoProf; } return context; }
//! Dump a CSV file with event information void EventList::dumpTraceCSV(char* path) { char* fullpath = NULL; FILE* fp = NULL; // Construct a filename based on the current time char* filename = this->createFilenameWithTimestamp(); fullpath = smartStrcat(path, filename); // Try to open the file for writing fp = fopen(fullpath, "w"); if(fp == NULL) { printf("Error opening %s\n", fullpath); exit(-1); } // Write some information out about the environment char* tmp; char* tmp2; // Write the device name tmp = cl_getDeviceName(); if(isUsingImages()) { tmp2 = smartStrcat(tmp, " (images)"); } else { tmp2 = smartStrcat(tmp, " (buffers)"); } fprintf(fp, "Info;\t%s\n", tmp2); free(tmp); free(tmp2); // Write the vendor name tmp = cl_getDeviceVendor(); fprintf(fp, "Info;\t%s\n", tmp); free(tmp); // Write the driver version tmp = cl_getDeviceDriverVersion(); fprintf(fp, "Info;\tDriver version %s\n", tmp); free(tmp); // Write the device version tmp = cl_getDeviceVersion(); fprintf(fp, "Info;\t%s\n", tmp); free(tmp); // Write the hostname #ifdef _WIN32 WSADATA wsaData; WSAStartup(MAKEWORD(2,2), &wsaData); #endif char hostname[50]; if(gethostname(hostname, 50) != 0) { printf("Error getting hostname\n"); } else { fprintf(fp, "Info;\tHost %s\n", hostname); } int kernelEventSize = this->kernel_events.size(); cl_ulong timer; cl_int status; for(int i = 0; i < kernelEventSize; i++) { fprintf(fp, "Kernel\t%s", this->kernel_events[i].second); // cl_computeExecTime(this->kernel_events[i].first)); status = clGetEventProfilingInfo(this->kernel_events[i].first, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu", timer); status = clGetEventProfilingInfo(this->kernel_events[i].first, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu", timer); status = clGetEventProfilingInfo(this->kernel_events[i].first, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu", timer); status = clGetEventProfilingInfo(this->kernel_events[i].first, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu\n", timer); } int ioEventSize = this->io_events.size(); for(int i = 0; i < ioEventSize; i++) { fprintf(fp, "IO\t%s", this->io_events[i].second); //,cl_computeExecTime(this->io_events[i].first)); status = clGetEventProfilingInfo(this->io_events[i].first, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu", timer); status = clGetEventProfilingInfo(this->io_events[i].first, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu", timer); status = clGetEventProfilingInfo(this->io_events[i].first, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu", timer); status = clGetEventProfilingInfo(this->io_events[i].first, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &timer, NULL); cl_errChk(status, "profiling", true); fprintf(fp, "\t%lu\n", timer); } /* int compileEventSize = this->compile_events.size(); for(int i = 0; i < compileEventSize; i++) { fprintf(fp, "Compile;\t%s;\t%3.3f\n", this->compile_events[i].second, compile_events[i].first); } int userEventSize = this->user_events.size(); for(int i = 0; i < userEventSize; i++) { fprintf(fp, "User;\t%s;\t%3.3f\n", this->user_events[i].second, user_events[i].first); } */ fclose(fp); free(filename); free(fullpath); }