cl_program getOrBuildProgram(const Context* ctx, const cv::ocl::ProgramEntry* source, const String& options)
    {
        cl_int status = 0;
        cl_program program = NULL;
        std::vector<char> binary;
        if (!enable_disk_cache || !readConfigurationFromFile(options, binary))
        {
            program = clCreateProgramWithSource(getClContext(ctx), 1, (const char**)&source->programStr, NULL, &status);
            openCLVerifyCall(status);
            cl_device_id device = getClDeviceID(ctx);
            status = clBuildProgram(program, 1, &device, options.c_str(), NULL, NULL);
            if(status == CL_SUCCESS)
            {
                if (enable_disk_cache)
                {
                    size_t binarySize;
                    openCLSafeCall(clGetProgramInfo(program,
                                            CL_PROGRAM_BINARY_SIZES,
                                            sizeof(size_t),
                                            &binarySize, NULL));

                    std::vector<char> binary(binarySize);

                    char* ptr = &binary[0];
                    openCLSafeCall(clGetProgramInfo(program,
                                            CL_PROGRAM_BINARIES,
                                            sizeof(char*),
                                            &ptr,
                                            NULL));

                    if (!writeConfigurationToFile(options, binary))
                    {
                        std::cerr << "Can't write data to file: " << fileName_ << std::endl;
                    }
                }
            }
        }
        else
        {
            cl_device_id device = getClDeviceID(ctx);
            size_t size = binary.size();
            const char* ptr = &binary[0];
            program = clCreateProgramWithBinary(getClContext(ctx),
                    1, &device,
                    (const size_t *)&size, (const unsigned char **)&ptr,
                    NULL, &status);
            openCLVerifyCall(status);
            status = clBuildProgram(program, 1, &device, options.c_str(), NULL, NULL);
        }

        if(status != CL_SUCCESS)
        {
            if (status == CL_BUILD_PROGRAM_FAILURE || status == CL_INVALID_BUILD_OPTIONS)
            {
                size_t buildLogSize = 0;
                openCLSafeCall(clGetProgramBuildInfo(program, getClDeviceID(ctx),
                        CL_PROGRAM_BUILD_LOG, 0, NULL, &buildLogSize));
                std::vector<char> buildLog; buildLog.resize(buildLogSize);
                memset(&buildLog[0], 0, buildLogSize);
                openCLSafeCall(clGetProgramBuildInfo(program, getClDeviceID(ctx),
                        CL_PROGRAM_BUILD_LOG, buildLogSize, &buildLog[0], NULL));
                std::cout << std::endl << "BUILD LOG: "
                        << (source->name ? source->name : "dynamic program") << ": "
                        << options << "\n";
                std::cout << &buildLog[0] << std::endl;
            }
            openCLVerifyCall(status);
        }
        return program;
    }
Exemple #2
0
    cl_program getOrBuildProgram(const Context* ctx, const cv::ocl::ProgramEntry* source, const String& options)
    {
        cl_int status = 0;
        cl_program program = NULL;
        std::vector<char> binary;
        if (!enable_disk_cache || !readConfigurationFromFile(options, binary))
        {
            program = clCreateProgramWithSource(getClContext(ctx), 1, (const char**)&source->programStr, NULL, &status);
            openCLVerifyCall(status);
            cl_device_id device = getClDeviceID(ctx);
            status = clBuildProgram(program, 1, &device, options.c_str(), NULL, NULL);
            if(status == CL_SUCCESS)
            {
                if (enable_disk_cache)
                {
                    size_t binarySize;
                    openCLSafeCall(clGetProgramInfo(program,
                                            CL_PROGRAM_BINARY_SIZES,
                                            sizeof(size_t),
                                            &binarySize, NULL));

                    std::vector<char> binary(binarySize);

                    char* ptr = &binary[0];
                    openCLSafeCall(clGetProgramInfo(program,
                                            CL_PROGRAM_BINARIES,
                                            sizeof(char*),
                                            &ptr,
                                            NULL));

                    if (!writeConfigurationToFile(options, binary))
                    {
                        std::cerr << "Can't write data to file: " << fileName_ << std::endl;
                    }
                }
            }
        }
        else
        {
            cl_device_id device = getClDeviceID(ctx);
            size_t size = binary.size();
            const char* ptr = &binary[0];
            program = clCreateProgramWithBinary(getClContext(ctx),
                    1, &device,
                    (const size_t *)&size, (const unsigned char **)&ptr,
                    NULL, &status);
            openCLVerifyCall(status);
            status = clBuildProgram(program, 1, &device, options.c_str(), NULL, NULL);
        }

        if(status != CL_SUCCESS)
        {
            if(status == CL_BUILD_PROGRAM_FAILURE)
            {
                cl_int logStatus;
                char *buildLog = NULL;
                size_t buildLogSize = 0;
                logStatus = clGetProgramBuildInfo(program,
                        getClDeviceID(ctx), CL_PROGRAM_BUILD_LOG, buildLogSize,
                        buildLog, &buildLogSize);
                if(logStatus != CL_SUCCESS)
                    std::cout << "Failed to build the program and get the build info." << std::endl;
                buildLog = new char[buildLogSize];
                CV_DbgAssert(!!buildLog);
                memset(buildLog, 0, buildLogSize);
                openCLSafeCall(clGetProgramBuildInfo(program, getClDeviceID(ctx),
                                                     CL_PROGRAM_BUILD_LOG, buildLogSize, buildLog, NULL));
                std::cout << "\nBUILD LOG: " << options << "\n";
                std::cout << buildLog << std::endl;
                delete [] buildLog;
            }
            openCLVerifyCall(status);
        }
        return program;
    }